+ | 'Form' => [
+ | 'is_safe' => [
+ | 'open'
+ | ]
+ | ]
+ |
+ |
+ | The values of the `is_safe` array must match the called method on the facade
+ | in order to be marked as safe.
+ |
+ */
+ 'facades' => [
+ 'Breadcrumbs' => [
+ 'is_safe' => [
+ 'renderIfExists'
+ ]
+ ],
+ 'Session',
+ 'Route',
+ 'Auth',
+ 'URL',
+ 'Config',
+ 'ExpandedForm' => [
+ 'is_safe' => [
+ 'date', 'text', 'select', 'balance', 'optionsList', 'checkbox', 'amount', 'tags', 'integer', 'textarea', 'location',
+ 'multiRadio'
+ ]
+ ],
+ 'Form' => [
+ 'is_safe' => [
+ 'input', 'select', 'checkbox', 'model', 'open','radio','textarea'
+ ]
+ ],
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Functions
+ |--------------------------------------------------------------------------
+ |
+ | Available functions. Access like `{{ secure_url(...) }}`.
+ |
+ | Each function can take an optional array of options. These options are
+ | passed directly to `Twig_SimpleFunction`.
+ |
+ | So for example, to mark a function as safe you can do the following:
+ |
+ |
+ | 'link_to' => [
+ | 'is_safe' => ['html']
+ | ]
+ |
+ |
+ | The options array also takes a `callback` that allows you to name the
+ | function differently in your Twig templates than what it's actually called.
+ |
+ |
+ | 'link' => [
+ | 'callback' => 'link_to'
+ | ]
+ |
+ |
+ */
+ 'functions' => [
+ 'elixir',
+ 'head',
+ 'last',
+ 'old'
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Filters
+ |--------------------------------------------------------------------------
+ |
+ | Available filters. Access like `{{ variable|filter }}`.
+ |
+ | Each filter can take an optional array of options. These options are
+ | passed directly to `Twig_SimpleFilter`.
+ |
+ | So for example, to mark a filter as safe you can do the following:
+ |
+ |
+ | 'studly_case' => [
+ | 'is_safe' => ['html']
+ | ]
+ |
+ |
+ | The options array also takes a `callback` that allows you to name the
+ | filter differently in your Twig templates than what is actually called.
+ |
+ |
+ | 'snake' => [
+ | 'callback' => 'snake_case'
+ | ]
+ |
+ |
+ */
+ 'filters' => [],
+ ],
+ ]
]
);
}
diff --git a/app/Providers/FireflyServiceProvider.php b/app/Providers/FireflyServiceProvider.php
index 542475d282..eaecd56528 100644
--- a/app/Providers/FireflyServiceProvider.php
+++ b/app/Providers/FireflyServiceProvider.php
@@ -2,13 +2,21 @@
namespace FireflyIII\Providers;
+use App;
+use FireflyIII\Models\Account;
use FireflyIII\Support\Amount;
use FireflyIII\Support\ExpandedForm;
use FireflyIII\Support\Navigation;
use FireflyIII\Support\Preferences;
use FireflyIII\Support\Steam;
+use FireflyIII\Support\Twig\Budget;
+use FireflyIII\Support\Twig\General;
+use FireflyIII\Support\Twig\Journal;
+use FireflyIII\Support\Twig\PiggyBank;
use FireflyIII\Validation\FireflyValidator;
use Illuminate\Support\ServiceProvider;
+use Twig;
+use TwigBridge\Extension\Loader\Functions;
use Validator;
/**
@@ -25,10 +33,22 @@ class FireflyServiceProvider extends ServiceProvider
return new FireflyValidator($translator, $data, $rules, $messages);
}
);
+ /*
+ * Default Twig configuration:
+ */
+
+ $config = App::make('config');
+ Twig::addExtension(new Functions($config));
+ Twig::addExtension(new PiggyBank);
+ Twig::addExtension(new General);
+ Twig::addExtension(new Journal);
+ Twig::addExtension(new Budget);
}
public function register()
{
+
+
$this->app->bind(
'preferences', function () {
return new Preferences;
@@ -72,6 +92,7 @@ class FireflyServiceProvider extends ServiceProvider
$this->app->bind('FireflyIII\Helpers\Report\ReportHelperInterface', 'FireflyIII\Helpers\Report\ReportHelper');
$this->app->bind('FireflyIII\Helpers\Report\ReportQueryInterface', 'FireflyIII\Helpers\Report\ReportQuery');
+
}
}
diff --git a/app/Support/Amount.php b/app/Support/Amount.php
index aed7c6bfcb..db7aecb52c 100644
--- a/app/Support/Amount.php
+++ b/app/Support/Amount.php
@@ -160,12 +160,15 @@ class Amount
$currencyPreference = Prefs::get('currencyPreference', 'EUR');
$currency = TransactionCurrency::whereCode($currencyPreference->data)->first();
+ if ($currency) {
- \Cache::forever('FFCURRENCYCODE', $currency->code);
+ Cache::forever('FFCURRENCYCODE', $currency->code);
+ define('FFCURRENCYCODE', $currency->code);
- define('FFCURRENCYCODE', $currency->code);
+ return $currency->code;
+ }
- return $currency->code;
+ return 'EUR';
}
public function getDefaultCurrency()
diff --git a/app/Support/Twig/Budget.php b/app/Support/Twig/Budget.php
new file mode 100644
index 0000000000..39ec2a1e04
--- /dev/null
+++ b/app/Support/Twig/Budget.php
@@ -0,0 +1,53 @@
+leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
+ ->leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budget_transaction_journal.budget_id')
+ ->leftJoin('limit_repetitions', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
+ ->where('transaction_journals.date', '>=', $repetition->startdate->format('Y-m-d'))
+ ->where('transaction_journals.date', '<=', $repetition->enddate->format('Y-m-d'))
+ ->where('transaction_journals.user_id', Auth::user()->id)
+ ->whereNull('transactions.deleted_at')
+ ->where('transactions.amount', '>', 0)
+ ->where('limit_repetitions.id', '=', $repetition->id)
+ ->sum('transactions.amount');
+
+ return floatval($sum);
+ }
+ );
+
+ return $functions;
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getName()
+ {
+ return 'FireflyIII\Support\Twig\Budget';
+ }
+}
\ No newline at end of file
diff --git a/app/Support/Twig/General.php b/app/Support/Twig/General.php
new file mode 100644
index 0000000000..f5faf71981
--- /dev/null
+++ b/app/Support/Twig/General.php
@@ -0,0 +1,146 @@
+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);
+ }
+ );
+
+ $filters[] = new Twig_SimpleFilter(
+ 'formatJournal', function ($journal) {
+ return App::make('amount')->formatJournal($journal);
+ }, ['is_safe' => ['html']]
+ );
+
+ $filters[] = new Twig_SimpleFilter(
+ 'balance', function (Account $account = null) {
+ if (is_null($account)) {
+ return 'NULL';
+ }
+
+ return App::make('steam')->balance($account);
+ }
+ );
+
+ // should be a function but OK
+ $filters[] = new Twig_SimpleFilter(
+ 'getAccountRole', function ($name) {
+ return Config::get('firefly.accountRoles.' . $name);
+ }
+ );
+
+ return $filters;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getFunctions()
+ {
+ $functions = [];
+
+ $functions[] = new Twig_SimpleFunction(
+ 'getCurrencyCode', function () {
+ return App::make('amount')->getCurrencyCode();
+ }
+ );
+
+ $functions[] = new Twig_SimpleFunction(
+ 'getCurrencySymbol', function () {
+ return App::make('amount')->getCurrencySymbol();
+ }
+ );
+
+ $functions[] = new Twig_SimpleFunction(
+ 'phpdate', function ($str) {
+ return date($str);
+ }
+ );
+
+
+ $functions[] = new Twig_SimpleFunction(
+ 'env', function ($name, $default) {
+ return env($name, $default);
+ }
+ );
+
+ $functions[] = new Twig_SimpleFunction(
+ 'activeRoute', function ($context) {
+ $args = func_get_args();
+ $route = $args[1];
+ $what = isset($args[2]) ? $args[2] : false;
+ $strict = isset($args[3]) ? $args[3] : false;
+ $activeWhat = isset($context['what']) ? $context['what'] : false;
+
+ // activeRoute
+ if (!($what === false)) {
+ if ($what == $activeWhat && Route::getCurrentRoute()->getName() == $route) {
+ return 'active because-active-what';
+ }
+ } else {
+ if (!$strict && !(strpos(Route::getCurrentRoute()->getName(), $route) === false)) {
+ return 'active because-route-matches-non-strict';
+ } else {
+ if ($strict && Route::getCurrentRoute()->getName() == $route) {
+ return 'active because-route-matches-strict';
+ }
+ }
+ }
+
+ return 'not-xxx-at-all';
+ }, ['needs_context' => true]
+ );
+
+ return $functions;
+
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getName()
+ {
+ return 'FireflyIII\Support\Twig\General';
+ }
+
+}
\ No newline at end of file
diff --git a/app/Support/Twig/Journal.php b/app/Support/Twig/Journal.php
new file mode 100644
index 0000000000..2b1be12e9f
--- /dev/null
+++ b/app/Support/Twig/Journal.php
@@ -0,0 +1,78 @@
+transactionType->type;
+ if ($type == 'Withdrawal') {
+ return '';
+ }
+ if ($type == 'Deposit') {
+ return '';
+ }
+ if ($type == 'Transfer') {
+ return '';
+ }
+ if ($type == 'Opening balance') {
+ return '';
+ }
+
+
+ }, ['is_safe' => ['html']]
+ );
+
+ return $filters;
+ }
+
+ public function getFunctions()
+ {
+ $functions = [];
+
+ $functions[] = new Twig_SimpleFunction(
+ 'invalidJournal', function (TransactionJournal $journal) {
+ if (!isset($journal->transactions[1]) || !isset($journal->transactions[0])) {
+ return true;
+ }
+
+ return false;
+ }
+ );
+
+ $functions[] = new Twig_SimpleFunction(
+ 'relevantTags', function (TransactionJournal $journal) {
+ return 'TODO'.$journal->amount;
+ }
+ );
+
+ return $functions;
+ }
+
+ /**
+ * Returns the name of the extension.
+ *
+ * @return string The extension name
+ */
+ public function getName()
+ {
+ return 'FireflyIII\Support\Twig\Journals';
+ }
+}
\ No newline at end of file
diff --git a/app/Support/Twig/PiggyBank.php b/app/Support/Twig/PiggyBank.php
new file mode 100644
index 0000000000..4d289a4b43
--- /dev/null
+++ b/app/Support/Twig/PiggyBank.php
@@ -0,0 +1,41 @@
+currentRelevantRep()->currentamount;
+ }
+ );
+ return $functions;
+ }
+
+ /**
+ * Returns the name of the extension.
+ *
+ * @return string The extension name
+ */
+ public function getName()
+ {
+ return 'FireflyIII\Support\Twig\PiggyBank';
+ }
+}
\ No newline at end of file
diff --git a/app/Validation/FireflyValidator.php b/app/Validation/FireflyValidator.php
index b886074aa9..b8cf753024 100644
--- a/app/Validation/FireflyValidator.php
+++ b/app/Validation/FireflyValidator.php
@@ -13,6 +13,7 @@ use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Validation\Validator;
use Log;
use Navigation;
+use Symfony\Component\Translation\TranslatorInterface;
/**
* Class FireflyValidator
@@ -22,6 +23,18 @@ use Navigation;
class FireflyValidator extends Validator
{
+ /**
+ * @param TranslatorInterface $translator
+ * @param array $data
+ * @param array $rules
+ * @param array $messages
+ * @param array $customAttributes
+ */
+ public function __construct(TranslatorInterface $translator, array $data, array $rules, array $messages = [], array $customAttributes = [])
+ {
+ parent::__construct($translator, $data, $rules, $messages);
+ }
+
/**
* @param $attribute
* @param $value
diff --git a/bootstrap/app.php b/bootstrap/app.php
index e3ec5b5519..5b299a9c83 100644
--- a/bootstrap/app.php
+++ b/bootstrap/app.php
@@ -11,6 +11,7 @@
|
*/
+
$app = new Illuminate\Foundation\Application(
realpath(__DIR__ . '/../')
);
@@ -26,6 +27,8 @@ $app = new Illuminate\Foundation\Application(
|
*/
+
+
$app->singleton(
'Illuminate\Contracts\Http\Kernel',
'FireflyIII\Http\Kernel'
@@ -41,6 +44,9 @@ $app->singleton(
'FireflyIII\Exceptions\Handler'
);
+
+
+
/*
|--------------------------------------------------------------------------
| Return The Application
diff --git a/composer.json b/composer.json
index c9459d4f3f..5bbf617f3b 100644
--- a/composer.json
+++ b/composer.json
@@ -26,7 +26,9 @@
"watson/validating": "~1.0",
"doctrine/dbal": "~2.5",
"illuminate/html": "~5.0",
- "league/commonmark": "0.7.*"
+ "league/commonmark": "0.7.*",
+ "rcrowe/twigbridge": "0.7.x@dev",
+ "twig/extensions": "~1.2"
},
"require-dev": {
"barryvdh/laravel-debugbar": "@stable",
diff --git a/composer.lock b/composer.lock
index 394312ec5e..bce1a9507c 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "0d43c4c85607c5cdc901cde2d18b75d5",
+ "hash": "e3e90dd365b74f4878cf3b5b4a1c4007",
"packages": [
{
"name": "classpreloader/classpreloader",
@@ -1527,6 +1527,70 @@
],
"time": "2015-03-26 18:43:54"
},
+ {
+ "name": "rcrowe/twigbridge",
+ "version": "0.7.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/rcrowe/TwigBridge.git",
+ "reference": "ac0bfb5bcdb4fcd0cd01ab8425620ff07f6af026"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/rcrowe/TwigBridge/zipball/ac0bfb5bcdb4fcd0cd01ab8425620ff07f6af026",
+ "reference": "ac0bfb5bcdb4fcd0cd01ab8425620ff07f6af026",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/support": "5.0.*",
+ "illuminate/view": "5.0.*",
+ "php": ">=5.4.0",
+ "twig/twig": "~1.15"
+ },
+ "require-dev": {
+ "laravel/framework": "5.0.*",
+ "mockery/mockery": "0.9.*",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "~0.6",
+ "squizlabs/php_codesniffer": "~1.5"
+ },
+ "suggest": {
+ "laravelcollective/html": "For bringing back html/form in Laravel 5.x",
+ "twig/extensions": "~1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.7-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "TwigBridge\\": "src",
+ "TwigBridge\\Tests\\": "tests"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Barry vd. Heuvel",
+ "email": "barryvdh@gmail.com"
+ },
+ {
+ "name": "Rob Crowe",
+ "email": "hello@vivalacrowe.com"
+ }
+ ],
+ "description": "Adds the power of Twig to Laravel",
+ "keywords": [
+ "laravel",
+ "twig"
+ ],
+ "time": "2015-04-22 09:19:03"
+ },
{
"name": "swiftmailer/swiftmailer",
"version": "v5.4.0",
@@ -2291,6 +2355,115 @@
],
"time": "2015-03-31 08:12:29"
},
+ {
+ "name": "twig/extensions",
+ "version": "v1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/Twig-extensions.git",
+ "reference": "8cf4b9fe04077bd54fc73f4fde83347040c3b8cd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/Twig-extensions/zipball/8cf4b9fe04077bd54fc73f4fde83347040c3b8cd",
+ "reference": "8cf4b9fe04077bd54fc73f4fde83347040c3b8cd",
+ "shasum": ""
+ },
+ "require": {
+ "twig/twig": "~1.12"
+ },
+ "require-dev": {
+ "symfony/translation": "~2.3"
+ },
+ "suggest": {
+ "symfony/translation": "Allow the time_diff output to be translated"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Twig_Extensions_": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Common additional features for Twig that do not directly belong in core",
+ "homepage": "http://twig.sensiolabs.org/doc/extensions/index.html",
+ "keywords": [
+ "i18n",
+ "text"
+ ],
+ "time": "2014-10-30 14:30:03"
+ },
+ {
+ "name": "twig/twig",
+ "version": "v1.18.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/Twig.git",
+ "reference": "9f70492f44398e276d1b81c1b43adfe6751c7b7f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/9f70492f44398e276d1b81c1b43adfe6751c7b7f",
+ "reference": "9f70492f44398e276d1b81c1b43adfe6751c7b7f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.7"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.18-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Twig_": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
+ },
+ {
+ "name": "Twig Team",
+ "homepage": "http://twig.sensiolabs.org/contributors",
+ "role": "Contributors"
+ }
+ ],
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "homepage": "http://twig.sensiolabs.org",
+ "keywords": [
+ "templating"
+ ],
+ "time": "2015-04-19 08:30:27"
+ },
{
"name": "vlucas/phpdotenv",
"version": "v1.1.0",
@@ -4179,6 +4352,7 @@
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
+ "rcrowe/twigbridge": 20,
"barryvdh/laravel-debugbar": 0
},
"prefer-stable": false,
diff --git a/config/app.php b/config/app.php
index 17bf91779e..f0b8a7a614 100644
--- a/config/app.php
+++ b/config/app.php
@@ -136,11 +136,12 @@ return [
'Illuminate\Validation\ValidationServiceProvider',
'Illuminate\View\ViewServiceProvider',
'Illuminate\Html\HtmlServiceProvider',
+ 'TwigBridge\ServiceProvider',
+
'DaveJamesMiller\Breadcrumbs\ServiceProvider',
'Barryvdh\Debugbar\ServiceProvider',
'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
-
/*
* Application Service Providers...
*/
@@ -152,6 +153,7 @@ return [
'FireflyIII\Providers\FireflyServiceProvider',
'FireflyIII\Providers\TestingServiceProvider',
+
],
/*
@@ -201,13 +203,14 @@ return [
'View' => 'Illuminate\Support\Facades\View',
'Form' => 'Illuminate\Html\FormFacade',
'Html' => 'Illuminate\Html\HtmlFacade',
- 'Breadcrumbs' => 'DaveJamesMiller\Breadcrumbs\Facade',
-
+ 'Breadcrumbs' => 'DaveJamesMiller\Breadcrumbs\Facade',
'Preferences' => 'FireflyIII\Support\Facades\Preferences',
'Navigation' => 'FireflyIII\Support\Facades\Navigation',
'Amount' => 'FireflyIII\Support\Facades\Amount',
'Steam' => 'FireflyIII\Support\Facades\Steam',
'ExpandedForm' => 'FireflyIII\Support\Facades\ExpandedForm',
+ 'Twig' => 'TwigBridge\Facade\Twig',
+
],
diff --git a/config/view.php b/config/view.php
index 88fc534aeb..6e1a698a10 100644
--- a/config/view.php
+++ b/config/view.php
@@ -14,7 +14,7 @@ return [
*/
'paths' => [
- realpath(base_path('resources/views'))
+ realpath(base_path('resources/twig'))
],
/*
diff --git a/phpunit.xml b/phpunit.xml
index 677b0226c7..bf13ff1240 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -7,7 +7,7 @@
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
- stopOnFailure="false"
+ stopOnFailure="true"
syntaxCheck="false">
+ Are you sure that you want to delete the {{account.accountType.type|lower}} "{{account.name}}"? +
+ + {% if account.transactions|length > 0 %} ++ {{account.accountType.type|capitalize}} "{{ account.name }}" still has {{ account.transactions|length }} transaction(s) associated to it. These will be deleted as well. +
+ {% endif %} + {% if account.piggyBanks|length > 0 %} ++ {{account.accountType.type|capitalize}} "{{ account.name }}" still has {{ account.piggyBanks|length }} piggy bank(s) associated to it. These will be deleted as well. +
+ {% endif %} ++ + Cancel +
++ +
++ Registering an account on Firefly requires an e-mail address. +
+ {% if errors|length > 0 %} ++ +
++ Are you sure that you want to delete bill "{{ bill.name }}"? +
+ + {% if bill.transactionjournals|length > 0 %} ++ Bill "{{ bill.name }}" still has {{ bill.transactionjournals|length }} transactions connected + to it. These will not be removed but will lose their connection to this bill. +
+ {% endif %} + ++ + Cancel +
++ +
++ Matching on + {% for word in bill.match|split(',') %} + {{ word }} + {% endfor %} + between {{ bill.amount_min|formatAmount }} and {{ bill.amount_max|formatAmount }}. + Repeats {{ bill.repeat_freq }}. | + +|
Next expected match | ++ {% if bill.nextExpectedMatch %} + {{bill.nextExpectedMatch.format('j F Y')}} + {% else %} + Unknown + {% endif %} + | +
+ +
++ Are you sure that you want to delete budget "{{ budget.name }}"? +
+ + {% if budget.transactionjournals|length > 0 %} ++ Budget "{{ budget.name }}" still has {{ budget.transactionjournals|length }} transactions connected + to it. These will not be removed but will lose their connection to this budget. +
+ {% endif %} + ++ + Cancel +
+Use budgets to organize and limit your expenses.
++ +
++ {% if budget.currentRep %} + + {% else %} + + {% endif %} +
+ ++ + + {% if budget.currentRep %} + + Budgeted: + + + {% if budget.currentRep.amount > budget.spent %} + {{ getCurrencySymbol() }} + {% else %} + {{ getCurrencySymbol() }} + {% endif %} + + {% else %} + No budget + + + {% endif %} + + +
+ ++ Spent: {{ budget.spent|formatAmount }} +
++ +
++ Are you sure that you want to delete category "{{ category.name }}"? +
+ + {% if category.transactionjournals|length > 0 %} ++ Category "{{ category.name }}" still has {{ category.transactionjournals|length }} transactions connected + to it. These will not be removed but will lose their connection to this category. +
+ {% endif %} + ++ + Cancel +
++ +
++ +
++ Are you sure that you want to delete currency "{{ currency.name }}"? +
++ + Cancel +
++ +
++ Firefly III supports various currencies which you can set and enable here. +
++ | Currency | +|
---|---|---|
+ + | +{{ currency.name }} ({{ currency.code }}) ({{ currency.symbol|raw }}) | ++ {% if currency.id == defaultCurrency.id %} + default + {% else %} + make default + {% endif %} + | +
{{ errors.first(name) }}
+{% endif %} diff --git a/resources/twig/form/help.twig b/resources/twig/form/help.twig new file mode 100644 index 0000000000..e1e2d011ea --- /dev/null +++ b/resources/twig/form/help.twig @@ -0,0 +1,3 @@ +{% if options.helpText %} +{{ options.helpText }}
+{% endif %} diff --git a/resources/twig/form/integer.twig b/resources/twig/form/integer.twig new file mode 100644 index 0000000000..527a5b2fea --- /dev/null +++ b/resources/twig/form/integer.twig @@ -0,0 +1,9 @@ +Right-click to set the tag's location. + Clear location +
+ + + + + {% include 'form/feedback.twig' %} +Welcome to Firefly III.
+ ++ Create a new asset account to get started. +
+Mark your asset accounts as "Savings account" to fill this panel.
+ {% else %} + {% for account in savings %} + +Create piggy banks to fill this panel.
+ {% else %} + {% for account in piggyBankAccounts %} ++ | Name | + {% if what == 'asset' %} +Role | + {% endif %} +Current balance | +Active | +Last activity | +Balance difference between {{ Session.get('start').format('jS F Y') }} and {{ Session.get('end').format('jS F Y') }} | +|
---|---|---|---|---|---|---|---|
+ + | +{{ account.name }} | + {% if what == "asset" %} ++ {% for entry in account.accountmeta %} + {% if entry.name == 'accountRole' %} + {{ entry.data|getAccountRole }} + {% endif %} + {% endfor %} + | + {% endif %} +{{ account|balance|formatAmount }} | ++ {% if account.active %} + + {% else %} + + {% endif %} + | + {% if account.lastActivityDate %} ++ {{ account.lastActivityDate.format('j F Y') }} + | + {% else %} ++ Never + | + {% endif %} ++ {{ (account.endBalance - account.startBalance)|formatAmount }} + | + +
+ | Name | +Matches on | +Matching amount | +Last seen match | +Next expected match | +Is active | +Will be automatched | +Repeats every | ++ | |
---|---|---|---|---|---|---|---|---|---|---|
+ + | ++ {{ entry.name }} + | ++ {% for match in entry.match|split(',') %} + {{ match }} + {% endfor %} + | ++ {{ entry.amount_min|formatAmount }} + | ++ {{ entry.amount_max|formatAmount }} + | ++ {% if entry.lastFoundMatch %} + {{entry.lastFoundMatch.format('j F Y')}} + {% else %} + Unknown + {% endif %} + | ++ {% if entry.nextExpectedMatch%} + {{entry.nextExpectedMatch.format('j F Y')}} + {% else %} + Unknown + {% endif %} + | ++ {% if entry.active %} + + {% else %} + + {% endif %} + | ++ {% if entry.automatch %} + + {% else %} + + {% endif %} + | ++ {{ entry.repeat_freq }} + {% if entry.skip > 0 %} + skips over {{entry.skip}} + {% endif %} + | ++ {% if entry.active %} + + {% endif %} + | +
+ | Name | +Last activity | +|
---|---|---|---|
+ | Without a category | ++ | |
+ + | ++ {{ category.name }} + | + {% if category.lastActivity %} ++ {{category.lastActivity.format('jS F Y') }} + | + {% else %} ++ Never + | + {% endif %} +
+ | Description | +Amount | +Date | +From | +To | + + {% if not hideBudgets %} ++ {% endif %} + + + {% if not hideCategories %} + | + {% endif %} + + + {% if not hideBills %} + | + {% endif %} + | |
---|---|---|---|---|---|---|---|---|---|
+ + | ++ | {{ journal.description }} | +Invalid journal: Found {{journal.transactions|length }} transaction(s) | +||||||
+ + | + ++ {{ journal|typeIcon }} + | ++ {{journal.description}} + | ++ {% if not hideTags %} + {{ relevantTags(journal) }} + {% else %} + {{ journal|formatJournal }} + {% endif %} + | ++ {{journal.date.format('j F Y')}} + | ++ {% if journal.transactions[0].account.accountType.type == 'Cash account' %} + (cash) + {% else %} + {{journal.transactions[0].account.name}} + {% endif %} + | ++ {% if journal.transactions[1].account.accountType.type == 'Cash account' %} + (cash) + {% else %} + {{journal.transactions[1].account.name}} + {% endif %} + | + + + {% if not hideBudgets %} ++ {% if journal.budgets[0] %} + {{journal.budgets[0].name}} + {% endif %} + | + {% endif %} + + + {% if not hideCategories %} ++ {% if journal.categories[0] %} + {{journal.categories[0].name}} + {% endif %} + | + {% endif %} + + + {% if not hideBills %} ++ {% if journal.bill %} + {{journal.bill.name}} + {% endif %} + | + {% endif %} +
Piggy bank | + {% endif %} +Date | +Amount | +
---|---|---|
+ {{ event.piggyBank.name }} + | + {% endif %} ++ {% if event.transaction_journal_id %} + {{ event.date.format('j F Y') }} + {% else %} + {{ event.date.format('j F Y') }} + {% endif %} + | + ++ {% if event.amount < 0 %} + Removed {{ event.amount*-1|formatAmountPlain }} + {% else %} + Added {{ event.amount|formatAmountPlain }} + {% endif %} + | +
+ + + | ++ + | ++ {{ piggyBank.name }} + | ++ {{piggyBank.savedSoFar|formatAmountPlain }} + | ++ {% if piggyBank.savedSoFar > 0 %} + + {% endif %} + | + +
+
+
+
+ |
+
+
+ + {% if piggyBank.leftToSave > 0 %} + + {% endif %} + | ++ {{ piggyBank.targetamount|formatAmount }} + {% if piggyBank.leftToSave > 0 %} + ({{ piggyBank.leftToSave|formatAmount }}) + {% endif %} + | +
+ This reminder is active between {{reminder.startdate.format('jS F Y')}} + and {{reminder.enddate.format('jS F Y')}}. +
+ {% if reminder.description %} +{{ reminder.description|raw }}
+ {% endif %} ++ (No reminders) +
++ +
++ Are you sure? +
+ ++ + Cancel +
++ +
+Account | +Balance | +Left for piggy banks | +Sum of piggy banks | +Saved so far | +Left to save | +
---|---|---|---|---|---|
{{ info.name }} | +{{ info.balance|formatAmount }} | +{{ info.leftForPiggyBanks|formatAmount }} | +{{ info.sumOfTargets|formatAmount }} | +{{ info.sumOfSaved|formatAmount }} | +{{ info.leftToSave|formatAmount }} | +
Account | +{{ piggyBank.account.name }} | +
Target amount | +{{ piggyBank.targetAmount|formatAmount }} | +
Saved so far | +{{ currentRelevantRepAmount(piggyBank)|formatAmount }} | +
Left to save | +{{ piggyBank.targetamount - currentRelevantRepAmount(piggyBank)|formatAmount }} | +
Start date | ++ {% if piggyBank.startdate %} + {{ piggyBank.startdate.format('jS F Y')}} + {% else %} + No start date + {% endif %} + | +
Target date | ++ {% if piggyBank.targetdate %} + {{ piggyBank.targetdate.format('jS F Y') }} + {% else %} + No start date + {% endif %} + | +
Reminder | ++ {% if piggyBank.remind_me == 0 %} + (no reminder) + {% else %} + Every + {% if piggyBank.reminder_skip != 0 %} + {{ piggyBank.reminder_skip }} + {% else %} + {{ piggyBank.reminder }}(s) + {% endif %} + {% endif %} + | +
Reminders left | +(in progress...) | +
Expected amount per reminder | +(in progress...) | +
Which accounts should be displayed on the home page?
+ {% for account in accounts %} ++ What's the maximum amount of money a budget envelope may contain? +
+ {{ ExpandedForm.amount('budgetMaximum',budgetMaximum,{'label' : 'Budget maximum'}) }} +Some charts are automatically grouped in periods. What period would you prefer?
++ Deleting your account will also delete any accounts, transactions, anything + you might have saved into Firefly III. It'll be GONE. +
++ Enter your password to continue. +
+ + {% if errors|length > 0 %} ++ Active between {{reminder.startdate.format('jS F Y')}} + and {{reminder.enddate.format('jS F Y')}}. +
+ + {% if reminder.description %} +{!! reminder.description !!}
+ {% endif %} ++
+ +Account | +Start of month | +Current balance | +Spent | +Earned | +
---|---|---|---|---|
{{ account.name }} | +{{ account.startBalance|formatAmount }} | +{{ account.endBalance|formatAmount }} | ++ {% if account.startBalance - account.endBalance > 0 %} + {{ (account.startBalance - account.endBalance)|formatAmountPlain }} + {% endif %} + | ++ {% if account.startBalance - account.endBalance < 0 %} + {{ ((account.startBalance - account.endBalance)*-1)|formatAmountPlain }} + {% endif %} + | +
Budgets | + {% for account in accounts %} + {% if not account.hide %} +{{ account.name }} | + {% endif %} + {% endfor %} ++ Left in budget + | +|||
---|---|---|---|---|---|
{{ budget.name }} | +{{ budget.queryAmount|formatAmount }} | + {% set spent = 0 %} + {% for account in accounts %} + {% if not account.hide %} + {% if account.budgetInformation[id] %} ++ {% if id == 0 %} + + {{ account.budgetInformation[id].queryAmount|formatAmount }} + + {% else %} + {{ account.budgetInformation[id].queryAmount|formatAmount }} + {% endif %} + | + {% set spent = spent + account.budgetInformation[id].queryAmount %} + {% else %} +{{ 0|formatAmount }} | + {% endif %} + {% endif %} + {% endfor %} +{{ (budget.queryAmount + budget.spent)|formatAmount }} | +{{ (budget.queryAmount + spent)|formatAmount }} | +
Balanced by transfers | + {% for account in accounts %} + {% if not account.hide %} ++ {{ account.balancedAmount|formatAmount }} + | + {% endif %} + {% endfor %} ++ | |||
Left unbalanced | + {% for account in accounts %} + + {% if not account.hide %} + {% if account.budgetInformation[0] %} ++ {% if account.budgetInformation[0].queryAmount + account.balancedAmount != 0.0 %} + {{ (account.budgetInformation[0].queryAmount + account.balancedAmount)|formatAmount }} + {% else %} + {{ (account.budgetInformation[0].queryAmount + account.balancedAmount)|formatAmount }} + {% endif %} + | + {% else %} +{{ 0|formatAmount }} | + {% endif %} + {% endif %} + {% endfor %} ++ | ||
Sum | + {% for account in accounts %} + {% if not account.hide %} +{{ accountAmounts[account.id]|formatAmount }} | + {% endif %} + {% endfor %} ++ | |||
Expected balance | + {% for account in accounts %} + {% if not account.hide %} +{{ (account.startBalance + accountAmounts[account.id])|formatAmount }} | + {% endif %} + {% endfor %} ++ |
+
+ ++
+ ++ {{ entry.description }} + | ++ {% if entry.type == 'Withdrawal' %} + {{entry.queryAmount|formatAmountPlain}} + {% endif %} + {% if entry.type == 'Deposit' %} + {{entry.queryAmount|formatAmountPlain}} + {% endif %} + {% if entry.type == 'Transfer' %} + {{entry.queryAmount|formatAmountPlain}} + {% endif %} + | ++ {{entry.date.format('j F Y')}} + | ++ {{ entry.name }} + | +
Sum | +{{ sum|formatAmount }} | +
{{ expense.name }} | + {% else %} +{{ expense.name }} | + {% endif %} +{{ expense.queryAmount|formatAmountPlain }} | +
Sum | +{{ sum|formatAmountPlain }} | +
In | +{{ totalIn|formatAmount }} | +
Out | +{{ sum|formatAmountPlain }} | +
Difference | +{{ (totalIn - sum)|formatAmount }} | +
Budget | +Envelope | +Spent | +Left | +
---|---|---|---|
+ {% if id > 0 %} + {{ budget.name }} + {% else %} + {{ budget.name }} + {% endif %} + | +{{ budget.queryAmount|formatAmount }} | +{{ (budget.spent*-1)|formatAmountPlain }} | +{{ (budget.queryAmount + budget.spent)|formatAmount }} | +
Sum | +{{ sumEnvelope|formatAmount }} | +{{ sumSpent|formatAmount }} | +{{ sumLeft|formatAmount }} | +
Category | +Spent | +
---|---|
+ {% if id > 0 %} + {{ category.name }} + {% else %} + {{ category.name }} + {% endif %} + | +{{ (category.queryAmount * -1)|formatAmountPlain }} | +
Sum | +{{ (sum * -1)|formatAmountPlain }} | +
{{ account.name }} | +{{ account.startBalance|formatAmount }} | +{{ account.endBalance|formatAmount }} | +{{ account.difference|formatAmount }} | +
Sum | +{{ sumStart|formatAmount }} | +{{ sumEnd|formatAmount }} | +{{ sumDiff|formatAmount }} | +
+
+ +Name | +Balance at start of year | +Balance at end of year | +Difference | +
---|---|---|---|
+ {{ balance.account.name }} + {% if balance.shared %} + shared + {% endif %} + | +{{ balance.start|formatAmount }} | +{{ balance.end|formatAmount }} | +{{ (balance.end - balance.start)|formatAmount }} | +
Sum of sums | +{{ start|formatAmount }} | +{{ end|formatAmount }} | +{{ diff|formatAmount }} | +
In | +{{ incomeSum|formatAmount }} | +
Out | +{{ (expenseSum*-1)|formatAmount }} | +
Difference | +{{ (incomeSum - expenseSum)|formatAmount }} | +
{{ income.name }} | +{{ (income.queryAmount * -1)|formatAmount }} | +
Sum | +{{ sum|formatAmount }} | +
{{ expense.name }} | +{{ (expense.queryAmount*-1)|formatAmount }} | +
Sum | +{{ sum|formatAmount }} | +
Bla bla
++ +
++ 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 +
++ +
++ 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. +
++ + {% if not helpHidden %} + Hide help + {% else %} + Show help + {% endif %} + +
++ Create new tag +
++ {% if tags|length == 0 %} + No tags + {% else %} + {% for tag in tags %} + +
+ {{tag.description}} +
+ {% endif %} + {% if tag.latitude and tag.longitude and tag.zoomLevel %} +
+
+
+ +
++ 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? +
+ ++ +
+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 %} + |
+
Amount | +{{ t|formatTransaction }} | +
New balance | +{{ t.before|formatAmount }} → {{ t.after|formatAmount }} | +
Description | +{{ t.description }} | +