+
+
+
+
+
+ {{ 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) }}
+
+ {# three buttons to distinguish type of transaction#}
+
+
+
+
+
+
+
+
{{ 'mandatory_fields_for_tranaction'|_ }}
+ {{ 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')}) }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ ExpandedForm.textarea('recurring_description') }}
+
+ {{ ExpandedForm.checkbox('active',1) }}
+
+ {{ ExpandedForm.checkbox('apply_rules',1) }}
+
+
+
+
+
+ {# 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') }}
+
+
+
+
+
+
+ {{ ExpandedForm.optionsList('create','recurrence') }}
+
+
+
+
+
+
+
+{% endblock %}
+{% block scripts %}
+
+
+
+
+
+
+{% endblock %}
+
+{% block styles %}
+
+
+
+{% endblock %}
diff --git a/resources/views/recurring/index.twig b/resources/views/recurring/index.twig
new file mode 100644
index 0000000000..63f12e8605
--- /dev/null
+++ b/resources/views/recurring/index.twig
@@ -0,0 +1,120 @@
+{% extends "./layout/default" %}
+
+{% block breadcrumbs %}
+ {{ Breadcrumbs.render(Route.getCurrentRoute.getName) }}
+{% endblock %}
+
+{% block content %}
+
+ {% if recurring|length > 0 %}
+
+
+
+
+
+
+
+
+
+
+ {{ recurring.render|raw }}
+
+
+
+
+ |
+ {{ trans('list.title') }} |
+ {{ trans('list.transaction_s') }} |
+ {{ trans('list.repetitions') }} |
+
+
+
+ {% for rt in recurring %}
+
+
+
+ |
+
+ {{ rt.transaction_type|_ }}:
+
+ {{ rt.title }}
+ {% if rt.description|length > 0 %}
+ {{ rt.description }}
+ {% endif %}
+ |
+
+
+ {% for rtt in rt.transactions %}
+ -
+ {# normal amount + comma#}
+ {{ formatAmountBySymbol(rtt['amount'],rtt['currency_symbol'],rtt['currency_dp']) }}{% if rtt['foreign_amount'] == null %},{% endif %}
+
+ {# foreign amount + comma #}
+ {% if null != rtt['foreign_amount'] %}
+ ({{ formatAmountBySymbol(rtt['foreign_amount'],rtt['foreign_currency_symbol'],rtt['foreign_currency_dp']) }}),
+ {% endif %}
+ {{ rtt['source_account_name'] }}
+ →
+ {{ rtt['destination_account_name'] }}
+
+ {% endfor %}
+
+ |
+
+
+ {% for rep in rt.repetitions %}
+ - {{ rep.description }}
+ {% endfor %}
+
+ |
+
+ {% endfor %}
+
+
+
+ {{ recurring.render|raw }}
+
+
+
+
+
+
+ {% endif %}
+
+
+
+
+ {% if recurring|length == 0 and page == 1 %}
+ {% include 'partials.empty' with {what: 'default', type: 'recurring',route: route('recurring.create')} %}
+ {% endif %}
+{% endblock %}
+
+{% block styles %}
+
+{% endblock %}
+
+{% block scripts %}
+
+{% endblock %}
diff --git a/resources/views/recurring/show.twig b/resources/views/recurring/show.twig
new file mode 100644
index 0000000000..492a15fffe
--- /dev/null
+++ b/resources/views/recurring/show.twig
@@ -0,0 +1,190 @@
+{% extends "./layout/default" %}
+
+{% block breadcrumbs %}
+ {{ Breadcrumbs.render(Route.getCurrentRoute.getName, recurrence) }}
+{% endblock %}
+
+{% block content %}
+
+
+
+
+
+
+
{{ array.description }}
+
+ {% for rep in array.repetitions %}
+ - {{ rep.description }}
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+
+
+ {% for rep in array.repetitions %}
+ - {{ rep.description }}
+
+ {% for occ in rep.occurrences %}
+ - {{ occ.formatLocalized(trans('config.month_and_date_day')) }}
+ {% endfor %}
+
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ trans('list.source') }} |
+ {{ trans('list.destination') }} |
+ {{ trans('list.amount') }} |
+ {{ trans('list.category') }} |
+ {{ trans('list.budget') }} |
+
+
+ {% for transaction in array.transactions %}
+
+
+ {{ transaction.source_account_name }}
+ |
+
+ {{ transaction.destination_account_name }}
+ |
+
+ {{ formatAmountBySymbol(transaction.amount,transaction.currency_symbol,transaction.currency_dp) }}
+ {% if null != transaction.foreign_amount %}
+ ({{ formatAmountBySymbol(transaction.foreign_amount,transaction.foreign_currency_symbol,transaction.foreign_currency_dp) }})
+ {% endif %}
+ |
+
+ {% for meta in transaction.meta %}
+ {% if meta.name == 'category_name' %}
+
+ {{ meta.category_name }}
+
+ {% endif %}
+ {% endfor %}
+ |
+
+ {% for meta in transaction.meta %}
+ {% if meta.name == 'budget_id' %}
+
+ {{ meta.budget_name }}
+
+ {% endif %}
+ {% endfor %}
+ |
+
+ {% endfor %}
+
+
+
+
+
+
+
+ {% if array.meta|length > 0 %}
+
+
+
+
+
+
+ {{ trans('list.field') }} |
+ {{ trans('list.value') }} |
+
+
+ {% for meta in array.meta %}
+
+ {{ trans('firefly.recurring_meta_field_'~meta.name) }} |
+
+ {% if meta.name == 'tags' %}
+ {% for tag in meta.tags %}
+ {{ tag }}
+ {% endfor %}
+ {% endif %}
+ {% if meta.name == 'notes' %}
+ {{ meta.value|markdown }}
+ {% endif %}
+ {% if meta.name == 'bill_id' %}
+ {{ meta.bill_name }}
+ {% endif %}
+ {% if meta.name == 'piggy_bank_id' %}
+ {{ meta.piggy_bank_name }}
+ {% endif %}
+ |
+
+ {% endfor %}
+
+
+
+
+
+
+ {% endif %}
+
+
+{% endblock %}
+
+{% block styles %}
+
+{% endblock %}
+
+{% block scripts %}
+
+{% endblock %}
diff --git a/routes/breadcrumbs.php b/routes/breadcrumbs.php
index cba44bd866..992ed89f63 100644
--- a/routes/breadcrumbs.php
+++ b/routes/breadcrumbs.php
@@ -33,6 +33,7 @@ use FireflyIII\Models\Category;
use FireflyIII\Models\ImportJob;
use FireflyIII\Models\LinkType;
use FireflyIII\Models\PiggyBank;
+use FireflyIII\Models\Recurrence;
use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Models\Tag;
@@ -761,6 +762,30 @@ try {
}
);
+ // Recurring transactions controller:
+ Breadcrumbs::register(
+ 'recurring.index',
+ function (BreadCrumbsGenerator $breadcrumbs) {
+ $breadcrumbs->parent('home');
+ $breadcrumbs->push(trans('firefly.recurrences'), route('recurring.index'));
+ }
+ );
+ Breadcrumbs::register(
+ 'recurring.show',
+ function (BreadCrumbsGenerator $breadcrumbs, Recurrence $recurrence) {
+ $breadcrumbs->parent('recurring.index');
+ $breadcrumbs->push($recurrence->title, route('recurring.show', [$recurrence->id]));
+ }
+ );
+
+ Breadcrumbs::register(
+ 'recurring.create',
+ function (BreadCrumbsGenerator $breadcrumbs) {
+ $breadcrumbs->parent('recurring.index');
+ $breadcrumbs->push(trans('firefly.create_new_recurrence'), route('recurring.create'));
+ }
+ );
+
// Rules
Breadcrumbs::register(
'rules.index',
diff --git a/routes/web.php b/routes/web.php
index 7c98292c2a..2fbd1c00d4 100755
--- a/routes/web.php
+++ b/routes/web.php
@@ -466,28 +466,6 @@ Route::group(
// download config:
Route::get('download/{importJob}', ['uses' => 'Import\IndexController@download', 'as' => 'job.download']);
-
- // import method prerequisites:
- #
- #
- #Route::get('reset/{bank}', ['uses' => 'Import\IndexController@reset', 'as' => 'reset']);
-
- // create the job:
- #Route::get('create/{bank}', ['uses' => 'Import\IndexController@create', 'as' => 'create-job']);
-
- // configure the job:
-
- #Route::post('configure/{importJob}', ['uses' => 'Import\ConfigurationController@post', 'as' => 'configure.post']);
-
- // get status of any job:
- #Route::get('status/{importJob}', ['uses' => 'Import\StatusController@index', 'as' => 'status']);
- #Route::get('json/{importJob}', ['uses' => 'Import\StatusController@json', 'as' => 'status.json']);
-
- // start a job
- #Route::any('start/{importJob}', ['uses' => 'Import\IndexController@start', 'as' => 'start']);
-
- // download config
- #Route::get('download/{importJob}', ['uses' => 'Import\IndexController@download', 'as' => 'download']);
}
);
@@ -632,6 +610,23 @@ Route::group(
}
);
+/**
+ * Recurring Transactions Controller
+ */
+Route::group(
+ ['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers\Recurring', 'prefix' => 'recurring', 'as' => 'recurring.'], function () {
+
+ Route::get('', ['uses' => 'IndexController@index', 'as' => 'index']);
+ Route::get('suggest', ['uses' => 'IndexController@suggest', 'as' => 'suggest']);
+ 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']);
+ Route::get('delete/{recurrence}', ['uses' => 'DeleteController@delete', 'as' => 'delete']);
+
+ Route::post('store', ['uses' => 'CreateController@store', 'as' => 'store']);
+}
+);
+
/**
* Report Controller
*/