Various code related to the recurring transactions.

This commit is contained in:
James Cole
2018-06-12 18:48:15 +02:00
parent 2de19547ca
commit 4b4dc2e298
9 changed files with 213 additions and 115 deletions

View File

@@ -74,6 +74,13 @@ class CreateController extends Controller
$tomorrow = new Carbon;
$tomorrow->addDay();
// types of repetitions:
$typesOfRepetitions = [
'forever' => trans('firefly.repeat_forever'),
'until_date' => trans('firefly.repeat_until_date'),
'times' => trans('firefly.repeat_times'),
];
// flash some data:
$preFilled = [
'first_date' => $tomorrow->format('Y-m-d'),
@@ -83,7 +90,7 @@ class CreateController extends Controller
];
$request->session()->flash('preFilled', $preFilled);
return view('recurring.create', compact('tomorrow', 'preFilled', 'defaultCurrency','budgets'));
return view('recurring.create', compact('tomorrow', 'preFilled','typesOfRepetitions', 'defaultCurrency', 'budgets'));
}
}

View File

@@ -63,6 +63,20 @@ class IndexController extends Controller
);
}
/**
* @param Request $request
*
* @return string
*/
public function calendar(Request $request)
{
$date = new Carbon;
$daysOfWeek = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
//$firstDayOfMonth = mktime(0, 0, 0, $month, 1, $year);
return view('recurring.calendar');
}
/**
* @param Request $request
*

View File

@@ -44,6 +44,7 @@ class ChangesForV475 extends Migration
$table->date('first_date');
$table->date('repeat_until')->nullable();
$table->date('latest_date')->nullable();
$table->smallInteger('repetitions', false, true);
$table->boolean('apply_rules')->default(true);
$table->boolean('active')->default(true);

View File

@@ -32,12 +32,44 @@ $(document).ready(function () {
initializeButtons();
initializeAutoComplete();
respondToFirstDateChange();
respondToRepetitionEnd();
$('.switch-button').on('click', switchTransactionType);
$('#ffInput_repetition_end').on('change', respondToRepetitionEnd);
$('#ffInput_first_date').on('change', respondToFirstDateChange);
$('#calendar-link').on('click', showRepCalendar);
});
function showRepCalendar() {
// fill model with calendar:
$('#defaultModal').modal({});
return false;
}
function respondToRepetitionEnd() {
var obj = $('#ffInput_repetition_end');
var value = obj.val();
switch (value) {
case 'forever':
$('#repeat_until_holder').hide();
$('#repetitions_holder').hide();
break;
case 'until_date':
$('#repeat_until_holder').show();
$('#repetitions_holder').hide();
break;
case 'times':
$('#repeat_until_holder').hide();
$('#repetitions_holder').show();
break;
}
}
function respondToFirstDateChange() {
var obj = $('#ffInput_first_date');
var select = $('#ffInput_repetition_type');

View File

@@ -34,4 +34,6 @@ return [
'transactions-index' => 'These expenses, deposits and transfers are not particularly imaginative. They have been generated automatically.',
'piggy-banks-index' => 'As you can see, there are three piggy banks. Use the plus and minus buttons to influence the amount of money in each piggy bank. Click the name of the piggy bank to see the administration for each piggy bank.',
'import-index' => 'Any CSV file can be imported into Firefly III. It also supports importing data from bunq and Spectre. Other banks and financial aggregators will be implemented in the future. As a demo-user however, you can only see the "fake"-provider in action. It will generate some random transactions to show you how the process works.',
'recurring-index' => 'Please note that this feature is under active development and may not work as expected.',
'recurring-create' => 'Please note that this feature is under active development and may not work as expected.',
];

View File

@@ -1235,6 +1235,10 @@ return [
'optional_for_transaction' => 'Optional transaction information',
'change_date_other_options' => 'Change the "first date" to see more options.',
'mandatory_fields_for_tranaction' => 'The values here will end up in the transaction(s) being created',
'click_for_calendar' => 'Click here for a calendar that shows you when the transaction would repeat.',
'repeat_forever' => 'Repeat forever',
'repeat_until_date' => 'Repeat until date',
'repeat_times' => 'Repeat a number of times',
];

View File

@@ -230,5 +230,8 @@ return [
'recurring_description' => 'Recurring transaction description',
'repetition_type' => 'Type of repetition',
'foreign_currency_id' => 'Foreign currency',
'repetition_end' => 'Repetition ends',
'repetitions' => 'Repetitions',
'calendar' => 'Calendar',
];

View File

@@ -6,129 +6,163 @@
<form action="{{ route('recurring.store') }}" method="post" id="store" class="form-horizontal">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
{# row with recurrence information #}
<div class="row">
<div class="col-lg-12">
<div class="col-lg-6 col-md-6 col-sm-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'mandatory_for_recurring'|_ }}</h3>
<div class="col-lg-6 col-md-6 col-sm-12">
{# mandatory recurrence stuff #}
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'mandatory_for_recurring'|_ }}</h3>
</div>
<div class="box-body">
{{ ExpandedForm.text('name') }}
{{ ExpandedForm.date('first_date',null, {helpText: trans('firefly.help_first_date')}) }}
{{ ExpandedForm.select('repetition_type', [], null, {helpText: trans('firefly.change_date_other_options')}) }}
{{ ExpandedForm.number('skip', 0) }}
{{ ExpandedForm.select('repetition_end', typesOfRepetitions) }}
{{ ExpandedForm.date('repeat_until',null) }}
{{ ExpandedForm.number('repetitions',null) }}
{# calendar in popup #}
<div class="form-group" id="calendar_holder">
<label for="ffInput_calendar" class="col-sm-4 control-label">{{ trans('form.calendar') }}</label>
<div class="col-sm-8">
<p class="form-control-static" id="ffInput_calendar">
<a href="#" id="calendar-link">{{ 'click_for_calendar'|_ }}</a>
</p>
</div>
</div>
<div class="box-body">
{{ ExpandedForm.text('name') }}
{{ ExpandedForm.date('first_date',null, {helpText: trans('firefly.help_first_date')}) }}
{{ ExpandedForm.date('repeat_until',null) }}
{{ ExpandedForm.select('repetition_type', [], null, {helpText: trans('firefly.change_date_other_options')}) }}
{{ ExpandedForm.number('skip', 0) }}
</div>
</div>
</div>
{# three buttons to distinguish type of transaction#}
<div class="form-group" id="name_holder">
<label for="ffInput_type" class="col-sm-4 control-label">
{{ trans('form.transaction_type') }}
</label>
<div class="col-lg-6 col-md-6 col-sm-12">
{# optional recurrence stuff #}
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ 'optional_for_recurring'|_ }}</h3>
</div>
<div class="box-body">
{{ ExpandedForm.textarea('recurring_description') }}
<div class="col-sm-8">
<div class="btn-group btn-group-sm">
<a href="#" class="btn btn-default switch-button" data-value="withdrawal">{{ 'withdrawal'|_ }}</a>
<a href="#" class="btn btn-default switch-button" data-value="deposit">{{ 'deposit'|_ }}</a>
<a href="#" class="btn btn-default switch-button" data-value="transfer">{{ 'transfer'|_ }}</a>
</div>
{{ ExpandedForm.checkbox('active',1) }}
{{ ExpandedForm.checkbox('apply_rules',1) }}
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-12">
{# mandatory transaction information #}
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'mandatory_for_transaction'|_ }}</h3>
</div>
<div class="box-body">
<p><em>{{ 'mandatory_fields_for_tranaction'|_ }}</em></p>
{# three buttons to distinguish type of transaction#}
<div class="form-group" id="name_holder">
<label for="ffInput_type" class="col-sm-4 control-label">
{{ trans('form.transaction_type') }}
</label>
<div class="col-sm-8">
<div class="btn-group btn-group-sm">
<a href="#" class="btn btn-default switch-button" data-value="withdrawal">{{ 'withdrawal'|_ }}</a>
<a href="#" class="btn btn-default switch-button" data-value="deposit">{{ 'deposit'|_ }}</a>
<a href="#" class="btn btn-default switch-button" data-value="transfer">{{ 'transfer'|_ }}</a>
</div>
</div>
</div>
{# end of three buttons#}
{{ ExpandedForm.text('transaction_description') }}
{# transaction information (mandatory) #}
{{ ExpandedForm.currencyList('transaction_currency_id', defaultCurrency.id) }}
{{ ExpandedForm.amountNoCurrency('amount', []) }}
{# source account if withdrawal, or if transfer: #}
{{ ExpandedForm.assetAccountList('source_account_id', null, {label: trans('form.asset_source_account')}) }}
{# source account name for deposits: #}
{{ ExpandedForm.text('source_account_name', null, {label: trans('form.revenue_account')}) }}
{# destination if deposit or transfer: #}
{{ ExpandedForm.assetAccountList('destination_account_id', null, {label: trans('form.asset_destination_account')} ) }}
{# destination account name for withdrawals #}
{{ ExpandedForm.text('destination_account_name', null, {label: trans('form.expense_account')}) }}
</div>
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'mandatory_for_transaction'|_ }}</h3>
</div>
<div class="box-body">
<p><em>{{ 'mandatory_fields_for_tranaction'|_ }}</em></p>
{{ ExpandedForm.text('transaction_description') }}
{# transaction information (mandatory) #}
{{ ExpandedForm.currencyList('transaction_currency_id', defaultCurrency.id) }}
{{ ExpandedForm.amountNoCurrency('amount', []) }}
{# source account if withdrawal, or if transfer: #}
{{ ExpandedForm.assetAccountList('source_account_id', null, {label: trans('form.asset_source_account')}) }}
{# source account name for deposits: #}
{{ ExpandedForm.text('source_account_name', null, {label: trans('form.revenue_account')}) }}
{# destination if deposit or transfer: #}
{{ ExpandedForm.assetAccountList('destination_account_id', null, {label: trans('form.asset_destination_account')} ) }}
{# destination account name for withdrawals #}
{{ ExpandedForm.text('destination_account_name', null, {label: trans('form.expense_account')}) }}
</div>
</div>
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'expected_repetitions'|_ }}</h3>
</div>
<div class="box-body">
Here.
</div>
</div>
</div>
<div class="col-lg-6 col-md-6 col-sm-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ 'optional_for_recurring'|_ }}</h3>
</div>
<div class="box-body">
{{ ExpandedForm.textarea('recurring_description') }}
{{ ExpandedForm.checkbox('active',1) }}
{{ ExpandedForm.checkbox('apply_rules',1) }}
</div>
</div>
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'optional_for_transaction'|_ }}</h3>
</div>
<div class="box-body">
{# transaction information (optional) #}
{{ ExpandedForm.currencyList('foreign_currency_id', defaultCurrency.id) }}
{{ ExpandedForm.amountNoCurrency('foreign_amount', []) }}
{# BUDGET ONLY WHEN CREATING A WITHDRAWAL #}
{% if budgets|length > 1 %}
{{ ExpandedForm.select('budget_id', budgets, null) }}
{% else %}
{{ ExpandedForm.select('budget_id', budgets, null, {helpText: trans('firefly.no_budget_pointer')}) }}
{% endif %}
{# CATEGORY ALWAYS #}
{{ ExpandedForm.text('category') }}
{# TAGS #}
{{ ExpandedForm.text('tags') }}
{# RELATE THIS TRANSFER TO A PIGGY BANK #}
{{ ExpandedForm.select('piggy_bank_id', [], '0') }}
</div>
</div>
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ 'options'|_ }}</h3>
</div>
<div class="box-body">
{{ ExpandedForm.optionsList('create','recurrence') }}
</div>
<div class="box-footer">
<button type="submit" class="btn pull-right btn-success">
{{ ('store_new_recurrence')|_ }}
</button>
</div>
</div>
</div>
</div>
<div class="col-lg-6 col-md-6 col-sm-12">
{# optional transaction information #}
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ 'optional_for_transaction'|_ }}</h3>
</div>
<div class="box-body">
{# transaction information (optional) #}
{{ ExpandedForm.currencyList('foreign_currency_id', defaultCurrency.id) }}
{{ ExpandedForm.amountNoCurrency('foreign_amount', []) }}
{# BUDGET ONLY WHEN CREATING A WITHDRAWAL #}
{% if budgets|length > 1 %}
{{ ExpandedForm.select('budget_id', budgets, null) }}
{% else %}
{{ ExpandedForm.select('budget_id', budgets, null, {helpText: trans('firefly.no_budget_pointer')}) }}
{% endif %}
{# CATEGORY ALWAYS #}
{{ ExpandedForm.text('category') }}
{# TAGS #}
{{ ExpandedForm.text('tags') }}
{# RELATE THIS TRANSFER TO A PIGGY BANK #}
{{ ExpandedForm.select('piggy_bank_id', [], '0') }}
</div>
</div>
</div>
</div>
{# row with submit stuff. #}
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-12 col-lg-offset-6 lg-md-offset-6">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ 'options'|_ }}</h3>
</div>
<div class="box-body">
{{ ExpandedForm.optionsList('create','recurrence') }}
</div>
<div class="box-footer">
<button type="submit" class="btn pull-right btn-success">
{{ ('store_new_recurrence')|_ }}
</button>
</div>
</div>
</div>
</div>
{#
<div class="row">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'expected_repetitions'|_ }}</h3>
</div>
<div class="box-body">
Here.
</div>
</div>
</div>
</div>
</div>
#}
</form>
{% endblock %}
{% block scripts %}

View File

@@ -618,6 +618,7 @@ Route::group(
Route::get('', ['uses' => 'IndexController@index', 'as' => 'index']);
Route::get('suggest', ['uses' => 'IndexController@suggest', 'as' => 'suggest']);
Route::get('calendar', ['uses' => 'IndexController@calendar', 'as' => 'calendar']);
Route::get('show/{recurrence}', ['uses' => 'IndexController@show', 'as' => 'show']);
Route::get('create', ['uses' => 'CreateController@create', 'as' => 'create']);
Route::get('edit/{recurrence}', ['uses' => 'EditController@edit', 'as' => 'edit']);