diff --git a/app/Providers/ConfigServiceProvider.php b/app/Providers/ConfigServiceProvider.php index 1f55469074..bd01842727 100644 --- a/app/Providers/ConfigServiceProvider.php +++ b/app/Providers/ConfigServiceProvider.php @@ -167,12 +167,13 @@ class ConfigServiceProvider extends ServiceProvider 'Config', 'ExpandedForm' => [ 'is_safe' => [ - 'date', 'text', 'select', 'balance', 'optionsList', 'checkbox', 'amount', 'tags', 'integer' + 'date', 'text', 'select', 'balance', 'optionsList', 'checkbox', 'amount', 'tags', 'integer', 'textarea', 'location', + 'multiRadio' ] ], 'Form' => [ 'is_safe' => [ - 'input', 'select', 'checkbox', 'model', 'open' + 'input', 'select', 'checkbox', 'model', 'open','radio','textarea' ] ], ], diff --git a/app/Support/Twig/General.php b/app/Support/Twig/General.php index ff7851dd66..f5faf71981 100644 --- a/app/Support/Twig/General.php +++ b/app/Support/Twig/General.php @@ -5,6 +5,7 @@ namespace FireflyIII\Support\Twig; use App; use Config; use FireflyIII\Models\Account; +use FireflyIII\Models\Transaction; use Route; use Twig_Extension; use Twig_SimpleFilter; @@ -31,6 +32,13 @@ class General extends Twig_Extension return App::make('amount')->format($string); }, ['is_safe' => ['html']] ); + + $filters[] = new Twig_SimpleFilter( + 'formatTransaction', function (Transaction $transaction) { + return App::make('amount')->formatTransaction($transaction); + }, ['is_safe' => ['html']] + ); + $filters[] = new Twig_SimpleFilter( 'formatAmountPlain', function ($string) { return App::make('amount')->format($string, false); diff --git a/phpunit.xml b/phpunit.xml index 677b0226c7..b1eba9eb5a 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -20,10 +20,11 @@ - + diff --git a/resources/twig/form/location.twig b/resources/twig/form/location.twig new file mode 100644 index 0000000000..efb95bb6c3 --- /dev/null +++ b/resources/twig/form/location.twig @@ -0,0 +1,14 @@ +
+ +
+
+

Right-click to set the tag's location. + Clear location +

+ + + + + {% include 'form/feedback.twig' %} +
+
diff --git a/resources/twig/form/multiRadio.twig b/resources/twig/form/multiRadio.twig new file mode 100644 index 0000000000..b79ff1559c --- /dev/null +++ b/resources/twig/form/multiRadio.twig @@ -0,0 +1,16 @@ +
+ +
+ {% for value,description in list %} +
+ +
+ {% endfor %} + {% include 'form/help.twig' %} + {% include 'form/feedback.twig' %} + +
+
diff --git a/resources/twig/form/textarea.twig b/resources/twig/form/textarea.twig new file mode 100644 index 0000000000..6d1d950a04 --- /dev/null +++ b/resources/twig/form/textarea.twig @@ -0,0 +1,7 @@ +
+ +
+ {{ Form.textarea(name, value, options) }} + {% include 'form/feedback.twig' %} +
+
diff --git a/resources/twig/tags/create.twig b/resources/twig/tags/create.twig new file mode 100644 index 0000000000..ab957ce3bf --- /dev/null +++ b/resources/twig/tags/create.twig @@ -0,0 +1,85 @@ +{% extends "./layout/default.twig" %} +{% block content %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName) }} + {{ Form.open({'class' : 'form-horizontal','id' : 'store','route' : 'tags.store'}) }} + +
+
+
+
+ Mandatory fields +
+
+ {{ ExpandedForm.text('tag') }} + {{ ExpandedForm.multiRadio('tagMode',tagOptions) }} +
+
+
+ +
+ +
+
+ Optional fields +
+
+ {{ ExpandedForm.date('date') }} + {{ ExpandedForm.textarea('description') }} + {{ ExpandedForm.location('tagPosition') }} +
+
+ + +
+
+ Options +
+
+ {{ ExpandedForm.optionsList('create','tag') }} +
+
+ +
+
+
+
+

+ +

+
+
+ + +{% endblock %} +{% block scripts %} + + + +{% endblock %} \ No newline at end of file diff --git a/resources/twig/tags/delete.twig b/resources/twig/tags/delete.twig new file mode 100644 index 0000000000..82ea36f45d --- /dev/null +++ b/resources/twig/tags/delete.twig @@ -0,0 +1,33 @@ +{% extends "./layout/default.twig" %} +{% block content %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, tag) }} + {{ Form.open({'class' : 'form-horizontal','id' : 'destroy','url' : route('tags.destroy',tag.id)}) }} +
+
+
+
+ Delete tag "{{ tag.tag }}" +
+
+

+ Are you sure that you want to delete tag "{{ tag.tag }}"? +

+ + {% if tag.transactionjournals|length > 0 %} +

+ Tag "{{ tag.tag }}" still has {{ tag.transactionjournals|length }} transaction(s) connected + to it. These will not be removed but will lose their connection to this tag. +

+ {% endif %} + +

+ + Cancel +

+
+
+
+
+ + +{% endblock %} diff --git a/resources/twig/tags/edit.twig b/resources/twig/tags/edit.twig new file mode 100644 index 0000000000..85f5e3503f --- /dev/null +++ b/resources/twig/tags/edit.twig @@ -0,0 +1,87 @@ +{% extends "./layout/default.twig" %} +{% block content %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, tag) }} + {{ Form.model(tag, {'class' : 'form-horizontal','id' : 'update','url' : route('tags.update',tag.id)}) }} + + + +
+
+
+
+ Mandatory fields +
+
+ {{ ExpandedForm.text('tag') }} + {{ ExpandedForm.multiRadio('tagMode',tagOptions) }} +
+
+
+ +
+ +
+
+ Optional fields +
+
+ {{ ExpandedForm.date('date') }} + {{ ExpandedForm.textarea('description') }} + {{ ExpandedForm.location('tagPosition') }} +
+
+ + +
+
+ Options +
+
+ {{ ExpandedForm.optionsList('update','tag') }} +
+
+ +
+
+
+
+

+ +

+
+
+ + +{% endblock %} +{% block scripts %} + + + +{% endblock %} \ No newline at end of file diff --git a/resources/twig/tags/index.twig b/resources/twig/tags/index.twig new file mode 100644 index 0000000000..9b520969a5 --- /dev/null +++ b/resources/twig/tags/index.twig @@ -0,0 +1,75 @@ +{% extends "./layout/default.twig" %} +{% block content %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName) }} +
+
+
+
Tags
+
+
+

+ Usually tags are singular words, designed to quickly band items together + using things like expensive, + bill or + for-party. In Firefly III, tags can have more properties + such as a date, description and location. This allows you to join transactions together in a more meaningful + way. For example, you could make a tag called Christmas dinner with friends + and add information about the restaurant. Such tags are "singular", you would only use them for a single occasion, + perhaps with multiple transactions. +

+

+ Tags group transactions together, which makes it possible to store reimbursements + (in case you front money for others) and other "balancing acts" where expenses + are summed up (the payments on your new TV) or where expenses and deposits + are cancelling each other out (buying something with saved money). It's all up to you. + Using tags the old-fashioned way is of course always possible. +

+

+ Create a tag to get started or enter tags when creating new transactions. +

+
+

+ +

+

+ Create new tag +

+

+ {% if tags|length == 0 %} + No tags + {% else %} + {% for tag in tags %} + +

+ {% if tag.tagMode == 'nothing' %} + + {% endif %} + {% if tag.tagMode == 'balancingAct' %} + + {% endif %} + {% if tag.tagMode == 'advancePayment' %} + + {% endif %} + {{tag.tag}} +

+ {% endfor %} + {% endif %} +

+
+
+
+
+{% endblock %} +{% block scripts %} + +{% endblock %} \ No newline at end of file diff --git a/resources/twig/tags/show.twig b/resources/twig/tags/show.twig new file mode 100644 index 0000000000..ae61d5b587 --- /dev/null +++ b/resources/twig/tags/show.twig @@ -0,0 +1,77 @@ +{% extends "./layout/default.twig" %} +{% block content %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, tag) }} + + {% if tag.latitude and tag.longitude and tag.zoomLevel %} +
+
+
+
+ {{ tag.tag }} + {% if tag.date %} + on {{tag.date.format('jS F Y')}} + {% endif %} + +
+
+ + +
+
+
+
+ {% if tag.description %} +

+ {{tag.description}} +

+ {% endif %} + {% if tag.latitude and tag.longitude and tag.zoomLevel %} +

+ +

+ {% endif %} +
+
+
+
+ {% endif %} + +
+
+
+
+ Transactions + + {% if not (tag.latitude and tag.longitude and tag.zoomLevel) %} + +
+
+ + +
+
+ {% endif %} +
+ {% include 'list/journals.twig' with {'journals': tag.transactionjournals} %} +
+
+
+ +{% endblock %} +{% block scripts %} + +{% endblock %} diff --git a/resources/twig/transactions/create.twig b/resources/twig/transactions/create.twig new file mode 100644 index 0000000000..01ef307391 --- /dev/null +++ b/resources/twig/transactions/create.twig @@ -0,0 +1,107 @@ +{% extends "./layout/default.twig" %} +{% block content %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, what) }} + {{ Form.open({'class' : 'form-horizontal','id' : 'store','url' : route('transactions.store',what)}) }} + + +
+
+ +
+
+ Mandatory fields +
+
+ + {{ ExpandedForm.text('description') }} + {% if what == 'deposit' or what == 'withdrawal' %} + {{ ExpandedForm.select('account_id',accounts) }} + {% endif %} + + + + {% if what == 'withdrawal' %} + {{ ExpandedForm.text('expense_account') }} + {% endif %} + + + {% if what == 'deposit' %} + {{ ExpandedForm.text('revenue_account') }} + {% endif %} + + + + {% if what == 'transfer' %} + {{ ExpandedForm.select('account_from_id',accounts) }} + {{ ExpandedForm.select('account_to_id',accounts) }} + {% endif %} + + + + {{ ExpandedForm.amount('amount') }} + + + {{ ExpandedForm.date('date', phpdate('Y-m-d')) }} +
+
+
+
+ +
+
+ Optional fields +
+
+ + {% if what == 'withdrawal' %} + {{ ExpandedForm.select('budget_id',budgets,0) }} + {% endif %} + + {{ ExpandedForm.text('category') }} + + + {{ ExpandedForm.text('tags') }} + + + + {% if what == 'withdrawal' and piggies|length > 0 %} + {{ ExpandedForm.select('piggy_bank_id',piggies) }} + {% endif %} +
+
+ + +
+
+ Options +
+
+ {{ ExpandedForm.optionsList('create','transaction') }} +
+
+
+
+
+
+

+ +

+
+
+ + +{% endblock %} +{% block scripts %} + + + + +{% endblock %} + +{% block styles %} + +{% endblock %} diff --git a/resources/twig/transactions/delete.twig b/resources/twig/transactions/delete.twig new file mode 100644 index 0000000000..b10a9a83a0 --- /dev/null +++ b/resources/twig/transactions/delete.twig @@ -0,0 +1,43 @@ +{% extends "./layout/default.twig" %} +{% block content %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, journal) }} + {{ Form.open({'class' : 'form-horizontal','id' : 'destroy','url' : route('transactions.destroy',journal.id)}) }} + +
+
+ +
+
+ Destroy "{{ journal.description }}" +
+
+

+ Deleting stuff from Firefly is permanent. This action will remove the transaction and all + associated data. +

+

+ This action will not destroy categories, piggy banks, accounts, etc. +

+

+ Are you sure? +

+
+ + {% if journal.transactiontype.type == 'Withdrawal' %} + Cancel + {% endif %} + {% if journal.transactiontype.type == 'Deposit' %} + Cancel + {% endif %} + {% if journal.transactiontype.type == 'Transfer' %} + Cancel + {% endif %} +
+
+
+
+
+ + + +{% endblock %} diff --git a/resources/twig/transactions/edit.twig b/resources/twig/transactions/edit.twig new file mode 100644 index 0000000000..5ac5f371bd --- /dev/null +++ b/resources/twig/transactions/edit.twig @@ -0,0 +1,111 @@ +{% extends "./layout/default.twig" %} +{% block content %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, journal) }} + {{ Form.open({'class' : 'form-horizontal','id' : 'update','url' : route('transactions.update',journal.id)}) }} + + + + +
+
+ +
+
+ Mandatory fields +
+
+ + {{ ExpandedForm.text('description',journal.description) }} + + + {% if what == 'deposit' or what == 'withdrawal' %} + {{ ExpandedForm.select('account_id',accounts,data['account_id']) }} + {% endif %} + + + {% if what == 'withdrawal' %} + {{ ExpandedForm.text('expense_account',data['expense_account']) }} + {% endif %} + + + {% if what == 'deposit' %} + {{ ExpandedForm.text('revenue_account',data['revenue_account']) }} + {% endif %} + + + {% if what == 'transfer' %} + {{ ExpandedForm.select('account_from_id',accounts,data['account_from_id']) }} + {{ ExpandedForm.select('account_to_id',accounts,data['account_to_id']) }} + {% endif %} + + + {{ ExpandedForm.amount('amount',data.amount,{'currency' : journal.transactionCurrency}) }} + + + {{ ExpandedForm.date('date',data['date']) }} +
+
+ +
+
+ +
+
+ Optional fields +
+
+ + {% if what == 'withdrawal' %} + {{ ExpandedForm.select('budget_id',budgets,data['budget_id']) }} + {% endif %} + + + {{ ExpandedForm.text('category',data['category']) }} + + + {{ ExpandedForm.text('tags') }} + + + {% if what == 'withdrawal' and piggies|length > 0 %} + {{ ExpandedForm.select('piggy_bank_id',piggies,data['piggy_bank_id']) }} + {% endif %} + +
+
+ + +
+
+ Options +
+
+ {{ ExpandedForm.optionsList('update','transaction') }} +
+
+
+
+ +
+
+

+ +

+
+
+ + + +{% endblock %} +{% block scripts %} + + + + +{% endblock %} +{% block styles %} + +{% endblock %} diff --git a/resources/twig/transactions/index.twig b/resources/twig/transactions/index.twig new file mode 100644 index 0000000000..25b11854a9 --- /dev/null +++ b/resources/twig/transactions/index.twig @@ -0,0 +1,19 @@ +{% extends "./layout/default.twig" %} +{% block content %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, what) }} +
+
+
+
+ {{ subTitle }} +
+ {% include 'list.journals' %} +
+
+
+ +{% endblock %} +{% block scripts %} + + +{% endblock %} diff --git a/resources/twig/transactions/show.twig b/resources/twig/transactions/show.twig new file mode 100644 index 0000000000..7c58bed910 --- /dev/null +++ b/resources/twig/transactions/show.twig @@ -0,0 +1,133 @@ +{% extends "./layout/default.twig" %} +{% block content %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, journal) }} +
+
+
+
+ + Metadata +
+ + + + + + + + + + + + + + {% for budget in journal.budgets %} + + + + + {% endfor %} + {% for category in journal.categories %} + + + + + {% endfor %} + {% if journal.tags|length > 0 %} + + + + + {% endif %} +
Date{{ journal.date.format('jS F Y') }}
Type{{ journal.transactiontype.type }}
Completed + {% if journal.completed %} + Yes + {% else %} + No + {% endif %} +
Budget{{ budget.name }}
Category{{ category.name }}
Tags + {% for tag in journal.tags %} + +

+ {% if tag.tagMode == 'nothing' %} + + {% endif %} + {% if tag.tagMode == 'balancingAct' %} + + {% endif %} + {% if tag.tagMode == 'advancePayment' %} + + {% endif %} + {{tag.tag}} +

+ {% endfor %} +
+
+ + {% if journal.piggyBankEvents|length > 0 %} +
+
+ Piggy banks +
+
+ {% include 'list/piggy-bank-events' with {'events': journal.piggyBankEvents, 'showPiggyBank':true} %} +
+
+ {% endif %} +
+
+ + {% for t in journal.transactions %} +
+
+ {% if t.account.accounttype.type == 'Asset account' %} + + {% endif %} + {% if t.account.accounttype.type == 'Default account' %} + + {% endif %} + {% if t.account.accounttype.type == 'Expense account' %} + + {% endif %} + {% if t.account.accounttype.type == 'Beneficiary account' %} + + {% endif %} + + {% if t.account.accounttype.type == 'Revenue account' %} + + {% endif %} + {{ t.account.name }}
{{ t.account.accounttype.description }} +
+ + + + + + + + + + {% if t.description %} + + + + + {% endif %} +
Amount{{ t|formatTransaction }}
New balance{{ t.before|formatAmount }} → {{ t.after|formatAmount }}
Description{{ t.description }}
+
+ {% endfor %} +
+
+ +
+
+ +
+
+ +{% endblock %} +{% block scripts %} + +{% endblock %}