diff --git a/.env.example b/.env.example index df8630b39b..0d3284ab7e 100755 --- a/.env.example +++ b/.env.example @@ -42,5 +42,3 @@ SHOW_DEMO_WARNING=false ANALYTICS_ID= RUNCLEANUP=true SITE_OWNER=mail@example.com - -BLOCKED_DOMAINS= \ No newline at end of file diff --git a/.gitignore b/.gitignore index 736f45d8ce..485afe93a2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ .env _development .env.local +result.html +test-import.sh +test-import-report.txt diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 61763a7648..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,22 +0,0 @@ -language: php -sudo: false -php: - - 7 - -install: - - phpenv config-rm xdebug.ini - - composer selfupdate - - rm composer.lock - - composer update --no-scripts - - php artisan clear-compiled - - php artisan optimize - - php artisan env - - mv -v .env.testing .env - - php artisan env - - touch storage/upload/at-1.data - - touch storage/upload/at-2.data - - touch storage/database/testing.db - - php artisan migrate --seed - -script: - - phpunit diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b5e4cf7af..6bc2c8ef1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,48 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - No unreleased changes yet. +## [3.10] - 2015-05-25 +### Added +- New charts in year report +- Can add / remove money from piggy bank on mobile device. +- Bill overview shows some useful things. +- Firefly will track registration / activation IP addresses. + + +### Changed +- Rewrote the import routine. +- The date picker now supports more ranges and periods. +- Rewrote all migrations. #272 + + +### Deprecated +- Initial release. + +### Removed +- Initial release. + +### Fixed +- Issue #264 +- Issue #265 +- Fixed amount calculation problems, #266, thanks @xzaz +- Issue #271 +- Issue #278, #273, thanks @StevenReitsma and @rubella +- Bug in attachment download routine would report the wrong size to the user's browser. +- Various NULL errors fixed. +- Various strict typing errors fixed. +- Fixed pagination problems, #276, thanks @xzaz +- Fixed a bug where an expense would be assigned to a piggy bank if you created a transfer first. +- Bulk update problems, #280, thanks @stickgrinder +- Fixed various problems with amount reporting of split transactions. + +### Security +- Initial release. + + +[3.9.1] +### Fixed +- Fixed a bug where removing money from a piggy bank would not work. See issue #265 and #269 + [3.9.0] ### Added - @zjean has added code that allows you to force "https://"-URL's. diff --git a/app/Console/Commands/EncryptFile.php b/app/Console/Commands/EncryptFile.php new file mode 100644 index 0000000000..174cc3917e --- /dev/null +++ b/app/Console/Commands/EncryptFile.php @@ -0,0 +1,69 @@ +argument('file'))); + if (!file_exists($file)) { + $this->error(sprintf('File "%s" does not seem to exist.', $file)); + + return; + } + $content = file_get_contents($file); + $content = Crypt::encrypt($content); + $newName = e(strval($this->argument('key'))) . '.upload'; + + $path = storage_path('upload') . '/' . $newName; + file_put_contents($path, $content); + $this->line(sprintf('Encrypted "%s" and put it in "%s"', $file, $path)); + + } +} diff --git a/app/Console/Commands/Import.php b/app/Console/Commands/Import.php new file mode 100644 index 0000000000..3d70737e7e --- /dev/null +++ b/app/Console/Commands/Import.php @@ -0,0 +1,113 @@ +argument('key'); + $job = ImportJob::whereKey($jobKey)->first(); + if (is_null($job)) { + $this->error('This job does not seem to exist.'); + + return; + } + + if ($job->status != 'settings_complete') { + $this->error('This job is not ready to be imported.'); + + return; + } + + $this->line('Going to import job with key "' . $job->key . '" of type ' . $job->file_type); + $valid = array_keys(config('firefly.import_formats')); + $class = 'INVALID'; + if (in_array($job->file_type, $valid)) { + $class = config('firefly.import_formats.' . $job->file_type); + } + + /** @var ImporterInterface $importer */ + $importer = app($class); + $importer->setJob($job); + // intercept logging by importer. + $monolog = Log::getMonolog(); + $handler = new CommandHandler($this); + + $monolog->pushHandler($handler); + + // create import entries + $collection = $importer->createImportEntries(); + + // validate / clean collection: + $validator = new ImportValidator($collection); + $validator->setUser($job->user); + if ($job->configuration['import-account'] != 0) { + $repository = app(AccountCrud::class, [$job->user]); + $validator->setDefaultImportAccount($repository->find($job->configuration['import-account'])); + } + + $cleaned = $validator->clean(); + + // then import collection: + $storage = new ImportStorage($cleaned); + $storage->setUser($job->user); + + // and run store routine: + $storage->store(); + + + $this->line('Something something import: ' . $jobKey); + } +} diff --git a/app/Console/Commands/UpgradeFireflyInstructions.php b/app/Console/Commands/UpgradeFireflyInstructions.php index 4535d17a7f..7881f87646 100644 --- a/app/Console/Commands/UpgradeFireflyInstructions.php +++ b/app/Console/Commands/UpgradeFireflyInstructions.php @@ -25,7 +25,7 @@ class UpgradeFireflyInstructions extends Command * * @var string */ - protected $description = 'Command description'; + protected $description = 'Instructions in case of upgrade trouble.'; /** * The name and signature of the console command. * diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index ea6b228eea..25b79b71eb 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -11,6 +11,8 @@ declare(strict_types = 1); namespace FireflyIII\Console; +use FireflyIII\Console\Commands\EncryptFile; +use FireflyIII\Console\Commands\Import; use FireflyIII\Console\Commands\UpgradeFireflyInstructions; use FireflyIII\Console\Commands\VerifyDatabase; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; @@ -51,5 +53,7 @@ class Kernel extends ConsoleKernel = [ UpgradeFireflyInstructions::class, VerifyDatabase::class, + Import::class, + EncryptFile::class, ]; } diff --git a/app/Crud/Account/AccountCrud.php b/app/Crud/Account/AccountCrud.php index b09c413407..803f88f3c4 100644 --- a/app/Crud/Account/AccountCrud.php +++ b/app/Crud/Account/AccountCrud.php @@ -11,6 +11,7 @@ declare(strict_types = 1); namespace FireflyIII\Crud\Account; +use Carbon\Carbon; use DB; use FireflyIII\Models\Account; use FireflyIII\Models\AccountMeta; @@ -52,14 +53,17 @@ class AccountCrud implements AccountCrudInterface * * @return bool */ - public function destroy(Account $account, Account $moveTo = null): bool + public function destroy(Account $account, Account $moveTo): bool { - if (!is_null($moveTo)) { + if (!is_null($moveTo->id)) { // update all transactions: DB::table('transactions')->where('account_id', $account->id)->update(['account_id' => $moveTo->id]); } + if (!is_null($account)) { + Log::debug('Now trigger account delete #' . $account->id); + $account->delete(); + } - $account->delete(); return true; } @@ -71,14 +75,99 @@ class AccountCrud implements AccountCrudInterface */ public function find(int $accountId): Account { + Log::debug('Searching for user ', ['user' => $this->user->id]); $account = $this->user->accounts()->find($accountId); if (is_null($account)) { - $account = new Account; + return new Account; } return $account; } + /** + * @param string $number + * @param array $types + * + * @return Account + */ + public function findByAccountNumber(string $number, array $types): Account + { + $query = $this->user->accounts() + ->leftJoin('account_meta', 'account_meta.account_id', '=', 'accounts.id') + ->where('account_meta.name', 'accountNumber') + ->where('account_meta.data', json_encode($number)); + + if (count($types) > 0) { + $query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id'); + $query->whereIn('account_types.type', $types); + } + + /** @var Collection $accounts */ + $accounts = $query->get(['accounts.*']); + if ($accounts->count() > 0) { + return $accounts->first(); + } + + return new Account; + } + + /** + * @param string $iban + * @param array $types + * + * @return Account + */ + public function findByIban(string $iban, array $types): Account + { + $query = $this->user->accounts()->where('iban', '!=', ''); + + if (count($types) > 0) { + $query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id'); + $query->whereIn('account_types.type', $types); + } + + $accounts = $query->get(['accounts.*']); + /** @var Account $account */ + foreach ($accounts as $account) { + if ($account->iban === $iban) { + return $account; + } + } + + return new Account; + } + + /** + * @param string $name + * @param array $types + * + * @return Account + */ + public function findByName(string $name, array $types): Account + { + $query = $this->user->accounts(); + Log::debug('Now in findByName()', ['name' => $name, 'types' => $types]); + + if (count($types) > 0) { + $query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id'); + $query->whereIn('account_types.type', $types); + } + + $accounts = $query->get(['accounts.*']); + Log::debug(sprintf('Total set count is %d ', $accounts->count())); + /** @var Account $account */ + foreach ($accounts as $account) { + if ($account->name === $name) { + Log::debug('Account name is an exact match. ', ['db' => $account->name, 'source' => $name, 'id' => $account->id]); + + return $account; + } + } + Log::debug('Found nothing in findByName()', ['name' => $name, 'types' => $types]); + + return new Account; + } + /** * @param array $accountIds * @@ -146,25 +235,12 @@ class AccountCrud implements AccountCrudInterface public function store(array $data): Account { $newAccount = $this->storeAccount($data); - if (!is_null($newAccount)) { + if (!is_null($newAccount->id)) { $this->storeMetadata($newAccount, $data); } - // continue with the opposing account: if ($data['openingBalance'] != 0) { - $opposingData = [ - 'user' => $data['user'], - 'accountType' => 'initial', - 'virtualBalance' => 0, - 'name' => $data['name'] . ' initial balance', - 'active' => false, - 'iban' => '', - ]; - $opposing = $this->storeAccount($opposingData); - if (!is_null($opposing) && !is_null($newAccount)) { - $this->storeInitialBalance($newAccount, $opposing, $data); - } - + $this->storeInitialBalance($newAccount, $data); } return $newAccount; @@ -199,39 +275,29 @@ class AccountCrud implements AccountCrudInterface $account->save(); $this->updateMetadata($account, $data); - $openingBalance = $this->openingBalanceTransaction($account); - if ($data['openingBalance'] != 0) { - if (!is_null($openingBalance->id)) { - $this->updateInitialBalance($account, $openingBalance, $data); - - return $account; - } - - $type = $data['openingBalance'] < 0 ? 'expense' : 'revenue'; - $opposingData = [ - 'user' => $data['user'], - 'accountType' => $type, - 'name' => $data['name'] . ' initial balance', - 'active' => false, - 'iban' => '', - 'virtualBalance' => 0, - ]; - $opposing = $this->storeAccount($opposingData); - if (!is_null($opposing)) { - $this->storeInitialBalance($account, $opposing, $data); - } - - return $account; - - } - - if ($openingBalance) { // opening balance is zero, should we delete it? - $openingBalance->delete(); // delete existing opening balance. - } + $this->updateInitialBalance($account, $data); return $account; } + /** + * @param Account $account + * @param string $type + * + * @return Account + */ + public function updateAccountType(Account $account, string $type): Account + { + $type = AccountType::whereType($type)->first(); + if (!is_null($type)) { + $account->accountType()->associate($type); + $account->save(); + } + + return $this->find($account->id); + + } + /** * @param array $data * @@ -263,8 +329,8 @@ class AccountCrud implements AccountCrudInterface ]; $existingAccount = Account::firstOrNullEncrypted($searchData); if (!$existingAccount) { - Log::error('Account create error: ' . $newAccount->getErrors()->toJson()); - abort(500); + Log::error('Account create error', $newAccount->getErrors()->toArray()); + return new Account; } $newAccount = $existingAccount; @@ -276,19 +342,21 @@ class AccountCrud implements AccountCrudInterface /** * @param Account $account - * @param Account $opposing * @param array $data * * @return TransactionJournal */ - protected function storeInitialBalance(Account $account, Account $opposing, array $data): TransactionJournal + protected function storeInitialBalance(Account $account, array $data): TransactionJournal { + $amount = $data['openingBalance']; + $user = $data['user']; + $name = $data['name']; + $opposing = $this->storeOpposingAccount($amount, $user, $name); $transactionType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first(); $journal = TransactionJournal::create( [ 'user_id' => $data['user'], 'transaction_type_id' => $transactionType->id, - 'bill_id' => null, 'transaction_currency_id' => $data['openingBalanceCurrency'], 'description' => 'Initial balance for "' . $account->name . '"', 'completed' => true, @@ -299,24 +367,22 @@ class AccountCrud implements AccountCrudInterface $firstAccount = $account; $secondAccount = $opposing; - $firstAmount = $data['openingBalance']; - $secondAmount = $data['openingBalance'] * -1; + $firstAmount = $amount; + $secondAmount = $amount * -1; if ($data['openingBalance'] < 0) { $firstAccount = $opposing; $secondAccount = $account; - $firstAmount = $data['openingBalance'] * -1; - $secondAmount = $data['openingBalance']; + $firstAmount = $amount * -1; + $secondAmount = $amount; } $one = new Transaction(['account_id' => $firstAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $firstAmount]); $one->save();// first transaction: from - $two = new Transaction(['account_id' => $secondAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $secondAmount]); $two->save(); // second transaction: to return $journal; - } /** @@ -342,30 +408,32 @@ class AccountCrud implements AccountCrudInterface } /** - * @param Account $account - * @param TransactionJournal $journal - * @param array $data + * @param Account $account + * @param array $data * - * @return TransactionJournal + * @return bool */ - protected function updateInitialBalance(Account $account, TransactionJournal $journal, array $data): TransactionJournal + protected function updateInitialBalance(Account $account, array $data): bool { - $journal->date = $data['openingBalanceDate']; - $journal->save(); + $openingBalance = $this->openingBalanceTransaction($account); + if ($data['openingBalance'] != 0) { + if (!is_null($openingBalance->id)) { + $date = $data['openingBalanceDate']; + $amount = $data['openingBalance']; - /** @var Transaction $transaction */ - foreach ($journal->transactions()->get() as $transaction) { - if ($account->id == $transaction->account_id) { - $transaction->amount = $data['openingBalance']; - $transaction->save(); - } - if ($account->id != $transaction->account_id) { - $transaction->amount = $data['openingBalance'] * -1; - $transaction->save(); + return $this->updateJournal($account, $openingBalance, $date, $amount); } + + $this->storeInitialBalance($account, $data); + + return true; + } + // else, delete it: + if ($openingBalance) { // opening balance is zero, should we delete it? + $openingBalance->delete(); // delete existing opening balance. } - return $journal; + return true; } /** @@ -418,4 +486,56 @@ class AccountCrud implements AccountCrudInterface return $journal; } -} \ No newline at end of file + + /** + * @param float $amount + * @param int $user + * @param string $name + * + * @return Account + */ + private function storeOpposingAccount(float $amount, int $user, string $name):Account + { + $type = $amount < 0 ? 'expense' : 'revenue'; + $opposingData = [ + 'user' => $user, + 'accountType' => $type, + 'name' => $name . ' initial balance', + 'active' => false, + 'iban' => '', + 'virtualBalance' => 0, + ]; + + return $this->storeAccount($opposingData); + } + + /** + * @param Account $account + * @param TransactionJournal $journal + * @param Carbon $date + * @param float $amount + * + * @return bool + */ + private function updateJournal(Account $account, TransactionJournal $journal, Carbon $date, float $amount): bool + { + // update date: + $journal->date = $date; + $journal->save(); + // update transactions: + /** @var Transaction $transaction */ + foreach ($journal->transactions()->get() as $transaction) { + if ($account->id == $transaction->account_id) { + $transaction->amount = $amount; + $transaction->save(); + } + if ($account->id != $transaction->account_id) { + $transaction->amount = $amount * -1; + $transaction->save(); + } + } + + return true; + + } +} diff --git a/app/Crud/Account/AccountCrudInterface.php b/app/Crud/Account/AccountCrudInterface.php index a325e3e6d2..460f6628e6 100644 --- a/app/Crud/Account/AccountCrudInterface.php +++ b/app/Crud/Account/AccountCrudInterface.php @@ -37,6 +37,30 @@ interface AccountCrudInterface */ public function find(int $accountId): Account; + /** + * @param string $number + * @param array $types + * + * @return Account + */ + public function findByAccountNumber(string $number, array $types): Account; + + /** + * @param string $iban + * @param array $types + * + * @return Account + */ + public function findByIban(string $iban, array $types): Account; + + /** + * @param string $name + * @param array $types + * + * @return Account + */ + public function findByName(string $name, array $types): Account; + /** * @param array $accountIds * @@ -67,7 +91,6 @@ interface AccountCrudInterface */ public function storeMeta(Account $account, string $name, $value): AccountMeta; - /** * @param Account $account * @param array $data @@ -75,4 +98,12 @@ interface AccountCrudInterface * @return Account */ public function update(Account $account, array $data): Account; -} \ No newline at end of file + + /** + * @param Account $account + * @param string $type + * + * @return Account + */ + public function updateAccountType(Account $account, string $type): Account; +} diff --git a/app/Crud/Split/Journal.php b/app/Crud/Split/Journal.php index 8930331d56..94eda45c5b 100644 --- a/app/Crud/Split/Journal.php +++ b/app/Crud/Split/Journal.php @@ -105,9 +105,6 @@ class Journal implements JournalInterface */ public function updateJournal(TransactionJournal $journal, array $data): TransactionJournal { - echo '
';
-        print_r($data);
-
         $journal->description             = $data['journal_description'];
         $journal->transaction_currency_id = $data['journal_currency_id'];
         $journal->date                    = $data['date'];
@@ -167,7 +164,8 @@ class Journal implements JournalInterface
     {
         $destinationAccount = Account::where('user_id', $this->user->id)->where('id', $data['destination_account_id'])->first(['accounts.*']);
 
-        if (strlen($data['source_account_name']) > 0) {
+
+        if (isset($data['source_account_name']) && strlen($data['source_account_name']) > 0) {
             $sourceType    = AccountType::where('type', 'Revenue account')->first();
             $sourceAccount = Account::firstOrCreateEncrypted(
                 ['user_id' => $this->user->id, 'account_type_id' => $sourceType->id, 'name' => $data['source_account_name'], 'active' => 1]
@@ -215,4 +213,4 @@ class Journal implements JournalInterface
 
 
     }
-}
\ No newline at end of file
+}
diff --git a/app/Crud/Split/JournalInterface.php b/app/Crud/Split/JournalInterface.php
index 81c852398d..15793101f2 100644
--- a/app/Crud/Split/JournalInterface.php
+++ b/app/Crud/Split/JournalInterface.php
@@ -44,4 +44,4 @@ interface JournalInterface
      * @return TransactionJournal
      */
     public function updateJournal(TransactionJournal $journal, array $data): TransactionJournal;
-}
\ No newline at end of file
+}
diff --git a/app/Events/UserIsConfirmed.php b/app/Events/UserIsConfirmed.php
new file mode 100644
index 0000000000..8313d835a0
--- /dev/null
+++ b/app/Events/UserIsConfirmed.php
@@ -0,0 +1,40 @@
+user      = $user;
+        $this->ipAddress = $ipAddress;
+    }
+}
diff --git a/app/Events/UserIsDeleted.php b/app/Events/UserIsDeleted.php
new file mode 100644
index 0000000000..34459decec
--- /dev/null
+++ b/app/Events/UserIsDeleted.php
@@ -0,0 +1,40 @@
+user      = $user;
+        $this->ipAddress = $ipAddress;
+    }
+}
diff --git a/app/Export/Collector/AttachmentCollector.php b/app/Export/Collector/AttachmentCollector.php
index 35a4a0ebb8..f3c9e83516 100644
--- a/app/Export/Collector/AttachmentCollector.php
+++ b/app/Export/Collector/AttachmentCollector.php
@@ -83,10 +83,10 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
         /** @var TransactionJournal $journal */
         $journal = $attachment->attachable;
         $args    = [
-            'attachment_name' => $attachment->filename,
+            'attachment_name' => e($attachment->filename),
             'attachment_id'   => $attachment->id,
             'type'            => strtolower($journal->transactionType->type),
-            'description'     => $journal->description,
+            'description'     => e($journal->description),
             'journal_id'      => $journal->id,
             'date'            => $journal->date->formatLocalized(strval(trans('config.month_and_day'))),
             'amount'          => Amount::formatJournal($journal, false),
diff --git a/app/Export/Collector/UploadCollector.php b/app/Export/Collector/UploadCollector.php
index 3841a52a9d..e161f89ece 100644
--- a/app/Export/Collector/UploadCollector.php
+++ b/app/Export/Collector/UploadCollector.php
@@ -45,8 +45,6 @@ class UploadCollector extends BasicCollector implements CollectorInterface
         // make storage:
         $this->uploadDisk = Storage::disk('upload');
         $this->exportDisk = Storage::disk('export');
-
-        // todo needs work for new importer (potentially collect other types as well)
         $this->expected   = 'csv-upload-' . Auth::user()->id . '-';
     }
 
diff --git a/app/Export/Entry/EntryAccount.php b/app/Export/Entry/EntryAccount.php
index 4a63c466a5..da23d80b68 100644
--- a/app/Export/Entry/EntryAccount.php
+++ b/app/Export/Entry/EntryAccount.php
@@ -44,4 +44,4 @@ class EntryAccount
         $this->type      = $account->accountType->type;
         $this->number    = $account->getMeta('accountNumber');
     }
-}
\ No newline at end of file
+}
diff --git a/app/Export/Entry/EntryBill.php b/app/Export/Entry/EntryBill.php
index 67d48af854..696fb58985 100644
--- a/app/Export/Entry/EntryBill.php
+++ b/app/Export/Entry/EntryBill.php
@@ -38,4 +38,4 @@ class EntryBill
         }
     }
 
-}
\ No newline at end of file
+}
diff --git a/app/Export/Entry/EntryBudget.php b/app/Export/Entry/EntryBudget.php
index 730de35406..0ca9d38ae5 100644
--- a/app/Export/Entry/EntryBudget.php
+++ b/app/Export/Entry/EntryBudget.php
@@ -38,4 +38,4 @@ class EntryBudget
         }
     }
 
-}
\ No newline at end of file
+}
diff --git a/app/Export/Entry/EntryCategory.php b/app/Export/Entry/EntryCategory.php
index 18d19f0642..8a8de50dfa 100644
--- a/app/Export/Entry/EntryCategory.php
+++ b/app/Export/Entry/EntryCategory.php
@@ -37,4 +37,4 @@ class EntryCategory
             $this->name       = $category->name;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/app/Handlers/Events/BudgetLimitEventHandler.php b/app/Handlers/Events/BudgetLimitEventHandler.php
index 5fb0439b2f..d7eb7327c4 100644
--- a/app/Handlers/Events/BudgetLimitEventHandler.php
+++ b/app/Handlers/Events/BudgetLimitEventHandler.php
@@ -104,4 +104,4 @@ class BudgetLimitEventHandler
         }
     }
 
-}
\ No newline at end of file
+}
diff --git a/app/Handlers/Events/UserSaveIpAddress.php b/app/Handlers/Events/UserSaveIpAddress.php
new file mode 100644
index 0000000000..7dcbf11394
--- /dev/null
+++ b/app/Handlers/Events/UserSaveIpAddress.php
@@ -0,0 +1,62 @@
+user, 'registration_ip_address', $event->ipAddress);
+
+        return true;
+    }
+
+    /**
+     * Handle the event.
+     *
+     * @param  UserIsConfirmed $event
+     *
+     * @return bool
+     */
+    public function saveFromConfirmation(UserIsConfirmed $event): bool
+    {
+        Preferences::setForUser($event->user, 'confirmation_ip_address', $event->ipAddress);
+
+        return true;
+    }
+}
diff --git a/app/Helpers/Csv/Converter/AccountId.php b/app/Helpers/Csv/Converter/AccountId.php
deleted file mode 100644
index 908cd132de..0000000000
--- a/app/Helpers/Csv/Converter/AccountId.php
+++ /dev/null
@@ -1,35 +0,0 @@
-mapped[$this->index][$this->value]) ? $this->mapped[$this->index][$this->value] : $this->value;
-        $account = $crud->find($var);
-
-        return $account;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/Amount.php b/app/Helpers/Csv/Converter/Amount.php
deleted file mode 100644
index 8e2cfc4d0e..0000000000
--- a/app/Helpers/Csv/Converter/Amount.php
+++ /dev/null
@@ -1,32 +0,0 @@
-value)) {
-            return strval($this->value);
-        }
-
-        return '0';
-    }
-}
diff --git a/app/Helpers/Csv/Converter/AmountComma.php b/app/Helpers/Csv/Converter/AmountComma.php
deleted file mode 100644
index 8cddad6dc8..0000000000
--- a/app/Helpers/Csv/Converter/AmountComma.php
+++ /dev/null
@@ -1,36 +0,0 @@
-value));
-
-        if (is_numeric($value)) {
-            return strval($value);
-        }
-
-        return '0';
-    }
-}
diff --git a/app/Helpers/Csv/Converter/AssetAccountIban.php b/app/Helpers/Csv/Converter/AssetAccountIban.php
deleted file mode 100644
index 4da3a73625..0000000000
--- a/app/Helpers/Csv/Converter/AssetAccountIban.php
+++ /dev/null
@@ -1,89 +0,0 @@
-mapped[$this->index][$this->value])) {
-            $account = $crud->find(intval($this->mapped[$this->index][$this->value]));
-
-            return $account;
-        }
-
-
-        if (strlen($this->value) > 0) {
-            $account = $this->searchOrCreate($crud);
-
-            return $account;
-        }
-
-        return new Account;
-    }
-
-    /**
-     * @param AccountCrudInterface $crud
-     *
-     * @return Account
-     */
-    private function searchOrCreate(AccountCrudInterface $crud)
-    {
-        // find or create new account:
-        $set = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
-        /** @var Account $entry */
-        foreach ($set as $entry) {
-            if ($entry->iban == $this->value) {
-
-                return $entry;
-            }
-        }
-
-
-        // create it if doesn't exist.
-        $accountData = [
-            'name'                   => $this->value,
-            'accountType'            => 'asset',
-            'virtualBalance'         => 0,
-            'virtualBalanceCurrency' => 1, // hard coded.
-            'active'                 => true,
-            'user'                   => Auth::user()->id,
-            'iban'                   => $this->value,
-            'accountNumber'          => $this->value,
-            'accountRole'            => null,
-            'openingBalance'         => 0,
-            'openingBalanceDate'     => new Carbon,
-            'openingBalanceCurrency' => 1, // hard coded.
-        ];
-
-        $account = $crud->store($accountData);
-
-        return $account;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/AssetAccountName.php b/app/Helpers/Csv/Converter/AssetAccountName.php
deleted file mode 100644
index e56620415e..0000000000
--- a/app/Helpers/Csv/Converter/AssetAccountName.php
+++ /dev/null
@@ -1,65 +0,0 @@
-mapped[$this->index][$this->value])) {
-            $account = $crud->find(intval($this->mapped[$this->index][$this->value]));
-
-            return $account;
-        }
-
-        $set = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
-        /** @var Account $entry */
-        foreach ($set as $entry) {
-            if ($entry->name == $this->value) {
-                return $entry;
-            }
-        }
-        $accountData = [
-            'name'                   => $this->value,
-            'accountType'            => 'asset',
-            'virtualBalance'         => 0,
-            'virtualBalanceCurrency' => 1, // hard coded.
-            'active'                 => true,
-            'user'                   => Auth::user()->id,
-            'iban'                   => null,
-            'accountNumber'          => $this->value,
-            'accountRole'            => null,
-            'openingBalance'         => 0,
-            'openingBalanceDate'     => new Carbon,
-            'openingBalanceCurrency' => 1, // hard coded.
-        ];
-
-        $account = $crud->store($accountData);
-
-        return $account;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/AssetAccountNumber.php b/app/Helpers/Csv/Converter/AssetAccountNumber.php
deleted file mode 100644
index 5b8efed50a..0000000000
--- a/app/Helpers/Csv/Converter/AssetAccountNumber.php
+++ /dev/null
@@ -1,77 +0,0 @@
-mapped[$this->index][$this->value])) {
-            $account = $crud->find(intval($this->mapped[$this->index][$this->value]));
-
-            return $account;
-        }
-        // if not, search for it (or create it):
-        $value = $this->value ?? '';
-        if (strlen($value) > 0) {
-            // find or create new account:
-            $set = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
-            /** @var Account $entry */
-            foreach ($set as $entry) {
-                $accountNumber = $entry->getMeta('accountNumber');
-                if ($accountNumber == $this->value) {
-
-                    return $entry;
-                }
-            }
-
-            $accountData = [
-                'name'                   => $this->value,
-                'accountType'            => 'asset',
-                'virtualBalance'         => 0,
-                'virtualBalanceCurrency' => 1, // hard coded.
-                'active'                 => true,
-                'user'                   => Auth::user()->id,
-                'iban'                   => null,
-                'accountNumber'          => $this->value,
-                'accountRole'            => null,
-                'openingBalance'         => 0,
-                'openingBalanceDate'     => new Carbon,
-                'openingBalanceCurrency' => 1, // hard coded.
-
-            ];
-
-            $account = $crud->store($accountData);
-
-            return $account;
-        }
-
-        return null; // is this accepted?
-    }
-
-}
diff --git a/app/Helpers/Csv/Converter/BasicConverter.php b/app/Helpers/Csv/Converter/BasicConverter.php
deleted file mode 100644
index 63e5f8bb96..0000000000
--- a/app/Helpers/Csv/Converter/BasicConverter.php
+++ /dev/null
@@ -1,114 +0,0 @@
-data;
-    }
-
-    /**
-     * @param array $data
-     */
-    public function setData(array $data)
-    {
-        $this->data = $data;
-    }
-
-    /**
-     * @return string
-     */
-    public function getField(): string
-    {
-        return $this->field;
-    }
-
-    /**
-     * @param string $field
-     */
-    public function setField(string $field)
-    {
-        $this->field = $field;
-    }
-
-    /**
-     * @return int
-     */
-    public function getIndex(): int
-    {
-        return $this->index;
-    }
-
-    /**
-     * @param int $index
-     */
-    public function setIndex(int $index)
-    {
-        $this->index = $index;
-    }
-
-    /**
-     * @return array
-     */
-    public function getMapped(): array
-    {
-        return $this->mapped;
-    }
-
-    /**
-     * @param array $mapped
-     */
-    public function setMapped(array $mapped)
-    {
-        $this->mapped = $mapped;
-    }
-
-    /**
-     * @return string
-     */
-    public function getValue(): string
-    {
-        return $this->value;
-    }
-
-    /**
-     * @param string $value
-     */
-    public function setValue(string $value)
-    {
-        $this->value = $value;
-    }
-
-
-}
diff --git a/app/Helpers/Csv/Converter/BillId.php b/app/Helpers/Csv/Converter/BillId.php
deleted file mode 100644
index 3e9102ccec..0000000000
--- a/app/Helpers/Csv/Converter/BillId.php
+++ /dev/null
@@ -1,36 +0,0 @@
-mapped[$this->index][$this->value]) ? $this->mapped[$this->index][$this->value] : $this->value;
-        $bill       = $repository->find($value);
-
-        return $bill;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/BillName.php b/app/Helpers/Csv/Converter/BillName.php
deleted file mode 100644
index a1328ef6c1..0000000000
--- a/app/Helpers/Csv/Converter/BillName.php
+++ /dev/null
@@ -1,47 +0,0 @@
-mapped[$this->index][$this->value])) {
-            return $repository->find($this->mapped[$this->index][$this->value]);
-        }
-        $bills = $repository->getBills();
-
-        /** @var Bill $bill */
-        foreach ($bills as $bill) {
-            if ($bill->name == $this->value) {
-                return $bill;
-            }
-        }
-
-        return new Bill;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/BudgetId.php b/app/Helpers/Csv/Converter/BudgetId.php
deleted file mode 100644
index d9302d7734..0000000000
--- a/app/Helpers/Csv/Converter/BudgetId.php
+++ /dev/null
@@ -1,36 +0,0 @@
-mapped[$this->index][$this->value]) ? $this->mapped[$this->index][$this->value] : $this->value;
-        $budget     = $repository->find($value);
-
-        return $budget;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/BudgetName.php b/app/Helpers/Csv/Converter/BudgetName.php
deleted file mode 100644
index 84f777775b..0000000000
--- a/app/Helpers/Csv/Converter/BudgetName.php
+++ /dev/null
@@ -1,44 +0,0 @@
-mapped[$this->index][$this->value])) {
-            $budget = $repository->find($this->mapped[$this->index][$this->value]);
-
-            return $budget;
-        }
-        $budget = $repository->store(['name' => $this->value, 'user' => Auth::user()->id]);
-
-
-        return $budget;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/CategoryId.php b/app/Helpers/Csv/Converter/CategoryId.php
deleted file mode 100644
index 8ffedd9ae1..0000000000
--- a/app/Helpers/Csv/Converter/CategoryId.php
+++ /dev/null
@@ -1,36 +0,0 @@
-mapped[$this->index][$this->value]) ? $this->mapped[$this->index][$this->value] : $this->value;
-        $category   = $repository->find($value);
-
-        return $category;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/CategoryName.php b/app/Helpers/Csv/Converter/CategoryName.php
deleted file mode 100644
index d322f7b02f..0000000000
--- a/app/Helpers/Csv/Converter/CategoryName.php
+++ /dev/null
@@ -1,49 +0,0 @@
-mapped[$this->index][$this->value])) {
-            $category = $repository->find($this->mapped[$this->index][$this->value]);
-
-            return $category;
-        }
-
-        $data = [
-            'name' => $this->value,
-            'user' => Auth::user()->id,
-        ];
-
-        $category = $repository->store($data);
-
-        return $category;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/ConverterInterface.php b/app/Helpers/Csv/Converter/ConverterInterface.php
deleted file mode 100644
index c8fb526b83..0000000000
--- a/app/Helpers/Csv/Converter/ConverterInterface.php
+++ /dev/null
@@ -1,52 +0,0 @@
-mapped[$this->index][$this->value])) {
-            $currency = $repository->find(intval($this->mapped[$this->index][$this->value]));
-
-            return $currency;
-        }
-
-        $currency = $repository->findByCode($this->value);
-
-
-        return $currency;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/CurrencyId.php b/app/Helpers/Csv/Converter/CurrencyId.php
deleted file mode 100644
index a18082872a..0000000000
--- a/app/Helpers/Csv/Converter/CurrencyId.php
+++ /dev/null
@@ -1,36 +0,0 @@
-mapped[$this->index][$this->value]) ? $this->mapped[$this->index][$this->value] : $this->value;
-        $currency   = $repository->find($value);
-
-        return $currency;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/CurrencyName.php b/app/Helpers/Csv/Converter/CurrencyName.php
deleted file mode 100644
index 62876fa9ba..0000000000
--- a/app/Helpers/Csv/Converter/CurrencyName.php
+++ /dev/null
@@ -1,42 +0,0 @@
-mapped[$this->index][$this->value])) {
-            $currency = $repository->find($this->mapped[$this->index][$this->value]);
-
-            return $currency;
-        }
-        $currency = $repository->findByName($this->value);
-
-
-        return $currency;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/CurrencySymbol.php b/app/Helpers/Csv/Converter/CurrencySymbol.php
deleted file mode 100644
index 51037ece2e..0000000000
--- a/app/Helpers/Csv/Converter/CurrencySymbol.php
+++ /dev/null
@@ -1,43 +0,0 @@
-mapped[$this->index][$this->value])) {
-            $currency = $repository->find($this->mapped[$this->index][$this->value]);
-
-            return $currency;
-        }
-
-        $currency = $repository->findBySymbol($this->value);
-
-
-        return $currency;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/Date.php b/app/Helpers/Csv/Converter/Date.php
deleted file mode 100644
index b164e9df5f..0000000000
--- a/app/Helpers/Csv/Converter/Date.php
+++ /dev/null
@@ -1,46 +0,0 @@
-value);
-        } catch (InvalidArgumentException $e) {
-            Log::error('Date conversion error: ' . $e->getMessage() . '. Value was "' . $this->value . '", format was "' . $format . '".');
-
-            $message = trans('firefly.csv_date_parse_error', ['format' => $format, 'value' => $this->value]);
-
-            throw new FireflyException($message);
-        }
-
-
-        return $date;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/OpposingAccountIban.php b/app/Helpers/Csv/Converter/OpposingAccountIban.php
deleted file mode 100644
index 37f8111b96..0000000000
--- a/app/Helpers/Csv/Converter/OpposingAccountIban.php
+++ /dev/null
@@ -1,64 +0,0 @@
-mapped[$this->index][$this->value])) {
-            $account = $crud->find($this->mapped[$this->index][$this->value]);
-
-            return $account;
-        }
-
-        return $this->findAccount($crud);
-    }
-
-    /**
-     * @param AccountCrudInterface $crud
-     *
-     * @return Account|string
-     */
-    private function findAccount(AccountCrudInterface $crud)
-    {
-        if (strlen($this->value) > 0) {
-
-            $set = $crud->getAccountsByType([]);
-            /** @var Account $account */
-            foreach ($set as $account) {
-                if ($account->iban == $this->value) {
-
-                    return $account;
-                }
-            }
-        }
-
-        return $this->value;
-    }
-
-}
diff --git a/app/Helpers/Csv/Converter/OpposingAccountId.php b/app/Helpers/Csv/Converter/OpposingAccountId.php
deleted file mode 100644
index 17836907bf..0000000000
--- a/app/Helpers/Csv/Converter/OpposingAccountId.php
+++ /dev/null
@@ -1,35 +0,0 @@
-mapped[$this->index][$this->value]) ? $this->mapped[$this->index][$this->value] : $this->value;
-        $account = $crud->find($value);
-
-        return $account;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/OpposingAccountName.php b/app/Helpers/Csv/Converter/OpposingAccountName.php
deleted file mode 100644
index 7c3d392985..0000000000
--- a/app/Helpers/Csv/Converter/OpposingAccountName.php
+++ /dev/null
@@ -1,41 +0,0 @@
-mapped[$this->index][$this->value])) {
-            $account = $crud->find($this->mapped[$this->index][$this->value]);
-
-            return $account;
-        }
-
-        return $this->value;
-
-    }
-}
diff --git a/app/Helpers/Csv/Converter/TagsComma.php b/app/Helpers/Csv/Converter/TagsComma.php
deleted file mode 100644
index c9477e7ada..0000000000
--- a/app/Helpers/Csv/Converter/TagsComma.php
+++ /dev/null
@@ -1,53 +0,0 @@
-value);
-        foreach ($strings as $string) {
-            $data = [
-                'tag'         => $string,
-                'date'        => null,
-                'description' => null,
-                'latitude'    => null,
-                'longitude'   => null,
-                'zoomLevel'   => null,
-                'tagMode'     => 'nothing',
-            ];
-            if (strlen($string) > 0) {
-                $tag = $repository->store($data); // should validate first?
-                $tags->push($tag);
-            }
-        }
-        $tags = $tags->merge($this->data['tags']);
-
-        return $tags;
-    }
-}
diff --git a/app/Helpers/Csv/Converter/TagsSpace.php b/app/Helpers/Csv/Converter/TagsSpace.php
deleted file mode 100644
index aa2694a330..0000000000
--- a/app/Helpers/Csv/Converter/TagsSpace.php
+++ /dev/null
@@ -1,54 +0,0 @@
-value);
-        foreach ($strings as $string) {
-            $data = [
-                'tag'         => $string,
-                'date'        => null,
-                'description' => null,
-                'latitude'    => null,
-                'longitude'   => null,
-                'zoomLevel'   => null,
-                'tagMode'     => 'nothing',
-            ];
-            if (strlen($string) > 0) {
-                $tag = $repository->store($data); // should validate first?
-                $tags->push($tag);
-            }
-        }
-        $tags = $tags->merge($this->data['tags']);
-
-        return $tags;
-    }
-}
diff --git a/app/Helpers/Csv/Data.php b/app/Helpers/Csv/Data.php
deleted file mode 100644
index d56f790204..0000000000
--- a/app/Helpers/Csv/Data.php
+++ /dev/null
@@ -1,336 +0,0 @@
-sessionHasHeaders();
-        $this->sessionDateFormat();
-        $this->sessionCsvFileLocation();
-        $this->sessionMap();
-        $this->sessionRoles();
-        $this->sessionMapped();
-        $this->sessionSpecifix();
-        $this->sessionImportAccount();
-        $this->sessionDelimiter();
-    }
-
-    /**
-     *
-     * @return string
-     */
-    public function getCsvFileContent(): string
-    {
-        return $this->csvFileContent ?? '';
-    }
-
-    /**
-     *
-     * @param string $csvFileContent
-     */
-    public function setCsvFileContent(string $csvFileContent)
-    {
-        $this->csvFileContent = $csvFileContent;
-    }
-
-    /**
-     * FIXxME may return null
-     *
-     * @return string
-     */
-    public function getCsvFileLocation(): string
-    {
-        return $this->csvFileLocation;
-    }
-
-    /**
-     *
-     * @param string $csvFileLocation
-     */
-    public function setCsvFileLocation(string $csvFileLocation)
-    {
-        Session::put('csv-file', $csvFileLocation);
-        $this->csvFileLocation = $csvFileLocation;
-    }
-
-    /**
-     * FIXxME may return null
-     *
-     * @return string
-     */
-    public function getDateFormat(): string
-    {
-        return $this->dateFormat;
-    }
-
-    /**
-     *
-     * @param string $dateFormat
-     */
-    public function setDateFormat(string $dateFormat)
-    {
-        Session::put('csv-date-format', $dateFormat);
-        $this->dateFormat = $dateFormat;
-    }
-
-    /**
-     * FIXxME may return null
-     *
-     * @return string
-     */
-    public function getDelimiter(): string
-    {
-        return $this->delimiter;
-    }
-
-    /**
-     *
-     * @param string $delimiter
-     */
-    public function setDelimiter(string $delimiter)
-    {
-        Session::put('csv-delimiter', $delimiter);
-        $this->delimiter = $delimiter;
-    }
-
-    /**
-     *
-     * @return array
-     */
-    public function getMap(): array
-    {
-        return $this->map;
-    }
-
-    /**
-     *
-     * @param array $map
-     */
-    public function setMap(array $map)
-    {
-        Session::put('csv-map', $map);
-        $this->map = $map;
-    }
-
-    /**
-     *
-     * @return array
-     */
-    public function getMapped(): array
-    {
-        return $this->mapped;
-    }
-
-    /**
-     *
-     * @param array $mapped
-     */
-    public function setMapped(array $mapped)
-    {
-        Session::put('csv-mapped', $mapped);
-        $this->mapped = $mapped;
-    }
-
-    /**
-     *
-     * @return Reader
-     */
-    public function getReader(): Reader
-    {
-        if (!is_null($this->csvFileContent) && strlen($this->csvFileContent) === 0) {
-            $this->loadCsvFile();
-        }
-
-        if (is_null($this->reader)) {
-            $this->reader = Reader::createFromString($this->getCsvFileContent());
-            $this->reader->setDelimiter($this->delimiter);
-        }
-
-        return $this->reader;
-    }
-
-    /**
-     *
-     * @return array
-     */
-    public function getRoles(): array
-    {
-        return $this->roles;
-    }
-
-    /**
-     *
-     * @param array $roles
-     */
-    public function setRoles(array $roles)
-    {
-        Session::put('csv-roles', $roles);
-        $this->roles = $roles;
-    }
-
-    /**
-     *
-     * @return array
-     */
-    public function getSpecifix(): array
-    {
-        return is_array($this->specifix) ? $this->specifix : [];
-    }
-
-    /**
-     *
-     * @param array $specifix
-     */
-    public function setSpecifix(array $specifix)
-    {
-        Session::put('csv-specifix', $specifix);
-        $this->specifix = $specifix;
-    }
-
-    /**
-     *
-     * @return bool
-     */
-    public function hasHeaders(): bool
-    {
-        return $this->hasHeaders;
-    }
-
-    /**
-     *
-     * @param bool $hasHeaders
-     */
-    public function setHasHeaders(bool $hasHeaders)
-    {
-        Session::put('csv-has-headers', $hasHeaders);
-        $this->hasHeaders = $hasHeaders;
-    }
-
-    /**
-     *
-     * @param int $importAccount
-     */
-    public function setImportAccount(int $importAccount)
-    {
-        Session::put('csv-import-account', $importAccount);
-        $this->importAccount = $importAccount;
-    }
-
-    protected function loadCsvFile()
-    {
-        $file             = $this->getCsvFileLocation();
-        $disk             = Storage::disk('upload');
-        $content          = $disk->get($file);
-        $contentDecrypted = Crypt::decrypt($content);
-        $this->setCsvFileContent($contentDecrypted);
-    }
-
-    protected function sessionCsvFileLocation()
-    {
-        if (Session::has('csv-file')) {
-            $this->csvFileLocation = (string)session('csv-file');
-        }
-    }
-
-    protected function sessionDateFormat()
-    {
-        if (Session::has('csv-date-format')) {
-            $this->dateFormat = (string)session('csv-date-format');
-        }
-    }
-
-    protected function sessionDelimiter()
-    {
-        if (Session::has('csv-delimiter')) {
-            $this->delimiter = session('csv-delimiter');
-        }
-    }
-
-    protected function sessionHasHeaders()
-    {
-        if (Session::has('csv-has-headers')) {
-            $this->hasHeaders = (bool)session('csv-has-headers');
-        }
-    }
-
-    protected function sessionImportAccount()
-    {
-        if (Session::has('csv-import-account')) {
-            $this->importAccount = intval(session('csv-import-account'));
-        }
-    }
-
-    protected function sessionMap()
-    {
-        if (Session::has('csv-map')) {
-            $this->map = (array)session('csv-map');
-        }
-    }
-
-    protected function sessionMapped()
-    {
-        if (Session::has('csv-mapped')) {
-            $this->mapped = (array)session('csv-mapped');
-        }
-    }
-
-    protected function sessionRoles()
-    {
-        if (Session::has('csv-roles')) {
-            $this->roles = (array)session('csv-roles');
-        }
-    }
-
-    protected function sessionSpecifix()
-    {
-        if (Session::has('csv-specifix')) {
-            $this->specifix = (array)session('csv-specifix');
-        }
-    }
-}
diff --git a/app/Helpers/Csv/Importer.php b/app/Helpers/Csv/Importer.php
index 9e50f02a46..bdf1563709 100644
--- a/app/Helpers/Csv/Importer.php
+++ b/app/Helpers/Csv/Importer.php
@@ -151,6 +151,7 @@ class Importer
 
         $transactionType = $this->getTransactionType(); // defaults to deposit
         $errors          = new MessageBag;
+        
         $journal         = TransactionJournal::create(
             [
                 'user_id'                 => Auth::user()->id,
diff --git a/app/Helpers/Csv/Mapper/AnyAccount.php b/app/Helpers/Csv/Mapper/AnyAccount.php
deleted file mode 100644
index 05c5bab9ea..0000000000
--- a/app/Helpers/Csv/Mapper/AnyAccount.php
+++ /dev/null
@@ -1,42 +0,0 @@
-accounts()->with('accountType')->orderBy('accounts.name', 'ASC')->get(['accounts.*']);
-
-        $list = [];
-        /** @var Account $account */
-        foreach ($result as $account) {
-            $list[$account->id] = $account->name . ' (' . $account->accountType->type . ')';
-        }
-        asort($list);
-
-        $list = [0 => trans('firefly.csv_do_not_map')] + $list;
-
-        return $list;
-    }
-}
diff --git a/app/Helpers/Csv/Mapper/Bill.php b/app/Helpers/Csv/Mapper/Bill.php
deleted file mode 100644
index 37946bf394..0000000000
--- a/app/Helpers/Csv/Mapper/Bill.php
+++ /dev/null
@@ -1,42 +0,0 @@
-bills()->get(['bills.*']);
-        $list   = [];
-
-        /** @var BillModel $bill */
-        foreach ($result as $bill) {
-            $list[$bill->id] = $bill->name . ' [' . $bill->match . ']';
-        }
-        asort($list);
-
-        $list = [0 => trans('firefly.csv_do_not_map')] + $list;
-
-        return $list;
-    }
-}
diff --git a/app/Helpers/Csv/Mapper/Budget.php b/app/Helpers/Csv/Mapper/Budget.php
deleted file mode 100644
index 7664cc3378..0000000000
--- a/app/Helpers/Csv/Mapper/Budget.php
+++ /dev/null
@@ -1,42 +0,0 @@
-budgets()->get(['budgets.*']);
-        $list   = [];
-
-        /** @var BudgetModel $budget */
-        foreach ($result as $budget) {
-            $list[$budget->id] = $budget->name;
-        }
-        asort($list);
-
-        $list = [0 => trans('firefly.csv_do_not_map')] + $list;
-
-        return $list;
-    }
-}
diff --git a/app/Helpers/Csv/Mapper/Category.php b/app/Helpers/Csv/Mapper/Category.php
deleted file mode 100644
index d0a104523a..0000000000
--- a/app/Helpers/Csv/Mapper/Category.php
+++ /dev/null
@@ -1,42 +0,0 @@
-categories()->get(['categories.*']);
-        $list   = [];
-
-        /** @var CategoryModel $category */
-        foreach ($result as $category) {
-            $list[$category->id] = $category->name;
-        }
-        asort($list);
-
-        $list = [0 => trans('firefly.csv_do_not_map')] + $list;
-
-        return $list;
-    }
-}
diff --git a/app/Helpers/Csv/Mapper/Tag.php b/app/Helpers/Csv/Mapper/Tag.php
deleted file mode 100644
index 637a27eed7..0000000000
--- a/app/Helpers/Csv/Mapper/Tag.php
+++ /dev/null
@@ -1,42 +0,0 @@
-budgets()->get(['tags.*']);
-        $list   = [];
-
-        /** @var TagModel $tag */
-        foreach ($result as $tag) {
-            $list[$tag->id] = $tag->tag;
-        }
-        asort($list);
-
-        $list = [0 => trans('firefly.csv_do_not_map')] + $list;
-
-        return $list;
-    }
-}
diff --git a/app/Helpers/Csv/PostProcessing/Amount.php b/app/Helpers/Csv/PostProcessing/Amount.php
deleted file mode 100644
index 504c887331..0000000000
--- a/app/Helpers/Csv/PostProcessing/Amount.php
+++ /dev/null
@@ -1,44 +0,0 @@
-data['amount'] ?? '0';
-        $modifier             = strval($this->data['amount-modifier']);
-        $this->data['amount'] = bcmul($amount, $modifier);
-
-        return $this->data;
-    }
-
-    /**
-     * @param array $data
-     */
-    public function setData(array $data)
-    {
-        $this->data = $data;
-    }
-}
diff --git a/app/Helpers/Csv/PostProcessing/AssetAccount.php b/app/Helpers/Csv/PostProcessing/AssetAccount.php
deleted file mode 100644
index e57e0f73f1..0000000000
--- a/app/Helpers/Csv/PostProcessing/AssetAccount.php
+++ /dev/null
@@ -1,274 +0,0 @@
-checkIdNameObject(); // has object in ID or Name?
-        if (!is_null($result)) {
-            return $result;
-        }
-
-        // no object? maybe asset-account-iban is a string and we can find the matching account.
-        $result = $this->checkIbanString();
-        if (!is_null($result)) {
-            return $result;
-        }
-
-        // no object still? maybe we can find the account by name.
-        $result = $this->checkNameString();
-        if (!is_null($result)) {
-            return $result;
-        }
-        // still nothing? Perhaps the account number can lead us to an account:
-        $result = $this->checkAccountNumberString();
-        if (!is_null($result)) {
-            return $result;
-        }
-
-        return null;
-    }
-
-    /**
-     * @param array $data
-     */
-    public function setData(array $data)
-    {
-        $this->data = $data;
-    }
-
-    /**
-     * @return array|null
-     */
-    protected function checkAccountNumberString()
-    {
-        $accountNumber = $this->data['asset-account-number'] ?? null;
-        if ($accountNumber instanceof Account) { // fourth: try to find account based on name, if any.
-            $this->data['asset-account-object'] = $accountNumber;
-
-            return $this->data;
-        }
-        if (is_string($accountNumber)) { // it's an actual account number
-            $this->data['asset-account-object'] = $this->parseAccountNumberString();
-
-            return $this->data;
-        }
-
-        return null;
-    }
-
-    /**
-     * @return array|null
-     */
-    protected function checkIbanString()
-    {
-        $iban      = $this->data['asset-account-iban'] ?? '';
-        $rules     = ['iban' => 'iban'];
-        $check     = ['iban' => $iban];
-        $validator = Validator::make($check, $rules);
-        if (!$validator->fails()) {
-            $this->data['asset-account-object'] = $this->parseIbanString();
-
-            return $this->data;
-        }
-
-        return null;
-    }
-
-    /**
-     * @return array
-     */
-    protected function checkIdNameObject()
-    {
-        $accountId     = $this->data['asset-account-id'] ?? null;
-        $accountIban   = $this->data['asset-account-iban'] ?? null;
-        $accountNumber = $this->data['asset-account-number'] ?? null;
-        if ($accountId instanceof Account) { // first priority. try to find the account based on ID, if any
-            $this->data['asset-account-object'] = $accountId;
-
-            return $this->data;
-        }
-        if ($accountIban instanceof Account) { // second: try to find the account based on IBAN, if any.
-            $this->data['asset-account-object'] = $accountIban;
-
-            return $this->data;
-        }
-
-        if ($accountNumber instanceof Account) { // second: try to find the account based on account number, if any.
-            $this->data['asset-account-object'] = $accountNumber;
-
-            return $this->data;
-        }
-
-
-        return null;
-    }
-
-    /**
-     * @return array|null
-     */
-    protected function checkNameString()
-    {
-        $accountName = $this->data['asset-account-name'] ?? null;
-        if ($accountName instanceof Account) { // third: try to find account based on name, if any.
-            $this->data['asset-account-object'] = $accountName;
-
-            return $this->data;
-        }
-        if (is_string($accountName)) {
-            $this->data['asset-account-object'] = $this->parseNameString();
-
-            return $this->data;
-        }
-
-        return null;
-    }
-
-    /**
-     * @return Account|null
-     */
-    protected function createAccount()
-    {
-        $accountType = $this->getAccountType();
-        $name        = $this->data['asset-account-name'] ?? '';
-        $iban        = $this->data['asset-account-iban'] ?? '';
-
-        // create if not exists: // See issue #180
-        $name    = strlen($name) > 0 ? $name : $iban;
-        $account = Account::firstOrCreateEncrypted(
-            [
-                'user_id'         => Auth::user()->id,
-                'account_type_id' => $accountType->id,
-                'name'            => $name,
-                'iban'            => $iban,
-                'active'          => true,
-            ]
-        );
-
-        return $account;
-    }
-
-    /**
-     *
-     * @return AccountType
-     */
-    protected function getAccountType()
-    {
-        return AccountType::where('type', 'Asset account')->first();
-    }
-
-    /**
-     * @return Account|null
-     */
-    protected function parseIbanString()
-    {
-        // create by name and/or iban.
-        $iban     = $this->data['asset-account-iban'] ?? '';
-        $accounts = Auth::user()->accounts()->get();
-        foreach ($accounts as $entry) {
-            if ($iban !== '' && $entry->iban === $iban) {
-
-                return $entry;
-            }
-        }
-        $account = $this->createAccount();
-
-        return $account;
-    }
-
-    /**
-     * @return Account|null
-     */
-    protected function parseNameString()
-    {
-        $accountType = $this->getAccountType();
-        $accounts    = Auth::user()->accounts()->where('account_type_id', $accountType->id)->get();
-        foreach ($accounts as $entry) {
-            if ($entry->name == $this->data['asset-account-name']) {
-
-                return $entry;
-            }
-        }
-        // create if not exists:
-        // See issue #180
-        $account = Account::firstOrCreateEncrypted(
-            [
-                'user_id'         => Auth::user()->id,
-                'account_type_id' => $accountType->id,
-                'name'            => $this->data['asset-account-name'],
-                'iban'            => '',
-                'active'          => true,
-            ]
-        );
-
-        return $account;
-    }
-
-    /**
-     * @return Account|null
-     */
-    private function parseAccountNumberString()
-    {
-        /** @var AccountCrudInterface $crud */
-        $crud = app(AccountCrudInterface::class);
-
-        $accountNumber = $this->data['asset-account-number'] ?? '';
-        $accountType   = $this->getAccountType();
-        $accounts      = Auth::user()->accounts()->with(['accountmeta'])->where('account_type_id', $accountType->id)->get();
-        /** @var Account $entry */
-        foreach ($accounts as $entry) {
-            $metaFieldValue = $entry->getMeta('accountNumber');
-            if ($metaFieldValue === $accountNumber && $metaFieldValue !== '') {
-
-                return $entry;
-            }
-        }
-        // create new if not exists and return that one:
-        $accountData = [
-            'name'                   => $accountNumber,
-            'accountType'            => 'asset',
-            'virtualBalance'         => 0,
-            'virtualBalanceCurrency' => 1, // hard coded.
-            'active'                 => true,
-            'user'                   => Auth::user()->id,
-            'iban'                   => null,
-            'accountNumber'          => $accountNumber,
-            'accountRole'            => null,
-            'openingBalance'         => 0,
-            'openingBalanceDate'     => new Carbon,
-            'openingBalanceCurrency' => 1, // hard coded.
-        ];
-        $account     = $crud->store($accountData);
-
-        return $account;
-    }
-}
diff --git a/app/Helpers/Csv/PostProcessing/Bill.php b/app/Helpers/Csv/PostProcessing/Bill.php
deleted file mode 100644
index 60392b2446..0000000000
--- a/app/Helpers/Csv/PostProcessing/Bill.php
+++ /dev/null
@@ -1,45 +0,0 @@
-data['bill']) && !is_null($this->data['bill']->id)) {
-            $this->data['bill-id'] = $this->data['bill']->id;
-        }
-
-        return $this->data;
-    }
-
-    /**
-     * @param array $data
-     */
-    public function setData(array $data)
-    {
-        $this->data = $data;
-    }
-}
diff --git a/app/Helpers/Csv/PostProcessing/Currency.php b/app/Helpers/Csv/PostProcessing/Currency.php
deleted file mode 100644
index 2a6f46cfd5..0000000000
--- a/app/Helpers/Csv/PostProcessing/Currency.php
+++ /dev/null
@@ -1,49 +0,0 @@
-data['currency'])) {
-            $currencyPreference     = Preferences::get('currencyPreference', env('DEFAULT_CURRENCY', 'EUR'));
-            $this->data['currency'] = TransactionCurrency::whereCode($currencyPreference->data)->first();
-        }
-
-        return $this->data;
-    }
-
-    /**
-     * @param array $data
-     */
-    public function setData(array $data)
-    {
-        $this->data = $data;
-    }
-}
diff --git a/app/Helpers/Csv/PostProcessing/Description.php b/app/Helpers/Csv/PostProcessing/Description.php
deleted file mode 100644
index 8c4843a58b..0000000000
--- a/app/Helpers/Csv/PostProcessing/Description.php
+++ /dev/null
@@ -1,47 +0,0 @@
-data['description'] ?? '';
-        $this->data['description'] = trim($description);
-        if (strlen($this->data['description']) == 0) {
-            $this->data['description'] = trans('firefly.csv_empty_description');
-        }
-
-
-        return $this->data;
-    }
-
-    /**
-     * @param array $data
-     */
-    public function setData(array $data)
-    {
-
-        $this->data = $data;
-    }
-}
diff --git a/app/Helpers/Csv/PostProcessing/OpposingAccount.php b/app/Helpers/Csv/PostProcessing/OpposingAccount.php
deleted file mode 100644
index 279328b24e..0000000000
--- a/app/Helpers/Csv/PostProcessing/OpposingAccount.php
+++ /dev/null
@@ -1,210 +0,0 @@
-checkIdNameObject();
-        if (!is_null($result)) {
-            return $result;
-        }
-
-        $result = $this->checkIbanString();
-        if (!is_null($result)) {
-            return $result;
-        }
-
-        $result = $this->checkNameString();
-        if (!is_null($result)) {
-            return $result;
-        }
-
-        return null;
-    }
-
-    /**
-     * @param array $data
-     */
-    public function setData(array $data)
-    {
-        $this->data = $data;
-    }
-
-    /**
-     * @return array|null
-     */
-    protected function checkIbanString()
-    {
-        $rules     = ['iban' => 'iban'];
-        $iban      = $this->data['opposing-account-iban'];
-        $check     = ['iban' => $iban];
-        $validator = Validator::make($check, $rules);
-        if (is_string($iban) && strlen($iban) > 0 && !$validator->fails()) {
-
-            $this->data['opposing-account-object'] = $this->parseIbanString();
-
-            return $this->data;
-        }
-
-        return null;
-    }
-
-    /**
-     * @return array
-     */
-    protected function checkIdNameObject()
-    {
-        if ($this->data['opposing-account-id'] instanceof Account) { // first priority. try to find the account based on ID, if any
-            $this->data['opposing-account-object'] = $this->data['opposing-account-id'];
-
-            return $this->data;
-        }
-        if ($this->data['opposing-account-iban'] instanceof Account) { // second: try to find the account based on IBAN, if any.
-            $this->data['opposing-account-object'] = $this->data['opposing-account-iban'];
-
-            return $this->data;
-        }
-
-        return null;
-    }
-
-    /**
-     * @return array|null
-     */
-    protected function checkNameString()
-    {
-        if ($this->data['opposing-account-name'] instanceof Account) { // third: try to find account based on name, if any.
-            $this->data['opposing-account-object'] = $this->data['opposing-account-name'];
-
-            return $this->data;
-        }
-        if (is_string($this->data['opposing-account-name'])) {
-
-            $this->data['opposing-account-object'] = $this->parseNameString();
-
-            return $this->data;
-        }
-
-        return null;
-    }
-
-    /**
-     * @return Account|null
-     */
-    protected function createAccount()
-    {
-        $accountType = $this->getAccountType();
-
-        // create if not exists:
-        $name    = is_string($this->data['opposing-account-name']) && strlen($this->data['opposing-account-name']) > 0 ? $this->data['opposing-account-name']
-            : $this->data['opposing-account-iban'];
-        $account = Account::firstOrCreateEncrypted( // See issue #180
-            [
-                'user_id'         => Auth::user()->id,
-                'account_type_id' => $accountType->id,
-                'name'            => $name,
-                'iban'            => $this->data['opposing-account-iban'],
-                'active'          => true,
-            ]
-        );
-
-        return $account;
-    }
-
-    /**
-     *
-     * @return AccountType
-     */
-    protected function getAccountType()
-    {
-        // opposing account type:
-        if ($this->data['amount'] < 0) {
-            // create expense account:
-
-            return AccountType::where('type', 'Expense account')->first();
-        }
-
-        // create revenue account:
-
-        return AccountType::where('type', 'Revenue account')->first();
-
-
-    }
-
-    /**
-     * @return Account|null
-     */
-    protected function parseIbanString()
-    {
-        // create by name and/or iban.
-        $accounts = Auth::user()->accounts()->get();
-        foreach ($accounts as $entry) {
-            if ($entry->iban == $this->data['opposing-account-iban']) {
-
-                return $entry;
-            }
-        }
-        $account = $this->createAccount();
-
-
-        return $account;
-    }
-
-    /**
-     * @return Account|null
-     */
-    protected function parseNameString()
-    {
-        $accountType = $this->getAccountType();
-        $accounts    = Auth::user()->accounts()->where('account_type_id', $accountType->id)->get();
-        foreach ($accounts as $entry) {
-            if ($entry->name == $this->data['opposing-account-name']) {
-
-                return $entry;
-            }
-        }
-        // create if not exists:
-        $account = Account::firstOrCreateEncrypted( // See issue #180
-            [
-                'user_id'         => Auth::user()->id,
-                'account_type_id' => $accountType->id,
-                'name'            => $this->data['opposing-account-name'],
-                'iban'            => '',
-                'active'          => true,
-            ]
-        );
-
-        return $account;
-    }
-}
diff --git a/app/Helpers/Csv/PostProcessing/PostProcessorInterface.php b/app/Helpers/Csv/PostProcessing/PostProcessorInterface.php
deleted file mode 100644
index 58f6ff09d0..0000000000
--- a/app/Helpers/Csv/PostProcessing/PostProcessorInterface.php
+++ /dev/null
@@ -1,31 +0,0 @@
-setProcessorType(self::POST_PROCESSOR);
-    }
-
-    /**
-     * @return array
-     */
-    public function fix(): array
-    {
-        return $this->data;
-
-    }
-
-    /**
-     * @param array $data
-     */
-    public function setData(array $data)
-    {
-        $this->data = $data;
-    }
-
-    /**
-     * @param array $row
-     */
-    public function setRow(array $row)
-    {
-        $this->row = $row;
-    }
-
-
-}
diff --git a/app/Helpers/Csv/Specifix/RabobankDescription.php b/app/Helpers/Csv/Specifix/RabobankDescription.php
deleted file mode 100644
index 67dbdb6c49..0000000000
--- a/app/Helpers/Csv/Specifix/RabobankDescription.php
+++ /dev/null
@@ -1,76 +0,0 @@
-setProcessorType(self::POST_PROCESSOR);
-    }
-
-
-    /**
-     * @return array
-     */
-    public function fix(): array
-    {
-        $this->rabobankFixEmptyOpposing();
-
-        return $this->data;
-
-    }
-
-    /**
-     * @param array $data
-     */
-    public function setData(array $data)
-    {
-        $this->data = $data;
-    }
-
-    /**
-     * @param array $row
-     */
-    public function setRow(array $row)
-    {
-        $this->row = $row;
-    }
-
-    /**
-     * Fixes Rabobank specific thing.
-     */
-    protected function rabobankFixEmptyOpposing()
-    {
-        if (is_string($this->data['opposing-account-name']) && strlen($this->data['opposing-account-name']) == 0) {
-            $this->data['opposing-account-name'] = $this->row[10];
-
-            $this->data['description'] = trim(str_replace($this->row[10], '', $this->data['description']));
-        }
-
-    }
-
-
-}
diff --git a/app/Helpers/Csv/Specifix/Specifix.php b/app/Helpers/Csv/Specifix/Specifix.php
deleted file mode 100644
index 8626d38dcb..0000000000
--- a/app/Helpers/Csv/Specifix/Specifix.php
+++ /dev/null
@@ -1,46 +0,0 @@
-processorType;
-    }
-
-    /**
-     * @param int $processorType
-     *
-     * @return $this
-     */
-    public function setProcessorType(int $processorType)
-    {
-        $this->processorType = $processorType;
-
-        return $this;
-    }
-
-
-}
diff --git a/app/Helpers/Csv/Specifix/SpecifixInterface.php b/app/Helpers/Csv/Specifix/SpecifixInterface.php
deleted file mode 100644
index e37d4d3ec4..0000000000
--- a/app/Helpers/Csv/Specifix/SpecifixInterface.php
+++ /dev/null
@@ -1,49 +0,0 @@
- $row) {
-            if ($this->useRow($hasHeaders, $index)) {
-                // collect all map values
-
-                foreach ($keys as $column) {
-                    $values[$column][] = $row[$column];
-                }
-            }
-        }
-        /*
-         * Make each one unique.
-         */
-        $values = $this->uniqueRecursive($values);
-
-        return $values;
-    }
-
-    /**
-     * @param array $roles
-     * @param array $map
-     *
-     * @return array
-     */
-    public function processSelectedMapping(array $roles, array $map): array
-    {
-        $configRoles = config('csv.roles');
-        $maps        = [];
-        $keys        = array_keys($map);
-        foreach ($keys as $index) {
-            if (isset($roles[$index])) {
-                $name = $roles[$index];
-                if ($configRoles[$name]['mappable']) {
-                    $maps[$index] = $name;
-                }
-            }
-        }
-
-        return $maps;
-
-    }
-
-    /**
-     * @param array $input
-     *
-     * @return array
-     */
-    public function processSelectedRoles(array $input): array
-    {
-        $roles = [];
-
-
-        /*
-         * Store all rows for each column:
-         */
-        if (is_array($input)) {
-            foreach ($input as $index => $role) {
-                if ($role != '_ignore') {
-                    $roles[$index] = $role;
-                }
-            }
-        }
-
-        return $roles;
-    }
-
-    /**
-     * @param array $fields
-     *
-     * @return bool
-     */
-    public function sessionHasValues(array $fields): bool
-    {
-        foreach ($fields as $field) {
-            if (!Session::has($field)) {
-                Log::error('Session is missing field: ' . $field);
-
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * @param array $map
-     *
-     * @return array
-     * @throws FireflyException
-     */
-    public function showOptions(array $map): array
-    {
-        $options = [];
-        foreach ($map as $index => $columnRole) {
-
-            $mapper = config('csv.roles.' . $columnRole . '.mapper');
-            if (is_null($mapper)) {
-                throw new FireflyException('Cannot map field of type "' . $columnRole . '".');
-            }
-            $class = 'FireflyIII\Helpers\Csv\Mapper\\' . $mapper;
-            try {
-                /** @var MapperInterface $mapObject */
-                $mapObject = app($class);
-            } catch (ReflectionException $e) {
-                throw new FireflyException('Column "' . $columnRole . '" cannot be mapped because mapper class ' . $mapper . ' does not exist.');
-            }
-            $set             = $mapObject->getMap();
-            $options[$index] = $set;
-        }
-
-        return $options;
-    }
-
-    /**
-     * @param string $path
-     *
-     * @return string
-     */
-    public function storeCsvFile(string $path): string
-    {
-        $time             = str_replace(' ', '-', microtime());
-        $fileName         = 'csv-upload-' . Auth::user()->id . '-' . $time . '.csv.encrypted';
-        $disk             = Storage::disk('upload');
-        $file             = new SplFileObject($path, 'r');
-        $content          = $file->fread($file->getSize());
-        $contentEncrypted = Crypt::encrypt($content);
-        $disk->put($fileName, $contentEncrypted);
-
-        return $fileName;
-
-
-    }
-
-    /**
-     * @param array $array
-     *
-     * @return array
-     */
-    protected function uniqueRecursive(array $array)
-    {
-        foreach ($array as $column => $found) {
-            $array[$column] = array_unique($found);
-        }
-
-        return $array;
-    }
-
-    /**
-     * @param bool $hasHeaders
-     * @param int  $index
-     *
-     * @return bool
-     */
-    protected function useRow(bool $hasHeaders, int $index)
-    {
-        return ($hasHeaders && $index > 1) || !$hasHeaders;
-    }
-}
diff --git a/app/Helpers/Csv/WizardInterface.php b/app/Helpers/Csv/WizardInterface.php
deleted file mode 100644
index cedcfbe5f6..0000000000
--- a/app/Helpers/Csv/WizardInterface.php
+++ /dev/null
@@ -1,68 +0,0 @@
-budgetRepository->getAllBudgetLimitRepetitions($start, $end);
         foreach ($accounts as $account) {
diff --git a/app/Helpers/Report/BudgetReportHelper.php b/app/Helpers/Report/BudgetReportHelper.php
index cf447ea4a6..547840f962 100644
--- a/app/Helpers/Report/BudgetReportHelper.php
+++ b/app/Helpers/Report/BudgetReportHelper.php
@@ -18,6 +18,7 @@ use FireflyIII\Helpers\Collection\BudgetLine;
 use FireflyIII\Models\Budget;
 use FireflyIII\Models\LimitRepetition;
 use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
+use FireflyIII\Support\CacheProperties;
 use Illuminate\Support\Collection;
 
 /**
@@ -40,6 +41,73 @@ class BudgetReportHelper implements BudgetReportHelperInterface
         $this->repository = $repository;
     }
 
+    /**
+     * @param Carbon     $start
+     * @param Carbon     $end
+     * @param Collection $accounts
+     *
+     * @return Collection
+     */
+    public function budgetYearOverview(Carbon $start, Carbon $end, Collection $accounts): Collection
+    {
+        // chart properties for cache:
+        $cache = new CacheProperties;
+        $cache->addProperty($start);
+        $cache->addProperty($end);
+        $cache->addProperty('budget-year');
+        $cache->addProperty($accounts->pluck('id')->toArray());
+        if ($cache->has()) {
+            return $cache->get();
+        }
+        
+        $headers = [];
+        $current = clone $start;
+        $return  = new Collection;
+        $set     = $this->repository->getBudgets();
+        $budgets = [];
+        $spent   = [];
+        while ($current < $end) {
+            $short           = $current->format('m-Y');
+            $headers[$short] = $current->formatLocalized((string)trans('config.month'));
+            $current->addMonth();
+        }
+
+
+        /** @var Budget $budget */
+        foreach ($set as $budget) {
+            $id           = $budget->id;
+            $budgets[$id] = $budget->name;
+            $spent[$id]   = [];
+            $current      = clone $start;
+            $sum          = '0';
+
+
+            while ($current < $end) {
+                $currentEnd = clone $current;
+                $currentEnd->endOfMonth();
+                $format              = $current->format('m-Y');
+                $budgetSpent         = $this->repository->spentInPeriod(new Collection([$budget]), $accounts, $current, $currentEnd);
+                $spent[$id][$format] = $budgetSpent;
+                $sum                 = bcadd($sum, $budgetSpent);
+                $current->addMonth();
+            }
+
+            if (bccomp('0', $sum) === 0) {
+                // not spent anything.
+                unset($spent[$id]);
+                unset($budgets[$id]);
+            }
+        }
+
+        $return->put('headers', $headers);
+        $return->put('budgets', $budgets);
+        $return->put('spent', $spent);
+
+        $cache->store($return);
+
+        return $return;
+    }
+
     /**
      * @param Carbon     $start
      * @param Carbon     $end
diff --git a/app/Helpers/Report/BudgetReportHelperInterface.php b/app/Helpers/Report/BudgetReportHelperInterface.php
index dd0290f6ae..d776da2ead 100644
--- a/app/Helpers/Report/BudgetReportHelperInterface.php
+++ b/app/Helpers/Report/BudgetReportHelperInterface.php
@@ -23,6 +23,15 @@ use Illuminate\Support\Collection;
  */
 interface BudgetReportHelperInterface
 {
+    /**
+     * @param Carbon     $start
+     * @param Carbon     $end
+     * @param Collection $accounts
+     *
+     * @return Collection
+     */
+    public function budgetYearOverview(Carbon $start, Carbon $end, Collection $accounts): Collection;
+
     /**
      * @param Carbon     $start
      * @param Carbon     $end
diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php
index 71ea51855e..f5381b4512 100644
--- a/app/Http/Controllers/AccountController.php
+++ b/app/Http/Controllers/AccountController.php
@@ -251,6 +251,7 @@ class AccountController extends Controller
             $end = Navigation::subtractPeriod($end, $range, 1);
 
         }
+        $cache->store($entries);
 
         return view('accounts.show', compact('account', 'what', 'entries', 'subTitleIcon', 'journals', 'subTitle'));
     }
@@ -270,6 +271,7 @@ class AccountController extends Controller
         $end      = Navigation::endOfPeriod($carbon, $range);
         $subTitle = $account->name . ' (' . Navigation::periodShow($start, $range) . ')';
         $page     = intval(Input::get('page'));
+        $page     = $page === 0 ? 1 : $page;
         $pageSize = Preferences::get('transactionPageSize', 50)->data;
         $offset   = ($page - 1) * $pageSize;
         $set      = $repository->journalsInPeriod(new Collection([$account]), [], $start, $end);
diff --git a/app/Http/Controllers/Admin/DomainController.php b/app/Http/Controllers/Admin/DomainController.php
new file mode 100644
index 0000000000..3c86f45708
--- /dev/null
+++ b/app/Http/Controllers/Admin/DomainController.php
@@ -0,0 +1,136 @@
+data;
+
+        // known domains
+        $knownDomains = $this->getKnownDomains();
+
+        return view('admin.domains.index', compact('title', 'mainTitleIcon', 'knownDomains', 'subTitle', 'subTitleIcon', 'domains'));
+    }
+
+
+    /**
+     * @param Request $request
+     *
+     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+     */
+    public function manual(Request $request)
+    {
+        if (strlen($request->get('domain')) === 0) {
+            Session::flash('error', trans('firefly.no_domain_filled_in'));
+
+            return redirect(route('admin.users.domains'));
+        }
+
+        $domain  = $request->get('domain');
+        $blocked = FireflyConfig::get('blocked-domains', [])->data;
+
+        if (in_array($domain, $blocked)) {
+            Session::flash('error', trans('firefly.domain_already_blocked', ['domain' => $domain]));
+
+            return redirect(route('admin.users.domains'));
+        }
+        $blocked[] = $domain;
+        FireflyConfig::set('blocked-domains', $blocked);
+
+        Session::flash('success', trans('firefly.domain_is_now_blocked', ['domain' => $domain]));
+
+        return redirect(route('admin.users.domains'));
+    }
+
+    /**
+     * @param string $domain
+     *
+     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+     */
+    public function toggleDomain(string $domain)
+    {
+        $blocked = FireflyConfig::get('blocked-domains', [])->data;
+
+        if (in_array($domain, $blocked)) {
+            $key = array_search($domain, $blocked);
+            unset($blocked[$key]);
+            sort($blocked);
+
+            FireflyConfig::set('blocked-domains', $blocked);
+            Session::flash('message', trans('firefly.domain_now_unblocked', ['domain' => $domain]));
+
+
+            return redirect(route('admin.users.domains'));
+
+        }
+
+        $blocked[] = $domain;
+
+        FireflyConfig::set('blocked-domains', $blocked);
+        Session::flash('message', trans('firefly.domain_now_blocked', ['domain' => $domain]));
+
+        return redirect(route('admin.users.domains'));
+    }
+
+    /**
+     * @return array
+     */
+    private function getKnownDomains(): array
+    {
+        $users    = User::get();
+        $set      = [];
+        $filtered = [];
+        /** @var User $user */
+        foreach ($users as $user) {
+            $email  = $user->email;
+            $parts  = explode('@', $email);
+            $domain = $parts[1];
+            $set[]  = $domain;
+        }
+        $set = array_unique($set);
+        // filter for already banned domains:
+        $blocked = FireflyConfig::get('blocked-domains', [])->data;
+
+        foreach ($set as $domain) {
+            // in the block array? ignore it.
+            if (!in_array($domain, $blocked)) {
+                $filtered[] = $domain;
+            }
+        }
+        asort($filtered);
+
+        return $filtered;
+    }
+}
diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index 996fc4c991..c55b586188 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -24,8 +24,23 @@ use Preferences;
  */
 class UserController extends Controller
 {
+
+
+    /**
+     * @param User $user
+     *
+     * @return int
+     */
+    public function edit(User $user)
+    {
+        return $user->id;
+
+    }
+
     /**
      * @param UserRepositoryInterface $repository
+     *
+     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
      */
     public function index(UserRepositoryInterface $repository)
     {
@@ -61,4 +76,5 @@ class UserController extends Controller
 
     }
 
+
 }
diff --git a/app/Http/Controllers/AttachmentController.php b/app/Http/Controllers/AttachmentController.php
index 94763e9327..903b2602e8 100644
--- a/app/Http/Controllers/AttachmentController.php
+++ b/app/Http/Controllers/AttachmentController.php
@@ -18,6 +18,7 @@ use FireflyIII\Http\Requests\AttachmentFormRequest;
 use FireflyIII\Models\Attachment;
 use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
 use Input;
+use Log;
 use Preferences;
 use Response;
 use Session;
@@ -93,9 +94,11 @@ class AttachmentController extends Controller
         if ($disk->exists($file)) {
 
             $quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
+            $content = Crypt::decrypt($disk->get($file));
 
+            Log::debug('Send file to user', ['file' =>  $quoted, 'size' => strlen($content)]);
 
-            return response(Crypt::decrypt($disk->get($file)), 200)
+            return response($content, 200)
                 ->header('Content-Description', 'File Transfer')
                 ->header('Content-Type', 'application/octet-stream')
                 ->header('Content-Disposition', 'attachment; filename=' . $quoted)
@@ -104,7 +107,7 @@ class AttachmentController extends Controller
                 ->header('Expires', '0')
                 ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
                 ->header('Pragma', 'public')
-                ->header('Content-Length', $disk->size($file));
+                ->header('Content-Length', strlen($content));
 
         }
         throw new FireflyException('Could not find the indicated attachment. The file is no longer there.');
diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php
index 7cec83dee4..e66c2561e9 100644
--- a/app/Http/Controllers/Auth/AuthController.php
+++ b/app/Http/Controllers/Auth/AuthController.php
@@ -15,6 +15,7 @@ use Auth;
 use FireflyIII\Events\UserRegistration;
 use FireflyIII\Exceptions\FireflyException;
 use FireflyIII\Http\Controllers\Controller;
+use FireflyIII\Support\Facades\FireflyConfig;
 use FireflyIII\User;
 use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
 use Illuminate\Foundation\Auth\ThrottlesLogins;
@@ -63,6 +64,7 @@ class AuthController extends Controller
      */
     public function login(Request $request)
     {
+
         $this->validate($request, [$this->loginUsername() => 'required', 'password' => 'required',]);
         $throttles = $this->isUsingThrottlesLoginsTrait();
 
@@ -177,16 +179,7 @@ class AuthController extends Controller
      */
     protected function getBlockedDomains()
     {
-        $set     = explode(',', env('BLOCKED_DOMAINS', ''));
-        $domains = [];
-        foreach ($set as $entry) {
-            $domain = trim($entry);
-            if (strlen($domain) > 0) {
-                $domains[] = $domain;
-            }
-        }
-
-        return $domains;
+        return FireflyConfig::get('blocked-domains', [])->data;
     }
 
     /**
diff --git a/app/Http/Controllers/Auth/ConfirmationController.php b/app/Http/Controllers/Auth/ConfirmationController.php
index ef0a045fd3..ea45b5efb8 100644
--- a/app/Http/Controllers/Auth/ConfirmationController.php
+++ b/app/Http/Controllers/Auth/ConfirmationController.php
@@ -13,6 +13,7 @@ namespace FireflyIII\Http\Controllers\Auth;
 
 use Auth;
 use FireflyIII\Events\ResendConfirmation;
+use FireflyIII\Events\UserIsConfirmed;
 use FireflyIII\Exceptions\FireflyException;
 use FireflyIII\Http\Controllers\Controller;
 use Illuminate\Http\Request;
@@ -36,12 +37,13 @@ class ConfirmationController extends Controller
     }
 
     /**
-     * @param string $code
+     * @param Request $request
+     * @param string  $code
      *
      * @return mixed
      * @throws FireflyException
      */
-    public function doConfirmation(string $code)
+    public function doConfirmation(Request $request, string $code)
     {
         // check user_confirmed_last_mail
 
@@ -51,6 +53,10 @@ class ConfirmationController extends Controller
         $maxDiff  = config('firefly.confirmation_age');
 
         if ($database === $code && ($now - $time <= $maxDiff)) {
+
+            // trigger user registration event:
+            event(new UserIsConfirmed(Auth::user(), $request->ip()));
+
             Preferences::setForUser(Auth::user(), 'user_confirmed', true);
             Preferences::setForUser(Auth::user(), 'user_confirmed_confirmed', time());
             Session::flash('success', strval(trans('firefly.account_is_confirmed')));
diff --git a/app/Http/Controllers/BillController.php b/app/Http/Controllers/BillController.php
index f1c9cb2db4..47ca757b4d 100644
--- a/app/Http/Controllers/BillController.php
+++ b/app/Http/Controllers/BillController.php
@@ -11,6 +11,7 @@ declare(strict_types = 1);
 
 namespace FireflyIII\Http\Controllers;
 
+use Carbon\Carbon;
 use FireflyIII\Http\Requests\BillFormRequest;
 use FireflyIII\Models\Bill;
 use FireflyIII\Models\TransactionJournal;
@@ -190,15 +191,20 @@ class BillController extends Controller
      */
     public function show(BillRepositoryInterface $repository, Bill $bill)
     {
-        $page     = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page'));
-        $pageSize = Preferences::get('transactionPageSize', 50)->data;
-        $journals = $repository->getJournals($bill, $page, $pageSize);
+        /** @var Carbon $date */
+        $date           = session('start');
+        $year           = $date->year;
+        $page           = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page'));
+        $pageSize       = Preferences::get('transactionPageSize', 50)->data;
+        $journals       = $repository->getJournals($bill, $page, $pageSize);
+        $yearAverage    = $repository->getYearAverage($bill, $date);
+        $overallAverage = $repository->getOverallAverage($bill);
         $journals->setPath('/bills/show/' . $bill->id);
         $bill->nextExpectedMatch = $repository->nextExpectedMatch($bill);
         $hideBill                = true;
         $subTitle                = e($bill->name);
 
-        return view('bills.show', compact('journals', 'hideBill', 'bill', 'subTitle'));
+        return view('bills.show', compact('journals', 'yearAverage', 'overallAverage', 'year', 'hideBill', 'bill', 'subTitle'));
     }
 
     /**
diff --git a/app/Http/Controllers/BudgetController.php b/app/Http/Controllers/BudgetController.php
index a858e82252..e6f517c9a8 100644
--- a/app/Http/Controllers/BudgetController.php
+++ b/app/Http/Controllers/BudgetController.php
@@ -164,6 +164,8 @@ class BudgetController extends Controller
      */
     public function index(BudgetRepositoryInterface $repository, AccountCrudInterface $crud)
     {
+        $repository->cleanupBudgets();
+
         $budgets    = $repository->getActiveBudgets();
         $inactive   = $repository->getInactiveBudgets();
         $spent      = '0';
diff --git a/app/Http/Controllers/Chart/BudgetController.php b/app/Http/Controllers/Chart/BudgetController.php
index 60cc1931e6..b6a80a0b7f 100644
--- a/app/Http/Controllers/Chart/BudgetController.php
+++ b/app/Http/Controllers/Chart/BudgetController.php
@@ -32,9 +32,12 @@ use Response;
 class BudgetController extends Controller
 {
 
-    /** @var  \FireflyIII\Generator\Chart\Budget\BudgetChartGeneratorInterface */
+    /** @var BudgetChartGeneratorInterface */
     protected $generator;
 
+    /** @var BudgetRepositoryInterface */
+    protected $repository;
+
     /**
      *
      */
@@ -43,6 +46,8 @@ class BudgetController extends Controller
         parent::__construct();
         // create chart generator:
         $this->generator = app(BudgetChartGeneratorInterface::class);
+
+        $this->repository = app(BudgetRepositoryInterface::class);
     }
 
     /**
@@ -136,11 +141,9 @@ class BudgetController extends Controller
     /**
      * Shows a budget list with spent/left/overspent.
      *
-     * @param BudgetRepositoryInterface $repository
-     *
      * @return \Symfony\Component\HttpFoundation\Response
      */
-    public function frontpage(BudgetRepositoryInterface $repository)
+    public function frontpage()
     {
         $start = session('start', Carbon::now()->startOfMonth());
         $end   = session('end', Carbon::now()->endOfMonth());
@@ -153,54 +156,26 @@ class BudgetController extends Controller
         if ($cache->has()) {
             return Response::json($cache->get());
         }
-        $budgets     = $repository->getActiveBudgets();
-        $repetitions = $repository->getAllBudgetLimitRepetitions($start, $end);
+        $budgets     = $this->repository->getActiveBudgets();
+        $repetitions = $this->repository->getAllBudgetLimitRepetitions($start, $end);
         $allEntries  = new Collection;
-        $format      = strval(trans('config.month_and_day'));
 
         /** @var Budget $budget */
         foreach ($budgets as $budget) {
             // get relevant repetitions:
-            $name = $budget->name;
-            $reps = $repetitions->filter(
-                function (LimitRepetition $repetition) use ($budget, $start, $end) {
-                    if ($repetition->startdate < $end && $repetition->enddate > $start && $repetition->budget_id === $budget->id) {
-                        return $repetition;
-                    }
-                }
-            );
+            $reps = $this->filterRepetitions($repetitions, $budget, $start, $end);
+
             if ($reps->count() === 0) {
-                $amount    = '0';
-                $left      = '0';
-                $spent     = $repository->spentInPeriod(new Collection([$budget]), new Collection, $start, $end);
-                $overspent = '0';
-                $allEntries->push([$name, $left, $spent, $overspent, $amount, $spent]);
-            }
-            /** @var LimitRepetition $repetition */
-            foreach ($reps as $repetition) {
-                $expenses = $repository->spentInPeriod(new Collection([$budget]), new Collection, $repetition->startdate, $repetition->enddate);
-                if ($reps->count() > 1) {
-                    $name = $budget->name . ' ' . trans(
-                            'firefly.between_dates',
-                            ['start' => $repetition->startdate->formatLocalized($format), 'end' => $repetition->enddate->formatLocalized($format)]
-                        );
-                }
-                $amount    = $repetition->amount;
-                $left      = bccomp(bcadd($amount, $expenses), '0') < 1 ? '0' : bcadd($amount, $expenses);
-                $spent     = bccomp(bcadd($amount, $expenses), '0') < 1 ? bcmul($amount, '-1') : $expenses;
-                $overspent = bccomp(bcadd($amount, $expenses), '0') < 1 ? bcadd($amount, $expenses) : '0';
-                $allEntries->push([$name, $left, $spent, $overspent, $amount, $spent]);
+                $collection = $this->spentInPeriodSingle($budget, $start, $end);
+                $allEntries = $allEntries->merge($collection);
+                continue;
             }
+            $collection = $this->spentInPeriodMulti($budget, $reps);
+            $allEntries = $allEntries->merge($collection);
 
         }
-
-        $list = $repository->journalsInPeriodWithoutBudget(new Collection, $start, $end);
-        $sum  = '0';
-        /** @var TransactionJournal $entry */
-        foreach ($list as $entry) {
-            $sum = bcadd(TransactionJournal::amount($entry), $sum);
-        }
-        $allEntries->push([trans('firefly.no_budget'), '0', '0', $sum, '0', '0']);
+        $entry = $this->spentInPeriodWithout($start, $end);
+        $allEntries->push($entry);
         $data = $this->generator->frontpage($allEntries);
         $cache->store($data);
 
@@ -335,4 +310,94 @@ class BudgetController extends Controller
 
         return Response::json($data);
     }
+
+    /**
+     * @param Collection $repetitions
+     * @param Budget     $budget
+     * @param Carbon     $start
+     * @param Carbon     $end
+     *
+     * @return Collection
+     */
+    private function filterRepetitions(Collection $repetitions, Budget $budget, Carbon $start, Carbon $end): Collection
+    {
+
+        return $repetitions->filter(
+            function (LimitRepetition $repetition) use ($budget, $start, $end) {
+                if ($repetition->startdate < $end && $repetition->enddate > $start && $repetition->budget_id === $budget->id) {
+                    return $repetition;
+                }
+            }
+        );
+    }
+
+    /**
+     * @param Budget     $budget
+     * @param Collection $repetitions
+     *
+     * @return Collection
+     */
+    private function spentInPeriodMulti(Budget $budget, Collection $repetitions): Collection
+    {
+        $format     = strval(trans('config.month_and_day'));
+        $collection = new Collection;
+        $name       = $budget->name;
+        /** @var LimitRepetition $repetition */
+        foreach ($repetitions as $repetition) {
+            $expenses = $this->repository->spentInPeriod(new Collection([$budget]), new Collection, $repetition->startdate, $repetition->enddate);
+
+            if ($repetitions->count() > 1) {
+                $name = $budget->name . ' ' . trans(
+                        'firefly.between_dates',
+                        ['start' => $repetition->startdate->formatLocalized($format), 'end' => $repetition->enddate->formatLocalized($format)]
+                    );
+            }
+            $amount    = $repetition->amount;
+            $left      = bccomp(bcadd($amount, $expenses), '0') < 1 ? '0' : bcadd($amount, $expenses);
+            $spent     = bccomp(bcadd($amount, $expenses), '0') < 1 ? bcmul($amount, '-1') : $expenses;
+            $overspent = bccomp(bcadd($amount, $expenses), '0') < 1 ? bcadd($amount, $expenses) : '0';
+            $array     = [$name, $left, $spent, $overspent, $amount, $spent];
+            $collection->push($array);
+        }
+
+        return $collection;
+    }
+
+    /**
+     * @param Budget $budget
+     * @param Carbon $start
+     * @param Carbon $end
+     *
+     * @return Collection
+     */
+    private function spentInPeriodSingle(Budget $budget, Carbon $start, Carbon $end): Collection
+    {
+        $collection = new Collection;
+        $amount     = '0';
+        $left       = '0';
+        $spent      = $this->repository->spentInPeriod(new Collection([$budget]), new Collection, $start, $end);
+        $overspent  = '0';
+        $array      = [$budget->name, $left, $spent, $overspent, $amount, $spent];
+        $collection->push($array);
+
+        return $collection;
+    }
+
+    /**
+     * @param Carbon $start
+     * @param Carbon $end
+     *
+     * @return array
+     */
+    private function spentInPeriodWithout(Carbon $start, Carbon $end):array
+    {
+        $list = $this->repository->journalsInPeriodWithoutBudget(new Collection, $start, $end);
+        $sum  = '0';
+        /** @var TransactionJournal $entry */
+        foreach ($list as $entry) {
+            $sum = bcadd(TransactionJournal::amount($entry), $sum);
+        }
+
+        return [trans('firefly.no_budget'), '0', '0', $sum, '0', '0'];
+    }
 }
diff --git a/app/Http/Controllers/Chart/CategoryController.php b/app/Http/Controllers/Chart/CategoryController.php
index 9d1d579bce..b585c0d1d2 100644
--- a/app/Http/Controllers/Chart/CategoryController.php
+++ b/app/Http/Controllers/Chart/CategoryController.php
@@ -13,8 +13,10 @@ namespace FireflyIII\Http\Controllers\Chart;
 
 
 use Carbon\Carbon;
+use FireflyIII\Crud\Account\AccountCrudInterface;
 use FireflyIII\Generator\Chart\Category\CategoryChartGeneratorInterface;
 use FireflyIII\Http\Controllers\Controller;
+use FireflyIII\Models\AccountType;
 use FireflyIII\Models\Category;
 use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI;
 use FireflyIII\Support\CacheProperties;
@@ -48,12 +50,13 @@ class CategoryController extends Controller
     /**
      * Show an overview for a category for all time, per month/week/year.
      *
-     * @param CRI      $repository
-     * @param Category $category
+     * @param CRI                  $repository
+     * @param AccountCrudInterface $crud
+     * @param Category             $category
      *
      * @return \Symfony\Component\HttpFoundation\Response
      */
-    public function all(CRI $repository, Category $category)
+    public function all(CRI $repository, AccountCrudInterface $crud, Category $category)
     {
         $start              = $repository->firstUseDate($category, new Collection);
         $range              = Preferences::get('viewRange', '1M')->data;
@@ -62,6 +65,7 @@ class CategoryController extends Controller
         $end                = new Carbon;
         $entries            = new Collection;
         $cache              = new CacheProperties;
+        $accounts           = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
         $cache->addProperty($start);
         $cache->addProperty($end);
         $cache->addProperty('all');
@@ -72,8 +76,8 @@ class CategoryController extends Controller
 
         while ($start <= $end) {
             $currentEnd = Navigation::endOfPeriod($start, $range);
-            $spent      = $repository->spentInPeriod($categoryCollection, new Collection, $start, $currentEnd);
-            $earned     = $repository->earnedInPeriod($categoryCollection, new Collection, $start, $currentEnd);
+            $spent      = $repository->spentInPeriod($categoryCollection, $accounts, $start, $currentEnd);
+            $earned     = $repository->earnedInPeriod($categoryCollection, $accounts, $start, $currentEnd);
             $date       = Navigation::periodShow($start, $range);
             $entries->push([clone $start, $date, $spent, $earned]);
             $start = Navigation::addPeriod($start, $range, 0);
@@ -250,18 +254,24 @@ class CategoryController extends Controller
     {
         $categoryCollection = new Collection([$category]);
         $cache              = new CacheProperties;
+        /** @var AccountCrudInterface $crud */
+        $crud     = app(AccountCrudInterface::class);
+        $accounts = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
+
         $cache->addProperty($start);
         $cache->addProperty($end);
+        $cache->addProperty($accounts);
         $cache->addProperty($category->id);
         $cache->addProperty('specific-period');
 
+
         if ($cache->has()) {
             return $cache->get();
         }
         $entries = new Collection;
         while ($start <= $end) {
-            $spent  = $repository->spentInPeriod($categoryCollection, new Collection, $start, $start);
-            $earned = $repository->earnedInPeriod($categoryCollection, new Collection, $start, $start);
+            $spent  = $repository->spentInPeriod($categoryCollection, $accounts, $start, $start);
+            $earned = $repository->earnedInPeriod($categoryCollection, $accounts, $start, $start);
             $date   = Navigation::periodShow($start, '1D');
             $entries->push([clone $start, $date, $spent, $earned]);
             $start->addDay();
diff --git a/app/Http/Controllers/CsvController.php b/app/Http/Controllers/CsvController.php
deleted file mode 100644
index 1ce2c57b33..0000000000
--- a/app/Http/Controllers/CsvController.php
+++ /dev/null
@@ -1,444 +0,0 @@
-wizard = app(WizardInterface::class);
-        $this->data   = app(Data::class);
-
-    }
-
-    /**
-     * Define column roles and mapping.
-     *
-     * STEP THREE
-     *
-     * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
-     */
-    public function columnRoles()
-    {
-
-        $fields = ['csv-file', 'csv-date-format', 'csv-has-headers', 'csv-import-account', 'csv-specifix', 'csv-delimiter'];
-        if (!$this->wizard->sessionHasValues($fields)) {
-            Log::error('Could not recover upload.');
-            Session::flash('warning', strval(trans('firefly.could_not_recover')));
-
-            return redirect(route('csv.index'));
-        }
-
-        $subTitle       = trans('firefly.csv_define_column_roles');
-        $firstRow       = $this->data->getReader()->fetchOne();
-        $count          = count($firstRow);
-        $headers        = [];
-        $example        = $this->data->getReader()->fetchOne(1);
-        $availableRoles = [];
-        $roles          = $this->data->getRoles();
-        $map            = $this->data->getMap();
-
-        for ($i = 1; $i <= $count; $i++) {
-            $headers[] = trans('firefly.csv_column') . ' #' . $i;
-        }
-        if ($this->data->hasHeaders()) {
-            $headers = $firstRow;
-        }
-        $keys = array_keys(config('csv.roles'));
-        foreach ($keys as $name) {
-            $availableRoles[$name] = trans('firefly.csv_column_' . $name);
-        }
-        asort($availableRoles);
-
-        return view('csv.column-roles', compact('availableRoles', 'map', 'roles', 'headers', 'example', 'subTitle'));
-    }
-
-    /**
-     * Optional download of mapping.
-     *
-     * STEP FOUR THREE-A
-     *
-     * @return \Illuminate\Http\RedirectResponse|string
-     */
-    public function downloadConfig()
-    {
-        $fields = ['csv-date-format', 'csv-has-headers', 'csv-delimiter'];
-        if (!$this->wizard->sessionHasValues($fields)) {
-            Session::flash('warning', strval(trans('firefly.could_not_recover')));
-
-            return redirect(route('csv.index'));
-        }
-        $data = [
-            'date-format' => session('csv-date-format'),
-            'has-headers' => session('csv-has-headers'),
-        ];
-        if (Session::has('csv-map')) {
-            $data['map'] = session('csv-map');
-        }
-        if (Session::has('csv-roles')) {
-            $data['roles'] = session('csv-roles');
-        }
-        if (Session::has('csv-mapped')) {
-            $data['mapped'] = session('csv-mapped');
-        }
-
-        if (Session::has('csv-specifix')) {
-            $data['specifix'] = session('csv-specifix');
-        }
-
-        $result = json_encode($data, JSON_PRETTY_PRINT);
-        $name   = sprintf('"%s"', addcslashes('csv-configuration-' . date('Y-m-d') . '.json', '"\\'));
-
-        return response($result, 200)
-            ->header('Content-disposition', 'attachment; filename=' . $name)
-            ->header('Content-Type', 'application/json')
-            ->header('Content-Description', 'File Transfer')
-            ->header('Connection', 'Keep-Alive')
-            ->header('Expires', '0')
-            ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
-            ->header('Pragma', 'public')
-            ->header('Content-Length', strlen($result));
-    }
-
-    /**
-     * @return \Illuminate\View\View
-     */
-    public function downloadConfigPage()
-    {
-        $fields = ['csv-date-format', 'csv-has-headers', 'csv-delimiter'];
-        if (!$this->wizard->sessionHasValues($fields)) {
-            Session::flash('warning', strval(trans('firefly.could_not_recover')));
-
-            return redirect(route('csv.index'));
-        }
-
-        $subTitle = trans('firefly.csv_download_config_title');
-
-        return view('csv.download-config', compact('subTitle'));
-    }
-
-    /**
-     * This method shows the initial upload form.
-     *
-     * STEP ONE
-     *
-     * @param AccountCrudInterface $crud
-     *
-     * @return \Illuminate\View\View
-     */
-    public function index(AccountCrudInterface $crud)
-    {
-        $subTitle = trans('firefly.csv_import');
-
-        Session::forget('csv-date-format');
-        Session::forget('csv-has-headers');
-        Session::forget('csv-file');
-        Session::forget('csv-import-account');
-        Session::forget('csv-map');
-        Session::forget('csv-roles');
-        Session::forget('csv-mapped');
-        Session::forget('csv-specifix');
-        Session::forget('csv-delimiter');
-
-        // get list of supported specifix
-        $specifix = [];
-        foreach (config('csv.specifix') as $entry) {
-            $specifix[$entry] = trans('firefly.csv_specifix_' . $entry);
-        }
-
-        // get a list of delimiters:
-        $delimiters = [
-            ','   => trans('form.csv_comma'),
-            ';'   => trans('form.csv_semicolon'),
-            'tab' => trans('form.csv_tab'),
-        ];
-
-        // get a list of asset accounts:
-        $accounts = ExpandedForm::makeSelectList($crud->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT]));
-
-        // can actually upload?
-        $uploadPossible = is_writable(storage_path('upload'));
-        $path           = storage_path('upload');
-
-        return view('csv.index', compact('subTitle', 'uploadPossible', 'path', 'specifix', 'accounts', 'delimiters'));
-    }
-
-    /**
-     * Parse the file.
-     *
-     * STEP FOUR
-     *
-     * @return \Illuminate\Http\RedirectResponse
-     */
-    public function initialParse()
-    {
-        $fields = ['csv-file', 'csv-date-format', 'csv-has-headers', 'csv-delimiter'];
-        if (!$this->wizard->sessionHasValues($fields)) {
-            Session::flash('warning', strval(trans('firefly.could_not_recover')));
-
-            return redirect(route('csv.index'));
-        }
-
-        // process given roles and mapping:
-        $inputMap   = Input::get('map') ?? [];
-        $inputRoles = Input::get('role') ?? [];
-        $roles      = $this->wizard->processSelectedRoles($inputRoles);
-        $maps       = $this->wizard->processSelectedMapping($roles, $inputMap);
-
-        Session::put('csv-map', $maps);
-        Session::put('csv-roles', $roles);
-
-        // Go back when no roles defined:
-        if (count($roles) === 0) {
-            Session::flash('warning', strval(trans('firefly.must_select_roles')));
-
-            return redirect(route('csv.column-roles'));
-        }
-
-        /*
-         * Continue with map specification when necessary.
-         */
-        if (count($maps) > 0) {
-            return redirect(route('csv.map'));
-        }
-
-        /*
-         * Or simply start processing.
-         */
-
-        // proceed to download config
-        return redirect(route('csv.download-config-page'));
-
-    }
-
-    /**
-     *
-     * Map first if necessary,
-     *
-     * STEP FIVE.
-     *
-     * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
-     * @throws FireflyException
-     */
-    public function map()
-    {
-
-        // Make sure all fields we need are accounted for.
-        $fields = ['csv-file', 'csv-date-format', 'csv-has-headers', 'csv-map', 'csv-roles', 'csv-delimiter'];
-        if (!$this->wizard->sessionHasValues($fields)) {
-            Session::flash('warning', strval(trans('firefly.could_not_recover')));
-
-            return redirect(route('csv.index'));
-        }
-        /*
-         * The "options" array contains all options the user has
-         * per column, where the key represents the column.
-         *
-         * For each key there is an array which in turn represents
-         * all the options available: grouped by ID.
-         *
-         * options[column index] = [
-         *       field id => field identifier.
-         * ]
-         */
-        $options = $this->wizard->showOptions($this->data->getMap());
-
-        // After these values are prepped, read the actual CSV file
-        $reader     = $this->data->getReader();
-        $map        = $this->data->getMap();
-        $hasHeaders = $this->data->hasHeaders();
-        $values     = $this->wizard->getMappableValues($reader, $map, $hasHeaders);
-        $map        = $this->data->getMap();
-        $mapped     = $this->data->getMapped();
-        $subTitle   = trans('firefly.csv_map_values');
-
-        return view('csv.map', compact('map', 'options', 'values', 'mapped', 'subTitle'));
-    }
-
-    /**
-     *
-     * Finally actually process the CSV file.
-     *
-     * STEP SEVEN
-     *
-     * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
-     */
-    public function process()
-    {
-        /*
-         * Make sure all fields we need are accounted for.
-         */
-        $fields = ['csv-file', 'csv-date-format', 'csv-has-headers', 'csv-map', 'csv-roles', 'csv-mapped', 'csv-delimiter'];
-        if (!$this->wizard->sessionHasValues($fields)) {
-            Session::flash('warning', strval(trans('firefly.could_not_recover')));
-
-            return redirect(route('csv.index'));
-        }
-
-        /** @var Importer $importer */
-        $importer = app(Importer::class);
-        $importer->setData($this->data);
-        $importer->run();
-
-        $rows     = $importer->getRows();
-        $errors   = $importer->getErrors();
-        $imported = $importer->getImported();
-        $journals = $importer->getJournals();
-
-        Preferences::mark();
-
-        $subTitle = trans('firefly.csv_process_title');
-
-        return view('csv.process', compact('rows', 'errors', 'imported', 'subTitle', 'journals'));
-
-    }
-
-    /**
-     * Store the mapping the user has made. This is
-     *
-     * STEP SIX
-     *
-     *
-     * @return \Illuminate\Http\RedirectResponse
-     */
-    public function saveMapping()
-    {
-        /*
-         * Make sure all fields we need are accounted for.
-         */
-        $fields = ['csv-file', 'csv-date-format', 'csv-has-headers', 'csv-map', 'csv-roles', 'csv-delimiter'];
-        if (!$this->wizard->sessionHasValues($fields)) {
-            Session::flash('warning', strval(trans('firefly.could_not_recover')));
-
-            return redirect(route('csv.index'));
-        }
-
-        // save mapping to session.
-        $mapped = [];
-        if (!is_array(Input::get('mapping'))) {
-            Session::flash('warning', strval(trans('firefly.invalid_mapping')));
-
-            return redirect(route('csv.map'));
-        }
-
-        foreach (Input::get('mapping') as $index => $data) {
-            $mapped[$index] = [];
-            foreach ($data as $value => $mapping) {
-                if (intval($mapping) !== 0) {
-                    $mapped[$index][$value] = $mapping;
-                }
-            }
-        }
-        Session::put('csv-mapped', $mapped);
-
-        // proceed to process.
-        return redirect(route('csv.download-config-page'));
-
-    }
-
-    /**
-     *
-     * This method processes the file, puts it away somewhere safe
-     * and sends you onwards.
-     *
-     * STEP TWO
-     *
-     * @param Request $request
-     *
-     * @return \Illuminate\Http\RedirectResponse
-     */
-    public function upload(Request $request)
-    {
-        if (!$request->hasFile('csv')) {
-            Session::flash('warning', strval(trans('firefly.no_file_uploaded')));
-
-            return redirect(route('csv.index'));
-        }
-
-        $path                       = $this->wizard->storeCsvFile($request->file('csv')->getRealPath());
-        $settings                   = [];
-        $settings['date-format']    = Input::get('date_format');
-        $settings['has-headers']    = intval(Input::get('has_headers')) === 1;
-        $settings['specifix']       = is_array(Input::get('specifix')) ? Input::get('specifix') : [];
-        $settings['import-account'] = intval(Input::get('csv_import_account'));
-        $settings['delimiter']      = Input::get('csv_delimiter', ',');
-
-        // A tab character cannot be used itself as option value in HTML
-        // See http://stackoverflow.com/questions/6064135/valid-characters-in-option-value
-        if ($settings['delimiter'] == 'tab') {
-            $settings['delimiter'] = "\t";
-        }
-
-        $settings['map']    = [];
-        $settings['mapped'] = [];
-        $settings['roles']  = [];
-
-        if ($request->hasFile('csv_config')) { // Process config file if present.
-
-            $size = $request->file('csv_config')->getSize();
-            $data = $request->file('csv_config')->openFile()->fread($size);
-            $json = json_decode($data, true);
-            if (is_array($json)) {
-                $settings = array_merge($settings, $json);
-            }
-        }
-
-        $this->data->setCsvFileLocation($path);
-        $this->data->setDateFormat($settings['date-format']);
-        $this->data->setHasHeaders($settings['has-headers']);
-        $this->data->setMap($settings['map']);
-        $this->data->setMapped($settings['mapped']);
-        $this->data->setRoles($settings['roles']);
-        $this->data->setSpecifix($settings['specifix']);
-        $this->data->setImportAccount($settings['import-account']);
-        $this->data->setDelimiter($settings['delimiter']);
-
-        return redirect(route('csv.column-roles'));
-
-    }
-}
diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index 172b4c6695..c70d974824 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -18,8 +18,9 @@ use FireflyIII\Models\AccountType;
 use FireflyIII\Models\Tag;
 use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
 use FireflyIII\Repositories\Tag\TagRepositoryInterface;
+use Illuminate\Http\Request;
 use Illuminate\Support\Collection;
-use Input;
+use Log;
 use Preferences;
 use Route;
 use Session;
@@ -41,18 +42,24 @@ class HomeController extends Controller
         parent::__construct();
     }
 
-    public function dateRange()
+    /**
+     * @param Request $request
+     */
+    public function dateRange(Request $request)
     {
 
-        $start         = new Carbon(Input::get('start'));
-        $end           = new Carbon(Input::get('end'));
-        $label         = Input::get('label');
+        $start         = new Carbon($request->get('start'));
+        $end           = new Carbon($request->get('end'));
+        $label         = $request->get('label');
         $isCustomRange = false;
 
+        Log::debug('Received dateRange', ['start' => $request->get('start'), 'end' => $request->get('end'), 'label' => $request->get('label')]);
+
         // check if the label is "everything" or "Custom range" which will betray
         // a possible problem with the budgets.
         if ($label === strval(trans('firefly.everything')) || $label === strval(trans('firefly.customRange'))) {
             $isCustomRange = true;
+            Log::debug('Range is now marked as "custom".');
         }
 
         $diff = $start->diffInDays($end);
@@ -112,6 +119,7 @@ class HomeController extends Controller
      */
     public function index(ARI $repository, AccountCrudInterface $crud)
     {
+
         $types = config('firefly.accountTypesByIdentifier.asset');
         $count = $repository->countAccounts($types);
 
@@ -173,11 +181,11 @@ class HomeController extends Controller
             $search  = [
                 '{account}', '{what}', '{rule}', '{tj}', '{category}', '{budget}', '{code}', '{date}', '{attachment}', '{bill}', '{limitrepetition}',
                 '{currency}', '{jobKey}', '{piggyBank}', '{ruleGroup}', '{rule}', '{route}', '{unfinishedJournal}',
-                '{reportType}', '{start_date}', '{end_date}', '{accountList}','{tag}','{journalList}'
+                '{reportType}', '{start_date}', '{end_date}', '{accountList}', '{tag}', '{journalList}',
 
             ];
             $replace = [1, 'asset', 1, 1, 1, 1, 'abc', '2016-01-01', 1, 1, 1, 1, 1, 1, 1, 1, 'index', 1,
-                        'default', '20160101', '20160131', '1,2',1,'1,2'
+                        'default', '20160101', '20160131', '1,2', 1, '1,2',
             ];
             if (count($search) != count($replace)) {
                 echo 'count';
diff --git a/app/Http/Controllers/ImportController.php b/app/Http/Controllers/ImportController.php
index 0319bdb87f..2d10dc6c1f 100644
--- a/app/Http/Controllers/ImportController.php
+++ b/app/Http/Controllers/ImportController.php
@@ -1,8 +1,26 @@
  $job->key]);
+        if (!$this->jobInCorrectStep($job, 'complete')) {
+            return $this->redirectToCorrectStep($job);
+        }
+        $subTitle     = trans('firefy.import_complete');
+        $subTitleIcon = 'fa-star';
+
+        return view('import.complete', compact('job', 'subTitle', 'subTitleIcon'));
+    }
+
+    /**
+     * This is step 3.
+     * This is the first step in configuring the job. It can only be executed
+     * when the job is set to "import_status_never_started".
+     *
+     * @param ImportJob $job
+     *
+     * @return View
+     * @throws FireflyException
+     */
+    public function configure(ImportJob $job)
+    {
+        Log::debug('Now at start of configure()');
+        if (!$this->jobInCorrectStep($job, 'configure')) {
+            Log::debug('Job is not in correct state for configure()', ['status' => $job->status]);
+
+            return $this->redirectToCorrectStep($job);
+        }
+
+        // actual code
+        $importer = $this->makeImporter($job);
+        $importer->configure();
+        $data         = $importer->getConfigurationData();
+        $subTitle     = trans('firefly.configure_import');
+        $subTitleIcon = 'fa-wrench';
+
+        return view('import.' . $job->file_type . '.configure', compact('data', 'job', 'subTitle', 'subTitleIcon'));
+
+
+    }
+
+    /**
+     * Generate a JSON file of the job's config and send it to the user.
+     *
+     * @param ImportJob $job
+     *
+     * @return mixed
+     */
+    public function download(ImportJob $job)
+    {
+        Log::debug('Now in download()', ['job' => $job->key]);
+        $config                            = $job->configuration;
+        $config['column-roles-complete']   = false;
+        $config['column-mapping-complete'] = false;
+        $result                            = json_encode($config, JSON_PRETTY_PRINT);
+        $name                              = sprintf('"%s"', addcslashes('import-configuration-' . date('Y-m-d') . '.json', '"\\'));
+
+        return response($result, 200)
+            ->header('Content-disposition', 'attachment; filename=' . $name)
+            ->header('Content-Type', 'application/json')
+            ->header('Content-Description', 'File Transfer')
+            ->header('Connection', 'Keep-Alive')
+            ->header('Expires', '0')
+            ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
+            ->header('Pragma', 'public')
+            ->header('Content-Length', strlen($result));
+
+
+    }
+
+    /**
+     * This is step 1. Upload a file.
+     *
+     * @return View
      */
     public function index()
     {
+        Log::debug('Now at index');
         $subTitle          = trans('firefly.import_data_index');
         $subTitleIcon      = 'fa-home';
         $importFileTypes   = [];
@@ -38,4 +138,224 @@ class ImportController extends Controller
 
         return view('import.index', compact('subTitle', 'subTitleIcon', 'importFileTypes', 'defaultImportType'));
     }
+
+    /**
+     * Step 4. Save the configuration.
+     *
+     * @param Request   $request
+     * @param ImportJob $job
+     *
+     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+     * @throws FireflyException
+     */
+    public function postConfigure(Request $request, ImportJob $job)
+    {
+        Log::debug('Now in postConfigure()', ['job' => $job->key]);
+        if (!$this->jobInCorrectStep($job, 'process')) {
+            return $this->redirectToCorrectStep($job);
+        }
+        Log::debug('Continue postConfigure()', ['job' => $job->key]);
+
+        // actual code
+        $importer = $this->makeImporter($job);
+        $data     = $request->all();
+        $files    = $request->files;
+        $importer->saveImportConfiguration($data, $files);
+
+        // update job:
+        $job->status = 'import_configuration_saved';
+        $job->save();
+
+        // return redirect to settings.
+        // this could loop until the user is done.
+        return redirect(route('import.settings', [$job->key]));
+    }
+
+    /**
+     * This step 6. Depending on the importer, this will process the
+     * settings given and store them.
+     *
+     * @param Request   $request
+     * @param ImportJob $job
+     *
+     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+     * @throws FireflyException
+     */
+    public function postSettings(Request $request, ImportJob $job)
+    {
+        Log::debug('Now in postSettings()', ['job' => $job->key]);
+        if (!$this->jobInCorrectStep($job, 'store-settings')) {
+            return $this->redirectToCorrectStep($job);
+        }
+        $importer = $this->makeImporter($job);
+        $importer->storeSettings($request);
+
+        // return redirect to settings (for more settings perhaps)
+        return redirect(route('import.settings', [$job->key]));
+    }
+
+    /**
+     * Step 5. Depending on the importer, this will show the user settings to
+     * fill in.
+     *
+     * @param ImportJob $job
+     *
+     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+     * @throws FireflyException
+     */
+    public function settings(ImportJob $job)
+    {
+        Log::debug('Now in settings()', ['job' => $job->key]);
+        if (!$this->jobInCorrectStep($job, 'settings')) {
+            Log::debug('Job should not be in settings()');
+
+            return $this->redirectToCorrectStep($job);
+        }
+        Log::debug('Continue in settings()');
+        $importer     = $this->makeImporter($job);
+        $subTitle     = trans('firefly.settings_for_import');
+        $subTitleIcon = 'fa-wrench';
+
+        // now show settings screen to user.
+        if ($importer->requireUserSettings()) {
+            Log::debug('Job requires user config.');
+            $data = $importer->getDataForSettings();
+            $view = $importer->getViewForSettings();
+
+            return view($view, compact('data', 'job', 'subTitle', 'subTitleIcon'));
+        }
+        Log::debug('Job does NOT require user config.');
+
+        $job->status = 'settings_complete';
+        $job->save();
+
+        // if no more settings, save job and continue to process thing.
+        return redirect(route('import.complete', [$job->key]));
+
+        // ask the importer for the requested action.
+        // for example pick columns or map data.
+        // depends of course on the data in the job.
+    }
+
+    /**
+     * This is step 2. It creates an Import Job. Stores the import.
+     *
+     * @param ImportUploadRequest          $request
+     * @param ImportJobRepositoryInterface $repository
+     *
+     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+     */
+    public function upload(ImportUploadRequest $request, ImportJobRepositoryInterface $repository)
+    {
+        Log::debug('Now in upload()');
+        // create import job:
+        $type = $request->get('import_file_type');
+        $job  = $repository->create($type);
+        Log::debug('Created new job', ['key' => $job->key, 'id' => $job->id]);
+
+        /** @var UploadedFile $upload */
+        $upload           = $request->files->get('import_file');
+        $newName          = $job->key . '.upload';
+        $uploaded         = new SplFileObject($upload->getRealPath());
+        $content          = $uploaded->fread($uploaded->getSize());
+        $contentEncrypted = Crypt::encrypt($content);
+        $disk             = Storage::disk('upload');
+        $disk->put($newName, $contentEncrypted);
+
+        Log::debug('Uploaded file', ['name' => $upload->getClientOriginalName(), 'size' => $upload->getSize(), 'mime' => $upload->getClientMimeType()]);
+
+        // store configuration file's content into the job's configuration
+        // thing.
+        // otherwise, leave it empty.
+        if ($request->files->has('configuration_file')) {
+            /** @var UploadedFile $configFile */
+            $configFile = $request->files->get('configuration_file');
+            Log::debug(
+                'Uploaded configuration file',
+                ['name' => $configFile->getClientOriginalName(), 'size' => $configFile->getSize(), 'mime' => $configFile->getClientMimeType()]
+            );
+
+            $configFileObject = new SplFileObject($configFile->getRealPath());
+            $configRaw        = $configFileObject->fread($configFileObject->getSize());
+            $configuration    = json_decode($configRaw, true);
+
+            if (!is_null($configuration) && is_array($configuration)) {
+                Log::debug('Found configuration', $configuration);
+                $job->configuration = $configuration;
+                $job->save();
+            }
+        }
+
+        return redirect(route('import.configure', [$job->key]));
+
+    }
+
+    /**
+     * @param ImportJob $job
+     * @param string    $method
+     *
+     * @return bool
+     */
+    private function jobInCorrectStep(ImportJob $job, string $method): bool
+    {
+        Log::debug('Now in jobInCorrectStep()', ['job' => $job->key, 'method' => $method]);
+        switch ($method) {
+            case 'configure':
+            case 'process':
+                return $job->status === 'import_status_never_started';
+            case 'settings':
+            case 'store-settings':
+                return $job->status === 'import_configuration_saved';
+            case 'complete':
+                return $job->status === 'settings_complete';
+        }
+
+        return false;
+
+    }
+
+    /**
+     * @param ImportJob $job
+     *
+     * @return SetupInterface
+     */
+    private function makeImporter(ImportJob $job): SetupInterface
+    {
+        // create proper importer (depends on job)
+        $type = $job->file_type;
+        /** @var SetupInterface $importer */
+        $importer = app('FireflyIII\Import\Setup\\' . ucfirst($type) . 'Setup');
+        $importer->setJob($job);
+
+        return $importer;
+
+    }
+
+    /**
+     * @param ImportJob $job
+     *
+     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+     * @throws FireflyException
+     */
+    private function redirectToCorrectStep(ImportJob $job)
+    {
+        Log::debug('Now in redirectToCorrectStep()', ['job' => $job->key]);
+        switch ($job->status) {
+            case 'import_status_never_started':
+                Log::debug('Will redirect to configure()');
+
+                return redirect(route('import.configure', [$job->key]));
+            case 'import_configuration_saved':
+                Log::debug('Will redirect to settings()');
+
+                return redirect(route('import.settings', [$job->key]));
+            case 'settings_complete':
+                Log::debug('Will redirect to complete()');
+
+                return redirect(route('import.complete', [$job->key]));
+        }
+
+        throw new FireflyException('Cannot redirect for job state ' . $job->status);
+
+    }
 }
diff --git a/app/Http/Controllers/NewUserController.php b/app/Http/Controllers/NewUserController.php
index 3c7dcd4102..81c2e05dda 100644
--- a/app/Http/Controllers/NewUserController.php
+++ b/app/Http/Controllers/NewUserController.php
@@ -42,6 +42,7 @@ class NewUserController extends Controller
      */
     public function index(ARI $repository)
     {
+
         View::share('title', 'Welcome to Firefly!');
         View::share('mainTitleIcon', 'fa-fire');
 
diff --git a/app/Http/Controllers/PiggyBankController.php b/app/Http/Controllers/PiggyBankController.php
index a3ec4d3d52..a7603d4bf2 100644
--- a/app/Http/Controllers/PiggyBankController.php
+++ b/app/Http/Controllers/PiggyBankController.php
@@ -48,6 +48,26 @@ class PiggyBankController extends Controller
         View::share('mainTitleIcon', 'fa-sort-amount-asc');
     }
 
+    /**
+     * Add money to piggy bank (for mobile devices)
+     *
+     * @param ARI       $repository
+     * @param PiggyBank $piggyBank
+     *
+     * @return $this
+     */
+    public function addMobile(ARI $repository, PiggyBank $piggyBank)
+    {
+        /** @var Carbon $date */
+        $date          = session('end', Carbon::now()->endOfMonth());
+        $leftOnAccount = $repository->leftOnAccount($piggyBank->account, $date);
+        $savedSoFar    = $piggyBank->currentRelevantRep()->currentamount;
+        $leftToSave    = bcsub($piggyBank->targetamount, $savedSoFar);
+        $maxAmount     = min($leftOnAccount, $leftToSave);
+
+        return view('piggy-banks.add-mobile', compact('piggyBank', 'maxAmount'));
+    }
+
     /**
      * Add money to piggy bank
      *
@@ -335,8 +355,6 @@ class PiggyBankController extends Controller
             'startdate'     => new Carbon,
             'account_id'    => intval($request->get('account_id')),
             'targetamount'  => round($request->get('targetamount'), 2),
-            'remind_me'     => false,
-            'reminder_skip' => 0,
             'order'         => $repository->getMaxOrder() + 1,
             'targetdate'    => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null,
         ];
@@ -371,8 +389,6 @@ class PiggyBankController extends Controller
             'startdate'     => is_null($piggyBank->startdate) ? $piggyBank->created_at : $piggyBank->startdate,
             'account_id'    => intval($request->get('account_id')),
             'targetamount'  => round($request->get('targetamount'), 2),
-            'remind_me'     => false,
-            'reminder_skip' => 0,
             'targetdate'    => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null,
         ];
 
diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php
index 95cf5fad7d..1febd0a0ab 100644
--- a/app/Http/Controllers/ProfileController.php
+++ b/app/Http/Controllers/ProfileController.php
@@ -12,10 +12,12 @@ declare(strict_types = 1);
 namespace FireflyIII\Http\Controllers;
 
 use Auth;
+use FireflyIII\Events\UserIsDeleted;
 use FireflyIII\Http\Requests\DeleteAccountFormRequest;
 use FireflyIII\Http\Requests\ProfileFormRequest;
 use FireflyIII\User;
 use Hash;
+use Preferences;
 use Session;
 
 /**
@@ -106,6 +108,13 @@ class ProfileController extends Controller
             return redirect(route('profile.delete-account'));
         }
 
+        // respond to deletion:
+        event(new UserIsDeleted(Auth::user(), $request->ip()));
+
+        // store some stuff for the future:
+        $registration = Preferences::get('registration_ip_address')->data;
+        $confirmation = Preferences::get('confirmation_ip_address')->data;
+
         // DELETE!
         $email = Auth::user()->email;
         Auth::user()->delete();
@@ -114,7 +123,7 @@ class ProfileController extends Controller
         Session::flash('gaEventAction', 'delete-account');
 
         // create a new user with the same email address so re-registration is blocked.
-        User::create(
+        $newUser = User::create(
             [
                 'email'        => $email,
                 'password'     => 'deleted',
@@ -122,6 +131,13 @@ class ProfileController extends Controller
                 'blocked_code' => 'deleted',
             ]
         );
+        if (strlen($registration) > 0) {
+            Preferences::setForUser($newUser, 'registration_ip_address', $registration);
+
+        }
+        if (strlen($confirmation) > 0) {
+            Preferences::setForUser($newUser, 'confirmation_ip_address', $confirmation);
+        }
 
         return redirect(route('index'));
     }
diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php
index 099aa84518..037d3c2ab1 100644
--- a/app/Http/Controllers/ReportController.php
+++ b/app/Http/Controllers/ReportController.php
@@ -320,9 +320,7 @@ class ReportController extends Controller
         $incomes       = $this->helper->getIncomeReport($start, $end, $accounts);
         $expenses      = $this->helper->getExpenseReport($start, $end, $accounts);
         $tags          = $this->helper->tagReport($start, $end, $accounts);
-
-        // find the budgets we've spent money on this period with these accounts:
-        $budgets = $this->budgetHelper->getBudgetsWithExpenses($start, $end, $accounts);
+        $budgets       = $this->budgetHelper->budgetYearOverview($start, $end, $accounts);
 
         Session::flash('gaEventCategory', 'report');
         Session::flash('gaEventAction', 'year');
diff --git a/app/Http/Controllers/Transaction/MassController.php b/app/Http/Controllers/Transaction/MassController.php
index a8b0ccc636..ec44c1ad11 100644
--- a/app/Http/Controllers/Transaction/MassController.php
+++ b/app/Http/Controllers/Transaction/MassController.php
@@ -110,13 +110,40 @@ class MassController extends Controller
         $crud        = app('FireflyIII\Crud\Account\AccountCrudInterface');
         $accountList = ExpandedForm::makeSelectList($crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]));
 
+        // skip transactions that have multiple destinations
+        // or multiple sources:
+        $filtered = new Collection;
+        $messages = [];
+        /**
+         * @var int                $index
+         * @var TransactionJournal $journal
+         */
+        foreach ($journals as $index => $journal) {
+            $sources      = TransactionJournal::sourceAccountList($journal);
+            $destinations = TransactionJournal::destinationAccountList($journal);
+            if ($sources->count() > 1) {
+                $messages[] = trans('firefly.cannot_edit_multiple_source', ['description' => $journal->description, 'id' => $journal->id]);
+                continue;
+            }
+
+            if ($destinations->count() > 1) {
+                $messages[] = trans('firefly.cannot_edit_multiple_dest', ['description' => $journal->description, 'id' => $journal->id]);
+                continue;
+            }
+            $filtered->push($journal);
+        }
+
+        if (count($messages)) {
+            Session::flash('info', $messages);
+        }
+
         // put previous url in session
         Session::put('transactions.mass-edit.url', URL::previous());
         Session::flash('gaEventCategory', 'transactions');
         Session::flash('gaEventAction', 'mass-edit');
 
         // set some values to be used in the edit routine:
-        $journals->each(
+        $filtered->each(
             function (TransactionJournal $journal) {
                 $journal->amount            = TransactionJournal::amountPositive($journal);
                 $sources                    = TransactionJournal::sourceAccountList($journal);
@@ -133,6 +160,12 @@ class MassController extends Controller
             }
         );
 
+        if ($filtered->count() === 0) {
+            Session::flash('error', trans('firefly.no_edit_multiple_left'));
+        }
+
+        $journals = $filtered;
+
         return view('transactions.mass-edit', compact('journals', 'subTitle', 'accountList'));
     }
 
@@ -151,33 +184,26 @@ class MassController extends Controller
                 $journal = $repository->find(intval($journalId));
                 if ($journal) {
                     // get optional fields:
-                    $what            = strtolower(TransactionJournal::transactionTypeStr($journal));
-                    $sourceAccountId = $request->get('source_account_id')[$journal->id] ??  0;
-                    $destAccountId   = $request->get('destination_account_id')[$journal->id] ??  0;
-                    $expenseAccount  = $request->get('expense_account')[$journal->id] ?? '';
-                    $revenueAccount  = $request->get('revenue_account')[$journal->id] ?? '';
-                    $budgetId        = $journal->budgets->first() ? $journal->budgets->first()->id : 0;
-                    $category        = $journal->categories->first() ? $journal->categories->first()->name : '';
-                    $tags            = $journal->tags->pluck('tag')->toArray();
+                    $what = strtolower(TransactionJournal::transactionTypeStr($journal));
 
-                    // for a deposit, the 'account_id' is the account the money is deposited on.
-                    // needs a better way of handling.
-                    // more uniform source/destination field names
-                    $accountId = $sourceAccountId;
-                    if ($what == 'deposit') {
-                        $accountId = $destAccountId;
-                    }
+                    $sourceAccountId   = $request->get('source_account_id')[$journal->id] ??  0;
+                    $sourceAccountName = $request->get('source_account_name')[$journal->id] ?? '';
+                    $destAccountId     = $request->get('destination_account_id')[$journal->id] ??  0;
+                    $destAccountName   = $request->get('destination_account_name')[$journal->id] ?? '';
+
+                    $budgetId = $journal->budgets->first() ? $journal->budgets->first()->id : 0;
+                    $category = $journal->categories->first() ? $journal->categories->first()->name : '';
+                    $tags     = $journal->tags->pluck('tag')->toArray();
 
                     // build data array
                     $data = [
                         'id'                        => $journal->id,
                         'what'                      => $what,
                         'description'               => $request->get('description')[$journal->id],
-                        'account_id'                => intval($accountId),
-                        'account_from_id'           => intval($sourceAccountId),
-                        'account_to_id'             => intval($destAccountId),
-                        'expense_account'           => $expenseAccount,
-                        'revenue_account'           => $revenueAccount,
+                        'source_account_id'         => intval($sourceAccountId),
+                        'source_account_name'       => intval($destAccountId),
+                        'destination_account_id'    => $sourceAccountName,
+                        'destination_account_name'  => $destAccountName,
                         'amount'                    => round($request->get('amount')[$journal->id], 4),
                         'user'                      => Auth::user()->id,
                         'amount_currency_id_amount' => intval($request->get('amount_currency_id_amount_' . $journal->id)),
@@ -204,4 +230,4 @@ class MassController extends Controller
         return redirect(session('transactions.mass-edit.url'));
 
     }
-}
\ No newline at end of file
+}
diff --git a/app/Http/Controllers/Transaction/SplitController.php b/app/Http/Controllers/Transaction/SplitController.php
index ee63c6a2ed..43e3d2e821 100644
--- a/app/Http/Controllers/Transaction/SplitController.php
+++ b/app/Http/Controllers/Transaction/SplitController.php
@@ -358,4 +358,4 @@ class SplitController extends Controller
         return $return;
     }
 
-}
\ No newline at end of file
+}
diff --git a/app/Http/Controllers/TransactionController.php b/app/Http/Controllers/TransactionController.php
index 3250147493..054801ddc5 100644
--- a/app/Http/Controllers/TransactionController.php
+++ b/app/Http/Controllers/TransactionController.php
@@ -197,7 +197,7 @@ class TransactionController extends Controller
      */
     public function index(Request $request, JournalRepositoryInterface $repository, string $what)
     {
-        $pageSize     = Preferences::get('transactionPageSize', 50)->data;
+        $pageSize     = intval(Preferences::get('transactionPageSize', 50)->data);
         $subTitleIcon = config('firefly.transactionIconsByWhat.' . $what);
         $types        = config('firefly.transactionTypesByWhat.' . $what);
         $subTitle     = trans('firefly.title_' . $what);
@@ -223,7 +223,7 @@ class TransactionController extends Controller
         if (count($ids) > 0) {
             $order = 0;
             foreach ($ids as $id) {
-                $journal = $repository->find($id);
+                $journal = $repository->find(intval($id));
                 if ($journal && $journal->date->format('Y-m-d') == $date->format('Y-m-d')) {
                     $journal->order = $order;
                     $order++;
@@ -274,6 +274,8 @@ class TransactionController extends Controller
         // store the journal only, flash the rest.
         if ($doSplit) {
             $journal = $repository->storeJournal($journalData);
+            $journal->completed = false;
+            $journal->save();
 
             // store attachments:
             $att->saveAttachmentsForModel($journal);
diff --git a/app/Http/Middleware/Range.php b/app/Http/Middleware/Range.php
index 2c9638ec97..91e6f4b9aa 100644
--- a/app/Http/Middleware/Range.php
+++ b/app/Http/Middleware/Range.php
@@ -13,6 +13,7 @@ namespace FireflyIII\Http\Middleware;
 
 use Carbon\Carbon;
 use Closure;
+use FireflyIII\Exceptions\FireflyException;
 use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
 use Illuminate\Contracts\Auth\Guard;
 use Illuminate\Http\Request;
@@ -64,7 +65,6 @@ class Range
             // ignore preference. set the range to be the current month:
             if (!Session::has('start') && !Session::has('end')) {
 
-                /** @var \FireflyIII\Models\Preference $viewRange */
                 $viewRange = Preferences::get('viewRange', '1M')->data;
                 $start     = new Carbon;
                 $start     = Navigation::updateStartDate($viewRange, $start);
@@ -84,16 +84,61 @@ class Range
                 }
                 Session::put('first', $first);
             }
-            $current = Carbon::now()->formatLocalized('%B %Y');
-            $next    = Carbon::now()->endOfMonth()->addDay()->formatLocalized('%B %Y');
-            $prev    = Carbon::now()->startOfMonth()->subDay()->formatLocalized('%B %Y');
-            View::share('currentMonthName', $current);
-            View::share('previousMonthName', $prev);
-            View::share('nextMonthName', $next);
+
         }
+        $this->datePicker();
 
         return $theNext($request);
 
     }
 
+    private function datePicker()
+    {
+        $viewRange          = Preferences::get('viewRange', '1M')->data;
+        $start              = Session::get('start');
+        $end                = Session::get('end');
+        $prevStart          = Navigation::subtractPeriod($start, $viewRange);// subtract for previous period
+        $prevEnd            = Navigation::endOfPeriod($prevStart, $viewRange);
+        $nextStart          = Navigation::addPeriod($start, $viewRange, 0); // add for previous period
+        $nextEnd            = Navigation::endOfPeriod($nextStart, $viewRange);
+        $ranges             = [];
+        $ranges['current']  = [$start->format('Y-m-d'), $end->format('Y-m-d')];
+        $ranges['previous'] = [$prevStart->format('Y-m-d'), $prevEnd->format('Y-m-d')];
+        $ranges['next']     = [$nextStart->format('Y-m-d'), $nextEnd->format('Y-m-d')];
+
+        switch ($viewRange) {
+            default:
+                throw new FireflyException('The date picker does not yet support "' . $viewRange . '".');
+            case '1D':
+                $format = (string)trans('config.month_and_day');
+                break;
+            case '3M':
+                $format = (string)trans('config.quarter_in_year');
+                break;
+            case '6M':
+                $format = (string)trans('config.half_year');
+                break;
+            case '1Y':
+                $format = (string)trans('config.year');
+                break;
+            case '1M':
+                $format = (string)trans('config.month');
+                break;
+            case '1W':
+                $format = (string)trans('config.week_in_year');
+                break;
+        }
+
+
+        $current = $start->formatLocalized($format);
+        $next    = $nextStart->formatLocalized($format);
+        $prev    = $prevStart->formatLocalized($format);
+        View::share('dpStart', $start->format('Y-m-d'));
+        View::share('dpEnd', $end->format('Y-m-d'));
+        View::share('dpCurrent', $current);
+        View::share('dpPrevious', $prev);
+        View::share('dpNext', $next);
+        View::share('dpRanges', $ranges);
+    }
+
 }
diff --git a/app/Http/Requests/ImportUploadRequest.php b/app/Http/Requests/ImportUploadRequest.php
new file mode 100644
index 0000000000..0f1e39155b
--- /dev/null
+++ b/app/Http/Requests/ImportUploadRequest.php
@@ -0,0 +1,46 @@
+ 'required|file',
+            'import_file_type' => 'required|in:' . join(',', $types),
+        ];
+
+    }
+}
diff --git a/app/Http/Requests/SplitJournalFormRequest.php b/app/Http/Requests/SplitJournalFormRequest.php
index 5213fb182e..7e49abb331 100644
--- a/app/Http/Requests/SplitJournalFormRequest.php
+++ b/app/Http/Requests/SplitJournalFormRequest.php
@@ -49,29 +49,9 @@ class SplitJournalFormRequest extends Request
             'interest_date'                    => $this->get('interest_date') ? new Carbon($this->get('interest_date')) : null,
             'book_date'                        => $this->get('book_date') ? new Carbon($this->get('book_date')) : null,
             'process_date'                     => $this->get('process_date') ? new Carbon($this->get('process_date')) : null,
-            'transactions'                     => [],
+            'transactions'                     => $this->getTransactionData(),
         ];
 
-        // description is leading because it is one of the mandatory fields.
-        foreach ($this->get('description') as $index => $description) {
-            $transaction            = [
-                'description'              => $description,
-                'amount'                   => round($this->get('amount')[$index], 2),
-                'budget_id'                => $this->get('budget_id')[$index] ? intval($this->get('budget_id')[$index]) : 0,
-                'category'                 => $this->get('category')[$index] ?? '',
-                'source_account_id'        => intval($this->get('journal_source_account_id')),
-                'source_account_name'      => $this->get('journal_source_account_name'),
-                'piggy_bank_id'            => isset($this->get('piggy_bank_id')[$index])
-                    ? intval($this->get('piggy_bank_id')[$index])
-                    : 0,
-                'destination_account_id'   => isset($this->get('destination_account_id')[$index])
-                    ? intval($this->get('destination_account_id')[$index])
-                    : intval($this->get('journal_destination_account_id')),
-                'destination_account_name' => $this->get('destination_account_name')[$index] ?? '',
-            ];
-            $data['transactions'][] = $transaction;
-        }
-
         return $data;
     }
 
@@ -91,14 +71,46 @@ class SplitJournalFormRequest extends Request
             'interest_date'                 => 'date',
             'book_date'                     => 'date',
             'process_date'                  => 'date',
-
-            'description.*'              => 'required|between:1,255',
-            'destination_account_id.*'   => 'numeric|belongsToUser:accounts,id',
-            'destination_account_name.*' => 'between:1,255',
-            'amount.*'                   => 'required|numeric',
-            'budget_id.*'                => 'belongsToUser:budgets,id',
-            'category.*'                 => 'between:1,255',
-            'piggy_bank_id.*'            => 'between:1,255',
+            'description.*'                 => 'required|between:1,255',
+            'destination_account_id.*'      => 'numeric|belongsToUser:accounts,id',
+            'destination_account_name.*'    => 'between:1,255',
+            'amount.*'                      => 'required|numeric',
+            'budget_id.*'                   => 'belongsToUser:budgets,id',
+            'category.*'                    => 'between:1,255',
+            'piggy_bank_id.*'               => 'between:1,255',
         ];
     }
-}
\ No newline at end of file
+
+    /**
+     * @return array
+     */
+    private function getTransactionData(): array
+    {
+        $return = [];
+        // description is leading because it is one of the mandatory fields.
+        foreach ($this->get('description') as $index => $description) {
+            $transaction = [
+                'description'              => $description,
+                'amount'                   => round($this->get('amount')[$index], 2),
+                'budget_id'                => $this->get('budget_id')[$index] ? intval($this->get('budget_id')[$index]) : 0,
+                'category'                 => $this->get('category')[$index] ?? '',
+                'source_account_id'        => isset($this->get('source_account_id')[$index])
+                    ? intval($this->get('source_account_id')[$index])
+                    : intval(
+                        $this->get('journal_source_account_id')
+                    ),
+                'source_account_name'      => $this->get('source_account_name')[$index] ?? '',
+                'piggy_bank_id'            => isset($this->get('piggy_bank_id')[$index]) ? intval($this->get('piggy_bank_id')[$index]) : 0,
+                'destination_account_id'   => isset($this->get('destination_account_id')[$index])
+                    ? intval($this->get('destination_account_id')[$index])
+                    : intval(
+                        $this->get('journal_destination_account_id')
+                    ),
+                'destination_account_name' => $this->get('destination_account_name')[$index] ?? '',
+            ];
+            $return[]    = $transaction;
+        }
+
+        return $return;
+    }
+}
diff --git a/app/Http/breadcrumbs.php b/app/Http/breadcrumbs.php
index cc42ebbe64..381920a156 100644
--- a/app/Http/breadcrumbs.php
+++ b/app/Http/breadcrumbs.php
@@ -96,6 +96,30 @@ Breadcrumbs::register(
 }
 );
 
+/**
+ * ADMIN
+ */
+Breadcrumbs::register(
+    'admin.index', function (BreadCrumbGenerator $breadcrumbs) {
+    $breadcrumbs->parent('home');
+    $breadcrumbs->push(trans('firefly.administration'), route('admin.index'));
+}
+);
+
+Breadcrumbs::register(
+    'admin.users', function (BreadCrumbGenerator $breadcrumbs) {
+    $breadcrumbs->parent('admin.index');
+    $breadcrumbs->push(trans('firefly.list_all_users'), route('admin.users'));
+}
+);
+
+Breadcrumbs::register(
+    'admin.users.domains', function (BreadCrumbGenerator $breadcrumbs) {
+    $breadcrumbs->parent('admin.index');
+    $breadcrumbs->push(trans('firefly.blocked_domains'), route('admin.users.domains'));
+}
+);
+
 /**
  * ATTACHMENTS
  */
@@ -269,44 +293,6 @@ Breadcrumbs::register(
 }
 );
 
-/**
- * CSV CONTROLLER
- */
-Breadcrumbs::register(
-    'csv.index', function (BreadCrumbGenerator $breadcrumbs) {
-    $breadcrumbs->parent('home');
-    $breadcrumbs->push(trans('firefly.csv_index_title'), route('csv.index'));
-}
-);
-
-Breadcrumbs::register(
-    'csv.column-roles', function (BreadCrumbGenerator $breadcrumbs) {
-    $breadcrumbs->parent('csv.index');
-    $breadcrumbs->push(trans('firefly.csv_define_column_roles'), route('csv.column-roles'));
-}
-);
-
-Breadcrumbs::register(
-    'csv.map', function (BreadCrumbGenerator $breadcrumbs) {
-    $breadcrumbs->parent('csv.index');
-    $breadcrumbs->push(trans('firefly.csv_map_values'), route('csv.map'));
-}
-);
-
-Breadcrumbs::register(
-    'csv.download-config-page', function (BreadCrumbGenerator $breadcrumbs) {
-    $breadcrumbs->parent('csv.index');
-    $breadcrumbs->push(trans('firefly.csv_download_config'), route('csv.download-config-page'));
-}
-);
-
-Breadcrumbs::register(
-    'csv.process', function (BreadCrumbGenerator $breadcrumbs) {
-    $breadcrumbs->parent('csv.index');
-    $breadcrumbs->push(trans('firefly.csv_process_title'), route('csv.process'));
-}
-);
-
 /**
  * CURRENCIES
  */
@@ -613,4 +599,4 @@ Breadcrumbs::register(
     $breadcrumbs->parent('transactions.index', $what);
     $breadcrumbs->push(trans('breadcrumbs.create_' . e($what)), route('split.journal.create', [$what]));
 }
-);
\ No newline at end of file
+);
diff --git a/app/Http/routes.php b/app/Http/routes.php
index 159931d398..955af396a3 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -157,21 +157,6 @@ Route::group(
     Route::post('/categories/update/{category}', ['uses' => 'CategoryController@update', 'as' => 'categories.update']);
     Route::post('/categories/destroy/{category}', ['uses' => 'CategoryController@destroy', 'as' => 'categories.destroy']);
 
-    /**
-     * CSV controller
-     */
-    Route::get('/csv', ['uses' => 'CsvController@index', 'as' => 'csv.index']);
-    Route::post('/csv/upload', ['uses' => 'CsvController@upload', 'as' => 'csv.upload']);
-    Route::get('/csv/column_roles', ['uses' => 'CsvController@columnRoles', 'as' => 'csv.column-roles']);
-    Route::post('/csv/initial_parse', ['uses' => 'CsvController@initialParse', 'as' => 'csv.initial_parse']);
-    Route::get('/csv/map', ['uses' => 'CsvController@map', 'as' => 'csv.map']);
-    Route::get('/csv/download-config', ['uses' => 'CsvController@downloadConfig', 'as' => 'csv.download-config']);
-    Route::get('/csv/download', ['uses' => 'CsvController@downloadConfigPage', 'as' => 'csv.download-config-page']);
-    Route::post('/csv/save_mapping', ['uses' => 'CsvController@saveMapping', 'as' => 'csv.save_mapping']);
-    
-    Route::get('/csv/process', ['uses' => 'CsvController@process', 'as' => 'csv.process']);
-
-
     /**
      * Currency Controller
      */
@@ -240,6 +225,13 @@ Route::group(
      */
     Route::get('/import', ['uses' => 'ImportController@index', 'as' => 'import.index']);
     Route::post('/import/upload', ['uses' => 'ImportController@upload', 'as' => 'import.upload']);
+    Route::get('/import/configure/{importJob}', ['uses' => 'ImportController@configure', 'as' => 'import.configure']);
+    Route::post('/import/configure/{importJob}', ['uses' => 'ImportController@postConfigure', 'as' => 'import.process_configuration']);
+    Route::get('/import/settings/{importJob}', ['uses' => 'ImportController@settings', 'as' => 'import.settings']);
+    Route::post('/import/settings/{importJob}', ['uses' => 'ImportController@postSettings', 'as' => 'import.postSettings']);
+    Route::get('/import/complete/{importJob}', ['uses' => 'ImportController@complete', 'as' => 'import.complete']);
+    Route::get('/import/download/{importJob}', ['uses' => 'ImportController@download', 'as' => 'import.download']);
+
 
     /**
      * Help Controller
@@ -277,6 +269,13 @@ Route::group(
     Route::get('/piggy-banks', ['uses' => 'PiggyBankController@index', 'as' => 'piggy-banks.index']);
     Route::get('/piggy-banks/add/{piggyBank}', ['uses' => 'PiggyBankController@add', 'as' => 'piggy-banks.addMoney']);
     Route::get('/piggy-banks/remove/{piggyBank}', ['uses' => 'PiggyBankController@remove', 'as' => 'piggy-banks.removeMoney']);
+
+    Route::get('/piggy-banks/add-money/{piggyBank}', ['uses' => 'PiggyBankController@addMobile', 'as' => 'piggy-banks.add-money-mobile']);
+    Route::get('/piggy-banks/remove-money/{piggyBank}', ['uses' => 'PiggyBankController@removeMobile', 'as' => 'piggy-banks.remove-money-mobile']);
+
+    Route::post('/piggy-banks/add-money/{piggyBank}', ['uses' => 'PiggyBankController@postAddMobile', 'as' => 'piggy-banks.post-add-mobile']);
+    Route::post('/piggy-banks/remove-money/{piggyBank}', ['uses' => 'PiggyBankController@postRemoveMobile', 'as' => 'piggy-banks.post-remove-mobile']);
+
     Route::get('/piggy-banks/create', ['uses' => 'PiggyBankController@create', 'as' => 'piggy-banks.create']);
     Route::get('/piggy-banks/edit/{piggyBank}', ['uses' => 'PiggyBankController@edit', 'as' => 'piggy-banks.edit']);
     Route::get('/piggy-banks/delete/{piggyBank}', ['uses' => 'PiggyBankController@delete', 'as' => 'piggy-banks.delete']);
@@ -425,6 +424,12 @@ Route::group(
 
     // user manager
     Route::get('/admin/users', ['uses' => 'Admin\UserController@index', 'as' => 'admin.users']);
+    Route::get('/admin/users/edit/{user}', ['uses' => 'Admin\UserController@edit', 'as' => 'admin.users.edit']);
+
+    // user domains:
+    Route::get('/admin/domains', ['uses' => 'Admin\DomainController@domains', 'as' => 'admin.users.domains']);
+    Route::get('/admin/domains/toggle/{domain}', ['uses' => 'Admin\DomainController@toggleDomain', 'as' => 'admin.users.domains.block-toggle']);
+    Route::post('/admin/domains/manual', ['uses' => 'Admin\DomainController@manual', 'as' => 'admin.users.domains.manual']);
 
 }
 );
diff --git a/app/Import/Converter/AccountId.php b/app/Import/Converter/AccountId.php
new file mode 100644
index 0000000000..1f07603f63
--- /dev/null
+++ b/app/Import/Converter/AccountId.php
@@ -0,0 +1,65 @@
+ $value]);
+        if ($value === 0) {
+            $this->setCertainty(0);
+
+            return new Account;
+        }
+        /** @var AccountCrudInterface $repository */
+        $repository = app(AccountCrudInterface::class, [$this->user]);
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found account in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $account = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($account->id)) {
+                Log::debug('Found account by ID', ['id' => $account->id]);
+
+                $this->setCertainty(100);
+
+                return $account;
+            }
+        }
+        $account = $repository->find($value);// not mapped? Still try to find it first:
+        if (!is_null($account->id)) {
+            $this->setCertainty(90);
+            Log::debug('Found account by ID ', ['id' => $account->id]);
+
+            return $account;
+        }
+        $this->setCertainty(0); // should not really happen. If the ID does not match FF, what is FF supposed to do?
+
+        return new Account;
+
+    }
+}
diff --git a/app/Import/Converter/Amount.php b/app/Import/Converter/Amount.php
new file mode 100644
index 0000000000..1e071652c0
--- /dev/null
+++ b/app/Import/Converter/Amount.php
@@ -0,0 +1,65 @@
+ 2 && $value{$decimalPosition} == '.') {
+            $decimal = '.';
+        }
+        if ($len > 2 && $value{$decimalPosition} == ',') {
+            $decimal = ',';
+        }
+
+        // if decimal is dot, replace all comma's and spaces with nothing. then parse as float (round to 4 pos)
+        if ($decimal === '.') {
+            $search = [',', ' '];
+            $value  = str_replace($search, '', $value);
+        }
+        if ($decimal === ',') {
+            $search = ['.', ' '];
+            $value  = str_replace($search, '', $value);
+            $value  = str_replace(',', '.', $value);
+        }
+        if (is_null($decimal)) {
+            // replace all:
+            $search = ['.', ' ', ','];
+            $value  = str_replace($search, '', $value);
+        }
+
+        $this->setCertainty(90);
+
+
+        return round(floatval($value), 4);
+
+    }
+}
diff --git a/app/Import/Converter/AssetAccountIban.php b/app/Import/Converter/AssetAccountIban.php
new file mode 100644
index 0000000000..97f1932e14
--- /dev/null
+++ b/app/Import/Converter/AssetAccountIban.php
@@ -0,0 +1,84 @@
+ $value]);
+
+        if (strlen($value) === 0) {
+            $this->setCertainty(0);
+
+            return new Account;
+        }
+
+        /** @var AccountCrudInterface $repository */
+        $repository = app(AccountCrudInterface::class, [$this->user]);
+
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found account in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $account = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($account->id)) {
+                $this->setCertainty(100);
+                Log::debug('Found account by ID', ['id' => $account->id]);
+
+                return $account;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $account = $repository->findByIban($value, [AccountType::ASSET]);
+        if (!is_null($account->id)) {
+            Log::debug('Found account by IBAN', ['id' => $account->id]);
+            $this->setCertainty(50);
+
+            return $account;
+        }
+
+
+        $account = $repository->store(
+            ['name'   => 'Asset account with IBAN ' . $value, 'iban' => $value, 'user' => $this->user->id, 'accountType' => 'asset', 'virtualBalance' => 0,
+             'active' => true, 'openingBalance' => 0]
+        );
+
+        if (is_null($account->id)) {
+            $this->setCertainty(0);
+            Log::info('Could not store new asset account by IBAN', $account->getErrors()->toArray());
+
+            return new Account;
+        }
+
+        $this->setCertainty(100);
+
+        return $account;
+    }
+}
diff --git a/app/Import/Converter/AssetAccountName.php b/app/Import/Converter/AssetAccountName.php
new file mode 100644
index 0000000000..f20cd7b798
--- /dev/null
+++ b/app/Import/Converter/AssetAccountName.php
@@ -0,0 +1,87 @@
+ $value]);
+
+        if (strlen($value) === 0) {
+            $this->setCertainty(0);
+
+            return new Account;
+        }
+
+        /** @var AccountCrudInterface $repository */
+        $repository = app(AccountCrudInterface::class, [$this->user]);
+
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found account in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $account = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($account->id)) {
+                Log::debug('Found account by ID', ['id' => $account->id]);
+                $this->setCertainty(100);
+
+                return $account;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $account = $repository->findByName($value, [AccountType::ASSET]);
+        if (!is_null($account->id)) {
+            Log::debug('Found asset account by name', ['value' => $value, 'id' => $account->id]);
+
+            return $account;
+        }
+
+
+        $account = $repository->store(
+            ['name'   => $value, 'iban' => null, 'openingBalance' => 0, 'user' => $this->user->id, 'accountType' => 'asset', 'virtualBalance' => 0,
+             'active' => true]
+        );
+
+        if (is_null($account->id)) {
+            $this->setCertainty(0);
+            Log::info('Could not store new asset account by name', $account->getErrors()->toArray());
+
+            return new Account;
+        }
+
+        $this->setCertainty(100);
+
+        Log::debug('Created new asset account ', ['name' => $account->name, 'id' => $account->id]);
+
+        return $account;
+
+
+    }
+}
diff --git a/app/Import/Converter/AssetAccountNumber.php b/app/Import/Converter/AssetAccountNumber.php
new file mode 100644
index 0000000000..cbad7b39a5
--- /dev/null
+++ b/app/Import/Converter/AssetAccountNumber.php
@@ -0,0 +1,93 @@
+ $value]);
+
+        if (strlen($value) === 0) {
+            return new Account;
+        }
+
+        /** @var AccountCrudInterface $repository */
+        $repository = app(AccountCrudInterface::class, [$this->user]);
+
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found account in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $account = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($account->id)) {
+                Log::debug('Found account by ID', ['id' => $account->id]);
+
+                return $account;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $account = $repository->findByAccountNumber($value, [AccountType::ASSET]);
+        if (!is_null($account->id)) {
+            Log::debug('Found account by name', ['id' => $account->id]);
+            $this->setCertainty(50);
+
+            return $account;
+        }
+
+        // try to find by the name we would give it:
+        $accountName = 'Asset account with number ' . e($value);
+        $account     = $repository->findByName($accountName, [AccountType::ASSET]);
+        if (!is_null($account->id)) {
+            Log::debug('Found account by name', ['id' => $account->id]);
+            $this->setCertainty(50);
+
+            return $account;
+        }
+
+
+        $account = $repository->store(
+            ['name'           => $accountName, 'openingBalance' => 0, 'iban' => null, 'user' => $this->user->id,
+             'accountType'    => 'asset',
+             'virtualBalance' => 0, 'accountNumber' => $value, 'active' => true]
+        );
+
+        if (is_null($account->id)) {
+            $this->setCertainty(0);
+            Log::notice('Could not store new asset account by account number', $account->getErrors()->toArray());
+
+            return new Account;
+        }
+
+        $this->setCertainty(100);
+
+        return $account;
+
+    }
+}
diff --git a/app/Import/Converter/BasicConverter.php b/app/Import/Converter/BasicConverter.php
new file mode 100644
index 0000000000..dbe7b56663
--- /dev/null
+++ b/app/Import/Converter/BasicConverter.php
@@ -0,0 +1,83 @@
+certainty;
+    }
+
+    /**
+     * @param int $certainty
+     */
+    protected function setCertainty(int $certainty)
+    {
+        $this->certainty = $certainty;
+    }
+
+    /**
+     * @param array $config
+     */
+    public function setConfig(array $config)
+    {
+        $this->config = $config;
+    }
+
+    /**
+     * @param mixed $doMap
+     */
+    public function setDoMap(bool $doMap)
+    {
+        $this->doMap = $doMap;
+    }
+
+    /**
+     * @param array $mapping
+     *
+     */
+    public function setMapping(array $mapping)
+    {
+        $this->mapping = $mapping;
+    }
+
+    /**
+     * @param User $user
+     */
+    public function setUser(User $user)
+    {
+        $this->user = $user;
+    }
+}
diff --git a/app/Import/Converter/BillId.php b/app/Import/Converter/BillId.php
new file mode 100644
index 0000000000..edb8817a10
--- /dev/null
+++ b/app/Import/Converter/BillId.php
@@ -0,0 +1,73 @@
+ $value]);
+
+        if ($value === 0) {
+            $this->setCertainty(0);
+
+            return new Bill;
+        }
+
+        /** @var BillRepositoryInterface $repository */
+        $repository = app(BillRepositoryInterface::class, [$this->user]);
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found bill in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $bill = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($bill->id)) {
+                Log::debug('Found bill by ID', ['id' => $bill->id]);
+                $this->setCertainty(100);
+
+                return $bill;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $bill = $repository->find($value);
+        if (!is_null($bill->id)) {
+            Log::debug('Found bill by ID ', ['id' => $bill->id]);
+            $this->setCertainty(100);
+
+            return $bill;
+        }
+
+        // should not really happen. If the ID does not match FF, what is FF supposed to do?
+        Log::info(sprintf('Could not find bill with ID %d. Will return NULL', $value));
+
+        $this->setCertainty(0);
+
+        return new Bill;
+
+    }
+}
diff --git a/app/Import/Converter/BillName.php b/app/Import/Converter/BillName.php
new file mode 100644
index 0000000000..2c9eb92f42
--- /dev/null
+++ b/app/Import/Converter/BillName.php
@@ -0,0 +1,92 @@
+ $value]);
+
+        if (strlen($value) === 0) {
+            $this->setCertainty(0);
+            return new Bill;
+        }
+
+        /** @var BillRepositoryInterface $repository */
+        $repository = app(BillRepositoryInterface::class, [$this->user]);
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found bill in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $bill = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($bill->id)) {
+                Log::debug('Found bill by ID', ['id' => $bill->id]);
+                $this->setCertainty(100);
+                return $bill;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $bill = $repository->findByName($value);
+        if (!is_null($bill->id)) {
+            Log::debug('Found bill by name ', ['id' => $bill->id]);
+            $this->setCertainty(100);
+            return $bill;
+        }
+
+        // create new bill. Use a lot of made up values.
+        $bill = $repository->store(
+            [
+                'name'        => $value,
+                'match'       => $value,
+                'amount_min'  => 1,
+                'user'     => $this->user->id,
+                'amount_max'  => 10,
+                'date'        => date('Ymd'),
+                'repeat_freq' => 'monthly',
+                'skip'        => 0,
+                'automatch'   => 0,
+                'active'      => 1,
+
+            ]
+        );
+        if (is_null($bill->id)) {
+            $this->setCertainty(0);
+            Log::info('Could not store new bill by name', $bill->getErrors()->toArray());
+
+            return new Bill;
+        }
+
+        $this->setCertainty(100);
+
+        return $bill;
+
+
+    }
+}
diff --git a/app/Import/Converter/BudgetId.php b/app/Import/Converter/BudgetId.php
new file mode 100644
index 0000000000..aa6448cb89
--- /dev/null
+++ b/app/Import/Converter/BudgetId.php
@@ -0,0 +1,72 @@
+ $value]);
+
+        if ($value === 0) {
+            $this->setCertainty(0);
+            return new Budget;
+        }
+
+        /** @var BudgetRepositoryInterface $repository */
+        $repository = app(BudgetRepositoryInterface::class, [$this->user]);
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found budget in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $budget = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($budget->id)) {
+                Log::debug('Found budget by ID', ['id' => $budget->id]);
+                $this->setCertainty(100);
+
+                return $budget;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $budget = $repository->find($value);
+        if (!is_null($budget->id)) {
+            Log::debug('Found budget by ID ', ['id' => $budget->id]);
+            $this->setCertainty(100);
+            return $budget;
+        }
+
+        // should not really happen. If the ID does not match FF, what is FF supposed to do?
+        $this->setCertainty(0);
+
+        Log::info(sprintf('Could not find budget with ID %d. Will return NULL', $value));
+
+        return new Budget;
+
+    }
+}
diff --git a/app/Import/Converter/BudgetName.php b/app/Import/Converter/BudgetName.php
new file mode 100644
index 0000000000..8611e7dd2e
--- /dev/null
+++ b/app/Import/Converter/BudgetName.php
@@ -0,0 +1,75 @@
+ $value]);
+
+        if (strlen($value) === 0) {
+            $this->setCertainty(0);
+            return new Budget;
+        }
+
+        /** @var BudgetRepositoryInterface $repository */
+        $repository = app(BudgetRepositoryInterface::class, [$this->user]);
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found budget in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $budget = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($budget->id)) {
+                Log::debug('Found budget by ID', ['id' => $budget->id]);
+                $this->setCertainty(100);
+                return $budget;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $budget = $repository->findByName($value);
+        if (!is_null($budget->id)) {
+            Log::debug('Found budget by name ', ['id' => $budget->id]);
+            $this->setCertainty(100);
+            return $budget;
+        }
+
+        // create new budget. Use a lot of made up values.
+        $budget = $repository->store(
+            [
+                'name'        => $value,
+                'user'     => $this->user->id,
+            ]
+        );
+        $this->setCertainty(100);
+
+        return $budget;
+
+    }
+}
diff --git a/app/Import/Converter/CategoryId.php b/app/Import/Converter/CategoryId.php
new file mode 100644
index 0000000000..47e5d7f965
--- /dev/null
+++ b/app/Import/Converter/CategoryId.php
@@ -0,0 +1,71 @@
+ $value]);
+
+        if ($value === 0) {
+            $this->setCertainty(0);
+            return new Category;
+        }
+
+        /** @var CategoryRepositoryInterface $repository */
+        $repository = app(CategoryRepositoryInterface::class, [$this->user]);
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found category in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $category = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($category->id)) {
+                Log::debug('Found category by ID', ['id' => $category->id]);
+                $this->setCertainty(100);
+                return $category;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $category = $repository->find($value);
+        if (!is_null($category->id)) {
+            Log::debug('Found category by ID ', ['id' => $category->id]);
+            $this->setCertainty(100);
+            return $category;
+        }
+
+        // should not really happen. If the ID does not match FF, what is FF supposed to do?
+        $this->setCertainty(0);
+
+        Log::info(sprintf('Could not find category with ID %d. Will return NULL', $value));
+
+        return new Category;
+
+    }
+}
diff --git a/app/Import/Converter/CategoryName.php b/app/Import/Converter/CategoryName.php
new file mode 100644
index 0000000000..383a1f907d
--- /dev/null
+++ b/app/Import/Converter/CategoryName.php
@@ -0,0 +1,75 @@
+ $value]);
+
+        if (strlen($value) === 0) {
+            $this->setCertainty(0);
+            return new Category;
+        }
+
+        /** @var CategoryRepositoryInterface $repository */
+        $repository = app(CategoryRepositoryInterface::class, [$this->user]);
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found category in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $category = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($category->id)) {
+                Log::debug('Found category by ID', ['id' => $category->id]);
+                $this->setCertainty(100);
+                return $category;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $category = $repository->findByName($value);
+        if (!is_null($category->id)) {
+            Log::debug('Found category by name ', ['id' => $category->id]);
+            $this->setCertainty(100);
+            return $category;
+        }
+
+        // create new category. Use a lot of made up values.
+        $category = $repository->store(
+            [
+                'name'    => $value,
+                'user' => $this->user->id,
+            ]
+        );
+        $this->setCertainty(100);
+
+        return $category;
+
+    }
+}
diff --git a/app/Import/Converter/ConverterInterface.php b/app/Import/Converter/ConverterInterface.php
new file mode 100644
index 0000000000..e474587a33
--- /dev/null
+++ b/app/Import/Converter/ConverterInterface.php
@@ -0,0 +1,54 @@
+ $value]);
+
+        /** @var CurrencyRepositoryInterface $repository */
+        $repository = app(CurrencyRepositoryInterface::class);
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found currency in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $currency = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($currency->id)) {
+                Log::debug('Found currency by ID', ['id' => $currency->id]);
+                $this->setCertainty(100);
+                return $currency;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $currency = $repository->findByCode($value);
+        if (!is_null($currency->id)) {
+            Log::debug('Found currency by code', ['id' => $currency->id]);
+            $this->setCertainty(100);
+            return $currency;
+        }
+        $currency = $repository->store(
+            [
+                'name'   => $value,
+                'code'   => $value,
+                'symbol' => $value,
+            ]
+        );
+        $this->setCertainty(100);
+
+        return $currency;
+    }
+}
diff --git a/app/Import/Converter/CurrencyId.php b/app/Import/Converter/CurrencyId.php
new file mode 100644
index 0000000000..59b6e2e13f
--- /dev/null
+++ b/app/Import/Converter/CurrencyId.php
@@ -0,0 +1,70 @@
+ $value]);
+
+        if ($value === 0) {
+            $this->setCertainty(0);
+            return new TransactionCurrency;
+        }
+
+        /** @var CurrencyRepositoryInterface $repository */
+        $repository = app(CurrencyRepositoryInterface::class, [$this->user]);
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found currency in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $currency = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($currency->id)) {
+                Log::debug('Found currency by ID', ['id' => $currency->id]);
+                $this->setCertainty(100);
+                return $currency;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $currency = $repository->find($value);
+        if (!is_null($currency->id)) {
+            Log::debug('Found currency by ID ', ['id' => $currency->id]);
+            $this->setCertainty(100);
+            return $currency;
+        }
+        $this->setCertainty(0);
+        // should not really happen. If the ID does not match FF, what is FF supposed to do?
+
+        Log::info(sprintf('Could not find category with ID %d. Will return NULL', $value));
+
+        return new TransactionCurrency;
+
+    }
+}
diff --git a/app/Import/Converter/CurrencyName.php b/app/Import/Converter/CurrencyName.php
new file mode 100644
index 0000000000..e2976852a5
--- /dev/null
+++ b/app/Import/Converter/CurrencyName.php
@@ -0,0 +1,75 @@
+ $value]);
+
+        if (strlen($value) === 0) {
+            $this->setCertainty(0);
+            return new TransactionCurrency;
+        }
+
+        /** @var CurrencyRepositoryInterface $repository */
+        $repository = app(CurrencyRepositoryInterface::class, [$this->user]);
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found currency in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $currency = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($currency->id)) {
+                Log::debug('Found currency by ID', ['id' => $currency->id]);
+                $this->setCertainty(100);
+                return $currency;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $currency = $repository->findByName($value);
+        if (!is_null($currency->id)) {
+            Log::debug('Found currency by name ', ['id' => $currency->id]);
+            $this->setCertainty(100);
+            return $currency;
+        }
+
+        // create new currency
+        $currency = $repository->store(
+            [
+                'name'   => $value,
+                'code'   => strtoupper(substr($value, 0, 3)),
+                'symbol' => strtoupper(substr($value, 0, 1)),
+            ]
+        );
+        $this->setCertainty(100);
+
+        return $currency;
+
+    }
+}
diff --git a/app/Import/Converter/CurrencySymbol.php b/app/Import/Converter/CurrencySymbol.php
new file mode 100644
index 0000000000..2855f2bd48
--- /dev/null
+++ b/app/Import/Converter/CurrencySymbol.php
@@ -0,0 +1,75 @@
+ $value]);
+
+        if (strlen($value) === 0) {
+            $this->setCertainty(0);
+            return new TransactionCurrency;
+        }
+
+        /** @var CurrencyRepositoryInterface $repository */
+        $repository = app(CurrencyRepositoryInterface::class, [$this->user]);
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found currency in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $currency = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($currency->id)) {
+                Log::debug('Found currency by ID', ['id' => $currency->id]);
+                $this->setCertainty(100);
+                return $currency;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $currency = $repository->findBySymbol($value);
+        if (!is_null($currency->id)) {
+            Log::debug('Found currency by symbol ', ['id' => $currency->id]);
+            $this->setCertainty(100);
+            return $currency;
+        }
+
+        // create new currency
+        $currency = $repository->store(
+            [
+                'name'   => 'Currency ' . $value,
+                'code'   => $value,
+                'symbol' => $value,
+            ]
+        );
+        $this->setCertainty(100);
+
+        return $currency;
+
+    }
+}
diff --git a/app/Import/Converter/Date.php b/app/Import/Converter/Date.php
new file mode 100644
index 0000000000..e873f9c128
--- /dev/null
+++ b/app/Import/Converter/Date.php
@@ -0,0 +1,49 @@
+ $value]);
+        Log::debug('Format: ', ['format' => $this->config['date-format']]);
+        try {
+            $date = Carbon::createFromFormat($this->config['date-format'], $value);
+        } catch (InvalidArgumentException $e) {
+            Log::notice($e->getMessage());
+            Log::notice('Cannot convert this string using the given format.', ['value' => $value, 'format' => $this->config['date-format']]);
+            $this->setCertainty(0);
+            return new Carbon;
+        }
+        Log::debug('Converted date', ['converted' => $date->toAtomString()]);
+        $this->setCertainty(100);
+        return $date;
+    }
+}
diff --git a/app/Helpers/Csv/Converter/Description.php b/app/Import/Converter/Description.php
similarity index 51%
rename from app/Helpers/Csv/Converter/Description.php
rename to app/Import/Converter/Description.php
index ea864a3e3e..d7a2cde245 100644
--- a/app/Helpers/Csv/Converter/Description.php
+++ b/app/Import/Converter/Description.php
@@ -8,24 +8,30 @@
  */
 
 declare(strict_types = 1);
-namespace FireflyIII\Helpers\Csv\Converter;
+
+namespace FireflyIII\Import\Converter;
 
 /**
  * Class Description
  *
- * @package FireflyIII\Helpers\Csv\Converter
+ * @package FireflyIII\Import\Converter
  */
 class Description extends BasicConverter implements ConverterInterface
 {
 
-
     /**
+     * @param $value
+     *
      * @return string
      */
-    public function convert(): string
+    public function convert($value): string
     {
-        $description = $this->data['description'] ?? '';
+        // this should replace all control characters
+        // but leave utf8 intact:
+        $value = preg_replace('/[\x00-\x1F\x80-\x9F]/u', '', $value);
+        $this->setCertainty(100);
+
+        return strval($value);
 
-        return trim($description . ' ' . $this->value);
     }
 }
diff --git a/app/Import/Converter/ExternalId.php b/app/Import/Converter/ExternalId.php
new file mode 100644
index 0000000000..5f8c493fed
--- /dev/null
+++ b/app/Import/Converter/ExternalId.php
@@ -0,0 +1,37 @@
+setCertainty(100);
+
+        return strval(trim($value));
+
+    }
+}
diff --git a/app/Helpers/Csv/Converter/INGDebetCredit.php b/app/Import/Converter/INGDebetCredit.php
similarity index 50%
rename from app/Helpers/Csv/Converter/INGDebetCredit.php
rename to app/Import/Converter/INGDebetCredit.php
index 59fd76248a..2e3ca15dbd 100644
--- a/app/Helpers/Csv/Converter/INGDebetCredit.php
+++ b/app/Import/Converter/INGDebetCredit.php
@@ -8,27 +8,38 @@
  */
 
 declare(strict_types = 1);
-namespace FireflyIII\Helpers\Csv\Converter;
 
+namespace FireflyIII\Import\Converter;
+
+use FireflyIII\Exceptions\FireflyException;
+use Log;
 
 /**
  * Class INGDebetCredit
  *
- * @package FireflyIII\Helpers\Csv\Converter
+ * @package FireflyIII\Import\Converter
  */
 class INGDebetCredit extends BasicConverter implements ConverterInterface
 {
 
-
     /**
+     * @param $value
+     *
      * @return int
      */
-    public function convert(): int
+    public function convert($value)
     {
-        if ($this->value === 'Af') {
+        Log::debug('Going to convert ing debet credit', ['value' => $value]);
+
+        if ($value === 'Af') {
+            Log::debug('Return -1');
+            $this->setCertainty(100);
             return -1;
         }
 
+        $this->setCertainty(100);
+        Log::debug('Return 1');
         return 1;
+
     }
 }
diff --git a/app/Helpers/Csv/Converter/Ignore.php b/app/Import/Converter/Ignore.php
similarity index 70%
rename from app/Helpers/Csv/Converter/Ignore.php
rename to app/Import/Converter/Ignore.php
index c2da8c3033..e96b5fabb1 100644
--- a/app/Helpers/Csv/Converter/Ignore.php
+++ b/app/Import/Converter/Ignore.php
@@ -8,21 +8,25 @@
  */
 
 declare(strict_types = 1);
-namespace FireflyIII\Helpers\Csv\Converter;
+
+namespace FireflyIII\Import\Converter;
 
 /**
- * Class Amount
+ * Class Ignore
  *
- * @package FireflyIII\Helpers\Csv\Converter
+ * @package FireflyIII\Import\Converter
  */
 class Ignore extends BasicConverter implements ConverterInterface
 {
 
     /**
+     * @param $value
+     *
      * @return null
      */
-    public function convert()
+    public function convert($value)
     {
         return null;
+
     }
 }
diff --git a/app/Import/Converter/OpposingAccountIban.php b/app/Import/Converter/OpposingAccountIban.php
new file mode 100644
index 0000000000..4fc2a1cc9d
--- /dev/null
+++ b/app/Import/Converter/OpposingAccountIban.php
@@ -0,0 +1,76 @@
+ $value]);
+
+        if (strlen($value) === 0) {
+            $this->setCertainty(0);
+            return new Account;
+        }
+
+        /** @var AccountCrudInterface $repository */
+        $repository = app(AccountCrudInterface::class, [$this->user]);
+
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found account in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $account = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($account->id)) {
+                Log::debug('Found account by ID', ['id' => $account->id]);
+                $this->setCertainty(100);
+                return $account;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $account = $repository->findByIban($value, []);
+        if (!is_null($account->id)) {
+            Log::debug('Found account by IBAN', ['id' => $account->id]);
+            Log::notice(
+                'The match between IBAN and account is uncertain because the type of transactions may not have been determined.',
+                ['id' => $account->id, 'iban' => $value]
+            );
+            $this->setCertainty(50);
+
+            return $account;
+        }
+
+        $account = $repository->store(
+            ['name'           => $value, 'iban' => $value, 'user' => $this->user->id, 'accountType' => 'import', 'virtualBalance' => 0, 'active' => true,
+             'openingBalance' => 0]
+        );
+        $this->setCertainty(100);
+
+        return $account;
+    }
+}
diff --git a/app/Import/Converter/OpposingAccountName.php b/app/Import/Converter/OpposingAccountName.php
new file mode 100644
index 0000000000..d5fe3fb7d6
--- /dev/null
+++ b/app/Import/Converter/OpposingAccountName.php
@@ -0,0 +1,85 @@
+ $value]);
+
+        if (strlen($value) === 0) {
+            $this->setCertainty(0);
+            return new Account;
+        }
+
+        /** @var AccountCrudInterface $repository */
+        $repository = app(AccountCrudInterface::class, [$this->user]);
+
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found account in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $account = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($account->id)) {
+                Log::debug('Found account by ID', ['id' => $account->id]);
+                $this->setCertainty(100);
+
+                return $account;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $account = $repository->findByName($value, []);
+        if (!is_null($account->id)) {
+            Log::debug('Found opposing account by name', ['id' => $account->id]);
+            Log::info(
+                'The match between name and account is uncertain because the type of transactions may not have been determined.',
+                ['id' => $account->id, 'name' => $value]
+            );
+            $this->setCertainty(50);
+
+            return $account;
+        }
+
+        $account = $repository->store(
+            ['name'           => $value, 'iban' => null, 'user' => $this->user->id, 'accountType' => 'import', 'virtualBalance' => 0, 'active' => true,
+             'openingBalance' => 0,
+            ]
+        );
+        if (is_null($account->id)) {
+            $this->setCertainty(0);
+
+            return new Account;
+        }
+        $this->setCertainty(100);
+
+        Log::debug('Created new opposing account ', ['name' => $account->name, 'id' => $account->id]);
+
+        return $account;
+    }
+}
diff --git a/app/Import/Converter/OpposingAccountNumber.php b/app/Import/Converter/OpposingAccountNumber.php
new file mode 100644
index 0000000000..ede513646a
--- /dev/null
+++ b/app/Import/Converter/OpposingAccountNumber.php
@@ -0,0 +1,85 @@
+ $value]);
+
+        if (strlen($value) === 0) {
+            $this->setCertainty(0);
+            return new Account;
+        }
+
+        /** @var AccountCrudInterface $repository */
+        $repository = app(AccountCrudInterface::class, [$this->user]);
+
+
+        if (isset($this->mapping[$value])) {
+            Log::debug('Found account in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
+            $account = $repository->find(intval($this->mapping[$value]));
+            if (!is_null($account->id)) {
+                Log::debug('Found account by ID', ['id' => $account->id]);
+                $this->setCertainty(100);
+                return $account;
+            }
+        }
+
+        // not mapped? Still try to find it first:
+        $account = $repository->findByAccountNumber($value, []);
+        if (!is_null($account->id)) {
+            Log::debug('Found account by number', ['id' => $account->id]);
+            $this->setCertainty(50);
+            return $account;
+        }
+
+        // try to find by the name we would give it:
+        $accountName = 'Import account with number ' . e($value);
+        $account     = $repository->findByName($accountName, [AccountType::IMPORT]);
+        if (!is_null($account->id)) {
+            Log::debug('Found account by name', ['id' => $account->id]);
+            $this->setCertainty(50);
+
+            return $account;
+        }
+
+
+        $account = $repository->store(
+            ['name'           => $accountName, 'openingBalance' => 0, 'iban' => null, 'user' => $this->user->id,
+             'accountType'    => 'import',
+             'virtualBalance' => 0, 'accountNumber' => $value, 'active' => true]
+        );
+        $this->setCertainty(100);
+        return $account;
+
+    }
+}
diff --git a/app/Helpers/Csv/Converter/RabobankDebetCredit.php b/app/Import/Converter/RabobankDebetCredit.php
similarity index 54%
rename from app/Helpers/Csv/Converter/RabobankDebetCredit.php
rename to app/Import/Converter/RabobankDebetCredit.php
index 854f812d45..2cd9e2ed98 100644
--- a/app/Helpers/Csv/Converter/RabobankDebetCredit.php
+++ b/app/Import/Converter/RabobankDebetCredit.php
@@ -8,27 +8,38 @@
  */
 
 declare(strict_types = 1);
-namespace FireflyIII\Helpers\Csv\Converter;
 
+namespace FireflyIII\Import\Converter;
+
+use Log;
 
 /**
  * Class RabobankDebetCredit
  *
- * @package FireflyIII\Helpers\Csv\Converter
+ * @package FireflyIII\Import\Converter
  */
 class RabobankDebetCredit extends BasicConverter implements ConverterInterface
 {
 
-
     /**
+     * @param $value
+     *
      * @return int
      */
-    public function convert(): int
+    public function convert($value): int
     {
-        if ($this->value == 'D') {
+        Log::debug('Going to convert ', ['value' => $value]);
+
+        if ($value === 'D') {
+            Log::debug('Return -1');
+            $this->setCertainty(100);
+
             return -1;
         }
 
+        Log::debug('Return 1');
+        $this->setCertainty(100);
+
         return 1;
     }
 }
diff --git a/app/Import/Converter/TagsComma.php b/app/Import/Converter/TagsComma.php
new file mode 100644
index 0000000000..2fb5981378
--- /dev/null
+++ b/app/Import/Converter/TagsComma.php
@@ -0,0 +1,89 @@
+ $value]);
+
+        if (strlen($value) === 0) {
+            $this->setCertainty(0);
+
+            return new Collection;
+        }
+        $parts = array_unique(explode(',', $value));
+        $set   = new Collection;
+        Log::debug('Exploded parts.', $parts);
+
+        /** @var TagRepositoryInterface $repository */
+        $repository = app(TagRepositoryInterface::class, [$this->user]);
+
+
+        /** @var string $part */
+        foreach ($parts as $part) {
+            if (isset($this->mapping[$part])) {
+                Log::debug('Found tag in mapping. Should exist.', ['value' => $part, 'map' => $this->mapping[$part]]);
+                $tag = $repository->find(intval($this->mapping[$part]));
+                if (!is_null($tag->id)) {
+                    Log::debug('Found tag by ID', ['id' => $tag->id]);
+
+                    $set->push($tag);
+                    continue;
+                }
+            }
+            // not mapped? Still try to find it first:
+            $tag = $repository->findByTag($part);
+            if (!is_null($tag->id)) {
+                Log::debug('Found tag by name ', ['id' => $tag->id]);
+
+                $set->push($tag);
+            }
+            if (is_null($tag->id)) {
+                // create new tag
+                $tag = $repository->store(
+                    [
+                        'tag'         => $part,
+                        'date'        => null,
+                        'description' => $part,
+                        'latitude'    => null,
+                        'longitude'   => null,
+                        'zoomLevel'   => null,
+                        'tagMode'     => 'nothing',
+                    ]
+                );
+                Log::debug('Created new tag', ['name' => $part, 'id' => $tag->id]);
+                $set->push($tag);
+            }
+        }
+        $this->setCertainty(100);
+
+        return $set;
+    }
+}
diff --git a/app/Import/Converter/TagsSpace.php b/app/Import/Converter/TagsSpace.php
new file mode 100644
index 0000000000..4f8c7e3196
--- /dev/null
+++ b/app/Import/Converter/TagsSpace.php
@@ -0,0 +1,90 @@
+ $value]);
+
+        if (strlen($value) === 0) {
+            $this->setCertainty(0);
+
+            return new Collection;
+        }
+        $parts = array_unique(explode(' ', $value));
+        $set   = new Collection;
+        Log::debug('Exploded parts.', $parts);
+
+        /** @var TagRepositoryInterface $repository */
+        $repository = app(TagRepositoryInterface::class, [$this->user]);
+
+
+        /** @var string $part */
+        foreach ($parts as $part) {
+            if (isset($this->mapping[$part])) {
+                Log::debug('Found tag in mapping. Should exist.', ['value' => $part, 'map' => $this->mapping[$part]]);
+                $tag = $repository->find(intval($this->mapping[$part]));
+                if (!is_null($tag->id)) {
+                    Log::debug('Found tag by ID', ['id' => $tag->id]);
+
+                    $set->push($tag);
+                    continue;
+                }
+            }
+            // not mapped? Still try to find it first:
+            $tag = $repository->findByTag($part);
+            if (!is_null($tag->id)) {
+                Log::debug('Found tag by name ', ['id' => $tag->id]);
+
+                $set->push($tag);
+            }
+            if (is_null($tag->id)) {
+                // create new tag
+                $tag = $repository->store(
+                    [
+                        'tag'         => $part,
+                        'date'        => null,
+                        'description' => $part,
+                        'latitude'    => null,
+                        'longitude'   => null,
+                        'zoomLevel'   => null,
+                        'tagMode'     => 'nothing',
+                    ]
+                );
+                Log::debug('Created new tag', ['name' => $part, 'id' => $tag->id]);
+                $set->push($tag);
+            }
+        }
+        $this->setCertainty(100);
+
+        return $set;
+
+    }
+}
diff --git a/app/Import/ImportEntry.php b/app/Import/ImportEntry.php
new file mode 100644
index 0000000000..3f2d577a2c
--- /dev/null
+++ b/app/Import/ImportEntry.php
@@ -0,0 +1,263 @@
+validFields as $value) {
+            $this->fields[$value]  = null;
+            $this->certain[$value] = 0;
+        }
+    }
+
+    /**
+     * @param string $role
+     * @param int    $certainty
+     * @param        $convertedValue
+     *
+     * @throws FireflyException
+     */
+    public function importValue(string $role, int $certainty, $convertedValue)
+    {
+        switch ($role) {
+            default:
+                Log::error('Import entry cannot handle object.', ['role' => $role]);
+                throw new FireflyException('Import entry cannot handle object of type "' . $role . '".');
+            case 'amount':
+                /*
+                 * Easy enough.
+                 */
+                $this->setFloat('amount', $convertedValue, $certainty);
+                $this->applyMultiplier('amount'); // if present.
+
+                return;
+            case 'account-id':
+            case 'account-iban':
+            case 'account-name':
+                $this->setObject('asset-account', $convertedValue, $certainty);
+                break;
+            case 'opposing-number':
+            case 'opposing-iban':
+            case 'opposing-id':
+            case 'opposing-name':
+                $this->setObject('opposing-account', $convertedValue, $certainty);
+                break;
+            case 'bill-id':
+            case 'bill-name':
+                $this->setObject('bill', $convertedValue, $certainty);
+                break;
+            case 'budget-id':
+            case 'budget-name':
+                $this->setObject('budget', $convertedValue, $certainty);
+                break;
+            case 'category-id':
+            case 'category-name':
+                $this->setObject('category', $convertedValue, $certainty);
+                break;
+            case 'currency-code':
+            case 'currency-id':
+            case 'currency-name':
+            case 'currency-symbol':
+                $this->setObject('currency', $convertedValue, $certainty);
+                break;
+            case 'date-transaction':
+                $this->setDate('date-transaction', $convertedValue, $certainty);
+                break;
+
+            case 'date-interest':
+                $this->setDate('date-interest', $convertedValue, $certainty);
+                break;
+            case 'date-book':
+                $this->setDate('date-book', $convertedValue, $certainty);
+                break;
+            case 'date-process':
+                $this->setDate('date-process', $convertedValue, $certainty);
+                break;
+            case 'sepa-ct-id':
+            case 'sepa-db':
+            case 'sepa-ct-op':
+            case 'description':
+                $this->setAppendableString('description', $convertedValue);
+                break;
+            case '_ignore':
+                break;
+            case 'ing-debet-credit':
+            case 'rabo-debet-credit':
+                $this->manipulateFloat('amount', 'multiply', $convertedValue);
+            $this->applyMultiplier('amount'); // if present.
+                break;
+            case 'tags-comma':
+            case 'tags-space':
+                $this->appendCollection('tags', $convertedValue);
+            break;
+            case 'external-id':
+                $this->externalID = $convertedValue;
+                break;
+
+        }
+    }
+
+    /**
+     * @param User $user
+     */
+    public function setUser(User $user)
+    {
+        $this->user = $user;
+    }
+
+    /**
+     * @param string     $field
+     * @param Collection $convertedValue
+     */
+    private function appendCollection(string $field, Collection $convertedValue)
+    {
+        if (is_null($this->fields[$field])) {
+            $this->fields[$field] = new Collection;
+        }
+        $this->fields[$field] = $this->fields[$field]->merge($convertedValue);
+    }
+
+    /**
+     * @param string $field
+     */
+    private function applyMultiplier(string $field)
+    {
+        if ($this->fields[$field] != 0 && $this->amountMultiplier != 0) {
+            $this->fields[$field] = $this->fields[$field] * $this->amountMultiplier;
+        }
+    }
+
+    /**
+     * @param string $field
+     * @param string $action
+     * @param        $convertedValue
+     *
+     * @throws FireflyException
+     */
+    private function manipulateFloat(string $field, string $action, $convertedValue)
+    {
+        switch ($action) {
+            default:
+                Log::error('Cannot handle manipulateFloat', ['field' => $field, 'action' => $action]);
+                throw new FireflyException('Cannot manipulateFloat with action ' . $action);
+            case 'multiply':
+                $this->amountMultiplier = $convertedValue;
+                break;
+        }
+    }
+
+    /**
+     * @param string $field
+     * @param string $value
+     */
+    private function setAppendableString(string $field, string $value)
+    {
+        $value = trim($value);
+        $this->fields[$field] .= ' ' . $value;
+    }
+
+    /**
+     * @param string  $field
+     * @param  Carbon $date
+     * @param int     $certainty
+     */
+    private function setDate(string $field, Carbon $date, int $certainty)
+    {
+        if ($certainty > $this->certain[$field] && !is_null($date)) {
+            Log::debug(sprintf('ImportEntry: %s is now %s with certainty %d', $field, $date->format('Y-m-d'), $certainty));
+            $this->fields[$field]  = $date;
+            $this->certain[$field] = $certainty;
+
+            return;
+        }
+        Log::info(sprintf('Will not set %s based on certainty %d (current certainty is %d) or NULL id.', $field, $certainty, $this->certain[$field]));
+
+    }
+
+    /**
+     * @param string $field
+     * @param float  $value
+     * @param int    $certainty
+     */
+    private function setFloat(string $field, float $value, int $certainty)
+    {
+        if ($certainty > $this->certain[$field]) {
+            Log::debug(sprintf('ImportEntry: %s is now %f with certainty %d', $field, $value, $certainty));
+            $this->fields[$field]  = $value;
+            $this->certain[$field] = $certainty;
+
+            return;
+        }
+        Log::info(sprintf('Will not set %s based on certainty %d (current certainty is %d).', $field, $certainty, $this->certain[$field]));
+    }
+
+    /**
+     * @param string $field
+     * @param        $object
+     * @param int    $certainty
+     */
+    private function setObject(string $field, $object, int $certainty)
+    {
+        if ($certainty > $this->certain[$field] && !is_null($object->id)) {
+            Log::debug(sprintf('ImportEntry: %s ID is now %d with certainty %d', $field, $object->id, $certainty));
+            $this->fields[$field]  = $object;
+            $this->certain[$field] = $certainty;
+
+            return;
+        }
+        Log::info(sprintf('Will not set %s based on certainty %d (current certainty is %d) or NULL id.', $field, $certainty, $this->certain[$field]));
+
+    }
+}
diff --git a/app/Import/ImportResult.php b/app/Import/ImportResult.php
new file mode 100644
index 0000000000..afc68bee82
--- /dev/null
+++ b/app/Import/ImportResult.php
@@ -0,0 +1,168 @@
+errors   = new Collection;
+        $this->warnings = new Collection;
+        $this->messages = new Collection;
+    }
+
+    /**
+     * @param string $error
+     *
+     * @return $this
+     */
+    public function appendError(string $error)
+    {
+        $this->errors->push($error);
+
+        return $this;
+    }
+
+    /**
+     * @param string $message
+     *
+     * @return $this
+     */
+    public function appendMessage(string $message)
+    {
+        $this->messages->push($message);
+
+        return $this;
+    }
+
+    /**
+     * @param string $title
+     *
+     * @return $this
+     */
+    public function appendTitle(string $title)
+    {
+        $this->title .= $title;
+
+        return $this;
+    }
+
+    /**
+     * @param string $warning
+     *
+     * @return $this
+     */
+    public function appendWarning(string $warning)
+    {
+        $this->warnings->push($warning);
+
+        return $this;
+    }
+
+    /**
+     * @return $this
+     */
+    public function failed()
+    {
+        $this->status = self::IMPORT_FAILED;
+
+        return $this;
+    }
+
+    /**
+     * @param Collection $errors
+     */
+    public function setErrors(Collection $errors)
+    {
+        $this->errors = $errors;
+    }
+
+    /**
+     * @param Collection $messages
+     */
+    public function setMessages(Collection $messages)
+    {
+        $this->messages = $messages;
+    }
+
+    /**
+     * @param string $title
+     *
+     * @return $this
+     */
+    public function setTitle(string $title)
+    {
+        $this->title = $title;
+
+        return $this;
+    }
+
+    /**
+     * @param Collection $warnings
+     */
+    public function setWarnings(Collection $warnings)
+    {
+        $this->warnings = $warnings;
+    }
+
+    /**
+     * @return $this
+     */
+    public function success()
+    {
+        $this->status = self::IMPORT_SUCCESS;
+
+        return $this;
+    }
+
+    /**
+     * @return bool
+     */
+    public function valid(): bool
+    {
+        return $this->status === self::IMPORT_VALID;
+    }
+
+    /**
+     *
+     */
+    public function validated()
+    {
+        $this->status = self::IMPORT_VALID;
+    }
+
+
+}
diff --git a/app/Import/ImportStorage.php b/app/Import/ImportStorage.php
new file mode 100644
index 0000000000..e016e93d24
--- /dev/null
+++ b/app/Import/ImportStorage.php
@@ -0,0 +1,247 @@
+entries = $entries;
+
+    }
+
+    /**
+     * @param User $user
+     */
+    public function setUser(User $user)
+    {
+        $this->user = $user;
+    }
+
+    /**
+     *
+     */
+    public function store()
+    {
+        foreach ($this->entries as $index => $entry) {
+            Log::debug(sprintf('--- import store start for row %d ---', $index));
+            $this->storeSingle($index, $entry);
+        }
+
+    }
+
+    /**
+     * @param float $amount
+     *
+     * @return string
+     */
+    private function makePositive(float $amount): string
+    {
+        $amount = strval($amount);
+        if (bccomp($amount, '0', 4) === -1) { // left is larger than right
+            $amount = bcmul($amount, '-1');
+        }
+
+        return $amount;
+    }
+
+    /**
+     * @param $entry
+     *
+     * @return array
+     * @throws FireflyException
+     */
+    private function storeAccounts($entry): array
+    {
+        // then create transactions. Single ones, unfortunately.
+        switch ($entry->fields['transaction-type']->type) {
+            default:
+                throw new FireflyException('ImportStorage cannot handle ' . $entry->fields['transaction-type']->type);
+            case TransactionType::WITHDRAWAL:
+                $source      = $entry->fields['asset-account'];
+                $destination = $entry->fields['opposing-account'];
+                // make amount positive, if it is not.
+                break;
+            case TransactionType::DEPOSIT:
+                $source      = $entry->fields['opposing-account'];
+                $destination = $entry->fields['asset-account'];
+                break;
+            case TransactionType::TRANSFER:
+                // depends on amount:
+                if ($entry->fields['amount'] < 0) {
+                    $source      = $entry->fields['asset-account'];
+                    $destination = $entry->fields['opposing-account'];
+                    break;
+                }
+                $destination = $entry->fields['asset-account'];
+                $source      = $entry->fields['opposing-account'];
+                break;
+        }
+
+        return [
+            'source'      => $source,
+            'destination' => $destination,
+        ];
+    }
+
+    /**
+     * @param TransactionJournal $journal
+     * @param ImportEntry        $entry
+     */
+    private function storeBill(TransactionJournal $journal, ImportEntry $entry)
+    {
+
+        if (!is_null($entry->fields['bill']) && !is_null($entry->fields['bill']->id)) {
+            $journal->bill()->associate($entry->fields['bill']);
+            Log::debug('Attached bill', ['id' => $entry->fields['bill']->id, 'name' => $entry->fields['bill']->name]);
+            $journal->save();
+        }
+    }
+
+    /**
+     * @param TransactionJournal $journal
+     * @param ImportEntry        $entry
+     */
+    private function storeBudget(TransactionJournal $journal, ImportEntry $entry)
+    {
+        if (!is_null($entry->fields['budget']) && !is_null($entry->fields['budget']->id)) {
+            $journal->budgets()->save($entry->fields['budget']);
+            Log::debug('Attached budget', ['id' => $entry->fields['budget']->id, 'name' => $entry->fields['budget']->name]);
+            $journal->save();
+        }
+
+    }
+
+    /**
+     * @param TransactionJournal $journal
+     * @param ImportEntry        $entry
+     */
+    private function storeCategory(TransactionJournal $journal, ImportEntry $entry)
+    {
+        if (!is_null($entry->fields['category']) && !is_null($entry->fields['category']->id)) {
+            $journal->categories()->save($entry->fields['category']);
+            Log::debug('Attached category', ['id' => $entry->fields['category']->id, 'name' => $entry->fields['category']->name]);
+            $journal->save();
+        }
+    }
+
+    /**
+     * @param $entry
+     *
+     * @return TransactionJournal
+     */
+    private function storeJournal($entry): TransactionJournal
+    {
+        $billId      = is_null($entry->fields['bill']) ? null : $entry->fields['bill']->id;
+        $journalData = [
+            'user_id'                 => $entry->user->id,
+            'transaction_type_id'     => $entry->fields['transaction-type']->id,
+            'bill_id'                 => $billId,
+            'transaction_currency_id' => $entry->fields['currency']->id,
+            'description'             => $entry->fields['description'],
+            'date'                    => $entry->fields['date-transaction'],
+            'interest_date'           => $entry->fields['date-interest'],
+            'book_date'               => $entry->fields['date-book'],
+            'process_date'            => $entry->fields['date-process'],
+            'completed'               => 0,
+        ];
+        /** @var TransactionJournal $journal */
+        $journal = TransactionJournal::create($journalData);
+
+        foreach ($journal->getErrors()->all() as $err) {
+            Log::error($err);
+        }
+        Log::debug('Created journal', ['id' => $journal->id]);
+
+        return $journal;
+    }
+
+    /**
+     * @param int         $index
+     * @param ImportEntry $entry
+     *
+     * @return ImportResult
+     * @throws FireflyException
+     */
+    private function storeSingle(int $index, ImportEntry $entry): ImportResult
+    {
+        if ($entry->valid === false) {
+            Log::error(sprintf('Cannot import row %d, because valid=false', $index));
+            $result = new ImportResult();
+            $result->failed();
+            $result->appendError(sprintf('Cannot import row %d, because valid=false', $index));
+
+            return $result;
+        }
+        Log::debug(sprintf('Going to store row %d', $index));
+
+
+        $journal  = $this->storeJournal($entry);
+        $amount   = $this->makePositive($entry->fields['amount']);
+        $accounts = $this->storeAccounts($entry);
+
+        // create new transactions. This is something that needs a rewrite for multiple/split transactions.
+        $sourceData = [
+            'account_id'             => $accounts['source']->id,
+            'transaction_journal_id' => $journal->id,
+            'description'            => $journal->description,
+            'amount'                 => bcmul($amount, '-1'),
+        ];
+
+        $destinationData = [
+            'account_id'             => $accounts['destination']->id,
+            'transaction_journal_id' => $journal->id,
+            'description'            => $journal->description,
+            'amount'                 => $amount,
+        ];
+
+        $one = Transaction::create($sourceData);
+        $two = Transaction::create($destinationData);
+        Log::debug('Created transaction 1', ['id' => $one->id, 'account' => $one->account_id, 'account_name' => $accounts['source']->name]);
+        Log::debug('Created transaction 2', ['id' => $two->id, 'account' => $two->account_id, 'account_name' => $accounts['destination']->name]);
+
+        $journal->completed = 1;
+        $journal->save();
+
+        // now attach budget and so on.
+        $this->storeBudget($journal, $entry);
+        $this->storeCategory($journal, $entry);
+        $this->storeBill($journal, $entry);
+
+
+    }
+}
diff --git a/app/Import/ImportValidator.php b/app/Import/ImportValidator.php
new file mode 100644
index 0000000000..af55598b53
--- /dev/null
+++ b/app/Import/ImportValidator.php
@@ -0,0 +1,389 @@
+entries = $entries;
+    }
+
+    /**
+     * Clean collection by filling in all the blanks.
+     */
+    public function clean(): Collection
+    {
+        $newCollection = new Collection;
+        /** @var ImportEntry $entry */
+        foreach ($this->entries as $index => $entry) {
+            Log::debug(sprintf('--- import validator start for row %d ---', $index));
+            /*
+             * X Adds the date (today) if no date is present.
+             * X Determins the types of accounts involved (asset, expense, revenue).
+             * X Determins the type of transaction (withdrawal, deposit, transfer).
+             * - Determins the currency of the transaction.
+             * X Adds a default description if there isn't one present.
+             */
+            $entry = $this->checkAmount($entry);
+            $entry = $this->setDate($entry);
+            $entry = $this->setAssetAccount($entry);
+            $entry = $this->setOpposingAccount($entry);
+            $entry = $this->cleanDescription($entry);
+            $entry = $this->setTransactionType($entry);
+            $entry = $this->setTransactionCurrency($entry);
+
+            $newCollection->put($index, $entry);
+        }
+
+        return $newCollection;
+    }
+
+    /**
+     * @param Account $defaultImportAccount
+     */
+    public function setDefaultImportAccount(Account $defaultImportAccount)
+    {
+        $this->defaultImportAccount = $defaultImportAccount;
+    }
+
+    /**
+     * @param User $user
+     */
+    public function setUser(User $user)
+    {
+        $this->user = $user;
+    }
+
+    /**
+     * @param ImportEntry $entry
+     *
+     * @return ImportEntry
+     */
+    private function checkAmount(ImportEntry $entry): ImportEntry
+    {
+        if ($entry->fields['amount'] == 0) {
+            $entry->valid = false;
+            Log::error('Amount of transaction is zero, cannot handle.');
+
+            return $entry;
+        }
+        Log::debug('Amount is OK.');
+
+        return $entry;
+    }
+
+    /**
+     * @param ImportEntry $entry
+     *
+     * @return ImportEntry
+     */
+    private function cleanDescription(ImportEntry $entry): ImportEntry
+    {
+
+        if (!isset($entry->fields['description'])) {
+            Log::debug('Set empty transaction description because field was not set.');
+            $entry->fields['description'] = '(empty transaction description)';
+
+            return $entry;
+        }
+        if (is_null($entry->fields['description'])) {
+            Log::debug('Set empty transaction description because field was null.');
+            $entry->fields['description'] = '(empty transaction description)';
+
+            return $entry;
+        }
+        $entry->fields['description'] = trim($entry->fields['description']);
+
+        if (strlen($entry->fields['description']) == 0) {
+            Log::debug('Set empty transaction description because field was empty.');
+            $entry->fields['description'] = '(empty transaction description)';
+
+            return $entry;
+        }
+        Log::debug('Transaction description is OK.', ['description' => $entry->fields['description']]);
+
+        return $entry;
+    }
+
+    /**
+     * @param Account $account
+     * @param string  $type
+     *
+     * @return Account
+     */
+    private function convertAccount(Account $account, string $type): Account
+    {
+        $accountType = $account->accountType->type;
+        if ($accountType === $type) {
+            Log::debug(sprintf('Account %s already of type %s', $account->name, $type));
+
+            return $account;
+        }
+        // find it first by new type:
+        /** @var AccountCrudInterface $repository */
+        $repository = app(AccountCrudInterface::class, [$this->user]);
+        $result     = $repository->findByName($account->name, [$type]);
+        if (is_null($result->id)) {
+            // can convert account:
+            Log::debug(sprintf('No account named %s of type %s, will convert.', $account->name, $type));
+            $result = $repository->updateAccountType($account, $type);
+
+        }
+
+        return $result;
+
+
+    }
+
+    /**
+     * @return Account
+     */
+    private function fallbackExpenseAccount(): Account
+    {
+
+        /** @var AccountCrudInterface $repository */
+        $repository = app(AccountCrudInterface::class, [$this->user]);
+        $name       = 'Unknown expense account';
+        $result     = $repository->findByName($name, [AccountType::EXPENSE]);
+        if (is_null($result->id)) {
+            $result = $repository->store(
+                ['name'   => $name, 'iban' => null, 'openingBalance' => 0, 'user' => $this->user->id, 'accountType' => 'expense', 'virtualBalance' => 0,
+                 'active' => true]
+            );
+        }
+
+        return $result;
+    }
+
+    /**
+     * @return Account
+     */
+    private function fallbackRevenueAccount(): Account
+    {
+
+        /** @var AccountCrudInterface $repository */
+        $repository = app(AccountCrudInterface::class, [$this->user]);
+        $name       = 'Unknown revenue account';
+        $result     = $repository->findByName($name, [AccountType::REVENUE]);
+        if (is_null($result->id)) {
+            $result = $repository->store(
+                ['name'   => $name, 'iban' => null, 'openingBalance' => 0, 'user' => $this->user->id, 'accountType' => 'revenue', 'virtualBalance' => 0,
+                 'active' => true]
+            );
+        }
+
+        return $result;
+    }
+
+    /**
+     * @param ImportEntry $entry
+     *
+     * @return ImportEntry
+     */
+    private function setAssetAccount(ImportEntry $entry): ImportEntry
+    {
+        if (is_null($entry->fields['asset-account'])) {
+            if (!is_null($this->defaultImportAccount)) {
+                Log::debug('Set asset account from default asset account');
+                $entry->fields['asset-account'] = $this->defaultImportAccount;
+
+                return $entry;
+            }
+            // default import is null? should not happen. Entry cannot be imported.
+            // set error message and block.
+            $entry->valid = false;
+            Log::error('Cannot import entry. Asset account is NULL and import account is also NULL.');
+
+        }
+        Log::debug('Asset account is OK.', ['id' => $entry->fields['asset-account']->id, 'name' => $entry->fields['asset-account']->name]);
+
+        return $entry;
+    }
+
+
+    /**
+     * @param ImportEntry $entry
+     *
+     * @return ImportEntry
+     */
+    private function setDate(ImportEntry $entry): ImportEntry
+    {
+        if (is_null($entry->fields['date-transaction']) || $entry->certain['date-transaction'] == 0) {
+            // empty date field? find alternative.
+            $alternatives = ['date-book', 'date-interest', 'date-process'];
+            foreach ($alternatives as $alternative) {
+                if (!is_null($entry->fields[$alternative])) {
+                    Log::debug(sprintf('Copied date-transaction from %s.', $alternative));
+                    $entry->fields['date-transaction'] = clone $entry->fields[$alternative];
+
+                    return $entry;
+                }
+            }
+            // date is still null at this point
+            Log::debug('Set date-transaction to today.');
+            $entry->fields['date-transaction'] = new Carbon;
+
+            return $entry;
+        }
+
+        // confidence is zero?
+
+        Log::debug('Date-transaction is OK');
+
+        return $entry;
+    }
+
+    /**
+     * @param ImportEntry $entry
+     *
+     * @return ImportEntry
+     */
+    private function setOpposingAccount(ImportEntry $entry): ImportEntry
+    {
+        // empty opposing account. Create one based on amount.
+        if (is_null($entry->fields['opposing-account'])) {
+
+            if ($entry->fields['amount'] < 0) {
+                // create or find general opposing expense account.
+                Log::debug('Created fallback expense account');
+                $entry->fields['opposing-account'] = $this->fallbackExpenseAccount();
+
+                return $entry;
+            }
+            Log::debug('Created fallback revenue account');
+            $entry->fields['opposing-account'] = $this->fallbackRevenueAccount();
+
+            return $entry;
+        }
+
+        // opposing is of type "import". Convert to correct type (by amount):
+        $type = $entry->fields['opposing-account']->accountType->type;
+        if ($type == AccountType::IMPORT && $entry->fields['amount'] < 0) {
+            $account                           = $this->convertAccount($entry->fields['opposing-account'], AccountType::EXPENSE);
+            $entry->fields['opposing-account'] = $account;
+            Log::debug('Converted import account to expense account');
+
+            return $entry;
+        }
+        if ($type == AccountType::IMPORT && $entry->fields['amount'] > 0) {
+            $account                           = $this->convertAccount($entry->fields['opposing-account'], AccountType::REVENUE);
+            $entry->fields['opposing-account'] = $account;
+            Log::debug('Converted import account to revenue account');
+
+            return $entry;
+        }
+        // amount < 0, but opposing is revenue
+        if ($type == AccountType::REVENUE && $entry->fields['amount'] < 0) {
+            $account                           = $this->convertAccount($entry->fields['opposing-account'], AccountType::EXPENSE);
+            $entry->fields['opposing-account'] = $account;
+            Log::debug('Converted revenue account to expense account');
+
+            return $entry;
+        }
+
+        // amount > 0, but opposing is expense
+        if ($type == AccountType::EXPENSE && $entry->fields['amount'] < 0) {
+            $account                           = $this->convertAccount($entry->fields['opposing-account'], AccountType::REVENUE);
+            $entry->fields['opposing-account'] = $account;
+            Log::debug('Converted expense account to revenue account');
+
+            return $entry;
+        }
+        // account type is OK
+        Log::debug('Opposing account is OK.');
+
+        return $entry;
+
+    }
+
+    /**
+     * @param ImportEntry $entry
+     *
+     * @return ImportEntry
+     */
+    private function setTransactionCurrency(ImportEntry $entry): ImportEntry
+    {
+        if (is_null($entry->fields['currency'])) {
+            /** @var CurrencyRepositoryInterface $repository */
+            $repository                = app(CurrencyRepositoryInterface::class);
+            $entry->fields['currency'] = $repository->findByCode(env('DEFAULT_CURRENCY', 'EUR'));
+            Log::debug('Set currency to EUR');
+
+            return $entry;
+        }
+        Log::debug('Currency is OK');
+
+        return $entry;
+    }
+
+    /**
+     * @param ImportEntry $entry
+     *
+     * @return ImportEntry
+     */
+    private function setTransactionType(ImportEntry $entry): ImportEntry
+    {
+        Log::debug(sprintf('Opposing account is of type %s', $entry->fields['opposing-account']->accountType->type));
+        $type = $entry->fields['opposing-account']->accountType->type;
+        switch ($type) {
+            case AccountType::EXPENSE:
+                $entry->fields['transaction-type'] = TransactionType::whereType(TransactionType::WITHDRAWAL)->first();
+                Log::debug('Transaction type is now withdrawal.');
+
+                return $entry;
+            case AccountType::REVENUE:
+                $entry->fields['transaction-type'] = TransactionType::whereType(TransactionType::DEPOSIT)->first();
+                Log::debug('Transaction type is now deposit.');
+
+                return $entry;
+            case AccountType::ASSET:
+                $entry->fields['transaction-type'] = TransactionType::whereType(TransactionType::TRANSFER)->first();
+                Log::debug('Transaction type is now transfer.');
+
+                return $entry;
+        }
+        Log::error(sprintf('Opposing account is of type %s, cannot handle this.', $type));
+        $entry->valid = false;
+
+        return $entry;
+    }
+
+
+}
diff --git a/app/Import/Importer/CsvImporter.php b/app/Import/Importer/CsvImporter.php
new file mode 100644
index 0000000000..3ce6694247
--- /dev/null
+++ b/app/Import/Importer/CsvImporter.php
@@ -0,0 +1,134 @@
+collection = new Collection;
+    }
+
+    /**
+     * Run the actual import
+     *
+     * @return Collection
+     */
+    public function createImportEntries(): Collection
+    {
+        $config  = $this->job->configuration;
+        $content = $this->job->uploadFileContents();
+
+        // create CSV reader.
+        $reader = Reader::createFromString($content);
+        $reader->setDelimiter($config['delimiter']);
+        $start   = $config['has-headers'] ? 1 : 0;
+        $results = $reader->fetch();
+        foreach ($results as $index => $row) {
+            if ($index >= $start) {
+                Log::debug('----- import entry build start --');
+                Log::debug(sprintf('Now going to import row %d.', $index));
+                $importEntry = $this->importSingleRow($index, $row);
+                $this->collection->put($index, $importEntry);
+            }
+        }
+        Log::debug(sprintf('Import collection contains %d entries', $this->collection->count()));
+
+        return $this->collection;
+    }
+
+    /**
+     * @param ImportJob $job
+     */
+    public function setJob(ImportJob $job)
+    {
+        $this->job = $job;
+    }
+
+    /**
+     * @param int   $index
+     * @param array $row
+     *
+     * @return ImportEntry
+     */
+    private function importSingleRow(int $index, array $row): ImportEntry
+    {
+        // create import object. This is where each entry ends up.
+        $object = new ImportEntry;
+
+        Log::debug(sprintf('Now at row %d', $index));
+
+        // set some vars:
+        $object->setUser($this->job->user);
+        $config = $this->job->configuration;
+
+        // and this is the point where the specifix go to work.
+        foreach ($config['specifics'] as $name => $enabled) {
+            /** @var SpecificInterface $specific */
+            $specific = app('FireflyIII\Import\Specifics\\' . $name);
+
+            // it returns the row, possibly modified:
+            $row = $specific->run($row);
+        }
+
+        foreach ($row as $rowIndex => $value) {
+            // find the role for this column:
+            $role           = $config['column-roles'][$rowIndex] ?? '_ignore';
+            $doMap          = $config['column-do-mapping'][$rowIndex] ?? false;
+            $converterClass = config('csv.import_roles.' . $role . '.converter');
+            $mapping        = $config['column-mapping-config'][$rowIndex] ?? [];
+            /** @var ConverterInterface $converter */
+            $converter = app('FireflyIII\\Import\\Converter\\' . $converterClass);
+            // set some useful values for the converter:
+            $converter->setMapping($mapping);
+            $converter->setDoMap($doMap);
+            $converter->setUser($this->job->user);
+            $converter->setConfig($config);
+
+            // run the converter for this value:
+            $convertedValue = $converter->convert($value);
+            $certainty      = $converter->getCertainty();
+
+            // log it.
+            Log::debug('Value ', ['index' => $rowIndex, 'value' => $value, 'role' => $role]);
+
+            // store in import entry:
+            Log::debug('Going to import', ['role' => $role, 'value' => $value, 'certainty' => $certainty]);
+            $object->importValue($role, $certainty, $convertedValue);
+        }
+
+
+        return $object;
+
+    }
+}
diff --git a/app/Import/Importer/ImporterInterface.php b/app/Import/Importer/ImporterInterface.php
new file mode 100644
index 0000000000..91dcbd3a7d
--- /dev/null
+++ b/app/Import/Importer/ImporterInterface.php
@@ -0,0 +1,35 @@
+command = $command;
+        $this->changeLevel(env('LOG_LEVEL', 'debug'));
+    }
+
+    /**
+     * Writes the record down to the log of the implementing handler
+     *
+     * @param  array $record
+     *
+     * @return void
+     */
+    protected function write(array $record)
+    {
+        $this->command->line((string)trim($record['formatted']));
+    }
+
+    /**
+     * @param string $level
+     */
+    private function changeLevel(string $level)
+    {
+        switch ($level) {
+            case 'debug':
+                $this->setLevel(Logger::DEBUG);
+                break;
+            case 'info':
+                $this->setLevel(Logger::INFO);
+                break;
+            case 'notice':
+                $this->setLevel(Logger::NOTICE);
+                break;
+            case 'warning':
+                $this->setLevel(Logger::WARNING);
+                break;
+            case 'error':
+                $this->setLevel(Logger::ERROR);
+                break;
+            case 'critical':
+                $this->setLevel(Logger::CRITICAL);
+                break;
+            case 'alert':
+                $this->setLevel(Logger::ALERT);
+                break;
+            case 'emergency':
+                $this->setLevel(Logger::EMERGENCY);
+                break;
+        }
+    }
+}
diff --git a/app/Import/Mapper/AssetAccountIbans.php b/app/Import/Mapper/AssetAccountIbans.php
new file mode 100644
index 0000000000..8ff105ff76
--- /dev/null
+++ b/app/Import/Mapper/AssetAccountIbans.php
@@ -0,0 +1,56 @@
+getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
+        $topList = [];
+        $list    = [];
+
+        /** @var Account $account */
+        foreach ($set as $account) {
+            $iban = $account->iban ?? '';
+            if (strlen($iban) > 0) {
+                $topList[$account->id] = $account->iban . ' (' . $account->name . ')';
+            }
+            if (strlen($iban) == 0) {
+                $list[$account->id] = $account->name;
+            }
+        }
+        asort($topList);
+        asort($list);
+
+        $list = $topList + $list;
+        $list = [0 => trans('csv.do_not_map')] + $list;
+
+        return $list;
+
+    }
+}
diff --git a/app/Helpers/Csv/Mapper/AssetAccount.php b/app/Import/Mapper/AssetAccounts.php
similarity index 52%
rename from app/Helpers/Csv/Mapper/AssetAccount.php
rename to app/Import/Mapper/AssetAccounts.php
index 8f32bbad57..21e4007361 100644
--- a/app/Helpers/Csv/Mapper/AssetAccount.php
+++ b/app/Import/Mapper/AssetAccounts.php
@@ -1,6 +1,6 @@
 accounts()->with(
-            ['accountmeta' => function (HasMany $query) {
-                $query->where('name', 'accountRole');
-            }]
-        )->accountTypeIn(['Default account', 'Asset account'])->orderBy('accounts.name', 'ASC')->get(['accounts.*']);
-
+        /** @var AccountCrudInterface $crud */
+        $crud = app(AccountCrudInterface::class);
+        $set  = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
         $list = [];
 
         /** @var Account $account */
-        foreach ($result as $account) {
+        foreach ($set as $account) {
             $name = $account->name;
             $iban = $account->iban ?? '';
             if (strlen($iban) > 0) {
@@ -47,8 +45,9 @@ class AssetAccount implements MapperInterface
 
         asort($list);
 
-        $list = [0 => trans('firefly.csv_do_not_map')] + $list;
+        $list = [0 => trans('csv.do_not_map')] + $list;
 
         return $list;
+
     }
 }
diff --git a/app/Import/Mapper/Bills.php b/app/Import/Mapper/Bills.php
new file mode 100644
index 0000000000..b1629d4865
--- /dev/null
+++ b/app/Import/Mapper/Bills.php
@@ -0,0 +1,46 @@
+getBills();
+        $list       = [];
+
+        /** @var Bill $bill */
+        foreach ($result as $bill) {
+            $list[$bill->id] = $bill->name . ' [' . $bill->match . ']';
+        }
+        asort($list);
+
+        $list = [0 => trans('csv.do_not_map')] + $list;
+
+        return $list;
+
+    }
+}
diff --git a/app/Import/Mapper/Budgets.php b/app/Import/Mapper/Budgets.php
new file mode 100644
index 0000000000..fad817ed32
--- /dev/null
+++ b/app/Import/Mapper/Budgets.php
@@ -0,0 +1,47 @@
+getBudgets();
+        $list       = [];
+
+        /** @var Budget $budget */
+        foreach ($result as $budget) {
+            $list[$budget->id] = $budget->name;
+        }
+        asort($list);
+
+        $list = [0 => trans('csv.do_not_map')] + $list;
+
+        return $list;
+
+    }
+}
diff --git a/app/Import/Mapper/Categories.php b/app/Import/Mapper/Categories.php
new file mode 100644
index 0000000000..784e748848
--- /dev/null
+++ b/app/Import/Mapper/Categories.php
@@ -0,0 +1,47 @@
+getCategories();
+        $list       = [];
+
+        /** @var Category $category */
+        foreach ($result as $category) {
+            $list[$category->id] = $category->name;
+        }
+        asort($list);
+
+        $list = [0 => trans('csv.do_not_map')] + $list;
+
+        return $list;
+
+    }
+}
diff --git a/app/Helpers/Csv/Mapper/MapperInterface.php b/app/Import/Mapper/MapperInterface.php
similarity index 82%
rename from app/Helpers/Csv/Mapper/MapperInterface.php
rename to app/Import/Mapper/MapperInterface.php
index eb6286d4f2..c285c9b31f 100644
--- a/app/Helpers/Csv/Mapper/MapperInterface.php
+++ b/app/Import/Mapper/MapperInterface.php
@@ -8,15 +8,17 @@
  */
 
 declare(strict_types = 1);
-namespace FireflyIII\Helpers\Csv\Mapper;
+
+namespace FireflyIII\Import\Mapper;
 
 /**
  * Interface MapperInterface
  *
- * @package FireflyIII\Helpers\Csv\Mapper
+ * @package FireflyIII\Import\Mapper
  */
 interface MapperInterface
 {
+
     /**
      * @return array
      */
diff --git a/app/Import/Mapper/OpposingAccountIbans.php b/app/Import/Mapper/OpposingAccountIbans.php
new file mode 100644
index 0000000000..2e1b7c8511
--- /dev/null
+++ b/app/Import/Mapper/OpposingAccountIbans.php
@@ -0,0 +1,61 @@
+getAccountsByType(
+            [
+                AccountType::DEFAULT, AccountType::ASSET,
+                AccountType::EXPENSE, AccountType::BENEFICIARY,
+                AccountType::REVENUE
+            ]);
+        $topList = [];
+        $list    = [];
+
+        /** @var Account $account */
+        foreach ($set as $account) {
+            $iban = $account->iban ?? '';
+            if (strlen($iban) > 0) {
+                $topList[$account->id] = $account->iban . ' (' . $account->name . ')';
+            }
+            if (strlen($iban) == 0) {
+                $list[$account->id] = $account->name;
+            }
+        }
+        asort($topList);
+        asort($list);
+
+        $list = $topList + $list;
+        $list = [0 => trans('csv.do_not_map')] + $list;
+
+
+        return $list;
+    }
+}
diff --git a/app/Import/Mapper/OpposingAccounts.php b/app/Import/Mapper/OpposingAccounts.php
new file mode 100644
index 0000000000..37f67dccae
--- /dev/null
+++ b/app/Import/Mapper/OpposingAccounts.php
@@ -0,0 +1,57 @@
+getAccountsByType(
+            [
+                AccountType::DEFAULT, AccountType::ASSET,
+                AccountType::EXPENSE, AccountType::BENEFICIARY,
+                AccountType::REVENUE
+            ]);
+        $list = [];
+
+        /** @var Account $account */
+        foreach ($set as $account) {
+            $name = $account->name;
+            $iban = $account->iban ?? '';
+            if (strlen($iban) > 0) {
+                $name .= ' (' . $account->iban . ')';
+            }
+            $list[$account->id] = $name;
+        }
+
+        asort($list);
+
+        $list = [0 => trans('csv.do_not_map')] + $list;
+
+        return $list;
+    }
+}
diff --git a/app/Import/Mapper/Tags.php b/app/Import/Mapper/Tags.php
new file mode 100644
index 0000000000..f38d1e0f08
--- /dev/null
+++ b/app/Import/Mapper/Tags.php
@@ -0,0 +1,46 @@
+get();
+        $list       = [];
+
+        /** @var Tag $tag */
+        foreach ($result as $tag) {
+            $list[$tag->id] = $tag->tag;
+        }
+        asort($list);
+
+        $list = [0 => trans('csv.do_not_map')] + $list;
+
+        return $list;
+
+    }
+}
diff --git a/app/Helpers/Csv/Mapper/TransactionCurrency.php b/app/Import/Mapper/TransactionCurrencies.php
similarity index 70%
rename from app/Helpers/Csv/Mapper/TransactionCurrency.php
rename to app/Import/Mapper/TransactionCurrencies.php
index f4257b1510..ff6d4a1feb 100644
--- a/app/Helpers/Csv/Mapper/TransactionCurrency.php
+++ b/app/Import/Mapper/TransactionCurrencies.php
@@ -1,6 +1,6 @@
  trans('firefly.csv_do_not_map')] + $list;
+        $list = [0 => trans('csv.do_not_map')] + $list;
 
         return $list;
+
     }
 }
diff --git a/app/Import/MapperPreProcess/PreProcessorInterface.php b/app/Import/MapperPreProcess/PreProcessorInterface.php
new file mode 100644
index 0000000000..3f6187a1eb
--- /dev/null
+++ b/app/Import/MapperPreProcess/PreProcessorInterface.php
@@ -0,0 +1,28 @@
+defaultImportAccount = new Account;
+    }
+
+    /**
+     * Create initial (empty) configuration array.
+     *
+     *
+     *
+     * @return bool
+     */
+    public function configure(): bool
+    {
+        if (is_null($this->job->configuration) || (is_array($this->job->configuration) && count($this->job->configuration) === 0)) {
+            Log::debug('No config detected, will create empty one.');
+
+            $config                   = [
+                'has-headers'             => false, // assume
+                'date-format'             => 'Ymd', // assume
+                'delimiter'               => ',', // assume
+                'import-account'          => 0, // none,
+                'specifics'               => [], // none
+                'column-count'            => 0, // unknown
+                'column-roles'            => [], // unknown
+                'column-do-mapping'       => [], // not yet set which columns must be mapped
+                'column-roles-complete'   => false, // not yet configured roles for columns
+                'column-mapping-config'   => [], // no mapping made yet.
+                'column-mapping-complete' => false, // so mapping is not complete.
+            ];
+            $this->job->configuration = $config;
+            $this->job->save();
+
+            return true;
+        }
+
+        // need to do nothing, for now.
+        Log::debug('Detected config in upload, will use that one. ', $this->job->configuration);
+
+        return true;
+    }
+
+    /**
+     * @return array
+     */
+    public function getConfigurationData(): array
+    {
+        $crud       = app('FireflyIII\Crud\Account\AccountCrudInterface');
+        $accounts   = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
+        $delimiters = [
+            ','   => trans('form.csv_comma'),
+            ';'   => trans('form.csv_semicolon'),
+            'tab' => trans('form.csv_tab'),
+        ];
+
+        $specifics = [];
+
+        // collect specifics.
+        foreach (config('csv.import_specifics') as $name => $className) {
+            $specifics[$name] = [
+                'name'        => $className::getName(),
+                'description' => $className::getDescription(),
+            ];
+        }
+
+        $data = [
+            'accounts'           => ExpandedForm::makeSelectList($accounts),
+            'specifix'           => [],
+            'delimiters'         => $delimiters,
+            'upload_path'        => storage_path('upload'),
+            'is_upload_possible' => is_writable(storage_path('upload')),
+            'specifics'          => $specifics,
+        ];
+
+        return $data;
+    }
+
+    /**
+     * This method returns the data required for the view that will let the user add settings to the import job.
+     *
+     * @return array
+     */
+    public function getDataForSettings(): array
+    {
+
+        if ($this->doColumnRoles()) {
+            $data = $this->getDataForColumnRoles();
+
+            return $data;
+        }
+
+        if ($this->doColumnMapping()) {
+            $data = $this->getDataForColumnMapping();
+
+            return $data;
+        }
+
+        echo 'no settings to do.';
+        exit;
+
+    }
+
+    /**
+     * This method returns the name of the view that will be shown to the user to further configure
+     * the import job.
+     *
+     * @return string
+     */
+    public function getViewForSettings(): string
+    {
+        if ($this->doColumnRoles()) {
+            return 'import.csv.roles';
+        }
+
+        if ($this->doColumnMapping()) {
+            return 'import.csv.map';
+        }
+
+        echo 'no view for settings';
+        exit;
+    }
+
+    /**
+     * This method returns whether or not the user must configure this import
+     * job further.
+     *
+     * @return bool
+     */
+    public function requireUserSettings(): bool
+    {
+        Log::debug('doColumnMapping is ' . ($this->doColumnMapping() ? 'true' : 'false'));
+        Log::debug('doColumnRoles is ' . ($this->doColumnRoles() ? 'true' : 'false'));
+        if ($this->doColumnMapping() || $this->doColumnRoles()) {
+            Log::debug('Return true');
+
+            return true;
+        }
+        Log::debug('Return false');
+
+        return false;
+    }
+
+    /**
+     * @param array $data
+     *
+     * @return bool
+     */
+    public function saveImportConfiguration(array $data, FileBag $files): bool
+    {
+        /** @var AccountCrud $repository */
+        $repository = app(AccountCrud::class, [auth()->user()]);
+        $importId   = $data['csv_import_account'] ?? 0;
+        $account    = $repository->find(intval($importId));
+
+        $hasHeaders            = isset($data['has_headers']) && intval($data['has_headers']) === 1 ? true : false;
+        $config                = $this->job->configuration;
+        $config['has-headers'] = $hasHeaders;
+        $config['date-format'] = $data['date_format'];
+        $config['delimiter']   = $data['csv_delimiter'];
+        $config['delimiter']   = $config['delimiter'] === 'tab' ? "\t" : $config['delimiter'];
+
+        Log::debug('Entered import account.', ['id' => $importId]);
+
+
+        if (!is_null($account->id)) {
+            Log::debug('Found account.', ['id' => $account->id, 'name' => $account->name]);
+            $config['import-account'] = $account->id;
+        } else {
+            Log::error('Could not find anything for csv_import_account.', ['id' => $importId]);
+        }
+        // loop specifics.
+        if (isset($data['specifics']) && is_array($data['specifics'])) {
+            foreach ($data['specifics'] as $name => $enabled) {
+                $config['specifics'][$name] = 1;
+            }
+        }
+        $this->job->configuration = $config;
+        $this->job->save();
+
+        return true;
+
+
+    }
+
+    /**
+     * @param ImportJob $job
+     */
+    public function setJob(ImportJob $job)
+    {
+        $this->job = $job;
+    }
+
+    /**
+     * Store the settings filled in by the user, if applicable.
+     *
+     * @param Request $request
+     *
+     */
+    public function storeSettings(Request $request)
+    {
+        $config = $this->job->configuration;
+        $all    = $request->all();
+        if ($request->get('settings') == 'roles') {
+            $count = $config['column-count'];
+
+            $roleSet = 0; // how many roles have been defined
+            $mapSet  = 0;  // how many columns must be mapped
+            for ($i = 0; $i < $count; $i++) {
+                $selectedRole = $all['role'][$i] ?? '_ignore';
+                $doMapping    = isset($all['map'][$i]) && $all['map'][$i] == '1' ? true : false;
+                if ($selectedRole == '_ignore' && $doMapping === true) {
+                    $doMapping = false; // cannot map ignored columns.
+                }
+                if ($selectedRole != '_ignore') {
+                    $roleSet++;
+                }
+                if ($doMapping === true) {
+                    $mapSet++;
+                }
+                $config['column-roles'][$i]      = $selectedRole;
+                $config['column-do-mapping'][$i] = $doMapping;
+            }
+            if ($roleSet > 0) {
+                $config['column-roles-complete'] = true;
+                $this->job->configuration        = $config;
+                $this->job->save();
+            }
+            if ($mapSet === 0) {
+                // skip setting of map:
+                $config['column-mapping-complete'] = true;
+            }
+        }
+        if ($request->get('settings') == 'map') {
+            if (isset($all['mapping'])) {
+                foreach ($all['mapping'] as $index => $data) {
+                    $config['column-mapping-config'][$index] = [];
+                    foreach ($data as $value => $mapId) {
+                        $mapId = intval($mapId);
+                        if ($mapId !== 0) {
+                            $config['column-mapping-config'][$index][$value] = intval($mapId);
+                        }
+                    }
+                }
+            }
+
+            // set thing to be completed.
+            $config['column-mapping-complete'] = true;
+            $this->job->configuration          = $config;
+            $this->job->save();
+        }
+    }
+
+    /**
+     * @return bool
+     */
+    private function doColumnMapping(): bool
+    {
+        $mapArray = $this->job->configuration['column-do-mapping'] ?? [];
+        $doMap    = false;
+        foreach ($mapArray as $value) {
+            if ($value === true) {
+                $doMap = true;
+                break;
+            }
+        }
+
+        return $this->job->configuration['column-mapping-complete'] === false && $doMap;
+    }
+
+    /**
+     * @return bool
+     */
+    private function doColumnRoles(): bool
+    {
+        return $this->job->configuration['column-roles-complete'] === false;
+    }
+
+    /**
+     * @return array
+     */
+    private function getDataForColumnMapping(): array
+    {
+        $config  = $this->job->configuration;
+        $data    = [];
+        $indexes = [];
+
+        foreach ($config['column-do-mapping'] as $index => $mustBeMapped) {
+            if ($mustBeMapped) {
+                $column        = $config['column-roles'][$index] ?? '_ignore';
+                $canBeMapped   = config('csv.import_roles.' . $column . '.mappable');
+                $preProcessMap = config('csv.import_roles.' . $column . '.pre-process-map');
+                if ($canBeMapped) {
+                    $mapperName = '\FireflyIII\Import\Mapper\\' . config('csv.import_roles.' . $column . '.mapper');
+                    /** @var MapperInterface $mapper */
+                    $mapper       = new $mapperName;
+                    $indexes[]    = $index;
+                    $data[$index] = [
+                        'name'          => $column,
+                        'mapper'        => $mapperName,
+                        'index'         => $index,
+                        'options'       => $mapper->getMap(),
+                        'preProcessMap' => null,
+                        'values'        => [],
+                    ];
+                    if ($preProcessMap) {
+                        $data[$index]['preProcessMap'] = '\FireflyIII\Import\MapperPreProcess\\' .
+                                                         config('csv.import_roles.' . $column . '.pre-process-mapper');
+                    }
+                }
+
+            }
+        }
+
+        // in order to actually map we also need all possible values from the CSV file.
+        $content = $this->job->uploadFileContents();
+        /** @var Reader $reader */
+        $reader = Reader::createFromString($content);
+        $reader->setDelimiter($config['delimiter']);
+        $results = $reader->fetch();
+
+        foreach ($results as $rowIndex => $row) {
+
+            // run specifics here:
+            // and this is the point where the specifix go to work.
+            foreach ($config['specifics'] as $name => $enabled) {
+                /** @var SpecificInterface $specific */
+                $specific = app('FireflyIII\Import\Specifics\\' . $name);
+
+                // it returns the row, possibly modified:
+                $row = $specific->run($row);
+            }
+
+            //do something here
+            foreach ($indexes as $index) { // this is simply 1, 2, 3, etc.
+                $value = $row[$index];
+                if (strlen($value) > 0) {
+
+                    // we can do some preprocessing here,
+                    // which is exclusively to fix the tags:
+                    if (!is_null($data[$index]['preProcessMap'])) {
+                        /** @var PreProcessorInterface $preProcessor */
+                        $preProcessor           = app($data[$index]['preProcessMap']);
+                        $result                 = $preProcessor->run($value);
+                        $data[$index]['values'] = array_merge($data[$index]['values'], $result);
+
+                        Log::debug($rowIndex . ':' . $index . 'Value before preprocessor', ['value' => $value]);
+                        Log::debug($rowIndex . ':' . $index . 'Value after preprocessor', ['value-new' => $result]);
+                        Log::debug($rowIndex . ':' . $index . 'Value after joining', ['value-complete' => $data[$index]['values']]);
+
+
+                        continue;
+                    }
+
+                    $data[$index]['values'][] = $value;
+                }
+            }
+        }
+        foreach ($data as $index => $entry) {
+            $data[$index]['values'] = array_unique($data[$index]['values']);
+        }
+
+        return $data;
+    }
+
+    /**
+     * @return array
+     */
+    private function getDataForColumnRoles():array
+    {
+        $config = $this->job->configuration;
+        $data   = [
+            'columns'     => [],
+            'columnCount' => 0,
+        ];
+
+        // show user column role configuration.
+        $content = $this->job->uploadFileContents();
+
+        // create CSV reader.
+        $reader = Reader::createFromString($content);
+        $reader->setDelimiter($config['delimiter']);
+        $start = $config['has-headers'] ? 1 : 0;
+        $end   = $start + self::EXAMPLE_ROWS; // first X rows
+
+        // collect example data in $data['columns']
+        while ($start < $end) {
+            $row = $reader->fetchOne($start);
+
+            // run specifics here:
+            // and this is the point where the specifix go to work.
+            foreach ($config['specifics'] as $name => $enabled) {
+                /** @var SpecificInterface $specific */
+                $specific = app('FireflyIII\Import\Specifics\\' . $name);
+
+                // it returns the row, possibly modified:
+                $row = $specific->run($row);
+            }
+
+            foreach ($row as $index => $value) {
+                $value = trim($value);
+                if (strlen($value) > 0) {
+                    $data['columns'][$index][] = $value;
+                }
+            }
+            $start++;
+            $data['columnCount'] = count($row) > $data['columnCount'] ? count($row) : $data['columnCount'];
+        }
+
+        // make unique example data
+        foreach ($data['columns'] as $index => $values) {
+            $data['columns'][$index] = array_unique($values);
+        }
+
+        $data['set_roles'] = [];
+        // collect possible column roles:
+        $data['available_roles'] = [];
+        foreach (array_keys(config('csv.import_roles')) as $role) {
+            $data['available_roles'][$role] = trans('csv.column_' . $role);
+        }
+
+        $config['column-count']   = $data['columnCount'];
+        $this->job->configuration = $config;
+        $this->job->save();
+
+        return $data;
+
+
+    }
+}
diff --git a/app/Import/Setup/SetupInterface.php b/app/Import/Setup/SetupInterface.php
new file mode 100644
index 0000000000..b45c4337c0
--- /dev/null
+++ b/app/Import/Setup/SetupInterface.php
@@ -0,0 +1,85 @@
+setProcessorType(self::POST_PROCESSOR);
-    }
-
-
-    /**
-     * @return array
-     */
-    public function fix(): array
-    {
-        // Try to parse the description in known formats.
-        $parsed = $this->parseSepaDescription() || $this->parseTRTPDescription() || $this->parseGEABEADescription() || $this->parseABNAMRODescription();
-
-        // If the description could not be parsed, specify an unknown opposing 
-        // account, as an opposing account is required
-        if (!$parsed) {
-            $this->data['opposing-account-name'] = trans('firefly.unknown');
-        }
-
-        return $this->data;
+        return 'Fixes possible problems with ABN Amro descriptions.';
     }
 
     /**
-     * @param array $data
+     * @return string
      */
-    public function setData(array $data)
+    public static function getName(): string
     {
-        $this->data = $data;
+        return 'ABN Amro description';
     }
 
     /**
      * @param array $row
+     *
+     * @return array
      */
-    public function setRow(array $row)
+    public function run(array $row): array
     {
         $this->row = $row;
+        // Try to parse the description in known formats.
+        $parsed = $this->parseSepaDescription() || $this->parseTRTPDescription() || $this->parseGEABEADescription() || $this->parseABNAMRODescription();
+
+        // If the description could not be parsed, specify an unknown opposing
+        // account, as an opposing account is required
+        if (!$parsed) {
+            $this->row[7] = trans('firefly.unknown'); // opposing-account-name
+        }
+
+        return $this->row;
     }
 
     /**
@@ -76,10 +70,10 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
     protected function parseABNAMRODescription()
     {
         // See if the current description is formatted in ABN AMRO format
-        if (preg_match('/ABN AMRO.{24} (.*)/', $this->data['description'], $matches)) {
+        if (preg_match('/ABN AMRO.{24} (.*)/', $this->row[7], $matches)) {
 
-            $this->data['opposing-account-name'] = 'ABN AMRO';
-            $this->data['description']           = $matches[1];
+            $this->row[8] = 'ABN AMRO'; // this one is new (opposing account name)
+            $this->row[7] = $matches[1]; // this is the description
 
             return true;
         }
@@ -95,14 +89,14 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
     protected function parseGEABEADescription()
     {
         // See if the current description is formatted in GEA/BEA format
-        if (preg_match('/([BG]EA) +(NR:[a-zA-Z:0-9]+) +([0-9.\/]+) +([^,]*)/', $this->data['description'], $matches)) {
+        if (preg_match('/([BG]EA) +(NR:[a-zA-Z:0-9]+) +([0-9.\/]+) +([^,]*)/', $this->row[7], $matches)) {
 
             // description and opposing account will be the same.
-            $this->data['opposing-account-name'] = $matches[4];
-            $this->data['description']           = $matches[4];
+            $this->row[8] = $matches[4]; // 'opposing-account-name'
+            $this->row[7] = $matches[4]; // 'description'
 
             if ($matches[1] == 'GEA') {
-                $this->data['description'] = 'GEA ' . $matches[4];
+                $this->row[7] = 'GEA ' . $matches[4]; // 'description'
             }
 
             return true;
@@ -119,7 +113,7 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
     protected function parseSepaDescription()
     {
         // See if the current description is formatted as a SEPA plain description
-        if (preg_match('/^SEPA(.{28})/', $this->data['description'], $matches)) {
+        if (preg_match('/^SEPA(.{28})/', $this->row[7], $matches)) {
 
             $type           = $matches[1];
             $reference      = '';
@@ -127,7 +121,7 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
             $newDescription = '';
 
             // SEPA plain descriptions contain several key-value pairs, split by a colon
-            preg_match_all('/([A-Za-z]+(?=:\s)):\s([A-Za-z 0-9._#-]+(?=\s|$))/', $this->data['description'], $matches, PREG_SET_ORDER);
+            preg_match_all('/([A-Za-z]+(?=:\s)):\s([A-Za-z 0-9._#-]+(?=\s|$))/', $this->row[7], $matches, PREG_SET_ORDER);
 
             if (is_array($matches)) {
                 foreach ($matches as $match) {
@@ -138,14 +132,14 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
                             $newDescription = $value;
                             break;
                         case 'NAAM':
-                            $this->data['opposing-account-name'] = $value;
+                            $this->row[8] = $value;
                             $name                                = $value;
                             break;
                         case 'KENMERK':
                             $reference = $value;
                             break;
                         case 'IBAN':
-                            $this->data['opposing-account-iban'] = $value;
+                            $this->row[9] = $value;
                             break;
                         default:
                             // Ignore the rest
@@ -155,9 +149,9 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
 
             // Set a new description for the current transaction. If none was given
             // set the description to type, name and reference
-            $this->data['description'] = $newDescription;
+            $this->row[7] = $newDescription;
             if (strlen($newDescription) === 0) {
-                $this->data['description'] = sprintf('%s - %s (%s)', $type, $name, $reference);
+                $this->row[7] = sprintf('%s - %s (%s)', $type, $name, $reference);
             }
 
             return true;
@@ -174,7 +168,7 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
     protected function parseTRTPDescription()
     {
         // See if the current description is formatted in TRTP format
-        if (preg_match_all('!\/([A-Z]{3,4})\/([^/]*)!', $this->data['description'], $matches, PREG_SET_ORDER)) {
+        if (preg_match_all('!\/([A-Z]{3,4})\/([^/]*)!', $this->row[7], $matches, PREG_SET_ORDER)) {
 
             $type           = '';
             $name           = '';
@@ -190,13 +184,13 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
 
                     switch (strtoupper($key)) {
                         case 'NAME':
-                            $this->data['opposing-account-name'] = $name = $value;
+                            $this->row[8] = $name = $value;
                             break;
                         case 'REMI':
                             $newDescription = $value;
                             break;
                         case 'IBAN':
-                            $this->data['opposing-account-iban'] = $value;
+                            $this->row[9] = $value;
                             break;
                         case 'EREF':
                             $reference = $value;
@@ -211,9 +205,9 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
 
                 // Set a new description for the current transaction. If none was given
                 // set the description to type, name and reference
-                $this->data['description'] = $newDescription;
+                $this->row[7] = $newDescription;
                 if (strlen($newDescription) === 0) {
-                    $this->data['description'] = sprintf('%s - %s (%s)', $type, $name, $reference);
+                    $this->row[7] = sprintf('%s - %s (%s)', $type, $name, $reference);
                 }
             }
 
@@ -223,4 +217,5 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
         return false;
     }
 
+
 }
diff --git a/app/Import/Specifics/RabobankDescription.php b/app/Import/Specifics/RabobankDescription.php
new file mode 100644
index 0000000000..75e074acb9
--- /dev/null
+++ b/app/Import/Specifics/RabobankDescription.php
@@ -0,0 +1,64 @@
+ 'required|exists:users,id',
             'account_type_id' => 'required|exists:account_types,id',
-            'name'            => 'required',
+            'name'            => 'required|between:1,200',
             'active'          => 'required|boolean',
+            'iban'            => 'between:1,50|iban',
         ];
     /** @var  bool */
     private $joinedAccountTypes;
@@ -183,10 +186,14 @@ class Account extends Model
      */
     public function getIbanAttribute($value): string
     {
-        if (is_null($value)) {
+        if (is_null($value) || strlen(strval($value)) === 0) {
             return '';
         }
-        $result = Crypt::decrypt($value);
+        try {
+            $result = Crypt::decrypt($value);
+        } catch (DecryptException $e) {
+            throw new FireflyException('Cannot decrypt value "' . $value . '" for account #' . $this->id);
+        }
         if (is_null($result)) {
             return '';
         }
@@ -295,8 +302,8 @@ class Account extends Model
      */
     public function setNameAttribute($value)
     {
-        $this->attributes['name']      = Crypt::encrypt($value);
-        $this->attributes['encrypted'] = true;
+        $this->attributes['name']      = $value;
+        $this->attributes['encrypted'] = false;
     }
 
     /**
diff --git a/app/Models/AccountType.php b/app/Models/AccountType.php
index 2bb17e3400..88bc502ff6 100644
--- a/app/Models/AccountType.php
+++ b/app/Models/AccountType.php
@@ -21,13 +21,11 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
  * @property \Carbon\Carbon                                          $created_at
  * @property \Carbon\Carbon                                          $updated_at
  * @property string                                                  $type
- * @property boolean                                                 $editable
  * @property-read \Illuminate\Database\Eloquent\Collection|Account[] $accounts
  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereId($value)
  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereCreatedAt($value)
  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereUpdatedAt($value)
  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereType($value)
- * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\AccountType whereEditable($value)
  * @mixin \Eloquent
  */
 class AccountType extends Model
diff --git a/app/Models/Bill.php b/app/Models/Bill.php
index 93888c5e4f..a833cd7c3f 100644
--- a/app/Models/Bill.php
+++ b/app/Models/Bill.php
@@ -17,6 +17,7 @@ use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\Relations\HasMany;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Watson\Validating\ValidatingTrait;
 
 /**
  * FireflyIII\Models\Bill
@@ -58,15 +59,20 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereNameEncrypted($value)
  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereMatchEncrypted($value)
  * @mixin \Eloquent
+ * @property string                                                             $deleted_at
+ * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereDeletedAt($value)
  */
 class Bill extends Model
 {
 
+    use ValidatingTrait;
+
     protected $dates  = ['created_at', 'updated_at', 'date'];
     protected $fillable
                       = ['name', 'match', 'amount_min', 'match_encrypted', 'name_encrypted', 'user_id', 'amount_max', 'date', 'repeat_freq', 'skip',
                          'automatch', 'active',];
     protected $hidden = ['amount_min_encrypted', 'amount_max_encrypted', 'name_encrypted', 'match_encrypted'];
+    protected $rules  = ['name' => 'required|between:1,200',];
 
     /**
      * @param Bill $value
diff --git a/app/Models/Budget.php b/app/Models/Budget.php
index 4b37b4e7da..d33cdad51f 100644
--- a/app/Models/Budget.php
+++ b/app/Models/Budget.php
@@ -17,6 +17,7 @@ use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\SoftDeletes;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Watson\Validating\ValidatingTrait;
 
 /**
  * FireflyIII\Models\Budget
@@ -46,15 +47,17 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Budget whereEncrypted($value)
  * @mixin \Eloquent
  * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Transaction[] $transactions
+ * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\LimitRepetition[] $limitrepetitions
  */
 class Budget extends Model
 {
 
-    use SoftDeletes;
+    use SoftDeletes, ValidatingTrait;
 
     protected $dates    = ['created_at', 'updated_at', 'deleted_at', 'startdate', 'enddate'];
     protected $fillable = ['user_id', 'name', 'active'];
     protected $hidden   = ['encrypted'];
+    protected $rules    = ['name' => 'required|between:1,200',];
 
     /**
      * @param array $fields
diff --git a/app/Models/Category.php b/app/Models/Category.php
index db3a8172f4..d88d627ecb 100644
--- a/app/Models/Category.php
+++ b/app/Models/Category.php
@@ -17,6 +17,7 @@ use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\SoftDeletes;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Watson\Validating\ValidatingTrait;
 
 /**
  * FireflyIII\Models\Category
@@ -46,11 +47,12 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  */
 class Category extends Model
 {
-    use SoftDeletes;
+    use SoftDeletes, ValidatingTrait;
 
     protected $dates    = ['created_at', 'updated_at', 'deleted_at'];
     protected $fillable = ['user_id', 'name'];
     protected $hidden   = ['encrypted'];
+    protected $rules    = ['name' => 'required|between:1,200',];
 
     /**
      * @param array $fields
diff --git a/app/Models/Configuration.php b/app/Models/Configuration.php
new file mode 100644
index 0000000000..93de3d0602
--- /dev/null
+++ b/app/Models/Configuration.php
@@ -0,0 +1,62 @@
+attributes['data'] = json_encode($value);
+    }
+
+
+
+}
diff --git a/app/Models/ImportJob.php b/app/Models/ImportJob.php
new file mode 100644
index 0000000000..3b106bbbb2
--- /dev/null
+++ b/app/Models/ImportJob.php
@@ -0,0 +1,114 @@
+where('user_id', Auth::user()->id)->first();
+            if (!is_null($model)) {
+                return $model;
+            }
+        }
+        throw new NotFoundHttpException;
+    }
+
+    /**
+     * @param $status
+     */
+    public function change($status)
+    {
+        $this->status = $status;
+        $this->save();
+    }
+
+    /**
+     * @param $value
+     *
+     * @return mixed
+     */
+    public function getConfigurationAttribute($value)
+    {
+        if (strlen($value) == 0) {
+            return [];
+        }
+
+        return json_decode($value, true);
+    }
+
+    /**
+     * @param $value
+     */
+    public function setConfigurationAttribute($value)
+    {
+        $this->attributes['configuration'] = json_encode($value);
+    }
+
+    /**
+     * @return string
+     */
+    public function uploadFileContents(): string
+    {
+        $fileName         = $this->key . '.upload';
+        $disk             = Storage::disk('upload');
+        $encryptedContent = $disk->get($fileName);
+        $content          = Crypt::decrypt($encryptedContent);
+
+        return $content;
+    }
+
+    /**
+     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+     */
+    public function user()
+    {
+        return $this->belongsTo('FireflyIII\User');
+    }
+}
diff --git a/app/Models/PiggyBank.php b/app/Models/PiggyBank.php
index 78749a8e5e..355d4a135c 100644
--- a/app/Models/PiggyBank.php
+++ b/app/Models/PiggyBank.php
@@ -31,8 +31,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  * @property \Carbon\Carbon                                                      $targetdate
  * @property integer                                                             $order
  * @property boolean                                                             $encrypted
- * @property boolean                                                             $remind_me
- * @property integer                                                             $reminder_skip
  * @property-read Account                                                        $account
  * @property-read \Illuminate\Database\Eloquent\Collection|PiggyBankRepetition[] $piggyBankRepetitions
  * @property-read \Illuminate\Database\Eloquent\Collection|PiggyBankEvent[]      $piggyBankEvents
@@ -53,13 +51,15 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereDeletedAt($value)
  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereEncrypted($value)
  * @mixin \Eloquent
+ * @property boolean $active
+ * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereActive($value)
  */
 class PiggyBank extends Model
 {
     use SoftDeletes;
 
     protected $fillable
-                      = ['name', 'account_id', 'order', 'targetamount', 'startdate', 'targetdate', 'remind_me', 'reminder_skip'];
+                      = ['name', 'account_id', 'order', 'targetamount', 'startdate', 'targetdate'];
     protected $hidden = ['targetamount_encrypted', 'encrypted'];
     protected $dates  = ['created_at', 'updated_at', 'deleted_at', 'startdate', 'targetdate'];
 
diff --git a/app/Models/Preference.php b/app/Models/Preference.php
index 33d7e22c33..15ddef16e6 100644
--- a/app/Models/Preference.php
+++ b/app/Models/Preference.php
@@ -12,8 +12,10 @@ declare(strict_types = 1);
 namespace FireflyIII\Models;
 
 use Crypt;
+use FireflyIII\Exceptions\FireflyException;
+use Illuminate\Contracts\Encryption\DecryptException;
 use Illuminate\Database\Eloquent\Model;
-
+use Log;
 /**
  * FireflyIII\Models\Preference
  *
@@ -24,7 +26,6 @@ use Illuminate\Database\Eloquent\Model;
  * @property string                $name
  * @property string                $name_encrypted
  * @property string                $data
- * @property string                $data_encrypted
  * @property-read \FireflyIII\User $user
  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Preference whereId($value)
  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Preference whereCreatedAt($value)
@@ -41,19 +42,21 @@ class Preference extends Model
 
     protected $dates    = ['created_at', 'updated_at'];
     protected $fillable = ['user_id', 'data', 'name'];
-    protected $hidden   = ['data_encrypted', 'name_encrypted'];
 
     /**
      * @param $value
      *
      * @return mixed
+     * @throws FireflyException
      */
     public function getDataAttribute($value)
     {
-        if (is_null($this->data_encrypted)) {
-            return json_decode($value);
+        try {
+            $data = Crypt::decrypt($value);
+        } catch (DecryptException $e) {
+            Log::error('Could not decrypt preference.', ['id' => $this->id,'name' => $this->name,'data' => $this->data]);
+            throw new FireflyException('Could not decrypt preference #' . $this->id . '.');
         }
-        $data = Crypt::decrypt($this->data_encrypted);
 
         return json_decode($data);
     }
@@ -63,8 +66,7 @@ class Preference extends Model
      */
     public function setDataAttribute($value)
     {
-        $this->attributes['data']           = '';
-        $this->attributes['data_encrypted'] = Crypt::encrypt(json_encode($value));
+        $this->attributes['data'] = Crypt::encrypt(json_encode($value));
     }
 
     /**
diff --git a/app/Models/Tag.php b/app/Models/Tag.php
index bfa9e17dee..2c5ddab13c 100644
--- a/app/Models/Tag.php
+++ b/app/Models/Tag.php
@@ -15,6 +15,7 @@ use Auth;
 use Crypt;
 use FireflyIII\Support\Models\TagSupport;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Watson\Validating\ValidatingTrait;
 
 /**
  * FireflyIII\Models\Tag
@@ -52,6 +53,9 @@ class Tag extends TagSupport
 {
     protected $dates    = ['created_at', 'updated_at', 'date'];
     protected $fillable = ['user_id', 'tag', 'date', 'description', 'longitude', 'latitude', 'zoomLevel', 'tagMode'];
+    protected $rules    = ['tag' => 'required|between:1,200',];
+
+    use ValidatingTrait;
 
     /**
      * @param array $fields
diff --git a/app/Models/TransactionCurrency.php b/app/Models/TransactionCurrency.php
index 69d33955b6..84208e2a22 100644
--- a/app/Models/TransactionCurrency.php
+++ b/app/Models/TransactionCurrency.php
@@ -15,6 +15,7 @@ use Auth;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\SoftDeletes;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Watson\Validating\ValidatingTrait;
 
 /**
  * FireflyIII\Models\TransactionCurrency
@@ -38,19 +39,12 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  */
 class TransactionCurrency extends Model
 {
-    use SoftDeletes;
+    use SoftDeletes, ValidatingTrait;
 
 
-    protected $fillable = ['name', 'code', 'symbol'];
     protected $dates    = ['created_at', 'updated_at', 'deleted_at'];
-
-    /**
-     * @return \Illuminate\Database\Eloquent\Relations\HasMany
-     */
-    public function transactionJournals()
-    {
-        return $this->hasMany('FireflyIII\Models\TransactionJournal');
-    }
+    protected $fillable = ['name', 'code', 'symbol'];
+    protected $rules    = ['name' => 'required|between:1,200', 'code' => 'required|between:3,3', 'symbol' => 'required|between:1,12'];
 
     /**
      * @param TransactionCurrency $currency
@@ -64,4 +58,12 @@ class TransactionCurrency extends Model
         }
         throw new NotFoundHttpException;
     }
+
+    /**
+     * @return \Illuminate\Database\Eloquent\Relations\HasMany
+     */
+    public function transactionJournals()
+    {
+        return $this->hasMany('FireflyIII\Models\TransactionJournal');
+    }
 }
diff --git a/app/Providers/AccountServiceProvider.php b/app/Providers/AccountServiceProvider.php
index 4ac1f3bab1..a41f4890bd 100644
--- a/app/Providers/AccountServiceProvider.php
+++ b/app/Providers/AccountServiceProvider.php
@@ -44,7 +44,7 @@ class AccountServiceProvider extends ServiceProvider
             'FireflyIII\Repositories\Account\AccountRepositoryInterface',
             function (Application $app, array $arguments) {
                 if (!isset($arguments[0]) && $app->auth->check()) {
-                    return app('FireflyIII\Repositories\Account\AccountRepository', [$app->auth->user()]);
+                    return app('FireflyIII\Repositories\Account\AccountRepository', [auth()->user()]);
                 }
                 if (!isset($arguments[0]) && !$app->auth->check()) {
                     throw new FireflyException('There is no user present.');
diff --git a/app/Providers/AttachmentServiceProvider.php b/app/Providers/AttachmentServiceProvider.php
index bee83cf88c..0cd70ecc90 100644
--- a/app/Providers/AttachmentServiceProvider.php
+++ b/app/Providers/AttachmentServiceProvider.php
@@ -44,7 +44,7 @@ class AttachmentServiceProvider extends ServiceProvider
             'FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface',
             function (Application $app, array $arguments) {
                 if (!isset($arguments[0]) && $app->auth->check()) {
-                    return app('FireflyIII\Repositories\Attachment\AttachmentRepository', [$app->auth->user()]);
+                    return app('FireflyIII\Repositories\Attachment\AttachmentRepository', [auth()->user()]);
                 }
                 if (!isset($arguments[0]) && !$app->auth->check()) {
                     throw new FireflyException('There is no user present.');
diff --git a/app/Providers/BillServiceProvider.php b/app/Providers/BillServiceProvider.php
index 289d712094..20bdd0f6bc 100644
--- a/app/Providers/BillServiceProvider.php
+++ b/app/Providers/BillServiceProvider.php
@@ -44,7 +44,7 @@ class BillServiceProvider extends ServiceProvider
             'FireflyIII\Repositories\Bill\BillRepositoryInterface',
             function (Application $app, array $arguments) {
                 if (!isset($arguments[0]) && $app->auth->check()) {
-                    return app('FireflyIII\Repositories\Bill\BillRepository', [$app->auth->user()]);
+                    return app('FireflyIII\Repositories\Bill\BillRepository', [auth()->user()]);
                 }
                 if (!isset($arguments[0]) && !$app->auth->check()) {
                     throw new FireflyException('There is no user present.');
diff --git a/app/Providers/BudgetServiceProvider.php b/app/Providers/BudgetServiceProvider.php
index afd73a846b..aa7f6687f3 100644
--- a/app/Providers/BudgetServiceProvider.php
+++ b/app/Providers/BudgetServiceProvider.php
@@ -44,7 +44,7 @@ class BudgetServiceProvider extends ServiceProvider
             'FireflyIII\Repositories\Budget\BudgetRepositoryInterface',
             function (Application $app, array $arguments) {
                 if (!isset($arguments[0]) && $app->auth->check()) {
-                    return app('FireflyIII\Repositories\Budget\BudgetRepository', [$app->auth->user()]);
+                    return app('FireflyIII\Repositories\Budget\BudgetRepository', [auth()->user()]);
                 }
                 if (!isset($arguments[0]) && !$app->auth->check()) {
                     throw new FireflyException('There is no user present.');
diff --git a/app/Providers/CategoryServiceProvider.php b/app/Providers/CategoryServiceProvider.php
index 5adab5c229..fbea960b60 100644
--- a/app/Providers/CategoryServiceProvider.php
+++ b/app/Providers/CategoryServiceProvider.php
@@ -44,7 +44,7 @@ class CategoryServiceProvider extends ServiceProvider
             'FireflyIII\Repositories\Category\CategoryRepositoryInterface',
             function (Application $app, array $arguments) {
                 if (!isset($arguments[0]) && $app->auth->check()) {
-                    return app('FireflyIII\Repositories\Category\CategoryRepository', [$app->auth->user()]);
+                    return app('FireflyIII\Repositories\Category\CategoryRepository', [auth()->user()]);
                 }
                 if (!isset($arguments[0]) && !$app->auth->check()) {
                     throw new FireflyException('There is no user present.');
diff --git a/app/Providers/CrudServiceProvider.php b/app/Providers/CrudServiceProvider.php
index 0117cf78a5..1eeacfa735 100644
--- a/app/Providers/CrudServiceProvider.php
+++ b/app/Providers/CrudServiceProvider.php
@@ -12,8 +12,10 @@ declare(strict_types = 1);
 namespace FireflyIII\Providers;
 
 use FireflyIII\Exceptions\FireflyException;
+use Illuminate\Auth\AuthManager;
 use Illuminate\Foundation\Application;
 use Illuminate\Support\ServiceProvider;
+use Log;
 
 /**
  * Class CrudServiceProvider
@@ -49,13 +51,13 @@ class CrudServiceProvider extends ServiceProvider
         $this->app->bind(
             'FireflyIII\Crud\Account\AccountCrudInterface',
             function (Application $app, array $arguments) {
-                if (!isset($arguments[0]) && $app->auth->check()) {
-                    return app('FireflyIII\Crud\Account\AccountCrud', [$app->auth->user()]);
+
+                if (!isset($arguments[0]) && auth()->check()) {
+                    return app('FireflyIII\Crud\Account\AccountCrud', [auth()->user()]);
                 }
                 if (!isset($arguments[0]) && !$app->auth->check()) {
                     throw new FireflyException('There is no user present.');
                 }
-
                 return app('FireflyIII\Crud\Account\AccountCrud', $arguments);
             }
         );
@@ -67,7 +69,7 @@ class CrudServiceProvider extends ServiceProvider
             'FireflyIII\Crud\Split\JournalInterface',
             function (Application $app, array $arguments) {
                 if (!isset($arguments[0]) && $app->auth->check()) {
-                    return app('FireflyIII\Crud\Split\Journal', [$app->auth->user()]);
+                    return app('FireflyIII\Crud\Split\Journal', [auth()->user()]);
                 }
                 if (!isset($arguments[0]) && !$app->auth->check()) {
                     throw new FireflyException('There is no user present.');
diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php
index 2b91f62b09..2758e7f0b6 100644
--- a/app/Providers/EventServiceProvider.php
+++ b/app/Providers/EventServiceProvider.php
@@ -15,8 +15,10 @@ use FireflyIII\Models\Account;
 use FireflyIII\Models\PiggyBank;
 use FireflyIII\Models\PiggyBankRepetition;
 use FireflyIII\Models\Transaction;
+use FireflyIII\Models\TransactionJournal;
 use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
 use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
+use Log;
 
 /**
  * Class EventServiceProvider
@@ -60,6 +62,10 @@ class EventServiceProvider extends ServiceProvider
                 'FireflyIII\Handlers\Events\SendRegistrationMail',
                 'FireflyIII\Handlers\Events\AttachUserRole',
                 'FireflyIII\Handlers\Events\UserConfirmation@sendConfirmation',
+                'FireflyIII\Handlers\Events\UserSaveIpAddress@saveFromRegistration',
+            ],
+            'FireflyIII\Events\UserIsConfirmed'          => [
+                'FireflyIII\Handlers\Events\UserSaveIpAddress@saveFromConfirmation',
             ],
             'FireflyIII\Events\ResendConfirmation'       => [
                 'FireflyIII\Handlers\Events\UserConfirmation@resendConfirmation',
@@ -107,11 +113,27 @@ class EventServiceProvider extends ServiceProvider
     {
         Account::deleted(
             function (Account $account) {
-
+                Log::debug('Now trigger account delete response #' . $account->id);
                 /** @var Transaction $transaction */
                 foreach ($account->transactions()->get() as $transaction) {
+                    Log::debug('Now at transaction #' . $transaction->id);
                     $journal = $transaction->transactionJournal()->first();
-                    $journal->delete();
+                    if (!is_null($journal)) {
+                        Log::debug('Call for deletion of journal #' . $journal->id);
+                        $journal->delete();
+                    }
+                }
+            }
+        );
+
+        TransactionJournal::deleted(
+            function (TransactionJournal $journal) {
+                Log::debug('Now triggered journal delete response #' . $journal->id);
+
+                /** @var Transaction $transaction */
+                foreach ($journal->transactions()->get() as $transaction) {
+                    Log::debug('Will now delete transaction #' . $transaction->id);
+                    $transaction->delete();
                 }
             }
         );
diff --git a/app/Providers/ExportJobServiceProvider.php b/app/Providers/ExportJobServiceProvider.php
index 380b14a2e9..cd908bc969 100644
--- a/app/Providers/ExportJobServiceProvider.php
+++ b/app/Providers/ExportJobServiceProvider.php
@@ -31,19 +31,9 @@ class ExportJobServiceProvider extends ServiceProvider
      */
     public function boot()
     {
-        $this->app->bind(
-            'FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface',
-            function (Application $app, array $arguments) {
-                if (!isset($arguments[0]) && $app->auth->check()) {
-                    return app('FireflyIII\Repositories\ExportJob\ExportJobRepository', [$app->auth->user()]);
-                }
-                if (!isset($arguments[0]) && !$app->auth->check()) {
-                    throw new FireflyException('There is no user present.');
-                }
+        $this->exportJob();
+        $this->importJob();
 
-                return app('FireflyIII\Repositories\ExportJob\ExportJobRepository', $arguments);
-            }
-        );
     }
 
     /**
@@ -55,4 +45,42 @@ class ExportJobServiceProvider extends ServiceProvider
     {
         //
     }
+
+    /**
+     *
+     */
+    private function exportJob()
+    {
+
+        $this->app->bind(
+            'FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface',
+            function (Application $app, array $arguments) {
+                if (!isset($arguments[0]) && $app->auth->check()) {
+                    return app('FireflyIII\Repositories\ExportJob\ExportJobRepository', [auth()->user()]);
+                }
+                if (!isset($arguments[0]) && !$app->auth->check()) {
+                    throw new FireflyException('There is no user present.');
+                }
+
+                return app('FireflyIII\Repositories\ExportJob\ExportJobRepository', $arguments);
+            }
+        );
+    }
+
+    private function importJob()
+    {
+        $this->app->bind(
+            'FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface',
+            function (Application $app, array $arguments) {
+                if (!isset($arguments[0]) && $app->auth->check()) {
+                    return app('FireflyIII\Repositories\ImportJob\ImportJobRepository', [auth()->user()]);
+                }
+                if (!isset($arguments[0]) && !$app->auth->check()) {
+                    throw new FireflyException('There is no user present.');
+                }
+
+                return app('FireflyIII\Repositories\ImportJob\ImportJobRepository', $arguments);
+            }
+        );
+    }
 }
diff --git a/app/Providers/FireflyServiceProvider.php b/app/Providers/FireflyServiceProvider.php
index 47ad19c301..8380895404 100644
--- a/app/Providers/FireflyServiceProvider.php
+++ b/app/Providers/FireflyServiceProvider.php
@@ -13,6 +13,7 @@ namespace FireflyIII\Providers;
 
 use FireflyIII\Support\Amount;
 use FireflyIII\Support\ExpandedForm;
+use FireflyIII\Support\FireflyConfig;
 use FireflyIII\Support\Navigation;
 use FireflyIII\Support\Preferences;
 use FireflyIII\Support\Steam;
@@ -62,6 +63,12 @@ class FireflyServiceProvider extends ServiceProvider
             return new Preferences;
         }
         );
+
+        $this->app->bind(
+            'fireflyconfig', function () {
+            return new FireflyConfig;
+        }
+        );
         $this->app->bind(
             'navigation', function () {
             return new Navigation;
@@ -87,7 +94,6 @@ class FireflyServiceProvider extends ServiceProvider
         $this->app->bind('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface', 'FireflyIII\Repositories\Currency\CurrencyRepository');
         $this->app->bind('FireflyIII\Support\Search\SearchInterface', 'FireflyIII\Support\Search\Search');
         $this->app->bind('FireflyIII\Repositories\User\UserRepositoryInterface', 'FireflyIII\Repositories\User\UserRepository');
-        $this->app->bind('FireflyIII\Helpers\Csv\WizardInterface', 'FireflyIII\Helpers\Csv\Wizard');
         $this->app->bind('FireflyIII\Helpers\Attachments\AttachmentHelperInterface', 'FireflyIII\Helpers\Attachments\AttachmentHelper');
         $this->app->bind(
             'FireflyIII\Generator\Chart\Account\AccountChartGeneratorInterface', 'FireflyIII\Generator\Chart\Account\ChartJsAccountChartGenerator'
diff --git a/app/Providers/JournalServiceProvider.php b/app/Providers/JournalServiceProvider.php
index db50c23499..4e82de187e 100644
--- a/app/Providers/JournalServiceProvider.php
+++ b/app/Providers/JournalServiceProvider.php
@@ -44,7 +44,7 @@ class JournalServiceProvider extends ServiceProvider
             'FireflyIII\Repositories\Journal\JournalRepositoryInterface',
             function (Application $app, array $arguments) {
                 if (!isset($arguments[0]) && $app->auth->check()) {
-                    return app('FireflyIII\Repositories\Journal\JournalRepository', [$app->auth->user()]);
+                    return app('FireflyIII\Repositories\Journal\JournalRepository', [auth()->user()]);
                 }
                 if (!isset($arguments[0]) && !$app->auth->check()) {
                     throw new FireflyException('There is no user present.');
diff --git a/app/Providers/PiggyBankServiceProvider.php b/app/Providers/PiggyBankServiceProvider.php
index 14aa3353af..d662698511 100644
--- a/app/Providers/PiggyBankServiceProvider.php
+++ b/app/Providers/PiggyBankServiceProvider.php
@@ -45,7 +45,7 @@ class PiggyBankServiceProvider extends ServiceProvider
             'FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface',
             function (Application $app, array $arguments) {
                 if (!isset($arguments[0]) && $app->auth->check()) {
-                    return app('FireflyIII\Repositories\PiggyBank\PiggyBankRepository', [$app->auth->user()]);
+                    return app('FireflyIII\Repositories\PiggyBank\PiggyBankRepository', [auth()->user()]);
                 }
                 if (!isset($arguments[0]) && !$app->auth->check()) {
                     throw new FireflyException('There is no user present.');
diff --git a/app/Providers/RuleGroupServiceProvider.php b/app/Providers/RuleGroupServiceProvider.php
index 7536006145..4cff99454f 100644
--- a/app/Providers/RuleGroupServiceProvider.php
+++ b/app/Providers/RuleGroupServiceProvider.php
@@ -45,7 +45,7 @@ class RuleGroupServiceProvider extends ServiceProvider
             'FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface',
             function (Application $app, array $arguments) {
                 if (!isset($arguments[0]) && $app->auth->check()) {
-                    return app('FireflyIII\Repositories\RuleGroup\RuleGroupRepository', [$app->auth->user()]);
+                    return app('FireflyIII\Repositories\RuleGroup\RuleGroupRepository', [auth()->user()]);
                 }
                 if (!isset($arguments[0]) && !$app->auth->check()) {
                     throw new FireflyException('There is no user present.');
diff --git a/app/Providers/RuleServiceProvider.php b/app/Providers/RuleServiceProvider.php
index 2a416fcea0..14d3163a53 100644
--- a/app/Providers/RuleServiceProvider.php
+++ b/app/Providers/RuleServiceProvider.php
@@ -44,7 +44,7 @@ class RuleServiceProvider extends ServiceProvider
             'FireflyIII\Repositories\Rule\RuleRepositoryInterface',
             function (Application $app, array $arguments) {
                 if (!isset($arguments[0]) && $app->auth->check()) {
-                    return app('FireflyIII\Repositories\Rule\RuleRepository', [$app->auth->user()]);
+                    return app('FireflyIII\Repositories\Rule\RuleRepository', [auth()->user()]);
                 }
                 if (!isset($arguments[0]) && !$app->auth->check()) {
                     throw new FireflyException('There is no user present.');
diff --git a/app/Providers/TagServiceProvider.php b/app/Providers/TagServiceProvider.php
index 51e4a16e45..34ef48591a 100644
--- a/app/Providers/TagServiceProvider.php
+++ b/app/Providers/TagServiceProvider.php
@@ -44,7 +44,7 @@ class TagServiceProvider extends ServiceProvider
             'FireflyIII\Repositories\Tag\TagRepositoryInterface',
             function (Application $app, array $arguments) {
                 if (!isset($arguments[0]) && $app->auth->check()) {
-                    return app('FireflyIII\Repositories\Tag\TagRepository', [$app->auth->user()]);
+                    return app('FireflyIII\Repositories\Tag\TagRepository', [auth()->user()]);
                 }
                 if (!isset($arguments[0]) && !$app->auth->check()) {
                     throw new FireflyException('There is no user present.');
diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php
index ef95442a73..b57c93f0f0 100644
--- a/app/Repositories/Account/AccountRepository.php
+++ b/app/Repositories/Account/AccountRepository.php
@@ -135,15 +135,24 @@ class AccountRepository implements AccountRepositoryInterface
 
             $query->whereIn('destination.account_id', $accountIds);
             $query->whereNotIn('source.account_id', $accountIds);
+            $query->whereNull('destination.deleted_at');
+            $query->whereNull('source.deleted_at');
 
         }
         // remove group by
         $query->getQuery()->getQuery()->groups = null;
+        $ids                                   = $query->get(['transaction_journals.id'])->pluck('id')->toArray();
+
+
 
         // that should do it:
-        $sum = strval($query->sum('destination.amount'));
+        $sum = $this->user->transactions()
+                          ->whereIn('transaction_journal_id', $ids)
+                          ->where('amount', '>', '0')
+                          ->whereNull('transactions.deleted_at')
+                          ->sum('amount');
 
-        return $sum;
+        return strval($sum);
 
     }
 
@@ -566,6 +575,7 @@ class AccountRepository implements AccountRepositoryInterface
                 $join->on('source.transaction_journal_id', '=', 'transaction_journals.id')->where('source.amount', '<', 0);
             }
             );
+
             $query->leftJoin(
                 'transactions as destination', function (JoinClause $join) {
                 $join->on('destination.transaction_journal_id', '=', 'transaction_journals.id')->where('destination.amount', '>', 0);
@@ -573,15 +583,22 @@ class AccountRepository implements AccountRepositoryInterface
             );
             $query->whereIn('source.account_id', $accountIds);
             $query->whereNotIn('destination.account_id', $accountIds);
+            $query->whereNull('source.deleted_at');
+            $query->whereNull('destination.deleted_at');
+            $query->distinct();
 
         }
         // remove group by
         $query->getQuery()->getQuery()->groups = null;
+        $ids                                   = $query->get(['transaction_journals.id'])->pluck('id')->toArray();
 
-        // that should do it:
-        $sum = strval($query->sum('source.amount'));
+        $sum = $this->user->transactions()
+                          ->whereIn('transaction_journal_id', $ids)
+                          ->where('amount', '<', '0')
+                          ->whereNull('transactions.deleted_at')
+                          ->sum('amount');
 
-        return $sum;
+        return strval($sum);
     }
 
 }
diff --git a/app/Repositories/Bill/BillRepository.php b/app/Repositories/Bill/BillRepository.php
index 7a6c99375d..51e0d4301a 100644
--- a/app/Repositories/Bill/BillRepository.php
+++ b/app/Repositories/Bill/BillRepository.php
@@ -72,6 +72,27 @@ class BillRepository implements BillRepositoryInterface
         return $bill;
     }
 
+    /**
+     * Find a bill by name.
+     *
+     * @param string $name
+     *
+     * @return Bill
+     */
+    public function findByName(string $name) : Bill
+    {
+        $bills = $this->user->bills()->get(['bills.*']);
+
+        /** @var Bill $bill */
+        foreach ($bills as $bill) {
+            if ($bill->name === $name) {
+                return $bill;
+            }
+        }
+
+        return new Bill;
+    }
+
     /**
      * @return Collection
      */
@@ -293,6 +314,28 @@ class BillRepository implements BillRepositoryInterface
         return $bill->transactionjournals()->before($end)->after($start)->get();
     }
 
+    /**
+     * @param $bill
+     *
+     * @return string
+     */
+    public function getOverallAverage($bill): string
+    {
+        $journals = $bill->transactionjournals()->get();
+        $sum      = '0';
+        $count    = strval($journals->count());
+        /** @var TransactionJournal $journal */
+        foreach ($journals as $journal) {
+            $sum = bcadd($sum, TransactionJournal::amountPositive($journal));
+        }
+        $avg = '0';
+        if ($journals->count() > 0) {
+            $avg = bcdiv($sum, $count);
+        }
+
+        return $avg;
+    }
+
     /**
      * @param Bill $bill
      *
@@ -358,6 +401,32 @@ class BillRepository implements BillRepositoryInterface
         return $validRanges;
     }
 
+    /**
+     * @param Bill   $bill
+     * @param Carbon $date
+     *
+     * @return string
+     */
+    public function getYearAverage(Bill $bill, Carbon $date): string
+    {
+        $journals = $bill->transactionjournals()
+                         ->where('date', '>=', $date->year . '-01-01')
+                         ->where('date', '<=', $date->year . '-12-31')
+                         ->get();
+        $sum      = '0';
+        $count    = strval($journals->count());
+        /** @var TransactionJournal $journal */
+        foreach ($journals as $journal) {
+            $sum = bcadd($sum, TransactionJournal::amountPositive($journal));
+        }
+        $avg = '0';
+        if ($journals->count() > 0) {
+            $avg = bcdiv($sum, $count);
+        }
+
+        return $avg;
+    }
+
     /**
      * @param Bill $bill
      *
diff --git a/app/Repositories/Bill/BillRepositoryInterface.php b/app/Repositories/Bill/BillRepositoryInterface.php
index 3305e26d68..ff28c7b521 100644
--- a/app/Repositories/Bill/BillRepositoryInterface.php
+++ b/app/Repositories/Bill/BillRepositoryInterface.php
@@ -41,6 +41,15 @@ interface BillRepositoryInterface
      */
     public function find(int $billId) : Bill;
 
+    /**
+     * Find a bill by name.
+     *
+     * @param string $name
+     *
+     * @return Bill
+     */
+    public function findByName(string $name) : Bill;
+
     /**
      * @return Collection
      */
@@ -113,6 +122,13 @@ interface BillRepositoryInterface
      */
     public function getJournalsInRange(Bill $bill, Carbon $start, Carbon $end): Collection;
 
+    /**
+     * @param $bill
+     *
+     * @return string
+     */
+    public function getOverallAverage($bill): string;
+
     /**
      * @param Bill $bill
      *
@@ -133,6 +149,14 @@ interface BillRepositoryInterface
      */
     public function getRanges(Bill $bill, Carbon $start, Carbon $end): array;
 
+    /**
+     * @param Bill   $bill
+     * @param Carbon $date
+     *
+     * @return string
+     */
+    public function getYearAverage(Bill $bill, Carbon $date): string;
+
     /**
      * @param Bill $bill
      *
diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php
index 04d63893a5..88bb56912a 100644
--- a/app/Repositories/Budget/BudgetRepository.php
+++ b/app/Repositories/Budget/BudgetRepository.php
@@ -44,6 +44,18 @@ class BudgetRepository implements BudgetRepositoryInterface
         $this->user = $user;
     }
 
+    /**
+     * @return bool
+     */
+    public function cleanupBudgets(): bool
+    {
+        // delete limits with amount 0:
+        BudgetLimit::where('amount', 0)->delete();
+
+        return true;
+
+    }
+
     /**
      * @param Budget $budget
      *
@@ -73,6 +85,26 @@ class BudgetRepository implements BudgetRepositoryInterface
         return $budget;
     }
 
+    /**
+     * Find a budget.
+     *
+     * @param string $name
+     *
+     * @return Budget
+     */
+    public function findByName(string $name): Budget
+    {
+        $budgets = $this->user->budgets()->get(['budgets.*']);
+        /** @var Budget $budget */
+        foreach ($budgets as $budget) {
+            if ($budget->name === $name) {
+                return $budget;
+            }
+        }
+
+        return new Budget;
+    }
+
     /**
      * This method returns the oldest journal or transaction date known to this budget.
      * Will cache result.
@@ -322,6 +354,9 @@ class BudgetRepository implements BudgetRepositoryInterface
                 $join->on('destination.transaction_journal_id', '=', 'transaction_journals.id')->where('destination.amount', '>', 0);
             }
             );
+        $query->whereNull('source.deleted_at');
+        $query->whereNull('destination.deleted_at');
+        $query->where('transaction_journals.completed', 1);
 
         if ($end >= $start) {
             $query->before($end)->after($start);
@@ -330,16 +365,27 @@ class BudgetRepository implements BudgetRepositoryInterface
             $accountIds = $accounts->pluck('id')->toArray();
             $set        = join(', ', $accountIds);
             $query->whereRaw('(source.account_id in (' . $set . ') XOR destination.account_id in (' . $set . '))');
+
         }
         if ($budgets->count() > 0) {
             $budgetIds = $budgets->pluck('id')->toArray();
             $query->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
             $query->whereIn('budget_transaction_journal.budget_id', $budgetIds);
+
         }
 
         // that should do it:
-        $first = strval($query->sum('source.amount'));
-
+        $ids   = $query->distinct()->get(['transaction_journals.id'])->pluck('id')->toArray();
+        $first = '0';
+        if (count($ids) > 0) {
+            $first = strval(
+                $this->user->transactions()
+                           ->whereIn('transaction_journal_id', $ids)
+                           ->where('amount', '<', '0')
+                           ->whereNull('transactions.deleted_at')
+                           ->sum('amount')
+            );
+        }
         // then collection transactions (harder)
         $query = $this->user->transactions()
                             ->where('transactions.amount', '<', 0)
@@ -387,7 +433,10 @@ class BudgetRepository implements BudgetRepositoryInterface
                             ->whereNull('budget_transaction_journal.id')
                             ->whereNull('budget_transaction.id')
                             ->before($end)
-                            ->after($start);
+                            ->after($start)
+                            ->whereNull('source.deleted_at')
+                            ->whereNull('destination.deleted_at')
+                            ->where('transaction_journals.completed', 1);
 
         if ($accounts->count() > 0) {
             $accountIds = $accounts->pluck('id')->toArray();
@@ -395,7 +444,17 @@ class BudgetRepository implements BudgetRepositoryInterface
             $set = join(', ', $accountIds);
             $query->whereRaw('(source.account_id in (' . $set . ') XOR destination.account_id in (' . $set . '))');
         }
-        $sum = strval($query->sum('source.amount'));
+        $ids = $query->get(['transaction_journals.id'])->pluck('id')->toArray();
+        $sum = '0';
+        if (count($ids) > 0) {
+            $sum = strval(
+                $this->user->transactions()
+                           ->whereIn('transaction_journal_id', $ids)
+                           ->where('amount', '<', '0')
+                           ->whereNull('transactions.deleted_at')
+                           ->sum('amount')
+            );
+        }
 
         return $sum;
     }
@@ -486,5 +545,4 @@ class BudgetRepository implements BudgetRepositoryInterface
 
         return $limit;
     }
-
 }
diff --git a/app/Repositories/Budget/BudgetRepositoryInterface.php b/app/Repositories/Budget/BudgetRepositoryInterface.php
index 6feeb5336c..ae5a07f3fc 100644
--- a/app/Repositories/Budget/BudgetRepositoryInterface.php
+++ b/app/Repositories/Budget/BudgetRepositoryInterface.php
@@ -24,6 +24,11 @@ use Illuminate\Support\Collection;
 interface BudgetRepositoryInterface
 {
 
+    /**
+     * @return bool
+     */
+    public function cleanupBudgets(): bool;
+
     /**
      * @param Budget $budget
      *
@@ -40,6 +45,15 @@ interface BudgetRepositoryInterface
      */
     public function find(int $budgetId): Budget;
 
+    /**
+     * Find a budget.
+     *
+     * @param string $name
+     *
+     * @return Budget
+     */
+    public function findByName(string $name): Budget;
+
     /**
      * This method returns the oldest journal or transaction date known to this budget.
      * Will cache result.
@@ -92,15 +106,6 @@ interface BudgetRepositoryInterface
      */
     public function journalsInPeriodWithoutBudget(Collection $accounts, Carbon $start, Carbon $end): Collection;
 
-    /**
-     * @param Collection $accounts
-     * @param Carbon     $start
-     * @param Carbon     $end
-     *
-     * @return string
-     */
-    public function spentInPeriodWithoutBudget(Collection $accounts, Carbon $start, Carbon $end): string;
-
     /**
      * @param Collection $budgets
      * @param Collection $accounts
@@ -111,6 +116,15 @@ interface BudgetRepositoryInterface
      */
     public function spentInPeriod(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end) : string;
 
+    /**
+     * @param Collection $accounts
+     * @param Carbon     $start
+     * @param Carbon     $end
+     *
+     * @return string
+     */
+    public function spentInPeriodWithoutBudget(Collection $accounts, Carbon $start, Carbon $end): string;
+
     /**
      * @param array $data
      *
diff --git a/app/Repositories/Category/CategoryRepository.php b/app/Repositories/Category/CategoryRepository.php
index 4287eb429c..e0a662b355 100644
--- a/app/Repositories/Category/CategoryRepository.php
+++ b/app/Repositories/Category/CategoryRepository.php
@@ -101,6 +101,25 @@ class CategoryRepository implements CategoryRepositoryInterface
         return $category;
     }
 
+    /**
+     * Find a category
+     *
+     * @param string $name
+     *
+     * @return Category
+     */
+    public function findByName(string $name) : Category
+    {
+        $categories = $this->user->categories()->get(['categories.*']);
+        foreach ($categories as $category) {
+            if ($category->name === $name) {
+                return $category;
+            }
+        }
+
+        return new Category;
+    }
+
     /**
      * @param Category   $category
      * @param Collection $accounts
@@ -554,4 +573,5 @@ class CategoryRepository implements CategoryRepositoryInterface
         return $sum;
 
     }
+
 }
diff --git a/app/Repositories/Category/CategoryRepositoryInterface.php b/app/Repositories/Category/CategoryRepositoryInterface.php
index 3df5717ab9..cb6d757e32 100644
--- a/app/Repositories/Category/CategoryRepositoryInterface.php
+++ b/app/Repositories/Category/CategoryRepositoryInterface.php
@@ -59,6 +59,15 @@ interface CategoryRepositoryInterface
      */
     public function find(int $categoryId) : Category;
 
+    /**
+     * Find a category
+     *
+     * @param string $name
+     *
+     * @return Category
+     */
+    public function findByName(string $name) : Category;
+
     /**
      * @param Category   $category
      * @param Collection $accounts
@@ -94,15 +103,6 @@ interface CategoryRepositoryInterface
      */
     public function journalsInPeriod(Collection $categories, Collection $accounts, array $types, Carbon $start, Carbon $end): Collection;
 
-    /**
-     * @param Collection $accounts
-     * @param Carbon     $start
-     * @param Carbon     $end
-     *
-     * @return string
-     */
-    public function spentInPeriodWithoutCategory(Collection $accounts, Carbon $start, Carbon $end) : string;
-
     /**
      * @param Collection $accounts
      * @param array      $types
@@ -133,6 +133,15 @@ interface CategoryRepositoryInterface
      */
     public function spentInPeriod(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): string;
 
+    /**
+     * @param Collection $accounts
+     * @param Carbon     $start
+     * @param Carbon     $end
+     *
+     * @return string
+     */
+    public function spentInPeriodWithoutCategory(Collection $accounts, Carbon $start, Carbon $end) : string;
+
     /**
      * @param array $data
      *
diff --git a/app/Repositories/ExportJob/ExportJobRepository.php b/app/Repositories/ExportJob/ExportJobRepository.php
index fe4f54f4f3..009aadbf6e 100644
--- a/app/Repositories/ExportJob/ExportJobRepository.php
+++ b/app/Repositories/ExportJob/ExportJobRepository.php
@@ -99,7 +99,7 @@ class ExportJobRepository implements ExportJobRepositoryInterface
      */
     public function findByKey(string $key): ExportJob
     {
-        $result = $this->user->exportJobs()->where('key', $key)->first();
+        $result = $this->user->exportJobs()->where('key', $key)->first(['export_jobs.*']);
         if (is_null($result)) {
             return new ExportJob;
         }
diff --git a/app/Repositories/ImportJob/ImportJobRepository.php b/app/Repositories/ImportJob/ImportJobRepository.php
new file mode 100644
index 0000000000..8badf97189
--- /dev/null
+++ b/app/Repositories/ImportJob/ImportJobRepository.php
@@ -0,0 +1,81 @@
+user = $user;
+    }
+
+    /**
+     * @param string $fileType
+     *
+     * @return ImportJob
+     */
+    public function create(string $fileType): ImportJob
+    {
+        $count = 0;
+        while ($count < 30) {
+            $key      = Str::random(12);
+            $existing = $this->findByKey($key);
+            if (is_null($existing->id)) {
+                $importJob = new ImportJob;
+                $importJob->user()->associate($this->user);
+                $importJob->file_type = $fileType;
+                $importJob->key    = Str::random(12);
+                $importJob->status = 'import_status_never_started';
+                $importJob->save();
+
+                // breaks the loop:
+                return $importJob;
+            }
+            $count++;
+
+        }
+
+        return new ImportJob;
+    }
+
+    /**
+     * @param string $key
+     *
+     * @return ImportJob
+     */
+    public function findByKey(string $key): ImportJob
+    {
+        $result = $this->user->importJobs()->where('key', $key)->first(['import_jobs.*']);
+        if (is_null($result)) {
+            return new ImportJob;
+        }
+
+        return $result;
+    }
+}
diff --git a/app/Repositories/ImportJob/ImportJobRepositoryInterface.php b/app/Repositories/ImportJob/ImportJobRepositoryInterface.php
new file mode 100644
index 0000000000..3d6c46b94d
--- /dev/null
+++ b/app/Repositories/ImportJob/ImportJobRepositoryInterface.php
@@ -0,0 +1,36 @@
+transactions()->get() as $transaction) {
-            $transaction->delete();
-        }
-
         $journal->delete();
 
         return true;
@@ -149,6 +144,7 @@ class JournalRepository implements JournalRepositoryInterface
     {
         $offset = ($page - 1) * $pageSize;
         $query  = $this->user->transactionJournals()->expanded()->sortCorrectly();
+        $query->where('transaction_journals.completed', 1);
         if (count($types) > 0) {
             $query->transactionTypes($types);
         }
@@ -171,6 +167,7 @@ class JournalRepository implements JournalRepositoryInterface
     public function getJournalsInRange(Collection $accounts, Carbon $start, Carbon $end): Collection
     {
         $query = $this->user->transactionJournals()->expanded()->sortCorrectly();
+        $query->where('transaction_journals.completed', 1);
         $query->before($end);
         $query->after($start);
 
diff --git a/app/Repositories/PiggyBank/PiggyBankRepository.php b/app/Repositories/PiggyBank/PiggyBankRepository.php
index d0e9a90ce3..f1a693c0a6 100644
--- a/app/Repositories/PiggyBank/PiggyBankRepository.php
+++ b/app/Repositories/PiggyBank/PiggyBankRepository.php
@@ -171,9 +171,6 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
      */
     public function store(array $data): PiggyBank
     {
-        $data['remind_me']     = false;
-        $data['reminder_skip'] = 0;
-
         $piggyBank = PiggyBank::create($data);
 
         return $piggyBank;
diff --git a/app/Repositories/Tag/TagRepository.php b/app/Repositories/Tag/TagRepository.php
index b2ae35a528..a794d3f6f7 100644
--- a/app/Repositories/Tag/TagRepository.php
+++ b/app/Repositories/Tag/TagRepository.php
@@ -82,6 +82,39 @@ class TagRepository implements TagRepositoryInterface
         return true;
     }
 
+    /**
+     * @param int $tagId
+     *
+     * @return Tag
+     */
+    public function find(int $tagId) : Tag
+    {
+        $tag = $this->user->tags()->find($tagId);
+        if (is_null($tag)) {
+            $tag = new Tag;
+        }
+
+        return $tag;
+    }
+
+    /**
+     * @param string $tag
+     *
+     * @return Tag
+     */
+    public function findByTag(string $tag) : Tag
+    {
+        $tags = $this->user->tags()->get();
+        /** @var Tag $tag */
+        foreach ($tags as $databaseTag) {
+            if ($databaseTag->tag === $tag) {
+                return $databaseTag;
+            }
+        }
+
+        return new Tag;
+    }
+
     /**
      * @return Collection
      */
diff --git a/app/Repositories/Tag/TagRepositoryInterface.php b/app/Repositories/Tag/TagRepositoryInterface.php
index 4f9304c662..fad9b301c8 100644
--- a/app/Repositories/Tag/TagRepositoryInterface.php
+++ b/app/Repositories/Tag/TagRepositoryInterface.php
@@ -42,6 +42,20 @@ interface TagRepositoryInterface
      */
     public function destroy(Tag $tag): bool;
 
+    /**
+     * @param string $tag
+     *
+     * @return Tag
+     */
+    public function findByTag(string $tag) : Tag;
+
+    /**
+     * @param int $tagId
+     *
+     * @return Tag
+     */
+    public function find(int $tagId) : Tag;
+
     /**
      * This method returns all the user's tags.
      *
diff --git a/app/Support/Binder/AccountList.php b/app/Support/Binder/AccountList.php
index de024c609d..e1b351a459 100644
--- a/app/Support/Binder/AccountList.php
+++ b/app/Support/Binder/AccountList.php
@@ -42,7 +42,6 @@ class AccountList implements BinderInterface
 
             /** @var \Illuminate\Support\Collection $object */
             $object = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
-                             ->where('account_types.editable', 1)
                              ->whereIn('accounts.id', $ids)
                              ->where('user_id', Auth::user()->id)
                              ->get(['accounts.*']);
diff --git a/app/Support/Facades/FireflyConfig.php b/app/Support/Facades/FireflyConfig.php
new file mode 100644
index 0000000000..0b1b47cff8
--- /dev/null
+++ b/app/Support/Facades/FireflyConfig.php
@@ -0,0 +1,33 @@
+id . $name;
+        if (Cache::has($fullName)) {
+            Cache::forget($fullName);
+        }
+        Preference::where('user_id', Auth::user()->id)->where('name', $name)->delete();
+
+        return true;
+    }
+
+    /**
+     * @param      $name
+     * @param null $default
+     *
+     * @return Configuration|null
+     */
+    public function get($name, $default = null)
+    {
+        Log::debug('Now in FFConfig::get()', ['name' => $name]);
+        $fullName = 'ff-config-' . $name;
+        if (Cache::has($fullName)) {
+            Log::debug('Return cache.');
+
+            return Cache::get($fullName);
+        }
+
+        $config = Configuration::where('name', $name)->first(['id', 'name', 'data']);
+
+        if ($config) {
+            Cache::forever($fullName, $config);
+            Log::debug('Return found one.');
+
+            return $config;
+        }
+        // no preference found and default is null:
+        if (is_null($default)) {
+            // return NULL
+            Log::debug('Return null.');
+
+            return null;
+        }
+
+        Log::debug('Return this->set().');
+
+        return $this->set($name, $default);
+
+    }
+
+    /**
+     * @param        $name
+     * @param string $value
+     *
+     * @return Configuration
+     */
+    public function set($name, $value): Configuration
+    {
+        Log::debug('Set new value for ', ['name' => $name]);
+        $config = Configuration::whereName($name)->first();
+        if (is_null($config)) {
+            Log::debug('Does not exist yet ', ['name' => $name]);
+            $item       = new Configuration;
+            $item->name = $name;
+            $item->data = $value;
+            $item->save();
+
+            Cache::forget('ff-config-' . $name);
+
+            return $item;
+        } else {
+            Log::debug('Exists already ', ['name' => $name]);
+            $config->data = $value;
+            $config->save();
+            Cache::forget('ff-config-' . $name);
+
+            return $config;
+        }
+
+    }
+
+}
diff --git a/app/Support/Migration/TestData.php b/app/Support/Migration/TestData.php
index 63c65d4c1c..3d39cc3215 100644
--- a/app/Support/Migration/TestData.php
+++ b/app/Support/Migration/TestData.php
@@ -72,9 +72,9 @@ class TestData
                 'updated_at'      => $this->time,
                 'user_id'         => $account['user_id'],
                 'account_type_id' => $account['account_type_id'],
-                'name'            => Crypt::encrypt($account['name']),
+                'name'            => $account['name'],
                 'active'          => 1,
-                'encrypted'       => 1,
+                'encrypted'       => 0,
                 'virtual_balance' => 0,
                 'iban'            => isset($account['iban']) ? Crypt::encrypt($account['iban']) : null,
             ];
@@ -244,6 +244,45 @@ class TestData
         DB::table('categories')->insert($insert);
     }
 
+    /**
+     *
+     */
+    private function createCurrencies()
+    {
+        $insert = [];
+        foreach ($this->data['currencies'] as $job) {
+            $insert[] = [
+                'created_at' => $this->time,
+                'updated_at' => $this->time,
+                'deleted_at' => null,
+                'code'       => $job['code'],
+                'name'       => $job['name'],
+                'symbol'     => $job['symbol'],
+            ];
+        }
+        DB::table('transaction_currencies')->insert($insert);
+    }
+
+    /**
+     *
+     */
+    private function createImportJobs()
+    {
+        $insert = [];
+        foreach ($this->data['import-jobs'] as $job) {
+            $insert[] = [
+                'created_at'    => $this->time,
+                'updated_at'    => $this->time,
+                'user_id'       => $job['user_id'],
+                'file_type'     => $job['file_type'],
+                'key'           => $job['key'],
+                'status'        => $job['status'],
+                'configuration' => json_encode($job['configuration']),
+            ];
+        }
+        DB::table('import_jobs')->insert($insert);
+    }
+
     /**
      *
      */
@@ -640,16 +679,14 @@ class TestData
         foreach ($this->data['piggy-banks'] as $piggyBank) {
             $piggyId = DB::table('piggy_banks')->insertGetId(
                 [
-                    'created_at'    => $this->time,
-                    'updated_at'    => $this->time,
-                    'account_id'    => $piggyBank['account_id'],
-                    'name'          => Crypt::encrypt($piggyBank['name']),
-                    'targetamount'  => $piggyBank['targetamount'],
-                    'startdate'     => $piggyBank['startdate'],
-                    'reminder_skip' => 0,
-                    'remind_me'     => 0,
-                    'order'         => $piggyBank['order'],
-                    'encrypted'     => 1,
+                    'created_at'   => $this->time,
+                    'updated_at'   => $this->time,
+                    'account_id'   => $piggyBank['account_id'],
+                    'name'         => Crypt::encrypt($piggyBank['name']),
+                    'targetamount' => $piggyBank['targetamount'],
+                    'startdate'    => $piggyBank['startdate'],
+                    'order'        => $piggyBank['order'],
+                    'encrypted'    => 1,
                 ]
             );
             if (isset($piggyBank['currentamount'])) {
@@ -773,10 +810,11 @@ class TestData
         foreach ($this->data['users'] as $user) {
             $insert[]
                 = [
-                'created_at' => $this->time,
-                'updated_at' => $this->time,
-                'email'      => $user['email'],
-                'password'   => bcrypt($user['password']),
+                'created_at'     => $this->time,
+                'updated_at'     => $this->time,
+                'email'          => $user['email'],
+                'remember_token' => '',
+                'password'       => bcrypt($user['password']),
             ];
 
         }
@@ -810,6 +848,8 @@ class TestData
         $this->createMultiWithdrawals();
         $this->createMultiDeposits();
         $this->createMultiTransfers();
+        $this->createImportJobs();
+        $this->createCurrencies();
     }
 
 }
diff --git a/app/Support/Models/TagSupport.php b/app/Support/Models/TagSupport.php
index 5af0e7c8fc..a0decf17e4 100644
--- a/app/Support/Models/TagSupport.php
+++ b/app/Support/Models/TagSupport.php
@@ -88,4 +88,4 @@ class TagSupport extends Model
 
     }
 
-}
\ No newline at end of file
+}
diff --git a/app/Support/Preferences.php b/app/Support/Preferences.php
index 717c7d364b..96d935bc85 100644
--- a/app/Support/Preferences.php
+++ b/app/Support/Preferences.php
@@ -69,7 +69,7 @@ class Preferences
             return Cache::get($fullName);
         }
 
-        $preference = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data_encrypted']);
+        $preference = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data']);
 
         if ($preference) {
             Cache::forever($fullName, $preference);
@@ -138,7 +138,7 @@ class Preferences
     {
         $fullName = 'preference' . $user->id . $name;
         Cache::forget($fullName);
-        $pref = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data_encrypted']);
+        $pref = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data']);
 
         if (!is_null($pref)) {
             $pref->data = $value;
diff --git a/app/Support/Steam.php b/app/Support/Steam.php
index d532a43cce..5158d2ab03 100644
--- a/app/Support/Steam.php
+++ b/app/Support/Steam.php
@@ -206,21 +206,28 @@ class Steam
     {
         $string = strtolower($string);
 
-        if (!(strpos($string, 'k') === false)) {
+        if (!(stripos($string, 'k') === false)) {
             // has a K in it, remove the K and multiply by 1024.
-            $bytes = bcmul(rtrim($string, 'k'), '1024');
+            $bytes = bcmul(rtrim($string, 'kK'), '1024');
 
             return intval($bytes);
         }
 
-        if (!(strpos($string, 'm') === false)) {
+        if (!(stripos($string, 'm') === false)) {
             // has a M in it, remove the M and multiply by 1048576.
-            $bytes = bcmul(rtrim($string, 'm'), '1048576');
+            $bytes = bcmul(rtrim($string, 'mM'), '1048576');
 
             return intval($bytes);
         }
 
-        return $string;
+        if (!(stripos($string, 'g') === false)) {
+            // has a G in it, remove the G and multiply by (1024)^3.
+            $bytes = bcmul(rtrim($string, 'gG'), '1073741824');
+
+            return intval($bytes);
+        }
+
+        return intval($string);
 
 
     }
diff --git a/app/User.php b/app/User.php
index d79b355d21..0c51395c41 100644
--- a/app/User.php
+++ b/app/User.php
@@ -54,6 +54,9 @@ use Illuminate\Foundation\Auth\User as Authenticatable;
  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\User whereBlocked($value)
  * @method static \Illuminate\Database\Query\Builder|\FireflyIII\User whereBlockedCode($value)
  * @mixin \Eloquent
+ * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\ImportJob[] $importjobs
+ * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBank[] $piggyBanks
+ * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Transaction[] $transactions
  */
 class User extends Authenticatable
 {
@@ -145,6 +148,14 @@ class User extends Authenticatable
         return $this->hasMany('FireflyIII\Models\ExportJob');
     }
 
+    /**
+     * @return HasMany
+     */
+    public function importjobs(): HasMany
+    {
+        return $this->hasMany('FireflyIII\Models\ImportJob');
+    }
+
     /**
      * Checks if the user has a role by its name.
      *
diff --git a/app/Validation/FireflyValidator.php b/app/Validation/FireflyValidator.php
index 76817224bc..636aea80ba 100644
--- a/app/Validation/FireflyValidator.php
+++ b/app/Validation/FireflyValidator.php
@@ -66,10 +66,8 @@ class FireflyValidator extends Validator
         }
 
         $secret = Session::get('two-factor-secret');
-        /** @var Google2FA $google2fa */
-        $google2fa = app(Google2FA::class);
 
-        return $google2fa->verifyKey($secret, $value);
+        return Google2FA::verifyKey($secret, $value);
     }
 
     /**
diff --git a/composer.lock b/composer.lock
index 8bcb7affc5..6168be6600 100644
--- a/composer.lock
+++ b/composer.lock
@@ -855,16 +855,16 @@
         },
         {
             "name": "laravel/framework",
-            "version": "v5.2.32",
+            "version": "5.2.41",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/framework.git",
-                "reference": "f688217113f70b01d0e127da9035195415812bef"
+                "reference": "29ba2e310cfeb42ab6545bcd81ff4c2ec1f6b5c2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/framework/zipball/f688217113f70b01d0e127da9035195415812bef",
-                "reference": "f688217113f70b01d0e127da9035195415812bef",
+                "url": "https://api.github.com/repos/laravel/framework/zipball/29ba2e310cfeb42ab6545bcd81ff4c2ec1f6b5c2",
+                "reference": "29ba2e310cfeb42ab6545bcd81ff4c2ec1f6b5c2",
                 "shasum": ""
             },
             "require": {
@@ -921,7 +921,8 @@
                 "illuminate/support": "self.version",
                 "illuminate/translation": "self.version",
                 "illuminate/validation": "self.version",
-                "illuminate/view": "self.version"
+                "illuminate/view": "self.version",
+                "tightenco/collect": "self.version"
             },
             "require-dev": {
                 "aws/aws-sdk-php": "~3.0",
@@ -980,7 +981,7 @@
                 "framework",
                 "laravel"
             ],
-            "time": "2016-05-17 13:24:40"
+            "time": "2016-07-20 13:13:06"
         },
         {
             "name": "laravelcollective/html",
@@ -1038,16 +1039,16 @@
         },
         {
             "name": "league/commonmark",
-            "version": "0.13.3",
+            "version": "0.14.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/commonmark.git",
-                "reference": "35816f39eb2498484fbb7b1495633a976ee1a8de"
+                "reference": "b73c0b7288bd0e6f9f56bd0b20d0657214b91838"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/35816f39eb2498484fbb7b1495633a976ee1a8de",
-                "reference": "35816f39eb2498484fbb7b1495633a976ee1a8de",
+                "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/b73c0b7288bd0e6f9f56bd0b20d0657214b91838",
+                "reference": "b73c0b7288bd0e6f9f56bd0b20d0657214b91838",
                 "shasum": ""
             },
             "require": {
@@ -1076,7 +1077,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "0.14-dev"
+                    "dev-master": "0.15-dev"
                 }
             },
             "autoload": {
@@ -1103,7 +1104,7 @@
                 "markdown",
                 "parser"
             ],
-            "time": "2016-05-21 18:41:30"
+            "time": "2016-07-02 18:48:39"
         },
         {
             "name": "league/csv",
@@ -1164,16 +1165,16 @@
         },
         {
             "name": "league/flysystem",
-            "version": "1.0.22",
+            "version": "1.0.25",
             "source": {
                 "type": "git",
                 "url": "https://github.com/thephpleague/flysystem.git",
-                "reference": "bd73a91703969a2d20ab4bfbf971d6c2cbe36612"
+                "reference": "a76afa4035931be0c78ca8efc6abf3902362f437"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/bd73a91703969a2d20ab4bfbf971d6c2cbe36612",
-                "reference": "bd73a91703969a2d20ab4bfbf971d6c2cbe36612",
+                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a76afa4035931be0c78ca8efc6abf3902362f437",
+                "reference": "a76afa4035931be0c78ca8efc6abf3902362f437",
                 "shasum": ""
             },
             "require": {
@@ -1186,7 +1187,7 @@
                 "ext-fileinfo": "*",
                 "mockery/mockery": "~0.9",
                 "phpspec/phpspec": "^2.2",
-                "phpunit/phpunit": "~4.8 || ~5.0"
+                "phpunit/phpunit": "~4.8"
             },
             "suggest": {
                 "ext-fileinfo": "Required for MimeType",
@@ -1243,20 +1244,20 @@
                 "sftp",
                 "storage"
             ],
-            "time": "2016-04-28 06:53:12"
+            "time": "2016-07-18 12:22:57"
         },
         {
             "name": "monolog/monolog",
-            "version": "1.19.0",
+            "version": "1.20.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Seldaek/monolog.git",
-                "reference": "5f56ed5212dc509c8dc8caeba2715732abb32dbf"
+                "reference": "55841909e2bcde01b5318c35f2b74f8ecc86e037"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/5f56ed5212dc509c8dc8caeba2715732abb32dbf",
-                "reference": "5f56ed5212dc509c8dc8caeba2715732abb32dbf",
+                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/55841909e2bcde01b5318c35f2b74f8ecc86e037",
+                "reference": "55841909e2bcde01b5318c35f2b74f8ecc86e037",
                 "shasum": ""
             },
             "require": {
@@ -1275,8 +1276,8 @@
                 "php-console/php-console": "^3.1.3",
                 "phpunit/phpunit": "~4.5",
                 "phpunit/phpunit-mock-objects": "2.3.0",
-                "raven/raven": "^0.13",
                 "ruflin/elastica": ">=0.90 <3.0",
+                "sentry/sentry": "^0.13",
                 "swiftmailer/swiftmailer": "~5.3"
             },
             "suggest": {
@@ -1288,9 +1289,9 @@
                 "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver",
                 "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
                 "php-console/php-console": "Allow sending log messages to Google Chrome",
-                "raven/raven": "Allow sending log messages to a Sentry server",
                 "rollbar/rollbar": "Allow sending log messages to Rollbar",
-                "ruflin/elastica": "Allow sending log messages to an Elastic Search server"
+                "ruflin/elastica": "Allow sending log messages to an Elastic Search server",
+                "sentry/sentry": "Allow sending log messages to a Sentry server"
             },
             "type": "library",
             "extra": {
@@ -1321,7 +1322,7 @@
                 "logging",
                 "psr-3"
             ],
-            "time": "2016-04-12 18:29:35"
+            "time": "2016-07-02 14:02:10"
         },
         {
             "name": "mtdowling/cron-expression",
@@ -1843,23 +1844,23 @@
         },
         {
             "name": "swiftmailer/swiftmailer",
-            "version": "v5.4.2",
+            "version": "v5.4.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/swiftmailer/swiftmailer.git",
-                "reference": "d8db871a54619458a805229a057ea2af33c753e8"
+                "reference": "4cc92842069c2bbc1f28daaaf1d2576ec4dfe153"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/d8db871a54619458a805229a057ea2af33c753e8",
-                "reference": "d8db871a54619458a805229a057ea2af33c753e8",
+                "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/4cc92842069c2bbc1f28daaaf1d2576ec4dfe153",
+                "reference": "4cc92842069c2bbc1f28daaaf1d2576ec4dfe153",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3"
             },
             "require-dev": {
-                "mockery/mockery": "~0.9.1,<0.9.4"
+                "mockery/mockery": "~0.9.1"
             },
             "type": "library",
             "extra": {
@@ -1892,20 +1893,20 @@
                 "mail",
                 "mailer"
             ],
-            "time": "2016-05-01 08:45:47"
+            "time": "2016-07-08 11:51:25"
         },
         {
             "name": "symfony/console",
-            "version": "v3.0.6",
+            "version": "v3.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "34a214710e0714b6efcf40ba3cd1e31373a97820"
+                "reference": "a7abb7153f6d1da47f87ec50274844e246b09d9f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/34a214710e0714b6efcf40ba3cd1e31373a97820",
-                "reference": "34a214710e0714b6efcf40ba3cd1e31373a97820",
+                "url": "https://api.github.com/repos/symfony/console/zipball/a7abb7153f6d1da47f87ec50274844e246b09d9f",
+                "reference": "a7abb7153f6d1da47f87ec50274844e246b09d9f",
                 "shasum": ""
             },
             "require": {
@@ -1952,20 +1953,20 @@
             ],
             "description": "Symfony Console Component",
             "homepage": "https://symfony.com",
-            "time": "2016-04-28 09:48:42"
+            "time": "2016-06-29 07:02:21"
         },
         {
             "name": "symfony/debug",
-            "version": "v3.0.6",
+            "version": "v3.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/debug.git",
-                "reference": "a06d10888a45afd97534506afb058ec38d9ba35b"
+                "reference": "c54bc3539c3b87e86799533801e8ae0e971d78c2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/debug/zipball/a06d10888a45afd97534506afb058ec38d9ba35b",
-                "reference": "a06d10888a45afd97534506afb058ec38d9ba35b",
+                "url": "https://api.github.com/repos/symfony/debug/zipball/c54bc3539c3b87e86799533801e8ae0e971d78c2",
+                "reference": "c54bc3539c3b87e86799533801e8ae0e971d78c2",
                 "shasum": ""
             },
             "require": {
@@ -2009,20 +2010,20 @@
             ],
             "description": "Symfony Debug Component",
             "homepage": "https://symfony.com",
-            "time": "2016-03-30 10:41:14"
+            "time": "2016-06-29 05:40:00"
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v3.0.6",
+            "version": "v3.1.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
-                "reference": "807dde98589f9b2b00624dca326740380d78dbbc"
+                "reference": "7f9839ede2070f53e7e2f0849b9bd14748c434c5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/807dde98589f9b2b00624dca326740380d78dbbc",
-                "reference": "807dde98589f9b2b00624dca326740380d78dbbc",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/7f9839ede2070f53e7e2f0849b9bd14748c434c5",
+                "reference": "7f9839ede2070f53e7e2f0849b9bd14748c434c5",
                 "shasum": ""
             },
             "require": {
@@ -2042,7 +2043,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.0-dev"
+                    "dev-master": "3.1-dev"
                 }
             },
             "autoload": {
@@ -2069,20 +2070,20 @@
             ],
             "description": "Symfony EventDispatcher Component",
             "homepage": "https://symfony.com",
-            "time": "2016-05-05 06:56:13"
+            "time": "2016-06-29 05:41:56"
         },
         {
             "name": "symfony/finder",
-            "version": "v3.0.6",
+            "version": "v3.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git",
-                "reference": "c54e407b35bc098916704e9fd090da21da4c4f52"
+                "reference": "3eb4e64c6145ef8b92adefb618a74ebdde9e3fe9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/finder/zipball/c54e407b35bc098916704e9fd090da21da4c4f52",
-                "reference": "c54e407b35bc098916704e9fd090da21da4c4f52",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/3eb4e64c6145ef8b92adefb618a74ebdde9e3fe9",
+                "reference": "3eb4e64c6145ef8b92adefb618a74ebdde9e3fe9",
                 "shasum": ""
             },
             "require": {
@@ -2118,20 +2119,20 @@
             ],
             "description": "Symfony Finder Component",
             "homepage": "https://symfony.com",
-            "time": "2016-03-10 11:13:05"
+            "time": "2016-06-29 05:40:00"
         },
         {
             "name": "symfony/http-foundation",
-            "version": "v3.0.6",
+            "version": "v3.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-foundation.git",
-                "reference": "18b24bc32d2495ae79d76e777368786a6536fe31"
+                "reference": "1341139f906d295baa4f4abd55293d07e25a065a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/18b24bc32d2495ae79d76e777368786a6536fe31",
-                "reference": "18b24bc32d2495ae79d76e777368786a6536fe31",
+                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/1341139f906d295baa4f4abd55293d07e25a065a",
+                "reference": "1341139f906d295baa4f4abd55293d07e25a065a",
                 "shasum": ""
             },
             "require": {
@@ -2171,20 +2172,20 @@
             ],
             "description": "Symfony HttpFoundation Component",
             "homepage": "https://symfony.com",
-            "time": "2016-04-12 18:09:53"
+            "time": "2016-06-29 07:02:21"
         },
         {
             "name": "symfony/http-kernel",
-            "version": "v3.0.6",
+            "version": "v3.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-kernel.git",
-                "reference": "6a5010978edf0a9646342232531e53bfc7abbcd3"
+                "reference": "177b63b2d50b63fa6d82ea41359ed9928cc7a1fb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6a5010978edf0a9646342232531e53bfc7abbcd3",
-                "reference": "6a5010978edf0a9646342232531e53bfc7abbcd3",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/177b63b2d50b63fa6d82ea41359ed9928cc7a1fb",
+                "reference": "177b63b2d50b63fa6d82ea41359ed9928cc7a1fb",
                 "shasum": ""
             },
             "require": {
@@ -2192,7 +2193,7 @@
                 "psr/log": "~1.0",
                 "symfony/debug": "~2.8|~3.0",
                 "symfony/event-dispatcher": "~2.8|~3.0",
-                "symfony/http-foundation": "~2.8|~3.0"
+                "symfony/http-foundation": "~2.8.8|~3.0.8|~3.1.2|~3.2"
             },
             "conflict": {
                 "symfony/config": "<2.8"
@@ -2253,7 +2254,7 @@
             ],
             "description": "Symfony HttpKernel Component",
             "homepage": "https://symfony.com",
-            "time": "2016-05-09 22:13:13"
+            "time": "2016-06-30 16:30:17"
         },
         {
             "name": "symfony/polyfill-mbstring",
@@ -2424,16 +2425,16 @@
         },
         {
             "name": "symfony/process",
-            "version": "v3.0.6",
+            "version": "v3.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git",
-                "reference": "53f9407c0bb1c5a79127db8f7bfe12f0f6f3dcdb"
+                "reference": "d7cde1f9d94d87060204f863779389b61c382eeb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/53f9407c0bb1c5a79127db8f7bfe12f0f6f3dcdb",
-                "reference": "53f9407c0bb1c5a79127db8f7bfe12f0f6f3dcdb",
+                "url": "https://api.github.com/repos/symfony/process/zipball/d7cde1f9d94d87060204f863779389b61c382eeb",
+                "reference": "d7cde1f9d94d87060204f863779389b61c382eeb",
                 "shasum": ""
             },
             "require": {
@@ -2469,20 +2470,20 @@
             ],
             "description": "Symfony Process Component",
             "homepage": "https://symfony.com",
-            "time": "2016-04-14 15:30:28"
+            "time": "2016-06-29 05:40:00"
         },
         {
             "name": "symfony/routing",
-            "version": "v3.0.6",
+            "version": "v3.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/routing.git",
-                "reference": "a6cd168310066176599442aa21f5da86c3f8e0b3"
+                "reference": "9038984bd9c05ab07280121e9e10f61a7231457b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/routing/zipball/a6cd168310066176599442aa21f5da86c3f8e0b3",
-                "reference": "a6cd168310066176599442aa21f5da86c3f8e0b3",
+                "url": "https://api.github.com/repos/symfony/routing/zipball/9038984bd9c05ab07280121e9e10f61a7231457b",
+                "reference": "9038984bd9c05ab07280121e9e10f61a7231457b",
                 "shasum": ""
             },
             "require": {
@@ -2544,20 +2545,20 @@
                 "uri",
                 "url"
             ],
-            "time": "2016-05-03 12:23:49"
+            "time": "2016-06-29 05:40:00"
         },
         {
             "name": "symfony/translation",
-            "version": "v3.0.6",
+            "version": "v3.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation.git",
-                "reference": "f7a07af51ea067745a521dab1e3152044a2fb1f2"
+                "reference": "6bf844e1ee3c820c012386c10427a5c67bbefec8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation/zipball/f7a07af51ea067745a521dab1e3152044a2fb1f2",
-                "reference": "f7a07af51ea067745a521dab1e3152044a2fb1f2",
+                "url": "https://api.github.com/repos/symfony/translation/zipball/6bf844e1ee3c820c012386c10427a5c67bbefec8",
+                "reference": "6bf844e1ee3c820c012386c10427a5c67bbefec8",
                 "shasum": ""
             },
             "require": {
@@ -2608,20 +2609,20 @@
             ],
             "description": "Symfony Translation Component",
             "homepage": "https://symfony.com",
-            "time": "2016-03-25 01:41:20"
+            "time": "2016-06-29 05:40:00"
         },
         {
             "name": "symfony/var-dumper",
-            "version": "v3.0.6",
+            "version": "v3.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/var-dumper.git",
-                "reference": "0e918c269093ba4c77fca14e9424fa74ed16f1a6"
+                "reference": "2f046e9a9d571f22cc8b26783564876713b06579"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0e918c269093ba4c77fca14e9424fa74ed16f1a6",
-                "reference": "0e918c269093ba4c77fca14e9424fa74ed16f1a6",
+                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/2f046e9a9d571f22cc8b26783564876713b06579",
+                "reference": "2f046e9a9d571f22cc8b26783564876713b06579",
                 "shasum": ""
             },
             "require": {
@@ -2671,20 +2672,20 @@
                 "debug",
                 "dump"
             ],
-            "time": "2016-04-25 11:17:47"
+            "time": "2016-06-29 05:40:00"
         },
         {
             "name": "twig/twig",
-            "version": "v1.24.0",
+            "version": "v1.24.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/twigphp/Twig.git",
-                "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8"
+                "reference": "3566d311a92aae4deec6e48682dc5a4528c4a512"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8",
-                "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8",
+                "url": "https://api.github.com/repos/twigphp/Twig/zipball/3566d311a92aae4deec6e48682dc5a4528c4a512",
+                "reference": "3566d311a92aae4deec6e48682dc5a4528c4a512",
                 "shasum": ""
             },
             "require": {
@@ -2732,20 +2733,20 @@
             "keywords": [
                 "templating"
             ],
-            "time": "2016-01-25 21:22:18"
+            "time": "2016-05-30 09:11:59"
         },
         {
             "name": "vlucas/phpdotenv",
-            "version": "v2.2.1",
+            "version": "v2.3.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/vlucas/phpdotenv.git",
-                "reference": "63f37b9395e8041cd4313129c08ece896d06ca8e"
+                "reference": "9ca5644c536654e9509b9d257f53c58630eb2a6a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/63f37b9395e8041cd4313129c08ece896d06ca8e",
-                "reference": "63f37b9395e8041cd4313129c08ece896d06ca8e",
+                "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/9ca5644c536654e9509b9d257f53c58630eb2a6a",
+                "reference": "9ca5644c536654e9509b9d257f53c58630eb2a6a",
                 "shasum": ""
             },
             "require": {
@@ -2757,7 +2758,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.2-dev"
+                    "dev-master": "2.3-dev"
                 }
             },
             "autoload": {
@@ -2782,7 +2783,7 @@
                 "env",
                 "environment"
             ],
-            "time": "2016-04-15 10:48:49"
+            "time": "2016-06-14 14:14:52"
         },
         {
             "name": "watson/validating",
@@ -2897,28 +2898,31 @@
         },
         {
             "name": "barryvdh/laravel-ide-helper",
-            "version": "v2.1.4",
+            "version": "v2.2.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/barryvdh/laravel-ide-helper.git",
-                "reference": "f1ebd847aac9a4545325d35108cafc285fe1605f"
+                "reference": "28af7cd19ca41cc0c63dd1de2b46c2b84d31c463"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/f1ebd847aac9a4545325d35108cafc285fe1605f",
-                "reference": "f1ebd847aac9a4545325d35108cafc285fe1605f",
+                "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/28af7cd19ca41cc0c63dd1de2b46c2b84d31c463",
+                "reference": "28af7cd19ca41cc0c63dd1de2b46c2b84d31c463",
                 "shasum": ""
             },
             "require": {
-                "illuminate/console": "5.0.x|5.1.x|5.2.x",
-                "illuminate/filesystem": "5.0.x|5.1.x|5.2.x",
-                "illuminate/support": "5.0.x|5.1.x|5.2.x",
+                "barryvdh/reflection-docblock": "^2.0.4",
+                "illuminate/console": "^5.0,<5.4",
+                "illuminate/filesystem": "^5.0,<5.4",
+                "illuminate/support": "^5.0,<5.4",
                 "php": ">=5.4.0",
-                "phpdocumentor/reflection-docblock": "^2.0.4",
-                "symfony/class-loader": "~2.3|~3.0"
+                "symfony/class-loader": "^2.3|^3.0"
             },
             "require-dev": {
-                "doctrine/dbal": "~2.3"
+                "doctrine/dbal": "~2.3",
+                "phpunit/phpunit": "4.*",
+                "scrutinizer/ocular": "~1.1",
+                "squizlabs/php_codesniffer": "~2.3"
             },
             "suggest": {
                 "doctrine/dbal": "Load information from the database about models for phpdocs (~2.3)"
@@ -2926,7 +2930,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.1-dev"
+                    "dev-master": "2.2-dev"
                 }
             },
             "autoload": {
@@ -2956,7 +2960,56 @@
                 "phpstorm",
                 "sublime"
             ],
-            "time": "2016-03-03 08:45:00"
+            "time": "2016-07-04 11:52:48"
+        },
+        {
+            "name": "barryvdh/reflection-docblock",
+            "version": "v2.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/barryvdh/ReflectionDocBlock.git",
+                "reference": "3dcbd98b5d9384a5357266efba8fd29884458e5c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/3dcbd98b5d9384a5357266efba8fd29884458e5c",
+                "reference": "3dcbd98b5d9384a5357266efba8fd29884458e5c",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~4.0,<4.5"
+            },
+            "suggest": {
+                "dflydev/markdown": "~1.0",
+                "erusev/parsedown": "~1.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Barryvdh": [
+                        "src/"
+                    ]
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mike van Riel",
+                    "email": "mike.vanriel@naenius.com"
+                }
+            ],
+            "time": "2016-06-13 19:28:20"
         },
         {
             "name": "doctrine/instantiator",
@@ -3066,12 +3119,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/hamcrest/hamcrest-php.git",
-                "reference": "8bfb4013724c1f62dc267af0e998207ac3fdc226"
+                "reference": "b7a5e18824117d8b65942e9aa77425d9b7dd7ff8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8bfb4013724c1f62dc267af0e998207ac3fdc226",
-                "reference": "8bfb4013724c1f62dc267af0e998207ac3fdc226",
+                "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b7a5e18824117d8b65942e9aa77425d9b7dd7ff8",
+                "reference": "b7a5e18824117d8b65942e9aa77425d9b7dd7ff8",
                 "shasum": ""
             },
             "require": {
@@ -3106,7 +3159,7 @@
             "keywords": [
                 "test"
             ],
-            "time": "2016-04-21 19:47:43"
+            "time": "2016-07-22 14:03:17"
         },
         {
             "name": "maximebf/debugbar",
@@ -3175,12 +3228,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/padraic/mockery.git",
-                "reference": "ad31ff997d983e0d5d60ac80cfcedcbb4e6c4461"
+                "reference": "ee06e7b564ea4dc9b90605d894c2626f87df334d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/padraic/mockery/zipball/ad31ff997d983e0d5d60ac80cfcedcbb4e6c4461",
-                "reference": "ad31ff997d983e0d5d60ac80cfcedcbb4e6c4461",
+                "url": "https://api.github.com/repos/padraic/mockery/zipball/ee06e7b564ea4dc9b90605d894c2626f87df334d",
+                "reference": "ee06e7b564ea4dc9b90605d894c2626f87df334d",
                 "shasum": ""
             },
             "require": {
@@ -3232,41 +3285,90 @@
                 "test double",
                 "testing"
             ],
-            "time": "2016-05-03 10:17:25"
+            "time": "2016-07-06 09:05:19"
         },
         {
-            "name": "phpdocumentor/reflection-docblock",
-            "version": "2.0.4",
+            "name": "phpdocumentor/reflection-common",
+            "version": "1.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
-                "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
+                "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+                "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
-                "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
+                "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.3"
+                "php": ">=5.5"
             },
             "require-dev": {
-                "phpunit/phpunit": "~4.0"
-            },
-            "suggest": {
-                "dflydev/markdown": "~1.0",
-                "erusev/parsedown": "~1.0"
+                "phpunit/phpunit": "^4.6"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.0.x-dev"
+                    "dev-master": "1.0.x-dev"
                 }
             },
             "autoload": {
-                "psr-0": {
-                    "phpDocumentor": [
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": [
+                        "src"
+                    ]
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jaap van Otterdijk",
+                    "email": "opensource@ijaap.nl"
+                }
+            ],
+            "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+            "homepage": "http://www.phpdoc.org",
+            "keywords": [
+                "FQSEN",
+                "phpDocumentor",
+                "phpdoc",
+                "reflection",
+                "static analysis"
+            ],
+            "time": "2015-12-27 11:43:31"
+        },
+        {
+            "name": "phpdocumentor/reflection-docblock",
+            "version": "3.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+                "reference": "9270140b940ff02e58ec577c237274e92cd40cdd"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9270140b940ff02e58ec577c237274e92cd40cdd",
+                "reference": "9270140b940ff02e58ec577c237274e92cd40cdd",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.5",
+                "phpdocumentor/reflection-common": "^1.0@dev",
+                "phpdocumentor/type-resolver": "^0.2.0",
+                "webmozart/assert": "^1.0"
+            },
+            "require-dev": {
+                "mockery/mockery": "^0.9.4",
+                "phpunit/phpunit": "^4.4"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": [
                         "src/"
                     ]
                 }
@@ -3278,39 +3380,87 @@
             "authors": [
                 {
                     "name": "Mike van Riel",
-                    "email": "mike.vanriel@naenius.com"
+                    "email": "me@mikevanriel.com"
                 }
             ],
-            "time": "2015-02-03 12:10:50"
+            "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+            "time": "2016-06-10 09:48:41"
         },
         {
-            "name": "phpspec/prophecy",
-            "version": "v1.6.0",
+            "name": "phpdocumentor/type-resolver",
+            "version": "0.2",
             "source": {
                 "type": "git",
-                "url": "https://github.com/phpspec/prophecy.git",
-                "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972"
+                "url": "https://github.com/phpDocumentor/TypeResolver.git",
+                "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972",
-                "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972",
+                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443",
+                "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.5",
+                "phpdocumentor/reflection-common": "^1.0"
+            },
+            "require-dev": {
+                "mockery/mockery": "^0.9.4",
+                "phpunit/phpunit": "^5.2||^4.8.24"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": [
+                        "src/"
+                    ]
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mike van Riel",
+                    "email": "me@mikevanriel.com"
+                }
+            ],
+            "time": "2016-06-10 07:14:17"
+        },
+        {
+            "name": "phpspec/prophecy",
+            "version": "v1.6.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpspec/prophecy.git",
+                "reference": "58a8137754bc24b25740d4281399a4a3596058e0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0",
+                "reference": "58a8137754bc24b25740d4281399a4a3596058e0",
                 "shasum": ""
             },
             "require": {
                 "doctrine/instantiator": "^1.0.2",
                 "php": "^5.3|^7.0",
-                "phpdocumentor/reflection-docblock": "~2.0",
-                "sebastian/comparator": "~1.1",
-                "sebastian/recursion-context": "~1.0"
+                "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
+                "sebastian/comparator": "^1.1",
+                "sebastian/recursion-context": "^1.0"
             },
             "require-dev": {
-                "phpspec/phpspec": "~2.0"
+                "phpspec/phpspec": "^2.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.5.x-dev"
+                    "dev-master": "1.6.x-dev"
                 }
             },
             "autoload": {
@@ -3343,7 +3493,7 @@
                 "spy",
                 "stub"
             ],
-            "time": "2016-02-15 07:46:21"
+            "time": "2016-06-07 08:13:47"
         },
         {
             "name": "phpunit/php-code-coverage",
@@ -3590,16 +3740,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "4.8.26",
+            "version": "4.8.27",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "fc1d8cd5b5de11625979125c5639347896ac2c74"
+                "reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fc1d8cd5b5de11625979125c5639347896ac2c74",
-                "reference": "fc1d8cd5b5de11625979125c5639347896ac2c74",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c062dddcb68e44b563f66ee319ddae2b5a322a90",
+                "reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90",
                 "shasum": ""
             },
             "require": {
@@ -3658,7 +3808,7 @@
                 "testing",
                 "xunit"
             ],
-            "time": "2016-05-17 03:09:28"
+            "time": "2016-07-21 06:48:14"
         },
         {
             "name": "phpunit/phpunit-mock-objects",
@@ -3884,16 +4034,16 @@
         },
         {
             "name": "sebastian/exporter",
-            "version": "1.2.1",
+            "version": "1.2.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/exporter.git",
-                "reference": "7ae5513327cb536431847bcc0c10edba2701064e"
+                "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e",
-                "reference": "7ae5513327cb536431847bcc0c10edba2701064e",
+                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
+                "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
                 "shasum": ""
             },
             "require": {
@@ -3901,12 +4051,13 @@
                 "sebastian/recursion-context": "~1.0"
             },
             "require-dev": {
+                "ext-mbstring": "*",
                 "phpunit/phpunit": "~4.4"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.2.x-dev"
+                    "dev-master": "1.3.x-dev"
                 }
             },
             "autoload": {
@@ -3946,7 +4097,7 @@
                 "export",
                 "exporter"
             ],
-            "time": "2015-06-21 07:55:53"
+            "time": "2016-06-17 09:04:28"
         },
         {
             "name": "sebastian/global-state",
@@ -4089,16 +4240,16 @@
         },
         {
             "name": "symfony/class-loader",
-            "version": "v3.0.6",
+            "version": "v3.1.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/class-loader.git",
-                "reference": "cbb7e6a9c0213a0cffa5d9065ee8214ca4e83877"
+                "reference": "0d0ac77c336eb73f35bebdf3e1f3695ac741bbc9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/class-loader/zipball/cbb7e6a9c0213a0cffa5d9065ee8214ca4e83877",
-                "reference": "cbb7e6a9c0213a0cffa5d9065ee8214ca4e83877",
+                "url": "https://api.github.com/repos/symfony/class-loader/zipball/0d0ac77c336eb73f35bebdf3e1f3695ac741bbc9",
+                "reference": "0d0ac77c336eb73f35bebdf3e1f3695ac741bbc9",
                 "shasum": ""
             },
             "require": {
@@ -4114,7 +4265,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.0-dev"
+                    "dev-master": "3.1-dev"
                 }
             },
             "autoload": {
@@ -4141,20 +4292,20 @@
             ],
             "description": "Symfony ClassLoader Component",
             "homepage": "https://symfony.com",
-            "time": "2016-03-30 10:41:14"
+            "time": "2016-06-29 05:41:56"
         },
         {
             "name": "symfony/css-selector",
-            "version": "v3.0.6",
+            "version": "v3.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/css-selector.git",
-                "reference": "65e764f404685f2dc20c057e889b3ad04b2e2db0"
+                "reference": "b8999c1f33c224b2b66b38253f5e3a838d0d0115"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/css-selector/zipball/65e764f404685f2dc20c057e889b3ad04b2e2db0",
-                "reference": "65e764f404685f2dc20c057e889b3ad04b2e2db0",
+                "url": "https://api.github.com/repos/symfony/css-selector/zipball/b8999c1f33c224b2b66b38253f5e3a838d0d0115",
+                "reference": "b8999c1f33c224b2b66b38253f5e3a838d0d0115",
                 "shasum": ""
             },
             "require": {
@@ -4194,20 +4345,20 @@
             ],
             "description": "Symfony CssSelector Component",
             "homepage": "https://symfony.com",
-            "time": "2016-03-04 07:55:57"
+            "time": "2016-06-29 05:40:00"
         },
         {
             "name": "symfony/dom-crawler",
-            "version": "v3.0.6",
+            "version": "v3.0.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/dom-crawler.git",
-                "reference": "49b588841225b205700e5122fa01911cabada857"
+                "reference": "62769e3409006b937bb333b29da8df9a8b262975"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/49b588841225b205700e5122fa01911cabada857",
-                "reference": "49b588841225b205700e5122fa01911cabada857",
+                "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/62769e3409006b937bb333b29da8df9a8b262975",
+                "reference": "62769e3409006b937bb333b29da8df9a8b262975",
                 "shasum": ""
             },
             "require": {
@@ -4250,20 +4401,20 @@
             ],
             "description": "Symfony DomCrawler Component",
             "homepage": "https://symfony.com",
-            "time": "2016-04-12 18:09:53"
+            "time": "2016-06-29 05:40:00"
         },
         {
             "name": "symfony/yaml",
-            "version": "v3.0.6",
+            "version": "v3.1.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "0047c8366744a16de7516622c5b7355336afae96"
+                "reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/0047c8366744a16de7516622c5b7355336afae96",
-                "reference": "0047c8366744a16de7516622c5b7355336afae96",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/2884c26ce4c1d61aebf423a8b912950fe7c764de",
+                "reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de",
                 "shasum": ""
             },
             "require": {
@@ -4272,7 +4423,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.0-dev"
+                    "dev-master": "3.1-dev"
                 }
             },
             "autoload": {
@@ -4299,7 +4450,56 @@
             ],
             "description": "Symfony Yaml Component",
             "homepage": "https://symfony.com",
-            "time": "2016-03-04 07:55:57"
+            "time": "2016-06-29 05:41:56"
+        },
+        {
+            "name": "webmozart/assert",
+            "version": "1.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/webmozart/assert.git",
+                "reference": "30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/webmozart/assert/zipball/30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde",
+                "reference": "30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.6"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Webmozart\\Assert\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Bernhard Schussek",
+                    "email": "bschussek@gmail.com"
+                }
+            ],
+            "description": "Assertions to validate method input/output with nice error messages.",
+            "keywords": [
+                "assert",
+                "check",
+                "validate"
+            ],
+            "time": "2015-08-24 13:29:44"
         }
     ],
     "aliases": [],
diff --git a/config/app.php b/config/app.php
index 79a9e67ed6..bef9fdc3bd 100644
--- a/config/app.php
+++ b/config/app.php
@@ -152,23 +152,6 @@ return [
         Collective\Html\HtmlServiceProvider::class,
 
 
-        /*
-         * More service providers.
-         */
-        FireflyIII\Providers\CrudServiceProvider::class,
-        FireflyIII\Providers\AccountServiceProvider::class,
-        FireflyIII\Providers\AttachmentServiceProvider::class,
-        FireflyIII\Providers\BillServiceProvider::class,
-        FireflyIII\Providers\BudgetServiceProvider::class,
-        FireflyIII\Providers\CategoryServiceProvider::class,
-        FireflyIII\Providers\ExportJobServiceProvider::class,
-        FireflyIII\Providers\JournalServiceProvider::class,
-        FireflyIII\Providers\PiggyBankServiceProvider::class,
-        FireflyIII\Providers\RuleServiceProvider::class,
-        FireflyIII\Providers\RuleGroupServiceProvider::class,
-        FireflyIII\Providers\TagServiceProvider::class,
-
-
         /*
          * Application Service Providers...
          */
@@ -186,6 +169,24 @@ return [
         'TwigBridge\ServiceProvider',
         'PragmaRX\Google2FA\Vendor\Laravel\ServiceProvider',
 
+
+        /*
+ * More service providers.
+ */
+        FireflyIII\Providers\CrudServiceProvider::class,
+        FireflyIII\Providers\AccountServiceProvider::class,
+        FireflyIII\Providers\AttachmentServiceProvider::class,
+        FireflyIII\Providers\BillServiceProvider::class,
+        FireflyIII\Providers\BudgetServiceProvider::class,
+        FireflyIII\Providers\CategoryServiceProvider::class,
+        FireflyIII\Providers\ExportJobServiceProvider::class,
+        FireflyIII\Providers\JournalServiceProvider::class,
+        FireflyIII\Providers\PiggyBankServiceProvider::class,
+        FireflyIII\Providers\RuleServiceProvider::class,
+        FireflyIII\Providers\RuleGroupServiceProvider::class,
+        FireflyIII\Providers\TagServiceProvider::class,
+
+
     ],
 
     /*
@@ -201,48 +202,49 @@ return [
 
     'aliases' => [
 
-        'App'          => Illuminate\Support\Facades\App::class,
-        'Artisan'      => Illuminate\Support\Facades\Artisan::class,
-        'Auth'         => Illuminate\Support\Facades\Auth::class,
-        'Blade'        => Illuminate\Support\Facades\Blade::class,
-        'Cache'        => Illuminate\Support\Facades\Cache::class,
-        'Config'       => Illuminate\Support\Facades\Config::class,
-        'Cookie'       => Illuminate\Support\Facades\Cookie::class,
-        'Crypt'        => Illuminate\Support\Facades\Crypt::class,
-        'DB'           => Illuminate\Support\Facades\DB::class,
-        'Eloquent'     => Illuminate\Database\Eloquent\Model::class,
-        'Event'        => Illuminate\Support\Facades\Event::class,
-        'File'         => Illuminate\Support\Facades\File::class,
-        'Gate'         => Illuminate\Support\Facades\Gate::class,
-        'Hash'         => Illuminate\Support\Facades\Hash::class,
-        'Lang'         => Illuminate\Support\Facades\Lang::class,
-        'Log'          => Illuminate\Support\Facades\Log::class,
-        'Mail'         => Illuminate\Support\Facades\Mail::class,
-        'Password'     => Illuminate\Support\Facades\Password::class,
-        'Queue'        => Illuminate\Support\Facades\Queue::class,
-        'Redirect'     => Illuminate\Support\Facades\Redirect::class,
-        'Redis'        => Illuminate\Support\Facades\Redis::class,
-        'Request'      => Illuminate\Support\Facades\Request::class,
-        'Response'     => Illuminate\Support\Facades\Response::class,
-        'Route'        => Illuminate\Support\Facades\Route::class,
-        'Schema'       => Illuminate\Support\Facades\Schema::class,
-        'Session'      => Illuminate\Support\Facades\Session::class,
-        'Storage'      => Illuminate\Support\Facades\Storage::class,
-        'URL'          => Illuminate\Support\Facades\URL::class,
-        'Validator'    => Illuminate\Support\Facades\Validator::class,
-        'View'         => Illuminate\Support\Facades\View::class,
-        'Twig'         => 'TwigBridge\Facade\Twig',
-        'Form'         => Collective\Html\FormFacade::class,
-        'Html'         => Collective\Html\HtmlFacade::class,
-        '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',
-        'Entrust'      => 'Zizaco\Entrust\EntrustFacade',
-        'Input'        => 'Illuminate\Support\Facades\Input',
-        'Google2FA'    => 'PragmaRX\Google2FA\Vendor\Laravel\Facade',
+        'App'           => Illuminate\Support\Facades\App::class,
+        'Artisan'       => Illuminate\Support\Facades\Artisan::class,
+        'Auth'          => Illuminate\Support\Facades\Auth::class,
+        'Blade'         => Illuminate\Support\Facades\Blade::class,
+        'Cache'         => Illuminate\Support\Facades\Cache::class,
+        'Config'        => Illuminate\Support\Facades\Config::class,
+        'Cookie'        => Illuminate\Support\Facades\Cookie::class,
+        'Crypt'         => Illuminate\Support\Facades\Crypt::class,
+        'DB'            => Illuminate\Support\Facades\DB::class,
+        'Eloquent'      => Illuminate\Database\Eloquent\Model::class,
+        'Event'         => Illuminate\Support\Facades\Event::class,
+        'File'          => Illuminate\Support\Facades\File::class,
+        'Gate'          => Illuminate\Support\Facades\Gate::class,
+        'Hash'          => Illuminate\Support\Facades\Hash::class,
+        'Lang'          => Illuminate\Support\Facades\Lang::class,
+        'Log'           => Illuminate\Support\Facades\Log::class,
+        'Mail'          => Illuminate\Support\Facades\Mail::class,
+        'Password'      => Illuminate\Support\Facades\Password::class,
+        'Queue'         => Illuminate\Support\Facades\Queue::class,
+        'Redirect'      => Illuminate\Support\Facades\Redirect::class,
+        'Redis'         => Illuminate\Support\Facades\Redis::class,
+        'Request'       => Illuminate\Support\Facades\Request::class,
+        'Response'      => Illuminate\Support\Facades\Response::class,
+        'Route'         => Illuminate\Support\Facades\Route::class,
+        'Schema'        => Illuminate\Support\Facades\Schema::class,
+        'Session'       => Illuminate\Support\Facades\Session::class,
+        'Storage'       => Illuminate\Support\Facades\Storage::class,
+        'URL'           => Illuminate\Support\Facades\URL::class,
+        'Validator'     => Illuminate\Support\Facades\Validator::class,
+        'View'          => Illuminate\Support\Facades\View::class,
+        'Twig'          => 'TwigBridge\Facade\Twig',
+        'Form'          => Collective\Html\FormFacade::class,
+        'Html'          => Collective\Html\HtmlFacade::class,
+        'Breadcrumbs'   => 'DaveJamesMiller\Breadcrumbs\Facade',
+        'Preferences'   => 'FireflyIII\Support\Facades\Preferences',
+        'FireflyConfig' => 'FireflyIII\Support\Facades\FireflyConfig',
+        'Navigation'    => 'FireflyIII\Support\Facades\Navigation',
+        'Amount'        => 'FireflyIII\Support\Facades\Amount',
+        'Steam'         => 'FireflyIII\Support\Facades\Steam',
+        'ExpandedForm'  => 'FireflyIII\Support\Facades\ExpandedForm',
+        'Entrust'       => 'Zizaco\Entrust\EntrustFacade',
+        'Input'         => 'Illuminate\Support\Facades\Input',
+        'Google2FA'     => 'PragmaRX\Google2FA\Vendor\Laravel\Facade',
 
     ],
 
diff --git a/config/csv.php b/config/csv.php
index 0419338367..5644b0f60f 100644
--- a/config/csv.php
+++ b/config/csv.php
@@ -3,195 +3,277 @@ declare(strict_types = 1);
 
 
 return [
-    'specifix'        => [
-        'RabobankDescription',
-        'AbnAmroDescription',
-        'Dummy'
-    ],
-    'post_processors' => [
-        'Description',
-        'Amount',
-        'Currency',
-        'Bill',
-        'OpposingAccount', // must be after Amount!
-        'AssetAccount',
 
+    /*
+     * Configuration for the CSV specifics.
+     */
+    'import_specifics' => [
+        'RabobankDescription' => 'FireflyIII\Import\Specifics\RabobankDescription',
+        'AbnAmroDescription'  => 'FireflyIII\Import\Specifics\AbnAmroDescription',
     ],
-    'roles'           => [
-        '_ignore'           => [
-            'mappable'  => false,
-            'converter' => 'Ignore',
-            'field'     => 'ignored',
+
+    /*
+     * Configuration for possible column roles.
+     *
+     * The key is the short name for the column role. There are five values, which mean this:
+     *
+     * 'mappable'
+     * Whether or not the value in the CSV column can be linked to an existing value in your
+     * Firefly database. For example: account names can be linked to existing account names you have already
+     * so double entries cannot occur. This process is called "mapping". You have to make each unique value in your
+     * CSV file to an existing entry in your database. For example, map all account names in your CSV file to existing
+     * accounts. If you have an entry that does not exist in your database, you can set Firefly to ignore it, and it will
+     * create it.
+     *
+     * 'pre-process-map'
+     * In the case of tags, there are multiple values in one csv column (for example: "expense groceries snack" in one column).
+     * This means the content of the column must be "pre processed" aka split in parts so the importer can work with the data.
+     *
+     * 'pre-process-mapper'
+     * This is the class that will actually do the pre-processing.
+     *
+     * 'field'
+     * I don't believe this value is used any more, but I am not sure.
+     *
+     * 'converter'
+     * The converter is a class in app/Import/Converter that converts the given value into an object Firefly understands.
+     * The CategoryName converter can convert a category name into an actual category. This converter will take a mapping
+     * into account: if you mapped "Groceries" to category "Groceries" the converter will simply return "Groceries" instead of
+     * trying to make a new category also named Groceries.
+     *
+     * 'mapper'
+     * When you map data (see "mappable") you need a list of stuff you can map to. If you say a certain column is mappable
+     * and the column contains "category names", the mapper will be "Category" and it will give you a list of possible categories.
+     * This way the importer always presents you with a valid list of things to map to.
+     *
+     *
+     *
+     */
+    'import_roles'     => [
+        '_ignore'       => [
+            'mappable'        => false,
+            'pre-process-map' => false,
+            'field'           => 'ignored',
+            'converter'       => 'Ignore',
+            'mapper'          => null,
+
+
         ],
-        'bill-id'           => [
-            'mappable'  => false,
-            'field'     => 'bill',
-            'converter' => 'BillId',
-            'mapper'    => 'Bill',
+        'bill-id'       => [
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'field'           => 'bill',
+            'converter'       => 'BillId',
+            'mapper'          => 'Bills',
         ],
-        'bill-name'         => [
-            'mappable'  => true,
-            'converter' => 'BillName',
-            'field'     => 'bill',
-            'mapper'    => 'Bill',
+        'bill-name'     => [
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'field'           => 'bill',
+            'converter'       => 'BillName',
+            'mapper'          => 'Bills',
         ],
-        'currency-id'       => [
-            'mappable'  => true,
-            'converter' => 'CurrencyId',
-            'field'     => 'currency',
-            'mapper'    => 'TransactionCurrency'
+        'currency-id'   => [
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'field'           => 'currency',
+            'converter'       => 'CurrencyId',
+            'mapper'          => 'TransactionCurrencies',
         ],
-        'currency-name'     => [
-            'mappable'  => true,
-            'converter' => 'CurrencyName',
-            'field'     => 'currency',
-            'mapper'    => 'TransactionCurrency'
+        'currency-name' => [
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'converter'       => 'CurrencyName',
+            'field'           => 'currency',
+            'mapper'          => 'TransactionCurrencies',
         ],
-        'currency-code'     => [
-            'mappable'  => true,
-            'converter' => 'CurrencyCode',
-            'field'     => 'currency',
-            'mapper'    => 'TransactionCurrency'
+        'currency-code' => [
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'converter'       => 'CurrencyCode',
+            'field'           => 'currency',
+            'mapper'          => 'TransactionCurrencies',
         ],
+        'external-id'   => [
+            'mappable'        => false,
+            'pre-process-map' => false,
+            'converter'       => 'ExternalId',
+            'field'           => 'external-id',
+        ],
+
         'currency-symbol'   => [
-            'mappable'  => true,
-            'converter' => 'CurrencySymbol',
-            'field'     => 'currency',
-            'mapper'    => 'TransactionCurrency'
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'converter'       => 'CurrencySymbol',
+            'field'           => 'currency',
+            'mapper'          => 'TransactionCurrencies',
         ],
         'description'       => [
-            'mappable'  => false,
-            'converter' => 'Description',
-            'field'     => 'description',
+            'mappable'        => false,
+            'pre-process-map' => false,
+            'converter'       => 'Description',
+            'field'           => 'description',
         ],
         'date-transaction'  => [
-            'mappable'  => false,
-            'converter' => 'Date',
-            'field'     => 'date',
+            'mappable'        => false,
+            'pre-process-map' => false,
+            'converter'       => 'Date',
+            'field'           => 'date',
         ],
-        'date-rent'         => [
-            'mappable'  => false,
-            'converter' => 'Date',
-            'field'     => 'date-rent',
+        'date-interest'     => [
+            'mappable'        => false,
+            'pre-process-map' => false,
+            'converter'       => 'Date',
+            'field'           => 'date-interest',
+        ],
+        'date-book'         => [
+            'mappable'        => false,
+            'pre-process-map' => false,
+            'converter'       => 'Date',
+            'field'           => 'date-book',
+        ],
+        'date-process'      => [
+            'mappable'        => false,
+            'pre-process-map' => false,
+            'converter'       => 'Date',
+            'field'           => 'date-process',
         ],
         'budget-id'         => [
-            'mappable'  => true,
-            'converter' => 'BudgetId',
-            'field'     => 'budget',
-            'mapper'    => 'Budget',
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'converter'       => 'BudgetId',
+            'field'           => 'budget',
+            'mapper'          => 'Budgets',
         ],
         'budget-name'       => [
-            'mappable'  => true,
-            'converter' => 'BudgetName',
-            'field'     => 'budget',
-            'mapper'    => 'Budget',
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'converter'       => 'BudgetName',
+            'field'           => 'budget',
+            'mapper'          => 'Budgets',
         ],
         'rabo-debet-credit' => [
-            'mappable'  => false,
-            'converter' => 'RabobankDebetCredit',
-            'field'     => 'amount-modifier',
+            'mappable'        => false,
+            'pre-process-map' => false,
+            'converter'       => 'RabobankDebetCredit',
+            'field'           => 'amount-modifier',
         ],
-        'ing-debet-credit' => [
-            'mappable'  => false,
-            'converter' => 'INGDebetCredit',
-            'field'     => 'amount-modifier',
+        'ing-debet-credit'  => [
+            'mappable'        => false,
+            'pre-process-map' => false,
+            'converter'       => 'INGDebetCredit',
+            'field'           => 'amount-modifier',
         ],
         'category-id'       => [
-            'mappable'  => true,
-            'converter' => 'CategoryId',
-            'field'     => 'category',
-            'mapper'    => 'Category',
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'converter'       => 'CategoryId',
+            'field'           => 'category',
+            'mapper'          => 'Categories',
         ],
         'category-name'     => [
-            'mappable'  => true,
-            'converter' => 'CategoryName',
-            'field'     => 'category',
-            'mapper'    => 'Category',
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'converter'       => 'CategoryName',
+            'field'           => 'category',
+            'mapper'          => 'Categories',
         ],
         'tags-comma'        => [
-            'mappable'  => true,
-            'field'     => 'tags',
-            'converter' => 'TagsComma',
-            'mapper'    => 'Tag',
+            'mappable'           => true,
+            'pre-process-map'    => true,
+            'pre-process-mapper' => 'TagsComma',
+            'field'              => 'tags',
+            'converter'          => 'TagsComma',
+            'mapper'             => 'Tags',
         ],
         'tags-space'        => [
-            'mappable'  => true,
-            'field'     => 'tags',
-            'converter' => 'TagsSpace',
-            'mapper'    => 'Tag',
+            'mappable'           => true,
+            'pre-process-map'    => true,
+            'pre-process-mapper' => 'TagsSpace',
+            'field'              => 'tags',
+            'converter'          => 'TagsSpace',
+            'mapper'             => 'Tags',
         ],
         'account-id'        => [
-            'mappable'  => true,
-            'mapper'    => 'AssetAccount',
-            'field'     => 'asset-account-id',
-            'converter' => 'AccountId'
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'field'           => 'asset-account-id',
+            'converter'       => 'AccountId',
+            'mapper'          => 'AssetAccounts',
         ],
         'account-name'      => [
-            'mappable'  => true,
-            'mapper'    => 'AssetAccount',
-            'field'     => 'asset-account-name',
-            'converter' => 'AssetAccountName'
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'field'           => 'asset-account-name',
+            'converter'       => 'AssetAccountName',
+            'mapper'          => 'AssetAccounts',
         ],
         'account-iban'      => [
-            'mappable'  => true,
-            'converter' => 'AssetAccountIban',
-            'field'     => 'asset-account-iban',
-            'mapper'    => 'AssetAccount'
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'field'           => 'asset-account-iban',
+            'converter'       => 'AssetAccountIban',
+            'mapper'          => 'AssetAccountIbans',
+
         ],
-        'account-number'      => [
-            'mappable'  => true,
-            'converter' => 'AssetAccountNumber',
-            'field'     => 'asset-account-number',
-            'mapper'    => 'AssetAccount'
+        'account-number'    => [
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'field'           => 'asset-account-number',
+            'converter'       => 'AssetAccountNumber',
+            'mapper'          => 'AssetAccounts',
         ],
         'opposing-id'       => [
-            'mappable'  => true,
-            'field'     => 'opposing-account-id',
-            'converter' => 'OpposingAccountId',
-            'mapper'    => 'AnyAccount',
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'field'           => 'opposing-account-id',
+            'converter'       => 'AccountId',
+            'mapper'          => 'OpposingAccounts',
         ],
         'opposing-name'     => [
-            'mappable'  => true,
-            'field'     => 'opposing-account-name',
-            'converter' => 'OpposingAccountName',
-            'mapper'    => 'AnyAccount',
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'field'           => 'opposing-account-name',
+            'converter'       => 'OpposingAccountName',
+            'mapper'          => 'OpposingAccounts',
         ],
         'opposing-iban'     => [
-            'mappable'  => true,
-            'field'     => 'opposing-account-iban',
-            'converter' => 'OpposingAccountIban',
-            'mapper'    => 'AnyAccount',
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'field'           => 'opposing-account-iban',
+            'converter'       => 'OpposingAccountIban',
+            'mapper'          => 'OpposingAccountIbans',
         ],
-        'opposing-number'     => [
-            'mappable'  => true,
-            'field'     => 'opposing-account-number',
-            'converter' => 'OpposingAccountNumber',
-            'mapper'    => 'AnyAccount',
+        'opposing-number'   => [
+            'mappable'        => true,
+            'pre-process-map' => false,
+            'field'           => 'opposing-account-number',
+            'converter'       => 'OpposingAccountNumber',
+            'mapper'          => 'OpposingAccounts',
         ],
         'amount'            => [
-            'mappable'  => false,
-            'converter' => 'Amount',
-            'field'     => 'amount',
-        ],
-        'amount-comma-separated' => [
-            'mappable'  => false,
-            'converter' => 'AmountComma',
-            'field'     => 'amount',
+            'mappable'        => false,
+            'pre-process-map' => false,
+            'converter'       => 'Amount',
+            'field'           => 'amount',
         ],
         'sepa-ct-id'        => [
-            'mappable'  => false,
-            'converter' => 'Description',
-            'field'     => 'description',
+            'mappable'        => false,
+            'pre-process-map' => false,
+            'converter'       => 'Description',
+            'field'           => 'description',
         ],
         'sepa-ct-op'        => [
-            'mappable'  => false,
-            'converter' => 'Description',
-            'field'     => 'description',
+            'mappable'        => false,
+            'pre-process-map' => false,
+            'converter'       => 'Description',
+            'field'           => 'description',
         ],
         'sepa-db'           => [
-            'mappable'  => false,
-            'converter' => 'Description',
-            'field'     => 'description',
+            'mappable'        => false,
+            'pre-process-map' => false,
+            'converter'       => 'Description',
+            'field'           => 'description',
         ],
-    ]
+    ],
 ];
diff --git a/config/firefly.php b/config/firefly.php
index 78a1b62634..8e0587da2a 100644
--- a/config/firefly.php
+++ b/config/firefly.php
@@ -4,23 +4,21 @@ declare(strict_types = 1);
 
 return [
     'chart'               => 'chartjs',
-    'version'             => '3.9.1',
+    'version'             => '3.10',
     'csv_import_enabled'  => true,
     'maxUploadSize'       => 5242880,
     'allowedMimes'        => ['image/png', 'image/jpeg', 'application/pdf'],
     'resend_confirmation' => 3600,
     'confirmation_age'    => 14400, // four hours
 
-    'export_formats' => [
+    'export_formats'        => [
         'csv' => 'FireflyIII\Export\Exporter\CsvExporter',
         // mt940 FireflyIII Export Exporter MtExporter
     ],
-    'import_formats' => [
+    'import_formats'        => [
         'csv' => 'FireflyIII\Import\Importer\CsvImporter',
         // mt940 FireflyIII Import Importer MtImporter
     ],
-
-
     'default_export_format' => 'csv',
     'default_import_format' => 'csv',
     'bill_periods'          => ['weekly', 'monthly', 'quarterly', 'half-year', 'yearly'],
@@ -62,12 +60,15 @@ return [
             'Beneficiary account' => 'fa-shopping-cart',
             'revenue'             => 'fa-download',
             'Revenue account'     => 'fa-download',
+            'import'              => 'fa-download',
+            'Import account'      => 'fa-download',
         ],
     'accountTypesByIdentifier' =>
         [
             'asset'   => ['Default account', 'Asset account'],
             'expense' => ['Expense account', 'Beneficiary account'],
             'revenue' => ['Revenue account'],
+            'import'  => ['Import account'],
         ],
     'accountTypeByIdentifier'  =>
         [
@@ -76,11 +77,13 @@ return [
             'revenue' => 'Revenue account',
             'opening' => 'Initial balance account',
             'initial' => 'Initial balance account',
+            'import'  => 'Import account',
         ],
     'shortNamesByFullName'     =>
         [
             'Default account'     => 'asset',
             'Asset account'       => 'asset',
+            'Import account'      => 'import',
             'Expense account'     => 'expense',
             'Beneficiary account' => 'expense',
             'Revenue account'     => 'revenue',
@@ -91,6 +94,8 @@ return [
         'nl_NL' => ['name_locale' => 'Nederlands', 'name_english' => 'Dutch', 'complete' => true],
         'pt_BR' => ['name_locale' => 'Português do Brasil', 'name_english' => 'Portuguese (Brazil)', 'complete' => true],
         'fr_FR' => ['name_locale' => 'Français', 'name_english' => 'French', 'complete' => false],
+        'zh-HK' => ['name_locale' => 'Chinese Traditional, Hong Kong', 'name_english' => 'Chinese Traditional, Hong Kong', 'complete' => false],
+        'zh-TW' => ['name_locale' => 'Chinese Traditional', 'name_english' => 'Chinese Traditional', 'complete' => false],
     ],
     'transactionTypesByWhat'   => [
         'expenses'   => ['Withdrawal'],
@@ -126,6 +131,7 @@ return [
         'rule'              => 'FireflyIII\Models\Rule',
         'ruleGroup'         => 'FireflyIII\Models\RuleGroup',
         'jobKey'            => 'FireflyIII\Models\ExportJob',
+        'importJob'         => 'FireflyIII\Models\ImportJob',
         // lists
         'accountList'       => 'FireflyIII\Support\Binder\AccountList',
         'budgetList'        => 'FireflyIII\Support\Binder\BudgetList',
diff --git a/config/twigbridge.php b/config/twigbridge.php
index 2064bbf643..586f7f047e 100644
--- a/config/twigbridge.php
+++ b/config/twigbridge.php
@@ -142,6 +142,7 @@ return [
             'Route',
             'Auth',
             'Lang',
+            'Preferences',
             'URL',
             'Config',
             'ExpandedForm' => [
diff --git a/config/upgrade.php b/config/upgrade.php
index 27059b92db..d12d96b1c3 100644
--- a/config/upgrade.php
+++ b/config/upgrade.php
@@ -27,5 +27,6 @@ return [
                      'Please follow the instructions on the following page: https://github.com/JC5/firefly-iii/wiki/Upgrade-to-3.7.0',
         '3.8.0'   => 'This version of Firefly III requires PHP 7.0.',
         '3.8.1'   => 'This version of Firefly III requires PHP 7.0.',
+        '3.10' => 'Please find the full upgrade instructions here: https://github.com/JC5/firefly-iii/wiki/Upgrade-to-3.10'
     ],
 ];
diff --git a/database/migrations/2014_06_27_163032_create_users_table.php b/database/migrations/2014_06_27_163032_create_users_table.php
deleted file mode 100644
index 57f44c51cd..0000000000
--- a/database/migrations/2014_06_27_163032_create_users_table.php
+++ /dev/null
@@ -1,46 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->string('email', 100)->unique();
-            $table->string('password', 60);
-            $table->rememberToken();
-            $table->string('reset', 32)->nullable();
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_06_27_163145_create_account_types_table.php b/database/migrations/2014_06_27_163145_create_account_types_table.php
deleted file mode 100644
index 85b0742038..0000000000
--- a/database/migrations/2014_06_27_163145_create_account_types_table.php
+++ /dev/null
@@ -1,47 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->string('type', 30);
-            $table->boolean('editable');
-
-            $table->unique('type');
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_06_27_163259_create_accounts_table.php b/database/migrations/2014_06_27_163259_create_accounts_table.php
deleted file mode 100644
index 972bf66fcb..0000000000
--- a/database/migrations/2014_06_27_163259_create_accounts_table.php
+++ /dev/null
@@ -1,57 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->softDeletes();
-            $table->integer('user_id')->unsigned();
-            $table->integer('account_type_id')->unsigned();
-            $table->string('name', 100);
-            $table->boolean('active');
-
-            // connect accounts to users
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-
-            // connect accounts to account_types
-            $table->foreign('account_type_id')->references('id')->on('account_types')->onDelete('cascade');
-
-            // for a user, the account name must be unique.
-            $table->unique(['user_id', 'account_type_id', 'name']);
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_06_27_163817_create_components_table.php b/database/migrations/2014_06_27_163817_create_components_table.php
deleted file mode 100644
index 795f14685f..0000000000
--- a/database/migrations/2014_06_27_163817_create_components_table.php
+++ /dev/null
@@ -1,54 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->softDeletes();
-            $table->string('name', 50);
-            $table->integer('user_id')->unsigned();
-            $table->string('class', 20);
-
-            // connect components to users
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-
-            // for a user, the component type & name must be unique.
-            $table->unique(['user_id', 'class', 'name']);
-        }
-        );
-
-    }
-
-}
diff --git a/database/migrations/2014_06_27_163818_create_piggybanks_table.php b/database/migrations/2014_06_27_163818_create_piggybanks_table.php
deleted file mode 100644
index cffda131c9..0000000000
--- a/database/migrations/2014_06_27_163818_create_piggybanks_table.php
+++ /dev/null
@@ -1,63 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->integer('account_id')->unsigned();
-            $table->string('name', 100);
-            $table->decimal('targetamount', 10, 2);
-            $table->date('startdate')->nullable();
-            $table->date('targetdate')->nullable();
-            $table->boolean('repeats');
-            $table->enum('rep_length', ['day', 'week', 'quarter', 'month', 'year'])->nullable();
-            $table->smallInteger('rep_every')->unsigned();
-            $table->smallInteger('rep_times')->unsigned()->nullable();
-            $table->enum('reminder', ['day', 'week', 'quarter', 'month', 'year'])->nullable();
-            $table->smallInteger('reminder_skip')->unsigned();
-            $table->boolean('remind_me');
-            $table->integer('order')->unsigned();
-
-            // connect account to piggy bank.
-            $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
-
-            // for an account, the name must be unique.
-            $table->unique(['account_id', 'name']);
-
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_06_27_164042_create_transaction_currencies_table.php b/database/migrations/2014_06_27_164042_create_transaction_currencies_table.php
deleted file mode 100644
index 4c0f9b7ef0..0000000000
--- a/database/migrations/2014_06_27_164042_create_transaction_currencies_table.php
+++ /dev/null
@@ -1,48 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->softDeletes();
-            $table->string('code', 3);
-
-            // code must be unique.
-            $table->unique(['code']);
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_06_27_164512_create_transaction_types_table.php b/database/migrations/2014_06_27_164512_create_transaction_types_table.php
deleted file mode 100644
index 46d82089c0..0000000000
--- a/database/migrations/2014_06_27_164512_create_transaction_types_table.php
+++ /dev/null
@@ -1,48 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->softDeletes();
-            $table->string('type', 50);
-
-            // type must be unique.
-            $table->unique(['type']);
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_06_27_164619_create_recurring_transactions_table.php b/database/migrations/2014_06_27_164619_create_recurring_transactions_table.php
deleted file mode 100644
index 1b6e637279..0000000000
--- a/database/migrations/2014_06_27_164619_create_recurring_transactions_table.php
+++ /dev/null
@@ -1,62 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->integer('user_id')->unsigned();
-            $table->string('name', 50);
-            $table->string('match', 255);
-            $table->decimal('amount_min', 10, 2);
-            $table->decimal('amount_max', 10, 2);
-            $table->date('date');
-            $table->boolean('active');
-
-            $table->boolean('automatch');
-            $table->enum('repeat_freq', ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly']);
-            $table->smallInteger('skip')->unsigned();
-
-            // connect user id to users
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-
-            // for a user, the name must be unique
-            $table->unique(['user_id', 'name']);
-
-
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_06_27_164620_create_transaction_journals_table.php b/database/migrations/2014_06_27_164620_create_transaction_journals_table.php
deleted file mode 100644
index fdb56228b1..0000000000
--- a/database/migrations/2014_06_27_164620_create_transaction_journals_table.php
+++ /dev/null
@@ -1,65 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->softDeletes();
-            $table->integer('user_id')->unsigned();
-            $table->integer('transaction_type_id')->unsigned();
-            $table->integer('recurring_transaction_id')->unsigned()->nullable();
-            $table->integer('transaction_currency_id')->unsigned();
-            $table->string('description', 255)->nullable();
-            $table->boolean('completed');
-            $table->date('date');
-
-            // connect users
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-
-            // connect transaction journals to transaction types
-            $table->foreign('transaction_type_id')->references('id')->on('transaction_types')->onDelete('cascade');
-
-            // connect transaction journals to recurring transactions
-            $table->foreign('recurring_transaction_id')->references('id')->on('recurring_transactions')->onDelete('set null');
-
-            // connect transaction journals to transaction currencies
-            $table->foreign('transaction_currency_id')->references('id')->on('transaction_currencies')->onDelete('cascade');
-
-
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_06_27_164836_create_transactions_table.php b/database/migrations/2014_06_27_164836_create_transactions_table.php
deleted file mode 100644
index 0ce8e2adab..0000000000
--- a/database/migrations/2014_06_27_164836_create_transactions_table.php
+++ /dev/null
@@ -1,60 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->softDeletes();
-            $table->integer('account_id')->unsigned();
-            $table->integer('piggybank_id')->nullable()->unsigned();
-            $table->integer('transaction_journal_id')->unsigned();
-            $table->string('description', 255)->nullable();
-            $table->decimal('amount', 10, 2);
-
-            // connect account id:
-            $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
-
-            // connect piggy banks
-            $table->foreign('piggybank_id')->references('id')->on('piggybanks')->onDelete('set null');
-
-            // connect transactions to transaction journals
-            $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
-
-
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_06_27_165344_create_component_transaction_table.php b/database/migrations/2014_06_27_165344_create_component_transaction_table.php
deleted file mode 100644
index 8d76199427..0000000000
--- a/database/migrations/2014_06_27_165344_create_component_transaction_table.php
+++ /dev/null
@@ -1,53 +0,0 @@
-increments('id');
-            $table->integer('component_id')->unsigned();
-            $table->integer('transaction_id')->unsigned();
-
-            // connect to components
-            $table->foreign('component_id')->references('id')->on('components')->onDelete('cascade');
-
-            // connect to transactions
-            $table->foreign('transaction_id')->references('id')->on('transactions')->onDelete('cascade');
-
-            // combo must be unique:
-            $table->unique(['component_id', 'transaction_id']);
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_07_05_171326_create_component_transaction_journal_table.php b/database/migrations/2014_07_05_171326_create_component_transaction_journal_table.php
deleted file mode 100644
index 06b2a89b4a..0000000000
--- a/database/migrations/2014_07_05_171326_create_component_transaction_journal_table.php
+++ /dev/null
@@ -1,52 +0,0 @@
-increments('id');
-            $table->integer('component_id')->unsigned();
-            $table->integer('transaction_journal_id')->unsigned();
-
-            // link components with component_id
-            $table->foreign('component_id')->references('id')->on('components')->onDelete('cascade');
-
-            // link transaction journals with transaction_journal_id
-            $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
-
-            // combo must be unique:
-            $table->unique(['component_id', 'transaction_journal_id'], 'cid_tjid_unique');
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_07_06_123842_create_preferences_table.php b/database/migrations/2014_07_06_123842_create_preferences_table.php
deleted file mode 100644
index a71f0205a4..0000000000
--- a/database/migrations/2014_07_06_123842_create_preferences_table.php
+++ /dev/null
@@ -1,52 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->integer('user_id')->unsigned();
-            $table->string('name');
-            $table->text('data');
-
-            // connect preferences to users
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-
-            // only one preference per name per user
-            $table->unique(['user_id', 'name']);
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_07_09_204843_create_session_table.php b/database/migrations/2014_07_09_204843_create_session_table.php
deleted file mode 100644
index 08a9a98f75..0000000000
--- a/database/migrations/2014_07_09_204843_create_session_table.php
+++ /dev/null
@@ -1,47 +0,0 @@
-string('id')->unique();
-            $table->integer('user_id')->nullable();
-            $table->string('ip_address', 45)->nullable();
-            $table->text('user_agent')->nullable();
-            $table->text('payload');
-            $table->integer('last_activity');
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_07_17_183717_create_limits_table.php b/database/migrations/2014_07_17_183717_create_limits_table.php
deleted file mode 100644
index d94065e832..0000000000
--- a/database/migrations/2014_07_17_183717_create_limits_table.php
+++ /dev/null
@@ -1,54 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->integer('component_id')->unsigned();
-            $table->date('startdate');
-            $table->decimal('amount', 10, 2);
-            $table->boolean('repeats');
-            $table->enum('repeat_freq', ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly']);
-
-            $table->unique(['component_id', 'startdate', 'repeat_freq'], 'unique_ci_combi');
-
-            // connect component
-            $table->foreign('component_id')->references('id')->on('components')->onDelete('cascade');
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_07_19_055011_create_limit_repeat_table.php b/database/migrations/2014_07_19_055011_create_limit_repeat_table.php
deleted file mode 100644
index 83a655c5a0..0000000000
--- a/database/migrations/2014_07_19_055011_create_limit_repeat_table.php
+++ /dev/null
@@ -1,52 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->integer('limit_id')->unsigned();
-            $table->date('startdate');
-            $table->date('enddate');
-            $table->decimal('amount', 10, 2);
-
-            $table->unique(['limit_id', 'startdate', 'enddate']);
-
-            // connect limit
-            $table->foreign('limit_id')->references('id')->on('limits')->onDelete('cascade');
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_08_06_044416_create_component_recurring_transaction_table.php b/database/migrations/2014_08_06_044416_create_component_recurring_transaction_table.php
deleted file mode 100644
index 21d0b8b6c3..0000000000
--- a/database/migrations/2014_08_06_044416_create_component_recurring_transaction_table.php
+++ /dev/null
@@ -1,55 +0,0 @@
-increments('id');
-            $table->integer('component_id')->unsigned();
-            $table->integer('recurring_transaction_id')->unsigned();
-            $table->boolean('optional');
-
-            // link components with component_id
-            $table->foreign('component_id')->references('id')->on('components')->onDelete('cascade');
-
-            // link transaction journals with transaction_journal_id
-            $table->foreign('recurring_transaction_id')->references('id')->on('recurring_transactions')->onDelete('cascade');
-
-            // component and recurring transaction must be unique.
-            $table->unique(['component_id', 'recurring_transaction_id'], 'cid_rtid_unique');
-
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_08_12_173919_create_piggybank_repetitions_table.php b/database/migrations/2014_08_12_173919_create_piggybank_repetitions_table.php
deleted file mode 100644
index e8dfda76b6..0000000000
--- a/database/migrations/2014_08_12_173919_create_piggybank_repetitions_table.php
+++ /dev/null
@@ -1,52 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->integer('piggybank_id')->unsigned();
-            $table->date('startdate')->nullable();
-            $table->date('targetdate')->nullable();
-            $table->decimal('currentamount', 10, 2);
-
-            $table->unique(['piggybank_id', 'startdate', 'targetdate']);
-
-            // connect instance to piggybank.
-            $table->foreign('piggybank_id')->references('id')->on('piggybanks')->onDelete('cascade');
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_08_18_100330_create_piggybank_events_table.php b/database/migrations/2014_08_18_100330_create_piggybank_events_table.php
deleted file mode 100644
index 54f57e90aa..0000000000
--- a/database/migrations/2014_08_18_100330_create_piggybank_events_table.php
+++ /dev/null
@@ -1,54 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->integer('piggybank_id')->unsigned();
-            $table->integer('transaction_journal_id')->unsigned()->nullable();
-
-            $table->date('date');
-            $table->decimal('amount', 10, 2);
-
-            // connect instance to piggybank.
-            $table->foreign('piggybank_id')->references('id')->on('piggybanks')->onDelete('cascade');
-
-            // connect to journal:
-            $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('set null');
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_08_23_113221_create_reminders_table.php b/database/migrations/2014_08_23_113221_create_reminders_table.php
deleted file mode 100644
index a7d769a2fc..0000000000
--- a/database/migrations/2014_08_23_113221_create_reminders_table.php
+++ /dev/null
@@ -1,53 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->integer('user_id')->unsigned();
-            $table->date('startdate');
-            $table->date('enddate')->nullable();
-            $table->boolean('active');
-            $table->boolean('notnow')->default(0);
-            $table->integer('remindersable_id')->unsigned()->nullable();
-            $table->string('remindersable_type')->nullable();
-
-            // connect reminders to users
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_10_12_100000_create_password_resets_table.php b/database/migrations/2014_10_12_100000_create_password_resets_table.php
deleted file mode 100644
index c9da2ac1cc..0000000000
--- a/database/migrations/2014_10_12_100000_create_password_resets_table.php
+++ /dev/null
@@ -1,42 +0,0 @@
-string('email')->index();
-            $table->string('token')->index();
-            $table->timestamp('created_at');
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_11_10_172053_create_account_meta_table.php b/database/migrations/2014_11_10_172053_create_account_meta_table.php
deleted file mode 100644
index 044d1e28e6..0000000000
--- a/database/migrations/2014_11_10_172053_create_account_meta_table.php
+++ /dev/null
@@ -1,53 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->integer('account_id')->unsigned();
-            $table->string('name');
-            $table->text('data');
-
-            $table->unique(['account_id', 'name']);
-
-            // link to account!
-            $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
-
-
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_11_29_135749_create_transaction_groups_table.php b/database/migrations/2014_11_29_135749_create_transaction_groups_table.php
deleted file mode 100644
index a312a3d7d9..0000000000
--- a/database/migrations/2014_11_29_135749_create_transaction_groups_table.php
+++ /dev/null
@@ -1,50 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->softDeletes();
-            $table->integer('user_id')->unsigned();
-            $table->enum('relation', ['balance']);
-
-            // connect groups to users
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-        }
-        );
-
-
-    }
-
-}
diff --git a/database/migrations/2014_11_29_140217_create_transaction_group_transaction_journal_table.php b/database/migrations/2014_11_29_140217_create_transaction_group_transaction_journal_table.php
deleted file mode 100644
index b615d7b102..0000000000
--- a/database/migrations/2014_11_29_140217_create_transaction_group_transaction_journal_table.php
+++ /dev/null
@@ -1,51 +0,0 @@
-increments('id');
-            $table->integer('transaction_group_id')->unsigned();
-            $table->integer('transaction_journal_id')->unsigned();
-
-            // link to foreign tables.
-            $table->foreign('transaction_group_id', 'tr_grp_id')->references('id')->on('transaction_groups')->onDelete('cascade');
-            $table->foreign('transaction_journal_id', 'tr_trj_id')->references('id')->on('transaction_journals')->onDelete('cascade');
-
-            // add unique.
-            $table->unique(['transaction_group_id', 'transaction_journal_id'], 'tt_joined');
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2014_12_13_190730_changes_for_v321.php b/database/migrations/2014_12_13_190730_changes_for_v321.php
deleted file mode 100644
index 13b4715fcc..0000000000
--- a/database/migrations/2014_12_13_190730_changes_for_v321.php
+++ /dev/null
@@ -1,502 +0,0 @@
-moveBudgetsBack(); // 1.
-        $this->moveCategoriesBack(); // 2.
-        $this->createComponentId(); // 3.
-        $this->updateComponentInBudgetLimits(); // 4.
-        $this->createComponentIdForeignKey(); // 5.
-        $this->dropBudgetIdColumnInBudgetLimits(); // 6.
-        $createComponents = new CreateComponentTransactionJournalTable;  // 7.
-        $createComponents->up();
-        $this->moveBackEntriesForBudgetsInJoinedTable(); // 8.
-        $this->moveBackEntriesForCategoriesInJoinedTable(); // 9.
-        $this->dropBudgetJournalTable(); // 10.
-        $this->dropCategoryJournalTable(); // 11.
-        $this->dropBudgetTable(); // 12.
-        $this->dropCategoryTable(); // 13.
-        $this->renameBudgetLimits(); // 14.
-        $this->renamePiggyBankEvents(); // 15.
-        $this->renameBudgetLimitToBudgetInRepetitions(); // 16.
-        // 17 and then 18 and then 19
-        $this->dropFieldsFromCurrencyTable(); // 20.
-
-
-    }
-
-    /**
-     * Run the migrations.
-     *
-     * @return void
-     */
-    public function up()
-    {
-        $this->createBudgetTable(); // 1.
-        $this->createCategoryTable(); // 2.
-        $this->createBudgetJournalTable(); // 3
-        $this->createCategoryJournalTable(); // 4.
-        $this->moveBudgets(); // 5.
-        $this->moveCategories(); // 6.
-        $this->correctNameForBudgetLimits(); // 7.
-        $this->correctNameForPiggyBankEvents(); // 8.
-        $this->renameBudgetToBudgetLimitInRepetitions(); // 9.
-        $this->addBudgetIdFieldToBudgetLimits(); // 10.
-        $this->moveComponentIdToBudgetId(); // 11.
-        $this->dropComponentJournalTable(); // 12.
-        $this->dropComponentRecurringTransactionTable(); // 13.
-        $this->dropComponentTransactionTable(); // 14.
-        $this->dropPiggyBankIdFromTransactions(); // 15.
-        $this->dropComponentIdFromBudgetLimits(); // 16.
-        $this->expandCurrencyTable(); // 17.
-
-    }
-
-    private function addBudgetIdFieldToBudgetLimits()
-    {
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->integer('budget_id', false, true)->nullable()->after('updated_at');
-            $table->foreign('budget_id', 'bid_foreign')->references('id')->on('budgets')->onDelete('cascade');
-        }
-        );
-    }
-
-    private function correctNameForBudgetLimits()
-    {
-        Schema::rename('limits', 'budget_limits');
-    }
-
-    private function correctNameForPiggyBankEvents()
-    {
-        Schema::rename('piggybank_events', 'piggy_bank_events');
-
-    }
-
-    private function createBudgetJournalTable()
-    {
-        Schema::create(
-            'budget_transaction_journal', function (Blueprint $table) {
-            $table->increments('id');
-            $table->integer('budget_id')->unsigned();
-            $table->integer('transaction_journal_id')->unsigned();
-            $table->foreign('budget_id')->references('id')->on('budgets')->onDelete('cascade');
-            $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
-            $table->unique(['budget_id', 'transaction_journal_id'], 'budid_tjid_unique');
-        }
-        );
-    }
-
-    private function createBudgetTable()
-    {
-        Schema::create(
-            'budgets', function (Blueprint $table) {
-            $table->increments('id');
-            $table->timestamps();
-            $table->softDeletes();
-            $table->string('name', 50);
-            $table->integer('user_id')->unsigned();
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-            $table->unique(['user_id', 'name']);
-        }
-        );
-
-
-    }
-
-    private function createCategoryJournalTable()
-    {
-        Schema::create(
-            'category_transaction_journal', function (Blueprint $table) {
-            $table->increments('id');
-            $table->integer('category_id')->unsigned();
-            $table->integer('transaction_journal_id')->unsigned();
-            $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
-            $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
-            $table->unique(['category_id', 'transaction_journal_id'], 'catid_tjid_unique');
-        }
-        );
-    }
-
-    private function createCategoryTable()
-    {
-        Schema::create(
-            'categories', function (Blueprint $table) {
-            $table->increments('id');
-            $table->timestamps();
-            $table->softDeletes();
-            $table->string('name', 50);
-            $table->integer('user_id')->unsigned();
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-            $table->unique(['user_id', 'name']);
-        }
-        );
-    }
-
-    private function createComponentId()
-    {
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->integer('component_id')->unsigned();
-        }
-        );
-    }
-
-    private function createComponentIdForeignKey()
-    {
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->foreign('component_id', 'limits_component_id_foreign')->references('id')->on('components')->onDelete('cascade');
-        }
-        );
-    }
-
-    private function dropBudgetIdColumnInBudgetLimits()
-    {
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->dropForeign('bid_foreign');
-            $table->dropColumn('budget_id'); // also drop foreign key!
-        }
-        );
-    }
-
-    private function dropBudgetJournalTable()
-    {
-        Schema::dropIfExists('budget_transaction_journal');
-    }
-
-    private function dropBudgetTable()
-    {
-        Schema::dropIfExists('budgets');
-    }
-
-    private function dropCategoryJournalTable()
-    {
-        Schema::dropIfExists('category_transaction_journal');
-    }
-
-    private function dropCategoryTable()
-    {
-        Schema::dropIfExists('categories');
-    }
-
-    private function dropComponentIdFromBudgetLimits()
-    {
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->dropForeign('limits_component_id_foreign');
-            $table->dropColumn('component_id');
-        }
-        );
-    }
-
-    private function dropComponentJournalTable()
-    {
-        Schema::dropIfExists('component_transaction_journal');
-    }
-
-    private function dropComponentRecurringTransactionTable()
-    {
-        Schema::dropIfExists('component_recurring_transaction');
-    }
-
-    private function dropComponentTransactionTable()
-    {
-        Schema::dropIfExists('component_transaction');
-    }
-
-    private function dropFieldsFromCurrencyTable()
-    {
-
-        Schema::table(
-            'transaction_currencies', function (Blueprint $table) {
-            $table->dropColumn('symbol');
-            $table->dropColumn('name');
-        }
-        );
-    }
-
-    private function dropPiggyBankIdFromTransactions()
-    {
-
-        Schema::table(
-            'transactions', function (Blueprint $table) {
-            if (Schema::hasColumn('transactions', 'piggybank_id')) {
-                $table->dropForeign('transactions_piggybank_id_foreign');
-                $table->dropColumn('piggybank_id');
-            }
-        }
-        );
-    }
-
-    private function expandCurrencyTable()
-    {
-        Schema::table(
-            'transaction_currencies', function (Blueprint $table) {
-            $table->string('name', 48)->nullable();
-            $table->string('symbol', 8)->nullable();
-        }
-        );
-        \DB::update('UPDATE `transaction_currencies` SET `symbol` = "€", `name` = "Euro" WHERE `code` = "EUR";');
-    }
-
-    private function moveBackEntriesForBudgetsInJoinedTable()
-    {
-        $set = DB::table('budget_transaction_journal')->get();
-        /** @var \stdClass $entry */
-        foreach ($set as $entry) {
-            $budget = Budget::find($entry->budget_id);
-            if ($budget) {
-                /** @var \FireflyIII\Models\Component $component */
-                $component = Component::where('class', 'Budget')->where('name', $budget->name)->where('user_id', $budget->user_id)->first();
-                if ($component) {
-                    DB::table('component_transaction_journal')->insert(
-                        [
-                            'component_id'           => $component->id,
-                            'transaction_journal_id' => $entry->transaction_journal_id,
-                        ]
-                    );
-                }
-
-            }
-        }
-
-    }
-
-    private function moveBackEntriesForCategoriesInJoinedTable()
-    {
-        $set = DB::table('category_transaction_journal')->get();
-        /** @var \stdClass $entry */
-        foreach ($set as $entry) {
-            $category = Category::find($entry->category_id);
-            if ($category) {
-                /** @var \FireflyIII\Models\Component $component */
-                $component = Component::where('class', 'Category')->where('name', $category->name)->where('user_id', $category->user_id)->first();
-                if ($component) {
-                    DB::table('component_transaction_journal')->insert(
-                        [
-                            'component_id'           => $component->id,
-                            'transaction_journal_id' => $entry->transaction_journal_id,
-                        ]
-                    );
-                }
-
-            }
-        }
-
-    }
-
-    private function moveBudgets()
-    {
-        Component::where('class', 'Budget')->get()->each(
-            function (Component $c) {
-                $entry  = [
-                    'user_id' => $c->user_id,
-                    'name'    => $c->name,
-
-                ];
-                $budget = Budget::firstOrCreate($entry);
-                // create entry in budget_transaction_journal
-                $connections = DB::table('component_transaction_journal')->where('component_id', $c->id)->get();
-                /** @var \stdClass $connection */
-                foreach ($connections as $connection) {
-                    DB::table('budget_transaction_journal')->insert(
-                        [
-                            'budget_id'              => $budget->id,
-                            'transaction_journal_id' => $connection->transaction_journal_id,
-                        ]
-                    );
-                }
-            }
-        );
-    }
-
-    private function moveBudgetsBack()
-    {
-        Budget::get()->each(
-            function (Budget $budget) {
-                Component::firstOrCreate(
-                    [
-                        'name'    => $budget->name,
-                        'user_id' => $budget->user_id,
-                        'class'   => 'Budget',
-                    ]
-                );
-            }
-        );
-    }
-
-    private function moveCategories()
-    {
-        Component::where('class', 'Category')->get()->each(
-            function (Component $c) {
-                $entry    = [
-                    'user_id' => $c->user_id,
-                    'name'    => $c->name,
-
-                ];
-                $category = Category::firstOrCreate($entry);
-                // create entry in category_transaction_journal
-                $connections = DB::table('component_transaction_journal')->where('component_id', $c->id)->get();
-                /** @var \stdClass $connection */
-                foreach ($connections as $connection) {
-                    DB::table('category_transaction_journal')->insert(
-                        [
-                            'category_id'            => $category->id,
-                            'transaction_journal_id' => $connection->transaction_journal_id,
-                        ]
-                    );
-                }
-            }
-        );
-    }
-
-    private function moveCategoriesBack()
-    {
-        Category::get()->each(
-            function (Category $category) {
-                Component::firstOrCreate(
-                    [
-                        'name'    => $category->name,
-                        'user_id' => $category->user_id,
-                        'class'   => 'Category',
-                    ]
-                );
-            }
-        );
-    }
-
-    private function moveComponentIdToBudgetId()
-    {
-        BudgetLimit::get()->each(
-            function (BudgetLimit $bl) {
-                $component = Component::find($bl->component_id);
-                if ($component) {
-                    $budget = Budget::whereName($component->name)->whereUserId($component->user_id)->first();
-                    if ($budget) {
-                        $bl->budget_id = $budget->id;
-                        $bl->save();
-                    }
-                }
-            }
-        );
-
-    }
-
-    private function renameBudgetLimitToBudgetInRepetitions()
-    {
-        Schema::table(
-            'limit_repetitions', function (Blueprint $table) {
-            $table->dropForeign('limit_repetitions_budget_limit_id_foreign');
-            $table->renameColumn('budget_limit_id', 'limit_id');
-            $table->foreign('limit_id')->references('id')->on('limits')->onDelete('cascade');
-        }
-        );
-    }
-
-    private function renameBudgetLimits()
-    {
-        Schema::rename('budget_limits', 'limits');
-    }
-
-    private function renameBudgetToBudgetLimitInRepetitions()
-    {
-        Schema::table(
-            'limit_repetitions', function (Blueprint $table) {
-            $table->dropForeign('limit_repetitions_limit_id_foreign');
-            $table->renameColumn('limit_id', 'budget_limit_id');
-            $table->foreign('budget_limit_id')->references('id')->on('budget_limits')->onDelete('cascade');
-        }
-        );
-    }
-
-    private function renamePiggyBankEvents()
-    {
-        Schema::rename('piggy_bank_events', 'piggybank_events');
-
-    }
-
-    private function updateComponentInBudgetLimits()
-    {
-        BudgetLimit::get()->each(
-            function (BudgetLimit $bl) {
-                $budgetId = $bl->budget_id;
-                $budget   = Budget::find($budgetId);
-                if ($budget) {
-                    $component = Component::where('class', 'Budget')->where('user_id', $budget->user_id)->where('name', $budget->name)->first();
-                    if ($component) {
-                        $bl->component_id = $component->id;
-                        $bl->save();
-                    }
-                }
-            }
-        );
-    }
-
-
-}
diff --git a/database/migrations/2014_12_24_191544_changes_for_v322.php b/database/migrations/2014_12_24_191544_changes_for_v322.php
deleted file mode 100644
index 5cd658dc5c..0000000000
--- a/database/migrations/2014_12_24_191544_changes_for_v322.php
+++ /dev/null
@@ -1,182 +0,0 @@
-dropForeign('piggy_bank_events_piggy_bank_id_foreign');
-            $table->renameColumn('piggy_bank_id', 'piggybank_id');
-            $table->foreign('piggybank_id')->references('id')->on('piggybanks')->onDelete('cascade');
-        }
-        );
-
-        Schema::table(
-            'piggybank_repetitions', function (Blueprint $table) {
-            $table->dropForeign('piggy_bank_repetitions_piggy_bank_id_foreign');
-            $table->renameColumn('piggy_bank_id', 'piggybank_id');
-            $table->foreign('piggybank_id')->references('id')->on('piggybanks')->onDelete('cascade');
-        }
-        );
-
-        // remove soft delete to piggy banks
-        Schema::table(
-            'piggybanks', function (Blueprint $table) {
-            $table->dropSoftDeletes();
-        }
-        );
-
-        // drop keys from bills (foreign bills_uid_for and unique uid_name_unique)
-        Schema::table(
-            'bills', function (Blueprint $table) {
-            $table->dropForeign('bills_uid_for');
-            $table->dropUnique('uid_name_unique');
-        }
-        );
-        // drop foreign key from transaction_journals (bill_id_foreign)
-        Schema::table(
-            'transaction_journals', function (Blueprint $table) {
-            $table->dropForeign('bill_id_foreign');
-
-        }
-        );
-
-        // drop unique constraint from budget_limits:
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->dropForeign('bid_foreign');
-            $table->dropUnique('unique_bl_combi');
-            $table->foreign('budget_id', 'bid_foreign')->references('id')->on('budgets')->onDelete('cascade');
-        }
-        );
-
-        // rename bills to recurring_transactions
-        Schema::rename('bills', 'recurring_transactions');
-        // recreate foreign key recurring_transactions_user_id_foreign in recurring_transactions
-        // recreate unique recurring_transactions_user_id_name_unique in recurring_transactions
-        Schema::table(
-            'recurring_transactions', function (Blueprint $table) {
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-            $table->unique(['user_id', 'name']);
-        }
-        );
-
-        // rename bill_id to recurring_transaction_id
-        // recreate foreign transaction_journals_recurring_transaction_id_foreign in transaction_journals
-        Schema::table(
-            'transaction_journals', function (Blueprint $table) {
-            $table->renameColumn('bill_id', 'recurring_transaction_id');
-            $table->foreign('recurring_transaction_id')->references('id')->on('recurring_transactions')->onDelete('set null');
-        }
-        );
-
-
-    }
-
-
-    /**
-     * Run the migrations.
-     *
-     * @return void
-     */
-    public function up()
-    {
-        // rename tables:
-        Schema::rename('piggybank_repetitions', 'piggy_bank_repetitions');
-        Schema::rename('piggybanks', 'piggy_banks');
-
-        // recreate it the correct way:
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->unique(['budget_id', 'startdate', 'repeat_freq'], 'unique_bl_combi');
-        }
-        );
-
-        // rename fields
-        Schema::table(
-            'piggy_bank_events', function (Blueprint $table) {
-            $table->dropForeign('piggybank_events_piggybank_id_foreign');
-            $table->renameColumn('piggybank_id', 'piggy_bank_id');
-            $table->foreign('piggy_bank_id')->references('id')->on('piggy_banks')->onDelete('cascade');
-        }
-        );
-
-        Schema::table(
-            'piggy_bank_repetitions', function (Blueprint $table) {
-            $table->dropForeign('piggybank_repetitions_piggybank_id_foreign');
-            $table->renameColumn('piggybank_id', 'piggy_bank_id');
-            $table->foreign('piggy_bank_id')->references('id')->on('piggy_banks')->onDelete('cascade');
-        }
-        );
-
-        // add soft delete to piggy banks
-        Schema::table(
-            'piggy_banks', function (Blueprint $table) {
-            $table->softDeletes();
-        }
-        );
-
-        // rename everything related to recurring transactions, aka bills:
-        Schema::table(
-            'transaction_journals', function (Blueprint $table) {
-
-
-            // drop relation
-            $table->dropForeign('transaction_journals_recurring_transaction_id_foreign');
-            // rename column
-            $table->renameColumn('recurring_transaction_id', 'bill_id');
-
-        }
-        );
-
-        Schema::table(
-            'recurring_transactions', function (Blueprint $table) {
-            $table->dropForeign('recurring_transactions_user_id_foreign');
-            $table->dropUnique('recurring_transactions_user_id_name_unique');
-        }
-        );
-        // rename table:
-        Schema::rename('recurring_transactions', 'bills');
-
-        // recreate foreign relation:
-        Schema::table(
-            'transaction_journals', function (Blueprint $table) {
-            $table->foreign('bill_id', 'bill_id_foreign')->references('id')->on('bills')->onDelete('set null');
-        }
-        );
-
-        // recreate more foreign relations.
-        Schema::table(
-            'bills', function (Blueprint $table) {
-            // connect user id to users
-            $table->foreign('user_id', 'bills_uid_for')->references('id')->on('users')->onDelete('cascade');
-
-            // for a user, the name must be unique
-            $table->unique(['user_id', 'name'], 'uid_name_unique');
-        }
-        );
-
-
-    }
-
-}
diff --git a/database/migrations/2015_01_18_082406_changes_for_v325.php b/database/migrations/2015_01_18_082406_changes_for_v325.php
deleted file mode 100644
index b232103ca9..0000000000
--- a/database/migrations/2015_01_18_082406_changes_for_v325.php
+++ /dev/null
@@ -1,60 +0,0 @@
-dropUnique('unique_ci_combi');
-
-            }
-            );
-        } catch (PDOException $e) {
-            // don't care.
-        }
-
-        // allow journal descriptions to be encrypted.
-        Schema::table(
-            'transaction_journals', function (Blueprint $table) {
-            $table->boolean('encrypted')->default(0);
-
-        }
-        );
-        try {
-            DB::update('ALTER TABLE `transaction_journals` MODIFY `description` VARCHAR(1024)');
-        } catch (PDOException $e) {
-            // don't care.
-        }
-
-    }
-
-}
diff --git a/database/migrations/2015_02_27_210653_changes_for_v332.php b/database/migrations/2015_02_27_210653_changes_for_v332.php
deleted file mode 100644
index 982bd02d42..0000000000
--- a/database/migrations/2015_02_27_210653_changes_for_v332.php
+++ /dev/null
@@ -1,50 +0,0 @@
-boolean('encrypted')->default(0);
-
-        }
-        );
-
-        Schema::table(
-            'reminders', function (Blueprint $table) {
-            $table->text('metadata')->nullable();
-
-        }
-        );
-
-
-    }
-
-}
diff --git a/database/migrations/2015_03_27_061038_changes_for_v333.php b/database/migrations/2015_03_27_061038_changes_for_v333.php
deleted file mode 100644
index 3f67a72a27..0000000000
--- a/database/migrations/2015_03_27_061038_changes_for_v333.php
+++ /dev/null
@@ -1,40 +0,0 @@
-smallInteger('order', false, true)->default(0);
-
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2015_03_29_174140_changes_for_v336.php b/database/migrations/2015_03_29_174140_changes_for_v336.php
deleted file mode 100644
index 315f1ff570..0000000000
--- a/database/migrations/2015_03_29_174140_changes_for_v336.php
+++ /dev/null
@@ -1,244 +0,0 @@
-dropForeign('account_user_id');
-
-        }
-        );
-
-
-        Schema::table(
-            'accounts', function (Blueprint $table) {
-            $table->string('name', 255)->change();
-            $table->dropColumn('virtual_balance');
-
-            // recreate foreign key
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-
-            // recreate unique:
-            $table->unique(['user_id', 'account_type_id', 'name']);
-        }
-        );
-
-
-        /**
-         * BILLS
-         */
-        // change field to be cryptable.
-        Schema::table(
-            'bills', function (Blueprint $table) {
-            // drop foreign key:
-            $table->dropForeign('bill_user_id');
-
-            // drop unique:
-            $table->dropUnique('bill_user_id');
-        }
-        );
-        //
-        Schema::table(
-            'bills', function (Blueprint $table) {
-            // raw query:
-
-            DB::insert('ALTER TABLE `bills` CHANGE `name` `name` varchar(255) NOT NULL');
-            DB::insert('ALTER TABLE `bills` CHANGE `match` `match` varchar(255) NOT NULL');
-            $table->foreign('user_id', 'bills_uid_for')->references('id')->on('users')->onDelete('cascade');
-            $table->unique(['user_id', 'name'], 'uid_name_unique');
-        }
-        );
-
-        // remove a long forgotten index:
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->dropUnique('unique_limit');
-        }
-        );
-
-    }
-
-    /**
-     * Run the migrations.
-     *
-     * @return void
-     */
-    public function up()
-    {
-
-        /**
-         * ACCOUNTS
-         */
-        // change field to be cryptable.
-        Schema::table(
-            'accounts', function (Blueprint $table) {
-            // drop foreign key:
-            $table->dropForeign('accounts_user_id_foreign');
-
-            // drop unique:
-            $table->dropUnique('accounts_user_id_account_type_id_name_unique');
-        }
-        );
-
-        Schema::table(
-            'accounts', function (Blueprint $table) {
-            $table->text('name')->change();
-            $table->decimal('virtual_balance', 10, 2)->default(0);
-            $table->foreign('user_id', 'account_user_id')->references('id')->on('users')->onDelete('cascade');
-        }
-        );
-
-        /**
-         * BUDGETS
-         */
-        // add active/inactive and encrypt.
-        Schema::table(
-            'budgets', function (Blueprint $table) {
-            $table->smallInteger('active', false, true)->default(1);
-            $table->smallInteger('encrypted', false, true)->default(0);
-
-            // drop foreign key:
-            $table->dropForeign('budgets_user_id_foreign');
-
-            // drop unique:
-            $table->dropUnique('budgets_user_id_name_unique');
-
-        }
-        );
-        Schema::table(
-            'budgets', function (Blueprint $table) {
-            $table->text('name')->change();
-            $table->foreign('user_id', 'budget_user_id')->references('id')->on('users')->onDelete('cascade');
-        }
-        );
-
-        // reinstate a long forgotten index:
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->unique(['budget_id', 'startdate'], 'unique_limit');
-        }
-        );
-
-
-        /**
-         * BILLS
-         */
-        // change field to be cryptable.
-        Schema::table(
-            'bills', function (Blueprint $table) {
-            // drop foreign key:
-            $table->dropForeign('bills_uid_for');
-
-            // drop unique:
-            $table->dropUnique('uid_name_unique');
-        }
-        );
-
-        Schema::table(
-            'bills', function (Blueprint $table) {
-            // raw query:
-            try {
-                DB::insert('ALTER TABLE `bills` CHANGE `name` `name` TEXT NOT NULL');
-            } catch (PDOException $e) {
-                // don't care.
-            }
-            try {
-                DB::insert('ALTER TABLE `bills` CHANGE `match` `match` TEXT NOT NULL');
-            } catch (PDOException $e) {
-                // don't care.
-            }
-            $table->smallInteger('name_encrypted', false, true)->default(0);
-            $table->smallInteger('match_encrypted', false, true)->default(0);
-            $table->foreign('user_id', 'bill_user_id')->references('id')->on('users')->onDelete('cascade');
-        }
-        );
-
-        /**
-         * CATEGORIES
-         */
-        Schema::table(
-            'categories', function (Blueprint $table) {
-            $table->smallInteger('encrypted', false, true)->default(0);
-
-            // drop foreign key:
-            $table->dropForeign('categories_user_id_foreign');
-
-            // drop unique:
-            $table->dropUnique('categories_user_id_name_unique');
-
-        }
-        );
-        Schema::table(
-            'categories', function (Blueprint $table) {
-            $table->text('name')->change();
-            $table->foreign('user_id', 'category_user_id')->references('id')->on('users')->onDelete('cascade');
-        }
-        );
-
-        /**
-         * PIGGY BANKS
-         */
-        Schema::table(
-            'piggy_banks', function (Blueprint $table) {
-            $table->smallInteger('encrypted', false, true)->default(0);
-
-            // drop foreign:
-            $table->dropForeign('piggybanks_account_id_foreign');
-
-            // drop unique:
-            $table->dropUnique('piggybanks_account_id_name_unique');
-
-        }
-        );
-        Schema::table(
-            'piggy_banks', function (Blueprint $table) {
-            try {
-                DB::insert('ALTER TABLE `piggy_banks` CHANGE `name` `name` TEXT NOT NULL');
-            } catch (PDOException $e) {
-                // don't care.
-            }
-            $table->dropColumn(['repeats', 'rep_length', 'rep_every', 'rep_times']);
-
-            // create index again:
-            $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
-        }
-        );
-
-        /**
-         * REMINDERS
-         */
-        Schema::table(
-            'reminders', function (Blueprint $table) {
-            $table->smallInteger('encrypted', false, true)->default(0);
-
-
-        }
-        );
-
-    }
-
-}
diff --git a/database/migrations/2015_04_26_054507_changes_for_v3310.php b/database/migrations/2015_04_26_054507_changes_for_v3310.php
deleted file mode 100644
index 2bd1c4f0ec..0000000000
--- a/database/migrations/2015_04_26_054507_changes_for_v3310.php
+++ /dev/null
@@ -1,85 +0,0 @@
-dropColumn('relation');
-        }
-        );
-
-        /*
-         * New table!
-         */
-        Schema::create(
-            'tags', function (Blueprint $table) {
-            $table->increments('id');
-            $table->timestamps();
-            $table->softDeletes();
-            $table->integer('user_id')->unsigned();
-            $table->string('tag', 1024);
-            $table->string('tagMode', 1024);
-            $table->date('date')->nullable();
-            $table->text('description')->nullable();
-            $table->decimal('latitude', 18, 12)->nullable();
-            $table->decimal('longitude', 18, 12)->nullable();
-            $table->smallInteger('zoomLevel', false, true)->nullable();
-
-            // connect tags to users
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-        }
-        );
-
-
-        Schema::create(
-            'tag_transaction_journal', function (Blueprint $table) {
-            $table->increments('id');
-            $table->integer('tag_id')->unsigned();
-            $table->integer('transaction_journal_id')->unsigned();
-
-            // link to foreign tables.
-            $table->foreign('tag_id', 'tag_grp_id')->references('id')->on('tags')->onDelete('cascade');
-            $table->foreign('transaction_journal_id', 'tag_trj_id')->references('id')->on('transaction_journals')->onDelete('cascade');
-
-            // add unique.
-            $table->unique(['tag_id', 'transaction_journal_id'], 'tag_t_joined');
-
-        }
-        );
-    }
-
-}
diff --git a/database/migrations/2015_04_28_075215_changes_for_v3310a.php b/database/migrations/2015_04_28_075215_changes_for_v3310a.php
deleted file mode 100644
index 81bdff7117..0000000000
--- a/database/migrations/2015_04_28_075215_changes_for_v3310a.php
+++ /dev/null
@@ -1,43 +0,0 @@
-string('relation', 50)->nullable();
-        }
-        );
-        // make new column "relation"
-
-    }
-
-}
diff --git a/database/migrations/2015_04_28_075317_changes_for_v3310b.php b/database/migrations/2015_04_28_075317_changes_for_v3310b.php
deleted file mode 100644
index f950b19c21..0000000000
--- a/database/migrations/2015_04_28_075317_changes_for_v3310b.php
+++ /dev/null
@@ -1,35 +0,0 @@
-update(['relation' => 'balance']);
-    }
-
-}
diff --git a/database/migrations/2015_05_22_172026_changes_for_v3409.php b/database/migrations/2015_05_22_172026_changes_for_v3409.php
deleted file mode 100644
index 6fdbd1e607..0000000000
--- a/database/migrations/2015_05_22_172026_changes_for_v3409.php
+++ /dev/null
@@ -1,50 +0,0 @@
-dropColumn('name_encrypted');
-            $table->dropColumn('data_encrypted');
-        }
-        );
-    }
-
-    /**
-     * Run the migrations.
-     *
-     * @return void
-     */
-    public function up()
-    {
-
-        // encrypt preference name (add field)
-        // encrypt preference data (add field)
-        Schema::table(
-            'preferences', function (Blueprint $table) {
-            $table->text('name_encrypted')->nullable()->after('name');
-            $table->text('data_encrypted')->nullable()->after('data');
-        }
-        );
-
-    }
-
-}
diff --git a/database/migrations/2015_05_28_041652_entrust_setup_tables.php b/database/migrations/2015_05_28_041652_entrust_setup_tables.php
deleted file mode 100644
index ab63daedab..0000000000
--- a/database/migrations/2015_05_28_041652_entrust_setup_tables.php
+++ /dev/null
@@ -1,87 +0,0 @@
-increments('id');
-            $table->string('name')->unique();
-            $table->string('display_name')->nullable();
-            $table->string('description')->nullable();
-            $table->timestamps();
-        }
-        );
-
-        // Create table for associating roles to users (Many-to-Many)
-        Schema::create(
-            'role_user', function (Blueprint $table) {
-            $table->integer('user_id')->unsigned();
-            $table->integer('role_id')->unsigned();
-
-            $table->foreign('user_id')->references('id')->on('users')
-                  ->onUpdate('cascade')->onDelete('cascade');
-            $table->foreign('role_id')->references('id')->on('roles')
-                  ->onUpdate('cascade')->onDelete('cascade');
-
-            $table->primary(['user_id', 'role_id']);
-        }
-        );
-
-        // Create table for storing permissions
-        Schema::create(
-            'permissions', function (Blueprint $table) {
-            $table->increments('id');
-            $table->string('name')->unique();
-            $table->string('display_name')->nullable();
-            $table->string('description')->nullable();
-            $table->timestamps();
-        }
-        );
-
-        // Create table for associating permissions to roles (Many-to-Many)
-        Schema::create(
-            'permission_role', function (Blueprint $table) {
-            $table->integer('permission_id')->unsigned();
-            $table->integer('role_id')->unsigned();
-
-            $table->foreign('permission_id')->references('id')->on('permissions')
-                  ->onUpdate('cascade')->onDelete('cascade');
-            $table->foreign('role_id')->references('id')->on('roles')
-                  ->onUpdate('cascade')->onDelete('cascade');
-
-            $table->primary(['permission_id', 'role_id']);
-        }
-        );
-    }
-}
diff --git a/database/migrations/2015_06_14_093841_changes_for_v345.php b/database/migrations/2015_06_14_093841_changes_for_v345.php
deleted file mode 100644
index bbcb205de1..0000000000
--- a/database/migrations/2015_06_14_093841_changes_for_v345.php
+++ /dev/null
@@ -1,44 +0,0 @@
-dropColumn('tag_count');
-        }
-        );
-    }
-
-    /**
-     * Run the migrations.
-     *
-     * @return void
-     */
-    public function up()
-    {
-        //
-        Schema::table(
-            'transaction_journals', function (Blueprint $table) {
-            $table->smallInteger('tag_count', false, true)->default(0);
-        }
-        );
-    }
-}
diff --git a/database/migrations/2015_07_03_102450_changes_for_v3462.php b/database/migrations/2015_07_03_102450_changes_for_v3462.php
deleted file mode 100644
index 3abeefe40e..0000000000
--- a/database/migrations/2015_07_03_102450_changes_for_v3462.php
+++ /dev/null
@@ -1,43 +0,0 @@
-dropColumn('iban');
-        }
-        );
-    }
-
-    /**
-     * Run the migrations.
-     *
-     * @return void
-     */
-    public function up()
-    {
-        // add IBAN to accounts:
-        Schema::table(
-            'accounts', function (Blueprint $table) {
-            $table->string('iban')->nullable();
-        }
-        );
-    }
-}
diff --git a/database/migrations/2015_07_14_204645_changes_for_v349.php b/database/migrations/2015_07_14_204645_changes_for_v349.php
deleted file mode 100644
index 2f5c419438..0000000000
--- a/database/migrations/2015_07_14_204645_changes_for_v349.php
+++ /dev/null
@@ -1,38 +0,0 @@
-boolean('blocked')->default(0);
-        }
-        );
-    }
-}
diff --git a/database/migrations/2015_07_17_190438_changes_for_v3410.php b/database/migrations/2015_07_17_190438_changes_for_v3410.php
deleted file mode 100644
index dcaafee5cd..0000000000
--- a/database/migrations/2015_07_17_190438_changes_for_v3410.php
+++ /dev/null
@@ -1,60 +0,0 @@
-increments('id');
-            $table->timestamps();
-            $table->softDeletes();
-            $table->integer('attachable_id')->unsigned();
-            $table->string('attachable_type');
-            $table->integer('user_id')->unsigned();
-            $table->string('md5', 32);
-            $table->text('filename');
-            $table->text('title')->nullable();
-            $table->text('description')->nullable();
-            $table->text('notes')->nullable();
-            $table->text('mime');
-            $table->integer('size')->unsigned();
-            $table->tinyInteger('uploaded', false, true)->default(0);
-
-        }
-        );
-
-        // add "blocked_code" to users:
-        Schema::table(
-            'users', function (Blueprint $table) {
-            $table->string('blocked_code', 25)->nullable();
-        }
-        );
-    }
-}
diff --git a/database/migrations/2016_01_11_193428_changes_for_v370.php b/database/migrations/2016_01_11_193428_changes_for_v370.php
deleted file mode 100644
index e35dc60c15..0000000000
--- a/database/migrations/2016_01_11_193428_changes_for_v370.php
+++ /dev/null
@@ -1,135 +0,0 @@
-date('interest_date')->nullable()->after('date');
-            $table->date('book_date')->nullable()->after('interest_date');
-        }
-        );
-
-
-        // new table "rule_groups"
-        Schema::create(
-            'rule_groups', function (Blueprint $table) {
-            $table->increments('id');
-            $table->timestamps();
-            $table->softDeletes();
-            $table->integer('user_id')->unsigned();
-            $table->unsignedSmallInteger('order');
-            $table->string('title', 255);
-            $table->text('description')->nullable();
-            $table->unsignedTinyInteger('active')->default(1);
-
-            // connect rule groups to users
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-
-        }
-        );
-
-
-        Schema::create(
-            'rules', function (Blueprint $table) {
-            $table->increments('id');
-            $table->timestamps();
-            $table->softDeletes();
-            $table->integer('user_id')->unsigned();
-            $table->integer('rule_group_id')->unsigned();
-            $table->unsignedSmallInteger('order');
-            $table->unsignedTinyInteger('active')->default(1);
-            $table->unsignedTinyInteger('stop_processing')->default(0);
-
-            $table->string('title', 255);
-            $table->text('description')->nullable();
-
-
-            // connect rules to users
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-
-            // connect rules to rule groups
-            $table->foreign('rule_group_id')->references('id')->on('rule_groups')->onDelete('cascade');
-
-        }
-        );
-
-
-        // new table "rule_triggers"
-        Schema::create(
-            'rule_triggers', function (Blueprint $table) {
-            $table->increments('id');
-            $table->timestamps();
-            $table->integer('rule_id')->unsigned();
-            $table->unsignedSmallInteger('order');
-            $table->unsignedTinyInteger('active')->default(1);
-            $table->unsignedTinyInteger('stop_processing')->default(0);
-
-            $table->string('trigger_type', 50);
-            $table->string('trigger_value', 255)->nullable();
-
-            // connect rule triggers to rules
-            $table->foreign('rule_id')->references('id')->on('rules')->onDelete('cascade');
-        }
-        );
-
-        // new table "rule_actions"
-        Schema::create(
-            'rule_actions', function (Blueprint $table) {
-            $table->increments('id');
-            $table->timestamps();
-            $table->integer('rule_id')->unsigned();
-            $table->unsignedSmallInteger('order');
-            $table->unsignedTinyInteger('active')->default(1);
-            $table->unsignedTinyInteger('stop_processing')->default(0);
-
-            $table->string('action_type', 50);
-            $table->string('action_value', 255)->nullable();
-
-            // connect rule actions to rules
-            $table->foreign('rule_id')->references('id')->on('rules')->onDelete('cascade');
-
-        }
-        );
-
-    }
-}
diff --git a/database/migrations/2016_02_04_144117_changes_for_v380.php b/database/migrations/2016_02_04_144117_changes_for_v380.php
deleted file mode 100644
index f1aed9e55f..0000000000
--- a/database/migrations/2016_02_04_144117_changes_for_v380.php
+++ /dev/null
@@ -1,70 +0,0 @@
-date('process_date')->nullable()->after('book_date');
-        }
-        );
-
-        // new table "export_jobs"
-        Schema::create(
-            'export_jobs', function (Blueprint $table) {
-            $table->increments('id');
-            $table->timestamps();
-            $table->integer('user_id')->unsigned();
-            $table->string('key', 12)->unique();
-            $table->string('status', 45);
-
-            // connect rule groups to users
-            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
-
-        }
-        );
-
-        // new table for transaction journal meta, "journal_meta"
-        Schema::create(
-            'journal_meta', function (Blueprint $table) {
-            $table->increments('id');
-            $table->timestamps();
-            $table->integer('transaction_journal_id')->unsigned();
-            $table->string('name');
-            $table->text('data');
-
-            $table->unique(['transaction_journal_id', 'name']);
-
-            // link to transaction journal
-            $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
-        }
-        );
-    }
-}
diff --git a/database/migrations/2016_02_24_172426_create_jobs_table.php b/database/migrations/2016_02_24_172426_create_jobs_table.php
deleted file mode 100644
index 34be24287c..0000000000
--- a/database/migrations/2016_02_24_172426_create_jobs_table.php
+++ /dev/null
@@ -1,42 +0,0 @@
-bigIncrements('id');
-            $table->string('queue');
-            $table->longText('payload');
-            $table->tinyInteger('attempts')->unsigned();
-            $table->tinyInteger('reserved')->unsigned();
-            $table->unsignedInteger('reserved_at')->nullable();
-            $table->unsignedInteger('available_at');
-            $table->unsignedInteger('created_at');
-            $table->index(['queue', 'reserved', 'reserved_at']);
-        });
-    }
-
-    /**
-     * Reverse the migrations.
-     *
-     * @return void
-     */
-    public function down()
-    {
-        Schema::drop('jobs');
-    }
-}
diff --git a/database/migrations/2016_04_08_181054_changes_for_v383.php b/database/migrations/2016_04_08_181054_changes_for_v383.php
deleted file mode 100644
index f550d2d18d..0000000000
--- a/database/migrations/2016_04_08_181054_changes_for_v383.php
+++ /dev/null
@@ -1,38 +0,0 @@
-string('hash', 64)->nullable();
-        }
-        );
-    }
-}
diff --git a/database/migrations/2016_04_25_093451_changes_for_v390.php b/database/migrations/2016_04_25_093451_changes_for_v390.php
deleted file mode 100644
index 016573a4af..0000000000
--- a/database/migrations/2016_04_25_093451_changes_for_v390.php
+++ /dev/null
@@ -1,194 +0,0 @@
-unique(['budget_id', 'startdate', 'repeat_freq'], 'unique_bl_combi');
-        }
-        );
-
-
-        $backup = $this->backupRepeatFreqsFromString();
-
-        // drop string and create enum field
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->dropColumn('repeat_freq');
-        }
-        );
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->enum('repeat_freq', ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly']);
-        }
-        );
-
-        // restore backup. Change unknowns to "monthly".
-        $this->restoreRepeatFreqsToEnum($backup);
-
-        // drop budget <> transaction table:
-        Schema::dropIfExists('budget_transaction');
-
-        // drop category <> transaction table:
-        Schema::dropIfExists('category_transaction');
-
-    }
-
-    /**
-     * Run the migrations.
-     *
-     * @return void
-     */
-    public function up()
-    {
-        //        // remove an index.
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->dropForeign('bid_foreign');
-        }
-        );
-
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->dropUnique('unique_limit');
-            $table->dropUnique('unique_bl_combi');
-        }
-        );
-
-
-        // recreate foreign key:
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->foreign('budget_id', 'bid_foreign')->references('id')->on('budgets')->onDelete('cascade');
-        }
-        );
-
-
-        // backup values
-        $backup = $this->backupRepeatFreqsFromEnum();
-
-        // drop enum and create varchar field
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->dropColumn('repeat_freq');
-        }
-        );
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->string('repeat_freq', 20)->default('monthly');
-        }
-        );
-
-        // put data back:
-        $this->restoreRepeatFreqsToVarchar($backup);
-
-
-        // create it again, correctly.
-        Schema::table(
-            'budget_limits', function (Blueprint $table) {
-            $table->unique(['budget_id', 'startdate', 'repeat_freq'], 'unique_limit');
-        }
-        );
-
-        // create NEW table for transactions <> budgets
-        Schema::create(
-            'budget_transaction', function (Blueprint $table) {
-            $table->increments('id');
-            $table->integer('budget_id')->unsigned();
-            $table->integer('transaction_id')->unsigned();
-            $table->foreign('budget_id')->references('id')->on('budgets')->onDelete('cascade');
-            $table->foreign('transaction_id')->references('id')->on('transactions')->onDelete('cascade');
-            $table->unique(['budget_id', 'transaction_id'], 'budid_tid_unique');
-        }
-        );
-
-        // create NEW table for transactions <> categories
-        Schema::create(
-            'category_transaction', function (Blueprint $table) {
-            $table->increments('id');
-            $table->integer('category_id')->unsigned();
-            $table->integer('transaction_id')->unsigned();
-            $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
-            $table->foreign('transaction_id')->references('id')->on('transactions')->onDelete('cascade');
-            $table->unique(['category_id', 'transaction_id'], 'catid_tid_unique');
-        }
-        );
-    }
-
-    /**
-     * @return array
-     */
-    private function backupRepeatFreqsFromEnum(): array
-    {
-        $backup = [];
-        $set    = BudgetLimit::get();
-        /** @var BudgetLimit $entry */
-        foreach ($set as $entry) {
-            $backup[$entry->id] = $entry->repeat_freq;
-        }
-
-        return $backup;
-    }
-
-    /**
-     * Same routine.
-     *
-     * @return array
-     */
-    private function backupRepeatFreqsFromString()
-    {
-        return $this->backupRepeatFreqsFromEnum();
-    }
-
-    /**
-     * @param array $backup
-     *
-     * @return bool
-     */
-    private function restoreRepeatFreqsToEnum(array $backup): bool
-    {
-        foreach ($backup as $id => $repeatFreq) {
-            $budgetLimit = BudgetLimit::find($id);
-            if (!in_array($repeatFreq, ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'])) {
-                $repeatFreq = 'monthly';
-            }
-            $budgetLimit->repeat_freq = $repeatFreq;
-            $budgetLimit->save();
-        }
-
-        return true;
-    }
-
-    /**
-     * @param array $backup
-     *
-     * @return bool
-     */
-    private function restoreRepeatFreqsToVarchar(array $backup): bool
-    {
-        foreach ($backup as $id => $repeatFreq) {
-            $budgetLimit              = BudgetLimit::find($id);
-            $budgetLimit->repeat_freq = $repeatFreq;
-            $budgetLimit->save();
-        }
-
-        return true;
-    }
-}
diff --git a/database/migrations/2016_06_16_000000_create_support_tables.php b/database/migrations/2016_06_16_000000_create_support_tables.php
new file mode 100644
index 0000000000..a379310090
--- /dev/null
+++ b/database/migrations/2016_06_16_000000_create_support_tables.php
@@ -0,0 +1,285 @@
+createAccountTypeTable();
+        /*
+         * transaction_currencies
+         */
+        $this->createCurrencyTable();
+
+        /*
+         * transaction_types
+         */
+        $this->createTransactionTypeTable();
+
+        /*
+         * jobs
+         */
+        $this->createJobsTable();
+
+        /*
+         * password_resets
+         */
+        $this->createPasswordTable();
+
+        /*
+         * permissions
+         */
+        $this->createPermissionsTable();
+
+        /*
+         * roles
+         */
+        $this->createRolesTable();
+
+        /*
+         * permission_role
+         */
+        $this->createPermissionRoleTable();
+
+        /*
+         * sessions
+         */
+        $this->createSessionsTable();
+
+        $this->createConfigurationTable();
+
+    }
+
+    /**
+     *
+     */
+    private function createAccountTypeTable()
+    {
+        if (!Schema::hasTable('account_types')) {
+            Schema::create(
+                'account_types', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->string('type', 50);
+
+                // type must be unique.
+                $table->unique(['type']);
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createCurrencyTable()
+    {
+        if (!Schema::hasTable('transaction_currencies')) {
+            Schema::create(
+                'transaction_currencies', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->softDeletes();
+                $table->string('code', 3);
+                $table->string('name', 255);
+                $table->string('symbol', 12);
+
+                // code must be unique.
+                $table->unique(['code']);
+
+            }
+            );
+        }
+    }
+
+    private function createConfigurationTable()
+    {
+        if (!Schema::hasTable('configuration')) {
+            Schema::create(
+                'configuration', function (Blueprint $table) {
+
+                $table->increments('id');
+                $table->timestamps();
+                $table->softDeletes();
+                $table->string('name', 50);
+                $table->text('data');
+                $table->unique(['name']);
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createJobsTable()
+    {
+        if (!Schema::hasTable('jobs')) {
+            Schema::create(
+                'jobs', function (Blueprint $table) {
+
+                // straight from Laravel
+                $table->bigIncrements('id');
+                $table->string('queue');
+                $table->longText('payload');
+                $table->tinyInteger('attempts')->unsigned();
+                $table->tinyInteger('reserved')->unsigned();
+                $table->unsignedInteger('reserved_at')->nullable();
+                $table->unsignedInteger('available_at');
+                $table->unsignedInteger('created_at');
+                $table->index(['queue', 'reserved', 'reserved_at']);
+
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createPasswordTable()
+    {
+        if (!Schema::hasTable('password_resets')) {
+            Schema::create(
+                'password_resets', function (Blueprint $table) {
+                // straight from laravel
+                $table->string('email')->index();
+                $table->string('token')->index();
+                $table->timestamp('created_at');
+
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createPermissionRoleTable()
+    {
+        if (!Schema::hasTable('permission_role')) {
+            Schema::create(
+                'permission_role', function (Blueprint $table) {
+                $table->integer('permission_id')->unsigned();
+                $table->integer('role_id')->unsigned();
+
+                $table->foreign('permission_id')->references('id')->on('permissions')->onUpdate('cascade')->onDelete('cascade');
+                $table->foreign('role_id')->references('id')->on('roles')->onUpdate('cascade')->onDelete('cascade');
+
+                $table->primary(['permission_id', 'role_id']);
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createPermissionsTable()
+    {
+        if (!Schema::hasTable('permissions')) {
+            Schema::create(
+                'permissions', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->string('name')->unique();
+                $table->string('display_name')->nullable();
+                $table->string('description')->nullable();
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createRolesTable()
+    {
+        if (!Schema::hasTable('roles')) {
+            Schema::create(
+                'roles', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->string('name')->unique();
+                $table->string('display_name')->nullable();
+                $table->string('description')->nullable();
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createSessionsTable()
+    {
+
+        if (!Schema::hasTable('sessions')) {
+            Schema::create(
+                'sessions', function (Blueprint $table) {
+                $table->string('id')->unique();
+                $table->integer('user_id')->nullable();
+                $table->string('ip_address', 45)->nullable();
+                $table->text('user_agent')->nullable();
+                $table->text('payload');
+                $table->integer('last_activity');
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createTransactionTypeTable()
+    {
+        if (!Schema::hasTable('transaction_types')) {
+            Schema::create(
+                'transaction_types', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->softDeletes();
+                $table->string('type', 50);
+
+                // type must be unique.
+                $table->unique(['type']);
+
+            }
+            );
+        }
+    }
+}
diff --git a/database/migrations/2016_06_16_000001_create_users_table.php b/database/migrations/2016_06_16_000001_create_users_table.php
new file mode 100644
index 0000000000..82e5af99fc
--- /dev/null
+++ b/database/migrations/2016_06_16_000001_create_users_table.php
@@ -0,0 +1,43 @@
+increments('id');
+                $table->timestamps();
+                $table->string('email', 255);
+                $table->string('password', 60);
+                $table->string('remember_token', 100);
+                $table->string('reset', 32);
+                $table->tinyInteger('blocked', false, true)->default('0');
+                $table->string('blocked_code', 25)->nullable();
+            }
+            );
+        }
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::drop('users');
+    }
+}
diff --git a/database/migrations/2016_06_16_000002_create_main_tables.php b/database/migrations/2016_06_16_000002_create_main_tables.php
new file mode 100644
index 0000000000..003bc03d2f
--- /dev/null
+++ b/database/migrations/2016_06_16_000002_create_main_tables.php
@@ -0,0 +1,661 @@
+createAccountTables();
+        $this->createPiggyBanksTable();
+        $this->createAttachmentsTable();
+        $this->createBillsTable();
+        $this->createBudgetTables();
+        $this->createCategoriesTable();
+        $this->createExportJobsTable();
+        $this->createPreferencesTable();
+        $this->createRoleTable();
+        $this->createRuleTables();
+        $this->createTagsTable();
+        $this->createTransactionTables();
+    }
+
+    /**
+     *
+     */
+    private function createAccountTables()
+    {
+        if (!Schema::hasTable('accounts')) {
+            Schema::create(
+                'accounts', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->softDeletes();
+                $table->integer('user_id', false, true);
+                $table->integer('account_type_id', false, true);
+                $table->string('name', 1024);
+                $table->decimal('virtual_balance', 10, 4);
+                $table->string('iban', 255);
+
+                $table->boolean('active')->default(1);
+                $table->boolean('encrypted')->default(0);
+
+                // link user id to users table
+                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
+
+                // link account type id to account types table
+                $table->foreign('account_type_id')->references('id')->on('account_types')->onDelete('cascade');
+            }
+            );
+        }
+
+        if (!Schema::hasTable('account_meta')) {
+            Schema::create(
+                'account_meta', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->integer('account_id', false, true);
+                $table->string('name');
+                $table->text('data');
+
+                // link account id to accounts:
+                $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createAttachmentsTable()
+    {
+
+        if (!Schema::hasTable('attachments')) {
+            Schema::create(
+                'attachments', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->softDeletes();
+                $table->integer('user_id', false, true);
+                $table->integer('attachable_id', false, true);
+                $table->string('attachable_type', 255);
+                $table->string('md5', 32);
+                $table->string('filename', 1024);
+                $table->string('title', 1024);
+                $table->text('description');
+                $table->text('notes');
+                $table->string('mime', 200);
+                $table->integer('size', false, true);
+                $table->boolean('uploaded')->default(1);
+
+                // link user id to users table
+                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
+
+
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createBillsTable()
+    {
+        if (!Schema::hasTable('bills')) {
+            Schema::create(
+                'bills', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->softDeletes();
+                $table->integer('user_id', false, true);
+                $table->string('name', 1024);
+                $table->string('match', 1024);
+                $table->decimal('amount_min', 10, 4);
+                $table->decimal('amount_max', 10, 4);
+                $table->date('date');
+                $table->string('repeat_freq', 30);
+                $table->smallInteger('skip', false, true)->default(0);
+                $table->boolean('automatch')->default(1);
+                $table->boolean('active')->default(1);
+                $table->boolean('name_encrypted')->default(0);
+                $table->boolean('match_encrypted')->default(0);
+
+                // link user id to users table
+                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createBudgetTables()
+    {
+
+
+        if (!Schema::hasTable('budgets')) {
+            Schema::create(
+                'budgets', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->softDeletes();
+                $table->integer('user_id', false, true);
+                $table->string('name', 1024);
+                $table->boolean('active')->default(1);
+                $table->boolean('encrypted')->default(0);
+
+                // link user id to users table
+                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
+
+
+            }
+            );
+        }
+        if (!Schema::hasTable('budget_limits')) {
+            Schema::create(
+                'budget_limits', function (Blueprint $table) {
+
+                $table->increments('id');
+                $table->timestamps();
+                $table->integer('budget_id', false, true);
+                $table->date('startdate');
+                $table->decimal('amount', 10, 4);
+                $table->string('repeat_freq', 30);
+                $table->boolean('repeats')->default(0);
+
+                // link budget id to budgets table
+                $table->foreign('budget_id')->references('id')->on('budgets')->onDelete('cascade');
+
+            }
+            );
+        }
+        if (!Schema::hasTable('limit_repetitions')) {
+            Schema::create(
+                'limit_repetitions', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->integer('budget_limit_id', false, true);
+                $table->date('startdate');
+                $table->date('enddate');
+                $table->decimal('amount', 10, 4);
+
+                // link budget limit id to budget_limitss table
+                $table->foreign('budget_limit_id')->references('id')->on('budget_limits')->onDelete('cascade');
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createCategoriesTable()
+    {
+        if (!Schema::hasTable('categories')) {
+            Schema::create(
+                'categories', function (Blueprint $table) {
+
+                $table->increments('id');
+                $table->timestamps();
+                $table->softDeletes();
+                $table->integer('user_id', false, true);
+                $table->string('name', 1024);
+                $table->boolean('encrypted')->default(0);
+
+                // link user id to users table
+                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createExportJobsTable()
+    {
+        if (!Schema::hasTable('export_jobs')) {
+            Schema::create(
+                'export_jobs', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->integer('user_id', false, true);
+                $table->string('key', 12);
+                $table->string('status', 255);
+                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
+            }
+            );
+        }
+
+        if (!Schema::hasTable('import_jobs')) {
+            Schema::create(
+                'import_jobs', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->integer('user_id')->unsigned();
+                $table->string('key', 12)->unique();
+                $table->string('file_type', 12);
+                $table->string('status', 45);
+                $table->text('configuration');
+                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
+            }
+            );
+        }
+
+    }
+
+    private function createJournalTables()
+    {
+        if (!Schema::hasTable('transaction_journals')) {
+            Schema::create(
+                'transaction_journals', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->softDeletes();
+
+                $table->integer('user_id', false, true);
+                $table->integer('transaction_type_id', false, true);
+                $table->integer('bill_id', false, true)->nullable();
+                $table->integer('transaction_currency_id', false, true);
+
+                $table->string('description', 1024);
+
+                $table->date('date');
+                $table->date('interest_date')->nullable();
+                $table->date('book_date')->nullable();
+                $table->date('process_date')->nullable();
+
+                $table->integer('order', false, true);
+                $table->integer('tag_count', false, true);
+
+                $table->boolean('encrypted')->default(1);
+                $table->boolean('completed')->default(1);
+
+                // links to other tables:
+                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
+                $table->foreign('transaction_type_id')->references('id')->on('transaction_types')->onDelete('cascade');
+                $table->foreign('bill_id')->references('id')->on('bills')->onDelete('set null');
+                $table->foreign('transaction_currency_id')->references('id')->on('transaction_currencies')->onDelete('cascade');
+            }
+            );
+        }
+
+        if (!Schema::hasTable('journal_meta')) {
+            Schema::create(
+                'journal_meta', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->integer('transaction_journal_id', false, true);
+                $table->string('name', 255);
+                $table->text('data');
+                $table->string('hash', 64);
+
+                $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
+            }
+            );
+        }
+    }
+
+    private function createMoreJournalTables()
+    {
+        if (!Schema::hasTable('tag_transaction_journal')) {
+            Schema::create(
+                'tag_transaction_journal', function (Blueprint $table) {
+                $table->increments('id');
+                $table->integer('tag_id', false, true);
+                $table->integer('transaction_journal_id', false, true);
+
+                $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
+                $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
+
+
+            }
+            );
+        }
+
+        if (!Schema::hasTable('budget_transaction_journal')) {
+            Schema::create(
+                'budget_transaction_journal', function (Blueprint $table) {
+                $table->increments('id');
+                $table->integer('budget_id', false, true);
+                $table->integer('transaction_journal_id', false, true);
+
+                $table->foreign('budget_id')->references('id')->on('budgets')->onDelete('cascade');
+                $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
+            }
+            );
+        }
+
+        if (!Schema::hasTable('category_transaction_journal')) {
+            Schema::create(
+                'category_transaction_journal', function (Blueprint $table) {
+                $table->increments('id');
+                $table->integer('category_id', false, true);
+                $table->integer('transaction_journal_id', false, true);
+
+                $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
+                $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
+            }
+            );
+        }
+
+    }
+
+    /**
+     *
+     */
+    private function createPiggyBanksTable()
+    {
+        if (!Schema::hasTable('piggy_banks')) {
+            Schema::create(
+                'piggy_banks', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->softDeletes();
+                $table->integer('account_id', false, true);
+                $table->string('name', 1024);
+                $table->decimal('targetamount', 10, 4);
+                $table->date('startdate');
+                $table->date('targetdate');
+                $table->integer('order', false, true);
+                $table->boolean('active')->default(0);
+                $table->boolean('encrypted')->default(1);
+
+                // link to account_id to accounts
+                $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
+            }
+            );
+        }
+
+        if (!Schema::hasTable('piggy_bank_repetitions')) {
+            Schema::create(
+                'piggy_bank_repetitions', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->integer('piggy_bank_id', false, true);
+                $table->date('startdate');
+                $table->date('targetdate');
+                $table->decimal('currentamount', 10, 4);
+
+                $table->foreign('piggy_bank_id')->references('id')->on('piggy_banks')->onDelete('cascade');
+
+            }
+            );
+        }
+
+    }
+
+    /**
+     *
+     */
+    private function createPreferencesTable()
+    {
+        if (!Schema::hasTable('preferences')) {
+            Schema::create(
+                'preferences', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->integer('user_id', false, true);
+                $table->string('name', 1024);
+                $table->text('data');
+
+                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createRoleTable()
+    {
+
+        if (!Schema::hasTable('role_user')) {
+            Schema::create(
+                'role_user', function (Blueprint $table) {
+                $table->integer('user_id', false, true);
+                $table->integer('role_id', false, true);
+
+                $table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('cascade');
+                $table->foreign('role_id')->references('id')->on('roles')->onUpdate('cascade')->onDelete('cascade');
+
+                $table->primary(['user_id', 'role_id']);
+
+            }
+            );
+        }
+
+    }
+
+    /**
+     *
+     */
+    private function createRuleTables()
+    {
+        if (!Schema::hasTable('rule_groups')) {
+            Schema::create(
+                'rule_groups', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->softDeletes();
+                $table->integer('user_id', false, true);
+                $table->string('title', 255);
+                $table->text('description');
+                $table->integer('order', false, true);
+                $table->boolean('active')->default(1);
+
+                // link user id to users table
+                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
+            }
+            );
+        }
+        if (!Schema::hasTable('rules')) {
+            Schema::create(
+                'rules', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->softDeletes();
+                $table->integer('user_id', false, true);
+                $table->integer('rule_group_id', false, true);
+                $table->string('title', 255);
+                $table->text('description');
+                $table->integer('order', false, true);
+                $table->boolean('active')->default(1);
+                $table->boolean('stop_processing')->default(0);
+
+                // link user id to users table
+                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
+
+                // link rule group id to rule group table
+                $table->foreign('rule_group_id')->references('id')->on('rule_groups')->onDelete('cascade');
+            }
+            );
+        }
+        if (!Schema::hasTable('rule_actions')) {
+            Schema::create(
+                'rule_actions', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->integer('rule_id', false, true);
+
+                $table->string('action_type', 50);
+                $table->string('action_value', 255);
+
+                $table->integer('order', false, true);
+                $table->boolean('active')->default(1);
+                $table->boolean('stop_processing')->default(0);
+
+
+                // link rule id to rules table
+                $table->foreign('rule_id')->references('id')->on('rules')->onDelete('cascade');
+            }
+            );
+        }
+        if (!Schema::hasTable('rule_triggers')) {
+            Schema::create(
+                'rule_triggers', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->integer('rule_id', false, true);
+
+                $table->string('trigger_type', 50);
+                $table->string('trigger_value', 255);
+
+                $table->integer('order', false, true);
+                $table->boolean('active')->default(1);
+                $table->boolean('stop_processing')->default(0);
+
+
+                // link rule id to rules table
+                $table->foreign('rule_id')->references('id')->on('rules')->onDelete('cascade');
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createTagsTable()
+    {
+        if (!Schema::hasTable('tags')) {
+            Schema::create(
+                'tags', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->softDeletes();
+                $table->integer('user_id', false, true);
+
+                $table->string('tag', 1024);
+                $table->string('tagMode', 1024);
+                $table->date('date')->nullable();
+                $table->text('description')->nullable();
+                $table->decimal('latitude', 18, 12)->nullable();
+                $table->decimal('longitude', 18, 12)->nullable();
+                $table->boolean('zoomLevel')->nullable();
+
+                // link user id to users table
+                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
+
+            }
+            );
+        }
+    }
+
+    /**
+     *
+     */
+    private function createTransactionTables()
+    {
+        $this->createJournalTables();
+        $this->createMoreJournalTables();
+
+
+        if (!Schema::hasTable('piggy_bank_events')) {
+            Schema::create(
+                'piggy_bank_events', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->integer('piggy_bank_id', false, true);
+                $table->integer('transaction_journal_id', false, true)->nullable();
+                $table->date('date');
+                $table->decimal('amount', 10, 4);
+
+                $table->foreign('piggy_bank_id')->references('id')->on('piggy_banks')->onDelete('cascade');
+                $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('set null');
+            }
+            );
+        }
+
+        if (!Schema::hasTable('transactions')) {
+            Schema::create(
+                'transactions', function (Blueprint $table) {
+                $table->increments('id');
+                $table->timestamps();
+                $table->softDeletes();
+                $table->integer('account_id', false, true);
+                $table->integer('transaction_journal_id', false, true);
+                $table->string('description', 255);
+                $table->decimal('amount', 10, 4);
+
+                $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
+                $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
+
+            }
+            );
+        }
+
+        if (!Schema::hasTable('budget_transaction')) {
+            Schema::create(
+                'budget_transaction', function (Blueprint $table) {
+                $table->increments('id');
+                $table->integer('budget_id', false, true);
+                $table->integer('transaction_id', false, true);
+
+                $table->foreign('budget_id')->references('id')->on('budgets')->onDelete('cascade');
+                $table->foreign('transaction_id')->references('id')->on('transactions')->onDelete('cascade');
+            }
+            );
+        }
+
+        if (!Schema::hasTable('')) {
+            Schema::create(
+                'category_transaction', function (Blueprint $table) {
+                $table->increments('id');
+                $table->integer('category_id', false, true);
+                $table->integer('transaction_id', false, true);
+
+                $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
+                $table->foreign('transaction_id')->references('id')->on('transactions')->onDelete('cascade');
+            }
+            );
+        }
+    }
+}
diff --git a/database/seeds/AccountTypeSeeder.php b/database/seeds/AccountTypeSeeder.php
index 76e22d8c37..2ea3dab70e 100644
--- a/database/seeds/AccountTypeSeeder.php
+++ b/database/seeds/AccountTypeSeeder.php
@@ -13,14 +13,14 @@ class AccountTypeSeeder extends Seeder
     {
         DB::table('account_types')->delete();
 
-        AccountType::create(['type' => 'Default account', 'editable' => true]);
-        AccountType::create(['type' => 'Cash account', 'editable' => false]);
-        AccountType::create(['type' => 'Asset account', 'editable' => true]);
-        AccountType::create(['type' => 'Expense account', 'editable' => true]);
-        AccountType::create(['type' => 'Revenue account', 'editable' => true]);
-        AccountType::create(['type' => 'Initial balance account', 'editable' => false]);
-        AccountType::create(['type' => 'Beneficiary account', 'editable' => true]);
-        AccountType::create(['type' => 'Import account', 'editable' => false]);
+        AccountType::create(['type' => 'Default account']);
+        AccountType::create(['type' => 'Cash account']);
+        AccountType::create(['type' => 'Asset account']);
+        AccountType::create(['type' => 'Expense account']);
+        AccountType::create(['type' => 'Revenue account']);
+        AccountType::create(['type' => 'Initial balance account']);
+        AccountType::create(['type' => 'Beneficiary account']);
+        AccountType::create(['type' => 'Import account']);
     }
 
 
diff --git a/database/seeds/TestDataSeeder.php b/database/seeds/TestDataSeeder.php
index d4faa0e4f3..a0ccd5eee9 100644
--- a/database/seeds/TestDataSeeder.php
+++ b/database/seeds/TestDataSeeder.php
@@ -38,10 +38,15 @@ class TestDataSeeder extends Seeder
         if ($disk->exists($fileName)) {
             Log::debug('Now seeding ' . $fileName);
             $file = json_decode($disk->get($fileName), true);
-            // run the file:
-            TestData::run($file);
 
+            if (is_array($file)) {
+                // run the file:
+                TestData::run($file);
+                return;
+            }
+            Log::error('No valid data found (' . $fileName . ') for environment ' . $env);
             return;
+
         }
         Log::info('No seed file (' . $fileName . ') for environment ' . $env);
     }
diff --git a/phpunit.xml b/phpunit.xml
old mode 100755
new mode 100644
diff --git a/public/js/ff/firefly.js b/public/js/ff/firefly.js
index 5ce868262a..d63eddbcc3 100644
--- a/public/js/ff/firefly.js
+++ b/public/js/ff/firefly.js
@@ -6,14 +6,9 @@ $(function () {
     $('.currency-option').click(currencySelect);
 
     var ranges = {};
-    // range for the current month:
-    ranges[dateRangeConfig.currentMonth] = [moment().startOf('month'), moment().endOf('month')];
-
-    // range for the previous month:
-    ranges[dateRangeConfig.previousMonth] = [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')];
-
-    // range for the next month:
-    ranges[dateRangeConfig.nextMonth] = [moment().add(1, 'month').startOf('month'), moment().add(1, 'month').endOf('month')];
+    ranges[dateRangeConfig.currentPeriod] = [moment(dateRangeConfig.ranges.current[0]), moment(dateRangeConfig.ranges.current[1])];
+    ranges[dateRangeConfig.previousPeriod] = [moment(dateRangeConfig.ranges.previous[0]), moment(dateRangeConfig.ranges.previous[1])];
+    ranges[dateRangeConfig.nextPeriod] = [moment(dateRangeConfig.ranges.next[0]), moment(dateRangeConfig.ranges.next[1])];
 
     // range for everything:
     ranges[dateRangeConfig.everything] = [dateRangeConfig.firstDate, moment()];
@@ -48,7 +43,7 @@ $(function () {
                 label: label,
                 _token: token
             }).done(function () {
-                console.log('Succesfully sent new date range.');
+                console.log('Succesfully sent new date range [' + start.format('YYYY-MM-DD') + '-' + end.format('YYYY-MM-DD') + '].');
                 window.location.reload(true);
             }).fail(function () {
                 console.log('Could not send new date range.');
diff --git a/public/js/ff/reports/default/year.js b/public/js/ff/reports/default/year.js
index f342c7e1dc..54627fc29d 100644
--- a/public/js/ff/reports/default/year.js
+++ b/public/js/ff/reports/default/year.js
@@ -1,8 +1,10 @@
 /* globals google,  startDate ,reportURL, endDate , reportType ,accountIds , picker:true, minDate, expenseRestShow:true, incomeRestShow:true, year, month, hideTheRest, showTheRest, showTheRestExpense, hideTheRestExpense, columnChart, lineChart, stackedColumnChart */
 
-
+var chartDrawn;
+var budgetChart;
 $(function () {
     "use strict";
+    chartDrawn = false;
     drawChart();
 
     // click open the top X income list:
@@ -19,16 +21,78 @@ function drawChart() {
     columnChart('chart/report/in-out/' + reportType + '/' + startDate + '/' + endDate + '/' + accountIds, 'income-expenses-chart');
     columnChart('chart/report/in-out-sum/' + reportType + '/' + startDate + '/' + endDate + '/' + accountIds, 'income-expenses-sum-chart');
 
-    // in a loop
-    $.each($('.budget_year_chart'), function (i, v) {
-        var holder = $(v);
-        var id = holder.attr('id');
-        var budgetId = holder.data('budget');
-        columnChart('chart/budget/period/' + budgetId + '/' + reportType + '/' + startDate + '/' + endDate + '/' + accountIds, id);
-
-    });
+    $('.budget-chart-activate').on('click', clickBudgetChart);
 }
 
+function clickBudgetChart(e) {
+    "use strict";
+    var link = $(e.target);
+    var budgetId = link.data('budget');
+    var URL = 'chart/budget/period/' + budgetId + '/' + reportType + '/' + startDate + '/' + endDate + '/' + accountIds;
+    var container = 'budget_chart';
+    // if chart drawn is false, draw the first one, then
+    // set to true
+    if (chartDrawn == false) {
+        // do new chart:
+        
+
+        $.getJSON(URL).done(function (data) {
+            console.log('Will draw new columnChart(' + URL + ')');
+
+            var ctx = document.getElementById(container).getContext("2d");
+            var newData = {};
+            newData.datasets = [];
+
+            for (var i = 0; i < data.count; i++) {
+                newData.labels = data.labels;
+                var dataset = data.datasets[i];
+                dataset.backgroundColor = fillColors[i];
+                newData.datasets.push(dataset);
+            }
+            // completely new chart.
+            budgetChart = new Chart(ctx, {
+                type: 'bar',
+                data: data,
+                options: defaultColumnOptions
+            });
+
+        }).fail(function () {
+            $('#' + container).addClass('general-chart-error');
+        });
+        console.log('URL for column chart : ' + URL);
+        chartDrawn = true;
+    } else {
+        console.log('Will now handle remove data and add new!');
+        $.getJSON(URL).done(function (data) {
+            console.log('Will draw updated columnChart(' + URL + ')');
+            var newData = {};
+            newData.datasets = [];
+
+            for (var i = 0; i < data.count; i++) {
+                newData.labels = data.labels;
+                var dataset = data.datasets[i];
+                dataset.backgroundColor = fillColors[i];
+                newData.datasets.push(dataset);
+            }
+            // update the chart
+            console.log('Now update chart thing.');
+            budgetChart.data.datasets = newData.datasets;
+            budgetChart.update();
+
+        }).fail(function () {
+            $('#' + container).addClass('general-chart-error');
+        });
+
+
+    }
+
+    // if chart drawn is true, add new data to existing chart.
+    // console.log('Budget id is ' + budgetId);
+    // $('#budget_chart').empty();
+    // columnChart('chart/budget/period/' + budgetId + '/' + reportType + '/' + startDate + '/' + endDate + '/' + accountIds, 'budget_chart');
+
+    return false;
+}
 
 function showIncomes() {
     "use strict";
diff --git a/public/js/ff/split/journal/from-store.js b/public/js/ff/split/journal/from-store.js
index 4cbb57d3d7..5c8b0ca708 100644
--- a/public/js/ff/split/journal/from-store.js
+++ b/public/js/ff/split/journal/from-store.js
@@ -8,9 +8,28 @@
 
 /* globals globalSum */
 
+var destAccounts = {};
+var srcAccounts = {};
+var categories = {};
 $(function () {
     "use strict";
     $('.btn-do-split').click(cloneRow);
+
+    $.getJSON('json/expense-accounts').done(function (data) {
+        destAccounts = data;
+        console.log('destAccounts length is now ' + destAccounts.length);
+    });
+
+    $.getJSON('json/revenue-accounts').done(function (data) {
+        srcAccounts = data;
+        console.log('srcAccounts length is now ' + srcAccounts.length);
+    });
+
+    $.getJSON('json/categories').done(function (data) {
+        categories = data;
+        console.log('categories length is now ' + categories.length);
+    });
+
     $('input[name="amount[]"]').on('input', calculateSum)
 });
 
@@ -21,6 +40,19 @@ function cloneRow() {
     source.removeClass('initial-row');
     source.find('.count').text('#' + count);
     source.find('input[name="amount[]"]').val("").on('input', calculateSum);
+    if (destAccounts.length > 0) {
+        console.log('Will be able to extend dest-accounts.');
+        source.find('input[name="destination_account_name[]"]').typeahead({source: destAccounts});
+    }
+
+    if (destAccounts.length > 0) {
+        console.log('Will be able to extend src-accounts.');
+        source.find('input[name="source_account_name[]"]').typeahead({source: srcAccounts});
+    }
+    if(categories.length > 0) {
+        console.log('Will be able to extend categories.');
+        source.find('input[name="category[]"]').typeahead({source: categories});
+    }
 
     $('.split-table tbody').append(source);
 
diff --git a/resources/lang/en_US/csv.php b/resources/lang/en_US/csv.php
new file mode 100644
index 0000000000..fef82823e3
--- /dev/null
+++ b/resources/lang/en_US/csv.php
@@ -0,0 +1,80 @@
+ 'Configure your import',
+    'import_configure_intro' => 'There are some options for your CSV import. Please indicate if your CSV file contains headers on the first column, and what the date format of your date-fields is. That might require some experimentation. The field delimiter is usually a ",", but could also be a ";". Check this carefully.',
+    'import_configure_form'  => 'Form',
+    'header_help'            => 'Check this if the first row of your CSV file are the column titles',
+    'date_help'              => 'Date time format in your CSV. Follow the format like this page indicates. The default value will parse dates that look like this: :dateExample.',
+    'delimiter_help'         => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
+    'config_file_help'       => 'Select your CSV import configuration here. If you do not know what this is, ignore it. It will be explained later.',
+    'import_account_help'    => 'If your CSV file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the CSV belong to.',
+    'upload_not_writeable'   => 'The grey box contains a file path. It should be writeable. Please make sure it is.',
+
+    // roles
+    'column_roles_title'     => 'Define column roles',
+    'column_roles_text'      => '

Firefly III cannot guess what data each column contains. You must tell Firefly which kinds of data to expect. The example data can guide you into picking the correct type from the dropdown. If a column cannot be matched to a useful data type, please let me know by creating an issue.

Some values in your CSV file, such as account names or categories, may already exist in your Firefly III database. If you select "map these values" Firefly will not attempt to search for matching values itself but allow you to match the CSV values against the values in your database. This allows you to fine-tune the import.

', + 'column_roles_table' => 'Table', + 'column_name' => 'Name of column', + 'column_example' => 'Column example data', + 'column_role' => 'Column data meaning', + 'do_map_value' => 'Map these values', + 'column' => 'Column', + 'no_example_data' => 'No example data available', + 'store_column_roles' => 'Continue import', + 'do_not_map' => '(do not map)', + 'map_title' => 'Connect import data to Firefly III data', + 'map_text' => 'In the following tables, the left value shows you information found in your uploaded CSV file. It is your task to map this value, if possible, to a value already present in your database. Firefly will stick to this mapping. If there is no value to map to, or you do not wish to map the specific value, select nothing.', + + 'field_value' => 'Field value', + 'field_mapped_to' => 'Mapped to', + 'store_column_mapping' => 'Store mapping', + + // map things. + + + 'column__ignore' => '(ignore this column)', + 'column_account-iban' => 'Asset account (IBAN)', + 'column_account-id' => 'Asset account ID (matching Firefly)', + 'column_account-name' => 'Asset account (name)', + 'column_amount' => 'Amount', + 'column_amount-comma-separated' => 'Amount (comma as decimal separator)', + 'column_bill-id' => 'Bill ID (matching Firefly)', + 'column_bill-name' => 'Bill name', + 'column_budget-id' => 'Budget ID (matching Firefly)', + 'column_budget-name' => 'Budget name', + 'column_category-id' => 'Category ID (matching Firefly)', + 'column_category-name' => 'Category name', + 'column_currency-code' => 'Currency code (ISO 4217)', + 'column_currency-id' => 'Currency ID (matching Firefly)', + 'column_currency-name' => 'Currency name (matching Firefly)', + 'column_currency-symbol' => 'Currency symbol (matching Firefly)', + 'column_date-interest' => 'Interest calculation date', + 'column_date-book' => 'Transaction booking date', + 'column_date-process' => 'Transaction process date', + 'column_date-transaction' => 'Date', + 'column_description' => 'Description', + 'column_opposing-iban' => 'Opposing account (IBAN)', + 'column_opposing-id' => 'Opposing account ID (matching Firefly)', + 'column_external-id' => 'External ID', + 'column_opposing-name' => 'Opposing account (name)', + 'column_rabo-debet-credit' => 'Rabobank specific debet/credit indicator', + 'column_ing-debet-credit' => 'ING specific debet/credit indicator', + 'column_sepa-ct-id' => 'SEPA Credit Transfer end-to-end ID', + 'column_sepa-ct-op' => 'SEPA Credit Transfer opposing account', + 'column_sepa-db' => 'SEPA Direct Debet', + 'column_tags-comma' => 'Tags (comma separated)', + 'column_tags-space' => 'Tags (space separated)', + 'column_account-number' => 'Asset account (account number)', + 'column_opposing-number' => 'Opposing account (account number)', +]; diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index 6d3f31f8b0..08238377e7 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -326,98 +326,6 @@ return [ 'title_transfer' => 'Transfers', 'title_transfers' => 'Transfers', - - // csv import: - 'csv_import' => 'Import CSV file', - 'csv' => 'CSV', - 'csv_index_title' => 'Upload and import a CSV file', - 'csv_define_column_roles' => 'Define column roles', - 'csv_map_values' => 'Map found values to existing values', - 'csv_download_config' => 'Download CSV configuration file.', - 'csv_index_text' => 'This form allows you to import a CSV file with transactions into Firefly. It is based on the excellent CSV importer made by the folks at Atlassian. Simply upload your CSV file and follow the instructions. If you would like to learn more, please click on the button at the top of this page.', - 'csv_index_beta_warning' => 'This tool is very much in beta. Please proceed with caution', - 'csv_header_help' => 'Check this box when your CSV file\'s first row consists of column names, not actual data', - 'csv_date_help' => 'Date time format in your CSV. Follow the format like this page indicates. The default value will parse dates that look like this: :dateExample.', - 'csv_csv_file_help' => 'Select the CSV file here. You can only upload one file at a time', - 'csv_csv_config_file_help' => 'Select your CSV import configuration here. If you do not know what this is, ignore it. It will be explained later.', - 'csv_upload_button' => 'Start importing CSV', - 'csv_column_roles_title' => 'Define column roles', - 'csv_column_roles_text' => 'Firefly does not know what each column means. You need to indicate what every column is. Please check out the example data if you\'re not sure yourself. Click on the question mark (top right of the page) to learn what each column means. If you want to map imported data onto existing data in Firefly, use the checkbox. The next step will show you what this button does.', - 'csv_column_roles_table' => 'Column roles', - 'csv_column' => 'CSV column', - 'csv_column_name' => 'CSV column name', - 'csv_column_example' => 'Column example data', - 'csv_column_role' => 'Column contains?', - 'csv_do_map_value' => 'Map value?', - 'csv_continue' => 'Continue to the next step', - 'csv_go_back' => 'Go back to the previous step', - 'csv_map_title' => 'Map found values to existing values', - 'csv_map_text' => 'This page allows you to map the values from the CSV file to existing entries in your database. This ensures that accounts and other things won\'t be created twice.', - 'csv_field_value' => 'Field value from CSV', - 'csv_field_mapped_to' => 'Must be mapped to...', - 'csv_do_not_map' => 'Do not map this value', - 'csv_download_config_title' => 'Download CSV configuration', - 'csv_download_config_text' => 'Everything you\'ve just set up can be downloaded as a configuration file. Click the button to do so.', - 'csv_more_information_text' => 'If the import fails, you can use this configuration file so you don\'t have to start all over again. But, if the import succeeds, it will be easier to upload similar CSV files.', - 'csv_do_download_config' => 'Download configuration file.', - 'csv_empty_description' => '(empty description)', - 'csv_upload_form' => 'CSV upload form', - 'csv_index_unsupported_warning' => 'The CSV importer is yet incapable of doing the following:', - 'csv_unsupported_map' => 'The importer cannot map the column ":columnRole" to existing values in the database.', - 'csv_unsupported_value' => 'The importer does not know how to handle values in columns marked as ":columnRole".', - 'csv_cannot_store_value' => 'The importer has not reserved space for columns marked ":columnRole" and will be incapable of processing them.', - 'csv_process_title' => 'CSV import finished!', - 'csv_process_text' => 'The CSV importer has finished and has processed :rows rows', - 'csv_row' => 'Row', - 'csv_import_with_errors' => 'There was one error.|There were :errors errors.', - 'csv_error_see_logs' => 'Check the log files to see details.', - 'csv_process_new_entries' => 'Firefly has created :imported new transaction(s).', - 'csv_start_over' => 'Import again', - 'csv_to_index' => 'Back home', - 'csv_upload_not_writeable' => 'Cannot write to the path mentioned here. Cannot upload', - 'csv_column__ignore' => '(ignore this column)', - 'csv_column_account-iban' => 'Asset account (IBAN)', - 'csv_column_account-id' => 'Asset account ID (matching Firefly)', - 'csv_column_account-name' => 'Asset account (name)', - 'csv_column_amount' => 'Amount', - 'csv_column_amount-comma-separated' => 'Amount (comma as decimal separator)', - 'csv_column_bill-id' => 'Bill ID (matching Firefly)', - 'csv_column_bill-name' => 'Bill name', - 'csv_column_budget-id' => 'Budget ID (matching Firefly)', - 'csv_column_budget-name' => 'Budget name', - 'csv_column_category-id' => 'Category ID (matching Firefly)', - 'csv_column_category-name' => 'Category name', - 'csv_column_currency-code' => 'Currency code (ISO 4217)', - 'csv_column_currency-id' => 'Currency ID (matching Firefly)', - 'csv_column_currency-name' => 'Currency name (matching Firefly)', - 'csv_column_currency-symbol' => 'Currency symbol (matching Firefly)', - 'csv_column_date-rent' => 'Rent calculation date', - 'csv_column_date-transaction' => 'Date', - 'csv_column_description' => 'Description', - 'csv_column_opposing-iban' => 'Opposing account (IBAN)', - 'csv_column_opposing-id' => 'Opposing account ID (matching Firefly)', - 'csv_column_opposing-name' => 'Opposing account (name)', - 'csv_column_rabo-debet-credit' => 'Rabobank specific debet/credit indicator', - 'csv_column_ing-debet-credit' => 'ING specific debet/credit indicator', - 'csv_column_sepa-ct-id' => 'SEPA Credit Transfer end-to-end ID', - 'csv_column_sepa-ct-op' => 'SEPA Credit Transfer opposing account', - 'csv_column_sepa-db' => 'SEPA Direct Debet', - 'csv_column_tags-comma' => 'Tags (comma separated)', - 'csv_column_tags-space' => 'Tags (space separated)', - 'csv_column_account-number' => 'Asset account (account number)', - 'csv_column_opposing-number' => 'Opposing account (account number)', - 'csv_specifix_RabobankDescription' => 'Select this when you\'re importing Rabobank CSV export files.', - 'csv_specifix_AbnAmroDescription' => 'Select this when you\'re importing ABN AMRO CSV export files.', - 'csv_specifix_Dummy' => 'Checking this has no effect whatsoever.', - 'csv_import_account_help' => 'If your CSV file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the CSV belong to.', - 'csv_delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.', - 'csv_date_parse_error' => 'Could not parse a valid date from ":value", using the format ":format". Are you sure your CSV is correct?', - 'could_not_recover' => 'Could not continue from the previous step. Your progress has been lost :(. The log files will tell you what happened.', - 'must_select_roles' => 'You must select some roles for your file content, or the process cannot continue.', - 'invalid_mapping' => 'You have submitted an invalid mapping. The process cannot continue.', - 'no_file_uploaded' => 'It seems you did not upload a file.', - - // create new stuff: 'create_new_withdrawal' => 'Create new withdrawal', 'create_new_deposit' => 'Create new deposit', @@ -500,6 +408,8 @@ return [ 'cannot_scan_inactive_bill' => 'Inactive bills cannot be scanned.', 'rescanned_bill' => 'Rescanned everything.', 'bill_date_little_relevance' => 'The only part of this date used by Firefly is the day. It is only useful when your bill arrives at exactly the same date every month. If the payment date of your bills varies, simply use the first of the month.', + 'average_bill_amount_year' => 'Average bill amount (:year)', + 'average_bill_amount_overall' => 'Average bill amount (overall)', // accounts: 'details_for_asset' => 'Details for asset account ":name"', @@ -739,6 +649,7 @@ return [ 'balanceFor' => 'Balance for :name', // piggy banks: + 'add_money_to_piggy' => 'Add money to piggy bank ":name"', 'piggy_bank' => 'Piggy bank', 'new_piggy_bank' => 'Create new piggy bank', 'store_piggy_bank' => 'Store new piggy bank', @@ -800,6 +711,18 @@ return [ 'user_administration' => 'User administration', 'list_all_users' => 'All users', 'all_users' => 'All users', + 'all_blocked_domains' => 'All blocked domains', + 'blocked_domains' => 'Blocked domains', + 'no_domains_banned' => 'No domains blocked', + 'all_user_domains' => 'All user email address domains', + 'all_domains_is_filtered' => 'This list does not include already blocked domains.', + 'domain_now_blocked' => 'Domain :domain is now blocked', + 'domain_now_unblocked' => 'Domain :domain is now unblocked', + 'manual_block_domain' => 'Block a domain by hand', + 'block_domain' => 'Block domain', + 'no_domain_filled_in' => 'No domain filled in', + 'domain_already_blocked' => 'Domain :domain is already blocked', + 'domain_is_now_blocked' => 'Domain :domain is now blocked', // split a transaction: 'transaction_meta_data' => 'Transaction meta-data', @@ -812,29 +735,46 @@ return [ 'split_table_intro_withdrawal' => 'Split your withdrawal in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', 'store_splitted_withdrawal' => 'Store splitted withdrawal', 'update_splitted_withdrawal' => 'Update splitted withdrawal', + 'split_title_deposit' => 'Split your new deposit', + 'split_intro_one_deposit' => 'Firefly supports the "splitting" of a deposit.', + 'split_intro_two_deposit' => 'It means that the amount of money you\'ve earned is divided between several source revenue accounts or categories.', + 'split_intro_three_deposit' => 'For example: you could split your :total salary so you get :split_one as your base salary and :split_two as a reimbursment for expenses made.', + 'split_table_intro_deposit' => 'Split your deposit in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', + 'store_splitted_deposit' => 'Store splitted deposit', + 'split_title_transfer' => 'Split your new transfer', + 'split_intro_one_transfer' => 'Firefly supports the "splitting" of a transfer.', + 'split_intro_two_transfer' => 'It means that the amount of money you\'re moving is divided between several categories or piggy banks.', + 'split_intro_three_transfer' => 'For example: you could split your :total move so you get :split_one in one piggy bank and :split_two in another.', + 'split_table_intro_transfer' => 'Split your transfer in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', + 'store_splitted_transfer' => 'Store splitted transfer', + 'add_another_split' => 'Add another split', + 'split-transactions' => 'Split transactions', + 'split-new-transaction' => 'Split a new transaction', + 'do_split' => 'Do a split', + 'split_this_withdrawal' => 'Split this withdrawal', + 'split_this_deposit' => 'Split this deposit', + 'split_this_transfer' => 'Split this transfer', + 'cannot_edit_multiple_source' => 'You cannot edit splitted transaction #:id with description ":description" because it contains multiple source accounts.', + 'cannot_edit_multiple_dest' => 'You cannot edit splitted transaction #:id with description ":description" because it contains multiple destination accounts.', + 'no_edit_multiple_left' => 'You have selected no valid transactions to edit.', - 'split_title_deposit' => 'Split your new deposit', - 'split_intro_one_deposit' => 'Firefly supports the "splitting" of a deposit.', - 'split_intro_two_deposit' => 'It means that the amount of money you\'ve earned is divided between several source revenue accounts or categories.', - 'split_intro_three_deposit' => 'For example: you could split your :total salary so you get :split_one as your base salary and :split_two as a reimbursment for expenses made.', - 'split_table_intro_deposit' => 'Split your deposit in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', - 'store_splitted_deposit' => 'Store splitted deposit', - - 'split_title_transfer' => 'Split your new transfer', - 'split_intro_one_transfer' => 'Firefly supports the "splitting" of a transfer.', - 'split_intro_two_transfer' => 'It means that the amount of money you\'re moving is divided between several categories or piggy banks.', - 'split_intro_three_transfer' => 'For example: you could split your :total move so you get :split_one in one piggy bank and :split_two in another.', - 'split_table_intro_transfer' => 'Split your transfer in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', - 'store_splitted_transfer' => 'Store splitted transfer', - - 'add_another_split' => 'Add another split', - 'split-transactions' => 'Split transactions', - 'split-new-transaction' => 'Split a new transaction', - - 'do_split' => 'Do a split', - 'split_this_withdrawal' => 'Split this withdrawal', - 'split_this_deposit' => 'Split this deposit', - 'split_this_transfer' => 'Split this transfer', - - + // import + 'configuration_file_help' => 'If you have previously imported data into Firefly III, you may have a configuration file, which will pre-set configuration values for you.', + 'import_data_index' => 'Index', + 'import_file_type_csv' => 'CSV (comma separated values)', + 'import_file_type_help' => 'Select the type of file you will upload', + 'import_start' => 'Start the import', + 'configure_import' => 'Further configure your import', + 'import_finish_configuration' => 'Finish configuration', + 'settings_for_import' => 'Settings', + 'import_complete' => 'Import configuration complete!', + 'import_complete_text' => 'The import is ready to start. All the configuration you needed to do has been done. Please download the configuration file. It will help you with the import should it not go as planned. To actually run the import, you need to execute the following command in your console. Unfortunately, a web-based import is not yet possible.', + 'import_download_config' => 'Download configuration', + 'import_start_import' => 'Start import', + 'import_intro_beta' => 'The import function of Firefly III is in beta. Many users of Firefly III have tried many different files. Although each individual compontent of this import routine works (really), the combination might break. If your file cannot be imported by Firefly, please read this wiki page so I can fix the problem you have run into.', + 'import_data' => 'Import data', + 'import_data_full' => 'Import data into Firefly III', + 'import' => 'Import', + 'import_intro_text' => 'Welcome to the Firefly III data import routine. At the moment, this routine can help you import files into Firefly. To do so, you must download or export transactions from other systems or software, and upload them here. The next steps will let you help Firefly III determin what the content is of your file, and how to handle it. Please select a file, and read all instructions carefully.', + 'import_file_help' => 'Select your file', ]; diff --git a/resources/lang/en_US/form.php b/resources/lang/en_US/form.php index b60433f727..fa1f42a199 100644 --- a/resources/lang/en_US/form.php +++ b/resources/lang/en_US/form.php @@ -71,13 +71,9 @@ return [ 'code' => 'Code', 'iban' => 'IBAN', 'accountNumber' => 'Account number', - 'csv' => 'CSV file', 'has_headers' => 'Headers', 'date_format' => 'Date format', - 'csv_config' => 'CSV import configuration', 'specifix' => 'Bank- or file specific fixes', - 'csv_import_account' => 'Default import account', - 'csv_delimiter' => 'CSV field delimiter', 'attachments[]' => 'Attachments', 'store_new_withdrawal' => 'Store new withdrawal', 'store_new_deposit' => 'Store new deposit', @@ -102,9 +98,6 @@ return [ 'include_config' => 'Include configuration file', 'include_old_uploads' => 'Include imported data', 'accounts' => 'Export transactions from these accounts', - 'csv_comma' => 'A comma (,)', - 'csv_semicolon' => 'A semicolon (;)', - 'csv_tab' => 'A tab (invisible)', 'delete_account' => 'Delete account ":name"', 'delete_bill' => 'Delete bill ":name"', 'delete_budget' => 'Delete budget ":name"', @@ -137,4 +130,20 @@ return [ 'budget_keep_transactions' => 'The only transaction connected to this budget will not be deleted.|All :count transactions connected to this budget will spared deletion.', 'category_keep_transactions' => 'The only transaction connected to this category will not be deleted.|All :count transactions connected to this category will spared deletion.', 'tag_keep_transactions' => 'The only transaction connected to this tag will not be deleted.|All :count transactions connected to this tag will spared deletion.', + + // admin + 'domain' => 'Domain', + + // import + 'import_file' => 'Import file', + 'configuration_file' => 'Configuration file', + 'import_file_type' => 'Import file type', + 'csv_comma' => 'A comma (,)', + 'csv_semicolon' => 'A semicolon (;)', + 'csv_tab' => 'A tab (invisible)', + 'csv_delimiter' => 'CSV field delimiter', + 'csv_import_account' => 'Default import account', + 'csv_config' => 'CSV import configuration', + + ]; diff --git a/resources/lang/en_US/help.php b/resources/lang/en_US/help.php index bf2fff9e38..d1fa572177 100644 --- a/resources/lang/en_US/help.php +++ b/resources/lang/en_US/help.php @@ -55,11 +55,6 @@ return [ 'categories-show' => 'categories.show', 'categories-show-date' => 'categories.show.date', 'categories-noCategory' => 'categories.noCategory', - 'csv-index' => 'csv.index', - 'csv-column-roles' => 'csv.column-roles', - 'csv-map' => 'csv.map', - 'csv-download-config-page' => 'csv.download-config-page', - 'csv-process' => 'csv.process', 'currency-index' => 'currency.index', 'currency-create' => 'currency.create', 'currency-edit' => 'currency.edit', diff --git a/resources/lang/en_US/list.php b/resources/lang/en_US/list.php index 8a69fced9e..193740c717 100644 --- a/resources/lang/en_US/list.php +++ b/resources/lang/en_US/list.php @@ -8,54 +8,59 @@ */ return [ - 'buttons' => 'Buttons', - 'icon' => 'Icon', - 'create_date' => 'Created at', - 'update_date' => 'Updated at', - 'balance_before' => 'Balance before', - 'balance_after' => 'Balance after', - 'name' => 'Name', - 'role' => 'Role', - 'currentBalance' => 'Current balance', - 'active' => 'Is active?', - 'lastActivity' => 'Last activity', - 'balanceDiff' => 'Balance difference between :start and :end', - 'matchedOn' => 'Matched on', - 'matchesOn' => 'Matched on', - 'account_type' => 'Account type', - 'new_balance' => 'New balance', - 'account' => 'Account', - 'matchingAmount' => 'Amount', - 'lastMatch' => 'Last match', - 'split_number' => 'Split #', - 'destination' => 'Destination', - 'expectedMatch' => 'Expected match', - 'automatch' => 'Auto match?', - 'repeat_freq' => 'Repeats', - 'description' => 'Description', - 'amount' => 'Amount', - 'date' => 'Date', - 'interest_date' => 'Interest date', - 'book_date' => 'Book date', - 'process_date' => 'Processing date', - 'from' => 'From', - 'piggy_bank' => 'Piggy bank', - 'to' => 'To', - 'budget' => 'Budget', - 'category' => 'Category', - 'bill' => 'Bill', - 'withdrawal' => 'Withdrawal', - 'deposit' => 'Deposit', - 'transfer' => 'Transfer', - 'type' => 'Type', - 'completed' => 'Completed', - 'iban' => 'IBAN', - 'paid_current_period' => 'Paid this period', - 'email' => 'Email', - 'registered_at' => 'Registered at', - 'is_activated' => 'Is activated', - 'is_blocked' => 'Is blocked', - 'is_admin' => 'Is admin', - 'has_two_factor' => 'Has 2FA', - 'blocked_code' => 'Block code', + 'buttons' => 'Buttons', + 'icon' => 'Icon', + 'create_date' => 'Created at', + 'update_date' => 'Updated at', + 'balance_before' => 'Balance before', + 'balance_after' => 'Balance after', + 'name' => 'Name', + 'role' => 'Role', + 'currentBalance' => 'Current balance', + 'active' => 'Is active?', + 'lastActivity' => 'Last activity', + 'balanceDiff' => 'Balance difference between :start and :end', + 'matchedOn' => 'Matched on', + 'matchesOn' => 'Matched on', + 'account_type' => 'Account type', + 'new_balance' => 'New balance', + 'account' => 'Account', + 'matchingAmount' => 'Amount', + 'lastMatch' => 'Last match', + 'split_number' => 'Split #', + 'destination' => 'Destination', + 'source' => 'Source', + 'expectedMatch' => 'Expected match', + 'automatch' => 'Auto match?', + 'repeat_freq' => 'Repeats', + 'description' => 'Description', + 'amount' => 'Amount', + 'date' => 'Date', + 'interest_date' => 'Interest date', + 'book_date' => 'Book date', + 'process_date' => 'Processing date', + 'from' => 'From', + 'piggy_bank' => 'Piggy bank', + 'to' => 'To', + 'budget' => 'Budget', + 'category' => 'Category', + 'bill' => 'Bill', + 'withdrawal' => 'Withdrawal', + 'deposit' => 'Deposit', + 'transfer' => 'Transfer', + 'type' => 'Type', + 'completed' => 'Completed', + 'iban' => 'IBAN', + 'paid_current_period' => 'Paid this period', + 'email' => 'Email', + 'registered_at' => 'Registered at', + 'is_activated' => 'Is activated', + 'is_blocked' => 'Is blocked', + 'is_admin' => 'Is admin', + 'has_two_factor' => 'Has 2FA', + 'confirmed_from' => 'Confirmed from', + 'registered_from' => 'Registered from', + 'blocked_code' => 'Block code', + 'domain' => 'Domain', + 'registration_attempts' => 'Registration attempts', ]; diff --git a/resources/lang/fr_FR/breadcrumbs.php b/resources/lang/fr_FR/breadcrumbs.php index d5fe95ea0e..e20f075864 100644 --- a/resources/lang/fr_FR/breadcrumbs.php +++ b/resources/lang/fr_FR/breadcrumbs.php @@ -10,13 +10,13 @@ return [ 'home' => 'Accueil', - 'cash_accounts' => 'Cash accounts', + 'cash_accounts' => 'Comptes de trésorerie', 'edit_account' => 'Editer le compte : ":name"', 'edit_currency' => 'Editer la devise : ";name"', 'delete_currency' => 'Supprimer la devise ":name"', - 'newPiggyBank' => 'Create a new piggy bank', - 'edit_piggyBank' => 'Edit piggy bank ":name"', - 'preferences' => 'Preferences', + 'newPiggyBank' => 'Créer une nouvelle tirelire', + 'edit_piggyBank' => 'Modifier la tirelire ":name"', + 'preferences' => 'Préférences', 'profile' => 'Profil', 'changePassword' => 'Modifier le mot de passe', 'bills' => 'Factures', @@ -35,7 +35,7 @@ return [ 'transfer_list' => 'Transferts', 'transfers_list' => 'Transferts', 'create_withdrawal' => 'Creer un nouveau retrait', - 'create_deposit' => 'Create new deposit', + 'create_deposit' => 'Créer un nouveau dépôt', 'create_transfer' => 'Creer un nouveau transfert', 'edit_journal' => 'Editer la transaction ":description"', 'delete_journal' => 'Supprimer la transaction ":description"', diff --git a/resources/lang/fr_FR/config.php b/resources/lang/fr_FR/config.php index f7faeec18e..3a7bf091bf 100644 --- a/resources/lang/fr_FR/config.php +++ b/resources/lang/fr_FR/config.php @@ -11,9 +11,9 @@ return [ 'locale' => 'fr, French, fr_FR, fr_FR.utf8', 'month' => '%B %Y', 'month_and_day' => '%e %B %Y', - 'date_time' => '%B %e, %Y, @ %T', + 'date_time' => '%B %e %Y @ %T', 'specific_day' => '%e %B %Y', - 'week_in_year' => 'Week %W, %Y', + 'week_in_year' => '%W %Y', 'quarter_of_year' => '%B %Y', 'year' => '%Y', 'half_year' => '%B %Y', diff --git a/resources/lang/fr_FR/csv.php b/resources/lang/fr_FR/csv.php new file mode 100644 index 0000000000..fef82823e3 --- /dev/null +++ b/resources/lang/fr_FR/csv.php @@ -0,0 +1,80 @@ + 'Configure your import', + 'import_configure_intro' => 'There are some options for your CSV import. Please indicate if your CSV file contains headers on the first column, and what the date format of your date-fields is. That might require some experimentation. The field delimiter is usually a ",", but could also be a ";". Check this carefully.', + 'import_configure_form' => 'Form', + 'header_help' => 'Check this if the first row of your CSV file are the column titles', + 'date_help' => 'Date time format in your CSV. Follow the format like this page indicates. The default value will parse dates that look like this: :dateExample.', + 'delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.', + 'config_file_help' => 'Select your CSV import configuration here. If you do not know what this is, ignore it. It will be explained later.', + 'import_account_help' => 'If your CSV file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the CSV belong to.', + 'upload_not_writeable' => 'The grey box contains a file path. It should be writeable. Please make sure it is.', + + // roles + 'column_roles_title' => 'Define column roles', + 'column_roles_text' => '

Firefly III cannot guess what data each column contains. You must tell Firefly which kinds of data to expect. The example data can guide you into picking the correct type from the dropdown. If a column cannot be matched to a useful data type, please let me know by creating an issue.

Some values in your CSV file, such as account names or categories, may already exist in your Firefly III database. If you select "map these values" Firefly will not attempt to search for matching values itself but allow you to match the CSV values against the values in your database. This allows you to fine-tune the import.

', + 'column_roles_table' => 'Table', + 'column_name' => 'Name of column', + 'column_example' => 'Column example data', + 'column_role' => 'Column data meaning', + 'do_map_value' => 'Map these values', + 'column' => 'Column', + 'no_example_data' => 'No example data available', + 'store_column_roles' => 'Continue import', + 'do_not_map' => '(do not map)', + 'map_title' => 'Connect import data to Firefly III data', + 'map_text' => 'In the following tables, the left value shows you information found in your uploaded CSV file. It is your task to map this value, if possible, to a value already present in your database. Firefly will stick to this mapping. If there is no value to map to, or you do not wish to map the specific value, select nothing.', + + 'field_value' => 'Field value', + 'field_mapped_to' => 'Mapped to', + 'store_column_mapping' => 'Store mapping', + + // map things. + + + 'column__ignore' => '(ignore this column)', + 'column_account-iban' => 'Asset account (IBAN)', + 'column_account-id' => 'Asset account ID (matching Firefly)', + 'column_account-name' => 'Asset account (name)', + 'column_amount' => 'Amount', + 'column_amount-comma-separated' => 'Amount (comma as decimal separator)', + 'column_bill-id' => 'Bill ID (matching Firefly)', + 'column_bill-name' => 'Bill name', + 'column_budget-id' => 'Budget ID (matching Firefly)', + 'column_budget-name' => 'Budget name', + 'column_category-id' => 'Category ID (matching Firefly)', + 'column_category-name' => 'Category name', + 'column_currency-code' => 'Currency code (ISO 4217)', + 'column_currency-id' => 'Currency ID (matching Firefly)', + 'column_currency-name' => 'Currency name (matching Firefly)', + 'column_currency-symbol' => 'Currency symbol (matching Firefly)', + 'column_date-interest' => 'Interest calculation date', + 'column_date-book' => 'Transaction booking date', + 'column_date-process' => 'Transaction process date', + 'column_date-transaction' => 'Date', + 'column_description' => 'Description', + 'column_opposing-iban' => 'Opposing account (IBAN)', + 'column_opposing-id' => 'Opposing account ID (matching Firefly)', + 'column_external-id' => 'External ID', + 'column_opposing-name' => 'Opposing account (name)', + 'column_rabo-debet-credit' => 'Rabobank specific debet/credit indicator', + 'column_ing-debet-credit' => 'ING specific debet/credit indicator', + 'column_sepa-ct-id' => 'SEPA Credit Transfer end-to-end ID', + 'column_sepa-ct-op' => 'SEPA Credit Transfer opposing account', + 'column_sepa-db' => 'SEPA Direct Debet', + 'column_tags-comma' => 'Tags (comma separated)', + 'column_tags-space' => 'Tags (space separated)', + 'column_account-number' => 'Asset account (account number)', + 'column_opposing-number' => 'Opposing account (account number)', +]; diff --git a/resources/lang/fr_FR/firefly.php b/resources/lang/fr_FR/firefly.php index 3a24a0601a..fee7cf1760 100644 --- a/resources/lang/fr_FR/firefly.php +++ b/resources/lang/fr_FR/firefly.php @@ -10,235 +10,235 @@ return [ // general stuff: 'language_incomplete' => 'Cette langue n\'est pas encore complètement traduite', - 'test' => 'Vous avez choisi Anglais', + 'test' => 'Vous avez choisi l\'anglais.', 'close' => 'Fermer', - 'pleaseHold' => 'Veuillew patienter...', + 'pleaseHold' => 'Veuillez patienter...', 'actions' => 'Actions', - 'edit' => 'Editer', + 'edit' => 'Modifier', 'delete' => 'Supprimer', - 'welcomeBack' => 'What\'s playing?', + 'welcomeBack' => 'Que se passe-t-il ?', 'everything' => 'Tout', - 'customRange' => 'Plage personnalisée', + 'customRange' => 'Etendue personnalisée', 'apply' => 'Appliquer', 'cancel' => 'Annuler', 'from' => 'Depuis', - 'to' => 'To', + 'to' => 'A', 'total_sum' => 'Montant total ', 'period_sum' => 'Somme pour la période', 'showEverything' => 'Tout Afficher', 'never' => 'Jamais', 'search_results_for' => 'Résultats de recherche pour ":query"', 'bounced_error' => 'Le message envoyé à :email a été rejeté, donc pas d\'accès pour vous.', - 'deleted_error' => 'These credentials do not match our records.', - 'general_blocked_error' => 'Your account has been disabled, so you cannot login.', - 'expired_error' => 'Your account has expired, and can no longer be used.', - 'unbalanced_error' => 'Your transactions are unbalanced. This means a withdrawal, deposit or transfer was not stored properly. Please check your accounts and transactions for errors (unbalanced amount :amount).', + 'deleted_error' => 'Ces informations d\'identification ne sont pas présentes dans nos données.', + 'general_blocked_error' => 'Votre compte a été désactivé, vous ne pouvez plus vous connecter.', + 'expired_error' => 'Votre compte a expiré et ne peut plus être utilisé.', + 'unbalanced_error' => 'Vos transactions sont mal équilibrées. Cela signifie qu\'un retrait, un dépôt ou un transfert n’a pas été enregistré correctement. Vérifier vos comptes et opérations pour trouver des erreurs (montant mal équilibré: montant).', 'removed_amount' => 'Supprimé :amount', 'added_amount' => 'Ajouté :amount', - 'asset_account_role_help' => 'Any extra options resulting from your choice can be set later.', + 'asset_account_role_help' => 'Toutes options supplémentaires résultant de votre choix peut être réglée plus tard.', 'Opening balance' => 'Solde initial', - 'create_new_stuff' => 'Create new stuff', + 'create_new_stuff' => 'Créer de nouvelles choses', 'new_withdrawal' => 'Nouveau retrait', 'new_deposit' => 'Nouveau dépôt', 'new_transfer' => 'Nouveau transfert', - 'new_asset_account' => 'New asset account', - 'new_expense_account' => 'New expense account', + 'new_asset_account' => 'Nouveau compte d’actif', + 'new_expense_account' => 'Nouveau compte de dépenses', 'new_revenue_account' => 'Nouveau compte de recettes', 'new_budget' => 'Nouveau budget', 'new_bill' => 'Nouvelle facture', - 'block_account_logout' => 'You have been logged out. Blocked accounts cannot use this site. Did you register with a valid email address?', - 'flash_success' => 'Success!', + 'block_account_logout' => 'Vous avez été déconnecté. Les comptes bloqués ne peuvent pas utiliser ce site. Vous êtes vous enregistrés avec une adresse email valide ?', + 'flash_success' => 'Terminé avec succès !', 'flash_info' => 'Message', - 'flash_warning' => 'Warning!', - 'flash_error' => 'Error!', - 'flash_info_multiple' => 'There is one message|There are :count messages', - 'flash_error_multiple' => 'There is one error|There are :count errors', - 'net_worth' => 'Net worth', - 'route_has_no_help' => 'There is no help for this route, or there is no help available in your language.', - 'two_factor_welcome' => 'Hello, :user!', - 'two_factor_enter_code' => 'To continue, please enter your two factor authentication code. Your application can generate it for you.', - 'two_factor_code_here' => 'Enter code here', - 'two_factor_title' => 'Two factor authentication', - 'authenticate' => 'Authenticate', - 'two_factor_forgot_title' => 'Lost two factor authentication', - 'two_factor_forgot' => 'I forgot my two-factor thing.', - 'two_factor_lost_header' => 'Lost your two factor authentication?', - 'two_factor_lost_intro' => 'Unfortunately, this is not something you can reset from the web interface. You have two choices.', - 'two_factor_lost_fix_self' => 'If you run your own instance of Firefly III, check the logs in storage/logs for instructions.', - 'two_factor_lost_fix_owner' => 'Otherwise, email the site owner, :site_owner and ask them to reset your two factor authentication.', - 'warning_much_data' => ':days days of data may take a while to load.', - 'registered' => 'You have registered successfully!', - 'search' => 'Search', - 'no_budget_pointer' => 'You seem to have no budgets yet. You should create some on the budgets-page. Budgets can help you keep track of expenses.', - 'source_accounts' => 'Source account(s)', - 'destination_accounts' => 'Destination account(s)', + 'flash_warning' => 'Attention !', + 'flash_error' => 'Erreur !', + 'flash_info_multiple' => 'Il y a un message| Il y a :count messages', + 'flash_error_multiple' => 'Il y a une erreur| Il y a :count errors', + 'net_worth' => 'Valeur nette', + 'route_has_no_help' => 'Il n\'y a pas d\'aide pour cette page, ou il n\'y a pas de texte d\'aide en français.', + 'two_factor_welcome' => 'Bonjour, :user !', + 'two_factor_enter_code' => 'Pour continuer, veuillez entrer votre code d’authentification à deux facteurs. Votre application peut la générer pour vous.', + 'two_factor_code_here' => 'Entrez votre code ici', + 'two_factor_title' => 'Authentification à deux facteurs', + 'authenticate' => 'S\'authentifier', + 'two_factor_forgot_title' => 'Perte de l’authentification à deux facteurs', + 'two_factor_forgot' => 'J’ai oublié mon code d\'identification à deux facteurs.', + 'two_factor_lost_header' => 'Perdu votre authentification à deux facteurs ?', + 'two_factor_lost_intro' => 'Malheureusement, ce n’est pas quelque chose que vous pouvez réinitialiser depuis l’interface web. Vous avez deux choix.', + 'two_factor_lost_fix_self' => 'Si vous exécutez votre propre instance de Firefly III, vérifiez les logs dans storage/logs pour obtenir des instructions.', + 'two_factor_lost_fix_owner' => 'Dans le cas contraire, contactez le propriétaire du site par courriel : site_owner et demandez leur de réinitialiser votre authentification à deux facteurs.', + 'warning_much_data' => ':days de données peuvent prendre un certain temps à charger.', + 'registered' => 'Vous avez été enregistré avec succès !', + 'search' => 'Rechercher', + 'no_budget_pointer' => 'Vous semblez n’avoir encore aucun budget. Vous devez en créer sur la page des budgets. Les budgets peuvent vous aider à garder une trace des dépenses.', + 'source_accounts' => 'Compte(s) source', + 'destination_accounts' => 'Compte(s) de destination', // repeat frequencies: - 'repeat_freq_monthly' => 'monthly', - 'weekly' => 'Weekly', - 'quarterly' => 'Quarterly', - 'half-year' => 'Every six months', - 'yearly' => 'Yearly', + 'repeat_freq_monthly' => 'mensuel', + 'weekly' => 'hebdomadaire', + 'quarterly' => 'trimestriel', + 'half-year' => 'semestriel', + 'yearly' => 'annuel', // account confirmation: - 'confirm_account_header' => 'Please confirm your account', - 'confirm_account_intro' => 'An email has been sent to the address you used during your registration. Please check it out for further instructions. If you did not get this message, you can have Firefly send it again.', - 'confirm_account_resend_email' => 'Send me the confirmation message I need to activate my account.', - 'account_is_confirmed' => 'Your account has been confirmed!', - 'invalid_activation_code' => 'It seems the code you are using is not valid, or has expired.', - 'confirm_account_is_resent_header' => 'The confirmation has been resent', - 'confirm_account_is_resent_text' => 'The confirmation message has been resent. If you still did not receive the confirmation message, please contact the site owner at :owner or check the log files to see what went wrong.', - 'confirm_account_is_resent_go_home' => 'Go to the index page of Firefly', - 'confirm_account_not_resent_header' => 'Something went wrong :(', - 'confirm_account_not_resent_intro' => 'The confirmation message has been not resent. If you still did not receive the confirmation message, please contact the site owner at :owner instead. Possibly, you have tried to resend the activation message too often. You can have Firefly III try to resend the confirmation message every hour.', - 'confirm_account_not_resent_go_home' => 'Go to the index page of Firefly', + 'confirm_account_header' => 'Merci de vérifier votre compte', + 'confirm_account_intro' => 'Un courriel a été envoyé à l’adresse utilisée lors de votre inscription. Merci de vous y référer pour obtenir des instructions supplémentaires. Si vous n’avez pas reçu ce message, Firefly peut vous l\'envoyer de nouveau.', + 'confirm_account_resend_email' => 'M’envoyer le message de confirmation nécessaire pour activer mon compte.', + 'account_is_confirmed' => 'Votre compte a été validé !', + 'invalid_activation_code' => 'Il semble que le code que vous utilisez n’est pas valide ou a expiré.', + 'confirm_account_is_resent_header' => 'La confirmation a été renvoyée', + 'confirm_account_is_resent_text' => 'Le message de confirmation a été renvoyé. Si vous n’avez toujours pas reçu le message de confirmation, veuillez prendre contact avec le propriétaire du site à :owner ou vérifiez les logs pour voir ce qui s’est mal passé.', + 'confirm_account_is_resent_go_home' => 'Aller à la page d’accueil de Firefly', + 'confirm_account_not_resent_header' => 'Quelque chose s\'est mal passé :(', + 'confirm_account_not_resent_intro' => 'Le message de confirmation n\'a pas été renvoyé. Si vous continuez à ne pas recevoir le message de confirmation, veuillez communiquer avec le propriétaire du site au : propriétaire. Vous pourriez avoir essayé de vous renvoyer le message d’activation trop souvent. Vous pouvez demander à Firefly III de vous renvoyer le message de confirmation toutes les heures.', + 'confirm_account_not_resent_go_home' => 'Aller à la page d’accueil de Firefly', // export data: - 'import_and_export' => 'Import and export', - 'export_data' => 'Export data', - 'export_data_intro' => 'For backup purposes, when migrating to another system or when migrating to another Firefly III installation.', - 'export_format' => 'Export format', - 'export_format_csv' => 'Comma separated values (CSV file)', - 'export_format_mt940' => 'MT940 compatible format', - 'export_included_accounts' => 'Export transactions from these accounts', - 'include_config_help' => 'For easy re-import into Firefly III', - 'include_old_uploads_help' => 'Firefly III does not throw away the original CSV files you have imported in the past. You can include them in your export.', - 'do_export' => 'Export', - 'export_status_never_started' => 'The export has not started yet', - 'export_status_make_exporter' => 'Creating exporter thing...', - 'export_status_collecting_journals' => 'Collecting your transactions...', - 'export_status_collected_journals' => 'Collected your transactions!', - 'export_status_converting_to_export_format' => 'Converting your transactions...', - 'export_status_converted_to_export_format' => 'Converted your transactions!', - 'export_status_creating_journal_file' => 'Creating the export file...', - 'export_status_created_journal_file' => 'Created the export file!', - 'export_status_collecting_attachments' => 'Collecting all your attachments...', - 'export_status_collected_attachments' => 'Collected all your attachments!', - 'export_status_collecting_old_uploads' => 'Collecting all your previous uploads...', - 'export_status_collected_old_uploads' => 'Collected all your previous uploads!', - 'export_status_creating_config_file' => 'Creating a configuration file...', - 'export_status_created_config_file' => 'Created a configuration file!', - 'export_status_creating_zip_file' => 'Creating a zip file...', - 'export_status_created_zip_file' => 'Created a zip file!', - 'export_status_finished' => 'Export has succesfully finished! Yay!', - 'export_data_please_wait' => 'Please wait...', - 'attachment_explanation' => 'The file called \':attachment_name\' (#:attachment_id) was originally uploaded to :type \':description\' (#:journal_id) dated :date for the amount of :amount.', + 'import_and_export' => 'Importer et Exporter', + 'export_data' => 'Exporter les données', + 'export_data_intro' => 'À des fins de sauvegarde, lors de la migration vers un autre système ou lors de la migration sur une autre installation de Firefly III.', + 'export_format' => 'Format d\'export', + 'export_format_csv' => 'Valeurs séparées par des virgules (fichier CSV)', + 'export_format_mt940' => 'Format compatible MT940', + 'export_included_accounts' => 'Exporter les opérations depuis ces comptes', + 'include_config_help' => 'Pour facilement ré-importer dans Firefly III', + 'include_old_uploads_help' => 'Firefly III ne détruit pas les fichier CSV originaux que vous avez déjà importé dans le passé. Vous pouvez les inclure dans votre exportation.', + 'do_export' => 'Exporter', + 'export_status_never_started' => 'L’exportation n’a pas encore commencé', + 'export_status_make_exporter' => 'Créer un export...', + 'export_status_collecting_journals' => 'Collecte de vos opérations...', + 'export_status_collected_journals' => 'Vos opérations sont collectées!', + 'export_status_converting_to_export_format' => 'Conversion de vos opérations...', + 'export_status_converted_to_export_format' => 'Vos opérations sont converties!', + 'export_status_creating_journal_file' => 'Création du fichier d\'export...', + 'export_status_created_journal_file' => 'Fichier d\'export créé!', + 'export_status_collecting_attachments' => 'Collecte toutes vos pièces jointes...', + 'export_status_collected_attachments' => 'Toutes vos pièces jointes sont collectées !', + 'export_status_collecting_old_uploads' => 'Tous vos précédent upload sont en cours de collecte...', + 'export_status_collected_old_uploads' => 'Tous vos précédent upload sont collectés !', + 'export_status_creating_config_file' => 'Création d’un fichier de configuration...', + 'export_status_created_config_file' => 'Fichier de configuration créé !', + 'export_status_creating_zip_file' => 'Création d’un fichier zip...', + 'export_status_created_zip_file' => 'Fichier zip créé!', + 'export_status_finished' => 'L\'export s\'est terminé avec succès ! Yay !', + 'export_data_please_wait' => 'Veuillez patienter...', + 'attachment_explanation' => 'Le fichier appelé \':attachment_name\' (#:attachment_id) était initialement envoyé à :type \': description\' (#:journal_id) en date du :date pour un montant de :amount.', // rules - 'rules' => 'Rules', - 'rules_explanation' => 'Here you can manage rules. Rules are triggered when a transaction is created or updated. Then, if the transaction has certain properties (called "triggers") Firefly will execute the "actions". Combined, you can make Firefly respond in a certain way to new transactions.', - 'rule_name' => 'Name of rule', - 'rule_triggers' => 'Rule triggers when', + 'rules' => 'Règles', + 'rules_explanation' => 'Ici vous pouvez gérer les règles. Les règles sont déclenchées lorsqu’une opération est créée ou mise à jour. Ensuite, si l\'opération a certaines propriétés (appelées "déclencheurs" ) Firefly exécutera des "actions". Combiné, vous pouvez faire réagir Firefly d’une certaine façon aux nouvelles opérations.', + 'rule_name' => 'Nom de la règle', + 'rule_triggers' => 'La règle se déclenchera lorsque', 'rule_actions' => 'Rule will', - 'new_rule' => 'New rule', - 'new_rule_group' => 'New rule group', - 'rule_priority_up' => 'Give rule more priority', - 'rule_priority_down' => 'Give rule less priority', - 'make_new_rule_group' => 'Make new rule group', - 'store_new_rule_group' => 'Store new rule group', - 'created_new_rule_group' => 'New rule group ":title" stored!', - 'updated_rule_group' => 'Successfully updated rule group ":title".', - 'edit_rule_group' => 'Edit rule group ":title"', - 'delete_rule_group' => 'Delete rule group ":title"', - 'deleted_rule_group' => 'Deleted rule group ":title"', - 'update_rule_group' => 'Update rule group', - 'no_rules_in_group' => 'There are no rules in this group', - 'move_rule_group_up' => 'Move rule group up', - 'move_rule_group_down' => 'Move rule group down', - 'save_rules_by_moving' => 'Save these rule(s) by moving them to another rule group:', - 'make_new_rule' => 'Make new rule in rule group ":title"', - 'rule_help_stop_processing' => 'When you check this box, later rules in this group will not be executed.', - 'rule_help_active' => 'Inactive rules will never fire.', - 'stored_new_rule' => 'Stored new rule with title ":title"', - 'deleted_rule' => 'Deleted rule with title ":title"', - 'store_new_rule' => 'Store new rule', - 'updated_rule' => 'Updated rule with title ":title"', - 'default_rule_group_name' => 'Default rules', - 'default_rule_group_description' => 'All your rules not in a particular group.', - 'default_rule_name' => 'Your first default rule', - 'default_rule_description' => 'This rule is an example. You can safely delete it.', - 'default_rule_trigger_description' => 'The Man Who Sold the World', + 'new_rule' => 'Nouvelle règle', + 'new_rule_group' => 'Nouveau groupe de règles', + 'rule_priority_up' => 'Donner à la règle plus de priorité', + 'rule_priority_down' => 'Donner à la règle moins de priorité', + 'make_new_rule_group' => 'Créer un nouveau groupe de règles', + 'store_new_rule_group' => 'Créer un nouveau groupe de règles', + 'created_new_rule_group' => 'Le nouveau groupe de règles ": titre" est créé !', + 'updated_rule_group' => 'Groupe de règles ":title" mise à jour avec succès.', + 'edit_rule_group' => 'Modifier le groupe de règles ":title"', + 'delete_rule_group' => 'Supprimer le groupe de règles ":title"', + 'deleted_rule_group' => 'Groupe de règles ":title" supprimée', + 'update_rule_group' => 'Mettre à jour le groupe de règles', + 'no_rules_in_group' => 'Il n’y a pas de règles dans ce groupe', + 'move_rule_group_up' => 'Monter le groupe de règles', + 'move_rule_group_down' => 'Descendre le groupe de règles', + 'save_rules_by_moving' => 'Enregistrer ces règles en les déplaçant vers un autre groupe de règles :', + 'make_new_rule' => 'Créer une nouvelle règle dans le groupe de règles ":title"', + 'rule_help_stop_processing' => 'Lorsque vous cochez cette case, les règles suivantes de ce groupe ne seront pas exécutées.', + 'rule_help_active' => 'Les règles inactives ne se déclencheront jamais.', + 'stored_new_rule' => 'Nouvelle règle créée avec le titre ":title"', + 'deleted_rule' => 'Règle supprimée avec le titre ":title"', + 'store_new_rule' => 'Créer une nouvelle règle', + 'updated_rule' => 'Nouvelle règle enregistrée avec le titre ":title"', + 'default_rule_group_name' => 'Règles par défaut', + 'default_rule_group_description' => 'Toutes vos règles n\'étant pas dans un groupe particulier.', + 'default_rule_name' => 'Votre première règle par défaut', + 'default_rule_description' => 'Cette règle est un exemple. Vous pouvez la supprimer en toute sécurité.', + 'default_rule_trigger_description' => 'L’homme qui a vendu le monde', 'default_rule_trigger_from_account' => 'David Bowie', 'default_rule_action_prepend' => 'Bought the world from ', - 'default_rule_action_set_category' => 'Large expenses', - 'trigger' => 'Trigger', - 'trigger_value' => 'Trigger on value', - 'stop_processing_other_triggers' => 'Stop processing other triggers', - 'add_rule_trigger' => 'Add new trigger', + 'default_rule_action_set_category' => 'Grandes dépenses', + 'trigger' => 'Déclencheur', + 'trigger_value' => 'Déclenchement sur valeur', + 'stop_processing_other_triggers' => 'Arrêter le traitement d’autres déclencheurs', + 'add_rule_trigger' => 'Ajouter un nouveau déclencheur', 'action' => 'Action', - 'action_value' => 'Action value', - 'stop_executing_other_actions' => 'Stop executing other actions', - 'add_rule_action' => 'Add new action', - 'edit_rule' => 'Edit rule ":title"', - 'delete_rule' => 'Delete rule ":title"', - 'update_rule' => 'Update rule', - 'test_rule_triggers' => 'See matching transactions', - 'warning_transaction_subset' => 'For performance reasons this list is limited to :max_num_transactions and may only show a subset of matching transactions', - 'warning_no_matching_transactions' => 'No matching transactions found. Please note that for performance reasons, only the last :num_transactions transactions have been checked.', - 'warning_no_valid_triggers' => 'No valid triggers provided.', - 'execute_on_existing_transactions' => 'Execute for existing transactions', - 'execute_on_existing_transactions_intro' => 'When a rule or group has been changed or added, you can execute it for existing transactions', - 'execute_on_existing_transactions_short' => 'Existing transactions', + 'action_value' => 'Valeur de l’action', + 'stop_executing_other_actions' => 'Arrêter l’exécution des autres actions', + 'add_rule_action' => 'Ajouter une nouvelle action', + 'edit_rule' => 'Modifier la règle ": titre"', + 'delete_rule' => 'Supprimer la règle ":titre"', + 'update_rule' => 'Mettre à jour la règle', + 'test_rule_triggers' => 'Voir les opérations correspondantes', + 'warning_transaction_subset' => 'Pour des raisons de performances cette liste est limitée à :max_num_transactions et peut n\'afficher qu\'une partie des opérations correspondantes', + 'warning_no_matching_transactions' => 'Aucunes opérations correspondantes trouvées. Veuillez noter que pour des raisons de performances, seule les dernières :num_transactions opérations ont été vérifiées.', + 'warning_no_valid_triggers' => 'Aucun déclencheurs valide fourni.', + 'execute_on_existing_transactions' => 'Exécuter des opérations existantes', + 'execute_on_existing_transactions_intro' => 'Lorsqu’une règle ou un groupe a été modifié ou ajouté, vous pouvez l’exécuter pour des opérations existantes', + 'execute_on_existing_transactions_short' => 'Opérations existantes', 'executed_group_on_existing_transactions' => 'Executed group ":title" for existing transactions', 'execute_group_on_existing_transactions' => 'Execute group ":title" for existing transactions', - 'include_transactions_from_accounts' => 'Include transactions from these accounts', - 'execute' => 'Execute', + 'include_transactions_from_accounts' => 'Iclure les opérations depuis ces comptes', + 'execute' => 'Executer', // actions and triggers - 'rule_trigger_user_action' => 'User action is ":trigger_value"', - 'rule_trigger_from_account_starts' => 'Source account starts with ":trigger_value"', - 'rule_trigger_from_account_ends' => 'Source account ends with ":trigger_value"', - 'rule_trigger_from_account_is' => 'Source account is ":trigger_value"', - 'rule_trigger_from_account_contains' => 'Source account contains ":trigger_value"', - 'rule_trigger_to_account_starts' => 'Destination account starts with ":trigger_value"', - 'rule_trigger_to_account_ends' => 'Destination account ends with ":trigger_value"', - 'rule_trigger_to_account_is' => 'Destination account is ":trigger_value"', - 'rule_trigger_to_account_contains' => 'Destination account contains ":trigger_value"', - 'rule_trigger_transaction_type' => 'Transaction is of type ":trigger_value"', - 'rule_trigger_amount_less' => 'Amount is less than :trigger_value', - 'rule_trigger_amount_exactly' => 'Amount is :trigger_value', - 'rule_trigger_amount_more' => 'Amount is more than :trigger_value', - 'rule_trigger_description_starts' => 'Description starts with ":trigger_value"', - 'rule_trigger_description_ends' => 'Description ends with ":trigger_value"', - 'rule_trigger_description_contains' => 'Description contains ":trigger_value"', - 'rule_trigger_description_is' => 'Description is ":trigger_value"', - 'rule_trigger_from_account_starts_choice' => 'Source account starts with..', - 'rule_trigger_from_account_ends_choice' => 'Source account ends with..', - 'rule_trigger_from_account_is_choice' => 'Source account is..', - 'rule_trigger_from_account_contains_choice' => 'Source account contains..', - 'rule_trigger_to_account_starts_choice' => 'Destination account starts with..', - 'rule_trigger_to_account_ends_choice' => 'Destination account ends with..', - 'rule_trigger_to_account_is_choice' => 'Destination account is..', - 'rule_trigger_to_account_contains_choice' => 'Destination account contains..', - 'rule_trigger_transaction_type_choice' => 'Transaction is of type..', - 'rule_trigger_amount_less_choice' => 'Amount is less than..', - 'rule_trigger_amount_exactly_choice' => 'Amount is..', - 'rule_trigger_amount_more_choice' => 'Amount is more than..', - 'rule_trigger_description_starts_choice' => 'Description starts with..', - 'rule_trigger_description_ends_choice' => 'Description ends with..', - 'rule_trigger_description_contains_choice' => 'Description contains..', - 'rule_trigger_description_is_choice' => 'Description is..', - 'rule_trigger_store_journal' => 'When a journal is created', - 'rule_trigger_update_journal' => 'When a journal is updated', - 'rule_action_set_category' => 'Set category to ":action_value"', - 'rule_action_clear_category' => 'Clear category', - 'rule_action_set_budget' => 'Set budget to ":action_value"', - 'rule_action_clear_budget' => 'Clear budget', - 'rule_action_add_tag' => 'Add tag ":action_value"', - 'rule_action_remove_tag' => 'Remove tag ":action_value"', - 'rule_action_remove_all_tags' => 'Remove all tags', - 'rule_action_set_description' => 'Set description to ":action_value"', - 'rule_action_append_description' => 'Append description with ":action_value"', - 'rule_action_prepend_description' => 'Prepend description with ":action_value"', - 'rule_action_set_category_choice' => 'Set category to..', - 'rule_action_clear_category_choice' => 'Clear any category', - 'rule_action_set_budget_choice' => 'Set budget to..', - 'rule_action_clear_budget_choice' => 'Clear any budget', - 'rule_action_add_tag_choice' => 'Add tag..', - 'rule_action_remove_tag_choice' => 'Remove tag..', - 'rule_action_remove_all_tags_choice' => 'Remove all tags', - 'rule_action_set_description_choice' => 'Set description to..', - 'rule_action_append_description_choice' => 'Append description with..', - 'rule_action_prepend_description_choice' => 'Prepend description with..', + 'rule_trigger_user_action' => 'L\'action de l’utilisateur est ": trigger_value"', + 'rule_trigger_from_account_starts' => 'Le compte source commence par ":trigger_value"', + 'rule_trigger_from_account_ends' => 'Le compte source se termine par ":trigger_value"', + 'rule_trigger_from_account_is' => 'Le compte source est ":trigger_value"', + 'rule_trigger_from_account_contains' => 'Le compte source contient ":trigger_value"', + 'rule_trigger_to_account_starts' => 'Le compte de destination commence par ":trigger_value"', + 'rule_trigger_to_account_ends' => 'Le compte de destination se termine par ":trigger_value"', + 'rule_trigger_to_account_is' => 'Le compte de destination est ":trigger_value"', + 'rule_trigger_to_account_contains' => 'Le compte de destination contient ":trigger_value"', + 'rule_trigger_transaction_type' => 'L\'opération est du type ":trigger_value"', + 'rule_trigger_amount_less' => 'Le montant est inférieur à :trigger_value', + 'rule_trigger_amount_exactly' => 'Le montant est :trigger_value', + 'rule_trigger_amount_more' => 'Le montant est supérieur à :trigger_value', + 'rule_trigger_description_starts' => 'La description commence par ":trigger_value"', + 'rule_trigger_description_ends' => 'La description se termine par ":trigger_value"', + 'rule_trigger_description_contains' => 'La description contient ":trigger_value"', + 'rule_trigger_description_is' => 'La description est ":trigger_value"', + 'rule_trigger_from_account_starts_choice' => 'Le compte source commence par..', + 'rule_trigger_from_account_ends_choice' => 'Le compte source se termine par..', + 'rule_trigger_from_account_is_choice' => 'Le compte source est..', + 'rule_trigger_from_account_contains_choice' => 'Le compte source contient..', + 'rule_trigger_to_account_starts_choice' => 'Le compte de destination commence par..', + 'rule_trigger_to_account_ends_choice' => 'Compte de destination se terminant par..', + 'rule_trigger_to_account_is_choice' => 'Le compte de destination est..', + 'rule_trigger_to_account_contains_choice' => 'Le compte de destination est..', + 'rule_trigger_transaction_type_choice' => 'L\'opération est du type..', + 'rule_trigger_amount_less_choice' => 'Le montant est inférieur à..', + 'rule_trigger_amount_exactly_choice' => 'Le montant est..', + 'rule_trigger_amount_more_choice' => 'Le montant est supérieur à..', + 'rule_trigger_description_starts_choice' => 'Le description commence par..', + 'rule_trigger_description_ends_choice' => 'La description se termine par..', + 'rule_trigger_description_contains_choice' => 'La description contient..', + 'rule_trigger_description_is_choice' => 'La description est..', + 'rule_trigger_store_journal' => 'Lorsqu’un journal est créé', + 'rule_trigger_update_journal' => 'Lorsqu’un journal est mis à jour', + 'rule_action_set_category' => 'Définir la catégorie à ":action_value"', + 'rule_action_clear_category' => 'Supprimer la catégorie', + 'rule_action_set_budget' => 'Définir le budget à ":action_value"', + 'rule_action_clear_budget' => 'Supprimer le budget', + 'rule_action_add_tag' => 'Ajouter un tag ":action_value"', + 'rule_action_remove_tag' => 'Supprimer un tag ":action_value"', + 'rule_action_remove_all_tags' => 'Supprimer tous les tags', + 'rule_action_set_description' => 'Définir la description à ":action_value"', + 'rule_action_append_description' => 'Ajouter à la description ":action_value"', + 'rule_action_prepend_description' => 'Préfixer la description avec ":action_value"', + 'rule_action_set_category_choice' => 'Définir la catégorie à..', + 'rule_action_clear_category_choice' => 'Effacer les catégories', + 'rule_action_set_budget_choice' => 'Définir le budget à..', + 'rule_action_clear_budget_choice' => 'Effacer les budgets', + 'rule_action_add_tag_choice' => 'Ajouter un tag..', + 'rule_action_remove_tag_choice' => 'Supprimer le tag..', + 'rule_action_remove_all_tags_choice' => 'Supprimer tous les tags', + 'rule_action_set_description_choice' => 'Définir la description à..', + 'rule_action_append_description_choice' => 'Suffixer la description avec..', + 'rule_action_prepend_description_choice' => 'Préfixer la description avec..', // tags 'store_new_tag' => 'Créer un nouveau tag', @@ -248,493 +248,400 @@ return [ 'location' => 'Emplacement', // preferences - 'pref_home_screen_accounts' => 'Home screen accounts', - 'pref_home_screen_accounts_help' => 'Which accounts should be displayed on the home page?', + 'pref_home_screen_accounts' => 'Comptes de l’écran d’accueil', + 'pref_home_screen_accounts_help' => 'Quel compte devrait être affiché sur l\'écran d’accueil?', 'pref_budget_settings' => 'Paramètres de budget', - 'pref_budget_settings_help' => 'What\'s the maximum amount of money a budget envelope may contain?', - 'pref_view_range' => 'View range', - 'pref_view_range_help' => 'Some charts are automatically grouped in periods. What period would you prefer?', - 'pref_1D' => 'One day', - 'pref_1W' => 'One week', - 'pref_1M' => 'One month', - 'pref_3M' => 'Three months (quarter)', - 'pref_6M' => 'Six months', - 'pref_1Y' => 'One year', - 'pref_languages' => 'Languages', - 'pref_languages_help' => 'Firefly III supports several languages. Which one do you prefer?', - 'pref_custom_fiscal_year' => 'Fiscal year settings', - 'pref_custom_fiscal_year_label' => 'Enabled', - 'pref_custom_fiscal_year_help' => 'In countries that use a financial year other than January 1 to December 31, you can switch this on and specify start / end days of the fiscal year', - 'pref_fiscal_year_start_label' => 'Fiscal year start date', - 'pref_two_factor_auth' => '2-step verification', - 'pref_two_factor_auth_help' => 'When you enable 2-step verification (also known as two-factor authentication), you add an extra layer of security to your account. You sign in with something you know (your password) and something you have (a verification code). Verification codes are generated by an application on your phone, such as Authy or Google Authenticator.', - 'pref_enable_two_factor_auth' => 'Enable 2-step verification', - 'pref_two_factor_auth_disabled' => '2-step verification code removed and disabled', - 'pref_two_factor_auth_remove_it' => 'Don\'t forget to remove the account from your authentication app!', - 'pref_two_factor_auth_code' => 'Verify code', - 'pref_two_factor_auth_code_help' => 'Scan the QR code with an application on your phone such as Authy or Google Authenticator and enter the generated code.', - 'pref_two_factor_auth_reset_code' => 'Reset verification code', - 'pref_two_factor_auth_remove_code' => 'Remove verification code', - 'pref_two_factor_auth_remove_will_disable' => '(this will also disable two-factor authentication)', - 'pref_save_settings' => 'Save settings', - 'saved_preferences' => 'Preferences saved!', - 'transaction_page_size_title' => 'Page size', + 'pref_budget_settings_help' => 'Quel est le montant maximum d’argent qu\'une enveloppe budgétaire peut contenir ?', + 'pref_view_range' => 'Voir l\'étendue', + 'pref_view_range_help' => 'Certains graphiques sont automatiquement groupés par périodes. Quelle période préférez-vous ?', + 'pref_1D' => 'Un jour', + 'pref_1W' => 'Une semaine', + 'pref_1M' => 'Un mois', + 'pref_3M' => 'Trois mois (trimestre)', + 'pref_6M' => 'Six mois', + 'pref_1Y' => 'Un an', + 'pref_languages' => 'Langues', + 'pref_languages_help' => 'Firefly III prend en charge plusieurs langues. Laquelle préférez-vous ?', + 'pref_custom_fiscal_year' => 'Paramètres fiscaux de l\'année', + 'pref_custom_fiscal_year_label' => 'Activé', + 'pref_custom_fiscal_year_help' => 'Dans les pays qui utilisent une année financière autre que du 1er janvier au 31 décembre, vous pouvez le changer en spécifiant le jour de début et de fin de l\'année fiscale', + 'pref_fiscal_year_start_label' => 'Date du début de l\'année fiscale', + 'pref_two_factor_auth' => 'Validation en 2 étapes', + 'pref_two_factor_auth_help' => 'Lorsque vous activez la validation en 2 étapes (également connu sous le nom de deux facteurs d’authentification), vous ajoutez une couche de sécurité supplémentaire à votre compte. Vous vous connecter avec quelque chose que vous connaissez (votre mot de passe) et quelque chose que vous avez (un code de vérification). Codes de vérification sont générés par une application sur votre téléphone, telles que Authy ou Google Authenticator.', + 'pref_enable_two_factor_auth' => 'Activez la validation en 2 étapes', + 'pref_two_factor_auth_disabled' => 'Le code de vérification en deux tapes a été enlevé et désactivé', + 'pref_two_factor_auth_remove_it' => 'N’oubliez pas de supprimer ce compte de votre application d’authentification !', + 'pref_two_factor_auth_code' => 'Vérifier le code', + 'pref_two_factor_auth_code_help' => 'Scanner le code QR avec une application sur votre téléphone comme Authy ou Google Authenticator et entrez le code généré.', + 'pref_two_factor_auth_reset_code' => 'Réinitialiser le code de vérification', + 'pref_two_factor_auth_remove_code' => 'Supprimez le code de vérification', + 'pref_two_factor_auth_remove_will_disable' => '(cela désactivera également l\'authentification à deux facteurs)', + 'pref_save_settings' => 'Enregistrer les paramètres', + 'saved_preferences' => 'Préférences enregistrées!', + 'transaction_page_size_title' => 'Taille de la page', 'transaction_page_size_help' => 'Any list of transactions shows at most this many transactions', - 'transaction_page_size_label' => 'Page size', + 'transaction_page_size_label' => 'Taille de la page', 'budget_maximum' => 'Budget maximum', - 'between_dates' => '(:start and :end)', + 'between_dates' => '(:start et :end)', // profile: - 'change_your_password' => 'Change your password', - 'delete_account' => 'Delete account', - 'current_password' => 'Current password', - 'new_password' => 'New password', - 'new_password_again' => 'New password (again)', - 'delete_your_account' => 'Delete your account', - 'delete_your_account_help' => 'Deleting your account will also delete any accounts, transactions, anything you might have saved into Firefly III. It\'ll be GONE.', - 'delete_your_account_password' => 'Enter your password to continue.', - 'password' => 'Password', - 'are_you_sure' => 'Are you sure? You cannot undo this.', - 'delete_account_button' => 'DELETE your account', - 'invalid_current_password' => 'Invalid current password!', - 'password_changed' => 'Password changed!', - 'should_change' => 'The idea is to change your password.', - 'invalid_password' => 'Invalid password!', + 'change_your_password' => 'Modifier votre mot de passe', + 'delete_account' => 'Supprimer le compte', + 'current_password' => 'Mot de passe actuel', + 'new_password' => 'Nouveau mot de passe ', + 'new_password_again' => 'Nouveau mot de passe (encore)', + 'delete_your_account' => 'Supprimer votre compte', + 'delete_your_account_help' => 'La suppression de votre compte supprimera également les comptes, les opérations, tout ce que vous pourriez avoir enregistré dans Firefly III. Tout sera SUPPRIME.', + 'delete_your_account_password' => 'Entrez votre mot de passe pour continuer.', + 'password' => 'Mot de passe', + 'are_you_sure' => 'Es-tu sûr ? Vous ne pourrez pas annuler cette action.', + 'delete_account_button' => 'SUPPRIMER votre compte', + 'invalid_current_password' => 'Mot de passe actuel non valide!', + 'password_changed' => 'Mot de passe modifié!', + 'should_change' => 'L’idée est de changer votre mot de passe.', + 'invalid_password' => 'Mot de passe incorrect!', // attachments - 'nr_of_attachments' => 'One attachment|:count attachments', - 'attachments' => 'Attachments', - 'edit_attachment' => 'Edit attachment ":name"', - 'update_attachment' => 'Update attachment', - 'delete_attachment' => 'Delete attachment ":name"', - 'attachment_deleted' => 'Deleted attachment ":name"', - 'attachment_updated' => 'Updated attachment ":name"', - 'upload_max_file_size' => 'Maximum file size: :size', + 'nr_of_attachments' => 'Une pièce jointe|:count pièces jointes', + 'attachments' => 'Pièces jointes', + 'edit_attachment' => 'Modifier la pièce jointe ":name"', + 'update_attachment' => 'Mettre à jour la pièce jointe', + 'delete_attachment' => 'Supprimer la pièce jointe ":name"', + 'attachment_deleted' => 'Pièce jointe ":name" supprimée', + 'attachment_updated' => 'Pièce jointe ":name" mise à jour', + 'upload_max_file_size' => 'Taille maximum du fichier : :size', // tour: - 'prev' => 'Prev', - 'next' => 'Next', + 'prev' => 'Précédent', + 'next' => 'Suivant', 'end-tour' => 'End tour', - 'pause' => 'Pause', + 'pause' => 'Suspendre', // transaction index - 'title_expenses' => 'Expenses', - 'title_withdrawal' => 'Expenses', - 'title_revenue' => 'Revenue / income', - 'title_deposit' => 'Revenue / income', + 'title_expenses' => 'Dépenses', + 'title_withdrawal' => 'Dépenses', + 'title_revenue' => 'Recette / revenu', + 'title_deposit' => 'Recette / revenu', 'title_transfer' => 'Transferts', 'title_transfers' => 'Transferts', - - // csv import: - 'csv_import' => 'Import CSV file', - 'csv' => 'CSV', - 'csv_index_title' => 'Upload and import a CSV file', - 'csv_define_column_roles' => 'Define column roles', - 'csv_map_values' => 'Map found values to existing values', - 'csv_download_config' => 'Download CSV configuration file.', - 'csv_index_text' => 'This form allows you to import a CSV file with transactions into Firefly. It is based on the excellent CSV importer made by the folks at Atlassian. Simply upload your CSV file and follow the instructions. If you would like to learn more, please click on the button at the top of this page.', - 'csv_index_beta_warning' => 'This tool is very much in beta. Please proceed with caution', - 'csv_header_help' => 'Check this box when your CSV file\'s first row consists of column names, not actual data', - 'csv_date_help' => 'Date time format in your CSV. Follow the format like this page indicates. The default value will parse dates that look like this: :dateExample.', - 'csv_csv_file_help' => 'Select the CSV file here. You can only upload one file at a time', - 'csv_csv_config_file_help' => 'Select your CSV import configuration here. If you do not know what this is, ignore it. It will be explained later.', - 'csv_upload_button' => 'Start importing CSV', - 'csv_column_roles_title' => 'Define column roles', - 'csv_column_roles_text' => 'Firefly does not know what each column means. You need to indicate what every column is. Please check out the example data if you\'re not sure yourself. Click on the question mark (top right of the page) to learn what each column means. If you want to map imported data onto existing data in Firefly, use the checkbox. The next step will show you what this button does.', - 'csv_column_roles_table' => 'Column roles', - 'csv_column' => 'CSV column', - 'csv_column_name' => 'CSV column name', - 'csv_column_example' => 'Column example data', - 'csv_column_role' => 'Column contains?', - 'csv_do_map_value' => 'Map value?', - 'csv_continue' => 'Continue to the next step', - 'csv_go_back' => 'Go back to the previous step', - 'csv_map_title' => 'Map found values to existing values', - 'csv_map_text' => 'This page allows you to map the values from the CSV file to existing entries in your database. This ensures that accounts and other things won\'t be created twice.', - 'csv_field_value' => 'Field value from CSV', - 'csv_field_mapped_to' => 'Must be mapped to...', - 'csv_do_not_map' => 'Do not map this value', - 'csv_download_config_title' => 'Download CSV configuration', - 'csv_download_config_text' => 'Everything you\'ve just set up can be downloaded as a configuration file. Click the button to do so.', - 'csv_more_information_text' => 'If the import fails, you can use this configuration file so you don\'t have to start all over again. But, if the import succeeds, it will be easier to upload similar CSV files.', - 'csv_do_download_config' => 'Download configuration file.', - 'csv_empty_description' => '(empty description)', - 'csv_upload_form' => 'CSV upload form', - 'csv_index_unsupported_warning' => 'The CSV importer is yet incapable of doing the following:', - 'csv_unsupported_map' => 'The importer cannot map the column ":columnRole" to existing values in the database.', - 'csv_unsupported_value' => 'The importer does not know how to handle values in columns marked as ":columnRole".', - 'csv_cannot_store_value' => 'The importer has not reserved space for columns marked ":columnRole" and will be incapable of processing them.', - 'csv_process_title' => 'CSV import finished!', - 'csv_process_text' => 'The CSV importer has finished and has processed :rows rows', - 'csv_row' => 'Row', - 'csv_import_with_errors' => 'There was one error.|There were :errors errors.', - 'csv_error_see_logs' => 'Check the log files to see details.', - 'csv_process_new_entries' => 'Firefly has created :imported new transaction(s).', - 'csv_start_over' => 'Import again', - 'csv_to_index' => 'Back home', - 'csv_upload_not_writeable' => 'Cannot write to the path mentioned here. Cannot upload', - 'csv_column__ignore' => '(ignore this column)', - 'csv_column_account-iban' => 'Asset account (IBAN)', - 'csv_column_account-id' => 'Asset account ID (matching Firefly)', - 'csv_column_account-name' => 'Asset account (name)', - 'csv_column_amount' => 'Amount', - 'csv_column_amount-comma-separated' => 'Amount (comma as decimal separator)', - 'csv_column_bill-id' => 'Bill ID (matching Firefly)', - 'csv_column_bill-name' => 'Bill name', - 'csv_column_budget-id' => 'Budget ID (matching Firefly)', - 'csv_column_budget-name' => 'Budget name', - 'csv_column_category-id' => 'Category ID (matching Firefly)', - 'csv_column_category-name' => 'Category name', - 'csv_column_currency-code' => 'Currency code (ISO 4217)', - 'csv_column_currency-id' => 'Currency ID (matching Firefly)', - 'csv_column_currency-name' => 'Currency name (matching Firefly)', - 'csv_column_currency-symbol' => 'Currency symbol (matching Firefly)', - 'csv_column_date-rent' => 'Rent calculation date', - 'csv_column_date-transaction' => 'Date', - 'csv_column_description' => 'Description', - 'csv_column_opposing-iban' => 'Opposing account (IBAN)', - 'csv_column_opposing-id' => 'Opposing account ID (matching Firefly)', - 'csv_column_opposing-name' => 'Opposing account (name)', - 'csv_column_rabo-debet-credit' => 'Rabobank specific debet/credit indicator', - 'csv_column_ing-debet-credit' => 'ING specific debet/credit indicator', - 'csv_column_sepa-ct-id' => 'SEPA Credit Transfer end-to-end ID', - 'csv_column_sepa-ct-op' => 'SEPA Credit Transfer opposing account', - 'csv_column_sepa-db' => 'SEPA Direct Debet', - 'csv_column_tags-comma' => 'Tags (comma separated)', - 'csv_column_tags-space' => 'Tags (space separated)', - 'csv_column_account-number' => 'Asset account (account number)', - 'csv_column_opposing-number' => 'Opposing account (account number)', - 'csv_specifix_RabobankDescription' => 'Select this when you\'re importing Rabobank CSV export files.', - 'csv_specifix_AbnAmroDescription' => 'Select this when you\'re importing ABN AMRO CSV export files.', - 'csv_specifix_Dummy' => 'Checking this has no effect whatsoever.', - 'csv_import_account_help' => 'If your CSV file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the CSV belong to.', - 'csv_delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.', - 'csv_date_parse_error' => 'Could not parse a valid date from ":value", using the format ":format". Are you sure your CSV is correct?', - 'could_not_recover' => 'Could not continue from the previous step. Your progress has been lost :(. The log files will tell you what happened.', - 'must_select_roles' => 'You must select some roles for your file content, or the process cannot continue.', - 'invalid_mapping' => 'You have submitted an invalid mapping. The process cannot continue.', - 'no_file_uploaded' => 'It seems you did not upload a file.', - - // create new stuff: 'create_new_withdrawal' => 'Creer un nouveau retrait', - 'create_new_deposit' => 'Create new deposit', + 'create_new_deposit' => 'Créer un nouveau dépôt', 'create_new_transfer' => 'Creer un nouveau transfert', - 'create_new_asset' => 'Create new asset account', - 'create_new_expense' => 'Create new expense account', - 'create_new_revenue' => 'Create new revenue account', - 'create_new_piggy_bank' => 'Create new piggy bank', - 'create_new_bill' => 'Create new bill', + 'create_new_asset' => 'Créer le nouveau compte d’actif', + 'create_new_expense' => 'Créer nouveau compte de dépenses', + 'create_new_revenue' => 'Créer nouveau compte de recettes', + 'create_new_piggy_bank' => 'Créer une nouvelle tirelire', + 'create_new_bill' => 'Créer une nouvelle facture', // currencies: - 'create_currency' => 'Create a new currency', - 'edit_currency' => 'Edit currency ":name"', - 'store_currency' => 'Store new currency', - 'update_currency' => 'Update currency', + 'create_currency' => 'Créer une nouvelle devise', + 'edit_currency' => 'Modifier la devise ":name"', + 'store_currency' => 'Créer une nouvelle devise', + 'update_currency' => 'Mise à jour de la balance', 'new_default_currency' => ':name is now the default currency.', 'cannot_delete_currency' => 'Cannot delete :name because there are still transactions attached to it!', - 'deleted_currency' => 'Currency :name deleted', - 'created_currency' => 'Currency :name created', - 'updated_currency' => 'Currency :name updated', - 'ask_site_owner' => 'Please ask :owner to add, remove or edit currencies.', - 'currencies_intro' => 'Firefly III supports various currencies which you can set and enable here.', - 'make_default_currency' => 'make default', - 'default_currency' => 'default', + 'deleted_currency' => 'Devise ":name" supprimée', + 'created_currency' => 'Devise ":name" créée', + 'updated_currency' => 'Devise ":name" mise à jour', + 'ask_site_owner' => 'Merci de demander à :owner pour ajouter, modifier ou supprimer des devises.', + 'currencies_intro' => 'Firefly III prend en charge diverses monnaies que vous pouvez configurer et activer ici.', + 'make_default_currency' => 'définir par défaut', + 'default_currency' => 'par défaut', // new user: - 'submit' => 'Submit', - 'getting_started' => 'Getting started', - 'to_get_started' => 'To get started with Firefly, please enter your current bank\'s name, and the balance of your checking account:', - 'savings_balance_text' => 'If you have a savings account, please enter the current balance of your savings account:', - 'cc_balance_text' => 'If you have a credit card, please enter your credit card\'s limit.', - 'stored_new_account_new_user' => 'Yay! Your new account has been stored.', - 'stored_new_accounts_new_user' => 'Yay! Your new accounts have been stored.', + 'submit' => 'Soumettre', + 'getting_started' => 'Mise en route', + 'to_get_started' => 'Pour débuter avec Firefly, veuillez entrer le nom de votre banque actuelle et le solde de votre compte courant :', + 'savings_balance_text' => 'Si vous avez un compte d’épargne, entrer le solde actuel de votre compte d’épargne :', + 'cc_balance_text' => 'Si vous avez une carte de crédit, entrez la plafond de votre carte.', + 'stored_new_account_new_user' => 'Super ! Votre nouveau compte à été créé.', + 'stored_new_accounts_new_user' => 'Super ! Vos nouveaux comptes ont été créé.', // forms: - 'mandatoryFields' => 'Mandatory fields', - 'optionalFields' => 'Optional fields', + 'mandatoryFields' => 'Champs obligatoires', + 'optionalFields' => 'Champs optionnels', 'options' => 'Options', - 'something' => 'Something!', + 'something' => 'Quelque chose !', // budgets: - 'create_new_budget' => 'Create a new budget', - 'store_new_budget' => 'Store new budget', - 'stored_new_budget' => 'Stored new budget ":name"', - 'availableIn' => 'Available in :date', + 'create_new_budget' => 'Créer un nouveau budget', + 'store_new_budget' => 'Créer un nouveau budget', + 'stored_new_budget' => 'Nouveau budget ":name" créé', + 'availableIn' => 'Disponible depuis', 'available_between' => 'Available between :start and :end', - 'transactionsWithoutBudget' => 'Expenses without budget', - 'transactionsWithoutBudgetDate' => 'Expenses without budget in :date', - 'transactions_no_budget' => 'Expenses without budget between :start and :end', - 'spent_between' => 'Spent between :start and :end', - 'createBudget' => 'New budget', - 'inactiveBudgets' => 'Inactive budgets', - 'without_budget_between' => 'Transactions without a budget between :start and :end', - 'budget_in_month' => ':name in :month', - 'delete_budget' => 'Delete budget ":name"', - 'deleted_budget' => 'Deleted budget ":name"', - 'edit_budget' => 'Edit budget ":name"', - 'updated_budget' => 'Updated budget ":name"', - 'update_amount' => 'Update amount', - 'update_budget' => 'Update budget', - 'update_budget_amount_range' => 'Update (expected) available amount between :start and :end', + 'transactionsWithoutBudget' => 'Dépenses non budgétisées', + 'transactionsWithoutBudgetDate' => 'Dépenses non budgétisées en date du :date', + 'transactions_no_budget' => 'Dépenses non budgetisées entre le :start et le :end', + 'spent_between' => 'Dépensé entre le :start et le :end', + 'createBudget' => 'Nouveau budget', + 'inactiveBudgets' => 'Budgets inactifs', + 'without_budget_between' => 'Opérations non budgetisées entre le :start et le :end', + 'budget_in_month' => ':name en :month', + 'delete_budget' => 'Supprimer le budget ":name"', + 'deleted_budget' => 'Budget ":name" supprimé', + 'edit_budget' => 'Modifier le budget ":name"', + 'updated_budget' => 'Mettre à jour le budget ":name"', + 'update_amount' => 'Mettre à jour le montant', + 'update_budget' => 'Mettre à jour le budget', + 'update_budget_amount_range' => 'Mettre à jour le montant disponible (prévu) entre le :start et le :end', // bills: 'matching_on' => 'Matching on', - 'between_amounts' => 'between :low and :high.', - 'repeats' => 'Repeats', - 'connected_journals' => 'Connected transactions', - 'auto_match_on' => 'Automatically matched by Firefly', - 'auto_match_off' => 'Not automatically matched by Firefly', - 'next_expected_match' => 'Next expected match', - 'delete_bill' => 'Delete bill ":name"', - 'deleted_bill' => 'Deleted bill ":name"', - 'edit_bill' => 'Edit bill ":name"', - 'more' => 'More', - 'rescan_old' => 'Rescan old transactions', - 'update_bill' => 'Update bill', - 'updated_bill' => 'Updated bill ":name"', - 'store_new_bill' => 'Store new bill', - 'stored_new_bill' => 'Stored new bill ":name"', - 'cannot_scan_inactive_bill' => 'Inactive bills cannot be scanned.', - 'rescanned_bill' => 'Rescanned everything.', - 'bill_date_little_relevance' => 'The only part of this date used by Firefly is the day. It is only useful when your bill arrives at exactly the same date every month. If the payment date of your bills varies, simply use the first of the month.', + 'between_amounts' => 'entre :low et :high.', + 'repeats' => 'Répétitions', + 'connected_journals' => 'Opérations liées', + 'auto_match_on' => 'Automatiquement mis en correspondance par Firefly', + 'auto_match_off' => 'Pas mis automatiquement en correspondance par Firefly', + 'next_expected_match' => 'Prochain montant attendu', + 'delete_bill' => 'Supprimer la facture ":name"', + 'deleted_bill' => 'Facture ":name" supprimée', + 'edit_bill' => 'Modifier la facture : ":name"', + 'more' => 'Plus', + 'rescan_old' => 'Réanalyser les anciennes opérations', + 'update_bill' => 'Mettre à jour la facture', + 'updated_bill' => 'Facture ":name" mise à jour', + 'store_new_bill' => 'Créer une nouvelle facture', + 'stored_new_bill' => 'Nouvelle facture ":name" créée', + 'cannot_scan_inactive_bill' => 'Les factures inactives ne peuvent pas être analysées.', + 'rescanned_bill' => 'Réanalyser tout.', + 'bill_date_little_relevance' => 'La seule partie de cette date utilisée par Firefly est le jour. Il n’est utile que lorsque votre facture arrive à exactement la même date chaque mois. Si la date de paiement de vos factures varie, il suffit d’utiliser le premier jour du mois.', + 'average_bill_amount_year' => 'Average bill amount (:year)', + 'average_bill_amount_overall' => 'Average bill amount (overall)', // accounts: - 'details_for_asset' => 'Details for asset account ":name"', - 'details_for_expense' => 'Details for expense account ":name"', - 'details_for_revenue' => 'Details for revenue account ":name"', - 'details_for_cash' => 'Details for cash account ":name"', - 'store_new_asset_account' => 'Store new asset account', - 'store_new_expense_account' => 'Store new expense account', - 'store_new_revenue_account' => 'Store new revenue account', - 'edit_asset_account' => 'Edit asset account ":name"', - 'edit_expense_account' => 'Edit expense account ":name"', - 'edit_revenue_account' => 'Edit revenue account ":name"', - 'delete_asset_account' => 'Delete asset account ":name"', - 'delete_expense_account' => 'Delete expense account ":name"', - 'delete_revenue_account' => 'Delete revenue account ":name"', - 'asset_deleted' => 'Successfully deleted asset account ":name"', - 'expense_deleted' => 'Successfully deleted expense account ":name"', - 'revenue_deleted' => 'Successfully deleted revenue account ":name"', - 'update_asset_account' => 'Update asset account', - 'update_expense_account' => 'Update expense account', - 'update_revenue_account' => 'Update revenue account', - 'make_new_asset_account' => 'Create a new asset account', - 'make_new_expense_account' => 'Create a new expense account', - 'make_new_revenue_account' => 'Create a new revenue account', - 'asset_accounts' => 'Asset accounts', - 'expense_accounts' => 'Expense accounts', - 'revenue_accounts' => 'Revenue accounts', - 'cash_accounts' => 'Cash accounts', - 'Cash account' => 'Cash account', + 'details_for_asset' => 'Détails pour le compte d’actif ":name"', + 'details_for_expense' => 'Détail du compte de dépenses ":name"', + 'details_for_revenue' => 'Détails du comptes de recettes ":name"', + 'details_for_cash' => 'Détails pour le compte de trésorerie ":name"', + 'store_new_asset_account' => 'Créer un nouveau compte d’actif', + 'store_new_expense_account' => 'Créer un nouveau compte de dépenses', + 'store_new_revenue_account' => 'Créer un compte de recettes', + 'edit_asset_account' => 'Modifier le compte d’actif ":name"', + 'edit_expense_account' => 'Modifier le compte de dépenses ";name"', + 'edit_revenue_account' => 'Modifier le compte de recettes ":name"', + 'delete_asset_account' => 'Supprimer le compte d’actif ":name"', + 'delete_expense_account' => 'Supprimer le compte de dépenses ":name"', + 'delete_revenue_account' => 'Supprimer le compte de recettes ":name"', + 'asset_deleted' => 'Compte d’actif ":name" correctement supprimé', + 'expense_deleted' => 'Compte de dépenses ":name" correctement supprimé', + 'revenue_deleted' => 'Compte de recettes ":name" correctement supprimé', + 'update_asset_account' => 'Mettre à jour le compte d’actif', + 'update_expense_account' => 'Mettre à jour le compte de dépenses', + 'update_revenue_account' => 'Mettre à jour le compte de recettes', + 'make_new_asset_account' => 'Créer un nouveau compte d’actif', + 'make_new_expense_account' => 'Créer un nouveau compte de dépenses', + 'make_new_revenue_account' => 'Créer un nouveau compte de recettes', + 'asset_accounts' => 'Comptes d’actif', + 'expense_accounts' => 'Comptes de dépenses', + 'revenue_accounts' => 'Comptes de recettes', + 'cash_accounts' => 'Comptes de trésorerie', + 'Cash account' => 'Compte de trésorerie', 'accountExtraHelp_asset' => '', 'accountExtraHelp_expense' => '', 'accountExtraHelp_revenue' => '', - 'account_type' => 'Account type', - 'save_transactions_by_moving' => 'Save these transaction(s) by moving them to another account:', - 'stored_new_account' => 'New account ":name" stored!', - 'updated_account' => 'Updated account ":name"', - 'credit_card_options' => 'Credit card options', + 'account_type' => 'Type de compte', + 'save_transactions_by_moving' => 'Enregistrer ces opération(s) en les déplaçant vers un autre compte :', + 'stored_new_account' => 'Nouveau compte ":name" créé !', + 'updated_account' => 'Nom du compte ":name"', + 'credit_card_options' => 'Cartes de crédit', // categories: - 'new_category' => 'New category', - 'create_new_category' => 'Create a new category', - 'without_category' => 'Without a category', - 'update_category' => 'Update category', - 'updated_category' => 'Updated category ":name"', - 'categories' => 'Categories', - 'edit_category' => 'Edit category ":name"', - 'no_category' => '(no category)', - 'category' => 'Category', - 'delete_category' => 'Delete category ":name"', - 'deleted_category' => 'Deleted category ":name"', - 'store_category' => 'Store new category', + 'new_category' => 'Nouvelle catégorie', + 'create_new_category' => 'Créer une nouvelle catégorie', + 'without_category' => 'Sans catégorie', + 'update_category' => 'Modifier la catégorie', + 'updated_category' => 'Catégorie ":name" mise à jour', + 'categories' => 'Catégories', + 'edit_category' => 'Modifier la catégorie ":name"', + 'no_category' => '(aucune catégorie)', + 'category' => 'Catégorie', + 'delete_category' => 'Supprimer la catégorie ":name"', + 'deleted_category' => 'Catégorie ":name" supprimée', + 'store_category' => 'Créer une nouvelle catgorie', 'stored_category' => 'Stored new category ":name"', - 'without_category_between' => 'Without category between :start and :end', + 'without_category_between' => 'Sans catégorie entre :start et :end', // transactions: - 'update_withdrawal' => 'Update withdrawal', - 'update_deposit' => 'Update deposit', - 'update_transfer' => 'Update transfer', - 'updated_withdrawal' => 'Updated withdrawal ":description"', - 'updated_deposit' => 'Updated deposit ":description"', - 'updated_transfer' => 'Updated transfer ":description"', - 'delete_withdrawal' => 'Delete withdrawal ":description"', - 'delete_deposit' => 'Delete deposit ":description"', - 'delete_transfer' => 'Delete transfer ":description"', - 'deleted_withdrawal' => 'Successfully deleted withdrawal ":description"', - 'deleted_deposit' => 'Successfully deleted deposit ":description"', - 'deleted_transfer' => 'Successfully deleted transfer ":description"', - 'stored_journal' => 'Successfully created new transaction ":description"', - 'select_transactions' => 'Select transactions', + 'update_withdrawal' => 'Mettre à jour un retrait', + 'update_deposit' => 'Mettre à jour un dépôt', + 'update_transfer' => 'Mettre à jour un transfert', + 'updated_withdrawal' => 'Retrait ":description" mis à jour', + 'updated_deposit' => 'Dépôt ":description" mis à jour', + 'updated_transfer' => 'Transfert ":description" mis à jour', + 'delete_withdrawal' => 'Supprimer le retrait ":description"', + 'delete_deposit' => 'Supprimer le dépôt ":description"', + 'delete_transfer' => 'Supprimer le transfert ":description"', + 'deleted_withdrawal' => 'Retrait ":name" correctement supprimé', + 'deleted_deposit' => 'Dépot ":name" correctement supprimé', + 'deleted_transfer' => 'Opération ":name" correctement supprimée', + 'stored_journal' => 'Opération créée avec succès ":description"', + 'select_transactions' => 'Sélectionner des opérations', 'stop_selection' => 'Stop selecting transactions', - 'edit_selected' => 'Edit selected', - 'delete_selected' => 'Delete selected', + 'edit_selected' => 'Modifier la sélection', + 'delete_selected' => 'Supprimer la sélection', 'mass_delete_journals' => 'Delete a number of transactions', - 'mass_edit_journals' => 'Edit a number of transactions', - 'cannot_edit_other_fields' => 'You cannot mass-edit other fields than the ones here, because there is no room to show them. Please follow the link and edit them by one-by-one, if you need to edit these fields.', + 'mass_edit_journals' => 'Modifier un certain nombre d’opérations', + 'cannot_edit_other_fields' => 'Vous ne peut pas modifier en masse d\'autres champs que ceux ici, car il n’y a pas de place pour tous les montrer. S’il vous plaît suivez le lien et modifiez les par un par un, si vous devez modifier ces champs.', 'perm-delete-many' => 'Deleting many items in one go can be very disruptive. Please be cautious.', - 'mass_deleted_transactions_success' => 'Deleted :amount transaction(s).', - 'mass_edited_transactions_success' => 'Updated :amount transaction(s)', + 'mass_deleted_transactions_success' => 'Montant des opérations supprimées : :amount.', + 'mass_edited_transactions_success' => 'Montant des opérations mises à jour : :amount', // new user: - 'welcome' => 'Welcome to Firefly!', - 'createNewAsset' => 'Create a new asset account to get started. ' . - 'This will allow you to create transactions and start your financial management', - 'createNewAssetButton' => 'Create new asset account', + 'welcome' => 'Bienvenue sur Firefly !', + 'createNewAsset' => 'Créer un nouveau compte d’actif pour commencer. ' . + 'Cela vous permettra de créer des opérations et de commencer votre gestion financière', + 'createNewAssetButton' => 'Créer un nouveau compte d’actif', // home page: - 'yourAccounts' => 'Your accounts', - 'budgetsAndSpending' => 'Budgets and spending', - 'savings' => 'Savings', - 'markAsSavingsToContinue' => 'Mark your asset accounts as "Savings account" to fill this panel', - 'createPiggyToContinue' => 'Create piggy banks to fill this panel.', - 'newWithdrawal' => 'New expense', - 'newDeposit' => 'New deposit', - 'newTransfer' => 'New transfer', - 'moneyIn' => 'Money in', - 'moneyOut' => 'Money out', - 'billsToPay' => 'Bills to pay', - 'billsPaid' => 'Bills paid', - 'viewDetails' => 'View details', - 'divided' => 'divided', - 'toDivide' => 'left to divide', + 'yourAccounts' => 'Vos comptes', + 'budgetsAndSpending' => 'Budgets et dépenses', + 'savings' => 'Épargne', + 'markAsSavingsToContinue' => 'Marquez votre compte d’actif comme "Compte d\'épargne" pour remplir ce panneau', + 'createPiggyToContinue' => 'Créer des tirelires pour remplir ce panneau.', + 'newWithdrawal' => 'Nouvelle dépense', + 'newDeposit' => 'Nouveau dépôt', + 'newTransfer' => 'Nouveau transfert', + 'moneyIn' => 'Argent entrant', + 'moneyOut' => 'Argent sortant', + 'billsToPay' => 'Factures à payer', + 'billsPaid' => 'Factures payées', + 'viewDetails' => 'Voir les détails', + 'divided' => 'divisé', + 'toDivide' => 'Restant à dépenser', // menu and titles, should be recycled as often as possible: - 'toggleNavigation' => 'Toggle navigation', - 'currency' => 'Currency', - 'preferences' => 'Preferences', - 'logout' => 'Logout', - 'searchPlaceholder' => 'Search...', - 'dashboard' => 'Dashboard', - 'currencies' => 'Currencies', - 'accounts' => 'Accounts', - 'Asset account' => 'Asset account', - 'Default account' => 'Asset account', - 'Expense account' => 'Expense account', - 'Revenue account' => 'Revenue account', - 'Initial balance account' => 'Initial balance account', + 'toggleNavigation' => 'Basculer la navigation', + 'currency' => 'Devise', + 'preferences' => 'Préférences', + 'logout' => 'Se déconnecter', + 'searchPlaceholder' => 'Rechercher...', + 'dashboard' => 'Tableau de Bord', + 'currencies' => 'Devises', + 'accounts' => 'Comptes', + 'Asset account' => 'Compte d’actif', + 'Default account' => 'Compte d’actif', + 'Expense account' => 'Compte de dépenses', + 'Revenue account' => 'Compte de recettes', + 'Initial balance account' => 'Balance initiale', 'budgets' => 'Budgets', 'tags' => 'Tags', - 'reports' => 'Reports', - 'transactions' => 'Transactions', - 'expenses' => 'Expenses', - 'income' => 'Revenue / income', + 'reports' => 'Rapports', + 'transactions' => 'Opérations', + 'expenses' => 'Dépenses', + 'income' => 'Recette / revenu', 'transfers' => 'Transferts', - 'moneyManagement' => 'Money management', - 'piggyBanks' => 'Piggy banks', - 'bills' => 'Bills', - 'createNew' => 'Create new', - 'withdrawal' => 'Withdrawal', - 'deposit' => 'Deposit', - 'account' => 'Account', - 'transfer' => 'Transfer', - 'Withdrawal' => 'Withdrawal', - 'Deposit' => 'Deposit', - 'Transfer' => 'Transfer', - 'bill' => 'Bill', - 'yes' => 'Yes', - 'no' => 'No', - 'amount' => 'Amount', - 'newBalance' => 'New balance', - 'overview' => 'Overview', - 'saveOnAccount' => 'Save on account', - 'unknown' => 'Unknown', - 'daily' => 'Daily', - 'weekly' => 'Weekly', - 'monthly' => 'Monthly', - 'quarterly' => 'Quarterly', - 'half-year' => 'Every six months', - 'yearly' => 'Yearly', - 'profile' => 'Profile', + 'moneyManagement' => 'Gérer les comptes', + 'piggyBanks' => 'Tirelires', + 'bills' => 'Factures', + 'createNew' => 'Créer un nouveau', + 'withdrawal' => 'Retrait', + 'deposit' => 'Dépôt', + 'account' => 'Compte', + 'transfer' => 'Transfert', + 'Withdrawal' => 'Retrait', + 'Deposit' => 'Dépôt', + 'Transfer' => 'Transfert', + 'bill' => 'Facture', + 'yes' => 'Oui', + 'no' => 'Non', + 'amount' => 'Montant', + 'newBalance' => 'Nouveau solde', + 'overview' => 'Vue globale', + 'saveOnAccount' => 'Sauvegarder le compte', + 'unknown' => 'Inconnu', + 'daily' => 'Journalier', + 'monthly' => 'Mensuel', + 'profile' => 'Profil', + 'errors' => 'Errors', // reports: - 'report_default' => 'Default financial report for :start until :end', - 'report_audit' => 'Transaction history overview for :start until :end', - 'quick_link_reports' => 'Quick links', - 'quick_link_default_report' => 'Default financial report', - 'quick_link_audit_report' => 'Transaction history overview', - 'report_this_month_quick' => 'Current month, all accounts', - 'report_this_year_quick' => 'Current year, all accounts', - 'report_this_fiscal_year_quick' => 'Current fiscal year, all accounts', + 'report_default' => 'Rapport financier par défaut du :start au :end', + 'report_audit' => 'Historique des transactions du :start au :end', + 'quick_link_reports' => 'Liens rapides', + 'quick_link_default_report' => 'Rapport financier par défaut', + 'quick_link_audit_report' => 'Historique des transactions', + 'report_this_month_quick' => 'Mois en cours, tous les comptes', + 'report_this_year_quick' => 'Année en cours, tous les comptes', + 'report_this_fiscal_year_quick' => 'Année fiscale en cours, tous les comptes', 'report_all_time_quick' => 'All-time, all accounts', 'reports_can_bookmark' => 'Remember that reports can be bookmarked.', - 'incomeVsExpenses' => 'Income vs. expenses', - 'accountBalances' => 'Account balances', - 'balanceStartOfYear' => 'Balance at start of year', - 'balanceEndOfYear' => 'Balance at end of year', - 'balanceStartOfMonth' => 'Balance at start of month', - 'balanceEndOfMonth' => 'Balance at end of month', + 'incomeVsExpenses' => 'Revenus vs dépenses', + 'accountBalances' => 'Solde du compte', + 'balanceStartOfYear' => 'Solde au début de l\'année', + 'balanceEndOfYear' => 'Solde à la fin de l\'année', + 'balanceStartOfMonth' => 'Solde au début du mois', + 'balanceEndOfMonth' => 'Solde à la fin du mois', 'balanceStart' => 'Balance at start of period', 'balanceEnd' => 'Balance at end of period', - 'reportsOwnAccounts' => 'Reports for your own accounts', - 'reportsOwnAccountsAndShared' => 'Reports for your own accounts and shared accounts', + 'reportsOwnAccounts' => 'Rapport pour vos propres comptes', + 'reportsOwnAccountsAndShared' => 'Rapport pour vos comptes et ceux partagés', 'splitByAccount' => 'Split by account', 'balancedByTransfersAndTags' => 'Balanced by transfers and tags', 'coveredWithTags' => 'Covered with tags', 'leftUnbalanced' => 'Left unbalanced', 'expectedBalance' => 'Expected balance', 'outsideOfBudgets' => 'Outside of budgets', - 'leftInBudget' => 'Left in budget', - 'sumOfSums' => 'Sum of sums', - 'noCategory' => '(no category)', + 'leftInBudget' => 'Budget restant', + 'sumOfSums' => 'Montant des sommes', + 'noCategory' => '(aucune catégorie)', 'notCharged' => 'Not charged (yet)', - 'inactive' => 'Inactive', - 'active' => 'Active', - 'difference' => 'Difference', + 'inactive' => 'Désactivé', + 'active' => 'Actif', + 'difference' => 'Différence', 'in' => 'In', 'out' => 'Out', 'topX' => 'top :number', - 'showTheRest' => 'Show everything', - 'hideTheRest' => 'Show only the top :number', - 'sum_of_year' => 'Sum of year', - 'sum_of_years' => 'Sum of years', - 'average_of_year' => 'Average of year', + 'showTheRest' => 'Tout Afficher', + 'hideTheRest' => 'Afficher uniquement le top :number', + 'sum_of_year' => 'Total sur l’année', + 'sum_of_years' => 'Total des années', + 'average_of_year' => 'Moyenne sur l\'année', 'average_of_years' => 'Average of years', - 'categories_earned_in_year' => 'Categories (by earnings)', - 'categories_spent_in_year' => 'Categories (by spendings)', - 'report_type' => 'Report type', - 'report_type_default' => 'Default financial report', - 'report_type_audit' => 'Transaction history overview (audit)', - 'report_type_meta-history' => 'Categories, budgets and bills overview', + 'categories_earned_in_year' => 'Catégories (selon le revenu)', + 'categories_spent_in_year' => 'Catégories (par dépenses)', + 'report_type' => 'Type de rapport', + 'report_type_default' => 'Rapport financier par défaut', + 'report_type_audit' => 'Historique des transactions', + 'report_type_meta-history' => 'Vue d’ensemble des budgets, des catégories et des factures', 'more_info_help' => 'More information about these types of reports can be found in the help pages. Press the (?) icon in the top right corner.', 'report_included_accounts' => 'Included accounts', - 'report_date_range' => 'Date range', - 'report_include_help' => 'In all cases, transfers to shared accounts count as expenses, and transfers from shared accounts count as income.', - 'report_preset_ranges' => 'Pre-set ranges', - 'shared' => 'Shared', - 'fiscal_year' => 'Fiscal year', + 'report_date_range' => 'Intervalle de dates', + 'report_include_help' => 'Dans tous les cas, les transferts vers des comptes partagés comptes comme des dépenses, et les transferts depuis les comptes partagés comme un revenu.', + 'report_preset_ranges' => 'Pré-configurer les étendues', + 'shared' => 'Partagé', + 'fiscal_year' => 'Année fiscale', 'income_entry' => 'Income from account ":name" between :start and :end', - 'expense_entry' => 'Expenses to account ":name" between :start and :end', - 'category_entry' => 'Expenses in category ":name" between :start and :end', - 'budget_spent_amount' => 'Expenses in budget ":budget" between :start and :end', - 'balance_amount' => 'Expenses in budget ":budget" paid from account ":account" between :start and :end', + 'expense_entry' => 'Dépenses du compte ":name" entre le :start et le :end', + 'category_entry' => 'Dépenses dans la catégorie ":name" entre le :start et le :end', + 'budget_spent_amount' => 'Dépenses dans le budget ":budget" entre le :start et le :end', + 'balance_amount' => 'Dépenses dans le budget ":budget" payé depuis le compte ":account" entre le :start et le :end', 'no_audit_activity' => 'No activity was recorded on account :account_name between :start and :end.', 'audit_end_balance' => 'Account balance of :account_name at the end of :end was: :balance', // charts: 'chart' => 'Chart', - 'dayOfMonth' => 'Day of the month', - 'month' => 'Month', + 'dayOfMonth' => 'Jour du mois', + 'month' => 'Mois', 'budget' => 'Budget', - 'spent' => 'Spent', - 'earned' => 'Earned', + 'spent' => 'Dépensé', + 'earned' => 'Gagné', 'overspent' => 'Overspent', - 'left' => 'Left', - 'no_budget' => '(no budget)', - 'maxAmount' => 'Maximum amount', - 'minAmount' => 'Minumum amount', + 'left' => 'Gauche', + 'no_budget' => '(pas de budget)', + 'maxAmount' => 'Montant maximum', + 'minAmount' => 'Montant minimum', 'billEntry' => 'Current bill entry', - 'name' => 'Name', + 'name' => 'Nom', 'date' => 'Date', - 'paid' => 'Paid', - 'unpaid' => 'Unpaid', - 'day' => 'Day', - 'budgeted' => 'Budgeted', - 'period' => 'Period', + 'paid' => 'Payé', + 'unpaid' => 'Impayé', + 'day' => 'Jour', + 'budgeted' => 'Budgétisé', + 'period' => 'Période', 'balance' => 'Balance', 'summary' => 'Summary', 'sum' => 'Sum', @@ -742,30 +649,31 @@ return [ 'balanceFor' => 'Balance for :name', // piggy banks: - 'piggy_bank' => 'Piggy bank', - 'new_piggy_bank' => 'Create new piggy bank', - 'store_piggy_bank' => 'Store new piggy bank', - 'stored_piggy_bank' => 'Store new piggy bank ":name"', - 'account_status' => 'Account status', + 'add_money_to_piggy' => 'Add money to piggy bank ":name"', + 'piggy_bank' => 'Tirelire', + 'new_piggy_bank' => 'Créer une nouvelle tirelire', + 'store_piggy_bank' => 'Créer une nouvelle tirelire', + 'stored_piggy_bank' => 'Créer une nouvelle tirelire ":name"', + 'account_status' => 'Statut du compte', 'left_for_piggy_banks' => 'Left for piggy banks', - 'sum_of_piggy_banks' => 'Sum of piggy banks', + 'sum_of_piggy_banks' => 'Somme des tirelires', 'saved_so_far' => 'Saved so far', 'left_to_save' => 'Left to save', 'add_money_to_piggy_title' => 'Add money to piggy bank ":name"', 'remove_money_from_piggy_title' => 'Remove money from piggy bank ":name"', 'add' => 'Add', 'remove' => 'Remove', - 'max_amount_add' => 'The maximum amount you can add is', - 'max_amount_remove' => 'The maximum amount you can remove is', + 'max_amount_add' => 'Le montant maximum que vous pouvez ajouter est', + 'max_amount_remove' => 'Le montant maximum que vous pouvez supprimer est', 'update_piggy_button' => 'Update piggy bank', 'update_piggy_title' => 'Update piggy bank ":name"', 'updated_piggy_bank' => 'Updated piggy bank ":name"', - 'details' => 'Details', - 'events' => 'Events', - 'target_amount' => 'Target amount', - 'start_date' => 'Start date', - 'target_date' => 'Target date', - 'no_target_date' => 'No target date', + 'details' => 'Détails', + 'events' => 'Evènements', + 'target_amount' => 'Montant cible', + 'start_date' => 'Date de début', + 'target_date' => 'Date cible', + 'no_target_date' => 'Aucune date butoir', 'todo' => 'to do', 'table' => 'Table', 'piggy_bank_not_exists' => 'Piggy bank no longer exists.', @@ -773,66 +681,100 @@ return [ 'add_set_amount_to_piggy' => 'Add :amount to fill this piggy bank on :date', 'delete_piggy_bank' => 'Delete piggy bank ":name"', 'cannot_add_amount_piggy' => 'Could not add :amount to ":name".', - 'deleted_piggy_bank' => 'Deleted piggy bank ":name"', + 'deleted_piggy_bank' => 'Tirelire ":name" supprimée', 'added_amount_to_piggy' => 'Added :amount to ":name"', 'removed_amount_from_piggy' => 'Removed :amount from ":name"', 'cannot_remove_amount_piggy' => 'Could not remove :amount from ":name".', // tags 'regular_tag' => 'Just a regular tag.', - 'balancing_act' => 'The tag takes at most two transactions; an expense and a transfer. They\'ll balance each other out.', - 'advance_payment' => 'The tag accepts one expense and any number of deposits aimed to repay the original expense.', + 'balancing_act' => 'Un tag prend au maximum deux opérations : une dépense et un transfert. Ils s\'équilibreront mutuellement.', + 'advance_payment' => 'Un tag accepte une dépense et un nombre quelconque de dépôts visant à rembourser la dépense originale.', 'delete_tag' => 'Supprimer le tag ":tag"', - 'deleted_tag' => 'Deleted tag ":tag"', - 'new_tag' => 'Make new tag', - 'edit_tag' => 'Editer le tag ":tag"', + 'deleted_tag' => 'Tag ":tag" supprimé', + 'new_tag' => 'Créer un nouveau tag', + 'edit_tag' => 'Modifier le tag ":tag"', 'updated_tag' => 'Updated tag ":tag"', 'created_tag' => 'Tag ":tag" has been created!', 'no_year' => 'No year set', 'no_month' => 'No month set', - 'tag_title_nothing' => 'Default tags', + 'tag_title_nothing' => 'Tags par défaut', 'tag_title_balancingAct' => 'Balancing act tags', - 'tag_title_advancePayment' => 'Advance payment tags', - 'tags_introduction' => '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' => '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.', + 'tag_title_advancePayment' => 'Tags de paiement anticipé', + 'tags_introduction' => 'Les tags sont généralement des mots au singulier, conçus pour grouper rapidement des éléments en utilisant des mots comme cher, factures ou pour-fêtes. Dans Firefly III, les tags peuvent avoir plus de propriétés comme une date, la description et l’emplacement. Cela vous permet de réunir des opérations de façon plus significative. Par exemple, vous pourriez faire un tag appelé Dîner de Noël avec des amis et ajouter des informations sur le restaurant. Ces tags sont au singulier, vous devez seulement les utiliser pour une occasion unique, peut-être avec plusieurs opérations.', + 'tags_group' => 'Les tags groupent des opérations ensemble, ce qui permet de stocker des remboursements (dans le cas où vous avancer de l\'argent aux autres) et d\'autres types "d\'équilibres" où résumer les dépenses (les remboursements de votre nouvelle TV) ou quand les dépenses et les dépôts s\'annulent les uns les autres (achat de quelque chose avec de l\'argent mis de coté). C\'est comme vous souhaitez. Utiliser les tags à l\'ancienne est toujours possible.', 'tags_start' => 'Create a tag to get started or enter tags when creating new transactions.', // administration 'administration' => 'Administration', - 'user_administration' => 'User administration', - 'list_all_users' => 'All users', - 'all_users' => 'All users', + 'user_administration' => 'Gestion des utilisateurs', + 'list_all_users' => 'Tous les utilisateurs', + 'all_users' => 'Tous les utilisateurs', + 'all_blocked_domains' => 'All blocked domains', + 'blocked_domains' => 'Blocked domains', + 'no_domains_banned' => 'No domains blocked', + 'all_user_domains' => 'All user email address domains', + 'all_domains_is_filtered' => 'This list does not include already blocked domains.', + 'domain_now_blocked' => 'Domain :domain is now blocked', + 'domain_now_unblocked' => 'Domain :domain is now unblocked', + 'manual_block_domain' => 'Block a domain by hand', + 'block_domain' => 'Block domain', + 'no_domain_filled_in' => 'No domain filled in', + 'domain_already_blocked' => 'Domain :domain is already blocked', + 'domain_is_now_blocked' => 'Domain :domain is now blocked', // split a transaction: 'transaction_meta_data' => 'Transaction meta-data', - 'transaction_dates' => 'Transaction dates', + 'transaction_dates' => 'Date de l\'opération', 'splits' => 'Splits', 'split_title_withdrawal' => 'Split your new withdrawal', 'split_intro_one_withdrawal' => 'Firefly supports the "splitting" of a withdrawal.', - 'split_intro_two_withdrawal' => 'It means that the amount of money you\'ve spent is divided between several destination expense accounts, budgets or categories.', + 'split_intro_two_withdrawal' => 'Cela signifie que le montant d’argent que vous avez dépensé est réparti entre plusieurs budgets, catégories ou comptes de revenus.', 'split_intro_three_withdrawal' => 'For example: you could split your :total groceries so you pay :split_one from your "daily groceries" budget and :split_two from your "cigarettes" budget.', 'split_table_intro_withdrawal' => 'Split your withdrawal in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', 'store_splitted_withdrawal' => 'Store splitted withdrawal', 'update_splitted_withdrawal' => 'Update splitted withdrawal', + 'split_title_deposit' => 'Split your new deposit', + 'split_intro_one_deposit' => 'Firefly supports the "splitting" of a deposit.', + 'split_intro_two_deposit' => 'Cela signifie que le montant d’argent que vous avez gagné est réparti entre plusieurs catégories ou comptes de revenus source.', + 'split_intro_three_deposit' => 'Par exemple : vous pouvez fractionner votre salaire de :total donc vous obtenez :split_one comme votre salaire de base et :split_two comme un remboursement des dépenses faites.', + 'split_table_intro_deposit' => 'Split your deposit in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', + 'store_splitted_deposit' => 'Store splitted deposit', + 'split_title_transfer' => 'Split your new transfer', + 'split_intro_one_transfer' => 'Firefly supports the "splitting" of a transfer.', + 'split_intro_two_transfer' => 'Cela signifie que le montant d’argent que vous déplacez est divisé entre plusieurs catégories ou tirelires.', + 'split_intro_three_transfer' => 'For example: you could split your :total move so you get :split_one in one piggy bank and :split_two in another.', + 'split_table_intro_transfer' => 'Split your transfer in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', + 'store_splitted_transfer' => 'Store splitted transfer', + 'add_another_split' => 'Add another split', + 'split-transactions' => 'Split transactions', + 'split-new-transaction' => 'Split a new transaction', + 'do_split' => 'Do a split', + 'split_this_withdrawal' => 'Split this withdrawal', + 'split_this_deposit' => 'Split this deposit', + 'split_this_transfer' => 'Split this transfer', + 'cannot_edit_multiple_source' => 'You cannot edit splitted transaction #:id with description ":description" because it contains multiple source accounts.', + 'cannot_edit_multiple_dest' => 'You cannot edit splitted transaction #:id with description ":description" because it contains multiple destination accounts.', + 'no_edit_multiple_left' => 'You have selected no valid transactions to edit.', - 'split_title_deposit' => 'Split your new deposit', - 'split_intro_one_deposit' => 'Firefly supports the "splitting" of a deposit.', - 'split_intro_two_deposit' => 'It means that the amount of money you\'ve earned is divided between several source revenue accounts or categories.', - 'split_intro_three_deposit' => 'For example: you could split your :total salary so you get :split_one as your base salary and :split_two as a reimbursment for expenses made.', - 'split_table_intro_deposit' => 'Split your deposit in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', - 'store_splitted_deposit' => 'Store splitted deposit', - - 'split_title_transfer' => 'Split your new transfer', - 'split_intro_one_transfer' => 'Firefly supports the "splitting" of a transfer.', - 'split_intro_two_transfer' => 'It means that the amount of money you\'re moving is divided between several categories or piggy banks.', - 'split_intro_three_transfer' => 'For example: you could split your :total move so you get :split_one in one piggy bank and :split_two in another.', - 'split_table_intro_transfer' => 'Split your transfer in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', - 'store_splitted_transfer' => 'Store splitted transfer', - - 'add_another_split' => 'Add another split', - 'split-transactions' => 'Split transactions', - 'split-new-transaction' => 'Split a new transaction', - - + // import + 'configuration_file_help' => 'If you have previously imported data into Firefly III, you may have a configuration file, which will pre-set configuration values for you.', + 'import_data_index' => 'Index', + 'import_file_type_csv' => 'CSV (comma separated values)', + 'import_file_type_help' => 'Select the type of file you will upload', + 'import_start' => 'Start the import', + 'configure_import' => 'Further configure your import', + 'import_finish_configuration' => 'Finish configuration', + 'settings_for_import' => 'Settings', + 'import_complete' => 'Import configuration complete!', + 'import_complete_text' => 'The import is ready to start. All the configuration you needed to do has been done. Please download the configuration file. It will help you with the import should it not go as planned. To actually run the import, you need to execute the following command in your console. Unfortunately, a web-based import is not yet possible.', + 'import_download_config' => 'Download configuration', + 'import_start_import' => 'Start import', + 'import_intro_beta' => 'The import function of Firefly III is in beta. Many users of Firefly III have tried many different files. Although each individual compontent of this import routine works (really), the combination might break. If your file cannot be imported by Firefly, please read this wiki page so I can fix the problem you have run into.', + 'import_data' => 'Import data', + 'import_data_full' => 'Import data into Firefly III', + 'import' => 'Import', + 'import_intro_text' => 'Welcome to the Firefly III data import routine. At the moment, this routine can help you import files into Firefly. To do so, you must download or export transactions from other systems or software, and upload them here. The next steps will let you help Firefly III determin what the content is of your file, and how to handle it. Please select a file, and read all instructions carefully.', + 'import_file_help' => 'Select your file', ]; diff --git a/resources/lang/fr_FR/form.php b/resources/lang/fr_FR/form.php index 6babd72883..ed8b0d0163 100644 --- a/resources/lang/fr_FR/form.php +++ b/resources/lang/fr_FR/form.php @@ -14,127 +14,136 @@ return [ 'bank_balance' => 'Solde', 'savings_balance' => 'Solde de l\'épargne', 'credit_card_limit' => 'Limite de carte de crédit', - 'automatch' => 'Match automatically', - 'skip' => 'Skip', + 'automatch' => 'Correspondre automatiquement', + 'skip' => 'Ignorer', 'name' => 'Nom', 'active' => 'Actif', 'amount_min' => 'Montant minimum', 'amount_max' => 'Montant maximum', - 'match' => 'Matches on', - 'repeat_freq' => 'Repeats', - 'journal_currency_id' => 'Currency', - 'journal_amount' => 'Amount', - 'journal_asset_source_account' => 'Asset account (source)', - 'journal_source_account_name' => 'Revenue account (source)', - 'journal_source_account_id' => 'Asset account (source)', + 'match' => 'Correspondre à', + 'repeat_freq' => 'Répétitions', + 'journal_currency_id' => 'Devise', + 'journal_amount' => 'Montant', + 'journal_asset_source_account' => 'Compte d’actif (source)', + 'journal_source_account_name' => 'Compte de recettes (source)', + 'journal_source_account_id' => 'Compte d’actif (source)', 'account_from_id' => 'Compte d\'origine', 'account_to_id' => 'Compte de destination', - 'journal_destination_account_id' => 'Asset account (destination)', - 'asset_destination_account' => 'Asset account (destination)', - 'asset_source_account' => 'Asset account (source)', + 'journal_destination_account_id' => 'Compte d’actif (destination)', + 'asset_destination_account' => 'Compte d’actif (destination)', + 'asset_source_account' => 'Compte d’actif (source)', 'journal_description' => 'Description', - 'split_journal' => 'Split this transaction', - 'split_journal_explanation' => 'Split this transaction in multiple parts', - 'currency' => 'Currency', - 'account_id' => 'Asset account', + 'split_journal' => 'Ventiler cette opération', + 'split_journal_explanation' => 'Diviser cette opération en plusieurs parties', + 'currency' => 'Devise', + 'account_id' => 'Compte d’actif', 'budget_id' => 'Budget', 'openingBalance' => 'Solde initial', - 'tagMode' => 'Tag mode', - 'tagPosition' => 'Tag location', + 'tagMode' => 'Mode tag', + 'tagPosition' => 'Emplacement du tag', 'virtualBalance' => 'Solde virtuel', - 'longitude_latitude' => 'Location', - 'targetamount' => 'Target amount', - 'accountRole' => 'Account role', - 'openingBalanceDate' => 'Opening balance date', + 'longitude_latitude' => 'Emplacement', + 'targetamount' => 'Montant cible', + 'accountRole' => 'Rôle du compte', + 'openingBalanceDate' => 'Date du solde initial', 'ccType' => 'Credit card payment plan', 'ccMonthlyPaymentDate' => 'Credit card monthly payment date', 'piggy_bank_id' => 'Tirelire', 'returnHere' => 'Return here', - 'returnHereExplanation' => 'After storing, return here to create another one.', - 'returnHereUpdateExplanation' => 'After updating, return here.', + 'returnHereExplanation' => 'Après enregistrement, revenir ici pour en créer un nouveau.', + 'returnHereUpdateExplanation' => 'Après mise à jour, revenir ici.', 'description' => 'Description', - 'expense_account' => 'Expense account', - 'revenue_account' => 'Revenue account', - 'amount' => 'Amount', + 'expense_account' => 'Compte de dépenses', + 'revenue_account' => 'Compte de recettes', + 'amount' => 'Montant', 'date' => 'Date', 'interest_date' => 'Interest date', 'book_date' => 'Book date', 'process_date' => 'Processing date', - 'category' => 'Category', + 'category' => 'Catégorie', 'tags' => 'Tags', - 'deletePermanently' => 'Delete permanently', - 'cancel' => 'Cancel', - 'targetdate' => 'Target date', + 'deletePermanently' => 'Supprimer définitivement', + 'cancel' => 'Annuler', + 'targetdate' => 'Date cible', 'tag' => 'Tag', - 'under' => 'Under', - 'symbol' => 'Symbol', + 'under' => 'En dessous de', + 'symbol' => 'Symbole', 'code' => 'Code', 'iban' => 'IBAN', - 'accountNumber' => 'Account number', - 'csv' => 'CSV file', - 'has_headers' => 'Headers', - 'date_format' => 'Date format', - 'csv_config' => 'CSV import configuration', + 'accountNumber' => 'N° de compte', + 'has_headers' => 'Entêtes ', + 'date_format' => 'Format de la date', 'specifix' => 'Bank- or file specific fixes', - 'csv_import_account' => 'Default import account', - 'csv_delimiter' => 'CSV field delimiter', - 'attachments[]' => 'Attachments', - 'store_new_withdrawal' => 'Store new withdrawal', - 'store_new_deposit' => 'Store new deposit', - 'store_new_transfer' => 'Store new transfer', - 'add_new_withdrawal' => 'Add a new withdrawal', - 'add_new_deposit' => 'Add a new deposit', - 'add_new_transfer' => 'Add a new transfer', - 'noPiggybank' => '(no piggy bank)', - 'title' => 'Title', + 'attachments[]' => 'Pièces jointes', + 'store_new_withdrawal' => 'Enregistrer un nouveau retrait', + 'store_new_deposit' => 'Enregistrer un nouveau dépôt', + 'store_new_transfer' => 'Enregistrer un nouveau transfert', + 'add_new_withdrawal' => 'Ajouter un nouveau retrait', + 'add_new_deposit' => 'Ajouter un nouveau dépôt', + 'add_new_transfer' => 'Ajouter un nouveau transfert', + 'noPiggybank' => '(aucun tirelire)', + 'title' => 'Titre', 'notes' => 'Notes', - 'filename' => 'File name', - 'mime' => 'Mime type', - 'size' => 'Size', - 'trigger' => 'Trigger', - 'stop_processing' => 'Stop processing', - 'start_date' => 'Start of range', - 'end_date' => 'End of range', - 'export_start_range' => 'Start of export range', - 'export_end_range' => 'End of export range', - 'export_format' => 'File format', - 'include_attachments' => 'Include uploaded attachments', - 'include_config' => 'Include configuration file', - 'include_old_uploads' => 'Include imported data', - 'accounts' => 'Export transactions from these accounts', - 'csv_comma' => 'A comma (,)', - 'csv_semicolon' => 'A semicolon (;)', - 'csv_tab' => 'A tab (invisible)', - 'delete_account' => 'Delete account ":name"', + 'filename' => 'Nom du fichier', + 'mime' => 'Type Mime', + 'size' => 'Taille', + 'trigger' => 'Déclencheur', + 'stop_processing' => 'Arrêter le traitement', + 'start_date' => 'Début de l\'étendue', + 'end_date' => 'Fin de l\'étendue', + 'export_start_range' => 'Début de l’étendue d’exportation', + 'export_end_range' => 'Fin de l’étendue d\'exportation', + 'export_format' => 'Format de fichier', + 'include_attachments' => 'Inclure des pièces jointes téléchargées', + 'include_config' => 'Inclure le fichier de configuration', + 'include_old_uploads' => 'Inclure les données importées', + 'accounts' => 'Exporter les opérations depuis ces comptes', + 'delete_account' => 'Supprimer le compte ":name"', 'delete_bill' => 'Supprimer la facture ":name"', - 'delete_budget' => 'Delete budget ":name"', - 'delete_category' => 'Delete category ":name"', - 'delete_currency' => 'Delete currency ":name"', - 'delete_journal' => 'Delete transaction with description ":description"', - 'delete_attachment' => 'Delete attachment ":name"', - 'delete_rule' => 'Delete rule ":title"', - 'delete_rule_group' => 'Delete rule group ":title"', - 'attachment_areYouSure' => 'Are you sure you want to delete the attachment named ":name"?', - 'account_areYouSure' => 'Are you sure you want to delete the account named ":name"?', - 'bill_areYouSure' => 'Are you sure you want to delete the bill named ":name"?', - 'rule_areYouSure' => 'Are you sure you want to delete the rule titled ":title"?', - 'ruleGroup_areYouSure' => 'Are you sure you want to delete the rule group titled ":title"?', - 'budget_areYouSure' => 'Are you sure you want to delete the budget named ":name"?', - 'category_areYouSure' => 'Are you sure you want to delete the category named ":name"?', - 'currency_areYouSure' => 'Are you sure you want to delete the currency named ":name"?', - 'piggyBank_areYouSure' => 'Are you sure you want to delete the piggy bank named ":name"?', - 'journal_areYouSure' => 'Are you sure you want to delete the transaction described ":description"?', - 'mass_journal_are_you_sure' => 'Are you sure you want to delete these transactions?', - 'tag_areYouSure' => 'Are you sure you want to delete the tag ":tag"?', - 'permDeleteWarning' => 'Deleting stuff from Firely is permanent and cannot be undone.', - 'mass_make_selection' => 'You can still prevent items from being deleted by removing the checkbox.', - 'delete_all_permanently' => 'Delete selected permanently', - 'update_all_journals' => 'Update these transactions', - 'also_delete_transactions' => 'The only transaction connected to this account will be deleted as well.|All :count transactions connected to this account will be deleted as well.', - 'also_delete_rules' => 'The only rule connected to this rule group will be deleted as well.|All :count rules connected to this rule group will be deleted as well.', - 'also_delete_piggyBanks' => 'The only piggy bank connected to this account will be deleted as well.|All :count piggy bank connected to this account will be deleted as well.', - 'bill_keep_transactions' => 'The only transaction connected to this bill will not be deleted.|All :count transactions connected to this bill will spared deletion.', - 'budget_keep_transactions' => 'The only transaction connected to this budget will not be deleted.|All :count transactions connected to this budget will spared deletion.', - 'category_keep_transactions' => 'The only transaction connected to this category will not be deleted.|All :count transactions connected to this category will spared deletion.', - 'tag_keep_transactions' => 'The only transaction connected to this tag will not be deleted.|All :count transactions connected to this tag will spared deletion.', + 'delete_budget' => 'Supprimer le budget ":name"', + 'delete_category' => 'Supprimer la catégorie ":name"', + 'delete_currency' => 'Supprimer la devise ":name"', + 'delete_journal' => 'Supprimer l\'opération ayant comme description ":description"', + 'delete_attachment' => 'Supprimer la pièce jointe ":name"', + 'delete_rule' => 'Supprimer la règle ":title"', + 'delete_rule_group' => 'Supprimer le groupe de filtres ":title"', + 'attachment_areYouSure' => 'Êtes-vous sûr de vouloir supprimer la pièce jointe nommée ":name" ?', + 'account_areYouSure' => 'Êtes-vous sûr de vouloir supprimer le compte nommé ": ame" ?', + 'bill_areYouSure' => 'Êtes-vous sûr de vouloir supprimer la facture nommée ":name" ?', + 'rule_areYouSure' => 'Êtes-vous sûr de vouloir supprimer la règle intitulée ":title" ?', + 'ruleGroup_areYouSure' => 'Êtes-vous sûr de vouloir supprimer le groupe de règles intitulé ":title" ?', + 'budget_areYouSure' => 'Êtes-vous sûr de vouloir supprimer le budget nommé ":name" ?', + 'category_areYouSure' => 'Êtes-vous sûr de vouloir supprimer la catégorie nommée ":name" ?', + 'currency_areYouSure' => 'Êtes-vous sûr de vouloir supprimer la devise nommée ":name" ?', + 'piggyBank_areYouSure' => 'Êtes-vous sûr de vouloir supprimer la tirelire nommée ":name" ?', + 'journal_areYouSure' => 'Êtes-vous sûr de vouloir supprimer la description de l\'opération ":description" ?', + 'mass_journal_are_you_sure' => 'Êtes-vous sûr de que vouloir supprimer ces opérations ?', + 'tag_areYouSure' => 'Êtes-vous sûr de vouloir supprimer le tag ":tag" ?', + 'permDeleteWarning' => 'Supprimer quelque chose dans Firefly est permanent et ne peut pas être annulé.', + 'mass_make_selection' => 'Vous pouvez toujours empêcher des éléments d’être supprimés en décochant la case à cocher.', + 'delete_all_permanently' => 'Supprimer la selection définitivement', + 'update_all_journals' => 'Mettre à jour ces opérations', + 'also_delete_transactions' => 'La seule opération liée à ce compte sera aussi supprimée.|Les :count opérations liées à ce compte seront aussi supprimées.', + 'also_delete_rules' => 'La seule règle liée à ce groupe de règles sera aussi supprimée.|Les :count règles liées à ce groupe de règles seront aussi supprimées.', + 'also_delete_piggyBanks' => 'La seule tirelire liée à ce compte sera aussi supprimée.|Les :count tirelires liées à ce compte seront aussi supprimées.', + 'bill_keep_transactions' => 'La seule opération liée à cette facture ne sera pas supprimée.|Les :count opérations liées à cette facture ne seront pas supprimées.', + 'budget_keep_transactions' => 'La seule opération liée à ce budget ne sera pas supprimée.|Les :count opérations liées à ce budget ne seront pas supprimées.', + 'category_keep_transactions' => 'La seule opération liée à cette catégorie ne sera pas supprimée.|Les :count opérations liées à cette catégorie ne seront pas supprimées.', + 'tag_keep_transactions' => 'La seule opération liée à ce tag ne sera pas supprimée.|Les :count opérations liées à ce tag ne seront pas supprimées.', + + // admin + 'domain' => 'Domain', + + // import + 'import_file' => 'Import file', + 'configuration_file' => 'Configuration file', + 'import_file_type' => 'Import file type', + 'csv_comma' => 'Une virgule (,)', + 'csv_semicolon' => 'Un point-virgule (;)', + 'csv_tab' => 'Un onglet (invisible)', + 'csv_delimiter' => 'Délimiteur de champ CSV', + 'csv_import_account' => 'Compte d’importation par défaut', + 'csv_config' => 'Configuration d\'importation CSV', + + ]; diff --git a/resources/lang/fr_FR/help.php b/resources/lang/fr_FR/help.php index 6cee914b70..77facb6918 100644 --- a/resources/lang/fr_FR/help.php +++ b/resources/lang/fr_FR/help.php @@ -11,80 +11,75 @@ return [ // tour! 'main-content-title' => 'Bienvenue sur Firefly III', - 'main-content-text' => 'Do yourself a favor and follow this short guide to make sure you know your way around.', - 'sidebar-toggle-title' => 'Sidebar to create stuff', - 'sidebar-toggle-text' => 'Hidden under the plus icon are all the buttons to create new stuff. Accounts, transactions, everything!', - 'account-menu-title' => 'All your accounts', - 'account-menu-text' => 'Here you can find all the accounts you\'ve made.', + 'main-content-text' => 'Rendez-vous service et suivez ce petit guide. Vous saurez exactement comment tout fonctionne.', + 'sidebar-toggle-title' => 'Barre latérale pour créer quelque chose', + 'sidebar-toggle-text' => 'Sous l\'icone plus sont cachés tous les boutons permettant de créer quelque chose. Comptes, opérations, tous!', + 'account-menu-title' => 'Tous vos comptes', + 'account-menu-text' => 'Vous trouverez ici tous les comptes que vous avez fait.', 'budget-menu-title' => 'Budgets', - 'budget-menu-text' => 'Use this page to organise your finances and limit spending.', - 'report-menu-title' => 'Rapport', - 'report-menu-text' => 'Check this out when you want a solid overview of your finances.', - 'transaction-menu-title' => 'Transactions', + 'budget-menu-text' => 'Utilisez cette page pour organiser vos finances et limiter les dépenses.', + 'report-menu-title' => 'Rapports', + 'report-menu-text' => 'Cochez cette case si vous voulez un aperçu complet de vos finances.', + 'transaction-menu-title' => 'Opérations', 'transaction-menu-text' => 'Toutes les transactions que vous avez créé peuvent être trouvées ici.', 'option-menu-title' => 'Options', 'option-menu-text' => 'C\'est assez explicite.', 'main-content-end-title' => 'Fin !', 'main-content-end-text' => 'N\'oubliez pas que chaque page a un petit point d\'interrogation en haut à droite. Cliquez dessus pour obtenir de l\'aide concernant la page actuelle.', 'index' => 'index', - 'home' => 'home', - 'accounts-index' => 'accounts.index', - 'accounts-create' => 'accounts.create', - 'accounts-edit' => 'accounts.edit', - 'accounts-delete' => 'accounts.delete', - 'accounts-show' => 'accounts.show', - 'attachments-edit' => 'attachments.edit', - 'attachments-delete' => 'attachments.delete', - 'attachments-show' => 'attachments.show', - 'attachments-preview' => 'attachments.preview', - 'bills-index' => 'bills.index', - 'bills-create' => 'bills.create', - 'bills-edit' => 'bills.edit', - 'bills-delete' => 'bills.delete', - 'bills-show' => 'bills.show', - 'budgets-index' => 'budgets.index', - 'budgets-create' => 'budgets.create', - 'budgets-edit' => 'budgets.edit', - 'budgets-delete' => 'budgets.delete', - 'budgets-show' => 'budgets.show', - 'budgets-noBudget' => 'budgets.noBudget', - 'categories-index' => 'categories.index', - 'categories-create' => 'categories.create', - 'categories-edit' => 'categories.edit', - 'categories-delete' => 'categories.delete', - 'categories-show' => 'categories.show', - 'categories-show-date' => 'categories.show.date', - 'categories-noCategory' => 'categories.noCategory', - 'csv-index' => 'csv.index', - 'csv-column-roles' => 'csv.column-roles', - 'csv-map' => 'csv.map', - 'csv-download-config-page' => 'csv.download-config-page', - 'csv-process' => 'csv.process', - 'currency-index' => 'currency.index', - 'currency-create' => 'currency.create', - 'currency-edit' => 'currency.edit', - 'currency-delete' => 'currency.delete', - 'new-user-index' => 'new-user.index', - 'piggy-banks-index' => 'piggy-banks.index', - 'piggy-banks-create' => 'piggy-banks.create', - 'piggy-banks-edit' => 'piggy-banks.edit', - 'piggy-banks-delete' => 'piggy-banks.delete', - 'piggy-banks-show' => 'piggy-banks.show', - 'preferences' => 'preferences', + 'home' => 'accueil', + 'accounts-index' => 'comptes', + 'accounts-create' => 'créer un compte', + 'accounts-edit' => 'éditer un compte', + 'accounts-delete' => 'supprimer un compte', + 'accounts-show' => 'visualiser un compte', + 'attachments-edit' => 'modifier la pièce jointe', + 'attachments-delete' => 'supprimer la pièce jointe', + 'attachments-show' => 'visualiser la pièce jointe', + 'attachments-preview' => 'prévisualiser les pièces jointes', + 'bills-index' => 'factures', + 'bills-create' => 'créer une facture', + 'bills-edit' => 'éditer une facture', + 'bills-delete' => 'supprimer une facture', + 'bills-show' => 'visualiser une facture', + 'budgets-index' => 'budgets', + 'budgets-create' => 'créer un budget', + 'budgets-edit' => 'éditer un budget', + 'budgets-delete' => 'supprimer un budget', + 'budgets-show' => 'visualiser un budget', + 'budgets-noBudget' => 'opérations sans budgets', + 'categories-index' => 'catégories', + 'categories-create' => 'créer des catégories', + 'categories-edit' => 'éditer les catégories', + 'categories-delete' => 'supprimer des catégories', + 'categories-show' => 'visualiser une catégorie', + 'categories-show-date' => 'voir la catégorie', + 'categories-noCategory' => 'opérations sans catégories', + 'currency-index' => 'devises', + 'currency-create' => 'créer une devise', + 'currency-edit' => 'éditer une devise', + 'currency-delete' => 'supprimer une devise', + 'new-user-index' => 'nouvel utilisateur', + 'piggy-banks-index' => 'tirelires', + 'piggy-banks-create' => 'créer une tirelire', + 'piggy-banks-edit' => 'éditer une tirelire', + 'piggy-banks-delete' => 'supprimer une tirelire', + 'piggy-banks-show' => 'visualiser une tire-lire', + 'preferences' => 'préférences', 'profile' => 'profile', - 'profile-change-password' => 'profile.change-password', - 'profile-delete-account' => 'profile.delete-account', - 'reports-index' => 'reports.index', - 'reports-report' => 'reports.report', - 'search' => 'search', - 'tags-index' => 'tags.index', - 'tags-create' => 'tags.create', - 'tags-show' => 'tags.show', - 'tags-edit' => 'tags.edit', - 'tags-delete' => 'tags.delete', - 'transactions-index' => 'transactions.index', - 'transactions-create' => 'transactions.create', - 'transactions-edit' => 'transactions.edit', - 'transactions-delete' => 'transactions.delete', - 'transactions-show' => 'transactions.show', + 'profile-change-password' => 'changez votre mot de passe', + 'profile-delete-account' => 'supprimer votre compte', + 'reports-index' => 'rapports', + 'reports-report' => 'rapports', + 'search' => 'recherche', + 'tags-index' => 'tags', + 'tags-create' => 'créer un tag', + 'tags-show' => 'visualiser un tag', + 'tags-edit' => 'éditer un tag', + 'tags-delete' => 'supprimer un tag', + 'transactions-index' => 'opérations', + 'transactions-create' => 'créer une opération', + 'transactions-edit' => 'éditer une opération', + 'transactions-delete' => 'supprimer une opération', + 'transactions-show' => 'visualiser une opération', ]; diff --git a/resources/lang/fr_FR/list.php b/resources/lang/fr_FR/list.php index 97815e936d..f68f3a1291 100644 --- a/resources/lang/fr_FR/list.php +++ b/resources/lang/fr_FR/list.php @@ -8,54 +8,59 @@ */ return [ - 'buttons' => 'Buttons', - 'icon' => 'Icon', - 'create_date' => 'Created at', - 'update_date' => 'Updated at', - 'balance_before' => 'Balance before', - 'balance_after' => 'Balance after', - 'name' => 'Nom', - 'role' => 'Rôle', - 'currentBalance' => 'Solde courant', - 'active' => 'Actif ?', - 'lastActivity' => 'Activité récente', - 'balanceDiff' => 'Difference solde entre :start et :end', - 'matchedOn' => 'Matched on', - 'matchesOn' => 'Matched on', - 'account_type' => 'Account type', - 'new_balance' => 'New balance', - 'account' => 'Account', - 'matchingAmount' => 'Montant', - 'lastMatch' => 'Last match', - 'split_number' => 'Split #', - 'destination' => 'Destination', - 'expectedMatch' => 'Expected match', - 'automatch' => 'Auto match?', - 'repeat_freq' => 'Repeats', - 'description' => 'Description', - 'amount' => 'Amount', - 'date' => 'Date', - 'interest_date' => 'Interest date', - 'book_date' => 'Book date', - 'process_date' => 'Processing date', - 'from' => 'From', - 'piggy_bank' => 'Piggy bank', - 'to' => 'To', - 'budget' => 'Budget', - 'category' => 'Category', - 'bill' => 'Bill', - 'withdrawal' => 'Withdrawal', - 'deposit' => 'Deposit', - 'transfer' => 'Transfer', - 'type' => 'Type', - 'completed' => 'Completed', - 'iban' => 'IBAN', - 'paid_current_period' => 'Paid this period', - 'email' => 'Email', - 'registered_at' => 'Registered at', - 'is_activated' => 'Is activated', - 'is_blocked' => 'Is blocked', - 'is_admin' => 'Is admin', - 'has_two_factor' => 'Has 2FA', - 'blocked_code' => 'Block code', + 'buttons' => 'Boutons', + 'icon' => 'Icône', + 'create_date' => 'Créé le', + 'update_date' => 'Mis à jour le', + 'balance_before' => 'Solde avant', + 'balance_after' => 'Solde après', + 'name' => 'Nom', + 'role' => 'Rôle', + 'currentBalance' => 'Solde courant', + 'active' => 'Actif ?', + 'lastActivity' => 'Activité récente', + 'balanceDiff' => 'Difference solde entre :start et :end', + 'matchedOn' => 'Correspond à', + 'matchesOn' => 'Correspond à', + 'account_type' => 'Type de compte', + 'new_balance' => 'Nouveau solde', + 'account' => 'Compte', + 'matchingAmount' => 'Montant', + 'lastMatch' => 'Dernière correspondance', + 'split_number' => 'Segmenter en', + 'destination' => 'Destination', + 'source' => 'Source', + 'expectedMatch' => 'Correspondance attendue', + 'automatch' => 'Correspondance automatique ?', + 'repeat_freq' => 'Répétitions', + 'description' => 'Description', + 'amount' => 'Montant', + 'date' => 'Date', + 'interest_date' => 'Date des intérêts', + 'book_date' => 'Book date', + 'process_date' => 'Date de traitement', + 'from' => 'Depuis', + 'piggy_bank' => 'Tirelire', + 'to' => 'À', + 'budget' => 'Budget', + 'category' => 'Catégorie', + 'bill' => 'Facture', + 'withdrawal' => 'Retrait', + 'deposit' => 'Dépôt', + 'transfer' => 'Transfert', + 'type' => 'Type', + 'completed' => 'Terminé', + 'iban' => 'IBAN', + 'paid_current_period' => 'Payé cette période', + 'email' => 'E-mail', + 'registered_at' => 'Enregistré le', + 'is_activated' => 'Est activé', + 'is_blocked' => 'Est bloqué', + 'is_admin' => 'Est admin', + 'has_two_factor' => 'A 2FA', + 'confirmed_from' => 'Confirmed from', + 'registered_from' => 'Registered from', + 'blocked_code' => 'Code de blocage', + 'domain' => 'Domain', + 'registration_attempts' => 'Registration attempts', ]; diff --git a/resources/lang/fr_FR/passwords.php b/resources/lang/fr_FR/passwords.php index 6c382f830f..6d64931122 100644 --- a/resources/lang/fr_FR/passwords.php +++ b/resources/lang/fr_FR/passwords.php @@ -8,10 +8,10 @@ */ return [ - 'password' => 'Passwords must be at least six characters and match the confirmation.', - 'user' => 'We can\'t find a user with that e-mail address.', - 'token' => 'This password reset token is invalid.', - 'sent' => 'We have e-mailed your password reset link!', - 'reset' => 'Your password has been reset!', - 'blocked' => 'Nice try though.', + 'password' => 'Les mots de passe doivent contenir au moins six caractères et correspondre à la confirmation.', + 'user' => 'Nous ne pouvons pas trouver un utilisateur avec cette adresse e-mail.', + 'token' => 'Le jeton de réinitialisation de mot de passe est invalide.', + 'sent' => 'Nous vous avons envoyé par e-mail un lien de réinitialisation de votre mot de passe !', + 'reset' => 'Votre mot de passe a été réinitialisé !', + 'blocked' => 'Bien essayé cependant.', ]; diff --git a/resources/lang/fr_FR/validation.php b/resources/lang/fr_FR/validation.php index 49fc9c9e96..4d34c2bdba 100644 --- a/resources/lang/fr_FR/validation.php +++ b/resources/lang/fr_FR/validation.php @@ -8,16 +8,16 @@ */ return [ - 'iban' => 'This is not a valid IBAN.', - 'unique_account_number_for_user' => 'It looks like this account number is already in use.', - 'rule_trigger_value' => 'This value is invalid for the selected trigger.', - 'rule_action_value' => 'This value is invalid for the selected action.', - 'invalid_domain' => 'Due to security constraints, you cannot register from this domain.', - 'file_already_attached' => 'Uploaded file ":name" is already attached to this object.', - 'file_attached' => 'Succesfully uploaded file ":name".', - 'file_invalid_mime' => 'File ":name" is of type ":mime" which is not accepted as a new upload.', - 'file_too_large' => 'File ":name" is too large.', - 'belongs_to_user' => 'The value of :attribute is unknown', + 'iban' => 'Il ne s\'agit pas d\'un IBAN valide.', + 'unique_account_number_for_user' => 'Il semble que ce numéro de compte est déjà utilisé.', + 'rule_trigger_value' => 'Cette valeur n’est pas valide pour le déclencheur sélectionné.', + 'rule_action_value' => 'Cette valeur n’est pas valide pour l’action sélectionnée.', + 'invalid_domain' => 'Compte tenu des contraintes de sécurité, vous ne peut pas vous enregistrer depuis ce domaine.', + 'file_already_attached' => 'Le fichier téléchargé ":name" est déjà attaché à cet objet.', + 'file_attached' => 'Envoi du fichier ":name" avec succès.', + 'file_invalid_mime' => 'Le fichier ":name" est du type ":mime" ce qui n\'est pas accepté pour un nouvel envoi.', + 'file_too_large' => 'Le fichier ":name" est trop grand.', + 'belongs_to_user' => 'La valeur de :attribute est inconnue', 'accepted' => 'Le champ :attribute doit être accepté.', 'active_url' => 'Le champ :attribute n\'est pas une URL valide.', 'after' => 'Le champ :attribute doit être une date postérieure au :date.', @@ -25,10 +25,10 @@ return [ 'alpha_dash' => 'Le champ :attribute doit seulement contenir des lettres, des chiffres et des tirets.', 'alpha_num' => 'Le champ :attribute doit seulement contenir des chiffres et des lettres.', 'array' => 'Le champ :attribute doit être un tableau.', - 'unique_for_user' => 'There already is an entry with this :attribute.', + 'unique_for_user' => 'Il existe déjà une entrée avec ceci :attribute.', 'before' => 'Le champ :attribute doit être une date antérieure au :date.', - 'unique_object_for_user' => 'This name is already in use', - 'unique_account_for_user' => 'This account name is already in use', + 'unique_object_for_user' => 'Ce nom est déjà utilisé', + 'unique_account_for_user' => 'Ce nom de compte est déjà utilisé', 'between.numeric' => 'La valeur de :attribute doit être comprise entre :min et :max.', 'between.file' => 'Le fichier :attribute doit avoir une taille entre :min et :max kilo-octets.', 'between.string' => 'Le texte :attribute doit avoir entre :min et :max caractères.', @@ -76,5 +76,5 @@ return [ 'string' => 'Le champ :attribute doit être une chaîne de caractères.', 'url' => 'Le format de l\'URL de :attribute n\'est pas valide.', 'timezone' => 'Le champ :attribute doit être un fuseau horaire valide.', - '2fa_code' => 'The :attribute field is invalid.', + '2fa_code' => 'Le champ :attribute est invalide.', ]; diff --git a/resources/lang/nl_NL/csv.php b/resources/lang/nl_NL/csv.php new file mode 100644 index 0000000000..668cbb1748 --- /dev/null +++ b/resources/lang/nl_NL/csv.php @@ -0,0 +1,80 @@ + 'Import configureren', + 'import_configure_intro' => 'Hier zie je enkele opties voor jouw CSV bestand. Geef aan of je CSV bestand kolomtitels bevat, en hoe het datumveld is opgebouwd. Hier moet je wellicht wat experimenteren. Het scheidingsteken is meestal een ",", maar dat kan ook een ";" zijn. Controleer dit zorgvuldig.', + 'import_configure_form' => 'Formulier', + 'header_help' => 'Vink hier als de eerste rij kolomtitels bevat', + 'date_help' => 'Datum/tijd formaat in jouw CSV bestand. Volg het formaat zoals ze het op deze pagina uitleggen. Het standaardformaat ziet er zo uit: :dateExample.', + 'delimiter_help' => 'Kies het veldscheidingsteken dat in jouw bestand wordt gebruikt. Als je het niet zeker weet, is de komma de beste optie.', + 'config_file_help' => 'Voer hier je configuratiebestand in. Als je deze niet hebt, geen zorgen. Latere stappen leggen dit uit.', + 'import_account_help' => 'Als jouw CSV bestand geen referenties bevat naar jouw rekening(en), geef dan hier aan om welke rekening het gaat.', + 'upload_not_writeable' => 'Het grijze vlak bevat een bestandspad. Dit pad moet schrijfbaar zijn.', + + // roles + 'column_roles_title' => 'Bepaal de inhoud van elke kolom', + 'column_roles_text' => '

Firefly III kan niet raden welke soort gegevens er in elke kolom staan. Dat moet je er bij vertellen. Gebruik de voorbeeldgegevens en kies het juiste type uit de dropdown. Staat jouw type er niet bij? Open dan een ticket.

Sommige waarden, zoals rekeningnummers en namen staan wellicht al in jouw Firefly III database. Als je dan het vinkje vinkt, kan je zelf de link leggen tussen wat er in het CSV bestand staat en wat er in de database staat. Hiermee kan je de import sturen.

', + 'column_roles_table' => 'Tabel', + 'column_name' => 'Kolomnaam', + 'column_example' => 'Voorbeeldgegevens', + 'column_role' => 'Kolomrol', + 'do_map_value' => 'Maak een mapping', + 'column' => 'Kolom', + 'no_example_data' => 'Geen voorbeeldgegevens', + 'store_column_roles' => 'Ga verder met import', + 'do_not_map' => '(niet mappen)', + 'map_title' => 'Verbind importdata met Firefly III data', + 'map_text' => 'In deze tabellen is de linkerwaarde een waarde uit je CSV bestand. Jij moet de link leggen, als mogelijk, met een waarde uit jouw database. Firefly houdt zich hier aan. Als er geen waarde is, selecteer dan ook niets.', + + 'field_value' => 'Veldwaarde', + 'field_mapped_to' => 'Gelinkt aan', + 'store_column_mapping' => 'Mapping opslaan', + + // map things. + + + 'column__ignore' => '(negeer deze kolom)', + 'column_account-iban' => 'Betaalrekening (IBAN)', + 'column_account-id' => 'Betaalrekening (ID gelijk aan Firefly)', + 'column_account-name' => 'Betaalrekeningnaam', + 'column_amount' => 'Bedrag', + 'column_amount-comma-separated' => 'Bedrag (komma as decimaalscheidingsteken)', + 'column_bill-id' => 'Contract (ID gelijk aan Firefly)', + 'column_bill-name' => 'Contractnaam', + 'column_budget-id' => 'Budget (ID gelijk aan Firefly)', + 'column_budget-name' => 'Budgetnaam', + 'column_category-id' => 'Categorie (ID gelijk aan Firefly)', + 'column_category-name' => 'Categorienaam', + 'column_currency-code' => 'Valutacode (ISO 4217)', + 'column_currency-id' => 'Valuta (ID gelijk aan Firefly)', + 'column_currency-name' => 'Valutanaam', + 'column_currency-symbol' => 'Valutasymbool', + 'column_date-interest' => 'Datum (renteberekening)', + 'column_date-book' => 'Datum (boeking)', + 'column_date-process' => 'Datum (verwerking)', + 'column_date-transaction' => 'Datum', + 'column_description' => 'Omschrijving', + 'column_opposing-iban' => 'Tegenrekening (IBAN)', + 'column_opposing-id' => 'Tegenrekening (ID gelijk aan Firefly)', + 'column_external-id' => 'Externe ID', + 'column_opposing-name' => 'Tegenrekeningnaam', + 'column_rabo-debet-credit' => 'Rabobankspecifiek bij/af indicator', + 'column_ing-debet-credit' => 'ING-specifieke bij/af indicator', + 'column_sepa-ct-id' => 'SEPA transactienummer', + 'column_sepa-ct-op' => 'SEPA tegenrekeningnummer', + 'column_sepa-db' => 'SEPA "direct debet"-nummer', + 'column_tags-comma' => 'Tags (kommagescheiden)', + 'column_tags-space' => 'Tags (spatiegescheiden)', + 'column_account-number' => 'Betaalrekening (rekeningnummer)', + 'column_opposing-number' => 'Tegenrekening (rekeningnummer)', +]; diff --git a/resources/lang/nl_NL/firefly.php b/resources/lang/nl_NL/firefly.php index 159eedee49..8926b5f0f1 100644 --- a/resources/lang/nl_NL/firefly.php +++ b/resources/lang/nl_NL/firefly.php @@ -75,10 +75,10 @@ return [ // repeat frequencies: 'repeat_freq_monthly' => 'maandelijks', - 'weekly' => 'Wekelijks', - 'quarterly' => 'Elk kwartaal', - 'half-year' => 'Elk half jaar', - 'yearly' => 'Jaarlijks', + 'weekly' => 'wekelijks', + 'quarterly' => 'elk kwartaal', + 'half-year' => 'elk half jaar', + 'yearly' => 'elk jaar', // account confirmation: 'confirm_account_header' => 'Bevestig je account', 'confirm_account_intro' => 'TIjdens het registreren heb je een mailtje gehad. Kijk daar in voor instructies. Als je het mailtje niet hebt gehad, kan Firefly je een nieuwe sturen.', @@ -326,98 +326,6 @@ return [ 'title_transfer' => 'Overboekingen', 'title_transfers' => 'Overboekingen', - - // csv import: - 'csv_import' => 'Importeer CSV-bestand', - 'csv' => 'CSV', - 'csv_index_title' => 'Upload en importeer een kommagescheiden tekstbestand', - 'csv_define_column_roles' => 'Bepaal kolominhoud', - 'csv_map_values' => 'Leg relaties met kolomwaardes', - 'csv_download_config' => 'Download CSV configuratiebestand.', - 'csv_index_text' => 'Met deze (en de komende) pagina\'s kan je kommagescheiden tekstbestanden importeren. Deze tool is gebaseerd op de prachtige tool van Atlassian. Om te beginnen selecteer je jouw tekstbestand bij "CSV-bestand". Als je hulp nodig hebt, klik dan op het -icoontje rechtsboven.', - 'csv_index_beta_warning' => 'Deze tool is nog erg experimenteel. Wees dus voorzichtig.', - 'csv_header_help' => 'Zet hier een vinkje als de eerste rij van het CSV-bestand de namen van de kolommen bevat', - 'csv_date_help' => 'Het gebruikte datumformaat in jouw bestand. Gebruik het formaat zoals deze pagina het uitlegt (Engels). Het standaardformaat kan omgaan met data zoals deze: :dateExample.', - 'csv_csv_file_help' => 'Voer hier je kommagescheiden tekstbestand in. Je kan er maar één tegelijkertijd invoeren.', - 'csv_csv_config_file_help' => 'Voer hier je configuratiebestand in. Als je deze niet hebt, geen zorgen. Latere stappen leggen dit uit.', - 'csv_upload_button' => 'Begin de import', - 'csv_column_roles_title' => 'Bepaal de inhoud van elke kolom', - 'csv_column_roles_text' => 'Firefly kan niet automatisch ontdekken wat elke kolom betekent. Je moet het zelf aangeven. Gebruik de voorbeeldgegevens als je het ook niet zeker weet. Klik op het vraagteken-icoontje (rechtsboven) om te ontdekken wat elke kolomsoort precies is. Als de kolominhoud een directe relatie heeft met gegevens die al in Firefly staan, gebruik dan het vinkje. Tijdens de volgende stap komt Firefly hier dan op terug.', - 'csv_column_roles_table' => 'Kolominhoud', - 'csv_column' => 'CSV-kolom', - 'csv_column_name' => 'CSV-kolomnaam', - 'csv_column_example' => 'Voorbeeldgegevens', - 'csv_column_role' => 'Kolom bevat?', - 'csv_do_map_value' => 'Directe relatie?', - 'csv_continue' => 'Naar de volgende stap', - 'csv_go_back' => 'Terug naar de vorige stap', - 'csv_map_title' => 'Leg relaties met kolomwaardes', - 'csv_map_text' => 'Sommige kolommen bevatten waardes die misschien al in Firefly bestaan. Selecteer hier de juiste combinaties zodat het importeren netjes aansluit bij je huidige gegevens.', - 'csv_field_value' => 'Veldwaarde', - 'csv_field_mapped_to' => 'Is gelijk aan', - 'csv_do_not_map' => 'Geen relatie', - 'csv_download_config_title' => 'Download importconfiguratie', - 'csv_download_config_text' => 'Alles wat je nu hebt zitten instellen kan je downloaden als configuratiebestand voor de volgende keer. Klik op de knop om dit te doen.', - 'csv_more_information_text' => 'Ook als het importeren fout gaat is dit bestand handig. Na het importeren krijg je nogmaals de gelegenheid dit bestand te downloaden.', - 'csv_do_download_config' => 'Download het configuratiebestand', - 'csv_empty_description' => '(geen omschrijving)', - 'csv_upload_form' => 'CSV upload formulier', - 'csv_index_unsupported_warning' => 'Het volgende wordt nog niet ondersteund:', - 'csv_unsupported_map' => 'De tool kan de kolom ":columnRole" niet koppelen aan bestaande gegevens in de database.', - 'csv_unsupported_value' => 'Firefly kan niet omgaan met kolommen gemarkeerd als ":columnRole".', - 'csv_cannot_store_value' => 'Firefly heeft geen ruimte gereserveerd voor kolommen gemarkeert als ":columnRole" en kan ze helaas niet verwerken.', - 'csv_process_title' => 'Het importeren is klaar', - 'csv_process_text' => ':rows rijen zijn verwerkt.', - 'csv_row' => 'Rij', - 'csv_import_with_errors' => 'Er ging één ding fout.|Er gingen :errors dingen fout.', - 'csv_error_see_logs' => 'De logboeken bevatten mogelijk meer details.', - 'csv_process_new_entries' => 'Firefly heeft :imported nieuwe transactie(s) gemaakt.', - 'csv_start_over' => 'Begin opnieuw', - 'csv_to_index' => 'Naar de index', - 'csv_upload_not_writeable' => 'Kan niet naar onderstaand pad schrijven. Kan dus niet uploaden.', - 'csv_column__ignore' => '(negeer deze kolom)', - 'csv_column_account-iban' => 'Betaalrekening (IBAN)', - 'csv_column_account-id' => 'Betaalrekening (ID gelijk aan Firefly)', - 'csv_column_account-name' => 'Betaalrekeningnaam', - 'csv_column_amount' => 'Bedrag', - 'csv_column_amount-comma-separated' => 'Bedrag (komma as decimaalscheidingsteken)', - 'csv_column_bill-id' => 'Contract (ID gelijk aan Firefly)', - 'csv_column_bill-name' => 'Contractnaam', - 'csv_column_budget-id' => 'Budget (ID gelijk aan Firefly)', - 'csv_column_budget-name' => 'Budgetnaam', - 'csv_column_category-id' => 'Categorie (ID gelijk aan Firefly)', - 'csv_column_category-name' => 'Categorienaam', - 'csv_column_currency-code' => 'Valutacode (ISO 4217)', - 'csv_column_currency-id' => 'Valuta (ID gelijk aan Firefly)', - 'csv_column_currency-name' => 'Valutanaam', - 'csv_column_currency-symbol' => 'Valuta', - 'csv_column_date-rent' => 'Datum (renteberekening)', - 'csv_column_date-transaction' => 'Datum (transactie)', - 'csv_column_description' => 'Omschrijving', - 'csv_column_opposing-iban' => 'Tegenrekening (IBAN)', - 'csv_column_opposing-id' => 'Tegenrekening (ID gelijk aan Firefly)', - 'csv_column_opposing-name' => 'Tegenrekeningnaam', - 'csv_column_rabo-debet-credit' => 'Rabobankspecifiek bij/af indicator', - 'csv_column_ing-debet-credit' => 'ING-specifieke bij/af indicator', - 'csv_column_sepa-ct-id' => 'SEPA transactienummer', - 'csv_column_sepa-ct-op' => 'SEPA tegenrekeningnummer', - 'csv_column_sepa-db' => 'SEPA "direct debet"-nummer', - 'csv_column_tags-comma' => 'Tags (kommagescheiden)', - 'csv_column_tags-space' => 'Tags (spatiegescheiden)', - 'csv_column_account-number' => 'Betaalrekening (rekeningnummer)', - 'csv_column_opposing-number' => 'Tegenrekening (rekeningnummer)', - 'csv_specifix_RabobankDescription' => 'Vink dit aan als je Rabobank CSV-bestanden importeert.', - 'csv_specifix_AbnAmroDescription' => 'Vink dit aan als je ABN AMRO CSV-bestanden importeert.', - 'csv_specifix_Dummy' => 'Dit vinkje doet niks (dummy).', - 'csv_import_account_help' => 'Als jouw CSV bestand geen referenties bevat naar jouw rekening(en), geef dan hier aan om welke rekening het gaat.', - 'csv_delimiter_help' => 'Kies het veldscheidingsteken dat in het invoerbestand is gebruikt. Bij twijfel is de komma de veiligste optie.', - 'csv_date_parse_error' => 'Firefly kan van ":value" geen datum maken, gegeven het formaat ":format". Weet je zeker dat je CSV goed is?', - 'could_not_recover' => 'Helaas, kan niet doorgaan vanaf de vorige stap. Je voortgang is verloren gegaan :(. De logbestanden bevatten meer informatie.', - 'must_select_roles' => 'Je moet enkele rollen selecteren voor de kolommen in je bestand, anders kan je niet verder.', - 'invalid_mapping' => 'Je hebt verkeerde gegevens ingevoerd. Je kan helaas niet verder.', - 'no_file_uploaded' => 'Het lijkt er op dat je niets hebt geüpload.', - - // create new stuff: 'create_new_withdrawal' => 'Nieuwe uitgave', 'create_new_deposit' => 'Nieuwe inkomsten', @@ -500,6 +408,8 @@ return [ 'cannot_scan_inactive_bill' => 'Inactieve contracten kunnen niet worden gescand.', 'rescanned_bill' => 'Alles is opnieuw gescand.', 'bill_date_little_relevance' => 'Firefly gebruikt alleen de dag van dit datumveld. Dit veld heeft alleen zin als je rekening ook echt op die dag van de maand komt. Zo niet, vul dan gewoon de 1e van de maand in.', + 'average_bill_amount_year' => 'Gemiddeld contractbedrag (:year)', + 'average_bill_amount_overall' => 'Gemiddeld contractbedrag (gehele periode)', // accounts: 'details_for_asset' => 'Overzicht voor betaalrekening ":name"', @@ -644,12 +554,9 @@ return [ 'saveOnAccount' => 'Sparen op rekening', 'unknown' => 'Onbekend', 'daily' => 'Dagelijks', - 'weekly' => 'Wekelijks', 'monthly' => 'Maandelijks', - 'quarterly' => 'Elk kwartaal', - 'half-year' => 'Elk half jaar', - 'yearly' => 'Jaarlijks', 'profile' => 'Profiel', + 'errors' => 'Fouten', // reports: 'report_default' => 'Standaard financieel rapport (:start tot :end)', @@ -742,6 +649,7 @@ return [ 'balanceFor' => 'Saldo op :name', // piggy banks: + 'add_money_to_piggy' => 'Stop geld in spaarpotje ":name"', 'piggy_bank' => 'Spaarpotje', 'new_piggy_bank' => 'Nieuw spaarpotje', 'store_piggy_bank' => 'Sla spaarpotje op', @@ -803,6 +711,18 @@ return [ 'user_administration' => 'Gebruikersadministratie', 'list_all_users' => 'Alle gebruikers', 'all_users' => 'Alle gebruikers', + 'all_blocked_domains' => 'Alle geblokkeerde domeinen', + 'blocked_domains' => 'Geblokkeerde domeinen', + 'no_domains_banned' => 'Geen domeinen geblokkeerd', + 'all_user_domains' => 'Alle domeinen van gebruikers', + 'all_domains_is_filtered' => 'Deze lijst bevat geen domeinen die al geblokkeerd zijn.', + 'domain_now_blocked' => 'Domein :domein is geblokkeerd', + 'domain_now_unblocked' => 'Domein :domain is niet meer geblokkeerd', + 'manual_block_domain' => 'Blokkeer een domein handmatig', + 'block_domain' => 'Blokkeer domein', + 'no_domain_filled_in' => 'Geen domein opgegeven', + 'domain_already_blocked' => 'Domein :domain is al geblokkeerd', + 'domain_is_now_blocked' => 'Domein :domain is nu geblokkeerd', // split a transaction: 'transaction_meta_data' => 'Transactie meta-data', @@ -815,24 +735,46 @@ return [ 'split_table_intro_withdrawal' => 'Split je uitgave in zoveel stukken als je maar wilt. Standaard is je uitgave niet gesplitst; er is maar één "split". Voeg hieronder zoveel splits toe als je wilt. Denk er aan dat je niet afwijkt van het totaalbedrag. Als je dat wel doet zal Firefly je waarschuwen maar niet corrigeren.', 'store_splitted_withdrawal' => 'Sla gesplitste uitgave op', 'update_splitted_withdrawal' => 'Gesplitste uitgave updaten', + 'split_title_deposit' => 'Splits je nieuwe inkomsten', + 'split_intro_one_deposit' => 'Firefly kan inkomsten "splitsen".', + 'split_intro_two_deposit' => 'Dat betekent dat de inkomsten die je krijgt wordt verdeeld over verschillende doelrekeningen of categorieën.', + 'split_intro_three_deposit' => 'Je kan bijvoorbeeld je salaris van :total verdelen zodat :split_one wordt opgeslagen als je basissalaris, en :split_two als declaratieteruggave.', + 'split_table_intro_deposit' => 'Split je inkomsten in zoveel stukken als je maar wilt. Standaard zijn je inkomsten niet gesplitst; er is maar één "split". Voeg hieronder zoveel splits toe als je wilt. Denk er aan dat je niet afwijkt van het totaalbedrag. Als je dat wel doet zal Firefly je waarschuwen maar niet corrigeren.', + 'store_splitted_deposit' => 'Sla gesplitse inkomsten op', + 'split_title_transfer' => 'Splits je nieuwe overschrijving', + 'split_intro_one_transfer' => 'Firefly kan overschrijvingen "splitsen".', + 'split_intro_two_transfer' => 'Dat betekent dat de uitgave die je maakt wordt verdeeld over verschillende categorieën of spaarpotjes.', + 'split_intro_three_transfer' => 'Je kan bijvoorbeeld je overschrijving van :total verdelen zodat :split_one in het ene spaarpotje terecht komt, en :split_two in het andere spaarpotje.', + 'split_table_intro_transfer' => 'Split je overschrijving in zoveel stukken als je maar wilt. Standaard is je overschrijving niet gesplitst; er is maar één "split". Voeg hieronder zoveel splits toe als je wilt. Denk er aan dat je niet afwijkt van het totaalbedrag. Als je dat wel doet zal Firefly je waarschuwen maar niet corrigeren.', + 'store_splitted_transfer' => 'Sla gesplitste overschrijving op', + 'add_another_split' => 'Voeg een split toe', + 'split-transactions' => 'Split transacties', + 'split-new-transaction' => 'Split een nieuwe transactie', + 'do_split' => 'Splits', + 'split_this_withdrawal' => 'Splits deze uitgave', + 'split_this_deposit' => 'Splits deze inkomsten', + 'split_this_transfer' => 'Splits deze overboeking', + 'cannot_edit_multiple_source' => 'Je kan transactie #:id met omschrijving ":description" niet splitsen, want deze bevat meerdere bronrekeningen.', + 'cannot_edit_multiple_dest' => 'Je kan transactie #:id met omschrijving ":description" niet splitsen, want deze bevat meerdere doelrekeningen.', + 'no_edit_multiple_left' => 'Je hebt geen geldige transacties geselecteerd.', - 'split_title_deposit' => 'Splits je nieuwe inkomsten', - 'split_intro_one_deposit' => 'Firefly kan inkomsten "splitsen".', - 'split_intro_two_deposit' => 'Dat betekent dat de inkomsten die je krijgt wordt verdeeld over verschillende doelrekeningen of categorieën.', - 'split_intro_three_deposit' => 'Je kan bijvoorbeeld je salaris van :total verdelen zodat :split_one wordt opgeslagen als je basissalaris, en :split_two als declaratieteruggave.', - 'split_table_intro_deposit' => 'Split je inkomsten in zoveel stukken als je maar wilt. Standaard zijn je inkomsten niet gesplitst; er is maar één "split". Voeg hieronder zoveel splits toe als je wilt. Denk er aan dat je niet afwijkt van het totaalbedrag. Als je dat wel doet zal Firefly je waarschuwen maar niet corrigeren.', - 'store_splitted_deposit' => 'Sla gesplitse inkomsten op', - - 'split_title_transfer' => 'Splits je nieuwe overschrijving', - 'split_intro_one_transfer' => 'Firefly kan overschrijvingen "splitsen".', - 'split_intro_two_transfer' => 'Dat betekent dat de uitgave die je maakt wordt verdeeld over verschillende categorieën of spaarpotjes.', - 'split_intro_three_transfer' => 'Je kan bijvoorbeeld je overschrijving van :total verdelen zodat :split_one in het ene spaarpotje terecht komt, en :split_two in het andere spaarpotje.', - 'split_table_intro_transfer' => 'Split je overschrijving in zoveel stukken als je maar wilt. Standaard is je overschrijving niet gesplitst; er is maar één "split". Voeg hieronder zoveel splits toe als je wilt. Denk er aan dat je niet afwijkt van het totaalbedrag. Als je dat wel doet zal Firefly je waarschuwen maar niet corrigeren.', - 'store_splitted_transfer' => 'Sla gesplitste overschrijving op', - - 'add_another_split' => 'Voeg een split toe', - 'split-transactions' => 'Split transacties', - 'split-new-transaction' => 'Split een nieuwe transactie', - - + // import + 'configuration_file_help' => 'Als je eerder gegevens in Firefly III hebt geïmporteerd, heb je een configuratiebestand, dat voor jou de instellingen zal doen.', + 'import_data_index' => 'Index', + 'import_file_type_csv' => 'CSV (kommagescheiden waardes)', + 'import_file_type_help' => 'Selecteer het type bestand dat je zal uploaden', + 'import_start' => 'Start importeren', + 'configure_import' => 'Verder configureren van je import', + 'import_finish_configuration' => 'De configuratie voltooien', + 'settings_for_import' => 'Instellingen', + 'import_complete' => 'Configureren van import is klaar!', + 'import_complete_text' => 'De import is klaar om te beginnen. Alle de configuratie die je moest doen is gedaan. Download alsjeblieft het configuratiebestand. Als de import mislukt hoef je straks niet overnieuw te beginnen. Voor het daadwerkelijk draaien van de import-routine, voer je het onderstaande commando uit in je browser. Via de site zelf is dit helaas nog niet mogelijk.', + 'import_download_config' => 'Download importconfiguratie', + 'import_start_import' => 'Import starten', + 'import_intro_beta' => 'De importfunctie van Firefly III is in bèta. Er zijn al veel bestanden geprobeerd, en elk individueel component zou moeten werken. Gecombineerd echter, kan er wat stuk gaan. Als jouw bestand problemen geeft, lees dan deze wikipagina zodat ik eventuele bugs kan fixen.', + 'import_data' => 'Importeer data', + 'import_data_full' => 'Gegevens importeren in Firefly III', + 'import' => 'Import', + 'import_intro_text' => 'Welkom bij de import-routine van Firefly III. Deze pagina\'s helpen je data in Firefly III te importeren. Om dat te doen, download of exporteer je transacties uit andere systemen, en upload ze hier. In de volgende stappen help je Firefly met het bepalen wat de inhoud is van de bestanden die je upload, en hoe er mee om te gaan. Selecteer een bestand, en lees alle instructies zorgvuldig.', + 'import_file_help' => 'Selecteer je bestand', ]; diff --git a/resources/lang/nl_NL/form.php b/resources/lang/nl_NL/form.php index be8e10d516..e6c4b74b91 100644 --- a/resources/lang/nl_NL/form.php +++ b/resources/lang/nl_NL/form.php @@ -71,13 +71,9 @@ return [ 'code' => 'Code', 'iban' => 'IBAN', 'accountNumber' => 'Rekeningnummer', - 'csv' => 'CSV-bestand', 'has_headers' => 'Kolomnamen op de eerste rij?', 'date_format' => 'Datumformaat', - 'csv_config' => 'Configuratiebestand', 'specifix' => 'Bank- or of bestandsspecifieke opties', - 'csv_import_account' => 'Standaard rekening voor importeren', - 'csv_delimiter' => 'CSV scheidingsteken', 'attachments[]' => 'Bijlagen', 'store_new_withdrawal' => 'Nieuwe uitgave opslaan', 'store_new_deposit' => 'Nieuwe inkomsten opslaan', @@ -102,9 +98,6 @@ return [ 'include_config' => 'Sla ook een configuratiebestand ook', 'include_old_uploads' => 'Sla ook geïmporteerde bestanden op', 'accounts' => 'Exporteer boekingen van deze rekeningen', - 'csv_comma' => 'Een komma (,)', - 'csv_semicolon' => 'Een puntkomma (;)', - 'csv_tab' => 'Een tab (onzichtbaar)', 'delete_account' => 'Verwijder rekening ":name"', 'delete_bill' => 'Verwijder contract ":name"', 'delete_budget' => 'Verwijder budget ":name"', @@ -137,4 +130,20 @@ return [ 'budget_keep_transactions' => 'De transactie verbonden aan dit budget blijft bewaard.|De :count transacties verbonden aan dit budget blijven bewaard.', 'category_keep_transactions' => 'De transactie verbonden aan deze categorie blijft bewaard.|De :count transacties verbonden aan deze categorie blijven bewaard.', 'tag_keep_transactions' => 'De transactie verbonden aan deze tag blijft bewaard.|De :count transacties verbonden aan deze tag blijven bewaard.', + + // admin + 'domain' => 'Domein', + + // import + 'import_file' => 'Importbestand', + 'configuration_file' => 'Configuratiebestand', + 'import_file_type' => 'Importbestandstype', + 'csv_comma' => 'Een komma (,)', + 'csv_semicolon' => 'Een puntkomma (;)', + 'csv_tab' => 'Een tab (onzichtbaar)', + 'csv_delimiter' => 'CSV scheidingsteken', + 'csv_import_account' => 'Standaard rekening voor importeren', + 'csv_config' => 'Configuratiebestand', + + ]; diff --git a/resources/lang/nl_NL/help.php b/resources/lang/nl_NL/help.php index 24ff6fbdac..76184e52fe 100644 --- a/resources/lang/nl_NL/help.php +++ b/resources/lang/nl_NL/help.php @@ -55,11 +55,6 @@ return [ 'categories-show' => 'bekijk een categorie', 'categories-show-date' => 'bekijk categorie', 'categories-noCategory' => 'transacties zonder categorie', - 'csv-index' => 'csv-index', - 'csv-column-roles' => 'kolommen en rollen', - 'csv-map' => 'kolommen en data', - 'csv-download-config-page' => 'download configuratie', - 'csv-process' => 'CSV verwerken', 'currency-index' => 'valuta\'s', 'currency-create' => 'maak een nieuwe munteenheid', 'currency-edit' => 'wijzig een munteenheid', diff --git a/resources/lang/nl_NL/list.php b/resources/lang/nl_NL/list.php index c96785ecbf..05e713409d 100644 --- a/resources/lang/nl_NL/list.php +++ b/resources/lang/nl_NL/list.php @@ -8,54 +8,59 @@ */ return [ - 'buttons' => 'Knoppen', - 'icon' => 'Icoon', - 'create_date' => 'Aangemaakt op', - 'update_date' => 'Bijgewerkt op', - 'balance_before' => 'Saldo voor', - 'balance_after' => 'Saldo na', - 'name' => 'Naam', - 'role' => 'Rol', - 'currentBalance' => 'Huidig saldo', - 'active' => 'Actief?', - 'lastActivity' => 'Laatste activiteit', - 'balanceDiff' => 'Saldoverschil tussen :start en :end', - 'matchedOn' => 'Wordt herkend', - 'matchesOn' => 'Wordt herkend', - 'account_type' => 'Accounttype', - 'new_balance' => 'Nieuw saldo', - 'account' => 'Rekening', - 'matchingAmount' => 'Bedrag', - 'lastMatch' => 'Laatste keer gezien', - 'split_number' => 'Split #', - 'destination' => 'Doel', - 'expectedMatch' => 'Wordt verwacht', - 'automatch' => 'Automatisch herkennen?', - 'repeat_freq' => 'Herhaling', - 'description' => 'Omschrijving', - 'amount' => 'Bedrag', - 'date' => 'Datum', - 'interest_date' => 'Rentedatum', - 'book_date' => 'Boekdatum', - 'process_date' => 'Verwerkingsdatum', - 'from' => 'Van', - 'piggy_bank' => 'Spaarpotje', - 'to' => 'Naar', - 'budget' => 'Budget', - 'category' => 'Categorie', - 'bill' => 'Contract', - 'withdrawal' => 'Uitgave', - 'deposit' => 'Inkomsten', - 'transfer' => 'Overschrijving', - 'type' => 'Type', - 'completed' => 'Opgeslagen', - 'iban' => 'IBAN', - 'paid_current_period' => 'Betaald deze periode', - 'email' => 'E-mail', - 'registered_at' => 'Geregistreerd op', - 'is_activated' => 'Is geactiveerd', - 'is_blocked' => 'Is geblokkeerd', - 'is_admin' => 'Is beheerder', - 'has_two_factor' => 'Heeft 2FA', - 'blocked_code' => 'Reden voor blokkade', + 'buttons' => 'Knoppen', + 'icon' => 'Icoon', + 'create_date' => 'Aangemaakt op', + 'update_date' => 'Bijgewerkt op', + 'balance_before' => 'Saldo voor', + 'balance_after' => 'Saldo na', + 'name' => 'Naam', + 'role' => 'Rol', + 'currentBalance' => 'Huidig saldo', + 'active' => 'Actief?', + 'lastActivity' => 'Laatste activiteit', + 'balanceDiff' => 'Saldoverschil tussen :start en :end', + 'matchedOn' => 'Wordt herkend', + 'matchesOn' => 'Wordt herkend', + 'account_type' => 'Accounttype', + 'new_balance' => 'Nieuw saldo', + 'account' => 'Rekening', + 'matchingAmount' => 'Bedrag', + 'lastMatch' => 'Laatste keer gezien', + 'split_number' => 'Split #', + 'destination' => 'Doel', + 'source' => 'Bron', + 'expectedMatch' => 'Wordt verwacht', + 'automatch' => 'Automatisch herkennen?', + 'repeat_freq' => 'Herhaling', + 'description' => 'Omschrijving', + 'amount' => 'Bedrag', + 'date' => 'Datum', + 'interest_date' => 'Rentedatum', + 'book_date' => 'Boekdatum', + 'process_date' => 'Verwerkingsdatum', + 'from' => 'Van', + 'piggy_bank' => 'Spaarpotje', + 'to' => 'Naar', + 'budget' => 'Budget', + 'category' => 'Categorie', + 'bill' => 'Contract', + 'withdrawal' => 'Uitgave', + 'deposit' => 'Inkomsten', + 'transfer' => 'Overschrijving', + 'type' => 'Type', + 'completed' => 'Opgeslagen', + 'iban' => 'IBAN', + 'paid_current_period' => 'Betaald deze periode', + 'email' => 'E-mail', + 'registered_at' => 'Geregistreerd op', + 'is_activated' => 'Is geactiveerd', + 'is_blocked' => 'Is geblokkeerd', + 'is_admin' => 'Is beheerder', + 'has_two_factor' => 'Heeft 2FA', + 'confirmed_from' => 'Bevestigd vanaf', + 'registered_from' => 'Geregistreerd vanaf', + 'blocked_code' => 'Reden voor blokkade', + 'domain' => 'Domein', + 'registration_attempts' => 'Registratiepogingen', ]; diff --git a/resources/lang/pt_BR/csv.php b/resources/lang/pt_BR/csv.php new file mode 100644 index 0000000000..fef82823e3 --- /dev/null +++ b/resources/lang/pt_BR/csv.php @@ -0,0 +1,80 @@ + 'Configure your import', + 'import_configure_intro' => 'There are some options for your CSV import. Please indicate if your CSV file contains headers on the first column, and what the date format of your date-fields is. That might require some experimentation. The field delimiter is usually a ",", but could also be a ";". Check this carefully.', + 'import_configure_form' => 'Form', + 'header_help' => 'Check this if the first row of your CSV file are the column titles', + 'date_help' => 'Date time format in your CSV. Follow the format like this page indicates. The default value will parse dates that look like this: :dateExample.', + 'delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.', + 'config_file_help' => 'Select your CSV import configuration here. If you do not know what this is, ignore it. It will be explained later.', + 'import_account_help' => 'If your CSV file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the CSV belong to.', + 'upload_not_writeable' => 'The grey box contains a file path. It should be writeable. Please make sure it is.', + + // roles + 'column_roles_title' => 'Define column roles', + 'column_roles_text' => '

Firefly III cannot guess what data each column contains. You must tell Firefly which kinds of data to expect. The example data can guide you into picking the correct type from the dropdown. If a column cannot be matched to a useful data type, please let me know by creating an issue.

Some values in your CSV file, such as account names or categories, may already exist in your Firefly III database. If you select "map these values" Firefly will not attempt to search for matching values itself but allow you to match the CSV values against the values in your database. This allows you to fine-tune the import.

', + 'column_roles_table' => 'Table', + 'column_name' => 'Name of column', + 'column_example' => 'Column example data', + 'column_role' => 'Column data meaning', + 'do_map_value' => 'Map these values', + 'column' => 'Column', + 'no_example_data' => 'No example data available', + 'store_column_roles' => 'Continue import', + 'do_not_map' => '(do not map)', + 'map_title' => 'Connect import data to Firefly III data', + 'map_text' => 'In the following tables, the left value shows you information found in your uploaded CSV file. It is your task to map this value, if possible, to a value already present in your database. Firefly will stick to this mapping. If there is no value to map to, or you do not wish to map the specific value, select nothing.', + + 'field_value' => 'Field value', + 'field_mapped_to' => 'Mapped to', + 'store_column_mapping' => 'Store mapping', + + // map things. + + + 'column__ignore' => '(ignore this column)', + 'column_account-iban' => 'Asset account (IBAN)', + 'column_account-id' => 'Asset account ID (matching Firefly)', + 'column_account-name' => 'Asset account (name)', + 'column_amount' => 'Amount', + 'column_amount-comma-separated' => 'Amount (comma as decimal separator)', + 'column_bill-id' => 'Bill ID (matching Firefly)', + 'column_bill-name' => 'Bill name', + 'column_budget-id' => 'Budget ID (matching Firefly)', + 'column_budget-name' => 'Budget name', + 'column_category-id' => 'Category ID (matching Firefly)', + 'column_category-name' => 'Category name', + 'column_currency-code' => 'Currency code (ISO 4217)', + 'column_currency-id' => 'Currency ID (matching Firefly)', + 'column_currency-name' => 'Currency name (matching Firefly)', + 'column_currency-symbol' => 'Currency symbol (matching Firefly)', + 'column_date-interest' => 'Interest calculation date', + 'column_date-book' => 'Transaction booking date', + 'column_date-process' => 'Transaction process date', + 'column_date-transaction' => 'Date', + 'column_description' => 'Description', + 'column_opposing-iban' => 'Opposing account (IBAN)', + 'column_opposing-id' => 'Opposing account ID (matching Firefly)', + 'column_external-id' => 'External ID', + 'column_opposing-name' => 'Opposing account (name)', + 'column_rabo-debet-credit' => 'Rabobank specific debet/credit indicator', + 'column_ing-debet-credit' => 'ING specific debet/credit indicator', + 'column_sepa-ct-id' => 'SEPA Credit Transfer end-to-end ID', + 'column_sepa-ct-op' => 'SEPA Credit Transfer opposing account', + 'column_sepa-db' => 'SEPA Direct Debet', + 'column_tags-comma' => 'Tags (comma separated)', + 'column_tags-space' => 'Tags (space separated)', + 'column_account-number' => 'Asset account (account number)', + 'column_opposing-number' => 'Opposing account (account number)', +]; diff --git a/resources/lang/pt_BR/firefly.php b/resources/lang/pt_BR/firefly.php index 599afa7b20..bbab95ef31 100644 --- a/resources/lang/pt_BR/firefly.php +++ b/resources/lang/pt_BR/firefly.php @@ -70,15 +70,15 @@ return [ 'registered' => 'Você se registrou com sucesso!', 'search' => 'Pesquisa', 'no_budget_pointer' => 'Parece que não há orçamentos ainda. Você deve criar alguns na página orçamentos. Orçamentos podem ajudá-lo a manter o controle de despesas.', - 'source_accounts' => 'Source account(s)', - 'destination_accounts' => 'Destination account(s)', + 'source_accounts' => 'Conta(s) de origem', + 'destination_accounts' => 'Conta(s) de destino', // repeat frequencies: 'repeat_freq_monthly' => 'mensal', - 'weekly' => 'Semanal', - 'quarterly' => 'Trimestral', - 'half-year' => 'Semestral', - 'yearly' => 'Anual', + 'weekly' => 'semanal', + 'quarterly' => 'trimestral', + 'half-year' => 'metade de cada ano', + 'yearly' => 'anual', // account confirmation: 'confirm_account_header' => 'Por favor, confirme sua conta', 'confirm_account_intro' => 'Um e-mail foi enviado para o endereço que você usou durante o seu registro. Por favor confira-o para mais instruções. Se não recebeu esta mensagem, podemos enviá-lo novamente.', @@ -326,98 +326,6 @@ return [ 'title_transfer' => 'Transferências', 'title_transfers' => 'Transferências', - - // csv import: - 'csv_import' => 'Importar arquivo CSV', - 'csv' => 'CSV', - 'csv_index_title' => 'Carregar e importar um arquivo CSV', - 'csv_define_column_roles' => 'Definir papeis da coluna', - 'csv_map_values' => 'Valores mapeados encontrados para valores existentes', - 'csv_download_config' => 'Download do arquivo CSV de configuração.', - 'csv_index_text' => 'Este formulário permite você importar um arquivo CSV com transações para dentro do Firefly. É baseado no excelente importador CSV feito pelo pessoal da Atlassian. Basta fazer upload de seu arquivo CSV e siga as instruções. Se você gostaria de aprender mais, por favor clique sobre o botão na parte superior desta página.', - 'csv_index_beta_warning' => 'Esta ferramenta está em beta. Por favor proceder com cautela', - 'csv_header_help' => 'Selecione esta caixa quando a primeira linha do arquivo CSV consiste em nomes de colunas, os dados não reais', - 'csv_date_help' => 'Formato de hora de data em seu CSV. Siga o formato como indica esta página. O valor padrão analisará datas que se parecem com isso: :dateExample.', - 'csv_csv_file_help' => 'Selecione o arquivo CSV aqui. Você só pode carregar um arquivo de cada vez', - 'csv_csv_config_file_help' => 'Selecione a configuração de importação CSV aqui. Se você não sabe o que é isso, ignore. Será explicado mais tarde.', - 'csv_upload_button' => 'Iniciando importação do CSV', - 'csv_column_roles_title' => 'Definir papeis da coluna', - 'csv_column_roles_text' => 'Firefly não sabe o que significa cada coluna. Você precisa indicar o que cada coluna é. Por favor confira os dados de exemplo se você não está certo mesmo. Clique sobre o ponto de interrogação (superior direito da página) para aprender o que significa que cada coluna. Se você deseja mapear dados importados para dados existentes em Firefly, use a caixa de seleção. O próximo passo irá mostrar-lhe o que esse botão faz.', - 'csv_column_roles_table' => 'Papéis da Coluna', - 'csv_column' => 'Coluna CSV', - 'csv_column_name' => 'Nome da coluna do CSV', - 'csv_column_example' => 'Exemplo de dados da coluna', - 'csv_column_role' => 'Coluna contém?', - 'csv_do_map_value' => 'Valor mapeado?', - 'csv_continue' => 'Continuar para o próximo passo', - 'csv_go_back' => 'Voltar para o passo anterior', - 'csv_map_title' => 'Valores mapeados encontrados para valores existentes', - 'csv_map_text' => 'Esta página permite mapear os valores do arquivo CSV para entradas existentes em seu banco de dados. Isso garante que as contas e outras coisas não serão criadas duas vezes.', - 'csv_field_value' => 'Valor do campo do CSV', - 'csv_field_mapped_to' => 'Deve ser mapeado para...', - 'csv_do_not_map' => 'Não mapear este valor', - 'csv_download_config_title' => 'Download do CSV de configuração ', - 'csv_download_config_text' => 'Tudo o que você configurou pode ser baixado como um arquivo de configuração. Clique no botão para fazê-lo.', - 'csv_more_information_text' => 'Se a importação falhar, você pode usar este arquivo de configuração, então você não tem que começar tudo de novo. Mas, se a importação for bem-sucedido, será mais fácil carregar arquivos CSV semelhantes.', - 'csv_do_download_config' => 'Download do arquivo de configuração.', - 'csv_empty_description' => '(descrição vazia)', - 'csv_upload_form' => 'Formulário de Upload do CSV', - 'csv_index_unsupported_warning' => 'O importador de CSV está incapaz de fazer o seguinte:', - 'csv_unsupported_map' => 'O importador não pode mapear a coluna ":columnRole" para os valores existentes no banco de dados.', - 'csv_unsupported_value' => 'O importador não sabe como lidar com valores em colunas marcadas como ":columnRole".', - 'csv_cannot_store_value' => 'O importador não reservou espaço para colunas marcadas ":columnRole" e será incapaz de processá-los.', - 'csv_process_title' => 'Importação do CSV terminou!', - 'csv_process_text' => 'O importador do CSV terminou e processou :rows linhas', - 'csv_row' => 'Linha', - 'csv_import_with_errors' => 'Houve um erro.|Houve :errors erros.', - 'csv_error_see_logs' => 'Verifique o arquivo de log para ver detalhes.', - 'csv_process_new_entries' => 'Firefly criou :imported nova(s) transação(ões)', - 'csv_start_over' => 'Importar novamente', - 'csv_to_index' => 'Voltar para tela inicial', - 'csv_upload_not_writeable' => 'Não é possível gravar no caminho mencionado aqui. Não pode fazer o upload', - 'csv_column__ignore' => '(ignorar esta coluna)', - 'csv_column_account-iban' => 'Conta de Ativo (IBAN)', - 'csv_column_account-id' => 'ID da Conta de Ativo (correspondente Firefly)', - 'csv_column_account-name' => 'Conta de Ativo (nome)', - 'csv_column_amount' => 'Valor', - 'csv_column_amount-comma-separated' => 'Auantia (vírgula como separador decimal)', - 'csv_column_bill-id' => 'ID Fatura (correspondente Firefly)', - 'csv_column_bill-name' => 'Nom da Fatura', - 'csv_column_budget-id' => 'ID do Orçamento (correspondente Firefly)', - 'csv_column_budget-name' => 'Nome do Orçamento', - 'csv_column_category-id' => 'ID da Categoria (correspondente Firefly)', - 'csv_column_category-name' => 'Nome da Categoria', - 'csv_column_currency-code' => 'Código da Moeda (ISO 4217)', - 'csv_column_currency-id' => 'ID da Moeda (correspondente Firefly)', - 'csv_column_currency-name' => 'Nome da Moeda (correspondente Firefly)', - 'csv_column_currency-symbol' => 'Símbolo da Moeda (correspondente Firefly)', - 'csv_column_date-rent' => 'Data de cálculo da renda', - 'csv_column_date-transaction' => 'Data', - 'csv_column_description' => 'Descrição', - 'csv_column_opposing-iban' => 'Opondo-se conta (IBAN)', - 'csv_column_opposing-id' => 'ID da conta opostas (Firefly equivalente)', - 'csv_column_opposing-name' => 'Opondo-se conta (nome)', - 'csv_column_rabo-debet-credit' => 'Indicador de débito/crédito do Rabobank', - 'csv_column_ing-debet-credit' => 'Indicador de débito/crédito do ING', - 'csv_column_sepa-ct-id' => 'Transferência de crédito SEPA fim-a-fim ID', - 'csv_column_sepa-ct-op' => 'Transferência de crédito SEPA conta contrária', - 'csv_column_sepa-db' => 'SEPA Débito Direto', - 'csv_column_tags-comma' => 'Tags (separadas por vírgula)', - 'csv_column_tags-space' => 'Tags (separadas por espaço)', - 'csv_column_account-number' => 'Conta de ativo (número da conta)', - 'csv_column_opposing-number' => 'Conta Contrária (número da conta)', - 'csv_specifix_RabobankDescription' => 'Selecione esta opção quando você estiver importando arquivos de exportação de CSV do Rabobank.', - 'csv_specifix_AbnAmroDescription' => 'Selecione esta opção quando você estiver importando arquivos de exportação de CSV do ABN AMRO.', - 'csv_specifix_Dummy' => 'Marcar esta não tem qualquer efeito.', - 'csv_import_account_help' => 'Se seu arquivo CSV não contém informações sobre sua(s) conta(s) ativa(s), use este combobox para selecionar para qual conta pertencem as transações em CSV.', - 'csv_delimiter_help' => 'Escolha o delimitador de campo que é usado em seu arquivo de entrada. Se não estiver claro, a vírgula é a opção mais segura.', - 'csv_date_parse_error' => 'Não foi possível analisar uma data válida de ":value", usando o formato ":formato". Tem certeza que seu CSV está correto?', - 'could_not_recover' => 'Não poderia continuar da etapa anterior. Seu progresso foi perdido :(. Os arquivos de log você dirão o que aconteceu.', - 'must_select_roles' => 'Você deve selecionar algumas funções para o conteúdo do arquivo, ou o processo não pode continuar.', - 'invalid_mapping' => 'Você se submeteu a um mapeamento inválido. O processo não pode continuar.', - 'no_file_uploaded' => 'Parece que você não enviou um arquivo.', - - // create new stuff: 'create_new_withdrawal' => 'Criar nova retirada', 'create_new_deposit' => 'Criar um novo depósito', @@ -500,6 +408,8 @@ return [ 'cannot_scan_inactive_bill' => 'Faturas inativas não podem ser verificadas.', 'rescanned_bill' => 'Tudo examinado novamente.', 'bill_date_little_relevance' => 'A única parte desta data usado pelo Firefly é o dia. Só é útil quando a conta chega exatamente na mesma data, todo mês. Se a data de pagamento de suas contas varia, basta usar o primeiro dia do mês.', + 'average_bill_amount_year' => 'Average bill amount (:year)', + 'average_bill_amount_overall' => 'Average bill amount (overall)', // accounts: 'details_for_asset' => 'Detalhes para a conta de ativo ":name"', @@ -644,19 +554,16 @@ return [ 'saveOnAccount' => 'Salvar na conta', 'unknown' => 'Desconhecido', 'daily' => 'Diário', - 'weekly' => 'Semanal', 'monthly' => 'Mensal', - 'quarterly' => 'Trimestral', - 'half-year' => 'Semestral', - 'yearly' => 'Anual', 'profile' => 'Perfil', + 'errors' => 'Errors', // reports: 'report_default' => 'Relatório financeiro padrão de :start até :end', 'report_audit' => 'Visão geral do histórico de transação de :start até :end', 'quick_link_reports' => 'Ligações rápidas', 'quick_link_default_report' => 'Relatório financeiro padrão', - 'quick_link_audit_report' => 'Transaction history overview', + 'quick_link_audit_report' => 'Visão geral do histórico de transação', 'report_this_month_quick' => 'Mês atual, todas as contas', 'report_this_year_quick' => 'Ano atual, todas as contas', 'report_this_fiscal_year_quick' => 'Ano fiscal atual, todas as contas', @@ -742,6 +649,7 @@ return [ 'balanceFor' => 'Saldo para ":name"', // piggy banks: + 'add_money_to_piggy' => 'Add money to piggy bank ":name"', 'piggy_bank' => 'Cofrinho', 'new_piggy_bank' => 'Criar novo cofrinho', 'store_piggy_bank' => 'Armazenar novo cofrinho', @@ -803,36 +711,70 @@ return [ 'user_administration' => 'Administração de usuários', 'list_all_users' => 'Todos os usuários', 'all_users' => 'Todos os usuários', + 'all_blocked_domains' => 'All blocked domains', + 'blocked_domains' => 'Blocked domains', + 'no_domains_banned' => 'No domains blocked', + 'all_user_domains' => 'All user email address domains', + 'all_domains_is_filtered' => 'This list does not include already blocked domains.', + 'domain_now_blocked' => 'Domain :domain is now blocked', + 'domain_now_unblocked' => 'Domain :domain is now unblocked', + 'manual_block_domain' => 'Block a domain by hand', + 'block_domain' => 'Block domain', + 'no_domain_filled_in' => 'No domain filled in', + 'domain_already_blocked' => 'Domain :domain is already blocked', + 'domain_is_now_blocked' => 'Domain :domain is now blocked', // split a transaction: - 'transaction_meta_data' => 'Transaction meta-data', - 'transaction_dates' => 'Transaction dates', - 'splits' => 'Splits', - 'split_title_withdrawal' => 'Split your new withdrawal', - 'split_intro_one_withdrawal' => 'Firefly supports the "splitting" of a withdrawal.', - 'split_intro_two_withdrawal' => 'It means that the amount of money you\'ve spent is divided between several destination expense accounts, budgets or categories.', - 'split_intro_three_withdrawal' => 'For example: you could split your :total groceries so you pay :split_one from your "daily groceries" budget and :split_two from your "cigarettes" budget.', - 'split_table_intro_withdrawal' => 'Split your withdrawal in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', - 'store_splitted_withdrawal' => 'Store splitted withdrawal', - 'update_splitted_withdrawal' => 'Update splitted withdrawal', - - 'split_title_deposit' => 'Split your new deposit', - 'split_intro_one_deposit' => 'Firefly supports the "splitting" of a deposit.', - 'split_intro_two_deposit' => 'It means that the amount of money you\'ve earned is divided between several source revenue accounts or categories.', - 'split_intro_three_deposit' => 'For example: you could split your :total salary so you get :split_one as your base salary and :split_two as a reimbursment for expenses made.', - 'split_table_intro_deposit' => 'Split your deposit in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', - 'store_splitted_deposit' => 'Store splitted deposit', - - 'split_title_transfer' => 'Split your new transfer', - 'split_intro_one_transfer' => 'Firefly supports the "splitting" of a transfer.', - 'split_intro_two_transfer' => 'It means that the amount of money you\'re moving is divided between several categories or piggy banks.', - 'split_intro_three_transfer' => 'For example: you could split your :total move so you get :split_one in one piggy bank and :split_two in another.', - 'split_table_intro_transfer' => 'Split your transfer in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', - 'store_splitted_transfer' => 'Store splitted transfer', - - 'add_another_split' => 'Add another split', - 'split-transactions' => 'Split transactions', - 'split-new-transaction' => 'Split a new transaction', - + 'transaction_meta_data' => 'Dados de transação', + 'transaction_dates' => 'Data de transação', + 'splits' => 'Divide-se', + 'split_title_withdrawal' => 'Dividir sua nova retirada', + 'split_intro_one_withdrawal' => 'Firefly suporta a "divisão" de uma retirada.', + 'split_intro_two_withdrawal' => 'Isso significa que a quantidade de dinheiro que você gastou será dividida entre várias contas de despesas do destino, orçamentos ou categorias.', + 'split_intro_three_withdrawal' => 'Por exemplo: você pode dividir seu :total de mantimentos de modo que você pague :split_one de seu orçamento diário de mantimentos e :split_two do seu orçamento para "cigarros".', + 'split_table_intro_withdrawal' => 'Dividi sua retirada em tantas coisas quanto quiser. Por padrão, a transação não será dividida, há apenas uma entrada. Adicione muitas divisões como desejar, abaixo. Lembre-se de que você não deve se desviar do seu montante total. Se o fizeres, Firefly irá avisá-lo mas não corrigirá.', + 'store_splitted_withdrawal' => 'Armazenar retirada dividida', + 'update_splitted_withdrawal' => 'Atualização de retirada dividida', + 'split_title_deposit' => 'Dividir seu novo depósito', + 'split_intro_one_deposit' => 'Firefly suporta a "divisão" de um depósito.', + 'split_intro_two_deposit' => 'Isso significa que a quantidade de dinheiro que você ganhou será dividida entre várias contas de receitas de fonte ou categorias.', + 'split_intro_three_deposit' => 'Por exemplo: você pode dividir seu :total salário para que você obtenha :split_one como seu salário-base e :split_two como um reembolso para alguma despesa.', + 'split_table_intro_deposit' => 'Dividi seu depósito em tantas coisas quanto quiser. Por padrão, a transação não será dividida, há apenas uma entrada. Adicione muitas divisões como desejar, abaixo. Lembre-se de que você não deve se desviar do seu montante total. Se o fizeres, Firefly irá avisá-lo mas não corrigirá.', + 'store_splitted_deposit' => 'Armazenar depósito dividido', + 'split_title_transfer' => 'Dividir sua nova transferência', + 'split_intro_one_transfer' => 'Firefly suporta a "divisão" de uma transferência.', + 'split_intro_two_transfer' => 'Isso significa que a quantidade de dinheiro que você está movendo será dividida entre várias categorias ou cofrinhos.', + 'split_intro_three_transfer' => 'Por exemplo: você pode dividir sua movimentação :total , para que você obtenha :split_one em um cofrinho e :split_two em outro.', + 'split_table_intro_transfer' => 'Dividi sua transferência em tantas coisas quanto quiser. Por padrão, a transação não será dividida, há apenas uma entrada. Adicione muitas divisões como desejar, abaixo. Lembre-se de que você não deve se desviar do seu montante total. Se o fizeres, Firefly irá avisá-lo mas não corrigirá.', + 'store_splitted_transfer' => 'Armazenar transferência dividida', + 'add_another_split' => 'Adicionar outra divisão', + 'split-transactions' => 'Dividir transações', + 'split-new-transaction' => 'Dividir uma nova transação', + 'do_split' => 'Do a split', + 'split_this_withdrawal' => 'Split this withdrawal', + 'split_this_deposit' => 'Split this deposit', + 'split_this_transfer' => 'Split this transfer', + 'cannot_edit_multiple_source' => 'You cannot edit splitted transaction #:id with description ":description" because it contains multiple source accounts.', + 'cannot_edit_multiple_dest' => 'You cannot edit splitted transaction #:id with description ":description" because it contains multiple destination accounts.', + 'no_edit_multiple_left' => 'You have selected no valid transactions to edit.', + // import + 'configuration_file_help' => 'If you have previously imported data into Firefly III, you may have a configuration file, which will pre-set configuration values for you.', + 'import_data_index' => 'Index', + 'import_file_type_csv' => 'CSV (comma separated values)', + 'import_file_type_help' => 'Select the type of file you will upload', + 'import_start' => 'Start the import', + 'configure_import' => 'Further configure your import', + 'import_finish_configuration' => 'Finish configuration', + 'settings_for_import' => 'Settings', + 'import_complete' => 'Import configuration complete!', + 'import_complete_text' => 'The import is ready to start. All the configuration you needed to do has been done. Please download the configuration file. It will help you with the import should it not go as planned. To actually run the import, you need to execute the following command in your console. Unfortunately, a web-based import is not yet possible.', + 'import_download_config' => 'Download configuration', + 'import_start_import' => 'Start import', + 'import_intro_beta' => 'The import function of Firefly III is in beta. Many users of Firefly III have tried many different files. Although each individual compontent of this import routine works (really), the combination might break. If your file cannot be imported by Firefly, please read this wiki page so I can fix the problem you have run into.', + 'import_data' => 'Import data', + 'import_data_full' => 'Import data into Firefly III', + 'import' => 'Import', + 'import_intro_text' => 'Welcome to the Firefly III data import routine. At the moment, this routine can help you import files into Firefly. To do so, you must download or export transactions from other systems or software, and upload them here. The next steps will let you help Firefly III determin what the content is of your file, and how to handle it. Please select a file, and read all instructions carefully.', + 'import_file_help' => 'Select your file', ]; diff --git a/resources/lang/pt_BR/form.php b/resources/lang/pt_BR/form.php index 1b7f25b825..639c6f6377 100644 --- a/resources/lang/pt_BR/form.php +++ b/resources/lang/pt_BR/form.php @@ -22,20 +22,20 @@ return [ 'amount_max' => 'Valor Máximo', 'match' => 'Corresponde em', 'repeat_freq' => 'Repetições', - 'journal_currency_id' => 'Currency', - 'journal_amount' => 'Amount', - 'journal_asset_source_account' => 'Asset account (source)', - 'journal_source_account_name' => 'Revenue account (source)', - 'journal_source_account_id' => 'Asset account (source)', + 'journal_currency_id' => 'Moeda', + 'journal_amount' => 'Quantia', + 'journal_asset_source_account' => 'Conta de ativo (fonte)', + 'journal_source_account_name' => 'Conta de receita (fonte)', + 'journal_source_account_id' => 'Conta de ativo (fonte)', 'account_from_id' => 'da conta', 'account_to_id' => 'para conta', - 'journal_destination_account_id' => 'Asset account (destination)', - 'asset_destination_account' => 'Asset account (destination)', - 'asset_source_account' => 'Asset account (source)', - 'journal_description' => 'Description', - 'split_journal' => 'Split this transaction', - 'split_journal_explanation' => 'Split this transaction in multiple parts', - 'currency' => 'Currency', + 'journal_destination_account_id' => 'Conta de ativo (destino)', + 'asset_destination_account' => 'Conta de ativo (destino)', + 'asset_source_account' => 'Conta de ativo (fonte)', + 'journal_description' => 'Descrição', + 'split_journal' => 'Dividir essa transação', + 'split_journal_explanation' => 'Dividir essa transação em várias partes', + 'currency' => 'Moeda', 'account_id' => 'Conta de ativo', 'budget_id' => 'Orçamento', 'openingBalance' => 'Saldo inicial', @@ -71,13 +71,9 @@ return [ 'code' => 'Código', 'iban' => 'IBAN', 'accountNumber' => 'Número de conta', - 'csv' => 'Arquivo CSV', 'has_headers' => 'Cabeçalhos', 'date_format' => 'Formato da Data', - 'csv_config' => 'Importar CSV de configuração', 'specifix' => 'Banco- ou arquivo específico corrigídos', - 'csv_import_account' => 'Conta de importação padrão', - 'csv_delimiter' => 'Delimitador de campo CSV', 'attachments[]' => 'Anexos', 'store_new_withdrawal' => 'Armazenar nova retirada', 'store_new_deposit' => 'Armazenar novo depósito', @@ -102,9 +98,6 @@ return [ 'include_config' => 'Incluir o arquivo de configuração', 'include_old_uploads' => 'Incluir dados importados', 'accounts' => 'Exportar transações destas contas', - 'csv_comma' => 'Uma vírgula (,)', - 'csv_semicolon' => 'Um ponto e vírgula (;)', - 'csv_tab' => 'Um Tab (invisível)', 'delete_account' => 'Apagar conta ":name"', 'delete_bill' => 'Apagar fatura ":name"', 'delete_budget' => 'Excluir o orçamento ":name"', @@ -137,4 +130,20 @@ return [ 'budget_keep_transactions' => 'A única transação conectada a este orçamento não será excluída.|Todos :count transações ligadas a este orçamento não serão excluídos.', 'category_keep_transactions' => 'A única transação ligada a esta categoria não será excluída.|Todos :count transações ligadas a esta categoria não serão excluídos.', 'tag_keep_transactions' => 'A única transação ligada a essa marca não será excluída.|Todos :count transações ligadas a essa marca não serão excluídos.', + + // admin + 'domain' => 'Domain', + + // import + 'import_file' => 'Import file', + 'configuration_file' => 'Configuration file', + 'import_file_type' => 'Import file type', + 'csv_comma' => 'Uma vírgula (,)', + 'csv_semicolon' => 'Um ponto e vírgula (;)', + 'csv_tab' => 'Um Tab (invisível)', + 'csv_delimiter' => 'Delimitador de campo CSV', + 'csv_import_account' => 'Conta de importação padrão', + 'csv_config' => 'Importar CSV de configuração', + + ]; diff --git a/resources/lang/pt_BR/help.php b/resources/lang/pt_BR/help.php index 9f720e032e..c0ce893390 100644 --- a/resources/lang/pt_BR/help.php +++ b/resources/lang/pt_BR/help.php @@ -55,11 +55,6 @@ return [ 'categories-show' => 'Detalhes de Categorias', 'categories-show-date' => 'Detalhes da Categoria por Data', 'categories-noCategory' => 'Sem Categorias', - 'csv-index' => 'Carregar e importar um arquivo CSV', - 'csv-column-roles' => 'CSV Papel da coluna', - 'csv-map' => 'Mapeamento CSV', - 'csv-download-config-page' => 'Baixando CSV de Configuração', - 'csv-process' => 'Processando CSV', 'currency-index' => 'Moedas', 'currency-create' => 'Criando Moedas', 'currency-edit' => 'Editando Moedas', diff --git a/resources/lang/pt_BR/list.php b/resources/lang/pt_BR/list.php index 21e94af988..5d0c5f460d 100644 --- a/resources/lang/pt_BR/list.php +++ b/resources/lang/pt_BR/list.php @@ -8,54 +8,59 @@ */ return [ - 'buttons' => 'Botões', - 'icon' => 'Ícone', - 'create_date' => 'Criado em', - 'update_date' => 'Atualizado em', - 'balance_before' => 'Saldo Antes', - 'balance_after' => 'Saldo depois', - 'name' => 'Nome', - 'role' => 'Papel', - 'currentBalance' => 'Saldo atual', - 'active' => 'Está ativo?', - 'lastActivity' => 'Última atividade', - 'balanceDiff' => 'Saldo diferente entre :start e :end', - 'matchedOn' => 'Coincide', - 'matchesOn' => 'Correspondido em', - 'account_type' => 'Account type', - 'new_balance' => 'New balance', - 'account' => 'Account', - 'matchingAmount' => 'Total', - 'lastMatch' => 'Último equivalente', - 'split_number' => 'Split #', - 'destination' => 'Destination', - 'expectedMatch' => 'Equivalente esperado', - 'automatch' => 'Auto match?', - 'repeat_freq' => 'Repetições', - 'description' => 'Descrição', - 'amount' => 'Total', - 'date' => 'Data', - 'interest_date' => 'Data de interesse', - 'book_date' => 'Data reserva', - 'process_date' => 'Data de processamento', - 'from' => 'De', - 'piggy_bank' => 'Piggy bank', - 'to' => 'Até', - 'budget' => 'Orçamento', - 'category' => 'Categoria', - 'bill' => 'Fatura', - 'withdrawal' => 'Retirada', - 'deposit' => 'Depósito', - 'transfer' => 'Transferência', - 'type' => 'Tipo', - 'completed' => 'Completo', - 'iban' => 'IBAN', - 'paid_current_period' => 'Pago este período', - 'email' => 'Email', - 'registered_at' => 'Registrado em', - 'is_activated' => 'Está ativo', - 'is_blocked' => 'Está bloqueado', - 'is_admin' => 'É admin', - 'has_two_factor' => 'Tem 2FA', - 'blocked_code' => 'Bloco de código', + 'buttons' => 'Botões', + 'icon' => 'Ícone', + 'create_date' => 'Criado em', + 'update_date' => 'Atualizado em', + 'balance_before' => 'Saldo Antes', + 'balance_after' => 'Saldo depois', + 'name' => 'Nome', + 'role' => 'Papel', + 'currentBalance' => 'Saldo atual', + 'active' => 'Está ativo?', + 'lastActivity' => 'Última atividade', + 'balanceDiff' => 'Saldo diferente entre :start e :end', + 'matchedOn' => 'Coincide', + 'matchesOn' => 'Correspondido em', + 'account_type' => 'Tipo de conta', + 'new_balance' => 'Novo saldo', + 'account' => 'Conta', + 'matchingAmount' => 'Total', + 'lastMatch' => 'Último equivalente', + 'split_number' => 'Dividir #', + 'destination' => 'Destino', + 'source' => 'Source', + 'expectedMatch' => 'Equivalente esperado', + 'automatch' => 'Auto match?', + 'repeat_freq' => 'Repetições', + 'description' => 'Descrição', + 'amount' => 'Total', + 'date' => 'Data', + 'interest_date' => 'Data de interesse', + 'book_date' => 'Data reserva', + 'process_date' => 'Data de processamento', + 'from' => 'De', + 'piggy_bank' => 'Cofrinho', + 'to' => 'Até', + 'budget' => 'Orçamento', + 'category' => 'Categoria', + 'bill' => 'Fatura', + 'withdrawal' => 'Retirada', + 'deposit' => 'Depósito', + 'transfer' => 'Transferência', + 'type' => 'Tipo', + 'completed' => 'Completo', + 'iban' => 'IBAN', + 'paid_current_period' => 'Pago este período', + 'email' => 'Email', + 'registered_at' => 'Registrado em', + 'is_activated' => 'Está ativo', + 'is_blocked' => 'Está bloqueado', + 'is_admin' => 'É admin', + 'has_two_factor' => 'Tem 2FA', + 'confirmed_from' => 'Confirmed from', + 'registered_from' => 'Registered from', + 'blocked_code' => 'Bloco de código', + 'domain' => 'Domain', + 'registration_attempts' => 'Registration attempts', ]; diff --git a/resources/lang/pt_BR/validation.php b/resources/lang/pt_BR/validation.php index f34f08e2d2..2817960330 100644 --- a/resources/lang/pt_BR/validation.php +++ b/resources/lang/pt_BR/validation.php @@ -17,7 +17,7 @@ return [ 'file_attached' => 'Arquivo carregado com sucesso ":name".', 'file_invalid_mime' => 'Arquivo ":name" é do tipo ":mime" que não é aceito como um novo upload.', 'file_too_large' => 'Arquivo ":name" é muito grande.', - 'belongs_to_user' => 'The value of :attribute is unknown', + 'belongs_to_user' => 'O valor de :attribute é desconhecido', 'accepted' => 'O campo :attribute deve ser aceito.', 'active_url' => 'O campo :attribute não contém um URL válido.', 'after' => 'O campo :attribute deverá conter uma data posterior a :date.', diff --git a/resources/lang/zh-HK/breadcrumbs.php b/resources/lang/zh-HK/breadcrumbs.php new file mode 100644 index 0000000000..bdd804cf63 --- /dev/null +++ b/resources/lang/zh-HK/breadcrumbs.php @@ -0,0 +1,46 @@ + 'Home', + 'cash_accounts' => 'Cash accounts', + 'edit_account' => 'Edit account ":name"', + 'edit_currency' => 'Edit currencies ":name"', + 'delete_currency' => 'Delete currencies ":name"', + 'newPiggyBank' => 'Create a new piggy bank', + 'edit_piggyBank' => 'Edit piggy bank ":name"', + 'preferences' => 'Preferences', + 'profile' => 'Profile', + 'changePassword' => 'Change your password', + 'bills' => 'Bills', + 'newBill' => 'New bill', + 'edit_bill' => 'Edit bill ":name"', + 'delete_bill' => 'Delete bill ":name"', + 'reports' => 'Reports', + 'monthly_report' => 'Monthly report for :date', + 'monthly_report_shared' => 'Monthly report for :date (including shared accounts)', + 'yearly_report' => 'Yearly report for :date', + 'yearly_report_shared' => 'Yearly report for :date (including shared accounts)', + 'budget_report' => 'Budget report for :date', + 'searchResult' => 'Search for ":query"', + 'withdrawal_list' => 'Expenses', + 'deposit_list' => 'Revenue, income and deposits', + 'transfer_list' => 'Transfers', + 'transfers_list' => 'Transfers', + 'create_withdrawal' => 'Create new withdrawal', + 'create_deposit' => 'Create new deposit', + 'create_transfer' => 'Create new transfer', + 'edit_journal' => 'Edit transaction ":description"', + 'delete_journal' => 'Delete transaction ":description"', + 'tags' => 'Tags', + 'createTag' => 'Create new tag', + 'edit_tag' => 'Edit tag ":tag"', + 'delete_tag' => 'Delete tag ":tag"', +]; diff --git a/resources/lang/zh-HK/config.php b/resources/lang/zh-HK/config.php new file mode 100644 index 0000000000..b8ed029a46 --- /dev/null +++ b/resources/lang/zh-HK/config.php @@ -0,0 +1,21 @@ + 'en, English, en_US, en_US.utf8', + 'month' => '%B %Y', + 'month_and_day' => '%B %e, %Y', + 'date_time' => '%B %e, %Y, @ %T', + 'specific_day' => '%e %B %Y', + 'week_in_year' => 'Week %W, %Y', + 'quarter_of_year' => '%B %Y', + 'year' => '%Y', + 'half_year' => '%B %Y', + +]; diff --git a/resources/lang/zh-HK/csv.php b/resources/lang/zh-HK/csv.php new file mode 100644 index 0000000000..fef82823e3 --- /dev/null +++ b/resources/lang/zh-HK/csv.php @@ -0,0 +1,80 @@ + 'Configure your import', + 'import_configure_intro' => 'There are some options for your CSV import. Please indicate if your CSV file contains headers on the first column, and what the date format of your date-fields is. That might require some experimentation. The field delimiter is usually a ",", but could also be a ";". Check this carefully.', + 'import_configure_form' => 'Form', + 'header_help' => 'Check this if the first row of your CSV file are the column titles', + 'date_help' => 'Date time format in your CSV. Follow the format like this page indicates. The default value will parse dates that look like this: :dateExample.', + 'delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.', + 'config_file_help' => 'Select your CSV import configuration here. If you do not know what this is, ignore it. It will be explained later.', + 'import_account_help' => 'If your CSV file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the CSV belong to.', + 'upload_not_writeable' => 'The grey box contains a file path. It should be writeable. Please make sure it is.', + + // roles + 'column_roles_title' => 'Define column roles', + 'column_roles_text' => '

Firefly III cannot guess what data each column contains. You must tell Firefly which kinds of data to expect. The example data can guide you into picking the correct type from the dropdown. If a column cannot be matched to a useful data type, please let me know by creating an issue.

Some values in your CSV file, such as account names or categories, may already exist in your Firefly III database. If you select "map these values" Firefly will not attempt to search for matching values itself but allow you to match the CSV values against the values in your database. This allows you to fine-tune the import.

', + 'column_roles_table' => 'Table', + 'column_name' => 'Name of column', + 'column_example' => 'Column example data', + 'column_role' => 'Column data meaning', + 'do_map_value' => 'Map these values', + 'column' => 'Column', + 'no_example_data' => 'No example data available', + 'store_column_roles' => 'Continue import', + 'do_not_map' => '(do not map)', + 'map_title' => 'Connect import data to Firefly III data', + 'map_text' => 'In the following tables, the left value shows you information found in your uploaded CSV file. It is your task to map this value, if possible, to a value already present in your database. Firefly will stick to this mapping. If there is no value to map to, or you do not wish to map the specific value, select nothing.', + + 'field_value' => 'Field value', + 'field_mapped_to' => 'Mapped to', + 'store_column_mapping' => 'Store mapping', + + // map things. + + + 'column__ignore' => '(ignore this column)', + 'column_account-iban' => 'Asset account (IBAN)', + 'column_account-id' => 'Asset account ID (matching Firefly)', + 'column_account-name' => 'Asset account (name)', + 'column_amount' => 'Amount', + 'column_amount-comma-separated' => 'Amount (comma as decimal separator)', + 'column_bill-id' => 'Bill ID (matching Firefly)', + 'column_bill-name' => 'Bill name', + 'column_budget-id' => 'Budget ID (matching Firefly)', + 'column_budget-name' => 'Budget name', + 'column_category-id' => 'Category ID (matching Firefly)', + 'column_category-name' => 'Category name', + 'column_currency-code' => 'Currency code (ISO 4217)', + 'column_currency-id' => 'Currency ID (matching Firefly)', + 'column_currency-name' => 'Currency name (matching Firefly)', + 'column_currency-symbol' => 'Currency symbol (matching Firefly)', + 'column_date-interest' => 'Interest calculation date', + 'column_date-book' => 'Transaction booking date', + 'column_date-process' => 'Transaction process date', + 'column_date-transaction' => 'Date', + 'column_description' => 'Description', + 'column_opposing-iban' => 'Opposing account (IBAN)', + 'column_opposing-id' => 'Opposing account ID (matching Firefly)', + 'column_external-id' => 'External ID', + 'column_opposing-name' => 'Opposing account (name)', + 'column_rabo-debet-credit' => 'Rabobank specific debet/credit indicator', + 'column_ing-debet-credit' => 'ING specific debet/credit indicator', + 'column_sepa-ct-id' => 'SEPA Credit Transfer end-to-end ID', + 'column_sepa-ct-op' => 'SEPA Credit Transfer opposing account', + 'column_sepa-db' => 'SEPA Direct Debet', + 'column_tags-comma' => 'Tags (comma separated)', + 'column_tags-space' => 'Tags (space separated)', + 'column_account-number' => 'Asset account (account number)', + 'column_opposing-number' => 'Opposing account (account number)', +]; diff --git a/resources/lang/zh-HK/firefly.php b/resources/lang/zh-HK/firefly.php new file mode 100644 index 0000000000..08238377e7 --- /dev/null +++ b/resources/lang/zh-HK/firefly.php @@ -0,0 +1,780 @@ + 'This language is not yet fully translated', + 'test' => 'You have selected English.', + 'close' => 'Close', + 'pleaseHold' => 'Please hold...', + 'actions' => 'Actions', + 'edit' => 'Edit', + 'delete' => 'Delete', + 'welcomeBack' => 'What\'s playing?', + 'everything' => 'Everything', + 'customRange' => 'Custom range', + 'apply' => 'Apply', + 'cancel' => 'Cancel', + 'from' => 'From', + 'to' => 'To', + 'total_sum' => 'Total sum', + 'period_sum' => 'Sum for period', + 'showEverything' => 'Show everything', + 'never' => 'Never', + 'search_results_for' => 'Search results for ":query"', + 'bounced_error' => 'The message sent to :email bounced, so no access for you.', + 'deleted_error' => 'These credentials do not match our records.', + 'general_blocked_error' => 'Your account has been disabled, so you cannot login.', + 'expired_error' => 'Your account has expired, and can no longer be used.', + 'unbalanced_error' => 'Your transactions are unbalanced. This means a withdrawal, deposit or transfer was not stored properly. Please check your accounts and transactions for errors (unbalanced amount :amount).', + 'removed_amount' => 'Removed :amount', + 'added_amount' => 'Added :amount', + 'asset_account_role_help' => 'Any extra options resulting from your choice can be set later.', + 'Opening balance' => 'Opening balance', + 'create_new_stuff' => 'Create new stuff', + 'new_withdrawal' => 'New withdrawal', + 'new_deposit' => 'New deposit', + 'new_transfer' => 'New transfer', + 'new_asset_account' => 'New asset account', + 'new_expense_account' => 'New expense account', + 'new_revenue_account' => 'New revenue account', + 'new_budget' => 'New budget', + 'new_bill' => 'New bill', + 'block_account_logout' => 'You have been logged out. Blocked accounts cannot use this site. Did you register with a valid email address?', + 'flash_success' => 'Success!', + 'flash_info' => 'Message', + 'flash_warning' => 'Warning!', + 'flash_error' => 'Error!', + 'flash_info_multiple' => 'There is one message|There are :count messages', + 'flash_error_multiple' => 'There is one error|There are :count errors', + 'net_worth' => 'Net worth', + 'route_has_no_help' => 'There is no help for this route, or there is no help available in your language.', + 'two_factor_welcome' => 'Hello, :user!', + 'two_factor_enter_code' => 'To continue, please enter your two factor authentication code. Your application can generate it for you.', + 'two_factor_code_here' => 'Enter code here', + 'two_factor_title' => 'Two factor authentication', + 'authenticate' => 'Authenticate', + 'two_factor_forgot_title' => 'Lost two factor authentication', + 'two_factor_forgot' => 'I forgot my two-factor thing.', + 'two_factor_lost_header' => 'Lost your two factor authentication?', + 'two_factor_lost_intro' => 'Unfortunately, this is not something you can reset from the web interface. You have two choices.', + 'two_factor_lost_fix_self' => 'If you run your own instance of Firefly III, check the logs in storage/logs for instructions.', + 'two_factor_lost_fix_owner' => 'Otherwise, email the site owner, :site_owner and ask them to reset your two factor authentication.', + 'warning_much_data' => ':days days of data may take a while to load.', + 'registered' => 'You have registered successfully!', + 'search' => 'Search', + 'no_budget_pointer' => 'You seem to have no budgets yet. You should create some on the budgets-page. Budgets can help you keep track of expenses.', + 'source_accounts' => 'Source account(s)', + 'destination_accounts' => 'Destination account(s)', + + // repeat frequencies: + 'repeat_freq_monthly' => 'monthly', + 'weekly' => 'weekly', + 'quarterly' => 'quarterly', + 'half-year' => 'every half year', + 'yearly' => 'yearly', + // account confirmation: + 'confirm_account_header' => 'Please confirm your account', + 'confirm_account_intro' => 'An email has been sent to the address you used during your registration. Please check it out for further instructions. If you did not get this message, you can have Firefly send it again.', + 'confirm_account_resend_email' => 'Send me the confirmation message I need to activate my account.', + 'account_is_confirmed' => 'Your account has been confirmed!', + 'invalid_activation_code' => 'It seems the code you are using is not valid, or has expired.', + 'confirm_account_is_resent_header' => 'The confirmation has been resent', + 'confirm_account_is_resent_text' => 'The confirmation message has been resent. If you still did not receive the confirmation message, please contact the site owner at :owner or check the log files to see what went wrong.', + 'confirm_account_is_resent_go_home' => 'Go to the index page of Firefly', + 'confirm_account_not_resent_header' => 'Something went wrong :(', + 'confirm_account_not_resent_intro' => 'The confirmation message has been not resent. If you still did not receive the confirmation message, please contact the site owner at :owner instead. Possibly, you have tried to resend the activation message too often. You can have Firefly III try to resend the confirmation message every hour.', + 'confirm_account_not_resent_go_home' => 'Go to the index page of Firefly', + + // export data: + 'import_and_export' => 'Import and export', + 'export_data' => 'Export data', + 'export_data_intro' => 'For backup purposes, when migrating to another system or when migrating to another Firefly III installation.', + 'export_format' => 'Export format', + 'export_format_csv' => 'Comma separated values (CSV file)', + 'export_format_mt940' => 'MT940 compatible format', + 'export_included_accounts' => 'Export transactions from these accounts', + 'include_config_help' => 'For easy re-import into Firefly III', + 'include_old_uploads_help' => 'Firefly III does not throw away the original CSV files you have imported in the past. You can include them in your export.', + 'do_export' => 'Export', + 'export_status_never_started' => 'The export has not started yet', + 'export_status_make_exporter' => 'Creating exporter thing...', + 'export_status_collecting_journals' => 'Collecting your transactions...', + 'export_status_collected_journals' => 'Collected your transactions!', + 'export_status_converting_to_export_format' => 'Converting your transactions...', + 'export_status_converted_to_export_format' => 'Converted your transactions!', + 'export_status_creating_journal_file' => 'Creating the export file...', + 'export_status_created_journal_file' => 'Created the export file!', + 'export_status_collecting_attachments' => 'Collecting all your attachments...', + 'export_status_collected_attachments' => 'Collected all your attachments!', + 'export_status_collecting_old_uploads' => 'Collecting all your previous uploads...', + 'export_status_collected_old_uploads' => 'Collected all your previous uploads!', + 'export_status_creating_config_file' => 'Creating a configuration file...', + 'export_status_created_config_file' => 'Created a configuration file!', + 'export_status_creating_zip_file' => 'Creating a zip file...', + 'export_status_created_zip_file' => 'Created a zip file!', + 'export_status_finished' => 'Export has succesfully finished! Yay!', + 'export_data_please_wait' => 'Please wait...', + 'attachment_explanation' => 'The file called \':attachment_name\' (#:attachment_id) was originally uploaded to :type \':description\' (#:journal_id) dated :date for the amount of :amount.', + + // rules + 'rules' => 'Rules', + 'rules_explanation' => 'Here you can manage rules. Rules are triggered when a transaction is created or updated. Then, if the transaction has certain properties (called "triggers") Firefly will execute the "actions". Combined, you can make Firefly respond in a certain way to new transactions.', + 'rule_name' => 'Name of rule', + 'rule_triggers' => 'Rule triggers when', + 'rule_actions' => 'Rule will', + 'new_rule' => 'New rule', + 'new_rule_group' => 'New rule group', + 'rule_priority_up' => 'Give rule more priority', + 'rule_priority_down' => 'Give rule less priority', + 'make_new_rule_group' => 'Make new rule group', + 'store_new_rule_group' => 'Store new rule group', + 'created_new_rule_group' => 'New rule group ":title" stored!', + 'updated_rule_group' => 'Successfully updated rule group ":title".', + 'edit_rule_group' => 'Edit rule group ":title"', + 'delete_rule_group' => 'Delete rule group ":title"', + 'deleted_rule_group' => 'Deleted rule group ":title"', + 'update_rule_group' => 'Update rule group', + 'no_rules_in_group' => 'There are no rules in this group', + 'move_rule_group_up' => 'Move rule group up', + 'move_rule_group_down' => 'Move rule group down', + 'save_rules_by_moving' => 'Save these rule(s) by moving them to another rule group:', + 'make_new_rule' => 'Make new rule in rule group ":title"', + 'rule_help_stop_processing' => 'When you check this box, later rules in this group will not be executed.', + 'rule_help_active' => 'Inactive rules will never fire.', + 'stored_new_rule' => 'Stored new rule with title ":title"', + 'deleted_rule' => 'Deleted rule with title ":title"', + 'store_new_rule' => 'Store new rule', + 'updated_rule' => 'Updated rule with title ":title"', + 'default_rule_group_name' => 'Default rules', + 'default_rule_group_description' => 'All your rules not in a particular group.', + 'default_rule_name' => 'Your first default rule', + 'default_rule_description' => 'This rule is an example. You can safely delete it.', + 'default_rule_trigger_description' => 'The Man Who Sold the World', + 'default_rule_trigger_from_account' => 'David Bowie', + 'default_rule_action_prepend' => 'Bought the world from ', + 'default_rule_action_set_category' => 'Large expenses', + 'trigger' => 'Trigger', + 'trigger_value' => 'Trigger on value', + 'stop_processing_other_triggers' => 'Stop processing other triggers', + 'add_rule_trigger' => 'Add new trigger', + 'action' => 'Action', + 'action_value' => 'Action value', + 'stop_executing_other_actions' => 'Stop executing other actions', + 'add_rule_action' => 'Add new action', + 'edit_rule' => 'Edit rule ":title"', + 'delete_rule' => 'Delete rule ":title"', + 'update_rule' => 'Update rule', + 'test_rule_triggers' => 'See matching transactions', + 'warning_transaction_subset' => 'For performance reasons this list is limited to :max_num_transactions and may only show a subset of matching transactions', + 'warning_no_matching_transactions' => 'No matching transactions found. Please note that for performance reasons, only the last :num_transactions transactions have been checked.', + 'warning_no_valid_triggers' => 'No valid triggers provided.', + 'execute_on_existing_transactions' => 'Execute for existing transactions', + 'execute_on_existing_transactions_intro' => 'When a rule or group has been changed or added, you can execute it for existing transactions', + 'execute_on_existing_transactions_short' => 'Existing transactions', + 'executed_group_on_existing_transactions' => 'Executed group ":title" for existing transactions', + 'execute_group_on_existing_transactions' => 'Execute group ":title" for existing transactions', + 'include_transactions_from_accounts' => 'Include transactions from these accounts', + 'execute' => 'Execute', + + // actions and triggers + 'rule_trigger_user_action' => 'User action is ":trigger_value"', + 'rule_trigger_from_account_starts' => 'Source account starts with ":trigger_value"', + 'rule_trigger_from_account_ends' => 'Source account ends with ":trigger_value"', + 'rule_trigger_from_account_is' => 'Source account is ":trigger_value"', + 'rule_trigger_from_account_contains' => 'Source account contains ":trigger_value"', + 'rule_trigger_to_account_starts' => 'Destination account starts with ":trigger_value"', + 'rule_trigger_to_account_ends' => 'Destination account ends with ":trigger_value"', + 'rule_trigger_to_account_is' => 'Destination account is ":trigger_value"', + 'rule_trigger_to_account_contains' => 'Destination account contains ":trigger_value"', + 'rule_trigger_transaction_type' => 'Transaction is of type ":trigger_value"', + 'rule_trigger_amount_less' => 'Amount is less than :trigger_value', + 'rule_trigger_amount_exactly' => 'Amount is :trigger_value', + 'rule_trigger_amount_more' => 'Amount is more than :trigger_value', + 'rule_trigger_description_starts' => 'Description starts with ":trigger_value"', + 'rule_trigger_description_ends' => 'Description ends with ":trigger_value"', + 'rule_trigger_description_contains' => 'Description contains ":trigger_value"', + 'rule_trigger_description_is' => 'Description is ":trigger_value"', + 'rule_trigger_from_account_starts_choice' => 'Source account starts with..', + 'rule_trigger_from_account_ends_choice' => 'Source account ends with..', + 'rule_trigger_from_account_is_choice' => 'Source account is..', + 'rule_trigger_from_account_contains_choice' => 'Source account contains..', + 'rule_trigger_to_account_starts_choice' => 'Destination account starts with..', + 'rule_trigger_to_account_ends_choice' => 'Destination account ends with..', + 'rule_trigger_to_account_is_choice' => 'Destination account is..', + 'rule_trigger_to_account_contains_choice' => 'Destination account contains..', + 'rule_trigger_transaction_type_choice' => 'Transaction is of type..', + 'rule_trigger_amount_less_choice' => 'Amount is less than..', + 'rule_trigger_amount_exactly_choice' => 'Amount is..', + 'rule_trigger_amount_more_choice' => 'Amount is more than..', + 'rule_trigger_description_starts_choice' => 'Description starts with..', + 'rule_trigger_description_ends_choice' => 'Description ends with..', + 'rule_trigger_description_contains_choice' => 'Description contains..', + 'rule_trigger_description_is_choice' => 'Description is..', + 'rule_trigger_store_journal' => 'When a journal is created', + 'rule_trigger_update_journal' => 'When a journal is updated', + 'rule_action_set_category' => 'Set category to ":action_value"', + 'rule_action_clear_category' => 'Clear category', + 'rule_action_set_budget' => 'Set budget to ":action_value"', + 'rule_action_clear_budget' => 'Clear budget', + 'rule_action_add_tag' => 'Add tag ":action_value"', + 'rule_action_remove_tag' => 'Remove tag ":action_value"', + 'rule_action_remove_all_tags' => 'Remove all tags', + 'rule_action_set_description' => 'Set description to ":action_value"', + 'rule_action_append_description' => 'Append description with ":action_value"', + 'rule_action_prepend_description' => 'Prepend description with ":action_value"', + 'rule_action_set_category_choice' => 'Set category to..', + 'rule_action_clear_category_choice' => 'Clear any category', + 'rule_action_set_budget_choice' => 'Set budget to..', + 'rule_action_clear_budget_choice' => 'Clear any budget', + 'rule_action_add_tag_choice' => 'Add tag..', + 'rule_action_remove_tag_choice' => 'Remove tag..', + 'rule_action_remove_all_tags_choice' => 'Remove all tags', + 'rule_action_set_description_choice' => 'Set description to..', + 'rule_action_append_description_choice' => 'Append description with..', + 'rule_action_prepend_description_choice' => 'Prepend description with..', + + // tags + 'store_new_tag' => 'Store new tag', + 'update_tag' => 'Update tag', + 'no_location_set' => 'No location set.', + 'meta_data' => 'Meta data', + 'location' => 'Location', + + // preferences + 'pref_home_screen_accounts' => 'Home screen accounts', + 'pref_home_screen_accounts_help' => 'Which accounts should be displayed on the home page?', + 'pref_budget_settings' => 'Budget settings', + 'pref_budget_settings_help' => 'What\'s the maximum amount of money a budget envelope may contain?', + 'pref_view_range' => 'View range', + 'pref_view_range_help' => 'Some charts are automatically grouped in periods. What period would you prefer?', + 'pref_1D' => 'One day', + 'pref_1W' => 'One week', + 'pref_1M' => 'One month', + 'pref_3M' => 'Three months (quarter)', + 'pref_6M' => 'Six months', + 'pref_1Y' => 'One year', + 'pref_languages' => 'Languages', + 'pref_languages_help' => 'Firefly III supports several languages. Which one do you prefer?', + 'pref_custom_fiscal_year' => 'Fiscal year settings', + 'pref_custom_fiscal_year_label' => 'Enabled', + 'pref_custom_fiscal_year_help' => 'In countries that use a financial year other than January 1 to December 31, you can switch this on and specify start / end days of the fiscal year', + 'pref_fiscal_year_start_label' => 'Fiscal year start date', + 'pref_two_factor_auth' => '2-step verification', + 'pref_two_factor_auth_help' => 'When you enable 2-step verification (also known as two-factor authentication), you add an extra layer of security to your account. You sign in with something you know (your password) and something you have (a verification code). Verification codes are generated by an application on your phone, such as Authy or Google Authenticator.', + 'pref_enable_two_factor_auth' => 'Enable 2-step verification', + 'pref_two_factor_auth_disabled' => '2-step verification code removed and disabled', + 'pref_two_factor_auth_remove_it' => 'Don\'t forget to remove the account from your authentication app!', + 'pref_two_factor_auth_code' => 'Verify code', + 'pref_two_factor_auth_code_help' => 'Scan the QR code with an application on your phone such as Authy or Google Authenticator and enter the generated code.', + 'pref_two_factor_auth_reset_code' => 'Reset verification code', + 'pref_two_factor_auth_remove_code' => 'Remove verification code', + 'pref_two_factor_auth_remove_will_disable' => '(this will also disable two-factor authentication)', + 'pref_save_settings' => 'Save settings', + 'saved_preferences' => 'Preferences saved!', + 'transaction_page_size_title' => 'Page size', + 'transaction_page_size_help' => 'Any list of transactions shows at most this many transactions', + 'transaction_page_size_label' => 'Page size', + 'budget_maximum' => 'Budget maximum', + 'between_dates' => '(:start and :end)', + + // profile: + 'change_your_password' => 'Change your password', + 'delete_account' => 'Delete account', + 'current_password' => 'Current password', + 'new_password' => 'New password', + 'new_password_again' => 'New password (again)', + 'delete_your_account' => 'Delete your account', + 'delete_your_account_help' => 'Deleting your account will also delete any accounts, transactions, anything you might have saved into Firefly III. It\'ll be GONE.', + 'delete_your_account_password' => 'Enter your password to continue.', + 'password' => 'Password', + 'are_you_sure' => 'Are you sure? You cannot undo this.', + 'delete_account_button' => 'DELETE your account', + 'invalid_current_password' => 'Invalid current password!', + 'password_changed' => 'Password changed!', + 'should_change' => 'The idea is to change your password.', + 'invalid_password' => 'Invalid password!', + + + // attachments + 'nr_of_attachments' => 'One attachment|:count attachments', + 'attachments' => 'Attachments', + 'edit_attachment' => 'Edit attachment ":name"', + 'update_attachment' => 'Update attachment', + 'delete_attachment' => 'Delete attachment ":name"', + 'attachment_deleted' => 'Deleted attachment ":name"', + 'attachment_updated' => 'Updated attachment ":name"', + 'upload_max_file_size' => 'Maximum file size: :size', + + // tour: + 'prev' => 'Prev', + 'next' => 'Next', + 'end-tour' => 'End tour', + 'pause' => 'Pause', + + // transaction index + 'title_expenses' => 'Expenses', + 'title_withdrawal' => 'Expenses', + 'title_revenue' => 'Revenue / income', + 'title_deposit' => 'Revenue / income', + 'title_transfer' => 'Transfers', + 'title_transfers' => 'Transfers', + + // create new stuff: + 'create_new_withdrawal' => 'Create new withdrawal', + 'create_new_deposit' => 'Create new deposit', + 'create_new_transfer' => 'Create new transfer', + 'create_new_asset' => 'Create new asset account', + 'create_new_expense' => 'Create new expense account', + 'create_new_revenue' => 'Create new revenue account', + 'create_new_piggy_bank' => 'Create new piggy bank', + 'create_new_bill' => 'Create new bill', + + // currencies: + 'create_currency' => 'Create a new currency', + 'edit_currency' => 'Edit currency ":name"', + 'store_currency' => 'Store new currency', + 'update_currency' => 'Update currency', + 'new_default_currency' => ':name is now the default currency.', + 'cannot_delete_currency' => 'Cannot delete :name because there are still transactions attached to it!', + 'deleted_currency' => 'Currency :name deleted', + 'created_currency' => 'Currency :name created', + 'updated_currency' => 'Currency :name updated', + 'ask_site_owner' => 'Please ask :owner to add, remove or edit currencies.', + 'currencies_intro' => 'Firefly III supports various currencies which you can set and enable here.', + 'make_default_currency' => 'make default', + 'default_currency' => 'default', + + // new user: + 'submit' => 'Submit', + 'getting_started' => 'Getting started', + 'to_get_started' => 'To get started with Firefly, please enter your current bank\'s name, and the balance of your checking account:', + 'savings_balance_text' => 'If you have a savings account, please enter the current balance of your savings account:', + 'cc_balance_text' => 'If you have a credit card, please enter your credit card\'s limit.', + 'stored_new_account_new_user' => 'Yay! Your new account has been stored.', + 'stored_new_accounts_new_user' => 'Yay! Your new accounts have been stored.', + + // forms: + 'mandatoryFields' => 'Mandatory fields', + 'optionalFields' => 'Optional fields', + 'options' => 'Options', + 'something' => 'Something!', + + // budgets: + 'create_new_budget' => 'Create a new budget', + 'store_new_budget' => 'Store new budget', + 'stored_new_budget' => 'Stored new budget ":name"', + 'availableIn' => 'Available in :date', + 'available_between' => 'Available between :start and :end', + 'transactionsWithoutBudget' => 'Expenses without budget', + 'transactionsWithoutBudgetDate' => 'Expenses without budget in :date', + 'transactions_no_budget' => 'Expenses without budget between :start and :end', + 'spent_between' => 'Spent between :start and :end', + 'createBudget' => 'New budget', + 'inactiveBudgets' => 'Inactive budgets', + 'without_budget_between' => 'Transactions without a budget between :start and :end', + 'budget_in_month' => ':name in :month', + 'delete_budget' => 'Delete budget ":name"', + 'deleted_budget' => 'Deleted budget ":name"', + 'edit_budget' => 'Edit budget ":name"', + 'updated_budget' => 'Updated budget ":name"', + 'update_amount' => 'Update amount', + 'update_budget' => 'Update budget', + 'update_budget_amount_range' => 'Update (expected) available amount between :start and :end', + + // bills: + 'matching_on' => 'Matching on', + 'between_amounts' => 'between :low and :high.', + 'repeats' => 'Repeats', + 'connected_journals' => 'Connected transactions', + 'auto_match_on' => 'Automatically matched by Firefly', + 'auto_match_off' => 'Not automatically matched by Firefly', + 'next_expected_match' => 'Next expected match', + 'delete_bill' => 'Delete bill ":name"', + 'deleted_bill' => 'Deleted bill ":name"', + 'edit_bill' => 'Edit bill ":name"', + 'more' => 'More', + 'rescan_old' => 'Rescan old transactions', + 'update_bill' => 'Update bill', + 'updated_bill' => 'Updated bill ":name"', + 'store_new_bill' => 'Store new bill', + 'stored_new_bill' => 'Stored new bill ":name"', + 'cannot_scan_inactive_bill' => 'Inactive bills cannot be scanned.', + 'rescanned_bill' => 'Rescanned everything.', + 'bill_date_little_relevance' => 'The only part of this date used by Firefly is the day. It is only useful when your bill arrives at exactly the same date every month. If the payment date of your bills varies, simply use the first of the month.', + 'average_bill_amount_year' => 'Average bill amount (:year)', + 'average_bill_amount_overall' => 'Average bill amount (overall)', + + // accounts: + 'details_for_asset' => 'Details for asset account ":name"', + 'details_for_expense' => 'Details for expense account ":name"', + 'details_for_revenue' => 'Details for revenue account ":name"', + 'details_for_cash' => 'Details for cash account ":name"', + 'store_new_asset_account' => 'Store new asset account', + 'store_new_expense_account' => 'Store new expense account', + 'store_new_revenue_account' => 'Store new revenue account', + 'edit_asset_account' => 'Edit asset account ":name"', + 'edit_expense_account' => 'Edit expense account ":name"', + 'edit_revenue_account' => 'Edit revenue account ":name"', + 'delete_asset_account' => 'Delete asset account ":name"', + 'delete_expense_account' => 'Delete expense account ":name"', + 'delete_revenue_account' => 'Delete revenue account ":name"', + 'asset_deleted' => 'Successfully deleted asset account ":name"', + 'expense_deleted' => 'Successfully deleted expense account ":name"', + 'revenue_deleted' => 'Successfully deleted revenue account ":name"', + 'update_asset_account' => 'Update asset account', + 'update_expense_account' => 'Update expense account', + 'update_revenue_account' => 'Update revenue account', + 'make_new_asset_account' => 'Create a new asset account', + 'make_new_expense_account' => 'Create a new expense account', + 'make_new_revenue_account' => 'Create a new revenue account', + 'asset_accounts' => 'Asset accounts', + 'expense_accounts' => 'Expense accounts', + 'revenue_accounts' => 'Revenue accounts', + 'cash_accounts' => 'Cash accounts', + 'Cash account' => 'Cash account', + 'accountExtraHelp_asset' => '', + 'accountExtraHelp_expense' => '', + 'accountExtraHelp_revenue' => '', + 'account_type' => 'Account type', + 'save_transactions_by_moving' => 'Save these transaction(s) by moving them to another account:', + 'stored_new_account' => 'New account ":name" stored!', + 'updated_account' => 'Updated account ":name"', + 'credit_card_options' => 'Credit card options', + + // categories: + 'new_category' => 'New category', + 'create_new_category' => 'Create a new category', + 'without_category' => 'Without a category', + 'update_category' => 'Update category', + 'updated_category' => 'Updated category ":name"', + 'categories' => 'Categories', + 'edit_category' => 'Edit category ":name"', + 'no_category' => '(no category)', + 'category' => 'Category', + 'delete_category' => 'Delete category ":name"', + 'deleted_category' => 'Deleted category ":name"', + 'store_category' => 'Store new category', + 'stored_category' => 'Stored new category ":name"', + 'without_category_between' => 'Without category between :start and :end', + + // transactions: + 'update_withdrawal' => 'Update withdrawal', + 'update_deposit' => 'Update deposit', + 'update_transfer' => 'Update transfer', + 'updated_withdrawal' => 'Updated withdrawal ":description"', + 'updated_deposit' => 'Updated deposit ":description"', + 'updated_transfer' => 'Updated transfer ":description"', + 'delete_withdrawal' => 'Delete withdrawal ":description"', + 'delete_deposit' => 'Delete deposit ":description"', + 'delete_transfer' => 'Delete transfer ":description"', + 'deleted_withdrawal' => 'Successfully deleted withdrawal ":description"', + 'deleted_deposit' => 'Successfully deleted deposit ":description"', + 'deleted_transfer' => 'Successfully deleted transfer ":description"', + 'stored_journal' => 'Successfully created new transaction ":description"', + 'select_transactions' => 'Select transactions', + 'stop_selection' => 'Stop selecting transactions', + 'edit_selected' => 'Edit selected', + 'delete_selected' => 'Delete selected', + 'mass_delete_journals' => 'Delete a number of transactions', + 'mass_edit_journals' => 'Edit a number of transactions', + 'cannot_edit_other_fields' => 'You cannot mass-edit other fields than the ones here, because there is no room to show them. Please follow the link and edit them by one-by-one, if you need to edit these fields.', + 'perm-delete-many' => 'Deleting many items in one go can be very disruptive. Please be cautious.', + 'mass_deleted_transactions_success' => 'Deleted :amount transaction(s).', + 'mass_edited_transactions_success' => 'Updated :amount transaction(s)', + + + // new user: + 'welcome' => 'Welcome to Firefly!', + 'createNewAsset' => 'Create a new asset account to get started. ' . + 'This will allow you to create transactions and start your financial management', + 'createNewAssetButton' => 'Create new asset account', + + // home page: + 'yourAccounts' => 'Your accounts', + 'budgetsAndSpending' => 'Budgets and spending', + 'savings' => 'Savings', + 'markAsSavingsToContinue' => 'Mark your asset accounts as "Savings account" to fill this panel', + 'createPiggyToContinue' => 'Create piggy banks to fill this panel.', + 'newWithdrawal' => 'New expense', + 'newDeposit' => 'New deposit', + 'newTransfer' => 'New transfer', + 'moneyIn' => 'Money in', + 'moneyOut' => 'Money out', + 'billsToPay' => 'Bills to pay', + 'billsPaid' => 'Bills paid', + 'viewDetails' => 'View details', + 'divided' => 'divided', + 'toDivide' => 'left to divide', + + // menu and titles, should be recycled as often as possible: + 'toggleNavigation' => 'Toggle navigation', + 'currency' => 'Currency', + 'preferences' => 'Preferences', + 'logout' => 'Logout', + 'searchPlaceholder' => 'Search...', + 'dashboard' => 'Dashboard', + 'currencies' => 'Currencies', + 'accounts' => 'Accounts', + 'Asset account' => 'Asset account', + 'Default account' => 'Asset account', + 'Expense account' => 'Expense account', + 'Revenue account' => 'Revenue account', + 'Initial balance account' => 'Initial balance account', + 'budgets' => 'Budgets', + 'tags' => 'Tags', + 'reports' => 'Reports', + 'transactions' => 'Transactions', + 'expenses' => 'Expenses', + 'income' => 'Revenue / income', + 'transfers' => 'Transfers', + 'moneyManagement' => 'Money management', + 'piggyBanks' => 'Piggy banks', + 'bills' => 'Bills', + 'createNew' => 'Create new', + 'withdrawal' => 'Withdrawal', + 'deposit' => 'Deposit', + 'account' => 'Account', + 'transfer' => 'Transfer', + 'Withdrawal' => 'Withdrawal', + 'Deposit' => 'Deposit', + 'Transfer' => 'Transfer', + 'bill' => 'Bill', + 'yes' => 'Yes', + 'no' => 'No', + 'amount' => 'Amount', + 'newBalance' => 'New balance', + 'overview' => 'Overview', + 'saveOnAccount' => 'Save on account', + 'unknown' => 'Unknown', + 'daily' => 'Daily', + 'monthly' => 'Monthly', + 'profile' => 'Profile', + 'errors' => 'Errors', + + // reports: + 'report_default' => 'Default financial report for :start until :end', + 'report_audit' => 'Transaction history overview for :start until :end', + 'quick_link_reports' => 'Quick links', + 'quick_link_default_report' => 'Default financial report', + 'quick_link_audit_report' => 'Transaction history overview', + 'report_this_month_quick' => 'Current month, all accounts', + 'report_this_year_quick' => 'Current year, all accounts', + 'report_this_fiscal_year_quick' => 'Current fiscal year, all accounts', + 'report_all_time_quick' => 'All-time, all accounts', + 'reports_can_bookmark' => 'Remember that reports can be bookmarked.', + 'incomeVsExpenses' => 'Income vs. expenses', + 'accountBalances' => 'Account balances', + 'balanceStartOfYear' => 'Balance at start of year', + 'balanceEndOfYear' => 'Balance at end of year', + 'balanceStartOfMonth' => 'Balance at start of month', + 'balanceEndOfMonth' => 'Balance at end of month', + 'balanceStart' => 'Balance at start of period', + 'balanceEnd' => 'Balance at end of period', + 'reportsOwnAccounts' => 'Reports for your own accounts', + 'reportsOwnAccountsAndShared' => 'Reports for your own accounts and shared accounts', + 'splitByAccount' => 'Split by account', + 'balancedByTransfersAndTags' => 'Balanced by transfers and tags', + 'coveredWithTags' => 'Covered with tags', + 'leftUnbalanced' => 'Left unbalanced', + 'expectedBalance' => 'Expected balance', + 'outsideOfBudgets' => 'Outside of budgets', + 'leftInBudget' => 'Left in budget', + 'sumOfSums' => 'Sum of sums', + 'noCategory' => '(no category)', + 'notCharged' => 'Not charged (yet)', + 'inactive' => 'Inactive', + 'active' => 'Active', + 'difference' => 'Difference', + 'in' => 'In', + 'out' => 'Out', + 'topX' => 'top :number', + 'showTheRest' => 'Show everything', + 'hideTheRest' => 'Show only the top :number', + 'sum_of_year' => 'Sum of year', + 'sum_of_years' => 'Sum of years', + 'average_of_year' => 'Average of year', + 'average_of_years' => 'Average of years', + 'categories_earned_in_year' => 'Categories (by earnings)', + 'categories_spent_in_year' => 'Categories (by spendings)', + 'report_type' => 'Report type', + 'report_type_default' => 'Default financial report', + 'report_type_audit' => 'Transaction history overview (audit)', + 'report_type_meta-history' => 'Categories, budgets and bills overview', + 'more_info_help' => 'More information about these types of reports can be found in the help pages. Press the (?) icon in the top right corner.', + 'report_included_accounts' => 'Included accounts', + 'report_date_range' => 'Date range', + 'report_include_help' => 'In all cases, transfers to shared accounts count as expenses, and transfers from shared accounts count as income.', + 'report_preset_ranges' => 'Pre-set ranges', + 'shared' => 'Shared', + 'fiscal_year' => 'Fiscal year', + 'income_entry' => 'Income from account ":name" between :start and :end', + 'expense_entry' => 'Expenses to account ":name" between :start and :end', + 'category_entry' => 'Expenses in category ":name" between :start and :end', + 'budget_spent_amount' => 'Expenses in budget ":budget" between :start and :end', + 'balance_amount' => 'Expenses in budget ":budget" paid from account ":account" between :start and :end', + 'no_audit_activity' => 'No activity was recorded on account :account_name between :start and :end.', + 'audit_end_balance' => 'Account balance of :account_name at the end of :end was: :balance', + + // charts: + 'chart' => 'Chart', + 'dayOfMonth' => 'Day of the month', + 'month' => 'Month', + 'budget' => 'Budget', + 'spent' => 'Spent', + 'earned' => 'Earned', + 'overspent' => 'Overspent', + 'left' => 'Left', + 'no_budget' => '(no budget)', + 'maxAmount' => 'Maximum amount', + 'minAmount' => 'Minumum amount', + 'billEntry' => 'Current bill entry', + 'name' => 'Name', + 'date' => 'Date', + 'paid' => 'Paid', + 'unpaid' => 'Unpaid', + 'day' => 'Day', + 'budgeted' => 'Budgeted', + 'period' => 'Period', + 'balance' => 'Balance', + 'summary' => 'Summary', + 'sum' => 'Sum', + 'average' => 'Average', + 'balanceFor' => 'Balance for :name', + + // piggy banks: + 'add_money_to_piggy' => 'Add money to piggy bank ":name"', + 'piggy_bank' => 'Piggy bank', + 'new_piggy_bank' => 'Create new piggy bank', + 'store_piggy_bank' => 'Store new piggy bank', + 'stored_piggy_bank' => 'Store new piggy bank ":name"', + 'account_status' => 'Account status', + 'left_for_piggy_banks' => 'Left for piggy banks', + 'sum_of_piggy_banks' => 'Sum of piggy banks', + 'saved_so_far' => 'Saved so far', + 'left_to_save' => 'Left to save', + 'add_money_to_piggy_title' => 'Add money to piggy bank ":name"', + 'remove_money_from_piggy_title' => 'Remove money from piggy bank ":name"', + 'add' => 'Add', + 'remove' => 'Remove', + 'max_amount_add' => 'The maximum amount you can add is', + 'max_amount_remove' => 'The maximum amount you can remove is', + 'update_piggy_button' => 'Update piggy bank', + 'update_piggy_title' => 'Update piggy bank ":name"', + 'updated_piggy_bank' => 'Updated piggy bank ":name"', + 'details' => 'Details', + 'events' => 'Events', + 'target_amount' => 'Target amount', + 'start_date' => 'Start date', + 'target_date' => 'Target date', + 'no_target_date' => 'No target date', + 'todo' => 'to do', + 'table' => 'Table', + 'piggy_bank_not_exists' => 'Piggy bank no longer exists.', + 'add_any_amount_to_piggy' => 'Add money to this piggy bank to reach your target of :amount.', + 'add_set_amount_to_piggy' => 'Add :amount to fill this piggy bank on :date', + 'delete_piggy_bank' => 'Delete piggy bank ":name"', + 'cannot_add_amount_piggy' => 'Could not add :amount to ":name".', + 'deleted_piggy_bank' => 'Deleted piggy bank ":name"', + 'added_amount_to_piggy' => 'Added :amount to ":name"', + 'removed_amount_from_piggy' => 'Removed :amount from ":name"', + 'cannot_remove_amount_piggy' => 'Could not remove :amount from ":name".', + + // tags + 'regular_tag' => 'Just a regular tag.', + 'balancing_act' => 'The tag takes at most two transactions; an expense and a transfer. They\'ll balance each other out.', + 'advance_payment' => 'The tag accepts one expense and any number of deposits aimed to repay the original expense.', + 'delete_tag' => 'Delete tag ":tag"', + 'deleted_tag' => 'Deleted tag ":tag"', + 'new_tag' => 'Make new tag', + 'edit_tag' => 'Edit tag ":tag"', + 'updated_tag' => 'Updated tag ":tag"', + 'created_tag' => 'Tag ":tag" has been created!', + 'no_year' => 'No year set', + 'no_month' => 'No month set', + 'tag_title_nothing' => 'Default tags', + 'tag_title_balancingAct' => 'Balancing act tags', + 'tag_title_advancePayment' => 'Advance payment tags', + 'tags_introduction' => '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' => '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.', + 'tags_start' => 'Create a tag to get started or enter tags when creating new transactions.', + + + // administration + 'administration' => 'Administration', + 'user_administration' => 'User administration', + 'list_all_users' => 'All users', + 'all_users' => 'All users', + 'all_blocked_domains' => 'All blocked domains', + 'blocked_domains' => 'Blocked domains', + 'no_domains_banned' => 'No domains blocked', + 'all_user_domains' => 'All user email address domains', + 'all_domains_is_filtered' => 'This list does not include already blocked domains.', + 'domain_now_blocked' => 'Domain :domain is now blocked', + 'domain_now_unblocked' => 'Domain :domain is now unblocked', + 'manual_block_domain' => 'Block a domain by hand', + 'block_domain' => 'Block domain', + 'no_domain_filled_in' => 'No domain filled in', + 'domain_already_blocked' => 'Domain :domain is already blocked', + 'domain_is_now_blocked' => 'Domain :domain is now blocked', + + // split a transaction: + 'transaction_meta_data' => 'Transaction meta-data', + 'transaction_dates' => 'Transaction dates', + 'splits' => 'Splits', + 'split_title_withdrawal' => 'Split your new withdrawal', + 'split_intro_one_withdrawal' => 'Firefly supports the "splitting" of a withdrawal.', + 'split_intro_two_withdrawal' => 'It means that the amount of money you\'ve spent is divided between several destination expense accounts, budgets or categories.', + 'split_intro_three_withdrawal' => 'For example: you could split your :total groceries so you pay :split_one from your "daily groceries" budget and :split_two from your "cigarettes" budget.', + 'split_table_intro_withdrawal' => 'Split your withdrawal in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', + 'store_splitted_withdrawal' => 'Store splitted withdrawal', + 'update_splitted_withdrawal' => 'Update splitted withdrawal', + 'split_title_deposit' => 'Split your new deposit', + 'split_intro_one_deposit' => 'Firefly supports the "splitting" of a deposit.', + 'split_intro_two_deposit' => 'It means that the amount of money you\'ve earned is divided between several source revenue accounts or categories.', + 'split_intro_three_deposit' => 'For example: you could split your :total salary so you get :split_one as your base salary and :split_two as a reimbursment for expenses made.', + 'split_table_intro_deposit' => 'Split your deposit in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', + 'store_splitted_deposit' => 'Store splitted deposit', + 'split_title_transfer' => 'Split your new transfer', + 'split_intro_one_transfer' => 'Firefly supports the "splitting" of a transfer.', + 'split_intro_two_transfer' => 'It means that the amount of money you\'re moving is divided between several categories or piggy banks.', + 'split_intro_three_transfer' => 'For example: you could split your :total move so you get :split_one in one piggy bank and :split_two in another.', + 'split_table_intro_transfer' => 'Split your transfer in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', + 'store_splitted_transfer' => 'Store splitted transfer', + 'add_another_split' => 'Add another split', + 'split-transactions' => 'Split transactions', + 'split-new-transaction' => 'Split a new transaction', + 'do_split' => 'Do a split', + 'split_this_withdrawal' => 'Split this withdrawal', + 'split_this_deposit' => 'Split this deposit', + 'split_this_transfer' => 'Split this transfer', + 'cannot_edit_multiple_source' => 'You cannot edit splitted transaction #:id with description ":description" because it contains multiple source accounts.', + 'cannot_edit_multiple_dest' => 'You cannot edit splitted transaction #:id with description ":description" because it contains multiple destination accounts.', + 'no_edit_multiple_left' => 'You have selected no valid transactions to edit.', + + // import + 'configuration_file_help' => 'If you have previously imported data into Firefly III, you may have a configuration file, which will pre-set configuration values for you.', + 'import_data_index' => 'Index', + 'import_file_type_csv' => 'CSV (comma separated values)', + 'import_file_type_help' => 'Select the type of file you will upload', + 'import_start' => 'Start the import', + 'configure_import' => 'Further configure your import', + 'import_finish_configuration' => 'Finish configuration', + 'settings_for_import' => 'Settings', + 'import_complete' => 'Import configuration complete!', + 'import_complete_text' => 'The import is ready to start. All the configuration you needed to do has been done. Please download the configuration file. It will help you with the import should it not go as planned. To actually run the import, you need to execute the following command in your console. Unfortunately, a web-based import is not yet possible.', + 'import_download_config' => 'Download configuration', + 'import_start_import' => 'Start import', + 'import_intro_beta' => 'The import function of Firefly III is in beta. Many users of Firefly III have tried many different files. Although each individual compontent of this import routine works (really), the combination might break. If your file cannot be imported by Firefly, please read this wiki page so I can fix the problem you have run into.', + 'import_data' => 'Import data', + 'import_data_full' => 'Import data into Firefly III', + 'import' => 'Import', + 'import_intro_text' => 'Welcome to the Firefly III data import routine. At the moment, this routine can help you import files into Firefly. To do so, you must download or export transactions from other systems or software, and upload them here. The next steps will let you help Firefly III determin what the content is of your file, and how to handle it. Please select a file, and read all instructions carefully.', + 'import_file_help' => 'Select your file', +]; diff --git a/resources/lang/zh-HK/form.php b/resources/lang/zh-HK/form.php new file mode 100644 index 0000000000..fa1f42a199 --- /dev/null +++ b/resources/lang/zh-HK/form.php @@ -0,0 +1,149 @@ + 'Bank name', + 'bank_balance' => 'Balance', + 'savings_balance' => 'Savings balance', + 'credit_card_limit' => 'Credit card limit', + 'automatch' => 'Match automatically', + 'skip' => 'Skip', + 'name' => 'Name', + 'active' => 'Active', + 'amount_min' => 'Minimum amount', + 'amount_max' => 'Maximum amount', + 'match' => 'Matches on', + 'repeat_freq' => 'Repeats', + 'journal_currency_id' => 'Currency', + 'journal_amount' => 'Amount', + 'journal_asset_source_account' => 'Asset account (source)', + 'journal_source_account_name' => 'Revenue account (source)', + 'journal_source_account_id' => 'Asset account (source)', + 'account_from_id' => 'From account', + 'account_to_id' => 'To account', + 'journal_destination_account_id' => 'Asset account (destination)', + 'asset_destination_account' => 'Asset account (destination)', + 'asset_source_account' => 'Asset account (source)', + 'journal_description' => 'Description', + 'split_journal' => 'Split this transaction', + 'split_journal_explanation' => 'Split this transaction in multiple parts', + 'currency' => 'Currency', + 'account_id' => 'Asset account', + 'budget_id' => 'Budget', + 'openingBalance' => 'Opening balance', + 'tagMode' => 'Tag mode', + 'tagPosition' => 'Tag location', + 'virtualBalance' => 'Virtual balance', + 'longitude_latitude' => 'Location', + 'targetamount' => 'Target amount', + 'accountRole' => 'Account role', + 'openingBalanceDate' => 'Opening balance date', + 'ccType' => 'Credit card payment plan', + 'ccMonthlyPaymentDate' => 'Credit card monthly payment date', + 'piggy_bank_id' => 'Piggy bank', + 'returnHere' => 'Return here', + 'returnHereExplanation' => 'After storing, return here to create another one.', + 'returnHereUpdateExplanation' => 'After updating, return here.', + 'description' => 'Description', + 'expense_account' => 'Expense account', + 'revenue_account' => 'Revenue account', + 'amount' => 'Amount', + 'date' => 'Date', + 'interest_date' => 'Interest date', + 'book_date' => 'Book date', + 'process_date' => 'Processing date', + 'category' => 'Category', + 'tags' => 'Tags', + 'deletePermanently' => 'Delete permanently', + 'cancel' => 'Cancel', + 'targetdate' => 'Target date', + 'tag' => 'Tag', + 'under' => 'Under', + 'symbol' => 'Symbol', + 'code' => 'Code', + 'iban' => 'IBAN', + 'accountNumber' => 'Account number', + 'has_headers' => 'Headers', + 'date_format' => 'Date format', + 'specifix' => 'Bank- or file specific fixes', + 'attachments[]' => 'Attachments', + 'store_new_withdrawal' => 'Store new withdrawal', + 'store_new_deposit' => 'Store new deposit', + 'store_new_transfer' => 'Store new transfer', + 'add_new_withdrawal' => 'Add a new withdrawal', + 'add_new_deposit' => 'Add a new deposit', + 'add_new_transfer' => 'Add a new transfer', + 'noPiggybank' => '(no piggy bank)', + 'title' => 'Title', + 'notes' => 'Notes', + 'filename' => 'File name', + 'mime' => 'Mime type', + 'size' => 'Size', + 'trigger' => 'Trigger', + 'stop_processing' => 'Stop processing', + 'start_date' => 'Start of range', + 'end_date' => 'End of range', + 'export_start_range' => 'Start of export range', + 'export_end_range' => 'End of export range', + 'export_format' => 'File format', + 'include_attachments' => 'Include uploaded attachments', + 'include_config' => 'Include configuration file', + 'include_old_uploads' => 'Include imported data', + 'accounts' => 'Export transactions from these accounts', + 'delete_account' => 'Delete account ":name"', + 'delete_bill' => 'Delete bill ":name"', + 'delete_budget' => 'Delete budget ":name"', + 'delete_category' => 'Delete category ":name"', + 'delete_currency' => 'Delete currency ":name"', + 'delete_journal' => 'Delete transaction with description ":description"', + 'delete_attachment' => 'Delete attachment ":name"', + 'delete_rule' => 'Delete rule ":title"', + 'delete_rule_group' => 'Delete rule group ":title"', + 'attachment_areYouSure' => 'Are you sure you want to delete the attachment named ":name"?', + 'account_areYouSure' => 'Are you sure you want to delete the account named ":name"?', + 'bill_areYouSure' => 'Are you sure you want to delete the bill named ":name"?', + 'rule_areYouSure' => 'Are you sure you want to delete the rule titled ":title"?', + 'ruleGroup_areYouSure' => 'Are you sure you want to delete the rule group titled ":title"?', + 'budget_areYouSure' => 'Are you sure you want to delete the budget named ":name"?', + 'category_areYouSure' => 'Are you sure you want to delete the category named ":name"?', + 'currency_areYouSure' => 'Are you sure you want to delete the currency named ":name"?', + 'piggyBank_areYouSure' => 'Are you sure you want to delete the piggy bank named ":name"?', + 'journal_areYouSure' => 'Are you sure you want to delete the transaction described ":description"?', + 'mass_journal_are_you_sure' => 'Are you sure you want to delete these transactions?', + 'tag_areYouSure' => 'Are you sure you want to delete the tag ":tag"?', + 'permDeleteWarning' => 'Deleting stuff from Firely is permanent and cannot be undone.', + 'mass_make_selection' => 'You can still prevent items from being deleted by removing the checkbox.', + 'delete_all_permanently' => 'Delete selected permanently', + 'update_all_journals' => 'Update these transactions', + 'also_delete_transactions' => 'The only transaction connected to this account will be deleted as well.|All :count transactions connected to this account will be deleted as well.', + 'also_delete_rules' => 'The only rule connected to this rule group will be deleted as well.|All :count rules connected to this rule group will be deleted as well.', + 'also_delete_piggyBanks' => 'The only piggy bank connected to this account will be deleted as well.|All :count piggy bank connected to this account will be deleted as well.', + 'bill_keep_transactions' => 'The only transaction connected to this bill will not be deleted.|All :count transactions connected to this bill will spared deletion.', + 'budget_keep_transactions' => 'The only transaction connected to this budget will not be deleted.|All :count transactions connected to this budget will spared deletion.', + 'category_keep_transactions' => 'The only transaction connected to this category will not be deleted.|All :count transactions connected to this category will spared deletion.', + 'tag_keep_transactions' => 'The only transaction connected to this tag will not be deleted.|All :count transactions connected to this tag will spared deletion.', + + // admin + 'domain' => 'Domain', + + // import + 'import_file' => 'Import file', + 'configuration_file' => 'Configuration file', + 'import_file_type' => 'Import file type', + 'csv_comma' => 'A comma (,)', + 'csv_semicolon' => 'A semicolon (;)', + 'csv_tab' => 'A tab (invisible)', + 'csv_delimiter' => 'CSV field delimiter', + 'csv_import_account' => 'Default import account', + 'csv_config' => 'CSV import configuration', + + +]; diff --git a/resources/lang/zh-HK/help.php b/resources/lang/zh-HK/help.php new file mode 100644 index 0000000000..d1fa572177 --- /dev/null +++ b/resources/lang/zh-HK/help.php @@ -0,0 +1,85 @@ + 'Welcome to Firefly III', + 'main-content-text' => 'Do yourself a favor and follow this short guide to make sure you know your way around.', + 'sidebar-toggle-title' => 'Sidebar to create stuff', + 'sidebar-toggle-text' => 'Hidden under the plus icon are all the buttons to create new stuff. Accounts, transactions, everything!', + 'account-menu-title' => 'All your accounts', + 'account-menu-text' => 'Here you can find all the accounts you\'ve made.', + 'budget-menu-title' => 'Budgets', + 'budget-menu-text' => 'Use this page to organise your finances and limit spending.', + 'report-menu-title' => 'Reports', + 'report-menu-text' => 'Check this out when you want a solid overview of your finances.', + 'transaction-menu-title' => 'Transactions', + 'transaction-menu-text' => 'All transactions you\'ve created can be found here.', + 'option-menu-title' => 'Options', + 'option-menu-text' => 'This is pretty self-explanatory.', + 'main-content-end-title' => 'The end!', + 'main-content-end-text' => 'Remember that every page has a small question mark at the right top. Click it to get help about the page you\'re on.', + 'index' => 'index', + 'home' => 'home', + 'accounts-index' => 'accounts.index', + 'accounts-create' => 'accounts.create', + 'accounts-edit' => 'accounts.edit', + 'accounts-delete' => 'accounts.delete', + 'accounts-show' => 'accounts.show', + 'attachments-edit' => 'attachments.edit', + 'attachments-delete' => 'attachments.delete', + 'attachments-show' => 'attachments.show', + 'attachments-preview' => 'attachments.preview', + 'bills-index' => 'bills.index', + 'bills-create' => 'bills.create', + 'bills-edit' => 'bills.edit', + 'bills-delete' => 'bills.delete', + 'bills-show' => 'bills.show', + 'budgets-index' => 'budgets.index', + 'budgets-create' => 'budgets.create', + 'budgets-edit' => 'budgets.edit', + 'budgets-delete' => 'budgets.delete', + 'budgets-show' => 'budgets.show', + 'budgets-noBudget' => 'budgets.noBudget', + 'categories-index' => 'categories.index', + 'categories-create' => 'categories.create', + 'categories-edit' => 'categories.edit', + 'categories-delete' => 'categories.delete', + 'categories-show' => 'categories.show', + 'categories-show-date' => 'categories.show.date', + 'categories-noCategory' => 'categories.noCategory', + 'currency-index' => 'currency.index', + 'currency-create' => 'currency.create', + 'currency-edit' => 'currency.edit', + 'currency-delete' => 'currency.delete', + 'new-user-index' => 'new-user.index', + 'piggy-banks-index' => 'piggy-banks.index', + 'piggy-banks-create' => 'piggy-banks.create', + 'piggy-banks-edit' => 'piggy-banks.edit', + 'piggy-banks-delete' => 'piggy-banks.delete', + 'piggy-banks-show' => 'piggy-banks.show', + 'preferences' => 'preferences', + 'profile' => 'profile', + 'profile-change-password' => 'profile.change-password', + 'profile-delete-account' => 'profile.delete-account', + 'reports-index' => 'reports.index', + 'reports-report' => 'reports.report', + 'search' => 'search', + 'tags-index' => 'tags.index', + 'tags-create' => 'tags.create', + 'tags-show' => 'tags.show', + 'tags-edit' => 'tags.edit', + 'tags-delete' => 'tags.delete', + 'transactions-index' => 'transactions.index', + 'transactions-create' => 'transactions.create', + 'transactions-edit' => 'transactions.edit', + 'transactions-delete' => 'transactions.delete', + 'transactions-show' => 'transactions.show', +]; diff --git a/resources/lang/zh-HK/list.php b/resources/lang/zh-HK/list.php new file mode 100644 index 0000000000..193740c717 --- /dev/null +++ b/resources/lang/zh-HK/list.php @@ -0,0 +1,66 @@ + 'Buttons', + 'icon' => 'Icon', + 'create_date' => 'Created at', + 'update_date' => 'Updated at', + 'balance_before' => 'Balance before', + 'balance_after' => 'Balance after', + 'name' => 'Name', + 'role' => 'Role', + 'currentBalance' => 'Current balance', + 'active' => 'Is active?', + 'lastActivity' => 'Last activity', + 'balanceDiff' => 'Balance difference between :start and :end', + 'matchedOn' => 'Matched on', + 'matchesOn' => 'Matched on', + 'account_type' => 'Account type', + 'new_balance' => 'New balance', + 'account' => 'Account', + 'matchingAmount' => 'Amount', + 'lastMatch' => 'Last match', + 'split_number' => 'Split #', + 'destination' => 'Destination', + 'source' => 'Source', + 'expectedMatch' => 'Expected match', + 'automatch' => 'Auto match?', + 'repeat_freq' => 'Repeats', + 'description' => 'Description', + 'amount' => 'Amount', + 'date' => 'Date', + 'interest_date' => 'Interest date', + 'book_date' => 'Book date', + 'process_date' => 'Processing date', + 'from' => 'From', + 'piggy_bank' => 'Piggy bank', + 'to' => 'To', + 'budget' => 'Budget', + 'category' => 'Category', + 'bill' => 'Bill', + 'withdrawal' => 'Withdrawal', + 'deposit' => 'Deposit', + 'transfer' => 'Transfer', + 'type' => 'Type', + 'completed' => 'Completed', + 'iban' => 'IBAN', + 'paid_current_period' => 'Paid this period', + 'email' => 'Email', + 'registered_at' => 'Registered at', + 'is_activated' => 'Is activated', + 'is_blocked' => 'Is blocked', + 'is_admin' => 'Is admin', + 'has_two_factor' => 'Has 2FA', + 'confirmed_from' => 'Confirmed from', + 'registered_from' => 'Registered from', + 'blocked_code' => 'Block code', + 'domain' => 'Domain', + 'registration_attempts' => 'Registration attempts', +]; diff --git a/resources/lang/zh-HK/pagination.php b/resources/lang/zh-HK/pagination.php new file mode 100644 index 0000000000..b1cf416ae8 --- /dev/null +++ b/resources/lang/zh-HK/pagination.php @@ -0,0 +1,13 @@ + '« Previous', + 'next' => 'Next »', +]; diff --git a/resources/lang/zh-HK/passwords.php b/resources/lang/zh-HK/passwords.php new file mode 100644 index 0000000000..6c382f830f --- /dev/null +++ b/resources/lang/zh-HK/passwords.php @@ -0,0 +1,17 @@ + 'Passwords must be at least six characters and match the confirmation.', + 'user' => 'We can\'t find a user with that e-mail address.', + 'token' => 'This password reset token is invalid.', + 'sent' => 'We have e-mailed your password reset link!', + 'reset' => 'Your password has been reset!', + 'blocked' => 'Nice try though.', +]; diff --git a/resources/lang/zh-HK/validation.php b/resources/lang/zh-HK/validation.php new file mode 100644 index 0000000000..fa086c9fbb --- /dev/null +++ b/resources/lang/zh-HK/validation.php @@ -0,0 +1,80 @@ + 'This is not a valid IBAN.', + 'unique_account_number_for_user' => 'It looks like this account number is already in use.', + 'rule_trigger_value' => 'This value is invalid for the selected trigger.', + 'rule_action_value' => 'This value is invalid for the selected action.', + 'invalid_domain' => 'Due to security constraints, you cannot register from this domain.', + 'file_already_attached' => 'Uploaded file ":name" is already attached to this object.', + 'file_attached' => 'Succesfully uploaded file ":name".', + 'file_invalid_mime' => 'File ":name" is of type ":mime" which is not accepted as a new upload.', + 'file_too_large' => 'File ":name" is too large.', + 'belongs_to_user' => 'The value of :attribute is unknown', + 'accepted' => 'The :attribute must be accepted.', + 'active_url' => 'The :attribute is not a valid URL.', + 'after' => 'The :attribute must be a date after :date.', + 'alpha' => 'The :attribute may only contain letters.', + 'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.', + 'alpha_num' => 'The :attribute may only contain letters and numbers.', + 'array' => 'The :attribute must be an array.', + 'unique_for_user' => 'There already is an entry with this :attribute.', + 'before' => 'The :attribute must be a date before :date.', + 'unique_object_for_user' => 'This name is already in use', + 'unique_account_for_user' => 'This account name is already in use', + 'between.numeric' => 'The :attribute must be between :min and :max.', + 'between.file' => 'The :attribute must be between :min and :max kilobytes.', + 'between.string' => 'The :attribute must be between :min and :max characters.', + 'between.array' => 'The :attribute must have between :min and :max items.', + 'boolean' => 'The :attribute field must be true or false.', + 'confirmed' => 'The :attribute confirmation does not match.', + 'date' => 'The :attribute is not a valid date.', + 'date_format' => 'The :attribute does not match the format :format.', + 'different' => 'The :attribute and :other must be different.', + 'digits' => 'The :attribute must be :digits digits.', + 'digits_between' => 'The :attribute must be between :min and :max digits.', + 'email' => 'The :attribute must be a valid email address.', + 'filled' => 'The :attribute field is required.', + 'exists' => 'The selected :attribute is invalid.', + 'image' => 'The :attribute must be an image.', + 'in' => 'The selected :attribute is invalid.', + 'integer' => 'The :attribute must be an integer.', + 'ip' => 'The :attribute must be a valid IP address.', + 'json' => 'The :attribute must be a valid JSON string.', + 'max.numeric' => 'The :attribute may not be greater than :max.', + 'max.file' => 'The :attribute may not be greater than :max kilobytes.', + 'max.string' => 'The :attribute may not be greater than :max characters.', + 'max.array' => 'The :attribute may not have more than :max items.', + 'mimes' => 'The :attribute must be a file of type: :values.', + 'min.numeric' => 'The :attribute must be at least :min.', + 'min.file' => 'The :attribute must be at least :min kilobytes.', + 'min.string' => 'The :attribute must be at least :min characters.', + 'min.array' => 'The :attribute must have at least :min items.', + 'not_in' => 'The selected :attribute is invalid.', + 'numeric' => 'The :attribute must be a number.', + 'regex' => 'The :attribute format is invalid.', + 'required' => 'The :attribute field is required.', + 'required_if' => 'The :attribute field is required when :other is :value.', + 'required_unless' => 'The :attribute field is required unless :other is in :values.', + 'required_with' => 'The :attribute field is required when :values is present.', + 'required_with_all' => 'The :attribute field is required when :values is present.', + 'required_without' => 'The :attribute field is required when :values is not present.', + 'required_without_all' => 'The :attribute field is required when none of :values are present.', + 'same' => 'The :attribute and :other must match.', + 'size.numeric' => 'The :attribute must be :size.', + 'size.file' => 'The :attribute must be :size kilobytes.', + 'size.string' => 'The :attribute must be :size characters.', + 'size.array' => 'The :attribute must contain :size items.', + 'unique' => 'The :attribute has already been taken.', + 'string' => 'The :attribute must be a string.', + 'url' => 'The :attribute format is invalid.', + 'timezone' => 'The :attribute must be a valid zone.', + '2fa_code' => 'The :attribute field is invalid.', +]; diff --git a/resources/lang/zh-TW/breadcrumbs.php b/resources/lang/zh-TW/breadcrumbs.php new file mode 100644 index 0000000000..bdd804cf63 --- /dev/null +++ b/resources/lang/zh-TW/breadcrumbs.php @@ -0,0 +1,46 @@ + 'Home', + 'cash_accounts' => 'Cash accounts', + 'edit_account' => 'Edit account ":name"', + 'edit_currency' => 'Edit currencies ":name"', + 'delete_currency' => 'Delete currencies ":name"', + 'newPiggyBank' => 'Create a new piggy bank', + 'edit_piggyBank' => 'Edit piggy bank ":name"', + 'preferences' => 'Preferences', + 'profile' => 'Profile', + 'changePassword' => 'Change your password', + 'bills' => 'Bills', + 'newBill' => 'New bill', + 'edit_bill' => 'Edit bill ":name"', + 'delete_bill' => 'Delete bill ":name"', + 'reports' => 'Reports', + 'monthly_report' => 'Monthly report for :date', + 'monthly_report_shared' => 'Monthly report for :date (including shared accounts)', + 'yearly_report' => 'Yearly report for :date', + 'yearly_report_shared' => 'Yearly report for :date (including shared accounts)', + 'budget_report' => 'Budget report for :date', + 'searchResult' => 'Search for ":query"', + 'withdrawal_list' => 'Expenses', + 'deposit_list' => 'Revenue, income and deposits', + 'transfer_list' => 'Transfers', + 'transfers_list' => 'Transfers', + 'create_withdrawal' => 'Create new withdrawal', + 'create_deposit' => 'Create new deposit', + 'create_transfer' => 'Create new transfer', + 'edit_journal' => 'Edit transaction ":description"', + 'delete_journal' => 'Delete transaction ":description"', + 'tags' => 'Tags', + 'createTag' => 'Create new tag', + 'edit_tag' => 'Edit tag ":tag"', + 'delete_tag' => 'Delete tag ":tag"', +]; diff --git a/resources/lang/zh-TW/config.php b/resources/lang/zh-TW/config.php new file mode 100644 index 0000000000..b8ed029a46 --- /dev/null +++ b/resources/lang/zh-TW/config.php @@ -0,0 +1,21 @@ + 'en, English, en_US, en_US.utf8', + 'month' => '%B %Y', + 'month_and_day' => '%B %e, %Y', + 'date_time' => '%B %e, %Y, @ %T', + 'specific_day' => '%e %B %Y', + 'week_in_year' => 'Week %W, %Y', + 'quarter_of_year' => '%B %Y', + 'year' => '%Y', + 'half_year' => '%B %Y', + +]; diff --git a/resources/lang/zh-TW/csv.php b/resources/lang/zh-TW/csv.php new file mode 100644 index 0000000000..fef82823e3 --- /dev/null +++ b/resources/lang/zh-TW/csv.php @@ -0,0 +1,80 @@ + 'Configure your import', + 'import_configure_intro' => 'There are some options for your CSV import. Please indicate if your CSV file contains headers on the first column, and what the date format of your date-fields is. That might require some experimentation. The field delimiter is usually a ",", but could also be a ";". Check this carefully.', + 'import_configure_form' => 'Form', + 'header_help' => 'Check this if the first row of your CSV file are the column titles', + 'date_help' => 'Date time format in your CSV. Follow the format like this page indicates. The default value will parse dates that look like this: :dateExample.', + 'delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.', + 'config_file_help' => 'Select your CSV import configuration here. If you do not know what this is, ignore it. It will be explained later.', + 'import_account_help' => 'If your CSV file does NOT contain information about your asset account(s), use this dropdown to select to which account the transactions in the CSV belong to.', + 'upload_not_writeable' => 'The grey box contains a file path. It should be writeable. Please make sure it is.', + + // roles + 'column_roles_title' => 'Define column roles', + 'column_roles_text' => '

Firefly III cannot guess what data each column contains. You must tell Firefly which kinds of data to expect. The example data can guide you into picking the correct type from the dropdown. If a column cannot be matched to a useful data type, please let me know by creating an issue.

Some values in your CSV file, such as account names or categories, may already exist in your Firefly III database. If you select "map these values" Firefly will not attempt to search for matching values itself but allow you to match the CSV values against the values in your database. This allows you to fine-tune the import.

', + 'column_roles_table' => 'Table', + 'column_name' => 'Name of column', + 'column_example' => 'Column example data', + 'column_role' => 'Column data meaning', + 'do_map_value' => 'Map these values', + 'column' => 'Column', + 'no_example_data' => 'No example data available', + 'store_column_roles' => 'Continue import', + 'do_not_map' => '(do not map)', + 'map_title' => 'Connect import data to Firefly III data', + 'map_text' => 'In the following tables, the left value shows you information found in your uploaded CSV file. It is your task to map this value, if possible, to a value already present in your database. Firefly will stick to this mapping. If there is no value to map to, or you do not wish to map the specific value, select nothing.', + + 'field_value' => 'Field value', + 'field_mapped_to' => 'Mapped to', + 'store_column_mapping' => 'Store mapping', + + // map things. + + + 'column__ignore' => '(ignore this column)', + 'column_account-iban' => 'Asset account (IBAN)', + 'column_account-id' => 'Asset account ID (matching Firefly)', + 'column_account-name' => 'Asset account (name)', + 'column_amount' => 'Amount', + 'column_amount-comma-separated' => 'Amount (comma as decimal separator)', + 'column_bill-id' => 'Bill ID (matching Firefly)', + 'column_bill-name' => 'Bill name', + 'column_budget-id' => 'Budget ID (matching Firefly)', + 'column_budget-name' => 'Budget name', + 'column_category-id' => 'Category ID (matching Firefly)', + 'column_category-name' => 'Category name', + 'column_currency-code' => 'Currency code (ISO 4217)', + 'column_currency-id' => 'Currency ID (matching Firefly)', + 'column_currency-name' => 'Currency name (matching Firefly)', + 'column_currency-symbol' => 'Currency symbol (matching Firefly)', + 'column_date-interest' => 'Interest calculation date', + 'column_date-book' => 'Transaction booking date', + 'column_date-process' => 'Transaction process date', + 'column_date-transaction' => 'Date', + 'column_description' => 'Description', + 'column_opposing-iban' => 'Opposing account (IBAN)', + 'column_opposing-id' => 'Opposing account ID (matching Firefly)', + 'column_external-id' => 'External ID', + 'column_opposing-name' => 'Opposing account (name)', + 'column_rabo-debet-credit' => 'Rabobank specific debet/credit indicator', + 'column_ing-debet-credit' => 'ING specific debet/credit indicator', + 'column_sepa-ct-id' => 'SEPA Credit Transfer end-to-end ID', + 'column_sepa-ct-op' => 'SEPA Credit Transfer opposing account', + 'column_sepa-db' => 'SEPA Direct Debet', + 'column_tags-comma' => 'Tags (comma separated)', + 'column_tags-space' => 'Tags (space separated)', + 'column_account-number' => 'Asset account (account number)', + 'column_opposing-number' => 'Opposing account (account number)', +]; diff --git a/resources/lang/zh-TW/firefly.php b/resources/lang/zh-TW/firefly.php new file mode 100644 index 0000000000..08238377e7 --- /dev/null +++ b/resources/lang/zh-TW/firefly.php @@ -0,0 +1,780 @@ + 'This language is not yet fully translated', + 'test' => 'You have selected English.', + 'close' => 'Close', + 'pleaseHold' => 'Please hold...', + 'actions' => 'Actions', + 'edit' => 'Edit', + 'delete' => 'Delete', + 'welcomeBack' => 'What\'s playing?', + 'everything' => 'Everything', + 'customRange' => 'Custom range', + 'apply' => 'Apply', + 'cancel' => 'Cancel', + 'from' => 'From', + 'to' => 'To', + 'total_sum' => 'Total sum', + 'period_sum' => 'Sum for period', + 'showEverything' => 'Show everything', + 'never' => 'Never', + 'search_results_for' => 'Search results for ":query"', + 'bounced_error' => 'The message sent to :email bounced, so no access for you.', + 'deleted_error' => 'These credentials do not match our records.', + 'general_blocked_error' => 'Your account has been disabled, so you cannot login.', + 'expired_error' => 'Your account has expired, and can no longer be used.', + 'unbalanced_error' => 'Your transactions are unbalanced. This means a withdrawal, deposit or transfer was not stored properly. Please check your accounts and transactions for errors (unbalanced amount :amount).', + 'removed_amount' => 'Removed :amount', + 'added_amount' => 'Added :amount', + 'asset_account_role_help' => 'Any extra options resulting from your choice can be set later.', + 'Opening balance' => 'Opening balance', + 'create_new_stuff' => 'Create new stuff', + 'new_withdrawal' => 'New withdrawal', + 'new_deposit' => 'New deposit', + 'new_transfer' => 'New transfer', + 'new_asset_account' => 'New asset account', + 'new_expense_account' => 'New expense account', + 'new_revenue_account' => 'New revenue account', + 'new_budget' => 'New budget', + 'new_bill' => 'New bill', + 'block_account_logout' => 'You have been logged out. Blocked accounts cannot use this site. Did you register with a valid email address?', + 'flash_success' => 'Success!', + 'flash_info' => 'Message', + 'flash_warning' => 'Warning!', + 'flash_error' => 'Error!', + 'flash_info_multiple' => 'There is one message|There are :count messages', + 'flash_error_multiple' => 'There is one error|There are :count errors', + 'net_worth' => 'Net worth', + 'route_has_no_help' => 'There is no help for this route, or there is no help available in your language.', + 'two_factor_welcome' => 'Hello, :user!', + 'two_factor_enter_code' => 'To continue, please enter your two factor authentication code. Your application can generate it for you.', + 'two_factor_code_here' => 'Enter code here', + 'two_factor_title' => 'Two factor authentication', + 'authenticate' => 'Authenticate', + 'two_factor_forgot_title' => 'Lost two factor authentication', + 'two_factor_forgot' => 'I forgot my two-factor thing.', + 'two_factor_lost_header' => 'Lost your two factor authentication?', + 'two_factor_lost_intro' => 'Unfortunately, this is not something you can reset from the web interface. You have two choices.', + 'two_factor_lost_fix_self' => 'If you run your own instance of Firefly III, check the logs in storage/logs for instructions.', + 'two_factor_lost_fix_owner' => 'Otherwise, email the site owner, :site_owner and ask them to reset your two factor authentication.', + 'warning_much_data' => ':days days of data may take a while to load.', + 'registered' => 'You have registered successfully!', + 'search' => 'Search', + 'no_budget_pointer' => 'You seem to have no budgets yet. You should create some on the budgets-page. Budgets can help you keep track of expenses.', + 'source_accounts' => 'Source account(s)', + 'destination_accounts' => 'Destination account(s)', + + // repeat frequencies: + 'repeat_freq_monthly' => 'monthly', + 'weekly' => 'weekly', + 'quarterly' => 'quarterly', + 'half-year' => 'every half year', + 'yearly' => 'yearly', + // account confirmation: + 'confirm_account_header' => 'Please confirm your account', + 'confirm_account_intro' => 'An email has been sent to the address you used during your registration. Please check it out for further instructions. If you did not get this message, you can have Firefly send it again.', + 'confirm_account_resend_email' => 'Send me the confirmation message I need to activate my account.', + 'account_is_confirmed' => 'Your account has been confirmed!', + 'invalid_activation_code' => 'It seems the code you are using is not valid, or has expired.', + 'confirm_account_is_resent_header' => 'The confirmation has been resent', + 'confirm_account_is_resent_text' => 'The confirmation message has been resent. If you still did not receive the confirmation message, please contact the site owner at :owner or check the log files to see what went wrong.', + 'confirm_account_is_resent_go_home' => 'Go to the index page of Firefly', + 'confirm_account_not_resent_header' => 'Something went wrong :(', + 'confirm_account_not_resent_intro' => 'The confirmation message has been not resent. If you still did not receive the confirmation message, please contact the site owner at :owner instead. Possibly, you have tried to resend the activation message too often. You can have Firefly III try to resend the confirmation message every hour.', + 'confirm_account_not_resent_go_home' => 'Go to the index page of Firefly', + + // export data: + 'import_and_export' => 'Import and export', + 'export_data' => 'Export data', + 'export_data_intro' => 'For backup purposes, when migrating to another system or when migrating to another Firefly III installation.', + 'export_format' => 'Export format', + 'export_format_csv' => 'Comma separated values (CSV file)', + 'export_format_mt940' => 'MT940 compatible format', + 'export_included_accounts' => 'Export transactions from these accounts', + 'include_config_help' => 'For easy re-import into Firefly III', + 'include_old_uploads_help' => 'Firefly III does not throw away the original CSV files you have imported in the past. You can include them in your export.', + 'do_export' => 'Export', + 'export_status_never_started' => 'The export has not started yet', + 'export_status_make_exporter' => 'Creating exporter thing...', + 'export_status_collecting_journals' => 'Collecting your transactions...', + 'export_status_collected_journals' => 'Collected your transactions!', + 'export_status_converting_to_export_format' => 'Converting your transactions...', + 'export_status_converted_to_export_format' => 'Converted your transactions!', + 'export_status_creating_journal_file' => 'Creating the export file...', + 'export_status_created_journal_file' => 'Created the export file!', + 'export_status_collecting_attachments' => 'Collecting all your attachments...', + 'export_status_collected_attachments' => 'Collected all your attachments!', + 'export_status_collecting_old_uploads' => 'Collecting all your previous uploads...', + 'export_status_collected_old_uploads' => 'Collected all your previous uploads!', + 'export_status_creating_config_file' => 'Creating a configuration file...', + 'export_status_created_config_file' => 'Created a configuration file!', + 'export_status_creating_zip_file' => 'Creating a zip file...', + 'export_status_created_zip_file' => 'Created a zip file!', + 'export_status_finished' => 'Export has succesfully finished! Yay!', + 'export_data_please_wait' => 'Please wait...', + 'attachment_explanation' => 'The file called \':attachment_name\' (#:attachment_id) was originally uploaded to :type \':description\' (#:journal_id) dated :date for the amount of :amount.', + + // rules + 'rules' => 'Rules', + 'rules_explanation' => 'Here you can manage rules. Rules are triggered when a transaction is created or updated. Then, if the transaction has certain properties (called "triggers") Firefly will execute the "actions". Combined, you can make Firefly respond in a certain way to new transactions.', + 'rule_name' => 'Name of rule', + 'rule_triggers' => 'Rule triggers when', + 'rule_actions' => 'Rule will', + 'new_rule' => 'New rule', + 'new_rule_group' => 'New rule group', + 'rule_priority_up' => 'Give rule more priority', + 'rule_priority_down' => 'Give rule less priority', + 'make_new_rule_group' => 'Make new rule group', + 'store_new_rule_group' => 'Store new rule group', + 'created_new_rule_group' => 'New rule group ":title" stored!', + 'updated_rule_group' => 'Successfully updated rule group ":title".', + 'edit_rule_group' => 'Edit rule group ":title"', + 'delete_rule_group' => 'Delete rule group ":title"', + 'deleted_rule_group' => 'Deleted rule group ":title"', + 'update_rule_group' => 'Update rule group', + 'no_rules_in_group' => 'There are no rules in this group', + 'move_rule_group_up' => 'Move rule group up', + 'move_rule_group_down' => 'Move rule group down', + 'save_rules_by_moving' => 'Save these rule(s) by moving them to another rule group:', + 'make_new_rule' => 'Make new rule in rule group ":title"', + 'rule_help_stop_processing' => 'When you check this box, later rules in this group will not be executed.', + 'rule_help_active' => 'Inactive rules will never fire.', + 'stored_new_rule' => 'Stored new rule with title ":title"', + 'deleted_rule' => 'Deleted rule with title ":title"', + 'store_new_rule' => 'Store new rule', + 'updated_rule' => 'Updated rule with title ":title"', + 'default_rule_group_name' => 'Default rules', + 'default_rule_group_description' => 'All your rules not in a particular group.', + 'default_rule_name' => 'Your first default rule', + 'default_rule_description' => 'This rule is an example. You can safely delete it.', + 'default_rule_trigger_description' => 'The Man Who Sold the World', + 'default_rule_trigger_from_account' => 'David Bowie', + 'default_rule_action_prepend' => 'Bought the world from ', + 'default_rule_action_set_category' => 'Large expenses', + 'trigger' => 'Trigger', + 'trigger_value' => 'Trigger on value', + 'stop_processing_other_triggers' => 'Stop processing other triggers', + 'add_rule_trigger' => 'Add new trigger', + 'action' => 'Action', + 'action_value' => 'Action value', + 'stop_executing_other_actions' => 'Stop executing other actions', + 'add_rule_action' => 'Add new action', + 'edit_rule' => 'Edit rule ":title"', + 'delete_rule' => 'Delete rule ":title"', + 'update_rule' => 'Update rule', + 'test_rule_triggers' => 'See matching transactions', + 'warning_transaction_subset' => 'For performance reasons this list is limited to :max_num_transactions and may only show a subset of matching transactions', + 'warning_no_matching_transactions' => 'No matching transactions found. Please note that for performance reasons, only the last :num_transactions transactions have been checked.', + 'warning_no_valid_triggers' => 'No valid triggers provided.', + 'execute_on_existing_transactions' => 'Execute for existing transactions', + 'execute_on_existing_transactions_intro' => 'When a rule or group has been changed or added, you can execute it for existing transactions', + 'execute_on_existing_transactions_short' => 'Existing transactions', + 'executed_group_on_existing_transactions' => 'Executed group ":title" for existing transactions', + 'execute_group_on_existing_transactions' => 'Execute group ":title" for existing transactions', + 'include_transactions_from_accounts' => 'Include transactions from these accounts', + 'execute' => 'Execute', + + // actions and triggers + 'rule_trigger_user_action' => 'User action is ":trigger_value"', + 'rule_trigger_from_account_starts' => 'Source account starts with ":trigger_value"', + 'rule_trigger_from_account_ends' => 'Source account ends with ":trigger_value"', + 'rule_trigger_from_account_is' => 'Source account is ":trigger_value"', + 'rule_trigger_from_account_contains' => 'Source account contains ":trigger_value"', + 'rule_trigger_to_account_starts' => 'Destination account starts with ":trigger_value"', + 'rule_trigger_to_account_ends' => 'Destination account ends with ":trigger_value"', + 'rule_trigger_to_account_is' => 'Destination account is ":trigger_value"', + 'rule_trigger_to_account_contains' => 'Destination account contains ":trigger_value"', + 'rule_trigger_transaction_type' => 'Transaction is of type ":trigger_value"', + 'rule_trigger_amount_less' => 'Amount is less than :trigger_value', + 'rule_trigger_amount_exactly' => 'Amount is :trigger_value', + 'rule_trigger_amount_more' => 'Amount is more than :trigger_value', + 'rule_trigger_description_starts' => 'Description starts with ":trigger_value"', + 'rule_trigger_description_ends' => 'Description ends with ":trigger_value"', + 'rule_trigger_description_contains' => 'Description contains ":trigger_value"', + 'rule_trigger_description_is' => 'Description is ":trigger_value"', + 'rule_trigger_from_account_starts_choice' => 'Source account starts with..', + 'rule_trigger_from_account_ends_choice' => 'Source account ends with..', + 'rule_trigger_from_account_is_choice' => 'Source account is..', + 'rule_trigger_from_account_contains_choice' => 'Source account contains..', + 'rule_trigger_to_account_starts_choice' => 'Destination account starts with..', + 'rule_trigger_to_account_ends_choice' => 'Destination account ends with..', + 'rule_trigger_to_account_is_choice' => 'Destination account is..', + 'rule_trigger_to_account_contains_choice' => 'Destination account contains..', + 'rule_trigger_transaction_type_choice' => 'Transaction is of type..', + 'rule_trigger_amount_less_choice' => 'Amount is less than..', + 'rule_trigger_amount_exactly_choice' => 'Amount is..', + 'rule_trigger_amount_more_choice' => 'Amount is more than..', + 'rule_trigger_description_starts_choice' => 'Description starts with..', + 'rule_trigger_description_ends_choice' => 'Description ends with..', + 'rule_trigger_description_contains_choice' => 'Description contains..', + 'rule_trigger_description_is_choice' => 'Description is..', + 'rule_trigger_store_journal' => 'When a journal is created', + 'rule_trigger_update_journal' => 'When a journal is updated', + 'rule_action_set_category' => 'Set category to ":action_value"', + 'rule_action_clear_category' => 'Clear category', + 'rule_action_set_budget' => 'Set budget to ":action_value"', + 'rule_action_clear_budget' => 'Clear budget', + 'rule_action_add_tag' => 'Add tag ":action_value"', + 'rule_action_remove_tag' => 'Remove tag ":action_value"', + 'rule_action_remove_all_tags' => 'Remove all tags', + 'rule_action_set_description' => 'Set description to ":action_value"', + 'rule_action_append_description' => 'Append description with ":action_value"', + 'rule_action_prepend_description' => 'Prepend description with ":action_value"', + 'rule_action_set_category_choice' => 'Set category to..', + 'rule_action_clear_category_choice' => 'Clear any category', + 'rule_action_set_budget_choice' => 'Set budget to..', + 'rule_action_clear_budget_choice' => 'Clear any budget', + 'rule_action_add_tag_choice' => 'Add tag..', + 'rule_action_remove_tag_choice' => 'Remove tag..', + 'rule_action_remove_all_tags_choice' => 'Remove all tags', + 'rule_action_set_description_choice' => 'Set description to..', + 'rule_action_append_description_choice' => 'Append description with..', + 'rule_action_prepend_description_choice' => 'Prepend description with..', + + // tags + 'store_new_tag' => 'Store new tag', + 'update_tag' => 'Update tag', + 'no_location_set' => 'No location set.', + 'meta_data' => 'Meta data', + 'location' => 'Location', + + // preferences + 'pref_home_screen_accounts' => 'Home screen accounts', + 'pref_home_screen_accounts_help' => 'Which accounts should be displayed on the home page?', + 'pref_budget_settings' => 'Budget settings', + 'pref_budget_settings_help' => 'What\'s the maximum amount of money a budget envelope may contain?', + 'pref_view_range' => 'View range', + 'pref_view_range_help' => 'Some charts are automatically grouped in periods. What period would you prefer?', + 'pref_1D' => 'One day', + 'pref_1W' => 'One week', + 'pref_1M' => 'One month', + 'pref_3M' => 'Three months (quarter)', + 'pref_6M' => 'Six months', + 'pref_1Y' => 'One year', + 'pref_languages' => 'Languages', + 'pref_languages_help' => 'Firefly III supports several languages. Which one do you prefer?', + 'pref_custom_fiscal_year' => 'Fiscal year settings', + 'pref_custom_fiscal_year_label' => 'Enabled', + 'pref_custom_fiscal_year_help' => 'In countries that use a financial year other than January 1 to December 31, you can switch this on and specify start / end days of the fiscal year', + 'pref_fiscal_year_start_label' => 'Fiscal year start date', + 'pref_two_factor_auth' => '2-step verification', + 'pref_two_factor_auth_help' => 'When you enable 2-step verification (also known as two-factor authentication), you add an extra layer of security to your account. You sign in with something you know (your password) and something you have (a verification code). Verification codes are generated by an application on your phone, such as Authy or Google Authenticator.', + 'pref_enable_two_factor_auth' => 'Enable 2-step verification', + 'pref_two_factor_auth_disabled' => '2-step verification code removed and disabled', + 'pref_two_factor_auth_remove_it' => 'Don\'t forget to remove the account from your authentication app!', + 'pref_two_factor_auth_code' => 'Verify code', + 'pref_two_factor_auth_code_help' => 'Scan the QR code with an application on your phone such as Authy or Google Authenticator and enter the generated code.', + 'pref_two_factor_auth_reset_code' => 'Reset verification code', + 'pref_two_factor_auth_remove_code' => 'Remove verification code', + 'pref_two_factor_auth_remove_will_disable' => '(this will also disable two-factor authentication)', + 'pref_save_settings' => 'Save settings', + 'saved_preferences' => 'Preferences saved!', + 'transaction_page_size_title' => 'Page size', + 'transaction_page_size_help' => 'Any list of transactions shows at most this many transactions', + 'transaction_page_size_label' => 'Page size', + 'budget_maximum' => 'Budget maximum', + 'between_dates' => '(:start and :end)', + + // profile: + 'change_your_password' => 'Change your password', + 'delete_account' => 'Delete account', + 'current_password' => 'Current password', + 'new_password' => 'New password', + 'new_password_again' => 'New password (again)', + 'delete_your_account' => 'Delete your account', + 'delete_your_account_help' => 'Deleting your account will also delete any accounts, transactions, anything you might have saved into Firefly III. It\'ll be GONE.', + 'delete_your_account_password' => 'Enter your password to continue.', + 'password' => 'Password', + 'are_you_sure' => 'Are you sure? You cannot undo this.', + 'delete_account_button' => 'DELETE your account', + 'invalid_current_password' => 'Invalid current password!', + 'password_changed' => 'Password changed!', + 'should_change' => 'The idea is to change your password.', + 'invalid_password' => 'Invalid password!', + + + // attachments + 'nr_of_attachments' => 'One attachment|:count attachments', + 'attachments' => 'Attachments', + 'edit_attachment' => 'Edit attachment ":name"', + 'update_attachment' => 'Update attachment', + 'delete_attachment' => 'Delete attachment ":name"', + 'attachment_deleted' => 'Deleted attachment ":name"', + 'attachment_updated' => 'Updated attachment ":name"', + 'upload_max_file_size' => 'Maximum file size: :size', + + // tour: + 'prev' => 'Prev', + 'next' => 'Next', + 'end-tour' => 'End tour', + 'pause' => 'Pause', + + // transaction index + 'title_expenses' => 'Expenses', + 'title_withdrawal' => 'Expenses', + 'title_revenue' => 'Revenue / income', + 'title_deposit' => 'Revenue / income', + 'title_transfer' => 'Transfers', + 'title_transfers' => 'Transfers', + + // create new stuff: + 'create_new_withdrawal' => 'Create new withdrawal', + 'create_new_deposit' => 'Create new deposit', + 'create_new_transfer' => 'Create new transfer', + 'create_new_asset' => 'Create new asset account', + 'create_new_expense' => 'Create new expense account', + 'create_new_revenue' => 'Create new revenue account', + 'create_new_piggy_bank' => 'Create new piggy bank', + 'create_new_bill' => 'Create new bill', + + // currencies: + 'create_currency' => 'Create a new currency', + 'edit_currency' => 'Edit currency ":name"', + 'store_currency' => 'Store new currency', + 'update_currency' => 'Update currency', + 'new_default_currency' => ':name is now the default currency.', + 'cannot_delete_currency' => 'Cannot delete :name because there are still transactions attached to it!', + 'deleted_currency' => 'Currency :name deleted', + 'created_currency' => 'Currency :name created', + 'updated_currency' => 'Currency :name updated', + 'ask_site_owner' => 'Please ask :owner to add, remove or edit currencies.', + 'currencies_intro' => 'Firefly III supports various currencies which you can set and enable here.', + 'make_default_currency' => 'make default', + 'default_currency' => 'default', + + // new user: + 'submit' => 'Submit', + 'getting_started' => 'Getting started', + 'to_get_started' => 'To get started with Firefly, please enter your current bank\'s name, and the balance of your checking account:', + 'savings_balance_text' => 'If you have a savings account, please enter the current balance of your savings account:', + 'cc_balance_text' => 'If you have a credit card, please enter your credit card\'s limit.', + 'stored_new_account_new_user' => 'Yay! Your new account has been stored.', + 'stored_new_accounts_new_user' => 'Yay! Your new accounts have been stored.', + + // forms: + 'mandatoryFields' => 'Mandatory fields', + 'optionalFields' => 'Optional fields', + 'options' => 'Options', + 'something' => 'Something!', + + // budgets: + 'create_new_budget' => 'Create a new budget', + 'store_new_budget' => 'Store new budget', + 'stored_new_budget' => 'Stored new budget ":name"', + 'availableIn' => 'Available in :date', + 'available_between' => 'Available between :start and :end', + 'transactionsWithoutBudget' => 'Expenses without budget', + 'transactionsWithoutBudgetDate' => 'Expenses without budget in :date', + 'transactions_no_budget' => 'Expenses without budget between :start and :end', + 'spent_between' => 'Spent between :start and :end', + 'createBudget' => 'New budget', + 'inactiveBudgets' => 'Inactive budgets', + 'without_budget_between' => 'Transactions without a budget between :start and :end', + 'budget_in_month' => ':name in :month', + 'delete_budget' => 'Delete budget ":name"', + 'deleted_budget' => 'Deleted budget ":name"', + 'edit_budget' => 'Edit budget ":name"', + 'updated_budget' => 'Updated budget ":name"', + 'update_amount' => 'Update amount', + 'update_budget' => 'Update budget', + 'update_budget_amount_range' => 'Update (expected) available amount between :start and :end', + + // bills: + 'matching_on' => 'Matching on', + 'between_amounts' => 'between :low and :high.', + 'repeats' => 'Repeats', + 'connected_journals' => 'Connected transactions', + 'auto_match_on' => 'Automatically matched by Firefly', + 'auto_match_off' => 'Not automatically matched by Firefly', + 'next_expected_match' => 'Next expected match', + 'delete_bill' => 'Delete bill ":name"', + 'deleted_bill' => 'Deleted bill ":name"', + 'edit_bill' => 'Edit bill ":name"', + 'more' => 'More', + 'rescan_old' => 'Rescan old transactions', + 'update_bill' => 'Update bill', + 'updated_bill' => 'Updated bill ":name"', + 'store_new_bill' => 'Store new bill', + 'stored_new_bill' => 'Stored new bill ":name"', + 'cannot_scan_inactive_bill' => 'Inactive bills cannot be scanned.', + 'rescanned_bill' => 'Rescanned everything.', + 'bill_date_little_relevance' => 'The only part of this date used by Firefly is the day. It is only useful when your bill arrives at exactly the same date every month. If the payment date of your bills varies, simply use the first of the month.', + 'average_bill_amount_year' => 'Average bill amount (:year)', + 'average_bill_amount_overall' => 'Average bill amount (overall)', + + // accounts: + 'details_for_asset' => 'Details for asset account ":name"', + 'details_for_expense' => 'Details for expense account ":name"', + 'details_for_revenue' => 'Details for revenue account ":name"', + 'details_for_cash' => 'Details for cash account ":name"', + 'store_new_asset_account' => 'Store new asset account', + 'store_new_expense_account' => 'Store new expense account', + 'store_new_revenue_account' => 'Store new revenue account', + 'edit_asset_account' => 'Edit asset account ":name"', + 'edit_expense_account' => 'Edit expense account ":name"', + 'edit_revenue_account' => 'Edit revenue account ":name"', + 'delete_asset_account' => 'Delete asset account ":name"', + 'delete_expense_account' => 'Delete expense account ":name"', + 'delete_revenue_account' => 'Delete revenue account ":name"', + 'asset_deleted' => 'Successfully deleted asset account ":name"', + 'expense_deleted' => 'Successfully deleted expense account ":name"', + 'revenue_deleted' => 'Successfully deleted revenue account ":name"', + 'update_asset_account' => 'Update asset account', + 'update_expense_account' => 'Update expense account', + 'update_revenue_account' => 'Update revenue account', + 'make_new_asset_account' => 'Create a new asset account', + 'make_new_expense_account' => 'Create a new expense account', + 'make_new_revenue_account' => 'Create a new revenue account', + 'asset_accounts' => 'Asset accounts', + 'expense_accounts' => 'Expense accounts', + 'revenue_accounts' => 'Revenue accounts', + 'cash_accounts' => 'Cash accounts', + 'Cash account' => 'Cash account', + 'accountExtraHelp_asset' => '', + 'accountExtraHelp_expense' => '', + 'accountExtraHelp_revenue' => '', + 'account_type' => 'Account type', + 'save_transactions_by_moving' => 'Save these transaction(s) by moving them to another account:', + 'stored_new_account' => 'New account ":name" stored!', + 'updated_account' => 'Updated account ":name"', + 'credit_card_options' => 'Credit card options', + + // categories: + 'new_category' => 'New category', + 'create_new_category' => 'Create a new category', + 'without_category' => 'Without a category', + 'update_category' => 'Update category', + 'updated_category' => 'Updated category ":name"', + 'categories' => 'Categories', + 'edit_category' => 'Edit category ":name"', + 'no_category' => '(no category)', + 'category' => 'Category', + 'delete_category' => 'Delete category ":name"', + 'deleted_category' => 'Deleted category ":name"', + 'store_category' => 'Store new category', + 'stored_category' => 'Stored new category ":name"', + 'without_category_between' => 'Without category between :start and :end', + + // transactions: + 'update_withdrawal' => 'Update withdrawal', + 'update_deposit' => 'Update deposit', + 'update_transfer' => 'Update transfer', + 'updated_withdrawal' => 'Updated withdrawal ":description"', + 'updated_deposit' => 'Updated deposit ":description"', + 'updated_transfer' => 'Updated transfer ":description"', + 'delete_withdrawal' => 'Delete withdrawal ":description"', + 'delete_deposit' => 'Delete deposit ":description"', + 'delete_transfer' => 'Delete transfer ":description"', + 'deleted_withdrawal' => 'Successfully deleted withdrawal ":description"', + 'deleted_deposit' => 'Successfully deleted deposit ":description"', + 'deleted_transfer' => 'Successfully deleted transfer ":description"', + 'stored_journal' => 'Successfully created new transaction ":description"', + 'select_transactions' => 'Select transactions', + 'stop_selection' => 'Stop selecting transactions', + 'edit_selected' => 'Edit selected', + 'delete_selected' => 'Delete selected', + 'mass_delete_journals' => 'Delete a number of transactions', + 'mass_edit_journals' => 'Edit a number of transactions', + 'cannot_edit_other_fields' => 'You cannot mass-edit other fields than the ones here, because there is no room to show them. Please follow the link and edit them by one-by-one, if you need to edit these fields.', + 'perm-delete-many' => 'Deleting many items in one go can be very disruptive. Please be cautious.', + 'mass_deleted_transactions_success' => 'Deleted :amount transaction(s).', + 'mass_edited_transactions_success' => 'Updated :amount transaction(s)', + + + // new user: + 'welcome' => 'Welcome to Firefly!', + 'createNewAsset' => 'Create a new asset account to get started. ' . + 'This will allow you to create transactions and start your financial management', + 'createNewAssetButton' => 'Create new asset account', + + // home page: + 'yourAccounts' => 'Your accounts', + 'budgetsAndSpending' => 'Budgets and spending', + 'savings' => 'Savings', + 'markAsSavingsToContinue' => 'Mark your asset accounts as "Savings account" to fill this panel', + 'createPiggyToContinue' => 'Create piggy banks to fill this panel.', + 'newWithdrawal' => 'New expense', + 'newDeposit' => 'New deposit', + 'newTransfer' => 'New transfer', + 'moneyIn' => 'Money in', + 'moneyOut' => 'Money out', + 'billsToPay' => 'Bills to pay', + 'billsPaid' => 'Bills paid', + 'viewDetails' => 'View details', + 'divided' => 'divided', + 'toDivide' => 'left to divide', + + // menu and titles, should be recycled as often as possible: + 'toggleNavigation' => 'Toggle navigation', + 'currency' => 'Currency', + 'preferences' => 'Preferences', + 'logout' => 'Logout', + 'searchPlaceholder' => 'Search...', + 'dashboard' => 'Dashboard', + 'currencies' => 'Currencies', + 'accounts' => 'Accounts', + 'Asset account' => 'Asset account', + 'Default account' => 'Asset account', + 'Expense account' => 'Expense account', + 'Revenue account' => 'Revenue account', + 'Initial balance account' => 'Initial balance account', + 'budgets' => 'Budgets', + 'tags' => 'Tags', + 'reports' => 'Reports', + 'transactions' => 'Transactions', + 'expenses' => 'Expenses', + 'income' => 'Revenue / income', + 'transfers' => 'Transfers', + 'moneyManagement' => 'Money management', + 'piggyBanks' => 'Piggy banks', + 'bills' => 'Bills', + 'createNew' => 'Create new', + 'withdrawal' => 'Withdrawal', + 'deposit' => 'Deposit', + 'account' => 'Account', + 'transfer' => 'Transfer', + 'Withdrawal' => 'Withdrawal', + 'Deposit' => 'Deposit', + 'Transfer' => 'Transfer', + 'bill' => 'Bill', + 'yes' => 'Yes', + 'no' => 'No', + 'amount' => 'Amount', + 'newBalance' => 'New balance', + 'overview' => 'Overview', + 'saveOnAccount' => 'Save on account', + 'unknown' => 'Unknown', + 'daily' => 'Daily', + 'monthly' => 'Monthly', + 'profile' => 'Profile', + 'errors' => 'Errors', + + // reports: + 'report_default' => 'Default financial report for :start until :end', + 'report_audit' => 'Transaction history overview for :start until :end', + 'quick_link_reports' => 'Quick links', + 'quick_link_default_report' => 'Default financial report', + 'quick_link_audit_report' => 'Transaction history overview', + 'report_this_month_quick' => 'Current month, all accounts', + 'report_this_year_quick' => 'Current year, all accounts', + 'report_this_fiscal_year_quick' => 'Current fiscal year, all accounts', + 'report_all_time_quick' => 'All-time, all accounts', + 'reports_can_bookmark' => 'Remember that reports can be bookmarked.', + 'incomeVsExpenses' => 'Income vs. expenses', + 'accountBalances' => 'Account balances', + 'balanceStartOfYear' => 'Balance at start of year', + 'balanceEndOfYear' => 'Balance at end of year', + 'balanceStartOfMonth' => 'Balance at start of month', + 'balanceEndOfMonth' => 'Balance at end of month', + 'balanceStart' => 'Balance at start of period', + 'balanceEnd' => 'Balance at end of period', + 'reportsOwnAccounts' => 'Reports for your own accounts', + 'reportsOwnAccountsAndShared' => 'Reports for your own accounts and shared accounts', + 'splitByAccount' => 'Split by account', + 'balancedByTransfersAndTags' => 'Balanced by transfers and tags', + 'coveredWithTags' => 'Covered with tags', + 'leftUnbalanced' => 'Left unbalanced', + 'expectedBalance' => 'Expected balance', + 'outsideOfBudgets' => 'Outside of budgets', + 'leftInBudget' => 'Left in budget', + 'sumOfSums' => 'Sum of sums', + 'noCategory' => '(no category)', + 'notCharged' => 'Not charged (yet)', + 'inactive' => 'Inactive', + 'active' => 'Active', + 'difference' => 'Difference', + 'in' => 'In', + 'out' => 'Out', + 'topX' => 'top :number', + 'showTheRest' => 'Show everything', + 'hideTheRest' => 'Show only the top :number', + 'sum_of_year' => 'Sum of year', + 'sum_of_years' => 'Sum of years', + 'average_of_year' => 'Average of year', + 'average_of_years' => 'Average of years', + 'categories_earned_in_year' => 'Categories (by earnings)', + 'categories_spent_in_year' => 'Categories (by spendings)', + 'report_type' => 'Report type', + 'report_type_default' => 'Default financial report', + 'report_type_audit' => 'Transaction history overview (audit)', + 'report_type_meta-history' => 'Categories, budgets and bills overview', + 'more_info_help' => 'More information about these types of reports can be found in the help pages. Press the (?) icon in the top right corner.', + 'report_included_accounts' => 'Included accounts', + 'report_date_range' => 'Date range', + 'report_include_help' => 'In all cases, transfers to shared accounts count as expenses, and transfers from shared accounts count as income.', + 'report_preset_ranges' => 'Pre-set ranges', + 'shared' => 'Shared', + 'fiscal_year' => 'Fiscal year', + 'income_entry' => 'Income from account ":name" between :start and :end', + 'expense_entry' => 'Expenses to account ":name" between :start and :end', + 'category_entry' => 'Expenses in category ":name" between :start and :end', + 'budget_spent_amount' => 'Expenses in budget ":budget" between :start and :end', + 'balance_amount' => 'Expenses in budget ":budget" paid from account ":account" between :start and :end', + 'no_audit_activity' => 'No activity was recorded on account :account_name between :start and :end.', + 'audit_end_balance' => 'Account balance of :account_name at the end of :end was: :balance', + + // charts: + 'chart' => 'Chart', + 'dayOfMonth' => 'Day of the month', + 'month' => 'Month', + 'budget' => 'Budget', + 'spent' => 'Spent', + 'earned' => 'Earned', + 'overspent' => 'Overspent', + 'left' => 'Left', + 'no_budget' => '(no budget)', + 'maxAmount' => 'Maximum amount', + 'minAmount' => 'Minumum amount', + 'billEntry' => 'Current bill entry', + 'name' => 'Name', + 'date' => 'Date', + 'paid' => 'Paid', + 'unpaid' => 'Unpaid', + 'day' => 'Day', + 'budgeted' => 'Budgeted', + 'period' => 'Period', + 'balance' => 'Balance', + 'summary' => 'Summary', + 'sum' => 'Sum', + 'average' => 'Average', + 'balanceFor' => 'Balance for :name', + + // piggy banks: + 'add_money_to_piggy' => 'Add money to piggy bank ":name"', + 'piggy_bank' => 'Piggy bank', + 'new_piggy_bank' => 'Create new piggy bank', + 'store_piggy_bank' => 'Store new piggy bank', + 'stored_piggy_bank' => 'Store new piggy bank ":name"', + 'account_status' => 'Account status', + 'left_for_piggy_banks' => 'Left for piggy banks', + 'sum_of_piggy_banks' => 'Sum of piggy banks', + 'saved_so_far' => 'Saved so far', + 'left_to_save' => 'Left to save', + 'add_money_to_piggy_title' => 'Add money to piggy bank ":name"', + 'remove_money_from_piggy_title' => 'Remove money from piggy bank ":name"', + 'add' => 'Add', + 'remove' => 'Remove', + 'max_amount_add' => 'The maximum amount you can add is', + 'max_amount_remove' => 'The maximum amount you can remove is', + 'update_piggy_button' => 'Update piggy bank', + 'update_piggy_title' => 'Update piggy bank ":name"', + 'updated_piggy_bank' => 'Updated piggy bank ":name"', + 'details' => 'Details', + 'events' => 'Events', + 'target_amount' => 'Target amount', + 'start_date' => 'Start date', + 'target_date' => 'Target date', + 'no_target_date' => 'No target date', + 'todo' => 'to do', + 'table' => 'Table', + 'piggy_bank_not_exists' => 'Piggy bank no longer exists.', + 'add_any_amount_to_piggy' => 'Add money to this piggy bank to reach your target of :amount.', + 'add_set_amount_to_piggy' => 'Add :amount to fill this piggy bank on :date', + 'delete_piggy_bank' => 'Delete piggy bank ":name"', + 'cannot_add_amount_piggy' => 'Could not add :amount to ":name".', + 'deleted_piggy_bank' => 'Deleted piggy bank ":name"', + 'added_amount_to_piggy' => 'Added :amount to ":name"', + 'removed_amount_from_piggy' => 'Removed :amount from ":name"', + 'cannot_remove_amount_piggy' => 'Could not remove :amount from ":name".', + + // tags + 'regular_tag' => 'Just a regular tag.', + 'balancing_act' => 'The tag takes at most two transactions; an expense and a transfer. They\'ll balance each other out.', + 'advance_payment' => 'The tag accepts one expense and any number of deposits aimed to repay the original expense.', + 'delete_tag' => 'Delete tag ":tag"', + 'deleted_tag' => 'Deleted tag ":tag"', + 'new_tag' => 'Make new tag', + 'edit_tag' => 'Edit tag ":tag"', + 'updated_tag' => 'Updated tag ":tag"', + 'created_tag' => 'Tag ":tag" has been created!', + 'no_year' => 'No year set', + 'no_month' => 'No month set', + 'tag_title_nothing' => 'Default tags', + 'tag_title_balancingAct' => 'Balancing act tags', + 'tag_title_advancePayment' => 'Advance payment tags', + 'tags_introduction' => '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' => '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.', + 'tags_start' => 'Create a tag to get started or enter tags when creating new transactions.', + + + // administration + 'administration' => 'Administration', + 'user_administration' => 'User administration', + 'list_all_users' => 'All users', + 'all_users' => 'All users', + 'all_blocked_domains' => 'All blocked domains', + 'blocked_domains' => 'Blocked domains', + 'no_domains_banned' => 'No domains blocked', + 'all_user_domains' => 'All user email address domains', + 'all_domains_is_filtered' => 'This list does not include already blocked domains.', + 'domain_now_blocked' => 'Domain :domain is now blocked', + 'domain_now_unblocked' => 'Domain :domain is now unblocked', + 'manual_block_domain' => 'Block a domain by hand', + 'block_domain' => 'Block domain', + 'no_domain_filled_in' => 'No domain filled in', + 'domain_already_blocked' => 'Domain :domain is already blocked', + 'domain_is_now_blocked' => 'Domain :domain is now blocked', + + // split a transaction: + 'transaction_meta_data' => 'Transaction meta-data', + 'transaction_dates' => 'Transaction dates', + 'splits' => 'Splits', + 'split_title_withdrawal' => 'Split your new withdrawal', + 'split_intro_one_withdrawal' => 'Firefly supports the "splitting" of a withdrawal.', + 'split_intro_two_withdrawal' => 'It means that the amount of money you\'ve spent is divided between several destination expense accounts, budgets or categories.', + 'split_intro_three_withdrawal' => 'For example: you could split your :total groceries so you pay :split_one from your "daily groceries" budget and :split_two from your "cigarettes" budget.', + 'split_table_intro_withdrawal' => 'Split your withdrawal in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', + 'store_splitted_withdrawal' => 'Store splitted withdrawal', + 'update_splitted_withdrawal' => 'Update splitted withdrawal', + 'split_title_deposit' => 'Split your new deposit', + 'split_intro_one_deposit' => 'Firefly supports the "splitting" of a deposit.', + 'split_intro_two_deposit' => 'It means that the amount of money you\'ve earned is divided between several source revenue accounts or categories.', + 'split_intro_three_deposit' => 'For example: you could split your :total salary so you get :split_one as your base salary and :split_two as a reimbursment for expenses made.', + 'split_table_intro_deposit' => 'Split your deposit in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', + 'store_splitted_deposit' => 'Store splitted deposit', + 'split_title_transfer' => 'Split your new transfer', + 'split_intro_one_transfer' => 'Firefly supports the "splitting" of a transfer.', + 'split_intro_two_transfer' => 'It means that the amount of money you\'re moving is divided between several categories or piggy banks.', + 'split_intro_three_transfer' => 'For example: you could split your :total move so you get :split_one in one piggy bank and :split_two in another.', + 'split_table_intro_transfer' => 'Split your transfer in as many things as you want. By default the transaction will not split, there is just one entry. Add as many splits as you want to, below. Remember that you should not deviate from your total amount. If you do, Firefly will warn you but not correct you.', + 'store_splitted_transfer' => 'Store splitted transfer', + 'add_another_split' => 'Add another split', + 'split-transactions' => 'Split transactions', + 'split-new-transaction' => 'Split a new transaction', + 'do_split' => 'Do a split', + 'split_this_withdrawal' => 'Split this withdrawal', + 'split_this_deposit' => 'Split this deposit', + 'split_this_transfer' => 'Split this transfer', + 'cannot_edit_multiple_source' => 'You cannot edit splitted transaction #:id with description ":description" because it contains multiple source accounts.', + 'cannot_edit_multiple_dest' => 'You cannot edit splitted transaction #:id with description ":description" because it contains multiple destination accounts.', + 'no_edit_multiple_left' => 'You have selected no valid transactions to edit.', + + // import + 'configuration_file_help' => 'If you have previously imported data into Firefly III, you may have a configuration file, which will pre-set configuration values for you.', + 'import_data_index' => 'Index', + 'import_file_type_csv' => 'CSV (comma separated values)', + 'import_file_type_help' => 'Select the type of file you will upload', + 'import_start' => 'Start the import', + 'configure_import' => 'Further configure your import', + 'import_finish_configuration' => 'Finish configuration', + 'settings_for_import' => 'Settings', + 'import_complete' => 'Import configuration complete!', + 'import_complete_text' => 'The import is ready to start. All the configuration you needed to do has been done. Please download the configuration file. It will help you with the import should it not go as planned. To actually run the import, you need to execute the following command in your console. Unfortunately, a web-based import is not yet possible.', + 'import_download_config' => 'Download configuration', + 'import_start_import' => 'Start import', + 'import_intro_beta' => 'The import function of Firefly III is in beta. Many users of Firefly III have tried many different files. Although each individual compontent of this import routine works (really), the combination might break. If your file cannot be imported by Firefly, please read this wiki page so I can fix the problem you have run into.', + 'import_data' => 'Import data', + 'import_data_full' => 'Import data into Firefly III', + 'import' => 'Import', + 'import_intro_text' => 'Welcome to the Firefly III data import routine. At the moment, this routine can help you import files into Firefly. To do so, you must download or export transactions from other systems or software, and upload them here. The next steps will let you help Firefly III determin what the content is of your file, and how to handle it. Please select a file, and read all instructions carefully.', + 'import_file_help' => 'Select your file', +]; diff --git a/resources/lang/zh-TW/form.php b/resources/lang/zh-TW/form.php new file mode 100644 index 0000000000..fa1f42a199 --- /dev/null +++ b/resources/lang/zh-TW/form.php @@ -0,0 +1,149 @@ + 'Bank name', + 'bank_balance' => 'Balance', + 'savings_balance' => 'Savings balance', + 'credit_card_limit' => 'Credit card limit', + 'automatch' => 'Match automatically', + 'skip' => 'Skip', + 'name' => 'Name', + 'active' => 'Active', + 'amount_min' => 'Minimum amount', + 'amount_max' => 'Maximum amount', + 'match' => 'Matches on', + 'repeat_freq' => 'Repeats', + 'journal_currency_id' => 'Currency', + 'journal_amount' => 'Amount', + 'journal_asset_source_account' => 'Asset account (source)', + 'journal_source_account_name' => 'Revenue account (source)', + 'journal_source_account_id' => 'Asset account (source)', + 'account_from_id' => 'From account', + 'account_to_id' => 'To account', + 'journal_destination_account_id' => 'Asset account (destination)', + 'asset_destination_account' => 'Asset account (destination)', + 'asset_source_account' => 'Asset account (source)', + 'journal_description' => 'Description', + 'split_journal' => 'Split this transaction', + 'split_journal_explanation' => 'Split this transaction in multiple parts', + 'currency' => 'Currency', + 'account_id' => 'Asset account', + 'budget_id' => 'Budget', + 'openingBalance' => 'Opening balance', + 'tagMode' => 'Tag mode', + 'tagPosition' => 'Tag location', + 'virtualBalance' => 'Virtual balance', + 'longitude_latitude' => 'Location', + 'targetamount' => 'Target amount', + 'accountRole' => 'Account role', + 'openingBalanceDate' => 'Opening balance date', + 'ccType' => 'Credit card payment plan', + 'ccMonthlyPaymentDate' => 'Credit card monthly payment date', + 'piggy_bank_id' => 'Piggy bank', + 'returnHere' => 'Return here', + 'returnHereExplanation' => 'After storing, return here to create another one.', + 'returnHereUpdateExplanation' => 'After updating, return here.', + 'description' => 'Description', + 'expense_account' => 'Expense account', + 'revenue_account' => 'Revenue account', + 'amount' => 'Amount', + 'date' => 'Date', + 'interest_date' => 'Interest date', + 'book_date' => 'Book date', + 'process_date' => 'Processing date', + 'category' => 'Category', + 'tags' => 'Tags', + 'deletePermanently' => 'Delete permanently', + 'cancel' => 'Cancel', + 'targetdate' => 'Target date', + 'tag' => 'Tag', + 'under' => 'Under', + 'symbol' => 'Symbol', + 'code' => 'Code', + 'iban' => 'IBAN', + 'accountNumber' => 'Account number', + 'has_headers' => 'Headers', + 'date_format' => 'Date format', + 'specifix' => 'Bank- or file specific fixes', + 'attachments[]' => 'Attachments', + 'store_new_withdrawal' => 'Store new withdrawal', + 'store_new_deposit' => 'Store new deposit', + 'store_new_transfer' => 'Store new transfer', + 'add_new_withdrawal' => 'Add a new withdrawal', + 'add_new_deposit' => 'Add a new deposit', + 'add_new_transfer' => 'Add a new transfer', + 'noPiggybank' => '(no piggy bank)', + 'title' => 'Title', + 'notes' => 'Notes', + 'filename' => 'File name', + 'mime' => 'Mime type', + 'size' => 'Size', + 'trigger' => 'Trigger', + 'stop_processing' => 'Stop processing', + 'start_date' => 'Start of range', + 'end_date' => 'End of range', + 'export_start_range' => 'Start of export range', + 'export_end_range' => 'End of export range', + 'export_format' => 'File format', + 'include_attachments' => 'Include uploaded attachments', + 'include_config' => 'Include configuration file', + 'include_old_uploads' => 'Include imported data', + 'accounts' => 'Export transactions from these accounts', + 'delete_account' => 'Delete account ":name"', + 'delete_bill' => 'Delete bill ":name"', + 'delete_budget' => 'Delete budget ":name"', + 'delete_category' => 'Delete category ":name"', + 'delete_currency' => 'Delete currency ":name"', + 'delete_journal' => 'Delete transaction with description ":description"', + 'delete_attachment' => 'Delete attachment ":name"', + 'delete_rule' => 'Delete rule ":title"', + 'delete_rule_group' => 'Delete rule group ":title"', + 'attachment_areYouSure' => 'Are you sure you want to delete the attachment named ":name"?', + 'account_areYouSure' => 'Are you sure you want to delete the account named ":name"?', + 'bill_areYouSure' => 'Are you sure you want to delete the bill named ":name"?', + 'rule_areYouSure' => 'Are you sure you want to delete the rule titled ":title"?', + 'ruleGroup_areYouSure' => 'Are you sure you want to delete the rule group titled ":title"?', + 'budget_areYouSure' => 'Are you sure you want to delete the budget named ":name"?', + 'category_areYouSure' => 'Are you sure you want to delete the category named ":name"?', + 'currency_areYouSure' => 'Are you sure you want to delete the currency named ":name"?', + 'piggyBank_areYouSure' => 'Are you sure you want to delete the piggy bank named ":name"?', + 'journal_areYouSure' => 'Are you sure you want to delete the transaction described ":description"?', + 'mass_journal_are_you_sure' => 'Are you sure you want to delete these transactions?', + 'tag_areYouSure' => 'Are you sure you want to delete the tag ":tag"?', + 'permDeleteWarning' => 'Deleting stuff from Firely is permanent and cannot be undone.', + 'mass_make_selection' => 'You can still prevent items from being deleted by removing the checkbox.', + 'delete_all_permanently' => 'Delete selected permanently', + 'update_all_journals' => 'Update these transactions', + 'also_delete_transactions' => 'The only transaction connected to this account will be deleted as well.|All :count transactions connected to this account will be deleted as well.', + 'also_delete_rules' => 'The only rule connected to this rule group will be deleted as well.|All :count rules connected to this rule group will be deleted as well.', + 'also_delete_piggyBanks' => 'The only piggy bank connected to this account will be deleted as well.|All :count piggy bank connected to this account will be deleted as well.', + 'bill_keep_transactions' => 'The only transaction connected to this bill will not be deleted.|All :count transactions connected to this bill will spared deletion.', + 'budget_keep_transactions' => 'The only transaction connected to this budget will not be deleted.|All :count transactions connected to this budget will spared deletion.', + 'category_keep_transactions' => 'The only transaction connected to this category will not be deleted.|All :count transactions connected to this category will spared deletion.', + 'tag_keep_transactions' => 'The only transaction connected to this tag will not be deleted.|All :count transactions connected to this tag will spared deletion.', + + // admin + 'domain' => 'Domain', + + // import + 'import_file' => 'Import file', + 'configuration_file' => 'Configuration file', + 'import_file_type' => 'Import file type', + 'csv_comma' => 'A comma (,)', + 'csv_semicolon' => 'A semicolon (;)', + 'csv_tab' => 'A tab (invisible)', + 'csv_delimiter' => 'CSV field delimiter', + 'csv_import_account' => 'Default import account', + 'csv_config' => 'CSV import configuration', + + +]; diff --git a/resources/lang/zh-TW/help.php b/resources/lang/zh-TW/help.php new file mode 100644 index 0000000000..d1fa572177 --- /dev/null +++ b/resources/lang/zh-TW/help.php @@ -0,0 +1,85 @@ + 'Welcome to Firefly III', + 'main-content-text' => 'Do yourself a favor and follow this short guide to make sure you know your way around.', + 'sidebar-toggle-title' => 'Sidebar to create stuff', + 'sidebar-toggle-text' => 'Hidden under the plus icon are all the buttons to create new stuff. Accounts, transactions, everything!', + 'account-menu-title' => 'All your accounts', + 'account-menu-text' => 'Here you can find all the accounts you\'ve made.', + 'budget-menu-title' => 'Budgets', + 'budget-menu-text' => 'Use this page to organise your finances and limit spending.', + 'report-menu-title' => 'Reports', + 'report-menu-text' => 'Check this out when you want a solid overview of your finances.', + 'transaction-menu-title' => 'Transactions', + 'transaction-menu-text' => 'All transactions you\'ve created can be found here.', + 'option-menu-title' => 'Options', + 'option-menu-text' => 'This is pretty self-explanatory.', + 'main-content-end-title' => 'The end!', + 'main-content-end-text' => 'Remember that every page has a small question mark at the right top. Click it to get help about the page you\'re on.', + 'index' => 'index', + 'home' => 'home', + 'accounts-index' => 'accounts.index', + 'accounts-create' => 'accounts.create', + 'accounts-edit' => 'accounts.edit', + 'accounts-delete' => 'accounts.delete', + 'accounts-show' => 'accounts.show', + 'attachments-edit' => 'attachments.edit', + 'attachments-delete' => 'attachments.delete', + 'attachments-show' => 'attachments.show', + 'attachments-preview' => 'attachments.preview', + 'bills-index' => 'bills.index', + 'bills-create' => 'bills.create', + 'bills-edit' => 'bills.edit', + 'bills-delete' => 'bills.delete', + 'bills-show' => 'bills.show', + 'budgets-index' => 'budgets.index', + 'budgets-create' => 'budgets.create', + 'budgets-edit' => 'budgets.edit', + 'budgets-delete' => 'budgets.delete', + 'budgets-show' => 'budgets.show', + 'budgets-noBudget' => 'budgets.noBudget', + 'categories-index' => 'categories.index', + 'categories-create' => 'categories.create', + 'categories-edit' => 'categories.edit', + 'categories-delete' => 'categories.delete', + 'categories-show' => 'categories.show', + 'categories-show-date' => 'categories.show.date', + 'categories-noCategory' => 'categories.noCategory', + 'currency-index' => 'currency.index', + 'currency-create' => 'currency.create', + 'currency-edit' => 'currency.edit', + 'currency-delete' => 'currency.delete', + 'new-user-index' => 'new-user.index', + 'piggy-banks-index' => 'piggy-banks.index', + 'piggy-banks-create' => 'piggy-banks.create', + 'piggy-banks-edit' => 'piggy-banks.edit', + 'piggy-banks-delete' => 'piggy-banks.delete', + 'piggy-banks-show' => 'piggy-banks.show', + 'preferences' => 'preferences', + 'profile' => 'profile', + 'profile-change-password' => 'profile.change-password', + 'profile-delete-account' => 'profile.delete-account', + 'reports-index' => 'reports.index', + 'reports-report' => 'reports.report', + 'search' => 'search', + 'tags-index' => 'tags.index', + 'tags-create' => 'tags.create', + 'tags-show' => 'tags.show', + 'tags-edit' => 'tags.edit', + 'tags-delete' => 'tags.delete', + 'transactions-index' => 'transactions.index', + 'transactions-create' => 'transactions.create', + 'transactions-edit' => 'transactions.edit', + 'transactions-delete' => 'transactions.delete', + 'transactions-show' => 'transactions.show', +]; diff --git a/resources/lang/zh-TW/list.php b/resources/lang/zh-TW/list.php new file mode 100644 index 0000000000..193740c717 --- /dev/null +++ b/resources/lang/zh-TW/list.php @@ -0,0 +1,66 @@ + 'Buttons', + 'icon' => 'Icon', + 'create_date' => 'Created at', + 'update_date' => 'Updated at', + 'balance_before' => 'Balance before', + 'balance_after' => 'Balance after', + 'name' => 'Name', + 'role' => 'Role', + 'currentBalance' => 'Current balance', + 'active' => 'Is active?', + 'lastActivity' => 'Last activity', + 'balanceDiff' => 'Balance difference between :start and :end', + 'matchedOn' => 'Matched on', + 'matchesOn' => 'Matched on', + 'account_type' => 'Account type', + 'new_balance' => 'New balance', + 'account' => 'Account', + 'matchingAmount' => 'Amount', + 'lastMatch' => 'Last match', + 'split_number' => 'Split #', + 'destination' => 'Destination', + 'source' => 'Source', + 'expectedMatch' => 'Expected match', + 'automatch' => 'Auto match?', + 'repeat_freq' => 'Repeats', + 'description' => 'Description', + 'amount' => 'Amount', + 'date' => 'Date', + 'interest_date' => 'Interest date', + 'book_date' => 'Book date', + 'process_date' => 'Processing date', + 'from' => 'From', + 'piggy_bank' => 'Piggy bank', + 'to' => 'To', + 'budget' => 'Budget', + 'category' => 'Category', + 'bill' => 'Bill', + 'withdrawal' => 'Withdrawal', + 'deposit' => 'Deposit', + 'transfer' => 'Transfer', + 'type' => 'Type', + 'completed' => 'Completed', + 'iban' => 'IBAN', + 'paid_current_period' => 'Paid this period', + 'email' => 'Email', + 'registered_at' => 'Registered at', + 'is_activated' => 'Is activated', + 'is_blocked' => 'Is blocked', + 'is_admin' => 'Is admin', + 'has_two_factor' => 'Has 2FA', + 'confirmed_from' => 'Confirmed from', + 'registered_from' => 'Registered from', + 'blocked_code' => 'Block code', + 'domain' => 'Domain', + 'registration_attempts' => 'Registration attempts', +]; diff --git a/resources/lang/zh-TW/pagination.php b/resources/lang/zh-TW/pagination.php new file mode 100644 index 0000000000..b1cf416ae8 --- /dev/null +++ b/resources/lang/zh-TW/pagination.php @@ -0,0 +1,13 @@ + '« Previous', + 'next' => 'Next »', +]; diff --git a/resources/lang/zh-TW/passwords.php b/resources/lang/zh-TW/passwords.php new file mode 100644 index 0000000000..6c382f830f --- /dev/null +++ b/resources/lang/zh-TW/passwords.php @@ -0,0 +1,17 @@ + 'Passwords must be at least six characters and match the confirmation.', + 'user' => 'We can\'t find a user with that e-mail address.', + 'token' => 'This password reset token is invalid.', + 'sent' => 'We have e-mailed your password reset link!', + 'reset' => 'Your password has been reset!', + 'blocked' => 'Nice try though.', +]; diff --git a/resources/lang/zh-TW/validation.php b/resources/lang/zh-TW/validation.php new file mode 100644 index 0000000000..fa086c9fbb --- /dev/null +++ b/resources/lang/zh-TW/validation.php @@ -0,0 +1,80 @@ + 'This is not a valid IBAN.', + 'unique_account_number_for_user' => 'It looks like this account number is already in use.', + 'rule_trigger_value' => 'This value is invalid for the selected trigger.', + 'rule_action_value' => 'This value is invalid for the selected action.', + 'invalid_domain' => 'Due to security constraints, you cannot register from this domain.', + 'file_already_attached' => 'Uploaded file ":name" is already attached to this object.', + 'file_attached' => 'Succesfully uploaded file ":name".', + 'file_invalid_mime' => 'File ":name" is of type ":mime" which is not accepted as a new upload.', + 'file_too_large' => 'File ":name" is too large.', + 'belongs_to_user' => 'The value of :attribute is unknown', + 'accepted' => 'The :attribute must be accepted.', + 'active_url' => 'The :attribute is not a valid URL.', + 'after' => 'The :attribute must be a date after :date.', + 'alpha' => 'The :attribute may only contain letters.', + 'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.', + 'alpha_num' => 'The :attribute may only contain letters and numbers.', + 'array' => 'The :attribute must be an array.', + 'unique_for_user' => 'There already is an entry with this :attribute.', + 'before' => 'The :attribute must be a date before :date.', + 'unique_object_for_user' => 'This name is already in use', + 'unique_account_for_user' => 'This account name is already in use', + 'between.numeric' => 'The :attribute must be between :min and :max.', + 'between.file' => 'The :attribute must be between :min and :max kilobytes.', + 'between.string' => 'The :attribute must be between :min and :max characters.', + 'between.array' => 'The :attribute must have between :min and :max items.', + 'boolean' => 'The :attribute field must be true or false.', + 'confirmed' => 'The :attribute confirmation does not match.', + 'date' => 'The :attribute is not a valid date.', + 'date_format' => 'The :attribute does not match the format :format.', + 'different' => 'The :attribute and :other must be different.', + 'digits' => 'The :attribute must be :digits digits.', + 'digits_between' => 'The :attribute must be between :min and :max digits.', + 'email' => 'The :attribute must be a valid email address.', + 'filled' => 'The :attribute field is required.', + 'exists' => 'The selected :attribute is invalid.', + 'image' => 'The :attribute must be an image.', + 'in' => 'The selected :attribute is invalid.', + 'integer' => 'The :attribute must be an integer.', + 'ip' => 'The :attribute must be a valid IP address.', + 'json' => 'The :attribute must be a valid JSON string.', + 'max.numeric' => 'The :attribute may not be greater than :max.', + 'max.file' => 'The :attribute may not be greater than :max kilobytes.', + 'max.string' => 'The :attribute may not be greater than :max characters.', + 'max.array' => 'The :attribute may not have more than :max items.', + 'mimes' => 'The :attribute must be a file of type: :values.', + 'min.numeric' => 'The :attribute must be at least :min.', + 'min.file' => 'The :attribute must be at least :min kilobytes.', + 'min.string' => 'The :attribute must be at least :min characters.', + 'min.array' => 'The :attribute must have at least :min items.', + 'not_in' => 'The selected :attribute is invalid.', + 'numeric' => 'The :attribute must be a number.', + 'regex' => 'The :attribute format is invalid.', + 'required' => 'The :attribute field is required.', + 'required_if' => 'The :attribute field is required when :other is :value.', + 'required_unless' => 'The :attribute field is required unless :other is in :values.', + 'required_with' => 'The :attribute field is required when :values is present.', + 'required_with_all' => 'The :attribute field is required when :values is present.', + 'required_without' => 'The :attribute field is required when :values is not present.', + 'required_without_all' => 'The :attribute field is required when none of :values are present.', + 'same' => 'The :attribute and :other must match.', + 'size.numeric' => 'The :attribute must be :size.', + 'size.file' => 'The :attribute must be :size kilobytes.', + 'size.string' => 'The :attribute must be :size characters.', + 'size.array' => 'The :attribute must contain :size items.', + 'unique' => 'The :attribute has already been taken.', + 'string' => 'The :attribute must be a string.', + 'url' => 'The :attribute format is invalid.', + 'timezone' => 'The :attribute must be a valid zone.', + '2fa_code' => 'The :attribute field is invalid.', +]; diff --git a/resources/views/admin/domains/index.twig b/resources/views/admin/domains/index.twig new file mode 100644 index 0000000000..2da0fe9ad2 --- /dev/null +++ b/resources/views/admin/domains/index.twig @@ -0,0 +1,120 @@ +{% extends "./layout/default.twig" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.renderIfExists }} +{% endblock %} +{% block content %} +
+
+
+
+

{{ 'all_blocked_domains'|_ }}

+
+
+ {% if domains|length > 0 %} + + + + + + + + + + {% for domain in domains %} + + + + + + {% endfor %} + +
 {{ trans('list.domain') }}{{ trans('list.is_blocked') }}
+ unblock + {{ domain }} + +
+ {% else %} +

+ {{ 'no_domains_banned'|_ }} +

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

{{ 'all_user_domains'|_ }}

+
+
+ {% if knownDomains|length > 0 %} +

+ {{ 'all_domains_is_filtered'|_ }} + +

+ + + + + + + + + {% for domain in knownDomains %} + + + + + + {% endfor %} + +
 {{ trans('list.domain') }}
block{{ domain }}
+ {% else %} +

+ {{ 'no_domains_banned'|_ }} +

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

{{ 'manual_block_domain'|_ }}

+
+
+ +
+
+ +
+ + + + {{ ExpandedForm.text('domain') }} + + + +
+ +
+
+
+
+
+
+ + +{% endblock %} diff --git a/resources/views/admin/index.twig b/resources/views/admin/index.twig index 55c45db3d5..ea8a12b066 100644 --- a/resources/views/admin/index.twig +++ b/resources/views/admin/index.twig @@ -13,6 +13,7 @@
diff --git a/resources/views/admin/users/index.twig b/resources/views/admin/users/index.twig index 05bd5375f7..9d17bee41b 100644 --- a/resources/views/admin/users/index.twig +++ b/resources/views/admin/users/index.twig @@ -17,6 +17,8 @@   {{ trans('list.email') }} {{ trans('list.registered_at') }} + {{ trans('list.registered_from') }} + {{ trans('list.confirmed_from') }} {{ trans('list.is_admin') }} {{ trans('list.has_two_factor') }} {{ trans('list.is_activated') }} @@ -27,13 +29,23 @@ {% for user in users %} - ~ + +
+ +
+ #{{ user.id }} {{ user.email }} {{ user.created_at.formatLocalized(monthAndDayFormat) }} {{ user.created_at.format('H:i') }} + + {{ Preferences.getForUser(user,"registration_ip_address").data }} + + + {{ Preferences.getForUser(user,"confirmation_ip_address").data }} + {% if user.isAdmin %} diff --git a/resources/views/bills/show.twig b/resources/views/bills/show.twig index ab5303ab6e..85dd232568 100644 --- a/resources/views/bills/show.twig +++ b/resources/views/bills/show.twig @@ -60,6 +60,14 @@ {% endif %} + + {{ trans('firefly.average_bill_amount_year', {year: year}) }} + {{ yearAverage|formatAmount }} + + + {{ 'average_bill_amount_overall'|_ }} + {{ overallAverage|formatAmount }} + diff --git a/resources/views/form/options.twig b/resources/views/form/options.twig index 4692b300b8..83212c903b 100644 --- a/resources/views/form/options.twig +++ b/resources/views/form/options.twig @@ -45,4 +45,4 @@ -{% endif %} \ No newline at end of file +{% endif %} diff --git a/resources/views/import/complete.twig b/resources/views/import/complete.twig new file mode 100644 index 0000000000..2f9d96cb26 --- /dev/null +++ b/resources/views/import/complete.twig @@ -0,0 +1,36 @@ +{% extends "./layout/default.twig" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.renderIfExists }} +{% endblock %} +{% block content %} +
+
+
+
+

{{ 'import_complete'|_ }}

+
+
+

+ {{ 'import_complete_text'|_ }} +

+

+ php artisan firefly:import {{ job.key }} +

+ +
+
+
+
+{% endblock %} +{% block scripts %} +{% endblock %} +{% block styles %} +{% endblock %} diff --git a/resources/views/import/csv/configure.twig b/resources/views/import/csv/configure.twig new file mode 100644 index 0000000000..7dccd35ede --- /dev/null +++ b/resources/views/import/csv/configure.twig @@ -0,0 +1,98 @@ +{% extends "./layout/default.twig" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, job) }} +{% endblock %} + +{% block content %} + +
+
+
+
+

{{ trans('csv.import_configure_title') }}

+
+
+

+ {{ trans('csv.import_configure_intro') }} +

+
+
+ +
+
+ +
+ + +
+
+
+
+

{{ trans('csv.import_configure_form') }}

+
+
+
+
+ + {{ ExpandedForm.checkbox('has_headers',1,job.configuration['has-headers'],{helpText: trans('csv.header_help')}) }} + {{ ExpandedForm.text('date_format',job.configuration['date-format'],{helpText: trans('csv.date_help', {dateExample: phpdate('Ymd')}) }) }} + {{ ExpandedForm.select('csv_delimiter', data.delimiters, job.configuration['delimiter'], {helpText: trans('csv.delimiter_help') } ) }} + {{ ExpandedForm.select('csv_import_account', data.accounts, job.configuration['import-account'], {helpText: trans('csv.import_account_help')} ) }} + + {% for type, specific in data.specifics %} +
+ + +
+
+
+
+
+ {% endfor %} + + {% if not data.is_upload_possible %} +
+
+   +
+ +
+
{{ data.upload_path }}
+

+ {{ trans('csv.upload_not_writeable') }} +

+
+
+ {% endif %} +
+
+
+
+
+
+ {% if data.is_upload_possible %} +
+
+
+
+ +
+
+
+
+ {% endif %} +
+ + + + +{% endblock %} diff --git a/resources/views/import/csv/map.twig b/resources/views/import/csv/map.twig new file mode 100644 index 0000000000..5f21f1a9d0 --- /dev/null +++ b/resources/views/import/csv/map.twig @@ -0,0 +1,122 @@ +{% extends "./layout/default.twig" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName) }} +{% endblock %} + +{% block content %} + + +
+
+
+
+

{{ trans('csv.map_title') }}

+
+
+

+ {{ trans('csv.map_text') }} +

+
+
+ +
+
+
+ + + + {% for field in data %} +
+
+
+
+

{{ trans('csv.column_'~field.name) }}

+
+
+ + + + + + + + + {% for option in field.values %} + + + + + {% endfor %} + +
{{ trans('csv.field_value') }}{{ trans('csv.field_mapped_to') }}
+ {{ option }} + + {{ Form.select('mapping['~field.index~']['~option~']', + field.options, + job.configuration['column-mapping-config'][field.index][option], {class: 'form-control'}) }} +
+
+
+
+
+ {% endfor %} + + + {# + + {% for index,columnName in map %} + +
+
+
+
+

{{ Config.get('csv.roles.'~columnName~'.name') }}

+
+
+ + + + + + + + + {% for value in values[index] %} + + + + + {% endfor %} + + + +
{{ 'csv_field_value'|_ }}{{ 'csv_field_mapped_to'|_ }}
{{ value }} + {{ Form.select('mapping['~index~']['~value~']',options[index], mapped[index][value], {class: 'form-control'}) }} +
+ + +
+
+
+
+ {% endfor %} + #} + + +
+
+
+
+ +
+
+
+
+ +
+ + +{% endblock %} diff --git a/resources/views/import/csv/roles.twig b/resources/views/import/csv/roles.twig new file mode 100644 index 0000000000..2886c62f25 --- /dev/null +++ b/resources/views/import/csv/roles.twig @@ -0,0 +1,95 @@ +{% extends "./layout/default.twig" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName) }} +{% endblock %} + +{% block content %} + +
+
+
+
+

{{ trans('csv.column_roles_title') }}

+
+
+

{{ trans('csv.column_roles_text')|raw }}

+
+
+ +
+
+
+ + + +
+
+
+
+

{{ trans('csv.column_roles_table') }}

+
+
+ + + + + + + + + + + {% for i in 0..(data.columnCount-1) %} + + + + + + + + {% endfor %} + + +
{{ trans('csv.column_name') }}{{ trans('csv.column_example') }}{{ trans('csv.column_role') }}{{ trans('csv.do_map_value') }}
{{ trans('csv.column') }} #{{ loop.index }} + {% if data.columns[i]|length == 0 %} + {{ trans('csv.no_example_data') }} + {% else %} + {% for example in data.columns[i] %} + {{ example }}
+ {% endfor %} + {% endif %} + +
+ {{ Form.select(('role['~loop.index0~']'), + data.available_roles, + job.configuration['column-roles'][loop.index0], + {class: 'form-control'}) }} + + {{ Form.checkbox(('map['~loop.index0~']'),1, + job.configuration['column-do-mapping'][loop.index0] + + ) }} +
+ + +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+ + +{% endblock %} diff --git a/resources/views/import/index.twig b/resources/views/import/index.twig index 16ea17886e..0627280b9f 100644 --- a/resources/views/import/index.twig +++ b/resources/views/import/index.twig @@ -6,7 +6,6 @@ {% block content %}
-

{{ 'import'|_ }}

@@ -15,8 +14,9 @@

{{ 'import_intro_text'|_ }}

-

-   + +

+  {{ 'import_intro_beta'|_ }}

- {{ ExpandedForm.file('import_file',{helpText: 'import_file_help'|_}) }} + {{ ExpandedForm.file('import_file', {helpText: 'import_file_help'|_}) }} + {{ ExpandedForm.file('configuration_file', {helpText: 'configuration_file_help'|_}) }} {{ ExpandedForm.select('import_file_type', importFileTypes, defaultImportType, {'helpText' : 'import_file_type_help'|_}) }} diff --git a/resources/views/index.twig b/resources/views/index.twig index 4363bbf924..64a8e1d873 100644 --- a/resources/views/index.twig +++ b/resources/views/index.twig @@ -59,7 +59,7 @@ {% for data in transactions %}
-

{{ data[1].name }}

+

{{ data[1].name }}

diff --git a/resources/views/layout/default.twig b/resources/views/layout/default.twig index 16ee742cef..b6e07e01a6 100644 --- a/resources/views/layout/default.twig +++ b/resources/views/layout/default.twig @@ -167,20 +167,21 @@ // date range picker configuration: var dateRangeConfig = { - startDate: moment("{{ Session.get('start').format('Y-m-d') }}"), - endDate: moment("{{ Session.get('end').format('Y-m-d') }}"), + startDate: moment("{{ dpStart }}"), + endDate: moment("{{ dpEnd }}"), linkTitle: "{{ Session.get('start').formatLocalized(monthAndDayFormat) }} - {{ Session.get('end').formatLocalized(monthAndDayFormat) }}", URL: "{{ route('daterange') }}", firstDate: moment("{{ Session.get('first').format('Y-m-d') }}"), - currentMonth: "{{ currentMonthName }}", - previousMonth: "{{ previousMonthName }}", - nextMonth: "{{ nextMonthName }}", + currentPeriod: "{{ dpCurrent }}", + previousPeriod: "{{ dpPrevious }}", + nextPeriod: "{{ dpNext }}", everything: '{{ 'everything'|_ }}', customRangeLabel: '{{ 'customRange'|_ }}', applyLabel: '{{ 'apply'|_ }}', cancelLabel: '{{ 'cancel'|_ }}', fromLabel: '{{ 'from'|_ }}', - toLabel: '{{ 'to'|_ }}' + toLabel: '{{ 'to'|_ }}', + ranges: {{ dpRanges|json_encode|raw }} }; var token = "{{ csrf_token() }}"; diff --git a/resources/views/list/piggy-banks.twig b/resources/views/list/piggy-banks.twig index 753fae7a47..3a049b0e1f 100644 --- a/resources/views/list/piggy-banks.twig +++ b/resources/views/list/piggy-banks.twig @@ -2,6 +2,12 @@ {% for piggyBank in piggyBanks %} + +
+ + +
+ diff --git a/resources/views/partials/menu-sidebar.twig b/resources/views/partials/menu-sidebar.twig index 54de5a7a93..4920233f04 100644 --- a/resources/views/partials/menu-sidebar.twig +++ b/resources/views/partials/menu-sidebar.twig @@ -110,8 +110,7 @@ -
  • - +
  • @@ -120,12 +119,9 @@
      - {% if Config.get('firefly.csv_import_enabled') %} -
    • - {{ 'csv_import'|_ }} -
    • - {% endif %} - +
    • + {{ 'import_data'|_ }} +
    • {{ 'export_data'|_ }}
    • diff --git a/resources/views/piggy-banks/add-mobile.twig b/resources/views/piggy-banks/add-mobile.twig new file mode 100644 index 0000000000..ed169cd487 --- /dev/null +++ b/resources/views/piggy-banks/add-mobile.twig @@ -0,0 +1,39 @@ +{% extends "./layout/default.twig" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName) }} +{% endblock %} + +{% block content %} + {{ Form.open({'class' : 'form-horizontal','id' : 'store','url' : route('piggy-banks.post-add-mobile', piggyBank.id)}) }} +
      +
      +
      +
      +

      {{ trans('firefly.add_money_to_piggy', {name: piggyBank.name}) }}

      +
      +
      + +

      + {{ 'max_amount_add'|_ }}: {{ maxAmount|formatAmount }}. +

      + +
      +
      {{ getCurrencySymbol()|raw }}
      + +
      +

      +   +

      + + + +
      +
      +
      + +
      + {{ Form.close|raw }} +{% endblock %} diff --git a/resources/views/reports/default/year.twig b/resources/views/reports/default/year.twig index 89a2403ca2..9f605f9f42 100644 --- a/resources/views/reports/default/year.twig +++ b/resources/views/reports/default/year.twig @@ -61,21 +61,55 @@
  • - {% for budget in budgets %} -
    -
    -
    -
    -

    {{ 'budget'|_ }} {{ budget.name }}

    -
    -
    - -
    +
    +
    +
    +
    +

    {{ 'budgets'|_ }}

    +
    +
    + + + + + {% for date, header in budgets.get('headers') %} + + {% endfor %} + + + + {% set spentData = budgets.get('spent') %} + {% for budgetId, budgetName in budgets.get('budgets') %} + + + {% for date, header in budgets.get('headers') %} + + {% endfor %} + + + {% endfor %} + + +
     {{ header }}
    + {{ budgetName }} + {{ spentData[budgetId][date]|formatAmount }}
    - {% endfor %} +
    +
    +
    +
    +
    +

    {{ 'chart'|_ }}

    +
    +
    + + +
    +
    +
    +
    {% endblock %} {% block scripts %} diff --git a/resources/views/split/journals/create.twig b/resources/views/split/journals/create.twig index 90acdc41f4..076d790df1 100644 --- a/resources/views/split/journals/create.twig +++ b/resources/views/split/journals/create.twig @@ -7,193 +7,219 @@ - - - + + + - {% if errors.all()|length > 0 %} + + + {% if errors.all()|length > 0 %} +
    +
    +
    +
    +

    {{ 'errors'|_ }}

    +
    +
    +
      + {% for key, err in errors.all() %} +
    • {{ err }}
    • + {% endfor %} +
    +
    +
    +
    +
    + {% endif %}
    -
    -
    +
    +
    -

    {{ 'errors'|_ }}

    +

    {{ 'transaction_meta_data'|_ }}

    -
      - {% for key, err in errors.all() %} -
    • {{ err }}
    • - {% endfor %} -
    + {{ ExpandedForm.text('journal_description', journal.description) }} + {{ ExpandedForm.select('journal_currency_id', currencies, journal.transaction_currency_id) }} + {{ ExpandedForm.staticText('journal_amount', preFilled.journal_amount|formatAmount ) }} + + + + {% if preFilled.what == 'withdrawal' or preFilled.what == 'transfer' %} + {{ ExpandedForm.select('journal_source_account_id', assetAccounts, preFilled.journal_source_account_id) }} + {% endif %} + + + {% if preFilled.what == 'deposit' %} + {{ ExpandedForm.select('journal_destination_account_id', assetAccounts, preFilled.journal_destination_account_id) }} + {% endif %} + + + {% if preFilled.what == 'transfer' %} + {{ ExpandedForm.select('journal_destination_account_id', assetAccounts, preFilled.journal_destination_account_id) }} + {% endif %}
    -
    - {% endif %} -
    -
    -
    -
    -

    {{ 'transaction_meta_data'|_ }}

    -
    -
    - {{ ExpandedForm.text('journal_description', journal.description) }} - {{ ExpandedForm.select('journal_currency_id', currencies, journal.transaction_currency_id) }} - {{ ExpandedForm.staticText('journal_amount', preFilled.journal_amount|formatAmount ) }} - - - {% if preFilled.what == 'withdrawal' or preFilled.what == 'transfer' %} - {{ ExpandedForm.select('journal_source_account_id', assetAccounts, preFilled.journal_source_account_id) }} - {% endif %} - - {% if preFilled.what == 'deposit' %} - {{ ExpandedForm.text('journal_source_account_name', preFilled.journal_source_account_name) }} - {% endif %} - - {% if preFilled.what == 'transfer' %} - {{ ExpandedForm.select('journal_destination_account_id', assetAccounts, preFilled.journal_destination_account_id) }} - {% endif %} +
    +
    +
    +

    {{ 'transaction_dates'|_ }}

    +
    +
    + {{ ExpandedForm.date('date', journal.date) }} + + {{ ExpandedForm.date('interest_date', journal.interest_date) }} + + {{ ExpandedForm.date('book_date', journal.book_date) }} + + {{ ExpandedForm.date('process_date', journal.process_date) }} +
    +
    -
    -
    -
    -

    {{ 'transaction_dates'|_ }}

    -
    -
    - {{ ExpandedForm.date('date', journal.date) }} +
    +
    +
    +
    +

    {{ 'splits'|_ }}

    +
    +
    + + + + + - {{ ExpandedForm.date('interest_date', journal.interest_date) }} - {{ ExpandedForm.date('book_date', journal.book_date) }} - - {{ ExpandedForm.date('process_date', journal.process_date) }} - - - - - -
    -
    -
    -
    -

    {{ 'splits'|_ }}

    -
    -
    -
    {{ trans('list.split_number') }}{{ trans('list.description') }}
    - - - - - {% if preFilled.what == 'withdrawal' or preFilled.what == 'deposit' %} - - {% endif %} - - {% if preFilled.what == 'withdrawal' %} - - {% endif %} - - {% if preFilled.what == 'transfer' %} - - {% endif %} - - - - {% for index, descr in preFilled.description %} - - - - - + {% if preFilled.what == 'withdrawal' %} - + {% endif %} - {% if preFilled.what == 'deposit' %} - + {% endif %} - + + + {% if preFilled.what == 'withdrawal' %} - + {% endif %} - + + {% if preFilled.what == 'transfer' %} - + {% endif %} - {% endfor %} - -
    {{ trans('list.split_number') }}{{ trans('list.description') }}{{ trans('list.destination') }}{{ trans('list.amount') }}{{ trans('list.budget') }}{{ trans('list.category') }}{{ trans('list.piggy_bank') }}
    #{{ loop.index }} - - - - {{ trans('list.destination') }} - {{ Form.select('destination_account_id[]', assetAccounts, preFilled.destination_account_id[index], {class: 'form-control'}) }} - {{ trans('list.source') }} - - {{ trans('list.amount') }} - - {{ trans('list.budget') }} - - {{ trans('list.category') }} - - {{ Form.select('piggy_bank_id[]',piggyBanks, preFilled.piggy_bank_id[index], {class: 'form-control'}) }} - {{ trans('list.piggy_bank') }}
    -

    -
    - {{ 'add_another_split'|_ }} -

    - + {% if preFilled.what == 'withdrawal' %} + + + + {% endif %} + + + {% if preFilled.what == 'deposit' %} + + + + {% endif %} + + + + + + {% if preFilled.what == 'withdrawal' %} + + + + {% endif %} + + + + {% if preFilled.what == 'transfer' %} + + + {{ Form.select('piggy_bank_id[]',piggyBanks, preFilled.piggy_bank_id[index], {class: 'form-control'}) }} + + {% endif %} + + {% endfor %} + + +

    +
    + {{ 'add_another_split'|_ }} +

    + +
    -
    -
    -
    +
    +
    -
    -
    -

    {{ 'optionalFields'|_ }}

    +
    +
    +

    {{ 'optionalFields'|_ }}

    +
    +
    + + {{ ExpandedForm.file('attachments[]', {'multiple': 'multiple','helpText': trans('firefly.upload_max_file_size', {'size': uploadSize|filesize}) }) }} +
    -
    - - {{ ExpandedForm.file('attachments[]', {'multiple': 'multiple','helpText': trans('firefly.upload_max_file_size', {'size': uploadSize|filesize}) }) }} +
    +
    + +
    +
    +

    {{ 'options'|_ }}

    +
    +
    + {{ ExpandedForm.optionsList('create','split-transaction') }} +
    +
    -
    - -
    -
    -

    {{ 'options'|_ }}

    -
    -
    - {{ ExpandedForm.optionsList('create','split-transaction') }} -
    - -
    -
    -
    {% endblock %} diff --git a/resources/views/split/journals/edit.twig b/resources/views/split/journals/edit.twig index 44deb1c9e1..2ec26d99ea 100644 --- a/resources/views/split/journals/edit.twig +++ b/resources/views/split/journals/edit.twig @@ -51,10 +51,6 @@ {{ ExpandedForm.select('journal_destination_account_id', assetAccounts, preFilled.journal_destination_account_id) }} {% endif %} - - {% if preFilled.what == 'deposit' %} - {% endif %} - {% if preFilled.what == 'transfer' %} {{ ExpandedForm.select('journal_destination_account_id', assetAccounts, preFilled.journal_destination_account_id) }} @@ -94,10 +90,14 @@ {{ trans('list.description') }} - {% if preFilled.what == 'withdrawal' or preFilled.what == 'deposit' %} + {% if preFilled.what == 'withdrawal' %} {{ trans('list.destination') }} {% endif %} + {% if preFilled.what == 'deposit' %} + {{ trans('list.source') }} + {% endif %} + {{ trans('list.amount') }} diff --git a/resources/views/transactions/mass-edit.twig b/resources/views/transactions/mass-edit.twig index 45fe55359d..ddeb20afa9 100644 --- a/resources/views/transactions/mass-edit.twig +++ b/resources/views/transactions/mass-edit.twig @@ -56,24 +56,24 @@ - + {% if journal.transaction_type_type == 'Transfer' or journal.transaction_type_type == 'Withdrawal' %} {{ Form.select('source_account_id['~journal.id~']', accountList, journal.source_account_id, {'class': 'form-control'}) }} {% else %} - - {{ Form.input('text', 'revenue_account['~journal.id~']', journal.source_account_name, {'class': 'form-control', 'placeholder': trans('form.revenue_account')}) }} + + {{ Form.input('text', 'source_account_name['~journal.id~']', journal.source_account_name, {'class': 'form-control', 'placeholder': trans('form.revenue_account')}) }} {% endif %} {% if journal.transaction_type_type == 'Transfer' or journal.transaction_type_type == 'Deposit' %} - + {{ Form.select('destination_account_id['~journal.id~']', accountList, journal.destination_account_id, {'class': 'form-control'}) }} {% else %} - + - {{ Form.input('text', 'expense_account['~journal.id~']', journal.destination_account_name, {'class': 'form-control', 'placeholder': trans('form.expense_account')}) }} + {{ Form.input('text', 'destination_account_name['~journal.id~']', journal.destination_account_name, {'class': 'form-control', 'placeholder': trans('form.expense_account')}) }} {% endif %} @@ -83,8 +83,11 @@
    diff --git a/resources/views/transactions/show.twig b/resources/views/transactions/show.twig index 74b1685f13..ffedce51dd 100644 --- a/resources/views/transactions/show.twig +++ b/resources/views/transactions/show.twig @@ -13,6 +13,10 @@
    + + + + diff --git a/storage/database/.gitignore b/storage/database/.gitignore index 79a5312b13..2f8355d95c 100644 --- a/storage/database/.gitignore +++ b/storage/database/.gitignore @@ -1,4 +1,3 @@ * !.gitignore -!seed.local.json -!seed.split.json \ No newline at end of file +!seed.*.json \ No newline at end of file diff --git a/storage/database/seed.import-test.json b/storage/database/seed.import-test.json new file mode 100644 index 0000000000..20ea6708ec --- /dev/null +++ b/storage/database/seed.import-test.json @@ -0,0 +1,170 @@ +{ + "users": [ + { + "email": "thegrumpydictator@gmail.com", + "password": "james" + } + ], + "roles": [ + { + "user_id": 1, + "role": 1 + } + ], + "accounts": [ + { + "user_id": 1, + "account_type_id": 3, + "name": "ExistingAssetAccount", + "iban": "NL62EXFK3945306779" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "ExistingOpposingAccount", + "iban": "NL79BGWN6303364632" + } + ], + "account-meta": [ + { + "account_id": 1, + "name": "accountNumber", + "data": "\"3945306779\"" + }, + { + "account_id": 2, + "name": "accountNumber", + "data": "\"6303364632\"" + } + ], + "bills": [ + { + "name": "ExistingBill", + "match": "ExistingBill", + "amount_min": 100, + "amount_max": 200, + "user_id": 1, + "date": "2015-01-01", + "active": 1, + "automatch": 1, + "repeat_freq": "monthly", + "skip": 0 + } + ], + "budgets": [ + { + "name": "ExistingBudget", + "user_id": 1 + } + ], + "budget-limits": [], + "monthly-limits": [], + "categories": [ + { + "name": "ExistingCategory", + "user_id": 1 + } + ], + "piggy-banks": [], + "piggy-events": [], + "rule-groups": [], + "rules": [], + "rule-triggers": [], + "rule-actions": [], + "tags": [ + { + "user_id": 1, + "tag": "ExistingTag", + "tagMode": "nothing" + }, + { + "user_id": 1, + "tag": "AnotherExistingTag", + "tagMode": "nothing" + } + ], + "monthly-deposits": [], + "monthly-transfers": [], + "monthly-withdrawals": [], + "attachments": [], + "multi-withdrawals": [], + "multi-deposits": [], + "multi-transfers": [], + "import-jobs": [ + { + "user_id": 1, + "key": "testImport", + "file_type": "csv", + "status": "settings_complete", + "configuration": { + "has-headers": false, + "date-format": "Ymd", + "delimiter": ",", + "import-account": 1, + "specifics": { + "RabobankDescription": 1 + }, + "column-count": 19, + "column-roles": [ + "account-iban", + "currency-code", + "date-interest", + "rabo-debet-credit", + "amount", + "opposing-iban", + "opposing-name", + "date-book", + "description", + "_ignore", + "description", + "description", + "description", + "description", + "description", + "description", + "sepa-ct-id", + "sepa-ct-op", + "sepa-db" + ], + "column-do-mapping": [ + true, + true, + false, + false, + false, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ], + "column-roles-complete": false, + "column-mapping-config": { + "0": [], + "1": { + "EUR": 1 + }, + "5": [], + "6": [] + }, + "column-mapping-complete": false + } + } + ], + "currencies": [ + { + "name": "ExistingCurrency", + "symbol": "#", + "code": "EXI" + } + ] +} \ No newline at end of file diff --git a/storage/database/seed.local.json b/storage/database/seed.local.json index 0a22dcf358..bd1d17d784 100644 --- a/storage/database/seed.local.json +++ b/storage/database/seed.local.json @@ -1006,5 +1006,7 @@ 9 ] } - ] + ], + "import-jobs": [], + "currencies": [] } \ No newline at end of file diff --git a/storage/database/seed.split.json b/storage/database/seed.split.json index aa276339e7..38fa070988 100644 --- a/storage/database/seed.split.json +++ b/storage/database/seed.split.json @@ -297,5 +297,7 @@ 3 ] } - ] + ], + "import-jobs": [], + "currencies": [] } \ No newline at end of file diff --git a/storage/database/seed.testing.json b/storage/database/seed.testing.json new file mode 100644 index 0000000000..847832ee07 --- /dev/null +++ b/storage/database/seed.testing.json @@ -0,0 +1,1012 @@ +{ + "users": [ + { + "email": "thegrumpydictator@gmail.com", + "password": "james" + }, + { + "email": "thegrumpydictator+empty@gmail.com", + "password": "james" + }, + { + "email": "thegrumpydictator+deleteme@gmail.com", + "password": "james" + } + ], + "roles": [ + { + "user_id": 1, + "role": 1 + } + ], + "accounts": [ + { + "user_id": 1, + "account_type_id": 3, + "name": "Checking Account", + "iban": "NL11XOLA6707795988" + }, + { + "user_id": 1, + "account_type_id": 3, + "name": "Alternate Checking Account", + "iban": "NL40UKBK3619908726" + }, + { + "user_id": 1, + "account_type_id": 3, + "name": "Savings Account", + "iban": "NL96DZCO4665940223" + }, + { + "user_id": 1, + "account_type_id": 3, + "name": "Shared Checking Account", + "iban": "NL81RCQZ7160379858" + }, + { + "user_id": 1, + "account_type_id": 3, + "name": "Emergency Savings Account", + "iban": "NL38SRMN4325934708" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Adobe" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Google" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Vitens" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Albert Heijn" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "PLUS" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Bakker" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Belastingdienst" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "bol.com" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Cafe Central" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "conrad.nl" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Coolblue" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Shell" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "SixtyFive" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "EightyFour" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Fiftyone" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "DUO" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Etos" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "FEBO" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Greenchoice" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Halfords" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "XS4All" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "iCentre" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Jumper" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Land lord" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "Job" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "Belastingdienst" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "Bank" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "KPN" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "Google" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "Work SixtyFive" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "Work EightyFour" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "Work Fiftyone" + }, + { + "user_id": 1, + "account_type_id": 6, + "name": "Opposing for Savings Account" + }, + { + "user_id": 1, + "account_type_id": 6, + "name": "Opposing for Emergency Savings Account" + } + ], + "account-meta": [ + { + "account_id": 1, + "name": "accountRole", + "data": "\"defaultAsset\"" + }, + { + "account_id": 2, + "name": "accountRole", + "data": "\"defaultAsset\"" + }, + { + "account_id": 3, + "name": "accountRole", + "data": "\"savingAsset\"" + }, + { + "account_id": 4, + "name": "accountRole", + "data": "\"sharedAsset\"" + } + ], + "bills": [ + { + "name": "Rent", + "match": "rent,land,lord", + "amount_min": 795, + "amount_max": 805, + "user_id": 1, + "date": "2015-01-01", + "active": 1, + "automatch": 1, + "repeat_freq": "monthly", + "skip": 0 + }, + { + "name": "Health insurance", + "match": "insurer,insurance,health", + "amount_min": 120, + "amount_max": 140, + "user_id": 1, + "date": "2015-01-01", + "active": 1, + "automatch": 1, + "repeat_freq": "monthly", + "skip": 0 + } + ], + "budgets": [ + { + "name": "Groceries", + "user_id": 1 + }, + { + "name": "Bills", + "user_id": 1 + }, + { + "name": "Car", + "user_id": 1 + }, + { + "name": "One Empty Budget", + "user_id": 1 + }, + { + "name": "Another Empty Budget", + "user_id": 1 + }, + { + "name": "Going out", + "user_id": 1 + }, + { + "name": "Multi budget A", + "user_id": 1 + }, + { + "name": "Multi budget B", + "user_id": 1 + }, + { + "name": "Multi budget C", + "user_id": 1 + } + ], + "budget-limits": [ + { + "budget_id": 1, + "startdate": "2016-04-01", + "amount_min": 100, + "amount_max": 200, + "repeat_freq": "daily" + }, + { + "budget_id": 1, + "startdate": "2016-05-01", + "amount_min": 100, + "amount_max": 200, + "repeat_freq": "weekly" + }, + { + "budget_id": 1, + "startdate": "2016-06-01", + "amount_min": 100, + "amount_max": 200, + "repeat_freq": "monthly" + }, + { + "budget_id": 1, + "startdate": "2016-07-01", + "amount_min": 100, + "amount_max": 200, + "repeat_freq": "quarterly" + }, + { + "budget_id": 1, + "startdate": "2016-08-01", + "amount_min": 100, + "amount_max": 200, + "repeat_freq": "half-year" + }, + { + "budget_id": 1, + "startdate": "2016-09-01", + "amount_min": 100, + "amount_max": 200, + "repeat_freq": "yearly" + } + ], + "monthly-limits": [ + { + "budget_id": 1, + "amount_min": 200, + "amount_max": 200 + }, + { + "budget_id": 2, + "amount_min": 1000, + "amount_max": 1000 + }, + { + "budget_id": 3, + "amount_min": 200, + "amount_max": 200 + }, + { + "budget_id": 6, + "amount_min": 100, + "amount_max": 100 + } + ], + "categories": [ + { + "name": "Daily groceries", + "user_id": 1 + }, + { + "name": "Car", + "user_id": 1 + }, + { + "name": "Reimbursements", + "user_id": 1 + }, + { + "name": "Salary", + "user_id": 1 + }, + { + "name": "Bills", + "user_id": 1 + }, + { + "name": "Going out", + "user_id": 1 + }, + { + "name": "Multi category A", + "user_id": 1 + }, + { + "name": "Multi category B", + "user_id": 1 + }, + { + "name": "Multi category C", + "user_id": 1 + } + ], + "piggy-banks": [ + { + "account_id": 3, + "name": "New camera", + "targetamount": 1000, + "startdate": "2015-04-01", + "reminder_skip": 0, + "remind_me": 0, + "order": 1, + "currentamount": 735 + }, + { + "account_id": 3, + "name": "New phone", + "targetamount": 600, + "startdate": "2015-04-01", + "reminder_skip": 0, + "remind_me": 0, + "order": 2, + "currentamount": 333 + }, + { + "account_id": 3, + "name": "New couch", + "targetamount": 500, + "startdate": "2015-04-01", + "reminder_skip": 0, + "remind_me": 0, + "order": 3, + "currentamount": 120 + } + ], + "piggy-events": [ + { + "piggy_bank_id": 1, + "date": "2015-05-01", + "amount": 245 + }, + { + "piggy_bank_id": 1, + "date": "2015-06-02", + "amount": 245 + }, + { + "piggy_bank_id": 1, + "date": "2015-07-03", + "amount": 245 + }, + { + "piggy_bank_id": 2, + "date": "2015-08-04", + "amount": 111 + }, + { + "piggy_bank_id": 2, + "date": "2015-09-05", + "amount": 111 + }, + { + "piggy_bank_id": 2, + "date": "2015-10-06", + "amount": 111 + }, + { + "piggy_bank_id": 3, + "date": "2015-11-07", + "amount": 40 + }, + { + "piggy_bank_id": 3, + "date": "2015-12-08", + "amount": 40 + }, + { + "piggy_bank_id": 3, + "date": "2016-01-09", + "amount": 40 + } + ], + "rule-groups": [ + { + "user_id": 1, + "order": 1, + "title": "Default rules", + "description": "All your rules not in a particular group." + } + ], + "rules": [ + { + "user_id": 1, + "rule_group_id": 1, + "order": 1, + "active": 1, + "stop_processing": 0, + "title": "Your first default rule", + "description": "This rule is an example. You can safely delete it." + } + ], + "rule-triggers": [ + { + "rule_id": 1, + "order": 1, + "active": 1, + "stop_processing": 0, + "trigger_type": "user_action", + "trigger_value": "store-journal" + }, + { + "rule_id": 1, + "order": 2, + "active": 1, + "stop_processing": 0, + "trigger_type": "description_is", + "trigger_value": "The Man Who Sold the World" + }, + { + "rule_id": 1, + "order": 3, + "active": 1, + "stop_processing": 0, + "trigger_type": "from_account_is", + "trigger_value": "David Bowie" + } + ], + "rule-actions": [ + { + "rule_id": 1, + "order": 1, + "active": 1, + "stop_processing": 0, + "action_type": "prepend_description", + "action_value": "Bought the world from " + }, + { + "rule_id": 1, + "order": 2, + "active": 1, + "stop_processing": 0, + "action_type": "set_category", + "action_value": "Large expenses" + } + ], + "tags": [ + { + "user_id": 1, + "tag": "TagJanuary", + "tagMode": "nothing", + "date": "2015-01-01" + }, + { + "user_id": 1, + "tag": "TagFebruary", + "tagMode": "nothing", + "date": "2015-02-02" + }, + { + "user_id": 1, + "tag": "TagMarch", + "tagMode": "nothing", + "date": "2015-03-03" + }, + { + "user_id": 1, + "tag": "TagApril", + "tagMode": "nothing", + "date": "2015-04-04" + }, + { + "user_id": 1, + "tag": "TagMay", + "tagMode": "nothing", + "date": "2015-05-05" + }, + { + "user_id": 1, + "tag": "TagJune", + "tagMode": "nothing", + "date": "2015-06-06" + }, + { + "user_id": 1, + "tag": "TagJuly", + "tagMode": "nothing", + "date": "2015-07-07" + }, + { + "user_id": 1, + "tag": "TagAugust", + "tagMode": "nothing", + "date": "2015-08-08" + }, + { + "user_id": 1, + "tag": "TagSeptember", + "tagMode": "nothing", + "date": "2015-09-09" + }, + { + "user_id": 1, + "tag": "TagOctober", + "tagMode": "nothing", + "date": "2015-10-10" + }, + { + "user_id": 1, + "tag": "TagNovember", + "tagMode": "nothing", + "date": "2015-11-11" + }, + { + "user_id": 1, + "tag": "TagDecember", + "tagMode": "nothing", + "date": "2015-12-12" + } + ], + "monthly-deposits": [ + { + "user_id": 1, + "day-of-month": 24, + "description": "Salary in :month", + "source_id": 30, + "destination_id": 1, + "min_amount": 1500, + "max_amount": 1700, + "category_id": 4 + } + ], + "monthly-transfers": [ + { + "user_id": 1, + "day-of-month": 28, + "description": "Saving money for :month", + "source_id": 1, + "destination_id": 3, + "min_amount": 150, + "max_amount": 150 + } + ], + "monthly-withdrawals": [ + { + "user_id": 1, + "day-of-month": "02", + "description": "Rent for :month", + "source_id": 1, + "destination_id": 29, + "min_amount": 800, + "max_amount": 800, + "category_id": 5, + "budget_id": 2 + }, + { + "user_id": 1, + "day-of-month": "04", + "description": "Water bill :month", + "source_id": 1, + "destination_id": 8, + "min_amount": 8, + "max_amount": 12, + "category_id": 5, + "budget_id": 2 + }, + { + "user_id": 1, + "day-of-month": "06", + "description": "TV bill :month", + "source_id": 1, + "destination_id": 26, + "min_amount": 50, + "max_amount": 60, + "category_id": 5, + "budget_id": 2 + }, + { + "user_id": 1, + "day-of-month": "08", + "description": "Power bill :month", + "source_id": 1, + "destination_id": 24, + "min_amount": 75, + "max_amount": 90, + "category_id": 5, + "budget_id": 2 + }, + { + "user_id": 1, + "day-of-month": "07", + "description": "Bought gas", + "source_id": 1, + "destination_id": 17, + "min_amount": 40, + "max_amount": 50, + "category_id": 2, + "budget_id": 3 + }, + { + "user_id": 1, + "day-of-month": 17, + "description": "Filled the car up again", + "source_id": 1, + "destination_id": 17, + "min_amount": 40, + "max_amount": 50, + "category_id": 2, + "budget_id": 3 + }, + { + "user_id": 1, + "day-of-month": 27, + "description": "Needed gas again", + "source_id": 1, + "destination_id": 17, + "min_amount": 45, + "max_amount": 55, + "category_id": 2, + "budget_id": 3 + }, + { + "user_id": 1, + "day-of-month": "02", + "description": "Groceries", + "source_id": 1, + "destination_id": 9, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": "06", + "description": "Groceries", + "source_id": 1, + "destination_id": 10, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": "08", + "description": "Groceries", + "source_id": 1, + "destination_id": 11, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": 11, + "description": "Groceries", + "source_id": 1, + "destination_id": 9, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": 15, + "description": "Groceries", + "source_id": 1, + "destination_id": 10, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": 19, + "description": "Groceries", + "source_id": 1, + "destination_id": 11, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": 23, + "description": "Groceries", + "source_id": 1, + "destination_id": 9, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": 26, + "description": "Groceries", + "source_id": 1, + "destination_id": 10, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": 13, + "description": "Going out for drinks", + "source_id": 1, + "destination_id": 14, + "min_amount": 15, + "max_amount": 36, + "category_id": 6, + "budget_id": 6 + }, + { + "user_id": 1, + "day-of-month": 26, + "description": "Going out for drinks again", + "source_id": 1, + "destination_id": 14, + "min_amount": 15, + "max_amount": 36, + "category_id": 6, + "budget_id": 6 + } + ], + "attachments": [ + { + "attachable_id": 1, + "attachable_type": "FireflyIII\\Models\\TransactionJournal", + "user_id": 1, + "content": "This is attachment number one.", + "filename": "empty-file.txt", + "title": "Empty file", + "description": "This file is empty", + "notes": "Some notes", + "mime": "text\/plain", + "uploaded": 1 + }, + { + "attachable_id": 2, + "attachable_type": "FireflyIII\\Models\\TransactionJournal", + "user_id": 1, + "content": "This is attachment number two.", + "filename": "empty-file2.txt", + "title": "Empty file", + "description": "This file is empty", + "notes": "Some notes", + "mime": "text\/plain", + "uploaded": 1 + } + ], + "multi-withdrawals": [ + { + "user_id": 1, + "date": "2016-03-12", + "description": "Even multi-withdrawal (50, 50)", + "destination_ids": [ + 18, + 19 + ], + "source_id": 1, + "amounts": [ + 50, + 50 + ], + "category_ids": [ + 7, + 8, + 9 + ], + "budget_ids": [ + 7, + 8, + 9 + ] + }, + { + "user_id": 1, + "date": "2016-05-12", + "description": "Uneven multi-withdrawal (15,34,51)", + "destination_ids": [ + 18, + 19, + 20 + ], + "source_id": 1, + "amounts": [ + 14, + 35, + 51 + ], + "category_ids": [ + 7, + 8, + 9 + ], + "budget_ids": [ + 7, + 8, + 9 + ] + } + ], + "multi-deposits": [ + { + "user_id": 1, + "date": "2016-03-02", + "description": "Even multi-deposit (50, 50)", + "source_ids": [ + 35, + 36 + ], + "destination_id": 1, + "amounts": [ + 50, + 50 + ], + "category_ids": [ + 7, + 8, + 9 + ] + }, + { + "user_id": 1, + "date": "2016-05-02", + "description": "Uneven multi-deposit (15,34,51)", + "source_ids": [ + 35, + 36, + 37 + ], + "destination_id": 1, + "amounts": [ + 14, + 35, + 51 + ], + "category_ids": [ + 7, + 8, + 9 + ] + } + ], + "multi-transfers": [ + { + "user_id": 1, + "date": "2016-03-02", + "description": "Even multi-transfer (50, 50)", + "source_ids": [ + 4, + 4 + ], + "destination_ids": [ + 5, + 5 + ], + "amounts": [ + 50, + 50 + ], + "category_ids": [ + 7, + 8 + ] + }, + { + "user_id": 1, + "date": "2016-05-02", + "description": "Uneven multi-transfer (15,34,51)", + "source_ids": [ + 4, + 4, + 4 + ], + "destination_ids": [ + 5, + 5, + 5 + ], + "amounts": [ + 14, + 35, + 51 + ], + "category_ids": [ + 7, + 8, + 9 + ] + } + ], + "import-jobs": [], + "currencies": [] +} \ No newline at end of file
    {{ trans('list.amount') }}{{ journal|formatJournal }}
    {{ trans('list.date') }} {{ journal.date.formatLocalized(monthAndDayFormat) }}