diff --git a/.env.example b/.env.example index 1333892862..28d87ce566 100755 --- a/.env.example +++ b/.env.example @@ -38,9 +38,14 @@ SEND_REGISTRATION_MAIL=true SEND_ERROR_MESSAGE=true SHOW_INCOMPLETE_TRANSLATIONS=false +CACHE_PREFIX=firefly + ANALYTICS_ID= SITE_OWNER=mail@example.com PUSHER_KEY= PUSHER_SECRET= PUSHER_APP_ID= + +DEMO_USERNAME= +DEMO_PASSWORD= \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index a8f360bfff..bcba948aa5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,14 +5,13 @@ php: 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 - - ./test.sh -r - - php artisan env + - cp .env.testing .env + - mv storage/database/databasecopy.sqlite storage/database/database.sqlite script: - phpunit \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 107e66c744..c2d14ac49e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,28 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). + +## [4.3.0] - 2015-12-26 +### Added +- New method of keeping track of available budget, see issue #489 +- Support for Spanish +- Firefly III now has an extended demo mode. Will expand further in the future. + + +### Changed +- New favicon +- Import routine no longer gives transactions a description #483 + + +### Removed +- All test data generation code. + +### Fixed +- Removed import accounts from search results #478 +- Redirect after delete will no longer go back to deleted item #477 +- Cannot math #482 +- Fixed bug in virtual balance field #479 + ## [4.2.2] - 2016-12-18 ### Added - New budget report (still a bit of a beta) diff --git a/README.md b/README.md index b6a4297b78..11c105c0a6 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# Firefly III [![Requires PHP7](https://img.shields.io/badge/php-7.0-red.svg)](https://secure.php.net/downloads.php#v7.0.4) [![Latest Stable Version](https://poser.pugx.org/grumpydictator/firefly-iii/v/stable)](https://packagist.org/packages/grumpydictator/firefly-iii) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/JC5/firefly-iii/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master) +# Firefly III: A personal finances manager -[![Build Status](https://travis-ci.org/JC5/firefly-iii.svg?branch=master)](https://travis-ci.org/JC5/firefly-iii) +[![Requires PHP7](https://img.shields.io/badge/php-7.0-red.svg)](https://secure.php.net/downloads.php#v7.0.4) [![Latest Stable Version](https://poser.pugx.org/grumpydictator/firefly-iii/v/stable)](https://packagist.org/packages/grumpydictator/firefly-iii) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/JC5/firefly-iii/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master) -## A personal finances manager +[![Build Status](https://travis-ci.org/JC5/firefly-iii.svg?branch=master)](https://travis-ci.org/JC5/firefly-iii) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=44UKUT455HUFA) [![The index of Firefly III](https://i.nder.be/hurdhgyg/400)](https://i.nder.be/h2b37243) [![The account overview of Firefly III](https://i.nder.be/hnkfkdpr/400)](https://i.nder.be/hv70pbwc) @@ -12,6 +12,10 @@ _(You can click on the images for a better view)_ "Firefly III" is a financial manager. It can help you keep track of expenses, income, budgets and everything in between. It even supports credit cards, shared household accounts and savings accounts! It's pretty fancy. You should use it to save and organise money. +## Try it out! + +Try out Firefly III on the [demo site](https://firefly-iii.nder.be/). + ## Installation To install Firefly III, you'll need a web server (preferrably on Linux) and access to the command line. Then, please read the [installation guide](https://firefly-iii.github.io/installation-guide/). @@ -31,4 +35,6 @@ Firefly works on the principle that if you know where you're money is going, you Firefly is pretty awesome. [You can read more about Firefly III, and its features, on the Github Pages](https://firefly-iii.github.io/). +If you like Firefly and if it helps you save lots of money, why not send me [a dime for every dollar saved](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=44UKUT455HUFA) (this is a joke, although the Paypal form works just fine, try it!) + If you want to contact me, please open an issue or [email me](mailto:thegrumpydictator@gmail.com). diff --git a/app/Console/Commands/CreateImport.php b/app/Console/Commands/CreateImport.php index 89767b2240..41fd83d762 100644 --- a/app/Console/Commands/CreateImport.php +++ b/app/Console/Commands/CreateImport.php @@ -50,11 +50,10 @@ class CreateImport extends Command } /** - * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) // cannot be helped */ public function handle() { - // find the file /** @var UserRepositoryInterface $userRepository */ $userRepository = app(UserRepositoryInterface::class); $file = $this->argument('file'); @@ -67,7 +66,6 @@ class CreateImport extends Command return; } - // try to parse configuration data: $configurationData = json_decode(file_get_contents($configuration)); if (is_null($configurationData)) { $this->error(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd)); @@ -82,21 +80,17 @@ class CreateImport extends Command /** @var ImportJobRepositoryInterface $jobRepository */ $jobRepository = app(ImportJobRepositoryInterface::class, [$user]); - - $job = $jobRepository->create($type); + $job = $jobRepository->create($type); $this->line(sprintf('Created job "%s"...', $job->key)); - // put the file in the proper place: Artisan::call('firefly:encrypt', ['file' => $file, 'key' => $job->key]); $this->line('Stored import data...'); - // store the configuration in the job: $job->configuration = $configurationData; $job->status = 'settings_complete'; $job->save(); $this->line('Stored configuration...'); - // if user wants to run it, do! if ($this->option('start') === true) { $this->line('The import will start in a moment. This process is not visible...'); Log::debug('Go for import!'); @@ -109,10 +103,10 @@ class CreateImport extends Command /** * @return bool + * @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five exactly. */ private function validArguments(): bool { - // find the file /** @var UserRepositoryInterface $userRepository */ $userRepository = app(UserRepositoryInterface::class); $file = $this->argument('file'); diff --git a/app/Console/Commands/Import.php b/app/Console/Commands/Import.php index 2e36d3d417..c67f39000f 100644 --- a/app/Console/Commands/Import.php +++ b/app/Console/Commands/Import.php @@ -18,6 +18,7 @@ use FireflyIII\Import\Logging\CommandHandler; use FireflyIII\Models\ImportJob; use FireflyIII\Models\TransactionJournal; use Illuminate\Console\Command; +use Illuminate\Support\Collection; use Log; /** @@ -69,32 +70,15 @@ class Import extends Command $monolog = Log::getMonolog(); $handler = new CommandHandler($this); $monolog->pushHandler($handler); + $importProcedure = new ImportProcedure; + $result = $importProcedure->runImport($job); - $result = ImportProcedure::runImport($job); - - - /** - * @var int $index - * @var TransactionJournal $journal - */ - foreach ($result as $index => $journal) { - if (!is_null($journal->id)) { - $this->line(sprintf('Line #%d has been imported as transaction #%d.', $index, $journal->id)); - continue; - } - $this->error(sprintf('Could not store line #%d', $index)); - } - + // display result to user: + $this->presentResults($result); $this->line('The import has completed.'); // get any errors from the importer: - $extendedStatus = $job->extended_status; - if (isset($extendedStatus['errors']) && count($extendedStatus['errors']) > 0) { - $this->line(sprintf('The following %d error(s) occured during the import:', count($extendedStatus['errors']))); - foreach ($extendedStatus['errors'] as $error) { - $this->error($error); - } - } + $this->presentErrors($job); return; } @@ -120,4 +104,36 @@ class Import extends Command return true; } + + /** + * @param ImportJob $job + */ + private function presentErrors(ImportJob $job) + { + $extendedStatus = $job->extended_status; + if (isset($extendedStatus['errors']) && count($extendedStatus['errors']) > 0) { + $this->line(sprintf('The following %d error(s) occured during the import:', count($extendedStatus['errors']))); + foreach ($extendedStatus['errors'] as $error) { + $this->error($error); + } + } + } + + /** + * @param Collection $result + */ + private function presentResults(Collection $result) + { + /** + * @var int $index + * @var TransactionJournal $journal + */ + foreach ($result as $index => $journal) { + if (!is_null($journal->id)) { + $this->line(sprintf('Line #%d has been imported as transaction #%d.', $index, $journal->id)); + continue; + } + $this->error(sprintf('Could not store line #%d', $index)); + } + } } diff --git a/app/Console/Commands/ScanAttachments.php b/app/Console/Commands/ScanAttachments.php index 04254afb6f..0dc03631f1 100644 --- a/app/Console/Commands/ScanAttachments.php +++ b/app/Console/Commands/ScanAttachments.php @@ -60,42 +60,26 @@ class ScanAttachments extends Command /** @var Attachment $attachment */ foreach ($attachments as $attachment) { $fileName = $attachment->fileName(); - - // try to grab file content: try { $content = $disk->get($fileName); } catch (FileNotFoundException $e) { $this->error(sprintf('Could not find data for attachment #%d', $attachment->id)); continue; } - // try to decrypt content. try { $decrypted = Crypt::decrypt($content); } catch (DecryptException $e) { $this->error(sprintf('Could not decrypt data of attachment #%d', $attachment->id)); continue; } - - // make temp file: $tmpfname = tempnam(sys_get_temp_dir(), 'FireflyIII'); - - // store content in temp file: file_put_contents($tmpfname, $decrypted); - - // get md5 and mime - $md5 = md5_file($tmpfname); - $mime = mime_content_type($tmpfname); - - // update attachment: + $md5 = md5_file($tmpfname); + $mime = mime_content_type($tmpfname); $attachment->md5 = $md5; $attachment->mime = $mime; $attachment->save(); - - $this->line(sprintf('Fixed attachment #%d', $attachment->id)); - - // find file: - } } } diff --git a/app/Console/Commands/VerifyDatabase.php b/app/Console/Commands/VerifyDatabase.php index 1d295abf0f..47b40ca69f 100644 --- a/app/Console/Commands/VerifyDatabase.php +++ b/app/Console/Commands/VerifyDatabase.php @@ -124,16 +124,16 @@ class VerifyDatabase extends Command { $set = Budget::leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id') ->leftJoin('users', 'budgets.user_id', '=', 'users.id') - ->groupBy(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email']) + ->groupBy(['budgets.id', 'budgets.name', 'budgets.encrypted', 'budgets.user_id', 'users.email']) ->whereNull('budget_limits.id') - ->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email']); + ->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'budgets.encrypted', 'users.email']); - /** @var stdClass $entry */ + /** @var Budget $entry */ foreach ($set as $entry) { - + $name = $entry->encrypted ? Crypt::decrypt($entry->name) : $entry->name; $line = sprintf( 'Notice: User #%d (%s) has budget #%d ("%s") which has no budget limits.', - $entry->user_id, $entry->email, $entry->id, Crypt::decrypt($entry->name) + $entry->user_id, $entry->email, $entry->id, $name ); $this->line($line); } diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php old mode 100755 new mode 100644 diff --git a/app/Events/DeletedUser.php b/app/Events/DeletedUser.php index 2670b2c48a..80ab5d58ce 100644 --- a/app/Events/DeletedUser.php +++ b/app/Events/DeletedUser.php @@ -35,4 +35,4 @@ class DeletedUser extends Event { $this->email = $email; } -} \ No newline at end of file +} diff --git a/app/Events/RequestedNewPassword.php b/app/Events/RequestedNewPassword.php index 7956cc8613..52919a646b 100644 --- a/app/Events/RequestedNewPassword.php +++ b/app/Events/RequestedNewPassword.php @@ -43,4 +43,4 @@ class RequestedNewPassword extends Event $this->ipAddress = $ipAddress; } -} \ No newline at end of file +} diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php old mode 100755 new mode 100644 diff --git a/app/Export/ProcessorInterface.php b/app/Export/ProcessorInterface.php index 364f4730d4..459cbf6276 100644 --- a/app/Export/ProcessorInterface.php +++ b/app/Export/ProcessorInterface.php @@ -64,4 +64,4 @@ interface ProcessorInterface * @return Collection */ public function getFiles(): Collection; -} \ No newline at end of file +} diff --git a/app/Generator/Chart/Basic/ChartJsGenerator.php b/app/Generator/Chart/Basic/ChartJsGenerator.php index a4a4caa8c1..3f5eb8145c 100644 --- a/app/Generator/Chart/Basic/ChartJsGenerator.php +++ b/app/Generator/Chart/Basic/ChartJsGenerator.php @@ -31,6 +31,8 @@ class ChartJsGenerator implements GeneratorInterface * 0: [ * 'label' => 'label of set', * 'type' => bar or line, optional + * 'yAxisID' => ID of yAxis, optional, will not be included when unused. + * 'fill' => if to fill a line? optional, will not be included when unused. * 'entries' => * [ * 'label-of-entry' => 'value' @@ -39,6 +41,8 @@ class ChartJsGenerator implements GeneratorInterface * 1: [ * 'label' => 'label of another set', * 'type' => bar or line, optional + * 'yAxisID' => ID of yAxis, optional, will not be included when unused. + * 'fill' => if to fill a line? optional, will not be included when unused. * 'entries' => * [ * 'label-of-entry' => 'value' @@ -64,11 +68,19 @@ class ChartJsGenerator implements GeneratorInterface unset($first, $labels); foreach ($data as $set) { - $chartData['datasets'][] = [ + $currentSet = [ 'label' => $set['label'], 'type' => $set['type'] ?? 'line', 'data' => array_values($set['entries']), ]; + if (isset($set['yAxisID'])) { + $currentSet['yAxisID'] = $set['yAxisID']; + } + if (isset($set['fill'])) { + $currentSet['fill'] = $set['fill']; + } + + $chartData['datasets'][] = $currentSet; } return $chartData; @@ -134,4 +146,4 @@ class ChartJsGenerator implements GeneratorInterface return $chartData; } -} \ No newline at end of file +} diff --git a/app/Generator/Chart/Basic/GeneratorInterface.php b/app/Generator/Chart/Basic/GeneratorInterface.php index 8299851822..8b4b90af8a 100644 --- a/app/Generator/Chart/Basic/GeneratorInterface.php +++ b/app/Generator/Chart/Basic/GeneratorInterface.php @@ -70,4 +70,4 @@ interface GeneratorInterface */ public function singleSet(string $setLabel, array $data): array; -} \ No newline at end of file +} diff --git a/app/Generator/Report/Audit/MonthReportGenerator.php b/app/Generator/Report/Audit/MonthReportGenerator.php index cc31219d9e..a5f30e9a10 100644 --- a/app/Generator/Report/Audit/MonthReportGenerator.php +++ b/app/Generator/Report/Audit/MonthReportGenerator.php @@ -153,4 +153,4 @@ class MonthReportGenerator implements ReportGeneratorInterface return $this; } -} \ No newline at end of file +} diff --git a/app/Generator/Report/Audit/MultiYearReportGenerator.php b/app/Generator/Report/Audit/MultiYearReportGenerator.php index 6d9e2857b8..f8baa6e66f 100644 --- a/app/Generator/Report/Audit/MultiYearReportGenerator.php +++ b/app/Generator/Report/Audit/MultiYearReportGenerator.php @@ -24,4 +24,4 @@ class MultiYearReportGenerator extends MonthReportGenerator /** * Doesn't do anything different. */ -} \ No newline at end of file +} diff --git a/app/Generator/Report/Audit/YearReportGenerator.php b/app/Generator/Report/Audit/YearReportGenerator.php index 915aef0d4a..b44bae8820 100644 --- a/app/Generator/Report/Audit/YearReportGenerator.php +++ b/app/Generator/Report/Audit/YearReportGenerator.php @@ -25,4 +25,4 @@ class YearReportGenerator extends MonthReportGenerator /** * Doesn't do anything different. */ -} \ No newline at end of file +} diff --git a/app/Generator/Report/Budget/MonthReportGenerator.php b/app/Generator/Report/Budget/MonthReportGenerator.php index a2512f3a72..085fb9bfe8 100644 --- a/app/Generator/Report/Budget/MonthReportGenerator.php +++ b/app/Generator/Report/Budget/MonthReportGenerator.php @@ -244,4 +244,4 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface return $result; } -} \ No newline at end of file +} diff --git a/app/Generator/Report/Budget/MultiYearReportGenerator.php b/app/Generator/Report/Budget/MultiYearReportGenerator.php index 3d92def9f3..b3820f88dd 100644 --- a/app/Generator/Report/Budget/MultiYearReportGenerator.php +++ b/app/Generator/Report/Budget/MultiYearReportGenerator.php @@ -24,4 +24,4 @@ class MultiYearReportGenerator extends MonthReportGenerator /** * Doesn't do anything different. */ -} \ No newline at end of file +} diff --git a/app/Generator/Report/Budget/YearReportGenerator.php b/app/Generator/Report/Budget/YearReportGenerator.php index 0f76de9b07..30f51e599c 100644 --- a/app/Generator/Report/Budget/YearReportGenerator.php +++ b/app/Generator/Report/Budget/YearReportGenerator.php @@ -25,4 +25,4 @@ class YearReportGenerator extends MonthReportGenerator /** * Doesn't do anything different. */ -} \ No newline at end of file +} diff --git a/app/Generator/Report/Category/MonthReportGenerator.php b/app/Generator/Report/Category/MonthReportGenerator.php index 410fd29346..53aa790e28 100644 --- a/app/Generator/Report/Category/MonthReportGenerator.php +++ b/app/Generator/Report/Category/MonthReportGenerator.php @@ -325,4 +325,4 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface return $result; } -} \ No newline at end of file +} diff --git a/app/Generator/Report/Category/MultiYearReportGenerator.php b/app/Generator/Report/Category/MultiYearReportGenerator.php index 2f663c3925..62b0e32af9 100644 --- a/app/Generator/Report/Category/MultiYearReportGenerator.php +++ b/app/Generator/Report/Category/MultiYearReportGenerator.php @@ -24,4 +24,4 @@ class MultiYearReportGenerator extends MonthReportGenerator /** * Doesn't do anything different. */ -} \ No newline at end of file +} diff --git a/app/Generator/Report/Category/YearReportGenerator.php b/app/Generator/Report/Category/YearReportGenerator.php index 038ab47ed6..a118c4c5b0 100644 --- a/app/Generator/Report/Category/YearReportGenerator.php +++ b/app/Generator/Report/Category/YearReportGenerator.php @@ -25,4 +25,4 @@ class YearReportGenerator extends MonthReportGenerator /** * Doesn't do anything different. */ -} \ No newline at end of file +} diff --git a/app/Generator/Report/ReportGeneratorFactory.php b/app/Generator/Report/ReportGeneratorFactory.php index 0323d56c46..9dbf45ed43 100644 --- a/app/Generator/Report/ReportGeneratorFactory.php +++ b/app/Generator/Report/ReportGeneratorFactory.php @@ -57,4 +57,4 @@ class ReportGeneratorFactory } throw new FireflyException(sprintf('Cannot generate report. There is no "%s"-report for period "%s".', $type, $period)); } -} \ No newline at end of file +} diff --git a/app/Generator/Report/ReportGeneratorInterface.php b/app/Generator/Report/ReportGeneratorInterface.php index ad46c0646a..593d318f10 100644 --- a/app/Generator/Report/ReportGeneratorInterface.php +++ b/app/Generator/Report/ReportGeneratorInterface.php @@ -64,4 +64,4 @@ interface ReportGeneratorInterface */ public function setStartDate(Carbon $date): ReportGeneratorInterface; -} \ No newline at end of file +} diff --git a/app/Generator/Report/Standard/MonthReportGenerator.php b/app/Generator/Report/Standard/MonthReportGenerator.php index 5905e12815..113b777c91 100644 --- a/app/Generator/Report/Standard/MonthReportGenerator.php +++ b/app/Generator/Report/Standard/MonthReportGenerator.php @@ -106,4 +106,4 @@ class MonthReportGenerator implements ReportGeneratorInterface return $this; } -} \ No newline at end of file +} diff --git a/app/Generator/Report/Standard/MultiYearReportGenerator.php b/app/Generator/Report/Standard/MultiYearReportGenerator.php index 3437283426..5dab371d6b 100644 --- a/app/Generator/Report/Standard/MultiYearReportGenerator.php +++ b/app/Generator/Report/Standard/MultiYearReportGenerator.php @@ -103,4 +103,4 @@ class MultiYearReportGenerator implements ReportGeneratorInterface return $this; } -} \ No newline at end of file +} diff --git a/app/Generator/Report/Standard/YearReportGenerator.php b/app/Generator/Report/Standard/YearReportGenerator.php index 545084909f..f3297e35df 100644 --- a/app/Generator/Report/Standard/YearReportGenerator.php +++ b/app/Generator/Report/Standard/YearReportGenerator.php @@ -103,4 +103,4 @@ class YearReportGenerator implements ReportGeneratorInterface return $this; } -} \ No newline at end of file +} diff --git a/app/Generator/Report/Support.php b/app/Generator/Report/Support.php index 56ee7e981c..1f71ad182a 100644 --- a/app/Generator/Report/Support.php +++ b/app/Generator/Report/Support.php @@ -88,4 +88,4 @@ class Support return $result; } -} \ No newline at end of file +} diff --git a/app/Helpers/Collector/JournalCollector.php b/app/Helpers/Collector/JournalCollector.php index 76f66a0019..c874c9949e 100644 --- a/app/Helpers/Collector/JournalCollector.php +++ b/app/Helpers/Collector/JournalCollector.php @@ -60,6 +60,7 @@ class JournalCollector implements JournalCollectorInterface 'transaction_types.type as transaction_type_type', 'transaction_journals.bill_id', 'bills.name as bill_name', + 'bills.name_encrypted as bill_name_encrypted', 'transactions.id as id', 'transactions.amount as transaction_amount', 'transactions.description as transaction_description', @@ -180,10 +181,12 @@ class JournalCollector implements JournalCollectorInterface $set->each( function (Transaction $transaction) { $transaction->date = new Carbon($transaction->date); - $transaction->description = intval($transaction->encrypted) === 1 ? Crypt::decrypt($transaction->description) : $transaction->description; - $transaction->bill_name = !is_null($transaction->bill_name) ? Crypt::decrypt($transaction->bill_name) : ''; + $transaction->description = $transaction->encrypted ? Crypt::decrypt($transaction->description) : $transaction->description; + + if (!is_null($transaction->bill_name)) { + $transaction->bill_name = $transaction->bill_name_encrypted ? Crypt::decrypt($transaction->bill_name) : $transaction->bill_name; + } - // optionally decrypted: try { $transaction->opposing_account_name = Crypt::decrypt($transaction->opposing_account_name); } catch (DecryptException $e) { @@ -726,4 +729,4 @@ class JournalCollector implements JournalCollectorInterface return $query; } -} \ No newline at end of file +} diff --git a/app/Helpers/Collector/JournalCollectorInterface.php b/app/Helpers/Collector/JournalCollectorInterface.php index 320fcab93b..b3307ebac0 100644 --- a/app/Helpers/Collector/JournalCollectorInterface.php +++ b/app/Helpers/Collector/JournalCollectorInterface.php @@ -173,4 +173,4 @@ interface JournalCollectorInterface * @return JournalCollectorInterface */ public function withoutCategory(): JournalCollectorInterface; -} \ No newline at end of file +} diff --git a/app/Helpers/Report/BalanceReportHelper.php b/app/Helpers/Report/BalanceReportHelper.php index acd623a2a9..18cdd71acc 100644 --- a/app/Helpers/Report/BalanceReportHelper.php +++ b/app/Helpers/Report/BalanceReportHelper.php @@ -26,6 +26,7 @@ use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use Illuminate\Database\Query\JoinClause; use Illuminate\Support\Collection; +use Log; /** * Class BalanceReportHelper @@ -59,19 +60,23 @@ class BalanceReportHelper implements BalanceReportHelperInterface */ public function getBalanceReport(Collection $accounts, Carbon $start, Carbon $end): Balance { + Log::debug('Start of balance report'); $balance = new Balance; $header = new BalanceHeader; $limitRepetitions = $this->budgetRepository->getAllBudgetLimitRepetitions($start, $end); foreach ($accounts as $account) { + Log::debug(sprintf('Add account %s to headers.', $account->name)); $header->addAccount($account); } /** @var LimitRepetition $repetition */ foreach ($limitRepetitions as $repetition) { $budget = $this->budgetRepository->find($repetition->budget_id); - $line = $this->createBalanceLine($budget, $repetition, $accounts); + Log::debug(sprintf('Create balance line for budget #%d ("%s") and repetition #%d', $budget->id, $budget->name, $repetition->id)); + $line = $this->createBalanceLine($budget, $repetition, $accounts); $balance->addBalanceLine($line); } + Log::debug('Create rest of the things.'); $noBudgetLine = $this->createNoBudgetLine($accounts, $start, $end); $coveredByTagLine = $this->createTagsBalanceLine($accounts, $start, $end); $leftUnbalancedLine = $this->createLeftUnbalancedLine($noBudgetLine, $coveredByTagLine); @@ -81,9 +86,12 @@ class BalanceReportHelper implements BalanceReportHelperInterface $balance->addBalanceLine($leftUnbalancedLine); $balance->setBalanceHeader($header); + Log::debug('Clear unused budgets.'); // remove budgets without expenses from balance lines: $balance = $this->removeUnusedBudgets($balance); + Log::debug('Return report.'); + return $balance; } diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 2372e7e101..eea03cbac5 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -124,17 +124,24 @@ class AccountController extends Controller */ public function destroy(ARI $repository, Account $account) { - $type = $account->accountType->type; - $typeName = config('firefly.shortNamesByFullName.' . $type); - $name = $account->name; - $moveTo = $repository->find(intval(Input::get('move_account_before_delete'))); + $type = $account->accountType->type; + $typeName = config('firefly.shortNamesByFullName.' . $type); + $name = $account->name; + $accountId = $account->id; + $moveTo = $repository->find(intval(Input::get('move_account_before_delete'))); $repository->destroy($account, $moveTo); Session::flash('success', strval(trans('firefly.' . $typeName . '_deleted', ['name' => $name]))); Preferences::mark(); - return redirect(session('accounts.delete.url')); + $uri = session('accounts.delete.url'); + if (!(strpos($uri, sprintf('accounts/show/%s', $accountId)) === false)) { + // uri would point back to account + $uri = route('accounts.index', [$typeName]); + } + + return redirect($uri); } /** @@ -192,8 +199,7 @@ class AccountController extends Controller */ public function index(ARI $repository, string $what) { - $what = $what ?? 'asset'; - + $what = $what ?? 'asset'; $subTitle = trans('firefly.' . $what . '_accounts'); $subTitleIcon = config('firefly.subIconsByIdentifier.' . $what); $types = config('firefly.accountTypesByIdentifier.' . $what); @@ -214,6 +220,7 @@ class AccountController extends Controller $account->lastActivityDate = $this->isInArray($activities, $account->id); $account->startBalance = $this->isInArray($startBalances, $account->id); $account->endBalance = $this->isInArray($endBalances, $account->id); + $account->difference = bcsub($account->endBalance, $account->startBalance); } ); @@ -235,12 +242,12 @@ class AccountController extends Controller $subTitleIcon = config('firefly.subIconsByIdentifier.' . $account->accountType->type); $subTitle = $account->name; $range = Preferences::get('viewRange', '1M')->data; - $start = session('start', Navigation::startOfPeriod(new Carbon, $range)); $end = session('end', Navigation::endOfPeriod(new Carbon, $range)); $page = intval(Input::get('page')) === 0 ? 1 : intval(Input::get('page')); $pageSize = intval(Preferences::get('transactionPageSize', 50)->data); $chartUri = route('chart.account.single', [$account->id]); + // grab those journals: $collector->setAccounts(new Collection([$account]))->setRange($start, $end)->setLimit($pageSize)->setPage($page); $journals = $collector->getPaginatedJournals(); @@ -379,7 +386,7 @@ class AccountController extends Controller return $array[$entryId]; } - return ''; + return '0'; } /** diff --git a/app/Http/Controllers/AttachmentController.php b/app/Http/Controllers/AttachmentController.php index 126a689b3d..8cf513f267 100644 --- a/app/Http/Controllers/AttachmentController.php +++ b/app/Http/Controllers/AttachmentController.php @@ -95,16 +95,12 @@ class AttachmentController extends Controller * @throws FireflyException * */ - public function download(Attachment $attachment) + public function download(AttachmentRepositoryInterface $repository, Attachment $attachment) { - // create a disk. - $disk = Storage::disk('upload'); - $file = $attachment->fileName(); - - if ($disk->exists($file)) { - + if ($repository->exists($attachment)) { + $content = $repository->getContent($attachment); $quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\')); - $content = Crypt::decrypt($disk->get($file)); + Log::debug('Send file to user', ['file' => $quoted, 'size' => strlen($content)]); @@ -118,8 +114,8 @@ class AttachmentController extends Controller ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') ->header('Pragma', 'public') ->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/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php old mode 100755 new mode 100644 index 7d6e12b3fc..1b95f56d44 --- a/app/Http/Controllers/Auth/ForgotPasswordController.php +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -13,7 +13,9 @@ declare(strict_types = 1); namespace FireflyIII\Http\Controllers\Auth; use FireflyIII\Http\Controllers\Controller; +use FireflyIII\User; use Illuminate\Foundation\Auth\SendsPasswordResetEmails; +use Illuminate\Http\Request; /** * Class ForgotPasswordController @@ -33,4 +35,39 @@ class ForgotPasswordController extends Controller parent::__construct(); $this->middleware('guest'); } + + /** + * Send a reset link to the given user. + * + * @param Request $request + * + * @return \Illuminate\Http\RedirectResponse + */ + public function sendResetLinkEmail(Request $request) + { + $this->validate($request, ['email' => 'required|email']); + + // verify if the user is not a demo user. If so, we give him back an error. + $user = User::where('email', $request->get('email'))->first(); + if (!is_null($user) && $user->hasRole('demo')) { + return back()->withErrors( + ['email' => trans('firefly.cannot_reset_demo_user')] + ); + } + + $response = $this->broker()->sendResetLink( + $request->only('email') + ); + + if ($response === Password::RESET_LINK_SENT) { + return back()->with('status', trans($response)); + } + + // If an error was returned by the password broker, we will get this message + // translated so we can notify a user of the problem. We'll redirect back + // to where the users came from so they can attempt this process again. + return back()->withErrors( + ['email' => trans($response)] + ); + } } diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php old mode 100755 new mode 100644 index 06faf92d07..4eb2782162 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -53,9 +53,9 @@ class LoginController extends Controller /** * Handle a login request to the application. * - * @param \Illuminate\Http\Request $request + * @param Request $request * - * @return \Illuminate\Http\Response + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response */ public function login(Request $request) { diff --git a/app/Http/Controllers/Auth/PasswordController.php b/app/Http/Controllers/Auth/PasswordController.php index 02a4757bc2..f49857ba67 100644 --- a/app/Http/Controllers/Auth/PasswordController.php +++ b/app/Http/Controllers/Auth/PasswordController.php @@ -26,8 +26,8 @@ use Illuminate\Support\Facades\Password; * * @package FireflyIII\Http\Controllers\Auth * @method getEmailSubject() - * @method getSendResetLinkEmailSuccessResponse() - * @method getSendResetLinkEmailFailureResponse() + * @method getSendResetLinkEmailSuccessResponse(string $response) + * @method getSendResetLinkEmailFailureResponse(string $response) */ class PasswordController extends Controller { diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php old mode 100755 new mode 100644 index b56978153a..23deaaf46d --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -22,11 +22,8 @@ use FireflyIII\Http\Controllers\Controller; use FireflyIII\User; use Illuminate\Foundation\Auth\RegistersUsers; use Illuminate\Http\Request; -use Illuminate\Mail\Message; use Log; -use Mail; use Session; -use Swift_TransportException; use Validator; /** diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php old mode 100755 new mode 100644 diff --git a/app/Http/Controllers/BillController.php b/app/Http/Controllers/BillController.php index 4cccbdeba3..5e3b3a09ef 100644 --- a/app/Http/Controllers/BillController.php +++ b/app/Http/Controllers/BillController.php @@ -99,13 +99,20 @@ class BillController extends Controller */ public function destroy(BillRepositoryInterface $repository, Bill $bill) { - $name = $bill->name; + $name = $bill->name; + $billId = $bill->id; $repository->destroy($bill); Session::flash('success', strval(trans('firefly.deleted_bill', ['name' => $name]))); Preferences::mark(); - return redirect(session('bills.delete.url')); + $uri = session('bills.delete.url'); + if (!(strpos($uri, sprintf('bills/show/%s', $billId)) === false)) { + // uri would point back to bill + $uri = route('bills.index'); + } + + return redirect($uri); } /** diff --git a/app/Http/Controllers/BudgetController.php b/app/Http/Controllers/BudgetController.php index 9605e0b8c6..77d6ecb164 100644 --- a/app/Http/Controllers/BudgetController.php +++ b/app/Http/Controllers/BudgetController.php @@ -15,10 +15,10 @@ namespace FireflyIII\Http\Controllers; use Amount; use Carbon\Carbon; -use Config; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Helpers\Collector\JournalCollector; use FireflyIII\Http\Requests\BudgetFormRequest; +use FireflyIII\Http\Requests\BudgetIncomeRequest; use FireflyIII\Models\AccountType; use FireflyIII\Models\Budget; use FireflyIII\Models\LimitRepetition; @@ -26,8 +26,6 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use Illuminate\Support\Collection; use Input; -use Log; -use Navigation; use Preferences; use Response; use Session; @@ -42,6 +40,9 @@ use View; class BudgetController extends Controller { + /** @var BudgetRepositoryInterface */ + private $repository; + /** * */ @@ -55,6 +56,7 @@ class BudgetController extends Controller function ($request, $next) { View::share('title', trans('firefly.budgets')); View::share('mainTitleIcon', 'fa-tasks'); + $this->repository = app(BudgetRepositoryInterface::class); return $next($request); } @@ -73,21 +75,15 @@ class BudgetController extends Controller /** @var Carbon $start */ $start = session('start', Carbon::now()->startOfMonth()); /** @var Carbon $end */ - $end = session('end', Carbon::now()->endOfMonth()); - $viewRange = Preferences::get('viewRange', '1M')->data; - - // is custom view range? - if (session('is_custom_range') === true) { - $viewRange = 'custom'; - } - + $end = session('end', Carbon::now()->endOfMonth()); + $viewRange = Preferences::get('viewRange', '1M')->data; $limitRepetition = $repository->updateLimitAmount($budget, $start, $end, $viewRange, $amount); if ($amount == 0) { $limitRepetition = null; } Preferences::mark(); - return Response::json(['name' => $budget->name, 'repetition' => $limitRepetition ? $limitRepetition->id : 0]); + return Response::json(['name' => $budget->name, 'repetition' => $limitRepetition ? $limitRepetition->id : 0, 'amount' => $amount]); } @@ -134,15 +130,21 @@ class BudgetController extends Controller public function destroy(Budget $budget, BudgetRepositoryInterface $repository) { - $name = $budget->name; + $name = $budget->name; + $budgetId = $budget->id; $repository->destroy($budget); Session::flash('success', strval(trans('firefly.deleted_budget', ['name' => e($name)]))); Preferences::mark(); + $uri = session('budgets.delete.url'); + if (!(strpos($uri, sprintf('budgets/show/%s', $budgetId)) === false)) { + // uri would point back to budget + $uri = route('budgets.index'); + } - return redirect(session('budgets.delete.url')); + return redirect($uri); } /** @@ -167,82 +169,27 @@ class BudgetController extends Controller } /** - * @param BudgetRepositoryInterface $repository - * @param AccountRepositoryInterface $accountRepository - * * @return View - * */ - public function index(BudgetRepositoryInterface $repository, AccountRepositoryInterface $accountRepository) + public function index() { - $repository->cleanupBudgets(); + $this->repository->cleanupBudgets(); - $budgets = $repository->getActiveBudgets(); - $inactive = $repository->getInactiveBudgets(); - $spent = '0'; - $budgeted = '0'; - $range = Preferences::get('viewRange', '1M')->data; - $repeatFreq = Config::get('firefly.range_to_repeat_freq.' . $range); - - if (session('is_custom_range') === true) { - $repeatFreq = 'custom'; - } - - /** @var Carbon $start */ - $start = session('start', new Carbon); - /** @var Carbon $end */ + $budgets = $this->repository->getActiveBudgets(); + $inactive = $this->repository->getInactiveBudgets(); + $start = session('start', new Carbon); $end = session('end', new Carbon); - $key = 'budgetIncomeTotal' . $start->format('Ymd') . $end->format('Ymd'); - $budgetIncomeTotal = Preferences::get($key, 1000)->data; - $period = Navigation::periodShow($start, $range); $periodStart = $start->formatLocalized($this->monthAndDayFormat); $periodEnd = $end->formatLocalized($this->monthAndDayFormat); - $accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::CASH]); - $startAsString = $start->format('Y-m-d'); - $endAsString = $end->format('Y-m-d'); - Log::debug('Now at /budgets'); - - // loop the budgets: - /** @var Budget $budget */ - foreach ($budgets as $budget) { - Log::debug(sprintf('Now at budget #%d ("%s")', $budget->id, $budget->name)); - $budget->spent = $repository->spentInPeriod(new Collection([$budget]), $accounts, $start, $end); - $allRepetitions = $repository->getAllBudgetLimitRepetitions($start, $end); - $otherRepetitions = new Collection; - - /** @var LimitRepetition $repetition */ - foreach ($allRepetitions as $repetition) { - if ($repetition->budget_id == $budget->id) { - if ($repetition->budgetLimit->repeat_freq == $repeatFreq - && $repetition->startdate->format('Y-m-d') == $startAsString - && $repetition->enddate->format('Y-m-d') == $endAsString - ) { - // do something - $budget->currentRep = $repetition; - continue; - } - $otherRepetitions->push($repetition); - } - } - $budget->otherRepetitions = $otherRepetitions; - - if (!is_null($budget->currentRep) && !is_null($budget->currentRep->id)) { - $budgeted = bcadd($budgeted, $budget->currentRep->amount); - } - $spent = bcadd($spent, $budget->spent); - - } - - - $defaultCurrency = Amount::getDefaultCurrency(); + $budgetInformation = $this->collectBudgetInformation($budgets, $start, $end); + $defaultCurrency = Amount::getDefaultCurrency(); + $available = $this->repository->getAvailableBudget($defaultCurrency, $start, $end); + $spent = array_sum(array_column($budgetInformation, 'spent')); + $budgeted = array_sum(array_column($budgetInformation, 'budgeted')); return view( - 'budgets.index', compact( - 'periodStart', 'periodEnd', - 'period', 'range', 'budgetIncomeTotal', - 'defaultCurrency', 'inactive', 'budgets', - 'spent', 'budgeted' - ) + 'budgets.index', + compact('available', 'periodStart', 'periodEnd', 'budgetInformation', 'defaultCurrency', 'inactive', 'budgets', 'spent', 'budgeted') ); } @@ -274,16 +221,14 @@ class BudgetController extends Controller /** * @return \Illuminate\Http\RedirectResponse */ - public function postUpdateIncome() + public function postUpdateIncome(BudgetIncomeRequest $request) { - $range = Preferences::get('viewRange', '1M')->data; - /** @var Carbon $date */ - $date = session('start', new Carbon); - $start = Navigation::startOfPeriod($date, $range); - $end = Navigation::endOfPeriod($start, $range); - $key = 'budgetIncomeTotal' . $start->format('Ymd') . $end->format('Ymd'); + $start = session('start', new Carbon); + $end = session('end', new Carbon); + $defaultCurrency = Amount::getDefaultCurrency(); + $amount = $request->get('amount'); - Preferences::set($key, intval(Input::get('amount'))); + $this->repository->setAvailableBudget($defaultCurrency, $start, $end, $amount); Preferences::mark(); return redirect(route('budgets.index')); @@ -424,19 +369,57 @@ class BudgetController extends Controller */ public function updateIncome() { - $range = Preferences::get('viewRange', '1M')->data; - $format = strval(trans('config.month_and_day')); + $start = session('start', new Carbon); + $end = session('end', new Carbon); + $defaultCurrency = Amount::getDefaultCurrency(); + $available = $this->repository->getAvailableBudget($defaultCurrency, $start, $end); - /** @var Carbon $date */ - $date = session('start', new Carbon); - $start = Navigation::startOfPeriod($date, $range); - $end = Navigation::endOfPeriod($start, $range); - $key = 'budgetIncomeTotal' . $start->format('Ymd') . $end->format('Ymd'); - $amount = Preferences::get($key, 1000); - $displayStart = $start->formatLocalized($format); - $displayEnd = $end->formatLocalized($format); - return view('budgets.income', compact('amount', 'displayStart', 'displayEnd')); + return view('budgets.income', compact('available', 'start', 'end')); + } + + /** + * @param Collection $budgets + * @param Carbon $start + * @param Carbon $end + * + * @return array + */ + private function collectBudgetInformation(Collection $budgets, Carbon $start, Carbon $end): array + { + // get account information + $accountRepository = app(AccountRepositoryInterface::class); + $accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::CASH]); + $return = []; + /** @var Budget $budget */ + foreach ($budgets as $budget) { + $budgetId = $budget->id; + $return[$budgetId] = [ + 'spent' => $this->repository->spentInPeriod(new Collection([$budget]), $accounts, $start, $end), + 'budgeted' => '0', + 'currentRep' => false, + ]; + $allRepetitions = $this->repository->getAllBudgetLimitRepetitions($start, $end); + $otherRepetitions = new Collection; + + // get all the limit repetitions relevant between start and end and examine them: + /** @var LimitRepetition $repetition */ + foreach ($allRepetitions as $repetition) { + if ($repetition->budget_id == $budget->id) { + if ($repetition->startdate->isSameDay($start) && $repetition->enddate->isSameDay($end) + ) { + $return[$budgetId]['currentRep'] = $repetition; + $return[$budgetId]['budgeted'] = $repetition->amount; + continue; + } + // otherwise it's just one of the many relevant repetitions: + $otherRepetitions->push($repetition); + } + } + $return[$budgetId]['otherRepetitions'] = $otherRepetitions; + } + + return $return; } } diff --git a/app/Http/Controllers/CategoryController.php b/app/Http/Controllers/CategoryController.php index e832f3245d..4d7a67e64c 100644 --- a/app/Http/Controllers/CategoryController.php +++ b/app/Http/Controllers/CategoryController.php @@ -98,13 +98,20 @@ class CategoryController extends Controller public function destroy(CRI $repository, Category $category) { - $name = $category->name; + $name = $category->name; + $categoryId = $category->id; $repository->destroy($category); Session::flash('success', strval(trans('firefly.deleted_category', ['name' => e($name)]))); Preferences::mark(); - return redirect(session('categories.delete.url')); + $uri = session('categories.delete.url'); + if (!(strpos($uri, sprintf('categories/show/%s', $categoryId)) === false)) { + // uri would point back to category + $uri = route('categories.index'); + } + + return redirect($uri); } /** @@ -262,7 +269,6 @@ class CategoryController extends Controller $journals = $collector->getPaginatedJournals(); $journals->setPath('categories/show/' . $category->id . '/' . $date); - return view('categories.show-by-date', compact('category', 'journals', 'hideCategory', 'subTitle', 'carbon')); } diff --git a/app/Http/Controllers/Chart/BudgetController.php b/app/Http/Controllers/Chart/BudgetController.php index 4fcb736e0f..aa9a737336 100644 --- a/app/Http/Controllers/Chart/BudgetController.php +++ b/app/Http/Controllers/Chart/BudgetController.php @@ -204,7 +204,7 @@ class BudgetController extends Controller } // for no budget: $row = $this->spentInPeriodWithout($start, $end); - if (bccomp($row['spent'], '0') !== 0 || bccomp($row['repetition_left'], '0') !== 0) { + if (bccomp($row['repetition_overspent'], '0') !== 0) { $chartData[0]['entries'][$row['name']] = bcmul($row['spent'], '-1'); $chartData[1]['entries'][$row['name']] = $row['repetition_left']; $chartData[2]['entries'][$row['name']] = bcmul($row['repetition_overspent'], '-1'); @@ -284,8 +284,8 @@ class BudgetController extends Controller foreach (array_keys($periods) as $period) { $label = $periods[$period]; $spent = isset($entries[$budget->id]['entries'][$period]) ? $entries[$budget->id]['entries'][$period] : '0'; - $limit = isset($entries[$period]) ? $budgeted[$period] : 0; - $chartData[0]['entries'][$label] = bcmul($spent, '-1'); + $limit = isset($budgeted[$period]) ? $budgeted[$period] : 0; + $chartData[0]['entries'][$label] = round(bcmul($spent, '-1'), 2); $chartData[1]['entries'][$label] = $limit; } @@ -386,7 +386,7 @@ class BudgetController extends Controller } $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; + $spent = $expenses; $overspent = bccomp(bcadd($amount, $expenses), '0') < 1 ? bcadd($amount, $expenses) : '0'; $return[] = [ 'name' => $name, @@ -454,8 +454,8 @@ class BudgetController extends Controller $array = [ 'name' => strval(trans('firefly.no_budget')), 'repetition_left' => '0', - 'repetition_overspent' => '0', - 'spent' => $sum, + 'repetition_overspent' => $sum, + 'spent' => '0', ]; return $array; diff --git a/app/Http/Controllers/Chart/BudgetReportController.php b/app/Http/Controllers/Chart/BudgetReportController.php index e053189066..5ba5e9dd0e 100644 --- a/app/Http/Controllers/Chart/BudgetReportController.php +++ b/app/Http/Controllers/Chart/BudgetReportController.php @@ -20,16 +20,17 @@ use FireflyIII\Generator\Report\Category\MonthReportGenerator; use FireflyIII\Helpers\Collector\JournalCollector; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Models\Budget; +use FireflyIII\Models\LimitRepetition; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Support\CacheProperties; use Illuminate\Support\Collection; +use Log; use Navigation; use Response; - /** * Separate controller because many helper functions are shared. * @@ -83,6 +84,7 @@ class BudgetReportController extends Controller $cache->addProperty($budgets); $cache->addProperty($start); $cache->addProperty($end); + $cache->addProperty($others); if ($cache->has()) { return Response::json($cache->get()); } @@ -139,6 +141,7 @@ class BudgetReportController extends Controller $cache->addProperty($budgets); $cache->addProperty($start); $cache->addProperty($end); + $cache->addProperty($others); if ($cache->has()) { return Response::json($cache->get()); } @@ -195,21 +198,39 @@ class BudgetReportController extends Controller if ($cache->has()) { return Response::json($cache->get()); } - + /** @var BudgetRepositoryInterface $repository */ + $repository = app(BudgetRepositoryInterface::class); $format = Navigation::preferredCarbonLocalizedFormat($start, $end); $function = Navigation::preferredEndOfPeriod($start, $end); $chartData = []; $currentStart = clone $start; + $limits = $repository->getAllBudgetLimitRepetitions($start, $end); // also for ALL budgets. // prep chart data: foreach ($budgets as $budget) { - $chartData[$budget->id] = [ - 'label' => $budget->name, + $chartData[$budget->id] = [ + 'label' => strval(trans('firefly.spent_in_specific_budget', ['budget' => $budget->name])), 'type' => 'bar', + 'yAxisID' => 'y-axis-0', + 'entries' => [], + ]; + $chartData[$budget->id . '-sum'] = [ + 'label' => strval(trans('firefly.sum_of_expenses_in_budget', ['budget' => $budget->name])), + 'type' => 'line', + 'fill' => false, + 'yAxisID' => 'y-axis-1', + 'entries' => [], + ]; + $chartData[$budget->id . '-left'] = [ + 'label' => strval(trans('firefly.left_in_budget_limit', ['budget' => $budget->name])), + 'type' => 'bar', + 'fill' => false, + 'yAxisID' => 'y-axis-0', 'entries' => [], ]; } - + $sumOfExpenses = []; + $leftOfLimits = []; while ($currentStart < $end) { $currentEnd = clone $currentStart; $currentEnd = $currentEnd->$function(); @@ -218,7 +239,20 @@ class BudgetReportController extends Controller /** @var Budget $budget */ foreach ($budgets as $budget) { - $chartData[$budget->id]['entries'][$label] = $expenses[$budget->id] ?? '0'; + $currentExpenses = $expenses[$budget->id] ?? '0'; + $sumOfExpenses[$budget->id] = $sumOfExpenses[$budget->id] ?? '0'; + $sumOfExpenses[$budget->id] = bcadd($currentExpenses, $sumOfExpenses[$budget->id]); + $chartData[$budget->id]['entries'][$label] = round(bcmul($currentExpenses, '-1'), 2); + $chartData[$budget->id . '-sum']['entries'][$label] = round(bcmul($sumOfExpenses[$budget->id], '-1'), 2); + + $limit = $this->filterLimits($limits, $budget, $currentStart); + if (!is_null($limit->id)) { + $leftOfLimits[$limit->id] = $leftOfLimits[$limit->id] ?? strval($limit->amount); + $leftOfLimits[$limit->id] = bcadd($leftOfLimits[$limit->id], $currentExpenses); + $chartData[$budget->id . '-left']['entries'][$label] = round($leftOfLimits[$limit->id], 2); + } + + } $currentStart = clone $currentEnd; $currentStart->addDay(); @@ -230,6 +264,44 @@ class BudgetReportController extends Controller return Response::json($data); } + /** + * @param $limits + * @param $budget + * @param $currentStart + * + * @return LimitRepetition + */ + private function filterLimits(Collection $limits, Budget $budget, Carbon $date): LimitRepetition + { + Log::debug(sprintf('Start of filterLimits with %d limits.', $limits->count())); + $filtered = $limits->filter( + function (LimitRepetition $limit) use ($budget, $date) { + if ($limit->budget_id !== $budget->id) { + Log::debug(sprintf('LimitRepetition has budget #%d but expecting #%d', $limit->budget_id, $budget->id)); + + return false; + } + if ($date < $limit->startdate || $date > $limit->enddate) { + Log::debug( + sprintf( + 'Date %s is not between %s and %s', + $date->format('Y-m-d'), $limit->startdate->format('Y-m-d'), $limit->enddate->format('Y-m-d') + ) + ); + + return false; + } + + return $limit; + } + ); + if ($filtered->count() === 1) { + return $filtered->first(); + } + + return new LimitRepetition; + } + /** * @param Collection $accounts @@ -289,4 +361,4 @@ class BudgetReportController extends Controller return $grouped; } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/Chart/CategoryReportController.php b/app/Http/Controllers/Chart/CategoryReportController.php index 003648218c..be76c938a4 100644 --- a/app/Http/Controllers/Chart/CategoryReportController.php +++ b/app/Http/Controllers/Chart/CategoryReportController.php @@ -83,6 +83,7 @@ class CategoryReportController extends Controller $cache->addProperty($categories); $cache->addProperty($start); $cache->addProperty($end); + $cache->addProperty($others); if ($cache->has()) { return Response::json($cache->get()); } @@ -138,6 +139,7 @@ class CategoryReportController extends Controller $cache->addProperty($accounts); $cache->addProperty($categories); $cache->addProperty($start); + $cache->addProperty($others); $cache->addProperty($end); if ($cache->has()) { return Response::json($cache->get()); @@ -194,6 +196,7 @@ class CategoryReportController extends Controller $cache->addProperty($categories); $cache->addProperty($start); $cache->addProperty($end); + $cache->addProperty($others); if ($cache->has()) { return Response::json($cache->get()); } @@ -250,6 +253,7 @@ class CategoryReportController extends Controller $cache->addProperty($categories); $cache->addProperty($start); $cache->addProperty($end); + $cache->addProperty($others); if ($cache->has()) { return Response::json($cache->get()); } @@ -314,14 +318,33 @@ class CategoryReportController extends Controller $chartData[$category->id . '-in'] = [ 'label' => $category->name . ' (' . strtolower(strval(trans('firefly.income'))) . ')', 'type' => 'bar', + 'yAxisID' => 'y-axis-0', 'entries' => [], ]; $chartData[$category->id . '-out'] = [ 'label' => $category->name . ' (' . strtolower(strval(trans('firefly.expenses'))) . ')', 'type' => 'bar', + 'yAxisID' => 'y-axis-0', + 'entries' => [], + ]; + // total in, total out: + $chartData[$category->id . '-total-in'] = [ + 'label' => $category->name . ' (' . strtolower(strval(trans('firefly.sum_of_income'))) . ')', + 'type' => 'line', + 'fill' => false, + 'yAxisID' => 'y-axis-1', + 'entries' => [], + ]; + $chartData[$category->id . '-total-out'] = [ + 'label' => $category->name . ' (' . strtolower(strval(trans('firefly.sum_of_expenses'))) . ')', + 'type' => 'line', + 'fill' => false, + 'yAxisID' => 'y-axis-1', 'entries' => [], ]; } + $sumOfIncome = []; + $sumOfExpense = []; while ($currentStart < $end) { $currentEnd = clone $currentStart; @@ -332,17 +355,40 @@ class CategoryReportController extends Controller /** @var Category $category */ foreach ($categories as $category) { - $labelIn = $category->id . '-in'; - $labelOut = $category->id . '-out'; - // get sum, and get label: - $chartData[$labelIn]['entries'][$label] = $income[$category->id] ?? '0'; - $chartData[$labelOut]['entries'][$label] = $expenses[$category->id] ?? '0'; + $labelIn = $category->id . '-in'; + $labelOut = $category->id . '-out'; + $labelSumIn = $category->id . '-total-in'; + $labelSumOut = $category->id . '-total-out'; + $currentIncome = $income[$category->id] ?? '0'; + $currentExpense = $expenses[$category->id] ?? '0'; + + + // add to sum: + $sumOfIncome[$category->id] = $sumOfIncome[$category->id] ?? '0'; + $sumOfExpense[$category->id] = $sumOfExpense[$category->id] ?? '0'; + $sumOfIncome[$category->id] = bcadd($sumOfIncome[$category->id], $currentIncome); + $sumOfExpense[$category->id] = bcadd($sumOfExpense[$category->id], $currentExpense); + + // add to chart: + $chartData[$labelIn]['entries'][$label] = $currentIncome; + $chartData[$labelOut]['entries'][$label] = $currentExpense; + $chartData[$labelSumIn]['entries'][$label] = $sumOfIncome[$category->id]; + $chartData[$labelSumOut]['entries'][$label] = $sumOfExpense[$category->id]; } $currentStart = clone $currentEnd; $currentStart->addDay(); } - - $data = $this->generator->multiSet($chartData); + // remove all empty entries to prevent cluttering: + $newSet = []; + foreach ($chartData as $key => $entry) { + if (!array_sum($entry['entries']) == 0) { + $newSet[$key] = $chartData[$key]; + } + } + if (count($newSet) === 0) { + $newSet = $chartData; + } + $data = $this->generator->multiSet($newSet); $cache->store($data); return Response::json($data); @@ -427,4 +473,4 @@ class CategoryReportController extends Controller return $grouped; } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php old mode 100755 new mode 100644 index 9aaad05724..ade70f5cf9 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -23,6 +23,7 @@ use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Routing\Controller as BaseController; use Session; use View; +use FireflyConfig; /** * Class Controller @@ -49,7 +50,10 @@ class Controller extends BaseController View::share('hideCategories', false); View::share('hideBills', false); View::share('hideTags', false); - + $isDemoSite = FireflyConfig::get('is_demo_site', config('firefly.configuration.is_demo_site'))->data; + View::share('IS_DEMO_SITE', $isDemoSite); + View::share('DEMO_USERNAME', env('DEMO_USERNAME','')); + View::share('DEMO_PASSWORD', env('DEMO_PASSWORD','')); // translations: diff --git a/app/Http/Controllers/ExportController.php b/app/Http/Controllers/ExportController.php index ef293cf7b7..f081736c93 100644 --- a/app/Http/Controllers/ExportController.php +++ b/app/Http/Controllers/ExportController.php @@ -22,6 +22,7 @@ use FireflyIII\Http\Requests\ExportFormRequest; use FireflyIII\Models\AccountType; use FireflyIII\Models\ExportJob; use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface; use FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface as EJRI; use Preferences; use Response; @@ -59,21 +60,22 @@ class ExportController extends Controller * @return \Symfony\Component\HttpFoundation\Response|\Illuminate\Contracts\Routing\ResponseFactory * @throws FireflyException */ - public function download(ExportJob $job) + public function download(ExportJobRepositoryInterface $repository, ExportJob $job) { - $disk = Storage::disk('export'); $file = $job->key . '.zip'; $date = date('Y-m-d \a\t H-i-s'); $name = 'Export job on ' . $date . '.zip'; $quoted = sprintf('"%s"', addcslashes($name, '"\\')); - if (!$disk->exists($file)) { + if (!$repository->exists($job)) { throw new FireflyException('Against all expectations, zip file "' . $file . '" does not exist.'); } + $content = $repository->getContent($job); + $job->change('export_downloaded'); - return response($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) @@ -82,7 +84,7 @@ class ExportController 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)); } diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 6882a0f14a..1abee2e11b 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -63,6 +63,7 @@ class HomeController extends Controller // a possible problem with the budgets. if ($label === strval(trans('firefly.everything')) || $label === strval(trans('firefly.customRange'))) { $isCustomRange = true; + //Preferences::set('viewRange', 'custom'); Log::debug('Range is now marked as "custom".'); } @@ -107,7 +108,7 @@ class HomeController extends Controller $journal->save(); } } - + Session::forget(['start', 'end', 'viewRange', 'range', 'is_custom_range']); Session::clear(); Artisan::call('cache:clear'); diff --git a/app/Http/Controllers/ImportController.php b/app/Http/Controllers/ImportController.php index 270afe99d1..7c19bde59e 100644 --- a/app/Http/Controllers/ImportController.php +++ b/app/Http/Controllers/ImportController.php @@ -15,7 +15,7 @@ namespace FireflyIII\Http\Controllers; use Crypt; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Http\Requests\ImportUploadRequest; -use FireflyIII\Import\ImportProcedure; +use FireflyIII\Import\ImportProcedureInterface; use FireflyIII\Import\Setup\SetupInterface; use FireflyIII\Models\ImportJob; use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; @@ -315,13 +315,13 @@ class ImportController extends Controller } /** - * @param ImportJob $job + * @param ImportProcedureInterface $importProcedure + * @param ImportJob $job */ - public function start(ImportJob $job) + public function start(ImportProcedureInterface $importProcedure, ImportJob $job) { set_time_limit(0); if ($job->status == 'settings_complete') { - $importProcedure = new ImportProcedure; $importProcedure->runImport($job); } } @@ -334,7 +334,7 @@ class ImportController extends Controller * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View */ public function status(ImportJob $job) - { + { // Log::debug('Now in status()', ['job' => $job->key]); if (!$this->jobInCorrectStep($job, 'status')) { return $this->redirectToCorrectStep($job); diff --git a/app/Http/Controllers/PiggyBankController.php b/app/Http/Controllers/PiggyBankController.php index 7239ba309a..5d494b5985 100644 --- a/app/Http/Controllers/PiggyBankController.php +++ b/app/Http/Controllers/PiggyBankController.php @@ -24,6 +24,7 @@ use Illuminate\Support\Collection; use Input; use Log; use Preferences; +use Response; use Session; use Steam; use URL; @@ -149,13 +150,18 @@ class PiggyBankController extends Controller */ public function destroy(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank) { - - Session::flash('success', strval(trans('firefly.deleted_piggy_bank', ['name' => e($piggyBank->name)]))); Preferences::mark(); + $piggyBankId = $piggyBank->id; $repository->destroy($piggyBank); - return redirect(session('piggy-banks.delete.url')); + $uri = session('piggy-banks.delete.url'); + if (!(strpos($uri, sprintf('piggy-banks/show/%s', $piggyBankId)) === false)) { + // uri would point back to piggy bank + $uri = route('piggy-banks.index'); + } + + return redirect($uri); } /** @@ -243,6 +249,8 @@ class PiggyBankController extends Controller /** * @param PiggyBankRepositoryInterface $repository + * + * @return \Illuminate\Http\JsonResponse */ public function order(PiggyBankRepositoryInterface $repository) { @@ -257,6 +265,8 @@ class PiggyBankController extends Controller $repository->setOrder(intval($id), ($order + 1)); } } + + return Response::json(['result' => 'ok']); } /** diff --git a/app/Http/Controllers/Popup/ReportController.php b/app/Http/Controllers/Popup/ReportController.php index e10a016495..3d730ca105 100644 --- a/app/Http/Controllers/Popup/ReportController.php +++ b/app/Http/Controllers/Popup/ReportController.php @@ -133,8 +133,8 @@ class ReportController extends Controller $budget->name = strval(trans('firefly.leftUnbalanced')); $journals = $journals->filter( - function (TransactionJournal $journal) { - $tags = $journal->tags()->where('tagMode', 'balancingAct')->count(); + function (Transaction $transaction) { + $tags = $transaction->transactionJournal->tags()->where('tagMode', 'balancingAct')->count(); if ($tags === 0) { return true; } diff --git a/app/Http/Controllers/PreferencesController.php b/app/Http/Controllers/PreferencesController.php index e8ddd70eb3..93efecf2a8 100644 --- a/app/Http/Controllers/PreferencesController.php +++ b/app/Http/Controllers/PreferencesController.php @@ -150,7 +150,7 @@ class PreferencesController extends Controller // custom fiscal year $customFiscalYear = intval($request->get('customFiscalYear')) === 1; - $fiscalYearStart = date('m-d', strtotime($request->get('fiscalYearStart'))); + $fiscalYearStart = date('m-d', strtotime(strval($request->get('fiscalYearStart')))); Preferences::set('customFiscalYear', $customFiscalYear); Preferences::set('fiscalYearStart', $fiscalYearStart); @@ -166,13 +166,17 @@ class PreferencesController extends Controller Preferences::set('transactionPageSize', 50); } - // two factor auth - $twoFactorAuthEnabled = intval($request->get('twoFactorAuthEnabled')); - $hasTwoFactorAuthSecret = !is_null(Preferences::get('twoFactorAuthSecret')); + $twoFactorAuthEnabled = false; + $hasTwoFactorAuthSecret = false; + if (!auth()->user()->hasRole('demo')) { + // two factor auth + $twoFactorAuthEnabled = intval($request->get('twoFactorAuthEnabled')); + $hasTwoFactorAuthSecret = !is_null(Preferences::get('twoFactorAuthSecret')); - // If we already have a secret, just set the two factor auth enabled to 1, and let the user continue with the existing secret. - if ($hasTwoFactorAuthSecret) { - Preferences::set('twoFactorAuthEnabled', $twoFactorAuthEnabled); + // If we already have a secret, just set the two factor auth enabled to 1, and let the user continue with the existing secret. + if ($hasTwoFactorAuthSecret) { + Preferences::set('twoFactorAuthEnabled', $twoFactorAuthEnabled); + } } // language: diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index 8f8fbc6b07..30b0553d0b 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -51,6 +51,12 @@ class ProfileController extends Controller */ public function changePassword() { + if (auth()->user()->hasRole('demo')) { + Session::flash('info', strval(trans('firefly.cannot_change_demo'))); + + return redirect(route('profile.index')); + } + $title = auth()->user()->email; $subTitle = strval(trans('firefly.change_your_password')); $subTitleIcon = 'fa-key'; @@ -63,6 +69,12 @@ class ProfileController extends Controller */ public function deleteAccount() { + if (auth()->user()->hasRole('demo')) { + Session::flash('info', strval(trans('firefly.cannot_delete_demo'))); + + return redirect(route('profile.index')); + } + $title = auth()->user()->email; $subTitle = strval(trans('firefly.delete_account')); $subTitleIcon = 'fa-trash'; @@ -83,12 +95,19 @@ class ProfileController extends Controller } /** - * @param ProfileFormRequest $request + * @param ProfileFormRequest $request + * @param UserRepositoryInterface $repository * - * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ - public function postChangePassword(ProfileFormRequest $request) + public function postChangePassword(ProfileFormRequest $request, UserRepositoryInterface $repository) { + if (auth()->user()->hasRole('demo')) { + Session::flash('info', strval(trans('firefly.cannot_change_demo'))); + + return redirect(route('profile.index')); + } + // old, new1, new2 if (!Hash::check($request->get('current_password'), auth()->user()->password)) { Session::flash('error', strval(trans('firefly.invalid_current_password'))); @@ -103,9 +122,7 @@ class ProfileController extends Controller } // update the user with the new password. - auth()->user()->password = bcrypt($request->get('new_password')); - auth()->user()->save(); - + $repository->changePassword(auth()->user(), $request->get('new_password')); Session::flash('success', strval(trans('firefly.password_changed'))); return redirect(route('profile.index')); @@ -119,6 +136,12 @@ class ProfileController extends Controller */ public function postDeleteAccount(UserRepositoryInterface $repository, DeleteAccountFormRequest $request) { + if (auth()->user()->hasRole('demo')) { + Session::flash('info', strval(trans('firefly.cannot_delete_demo'))); + + return redirect(route('profile.index')); + } + // old, new1, new2 if (!Hash::check($request->get('password'), auth()->user()->password)) { Session::flash('error', strval(trans('firefly.invalid_password'))); diff --git a/app/Http/Controllers/Report/BalanceController.php b/app/Http/Controllers/Report/BalanceController.php index 664217472a..9dadfa608d 100644 --- a/app/Http/Controllers/Report/BalanceController.php +++ b/app/Http/Controllers/Report/BalanceController.php @@ -57,4 +57,4 @@ class BalanceController extends Controller return $result; } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/Report/BudgetController.php b/app/Http/Controllers/Report/BudgetController.php index a541a7a8bb..bc4d026631 100644 --- a/app/Http/Controllers/Report/BudgetController.php +++ b/app/Http/Controllers/Report/BudgetController.php @@ -120,4 +120,4 @@ class BudgetController extends Controller return $data; } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/Report/CategoryController.php b/app/Http/Controllers/Report/CategoryController.php index 0d5f3e3f07..730deeaece 100644 --- a/app/Http/Controllers/Report/CategoryController.php +++ b/app/Http/Controllers/Report/CategoryController.php @@ -15,7 +15,6 @@ namespace FireflyIII\Http\Controllers\Report; use Carbon\Carbon; -use FireflyIII\Helpers\Report\ReportHelperInterface; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Models\Category; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; @@ -170,4 +169,4 @@ class CategoryController extends Controller } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/Report/OperationsController.php b/app/Http/Controllers/Report/OperationsController.php index 3282e98d80..a30954ec7b 100644 --- a/app/Http/Controllers/Report/OperationsController.php +++ b/app/Http/Controllers/Report/OperationsController.php @@ -241,4 +241,4 @@ class OperationsController extends Controller return $expenses; } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/RuleController.php b/app/Http/Controllers/RuleController.php index 6a1d606af1..0216496be6 100644 --- a/app/Http/Controllers/RuleController.php +++ b/app/Http/Controllers/RuleController.php @@ -22,6 +22,7 @@ use FireflyIII\Models\RuleTrigger; use FireflyIII\Repositories\Rule\RuleRepositoryInterface; use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface; use FireflyIII\Rules\TransactionMatcher; +use Illuminate\Http\Request; use Input; use Preferences; use Response; @@ -86,10 +87,10 @@ class RuleController extends Controller $subTitle = trans('firefly.make_new_rule', ['title' => $ruleGroup->title]); // put previous url in session if not redirect from store (not "create another"). - if (session('rules.rule.create.fromStore') !== true) { - Session::put('rules.rule.create.url', URL::previous()); + if (session('rules.create.fromStore') !== true) { + Session::put('rules.create.url', URL::previous()); } - Session::forget('rules.rule.create.fromStore'); + Session::forget('rules.create.fromStore'); Session::flash('gaEventCategory', 'rules'); Session::flash('gaEventAction', 'create-rule'); @@ -110,7 +111,7 @@ class RuleController extends Controller $subTitle = trans('firefly.delete_rule', ['title' => $rule->title]); // put previous url in session - Session::put('rules.rule.delete.url', URL::previous()); + Session::put('rules.delete.url', URL::previous()); Session::flash('gaEventCategory', 'rules'); Session::flash('gaEventAction', 'delete-rule'); @@ -135,7 +136,7 @@ class RuleController extends Controller Preferences::mark(); - return redirect(session('rules.rule.delete.url')); + return redirect(session('rules.delete.url')); } /** @@ -178,10 +179,10 @@ class RuleController extends Controller $subTitle = trans('firefly.edit_rule', ['title' => $rule->title]); // put previous url in session if not redirect from store (not "return_to_edit"). - if (session('rules.rule.edit.fromUpdate') !== true) { - Session::put('rules.rule.edit.url', URL::previous()); + if (session('rules.edit.fromUpdate') !== true) { + Session::put('rules.edit.url', URL::previous()); } - Session::forget('rules.rule.edit.fromUpdate'); + Session::forget('rules.edit.fromUpdate'); Session::flash('gaEventCategory', 'rules'); Session::flash('gaEventAction', 'edit-rule'); @@ -203,14 +204,15 @@ class RuleController extends Controller } /** + * @param Request $request * @param RuleRepositoryInterface $repository * @param Rule $rule * * @return \Illuminate\Http\JsonResponse */ - public function reorderRuleActions(RuleRepositoryInterface $repository, Rule $rule) + public function reorderRuleActions(Request $request, RuleRepositoryInterface $repository, Rule $rule) { - $ids = Input::get('actions'); + $ids = $request->get('actions'); if (is_array($ids)) { $repository->reorderRuleActions($rule, $ids); } @@ -220,14 +222,15 @@ class RuleController extends Controller } /** + * @param Request $request * @param RuleRepositoryInterface $repository * @param Rule $rule * * @return \Illuminate\Http\JsonResponse */ - public function reorderRuleTriggers(RuleRepositoryInterface $repository, Rule $rule) + public function reorderRuleTriggers(Request $request, RuleRepositoryInterface $repository, Rule $rule) { - $ids = Input::get('triggers'); + $ids = $request->get('triggers'); if (is_array($ids)) { $repository->reorderRuleTriggers($rule, $ids); } @@ -254,13 +257,13 @@ class RuleController extends Controller if (intval(Input::get('create_another')) === 1) { // set value so create routine will not overwrite URL: - Session::put('rules.rule.create.fromStore', true); + Session::put('rules.create.fromStore', true); - return redirect(route('rules.rule.create', [$ruleGroup]))->withInput(); + return redirect(route('rules.create', [$ruleGroup]))->withInput(); } // redirect to previous URL. - return redirect(session('rules.rule.create.url')); + return redirect(session('rules.create.url')); } @@ -341,13 +344,13 @@ class RuleController extends Controller if (intval(Input::get('return_to_edit')) === 1) { // set value so edit routine will not overwrite URL: - Session::put('rules.rule.edit.fromUpdate', true); + Session::put('rules.edit.fromUpdate', true); - return redirect(route('rules.rule.edit', [$rule->id]))->withInput(['return_to_edit' => 1]); + return redirect(route('rules.edit', [$rule->id]))->withInput(['return_to_edit' => 1]); } // redirect to previous URL. - return redirect(session('rules.rule.edit.url')); + return redirect(session('rules.edit.url')); } private function createDefaultRule() diff --git a/app/Http/Controllers/RuleGroupController.php b/app/Http/Controllers/RuleGroupController.php index f1ab10422b..6f0a136a1d 100644 --- a/app/Http/Controllers/RuleGroupController.php +++ b/app/Http/Controllers/RuleGroupController.php @@ -62,10 +62,10 @@ class RuleGroupController extends Controller $subTitle = trans('firefly.make_new_rule_group'); // put previous url in session if not redirect from store (not "create another"). - if (session('rules.rule-group.create.fromStore') !== true) { - Session::put('rules.rule-group.create.url', URL::previous()); + if (session('rule-groups.create.fromStore') !== true) { + Session::put('rule-groups.create.url', URL::previous()); } - Session::forget('rules.rule-group.create.fromStore'); + Session::forget('rule-groups.create.fromStore'); Session::flash('gaEventCategory', 'rules'); Session::flash('gaEventAction', 'create-rule-group'); @@ -86,7 +86,7 @@ class RuleGroupController extends Controller unset($ruleGroupList[$ruleGroup->id]); // put previous url in session - Session::put('rules.rule-group.delete.url', URL::previous()); + Session::put('rule-groups.delete.url', URL::previous()); Session::flash('gaEventCategory', 'rules'); Session::flash('gaEventAction', 'delete-rule-group'); @@ -113,7 +113,7 @@ class RuleGroupController extends Controller Preferences::mark(); - return redirect(session('rules.rule-group.delete.url')); + return redirect(session('rule-groups.delete.url')); } /** @@ -140,10 +140,10 @@ class RuleGroupController extends Controller $subTitle = trans('firefly.edit_rule_group', ['title' => $ruleGroup->title]); // put previous url in session if not redirect from store (not "return_to_edit"). - if (session('rules.rule-group.edit.fromUpdate') !== true) { - Session::put('rules.rule-group.edit.url', URL::previous()); + if (session('rule-groups.edit.fromUpdate') !== true) { + Session::put('rule-groups.edit.url', URL::previous()); } - Session::forget('rules.rule-group.edit.fromUpdate'); + Session::forget('rule-groups.edit.fromUpdate'); Session::flash('gaEventCategory', 'rules'); Session::flash('gaEventAction', 'edit-rule-group'); @@ -220,13 +220,13 @@ class RuleGroupController extends Controller if (intval(Input::get('create_another')) === 1) { // set value so create routine will not overwrite URL: - Session::put('rules.rule-group.create.fromStore', true); + Session::put('rule-groups.create.fromStore', true); - return redirect(route('rules.rule-group.create'))->withInput(); + return redirect(route('rule-groups.create'))->withInput(); } // redirect to previous URL. - return redirect(session('rules.rule-group.create.url')); + return redirect(session('rule-groups.create.url')); } /** @@ -265,13 +265,13 @@ class RuleGroupController extends Controller if (intval(Input::get('return_to_edit')) === 1) { // set value so edit routine will not overwrite URL: - Session::put('rules.rule-group.edit.fromUpdate', true); + Session::put('rule-groups.edit.fromUpdate', true); - return redirect(route('rules.rule-group.edit', [$ruleGroup->id]))->withInput(['return_to_edit' => 1]); + return redirect(route('rule-groups.edit', [$ruleGroup->id]))->withInput(['return_to_edit' => 1]); } // redirect to previous URL. - return redirect(session('rules.rule-group.edit.url')); + return redirect(session('rule-groups.edit.url')); } } diff --git a/app/Http/Controllers/Transaction/ConvertController.php b/app/Http/Controllers/Transaction/ConvertController.php index f83a317229..ebeec3b1d3 100644 --- a/app/Http/Controllers/Transaction/ConvertController.php +++ b/app/Http/Controllers/Transaction/ConvertController.php @@ -244,4 +244,4 @@ class ConvertController extends Controller } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/Transaction/SingleController.php b/app/Http/Controllers/Transaction/SingleController.php index 98ba1458de..96915dae35 100644 --- a/app/Http/Controllers/Transaction/SingleController.php +++ b/app/Http/Controllers/Transaction/SingleController.php @@ -153,16 +153,21 @@ class SingleController extends Controller if ($this->isOpeningBalance($transactionJournal)) { return $this->redirectToAccount($transactionJournal); } - - $type = TransactionJournal::transactionTypeStr($transactionJournal); + $journalId = $transactionJournal->id; + $type = TransactionJournal::transactionTypeStr($transactionJournal); Session::flash('success', strval(trans('firefly.deleted_' . strtolower($type), ['description' => e($transactionJournal->description)]))); $repository->delete($transactionJournal); Preferences::mark(); - // redirect to previous URL: - return redirect(session('transactions.delete.url')); + $uri = session('transactions.delete.url'); + if (!(strpos($uri, sprintf('transactions/show/%s', $journalId)) === false)) { + // uri would point back to transaction + $uri = route('transactions.index', [strtolower($type)]); + } + + return redirect($uri); } /** diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php old mode 100755 new mode 100644 diff --git a/app/Http/Middleware/EncryptCookies.php b/app/Http/Middleware/EncryptCookies.php old mode 100755 new mode 100644 diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php old mode 100755 new mode 100644 diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php old mode 100755 new mode 100644 diff --git a/app/Http/Requests/BudgetIncomeRequest.php b/app/Http/Requests/BudgetIncomeRequest.php new file mode 100644 index 0000000000..e8c2c93e39 --- /dev/null +++ b/app/Http/Requests/BudgetIncomeRequest.php @@ -0,0 +1,42 @@ +check(); + } + + /** + * @return array + */ + public function rules() + { + return [ + 'amount' => 'numeric|required|min:0', + ]; + } +} diff --git a/app/Http/Requests/PiggyBankFormRequest.php b/app/Http/Requests/PiggyBankFormRequest.php index 69c11d70b2..684ad148d9 100644 --- a/app/Http/Requests/PiggyBankFormRequest.php +++ b/app/Http/Requests/PiggyBankFormRequest.php @@ -42,8 +42,8 @@ class PiggyBankFormRequest extends Request 'startdate' => new Carbon, 'account_id' => intval($this->get('account_id')), 'targetamount' => round($this->get('targetamount'), 2), - 'targetdate' => strlen($this->get('targetdate')) > 0 ? new Carbon($this->get('targetdate')) : null, - 'note' => trim($this->get('note')), + 'targetdate' => strlen(strval($this->get('targetdate'))) > 0 ? new Carbon($this->get('targetdate')) : null, + 'note' => trim(strval($this->get('note'))), ]; } @@ -64,7 +64,7 @@ class PiggyBankFormRequest extends Request 'name' => $nameRule, 'account_id' => 'required|belongsToUser:accounts', 'targetamount' => 'required|min:0.01', - 'amount_currency_id_targetamount' => 'exists:transaction_currencies,id', + 'amount_currency_id_targetamount' => 'required|exists:transaction_currencies,id', 'startdate' => 'date', 'targetdate' => $targetDateRule, 'order' => 'integer|min:1', diff --git a/app/Http/Requests/RuleGroupFormRequest.php b/app/Http/Requests/RuleGroupFormRequest.php index 9fa09fdefa..b5420c5ce5 100644 --- a/app/Http/Requests/RuleGroupFormRequest.php +++ b/app/Http/Requests/RuleGroupFormRequest.php @@ -10,13 +10,6 @@ */ declare(strict_types = 1); -/** - * RuleGroupFormRequest.php - * Copyright (C) 2016 thegrumpydictator@gmail.com - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ namespace FireflyIII\Http\Requests; diff --git a/app/Http/breadcrumbs.php b/app/Http/breadcrumbs.php index 5b99d097ee..339855c695 100644 --- a/app/Http/breadcrumbs.php +++ b/app/Http/breadcrumbs.php @@ -413,7 +413,22 @@ Breadcrumbs::register( 'piggy-banks.show', function (BreadCrumbGenerator $breadcrumbs, PiggyBank $piggyBank) { $breadcrumbs->parent('piggy-banks.index'); $breadcrumbs->push(e($piggyBank->name), route('piggy-banks.show', [$piggyBank->id])); +} +); +Breadcrumbs::register( + 'piggy-banks.add-money-mobile', function (BreadCrumbGenerator $breadcrumbs, PiggyBank $piggyBank) { + $breadcrumbs->parent('piggy-banks.show', $piggyBank); + $breadcrumbs->push(trans('firefly.add_money_to_piggy', ['name' => $piggyBank->name]), route('piggy-banks.add-money-mobile', [$piggyBank->id])); +} +); + +Breadcrumbs::register( + 'piggy-banks.remove-money-mobile', function (BreadCrumbGenerator $breadcrumbs, PiggyBank $piggyBank) { + $breadcrumbs->parent('piggy-banks.show', $piggyBank); + $breadcrumbs->push( + trans('firefly.remove_money_from_piggy_title', ['name' => $piggyBank->name]), route('piggy-banks.remove-money-mobile', [$piggyBank->id]) + ); } ); @@ -500,16 +515,63 @@ Breadcrumbs::register( ); Breadcrumbs::register( - 'reports.report', function (BreadCrumbGenerator $breadcrumbs, Carbon $start, Carbon $end, $reportType, $accountIds) { + 'reports.report.audit', function (BreadCrumbGenerator $breadcrumbs, string $accountIds, Carbon $start, Carbon $end) { $breadcrumbs->parent('reports.index'); $monthFormat = (string)trans('config.month_and_day'); - $title = (string)trans( - 'firefly.report_' . $reportType, - ['start' => $start->formatLocalized($monthFormat), 'end' => $end->formatLocalized($monthFormat)] - ); + $startString = $start->formatLocalized($monthFormat); + $endString = $end->formatLocalized($monthFormat); + $title = (string)trans('firefly.report_audit', ['start' => $startString, 'end' => $endString]); - $breadcrumbs->push($title, route('reports.report', [$reportType, $start->format('Ymd'), $end->format('Ymd'), $accountIds])); + $breadcrumbs->push($title, route('reports.report.audit', [$accountIds, $start->format('Ymd'), $end->format('Ymd')])); +} +); +Breadcrumbs::register( + 'reports.report.budget', function (BreadCrumbGenerator $breadcrumbs, string $accountIds, string $budgetIds, Carbon $start, Carbon $end) { + $breadcrumbs->parent('reports.index'); + + $monthFormat = (string)trans('config.month_and_day'); + $startString = $start->formatLocalized($monthFormat); + $endString = $end->formatLocalized($monthFormat); + $title = (string)trans('firefly.report_budget', ['start' => $startString, 'end' => $endString]); + + $breadcrumbs->push($title, route('reports.report.budget', [$accountIds, $budgetIds, $start->format('Ymd'), $end->format('Ymd')])); +} +); + +Breadcrumbs::register( + 'reports.report.category', function (BreadCrumbGenerator $breadcrumbs, string $accountIds, string $categoryIds, Carbon $start, Carbon $end) { + $breadcrumbs->parent('reports.index'); + + $monthFormat = (string)trans('config.month_and_day'); + $startString = $start->formatLocalized($monthFormat); + $endString = $end->formatLocalized($monthFormat); + $title = (string)trans('firefly.report_category', ['start' => $startString, 'end' => $endString]); + + $breadcrumbs->push($title, route('reports.report.category', [$accountIds, $categoryIds, $start->format('Ymd'), $end->format('Ymd')])); +} +); + +Breadcrumbs::register( + 'reports.report.default', function (BreadCrumbGenerator $breadcrumbs, string $accountIds, Carbon $start, Carbon $end) { + $breadcrumbs->parent('reports.index'); + + $monthFormat = (string)trans('config.month_and_day'); + $startString = $start->formatLocalized($monthFormat); + $endString = $end->formatLocalized($monthFormat); + $title = (string)trans('firefly.report_default', ['start' => $startString, 'end' => $endString]); + + $breadcrumbs->push($title, route('reports.report.default', [$accountIds, $start->format('Ymd'), $end->format('Ymd')])); +} +); + +/** + * New user Controller + */ +Breadcrumbs::register( + 'new-user.index', function (BreadCrumbGenerator $breadcrumbs) { + $breadcrumbs->parent('home'); + $breadcrumbs->push(trans('firefly.getting_started'), route('new-user.index')); } ); @@ -524,47 +586,54 @@ Breadcrumbs::register( ); Breadcrumbs::register( - 'rules.rule.create', function (BreadCrumbGenerator $breadcrumbs, RuleGroup $ruleGroup) { + 'rules.create', function (BreadCrumbGenerator $breadcrumbs, RuleGroup $ruleGroup) { $breadcrumbs->parent('rules.index'); - $breadcrumbs->push(trans('firefly.make_new_rule', ['title' => $ruleGroup->title]), route('rules.rule.create', [$ruleGroup])); + $breadcrumbs->push(trans('firefly.make_new_rule', ['title' => $ruleGroup->title]), route('rules.create', [$ruleGroup])); } ); Breadcrumbs::register( - 'rules.rule.edit', function (BreadCrumbGenerator $breadcrumbs, Rule $rule) { + 'rules.edit', function (BreadCrumbGenerator $breadcrumbs, Rule $rule) { $breadcrumbs->parent('rules.index'); - $breadcrumbs->push(trans('firefly.edit_rule', ['title' => $rule->title]), route('rules.rule.edit', [$rule])); + $breadcrumbs->push(trans('firefly.edit_rule', ['title' => $rule->title]), route('rules.edit', [$rule])); } ); Breadcrumbs::register( - 'rules.rule.delete', function (BreadCrumbGenerator $breadcrumbs, Rule $rule) { + 'rules.delete', function (BreadCrumbGenerator $breadcrumbs, Rule $rule) { $breadcrumbs->parent('rules.index'); - $breadcrumbs->push(trans('firefly.delete_rule', ['title' => $rule->title]), route('rules.rule.delete', [$rule])); + $breadcrumbs->push(trans('firefly.delete_rule', ['title' => $rule->title]), route('rules.delete', [$rule])); } ); Breadcrumbs::register( - 'rules.rule-group.create', function (BreadCrumbGenerator $breadcrumbs) { + 'rule-groups.create', function (BreadCrumbGenerator $breadcrumbs) { $breadcrumbs->parent('rules.index'); - $breadcrumbs->push(trans('firefly.make_new_rule_group'), route('rules.rule-group.create')); + $breadcrumbs->push(trans('firefly.make_new_rule_group'), route('rule-groups.create')); } ); Breadcrumbs::register( - 'rules.rule-group.edit', function (BreadCrumbGenerator $breadcrumbs, RuleGroup $ruleGroup) { + 'rule-groups.edit', function (BreadCrumbGenerator $breadcrumbs, RuleGroup $ruleGroup) { $breadcrumbs->parent('rules.index'); - $breadcrumbs->push(trans('firefly.edit_rule_group', ['title' => $ruleGroup->title]), route('rules.rule-group.edit', [$ruleGroup])); + $breadcrumbs->push(trans('firefly.edit_rule_group', ['title' => $ruleGroup->title]), route('rule-groups.edit', [$ruleGroup])); } ); Breadcrumbs::register( - 'rules.rule-group.delete', function (BreadCrumbGenerator $breadcrumbs, RuleGroup $ruleGroup) { + 'rule-groups.delete', function (BreadCrumbGenerator $breadcrumbs, RuleGroup $ruleGroup) { $breadcrumbs->parent('rules.index'); - $breadcrumbs->push(trans('firefly.delete_rule_group', ['title' => $ruleGroup->title]), route('rules.rule-group.delete', [$ruleGroup])); + $breadcrumbs->push(trans('firefly.delete_rule_group', ['title' => $ruleGroup->title]), route('rule-groups.delete', [$ruleGroup])); } ); Breadcrumbs::register( - 'rules.rule-group.select_transactions', function (BreadCrumbGenerator $breadcrumbs, RuleGroup $ruleGroup) { + 'rule-groups.select-transactions', function (BreadCrumbGenerator $breadcrumbs, RuleGroup $ruleGroup) { + $breadcrumbs->parent('rules.index'); + $breadcrumbs->push(trans('firefly.rule_group_select_transactions', ['title' => $ruleGroup->title]), route('rule-groups.select-transactions', [$ruleGroup])); +} +); + +Breadcrumbs::register( + 'rule-groups.select_transactions', function (BreadCrumbGenerator $breadcrumbs, RuleGroup $ruleGroup) { $breadcrumbs->parent('rules.index'); $breadcrumbs->push( - trans('firefly.execute_group_on_existing_transactions', ['title' => $ruleGroup->title]), route('rules.rule-group.select_transactions', [$ruleGroup]) + trans('firefly.execute_group_on_existing_transactions', ['title' => $ruleGroup->title]), route('rule-groups.select_transactions', [$ruleGroup]) ); } ); diff --git a/app/Import/Converter/TagSplit.php b/app/Import/Converter/TagSplit.php index 53d3fc1d1c..cc99561663 100644 --- a/app/Import/Converter/TagSplit.php +++ b/app/Import/Converter/TagSplit.php @@ -82,4 +82,4 @@ class TagSplit return $set; } -} \ No newline at end of file +} diff --git a/app/Import/ImportEntry.php b/app/Import/ImportEntry.php index cd3f48b402..fba65e99d4 100644 --- a/app/Import/ImportEntry.php +++ b/app/Import/ImportEntry.php @@ -96,6 +96,7 @@ class ImportEntry case 'account-id': case 'account-iban': case 'account-name': + case 'account-number': $this->setObject('asset-account', $convertedValue, $certainty); break; case 'opposing-number': diff --git a/app/Import/ImportProcedure.php b/app/Import/ImportProcedure.php index dd3878a01b..c535d47fae 100644 --- a/app/Import/ImportProcedure.php +++ b/app/Import/ImportProcedure.php @@ -23,7 +23,7 @@ use Illuminate\Support\Collection; * * @package FireflyIII\Import */ -class ImportProcedure +class ImportProcedure implements ImportProcedureInterface { /** diff --git a/app/Import/ImportProcedureInterface.php b/app/Import/ImportProcedureInterface.php new file mode 100644 index 0000000000..72765aa4ce --- /dev/null +++ b/app/Import/ImportProcedureInterface.php @@ -0,0 +1,33 @@ + $accounts['source']->id, 'transaction_journal_id' => $journal->id, - 'description' => $journal->description, + 'description' => null, 'amount' => bcmul($amount, '-1'), ]; $destinationData = [ 'account_id' => $accounts['destination']->id, 'transaction_journal_id' => $journal->id, - 'description' => $journal->description, + 'description' => null, 'amount' => $amount, ]; diff --git a/app/Jobs/MailError.php b/app/Jobs/MailError.php index 883443f9a7..44e1ec89b5 100644 --- a/app/Jobs/MailError.php +++ b/app/Jobs/MailError.php @@ -81,7 +81,7 @@ class MailError extends Job implements ShouldQueue ['emails.error-html', 'emails.error-text'], $args, function (Message $message) use ($email) { if ($email != 'mail@example.com') { - $message->to($email, $email)->subject('Caught an error in Firely III.'); + $message->to($email, $email)->subject('Caught an error in Firely III'); } } ); diff --git a/app/Models/Account.php b/app/Models/Account.php index bc06e9b665..2d07b89f37 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -36,12 +36,25 @@ class Account extends Model { use SoftDeletes, ValidatingTrait; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + 'active' => 'boolean', + 'encrypted' => 'boolean', + ]; /** @var array */ protected $dates = ['created_at', 'updated_at', 'deleted_at']; /** @var array */ protected $fillable = ['user_id', 'account_type_id', 'name', 'active', 'virtual_balance', 'iban']; /** @var array */ - protected $hidden = ['virtual_balance_encrypted', 'encrypted']; + protected $hidden = ['encrypted']; protected $rules = [ 'user_id' => 'required|exists:users,id', @@ -184,7 +197,7 @@ class Account extends Model public function getNameAttribute($value): string { - if (intval($this->encrypted) == 1) { + if ($this->encrypted) { return Crypt::decrypt($value); } diff --git a/app/Models/AccountMeta.php b/app/Models/AccountMeta.php index d8c08233a5..797058c122 100644 --- a/app/Models/AccountMeta.php +++ b/app/Models/AccountMeta.php @@ -24,7 +24,18 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; class AccountMeta extends Model { - protected $dates = ['created_at', 'updated_at']; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + ]; + /** @var array */ + protected $dates = ['created_at', 'updated_at']; protected $fillable = ['account_id', 'name', 'data']; protected $table = 'account_meta'; diff --git a/app/Models/AccountType.php b/app/Models/AccountType.php index 0bf346f471..3efa588ada 100644 --- a/app/Models/AccountType.php +++ b/app/Models/AccountType.php @@ -33,6 +33,18 @@ class AccountType extends Model const IMPORT = 'Import account'; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + ]; + + /** @var array */ protected $dates = ['created_at', 'updated_at']; // diff --git a/app/Models/Attachment.php b/app/Models/Attachment.php index eff2095f78..84dfbfc106 100644 --- a/app/Models/Attachment.php +++ b/app/Models/Attachment.php @@ -29,6 +29,21 @@ class Attachment extends Model { use SoftDeletes; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + 'uploaded' => 'boolean', + ]; + /** @var array */ + protected $dates = ['created_at', 'updated_at', 'deleted_at']; + /** @var array */ protected $fillable = ['attachable_id', 'attachable_type', 'user_id', 'md5', 'filename', 'mime', 'title', 'notes', 'description', 'size', 'uploaded']; /** diff --git a/app/Models/AvailableBudget.php b/app/Models/AvailableBudget.php new file mode 100644 index 0000000000..c96893fbb9 --- /dev/null +++ b/app/Models/AvailableBudget.php @@ -0,0 +1,63 @@ + 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + 'start_date' => 'date', + 'end_date' => 'date', + ]; + + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function transactionCurrency() + { + return $this->belongsTo('FireflyIII\Models\TransactionCurrency'); + } + + /** + * @return BelongsTo + */ + public function user(): BelongsTo + { + return $this->belongsTo('FireflyIII\User'); + } +} diff --git a/app/Models/Bill.php b/app/Models/Bill.php index 7c6ca35924..a536caa18e 100644 --- a/app/Models/Bill.php +++ b/app/Models/Bill.php @@ -29,8 +29,26 @@ class Bill extends Model { use ValidatingTrait; + /** @var array */ + protected $dates = ['created_at', 'updated_at', 'deleted_at']; - protected $dates = ['created_at', 'updated_at', 'date']; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + 'date' => 'date', + 'skip' => 'int', + 'automatch' => 'boolean', + 'active' => 'boolean', + 'name_encrypted' => 'boolean', + 'match_encrypted' => 'boolean', + ]; protected $fillable = ['name', 'match', 'amount_min', 'match_encrypted', 'name_encrypted', 'user_id', 'amount_max', 'date', 'repeat_freq', 'skip', 'automatch', 'active',]; diff --git a/app/Models/Budget.php b/app/Models/Budget.php index 8d073fa561..6bca976677 100644 --- a/app/Models/Budget.php +++ b/app/Models/Budget.php @@ -30,7 +30,23 @@ class Budget extends Model use SoftDeletes, ValidatingTrait; - protected $dates = ['created_at', 'updated_at', 'deleted_at', 'startdate', 'enddate']; + /** @var array */ + protected $dates = ['created_at', 'updated_at', 'deleted_at']; + + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + 'active' => 'boolean', + 'encrypted' => 'boolean', + ]; + protected $fillable = ['user_id', 'name', 'active']; protected $hidden = ['encrypted']; protected $rules = ['name' => 'required|between:1,200',]; @@ -95,7 +111,7 @@ class Budget extends Model public function getNameAttribute($value) { - if (intval($this->encrypted) == 1) { + if ($this->encrypted) { return Crypt::decrypt($value); } @@ -115,8 +131,8 @@ class Budget 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/BudgetLimit.php b/app/Models/BudgetLimit.php index 86322743bd..622ad9bbc7 100644 --- a/app/Models/BudgetLimit.php +++ b/app/Models/BudgetLimit.php @@ -23,7 +23,20 @@ use Illuminate\Database\Eloquent\Model; class BudgetLimit extends Model { - protected $dates = ['created_at', 'updated_at', 'startdate']; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'startdate' => 'date', + 'repeats' => 'boolean', + ]; + /** @var array */ + protected $dates = ['created_at', 'updated_at']; protected $hidden = ['amount_encrypted']; /** diff --git a/app/Models/Category.php b/app/Models/Category.php index b80e03d1b7..c0db1259b8 100644 --- a/app/Models/Category.php +++ b/app/Models/Category.php @@ -29,10 +29,26 @@ class Category extends Model { use SoftDeletes, ValidatingTrait; - protected $dates = ['created_at', 'updated_at', 'deleted_at']; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + 'encrypted' => 'boolean', + ]; + /** @var array */ protected $fillable = ['user_id', 'name']; + /** @var array */ protected $hidden = ['encrypted']; + /** @var array */ protected $rules = ['name' => 'required|between:1,200',]; + /** @var array */ + protected $dates = ['created_at', 'updated_at', 'deleted_at']; /** * @param array $fields @@ -86,7 +102,7 @@ class Category extends Model public function getNameAttribute($value) { - if (intval($this->encrypted) == 1) { + if ($this->encrypted) { return Crypt::decrypt($value); } @@ -99,8 +115,8 @@ class Category 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/Configuration.php b/app/Models/Configuration.php index 9bbee9e894..b5edf6aced 100644 --- a/app/Models/Configuration.php +++ b/app/Models/Configuration.php @@ -25,6 +25,17 @@ class Configuration extends Model { use SoftDeletes; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + ]; + /** @var array */ protected $dates = ['created_at', 'updated_at', 'deleted_at']; protected $table = 'configuration'; diff --git a/app/Models/ExportJob.php b/app/Models/ExportJob.php index 9a3807c728..a0eb58cfed 100644 --- a/app/Models/ExportJob.php +++ b/app/Models/ExportJob.php @@ -23,6 +23,15 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; */ class ExportJob extends Model { + /** @var array */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + ]; + /** @var array */ + protected $dates = ['created_at', 'updated_at']; + /** * @param $value * diff --git a/app/Models/ImportJob.php b/app/Models/ImportJob.php index 01094638e4..b8a7bd27c3 100644 --- a/app/Models/ImportJob.php +++ b/app/Models/ImportJob.php @@ -27,6 +27,19 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class ImportJob extends Model { + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + ]; + /** @var array */ + protected $dates = ['created_at', 'updated_at']; + protected $validStatus = [ 'import_status_never_started', // initial state diff --git a/app/Models/LimitRepetition.php b/app/Models/LimitRepetition.php index be87b5accf..9c76eab93f 100644 --- a/app/Models/LimitRepetition.php +++ b/app/Models/LimitRepetition.php @@ -26,6 +26,18 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class LimitRepetition extends Model { + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'startdate' => 'date', + 'enddate' => 'date', + ]; protected $dates = ['created_at', 'updated_at', 'startdate', 'enddate']; protected $hidden = ['amount_encrypted']; @@ -38,10 +50,10 @@ class LimitRepetition extends Model { if (auth()->check()) { $object = self::where('limit_repetitions.id', $value) - ->leftJoin('budget_limits', 'budget_limits.id', '=', 'limit_repetitions.budget_limit_id') - ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') - ->where('budgets.user_id', auth()->user()->id) - ->first(['limit_repetitions.*']); + ->leftJoin('budget_limits', 'budget_limits.id', '=', 'limit_repetitions.budget_limit_id') + ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') + ->where('budgets.user_id', auth()->user()->id) + ->first(['limit_repetitions.*']); if ($object) { return $object; } diff --git a/app/Models/Note.php b/app/Models/Note.php index 1465008ecf..58600a8073 100644 --- a/app/Models/Note.php +++ b/app/Models/Note.php @@ -23,10 +23,20 @@ use League\CommonMark\CommonMarkConverter; */ class Note extends Model { + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + ]; protected $dates = ['created_at', 'updated_at', 'deleted_at']; protected $fillable = ['title', 'text']; - /** * @return string */ diff --git a/app/Models/PiggyBank.php b/app/Models/PiggyBank.php index 2e3f1f01b0..e9b6b4a980 100644 --- a/app/Models/PiggyBank.php +++ b/app/Models/PiggyBank.php @@ -29,10 +29,25 @@ class PiggyBank extends Model { use SoftDeletes; - protected $dates = ['created_at', 'updated_at', 'deleted_at', 'startdate', 'targetdate']; - protected $fillable - = ['name', 'account_id', 'order', 'targetamount', 'startdate', 'targetdate']; - protected $hidden = ['targetamount_encrypted', 'encrypted']; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + 'startdate' => 'date', + 'targetdate' => 'date', + 'order' => 'int', + 'active' => 'boolean', + 'encrypted' => 'boolean', + ]; + protected $dates = ['created_at', 'updated_at', 'deleted_at', 'startdate', 'targetdate']; + protected $fillable = ['name', 'account_id', 'order', 'targetamount', 'startdate', 'targetdate']; + protected $hidden = ['targetamount_encrypted', 'encrypted']; /** * @param PiggyBank $value @@ -86,7 +101,7 @@ class PiggyBank extends Model public function getNameAttribute($value) { - if (intval($this->encrypted) == 1) { + if ($this->encrypted) { return Crypt::decrypt($value); } @@ -144,8 +159,8 @@ class PiggyBank 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/PiggyBankEvent.php b/app/Models/PiggyBankEvent.php index ac11ec0d70..be731402ab 100644 --- a/app/Models/PiggyBankEvent.php +++ b/app/Models/PiggyBankEvent.php @@ -23,6 +23,17 @@ use Illuminate\Database\Eloquent\Model; class PiggyBankEvent extends Model { + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'date' => 'date', + ]; protected $dates = ['created_at', 'updated_at', 'date']; protected $fillable = ['piggy_bank_id', 'transaction_journal_id', 'date', 'amount']; protected $hidden = ['amount_encrypted']; diff --git a/app/Models/PiggyBankRepetition.php b/app/Models/PiggyBankRepetition.php index cc1432e31b..8b048879df 100644 --- a/app/Models/PiggyBankRepetition.php +++ b/app/Models/PiggyBankRepetition.php @@ -25,9 +25,21 @@ use Illuminate\Database\Eloquent\Model; class PiggyBankRepetition extends Model { + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + 'startdate' => 'date', + 'targetdate' => 'date', + ]; protected $dates = ['created_at', 'updated_at', 'startdate', 'targetdate']; protected $fillable = ['piggy_bank_id', 'startdate', 'targetdate', 'currentamount']; - protected $hidden = ['currentamount_encrypted']; /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo diff --git a/app/Models/Preference.php b/app/Models/Preference.php index 10f38ddd2d..5ec7b943ad 100644 --- a/app/Models/Preference.php +++ b/app/Models/Preference.php @@ -27,6 +27,16 @@ use Log; class Preference extends Model { + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + ]; protected $dates = ['created_at', 'updated_at']; protected $fillable = ['user_id', 'data', 'name', 'data']; diff --git a/app/Models/Role.php b/app/Models/Role.php index 23584fd274..5f1a7c33e9 100644 --- a/app/Models/Role.php +++ b/app/Models/Role.php @@ -23,6 +23,17 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany; */ class Role extends Model { + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + ]; + protected $dates = ['created_at', 'updated_at']; /** * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany diff --git a/app/Models/Rule.php b/app/Models/Rule.php index 09f8897326..ad3db4309c 100644 --- a/app/Models/Rule.php +++ b/app/Models/Rule.php @@ -26,6 +26,23 @@ class Rule extends Model { use SoftDeletes; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + 'active' => 'boolean', + 'order' => 'int', + 'stop_processing' => 'boolean', + ]; + /** @var array */ + protected $dates = ['created_at', 'updated_at', 'deleted_at']; + /** * @param Rule $value * diff --git a/app/Models/RuleAction.php b/app/Models/RuleAction.php index 11a40ef6a6..8817a108dc 100644 --- a/app/Models/RuleAction.php +++ b/app/Models/RuleAction.php @@ -10,13 +10,6 @@ */ declare(strict_types = 1); -/** - * RuleAction.php - * Copyright (C) 2016 thegrumpydictator@gmail.com - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ namespace FireflyIII\Models; @@ -29,6 +22,22 @@ use Illuminate\Database\Eloquent\Model; */ class RuleAction extends Model { + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'active' => 'boolean', + 'order' => 'int', + 'stop_processing' => 'boolean', + ]; + /** @var array */ + protected $dates = ['created_at', 'updated_at']; + /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ diff --git a/app/Models/RuleGroup.php b/app/Models/RuleGroup.php index f3dc6abd20..b4be42a160 100644 --- a/app/Models/RuleGroup.php +++ b/app/Models/RuleGroup.php @@ -25,6 +25,22 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class RuleGroup extends Model { use SoftDeletes; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + 'active' => 'boolean', + 'order' => 'int', + ]; + /** @var array */ + protected $dates = ['created_at', 'updated_at', 'deleted_at']; + protected $fillable = ['user_id', 'order', 'title', 'description', 'active']; diff --git a/app/Models/RuleTrigger.php b/app/Models/RuleTrigger.php index 72fe0f76a4..048d1c94fc 100644 --- a/app/Models/RuleTrigger.php +++ b/app/Models/RuleTrigger.php @@ -22,6 +22,22 @@ use Illuminate\Database\Eloquent\Model; */ class RuleTrigger extends Model { + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'active' => 'boolean', + 'order' => 'int', + 'stop_processing' => 'boolean', + ]; + /** @var array */ + protected $dates = ['created_at', 'updated_at']; + /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ diff --git a/app/Models/Tag.php b/app/Models/Tag.php index 6912a47582..769ea2c5af 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -15,6 +15,7 @@ namespace FireflyIII\Models; use Crypt; use FireflyIII\Support\Models\TagSupport; +use Illuminate\Database\Eloquent\SoftDeletes; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Watson\Validating\ValidatingTrait; @@ -25,11 +26,25 @@ use Watson\Validating\ValidatingTrait; */ class Tag extends TagSupport { - protected $dates = ['created_at', 'updated_at', 'date']; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + 'date' => 'date', + 'zoomLevel' => 'int', + + ]; + protected $dates = ['created_at', 'updated_at', 'date', 'deleted_at']; protected $fillable = ['user_id', 'tag', 'date', 'description', 'longitude', 'latitude', 'zoomLevel', 'tagMode']; protected $rules = ['tag' => 'required|between:1,200',]; - use ValidatingTrait; + use ValidatingTrait, SoftDeletes; /** * @param array $fields diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index 6a93196cfb..5b5036d7a0 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -27,6 +27,20 @@ use Watson\Validating\ValidatingTrait; class Transaction extends Model { + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + 'identifier' => 'int', + 'encrypted' => 'boolean', // model does not have these fields though + 'bill_name_encrypted' => 'boolean', + ]; protected $dates = ['created_at', 'updated_at', 'deleted_at']; protected $fillable = ['account_id', 'transaction_journal_id', 'description', 'amount', 'identifier']; protected $hidden = ['encrypted']; @@ -37,7 +51,6 @@ class Transaction extends Model 'description' => 'between:0,1024', 'amount' => 'required|numeric', ]; - use SoftDeletes, ValidatingTrait; /** diff --git a/app/Models/TransactionCurrency.php b/app/Models/TransactionCurrency.php index 3e48b6c1d4..aded707d80 100644 --- a/app/Models/TransactionCurrency.php +++ b/app/Models/TransactionCurrency.php @@ -27,11 +27,20 @@ class TransactionCurrency extends Model { use SoftDeletes, ValidatingTrait; - - protected $dates = ['created_at', 'updated_at', 'deleted_at']; + protected $dates = ['created_at', 'updated_at', 'deleted_at','date']; protected $fillable = ['name', 'code', 'symbol']; protected $rules = ['name' => 'required|between:1,200', 'code' => 'required|between:3,3', 'symbol' => 'required|between:1,12']; - + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + ]; /** * @param TransactionCurrency $currency * diff --git a/app/Models/TransactionGroup.php b/app/Models/TransactionGroup.php deleted file mode 100644 index 46ff2d6e2c..0000000000 --- a/app/Models/TransactionGroup.php +++ /dev/null @@ -1,46 +0,0 @@ -belongsToMany('FireflyIII\Models\TransactionJournal'); - } - - /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - */ - public function user() - { - return $this->belongsTo('FireflyIII\User'); - } - -} diff --git a/app/Models/TransactionJournal.php b/app/Models/TransactionJournal.php index 56773f7b5c..1cf5faf17f 100644 --- a/app/Models/TransactionJournal.php +++ b/app/Models/TransactionJournal.php @@ -34,6 +34,25 @@ class TransactionJournal extends TransactionJournalSupport { use SoftDeletes, ValidatingTrait; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + 'date' => 'date', + 'interest_date' => 'date', + 'book_date' => 'date', + 'process_date' => 'date', + 'order' => 'int', + 'tag_count' => 'int', + 'encrypted' => 'boolean', + 'completed' => 'boolean', + ]; /** @var array */ protected $dates = ['created_at', 'updated_at', 'date', 'deleted_at', 'interest_date', 'book_date', 'process_date']; /** @var array */ @@ -65,9 +84,9 @@ class TransactionJournal extends TransactionJournalSupport { if (auth()->check()) { $object = self::where('transaction_journals.id', $value) - ->with('transactionType') - ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') - ->where('user_id', auth()->user()->id)->first(['transaction_journals.*']); + ->with('transactionType') + ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') + ->where('user_id', auth()->user()->id)->first(['transaction_journals.*']); if (!is_null($object)) { return $object; } @@ -352,8 +371,8 @@ class TransactionJournal extends TransactionJournalSupport */ public function setDescriptionAttribute($value) { - $this->attributes['description'] = Crypt::encrypt($value); - $this->attributes['encrypted'] = true; + $this->attributes['description'] = $value; + $this->attributes['encrypted'] = false; } /** diff --git a/app/Models/TransactionJournalMeta.php b/app/Models/TransactionJournalMeta.php index 2f57d9ad27..6d54430a47 100644 --- a/app/Models/TransactionJournalMeta.php +++ b/app/Models/TransactionJournalMeta.php @@ -26,7 +26,18 @@ class TransactionJournalMeta extends Model { use SoftDeletes; - protected $dates = ['created_at', 'updated_at']; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + ]; + protected $dates = ['created_at', 'updated_at', 'deleted_at']; protected $fillable = ['transaction_journal_id', 'name', 'data', 'hash']; protected $table = 'journal_meta'; diff --git a/app/Models/TransactionType.php b/app/Models/TransactionType.php index 9d0e6af288..aceffbd8fb 100644 --- a/app/Models/TransactionType.php +++ b/app/Models/TransactionType.php @@ -31,6 +31,18 @@ class TransactionType extends Model const TRANSFER = 'Transfer'; const OPENING_BALANCE = 'Opening balance'; + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'date', + 'updated_at' => 'date', + 'deleted_at' => 'date', + ]; + protected $dates = ['created_at', 'updated_at', 'deleted_at']; /** diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php old mode 100755 new mode 100644 diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php old mode 100755 new mode 100644 diff --git a/app/Providers/BroadcastServiceProvider.php b/app/Providers/BroadcastServiceProvider.php old mode 100755 new mode 100644 diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php old mode 100755 new mode 100644 diff --git a/app/Providers/FireflyServiceProvider.php b/app/Providers/FireflyServiceProvider.php index 048c45c713..2a49d5b15e 100644 --- a/app/Providers/FireflyServiceProvider.php +++ b/app/Providers/FireflyServiceProvider.php @@ -98,21 +98,13 @@ class FireflyServiceProvider extends ServiceProvider // other generators $this->app->bind('FireflyIII\Export\ProcessorInterface', 'FireflyIII\Export\Processor'); + $this->app->bind('FireflyIII\Import\ImportProcedureInterface', 'FireflyIII\Import\ImportProcedure'); $this->app->bind('FireflyIII\Repositories\User\UserRepositoryInterface', 'FireflyIII\Repositories\User\UserRepository'); $this->app->bind('FireflyIII\Helpers\Attachments\AttachmentHelperInterface', 'FireflyIII\Helpers\Attachments\AttachmentHelper'); - $this->app->bind('FireflyIII\Generator\Chart\Bill\BillChartGeneratorInterface', 'FireflyIII\Generator\Chart\Bill\ChartJsBillChartGenerator'); - $this->app->bind('FireflyIII\Generator\Chart\Budget\BudgetChartGeneratorInterface', 'FireflyIII\Generator\Chart\Budget\ChartJsBudgetChartGenerator'); - $this->app->bind( - 'FireflyIII\Generator\Chart\Category\CategoryChartGeneratorInterface', 'FireflyIII\Generator\Chart\Category\ChartJsCategoryChartGenerator' - ); - $this->app->bind( - 'FireflyIII\Generator\Chart\PiggyBank\PiggyBankChartGeneratorInterface', 'FireflyIII\Generator\Chart\PiggyBank\ChartJsPiggyBankChartGenerator' - ); - $this->app->bind('FireflyIII\Generator\Chart\Report\ReportChartGeneratorInterface', 'FireflyIII\Generator\Chart\Report\ChartJsReportChartGenerator'); + $this->app->bind('FireflyIII\Helpers\Help\HelpInterface', 'FireflyIII\Helpers\Help\Help'); $this->app->bind('FireflyIII\Helpers\Report\ReportHelperInterface', 'FireflyIII\Helpers\Report\ReportHelper'); $this->app->bind('FireflyIII\Helpers\FiscalHelperInterface', 'FireflyIII\Helpers\FiscalHelper'); - $this->app->bind('FireflyIII\Helpers\Report\AccountReportHelperInterface', 'FireflyIII\Helpers\Report\AccountReportHelper'); $this->app->bind('FireflyIII\Helpers\Report\BalanceReportHelperInterface', 'FireflyIII\Helpers\Report\BalanceReportHelper'); $this->app->bind('FireflyIII\Helpers\Report\BudgetReportHelperInterface', 'FireflyIII\Helpers\Report\BudgetReportHelper'); } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php old mode 100755 new mode 100644 diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index 140b865fd3..ab2cc761bd 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -343,7 +343,9 @@ class AccountRepository implements AccountRepositoryInterface $account->save(); $this->updateMetadata($account, $data); - $this->updateInitialBalance($account, $data); + if ($this->validOpeningBalanceData($data)) { + $this->updateInitialBalance($account, $data); + } return $account; } @@ -438,7 +440,7 @@ class AccountRepository implements AccountRepositoryInterface { $amount = $data['openingBalance']; $name = $data['name']; - $opposing = $this->storeOpposingAccount($amount, $name); + $opposing = $this->storeOpposingAccount($name); $transactionType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first(); $journal = TransactionJournal::create( [ @@ -448,7 +450,6 @@ class AccountRepository implements AccountRepositoryInterface 'description' => 'Initial balance for "' . $account->name . '"', 'completed' => true, 'date' => $data['openingBalanceDate'], - 'encrypted' => true, ] ); Log::debug(sprintf('Created new opening balance journal: #%d', $journal->id)); @@ -481,17 +482,16 @@ class AccountRepository implements AccountRepositoryInterface * * @return Account */ - protected function storeOpposingAccount(float $amount, string $name): Account + protected function storeOpposingAccount(string $name): Account { - $type = $amount < 0 ? 'expense' : 'revenue'; $opposingData = [ - 'accountType' => $type, + 'accountType' => 'initial', 'name' => $name . ' initial balance', 'active' => false, 'iban' => '', 'virtualBalance' => 0, ]; - Log::debug('Going to create an opening balance opposing account'); + Log::debug('Going to create an opening balance opposing account.'); return $this->storeAccount($opposingData); } diff --git a/app/Repositories/Attachment/AttachmentRepository.php b/app/Repositories/Attachment/AttachmentRepository.php index 065b5c0167..b1e7bbbe78 100644 --- a/app/Repositories/Attachment/AttachmentRepository.php +++ b/app/Repositories/Attachment/AttachmentRepository.php @@ -18,6 +18,7 @@ use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; use FireflyIII\Models\Attachment; use FireflyIII\User; use Illuminate\Support\Collection; +use Storage; /** * Class AttachmentRepository @@ -56,6 +57,19 @@ class AttachmentRepository implements AttachmentRepositoryInterface return true; } + /** + * @param Attachment $attachment + * + * @return bool + */ + public function exists(Attachment $attachment): bool + { + /** @var Storage $disk */ + $disk = Storage::disk('upload'); + + return $disk->exists($attachment->fileName()); + } + /** * @return Collection */ @@ -82,6 +96,26 @@ class AttachmentRepository implements AttachmentRepositoryInterface return $query; } + /** + * @param Attachment $attachment + * + * @return string + */ + public function getContent(Attachment $attachment): string + { + // create a disk. + $disk = Storage::disk('upload'); + $file = $attachment->fileName(); + + if ($disk->exists($file)) { + $content = Crypt::decrypt($disk->get($file)); + + return $content; + } + + return ''; + } + /** * @param Attachment $attachment * @param array $data diff --git a/app/Repositories/Attachment/AttachmentRepositoryInterface.php b/app/Repositories/Attachment/AttachmentRepositoryInterface.php index 912dc67190..733e3bd59f 100644 --- a/app/Repositories/Attachment/AttachmentRepositoryInterface.php +++ b/app/Repositories/Attachment/AttachmentRepositoryInterface.php @@ -37,6 +37,20 @@ interface AttachmentRepositoryInterface */ public function get(): Collection; + /** + * @param Attachment $attachment + * + * @return bool + */ + public function exists(Attachment $attachment): bool; + + /** + * @param Attachment $attachment + * + * @return string + */ + public function getContent(Attachment $attachment): string; + /** * @param Carbon $start * @param Carbon $end diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index f4633d5ec3..92645343aa 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -17,10 +17,12 @@ use Carbon\Carbon; use FireflyIII\Events\StoredBudgetLimit; use FireflyIII\Events\UpdatedBudgetLimit; use FireflyIII\Helpers\Collector\JournalCollectorInterface; +use FireflyIII\Models\AvailableBudget; use FireflyIII\Models\Budget; use FireflyIII\Models\BudgetLimit; use FireflyIII\Models\LimitRepetition; use FireflyIII\Models\Transaction; +use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; use FireflyIII\User; @@ -201,15 +203,51 @@ class BudgetRepository implements BudgetRepositoryInterface { $query = LimitRepetition::leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id') ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') - ->where('limit_repetitions.startdate', '<=', $end->format('Y-m-d 00:00:00')) - ->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d 00:00:00')) - ->where('budgets.user_id', $this->user->id); + ->where( + function (Builder $q1) use ($start, $end) { + $q1->where( + function (Builder $q2) use ($start, $end) { + $q2->where('limit_repetitions.enddate', '>=', $start->format('Y-m-d 00:00:00')); + $q2->where('limit_repetitions.enddate', '<=', $end->format('Y-m-d 00:00:00')); + } + ) + ->orWhere( + function (Builder $q3) use ($start, $end) { + $q3->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d 00:00:00')); + $q3->where('limit_repetitions.startdate', '<=', $end->format('Y-m-d 00:00:00')); + } + ); + } + ) + ->where('budgets.user_id', $this->user->id) + ->whereNull('budgets.deleted_at'); $set = $query->get(['limit_repetitions.*', 'budget_limits.budget_id']); return $set; } + /** + * @param TransactionCurrency $currency + * @param Carbon $start + * @param Carbon $end + * + * @return string + */ + public function getAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end): string + { + $amount = '0'; + $availableBudget = $this->user->availableBudgets() + ->where('transaction_currency_id', $currency->id) + ->where('start_date', $start->format('Y-m-d')) + ->where('end_date', $end->format('Y-m-d'))->first(); + if (!is_null($availableBudget)) { + $amount = strval($availableBudget->amount); + } + + return $amount; + } + /** * This method is being used to generate the budget overview in the year/multi-year report. Its used * in both the year/multi-year budget overview AND in the accompanying chart. @@ -322,6 +360,33 @@ class BudgetRepository implements BudgetRepositoryInterface return $result; } + /** + * @param TransactionCurrency $currency + * @param Carbon $start + * @param Carbon $end + * @param string $amount + * + * @return bool + */ + public function setAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end, string $amount): bool + { + $availableBudget = $this->user->availableBudgets() + ->where('transaction_currency_id', $currency->id) + ->where('start_date', $start->format('Y-m-d')) + ->where('end_date', $end->format('Y-m-d'))->first(); + if (is_null($availableBudget)) { + $availableBudget = new AvailableBudget; + $availableBudget->user()->associate($this->user); + $availableBudget->transactionCurrency()->associate($currency); + $availableBudget->start_date = $start; + $availableBudget->end_date = $end; + } + $availableBudget->amount = $amount; + $availableBudget->save(); + + return true; + } + /** * @param Collection $budgets * @param Collection $accounts @@ -333,10 +398,11 @@ class BudgetRepository implements BudgetRepositoryInterface public function spentInPeriod(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): string { // collect amount of transaction journals, which is easy: - $budgetIds = $budgets->pluck('id')->toArray(); + $budgetIds = $budgets->pluck('id')->toArray(); + $accountIds = $accounts->pluck('id')->toArray(); - Log::debug('spentInPeriod: Now in spentInPeriod for these budgets: ', $budgetIds); + Log::debug(sprintf('spentInPeriod: Now in spentInPeriod for these budgets (%d): ', count($budgetIds)), $budgetIds); Log::debug('spentInPeriod: and these accounts: ', $accountIds); Log::debug(sprintf('spentInPeriod: Start date is "%s", end date is "%s"', $start->format('Y-m-d'), $end->format('Y-m-d'))); diff --git a/app/Repositories/Budget/BudgetRepositoryInterface.php b/app/Repositories/Budget/BudgetRepositoryInterface.php index 30633beff9..8d04c7bff6 100644 --- a/app/Repositories/Budget/BudgetRepositoryInterface.php +++ b/app/Repositories/Budget/BudgetRepositoryInterface.php @@ -16,6 +16,7 @@ namespace FireflyIII\Repositories\Budget; use Carbon\Carbon; use FireflyIII\Models\Budget; use FireflyIII\Models\BudgetLimit; +use FireflyIII\Models\TransactionCurrency; use Illuminate\Support\Collection; /** @@ -90,6 +91,15 @@ interface BudgetRepositoryInterface */ public function getAllBudgetLimitRepetitions(Carbon $start, Carbon $end): Collection; + /** + * @param TransactionCurrency $currency + * @param Carbon $start + * @param Carbon $end + * + * @return string + */ + public function getAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end): string; + /** * * @param Collection $budgets @@ -120,6 +130,16 @@ interface BudgetRepositoryInterface */ public function getNoBudgetPeriodReport(Collection $accounts, Carbon $start, Carbon $end): array; + /** + * @param TransactionCurrency $currency + * @param Carbon $start + * @param Carbon $end + * @param string $amount + * + * @return bool + */ + public function setAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end, string $amount): bool; + /** * @param Collection $budgets * @param Collection $accounts diff --git a/app/Repositories/ExportJob/ExportJobRepository.php b/app/Repositories/ExportJob/ExportJobRepository.php index 1aae76d43e..acb8999786 100644 --- a/app/Repositories/ExportJob/ExportJobRepository.php +++ b/app/Repositories/ExportJob/ExportJobRepository.php @@ -17,6 +17,7 @@ use Carbon\Carbon; use FireflyIII\Models\ExportJob; use FireflyIII\User; use Illuminate\Support\Str; +use Storage; /** * Class ExportJobRepository @@ -94,6 +95,19 @@ class ExportJobRepository implements ExportJobRepositoryInterface } + /** + * @param ExportJob $job + * + * @return bool + */ + public function exists(ExportJob $job): bool + { + $disk = Storage::disk('export'); + $file = $job->key . '.zip'; + + return $disk->exists($file); + } + /** * @param string $key * @@ -109,4 +123,17 @@ class ExportJobRepository implements ExportJobRepositoryInterface return $result; } + /** + * @param ExportJob $job + * + * @return string + */ + public function getContent(ExportJob $job): string + { + $disk = Storage::disk('export'); + $file = $job->key . '.zip'; + $content = $disk->get($file); + + return $content; + } } diff --git a/app/Repositories/ExportJob/ExportJobRepositoryInterface.php b/app/Repositories/ExportJob/ExportJobRepositoryInterface.php index c9d6167873..650aac15a6 100644 --- a/app/Repositories/ExportJob/ExportJobRepositoryInterface.php +++ b/app/Repositories/ExportJob/ExportJobRepositoryInterface.php @@ -32,6 +32,13 @@ interface ExportJobRepositoryInterface */ public function create(): ExportJob; + /** + * @param ExportJob $job + * + * @return bool + */ + public function exists(ExportJob $job): bool; + /** * @param string $key * @@ -39,4 +46,11 @@ interface ExportJobRepositoryInterface */ public function findByKey(string $key): ExportJob; + /** + * @param ExportJob $job + * + * @return string + */ + public function getContent(ExportJob $job): string; + } diff --git a/app/Repositories/User/UserRepository.php b/app/Repositories/User/UserRepository.php index f33171c1e4..6e38137f9c 100644 --- a/app/Repositories/User/UserRepository.php +++ b/app/Repositories/User/UserRepository.php @@ -148,4 +148,17 @@ class UserRepository implements UserRepositoryInterface return $return; } + + /** + * @param User $user + * @param string $password + * + * @return bool + */ + public function changePassword(User $user, string $password): bool + { + $user->password = bcrypt($password); + $user->save(); + return true; + } } diff --git a/app/Repositories/User/UserRepositoryInterface.php b/app/Repositories/User/UserRepositoryInterface.php index 66283a9ba0..93e34a7a14 100644 --- a/app/Repositories/User/UserRepositoryInterface.php +++ b/app/Repositories/User/UserRepositoryInterface.php @@ -41,6 +41,14 @@ interface UserRepositoryInterface */ public function attachRole(User $user, string $role): bool; + /** + * @param User $user + * @param string $password + * + * @return mixed + */ + public function changePassword(User $user, string $password); + /** * Returns a count of all users. * diff --git a/app/Rules/Factory/ActionFactory.php b/app/Rules/Factory/ActionFactory.php index a73c1c23b2..9bbdb7468d 100644 --- a/app/Rules/Factory/ActionFactory.php +++ b/app/Rules/Factory/ActionFactory.php @@ -10,13 +10,6 @@ */ declare(strict_types = 1); -/** - * ActionFactory.php - * Copyright (C) 2016 Robert Horlings - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ namespace FireflyIII\Rules\Factory; diff --git a/app/Support/CacheProperties.php b/app/Support/CacheProperties.php index 105115f959..b8e493d134 100644 --- a/app/Support/CacheProperties.php +++ b/app/Support/CacheProperties.php @@ -76,8 +76,6 @@ class CacheProperties public function has(): bool { if (getenv('APP_ENV') == 'testing') { - Log::debug('APP_ENV is testing, cache disabled.'); - return false; } $this->md5(); diff --git a/app/Support/ChartColour.php b/app/Support/ChartColour.php index 5ae8f881c0..c04b75b28e 100644 --- a/app/Support/ChartColour.php +++ b/app/Support/ChartColour.php @@ -53,4 +53,4 @@ class ChartColour return sprintf('rgba(%d, %d, %d, 0.7)', $row[0], $row[1], $row[2]); } -} \ No newline at end of file +} diff --git a/app/Support/ExpandedForm.php b/app/Support/ExpandedForm.php index 0943ac9a00..50e3398f26 100644 --- a/app/Support/ExpandedForm.php +++ b/app/Support/ExpandedForm.php @@ -283,6 +283,24 @@ class ExpandedForm return $html; } + /** + * @param $name + * @param null $value + * @param array $options + * + * @return string + */ + public function password(string $name, array $options = []): string + { + $label = $this->label($name, $options); + $options = $this->expandOptionArray($name, $label, $options); + $classes = $this->getHolderClasses($name); + $html = view('form.password', compact('classes', 'name', 'label', 'value', 'options'))->render(); + + return $html; + + } + /** * @param $name * @param array $list @@ -341,24 +359,6 @@ class ExpandedForm return $html; } - /** - * @param $name - * @param null $value - * @param array $options - * - * @return string - */ - public function password(string $name, array $options = []): string - { - $label = $this->label($name, $options); - $options = $this->expandOptionArray($name, $label, $options); - $classes = $this->getHolderClasses($name); - $html = view('form.password', compact('classes', 'name', 'label', 'value', 'options'))->render(); - - return $html; - - } - /** * @param $name * @param null $value @@ -496,11 +496,20 @@ class ExpandedForm $classes = $this->getHolderClasses($name); $value = $this->fillFieldValue($name, $value); $options['step'] = 'any'; - $options['min'] = '0.01'; + if ($view !== 'balance') { + $options['min'] = '0.01'; + } $defaultCurrency = isset($options['currency']) ? $options['currency'] : Amt::getDefaultCurrency(); $currencies = Amt::getAllCurrencies(); unset($options['currency']); unset($options['placeholder']); + + // make sure value is formatted nicely: + if (!is_null($value) && $value !== '') { + $value = round($value, 2); + } + + $html = view('form.' . $view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render(); return $html; diff --git a/app/Support/Migration/TestData.php b/app/Support/Migration/TestData.php deleted file mode 100644 index dab024765c..0000000000 --- a/app/Support/Migration/TestData.php +++ /dev/null @@ -1,897 +0,0 @@ -data = $data; - $start = new Carbon; - $start->startOfYear(); - $start->subYears(2); - $end = new Carbon; - - $this->start = $start; - $this->end = $end; - $this->time = $end->format('Y-m-d H:i:s'); - } - - /** - * @param array $data - */ - public static function run(array $data) - { - $seeder = new TestData($data); - $seeder->go(); - } - - /** - * - */ - private function createAccounts() - { - $insert = []; - foreach ($this->data['accounts'] as $account) { - $insert[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'user_id' => $account['user_id'], - 'account_type_id' => $account['account_type_id'], - 'name' => $account['name'], - 'active' => 1, - 'encrypted' => 0, - 'virtual_balance' => 0, - 'iban' => isset($account['iban']) ? Crypt::encrypt($account['iban']) : null, - ]; - } - DB::table('accounts')->insert($insert); - $insert = []; - foreach ($this->data['account-meta'] as $meta) { - $insert[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'account_id' => $meta['account_id'], - 'name' => $meta['name'], - 'data' => $meta['data'], - ]; - } - DB::table('account_meta')->insert($insert); - } - - /** - * - */ - private function createAttachments() - { - $disk = Storage::disk('upload'); - foreach ($this->data['attachments'] as $attachment) { - $data = Crypt::encrypt($attachment['content']); - $attachmentId = DB::table('attachments')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'attachable_id' => $attachment['attachable_id'], - 'attachable_type' => $attachment['attachable_type'], - 'user_id' => $attachment['user_id'], - 'md5' => md5($attachment['content']), - 'filename' => Crypt::encrypt($attachment['filename']), - 'title' => Crypt::encrypt($attachment['title']), - 'description' => Crypt::encrypt($attachment['description']), - 'notes' => Crypt::encrypt($attachment['notes']), - 'mime' => Crypt::encrypt($attachment['mime']), - 'size' => strlen($attachment['content']), - 'uploaded' => 1, - ] - ); - - $disk->put('at-' . $attachmentId . '.data', $data); - } - } - - /** - * - */ - private function createBills() - { - $insert = []; - foreach ($this->data['bills'] as $bill) { - $insert[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'user_id' => $bill['user_id'], - 'name' => Crypt::encrypt($bill['name']), - 'match' => Crypt::encrypt($bill['match']), - 'amount_min' => $bill['amount_min'], - 'amount_max' => $bill['amount_max'], - 'date' => $bill['date'], - 'active' => $bill['active'], - 'automatch' => $bill['automatch'], - 'repeat_freq' => $bill['repeat_freq'], - 'skip' => $bill['skip'], - 'name_encrypted' => 1, - 'match_encrypted' => 1, - ]; - } - DB::table('bills')->insert($insert); - } - - /** - * - */ - private function createBudgets() - { - $insert = []; - foreach ($this->data['budgets'] as $budget) { - $insert[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'user_id' => $budget['user_id'], - 'name' => Crypt::encrypt($budget['name']), - 'encrypted' => 1, - ]; - } - DB::table('budgets')->insert($insert); - - foreach ($this->data['budget-limits'] as $limit) { - $amount = rand($limit['amount_min'], $limit['amount_max']); - $limitId = DB::table('budget_limits')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'budget_id' => $limit['budget_id'], - 'startdate' => $limit['startdate'], - 'amount' => $amount, - 'repeats' => 0, - 'repeat_freq' => $limit['repeat_freq'], - ] - ); - - DB::table('limit_repetitions')->insert( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'budget_limit_id' => $limitId, - 'startdate' => $limit['startdate'], - 'enddate' => Navigation::endOfPeriod(new Carbon($limit['startdate']), $limit['repeat_freq'])->format('Y-m-d'), - 'amount' => $amount, - ] - ); - } - $current = clone $this->start; - while ($current <= $this->end) { - foreach ($this->data['monthly-limits'] as $limit) { - $amount = rand($limit['amount_min'], $limit['amount_max']); - $limitId = DB::table('budget_limits')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'budget_id' => $limit['budget_id'], - 'startdate' => $current->format('Y-m-d'), - 'amount' => $amount, - 'repeats' => 0, - 'repeat_freq' => 'monthly', - ] - ); - - DB::table('limit_repetitions')->insert( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'budget_limit_id' => $limitId, - 'startdate' => $current->format('Y-m-d'), - 'enddate' => Navigation::endOfPeriod($current, 'monthly')->format('Y-m-d'), - 'amount' => $amount, - ] - ); - } - - $current->addMonth(); - } - - } - - /** - * - */ - private function createCategories() - { - $insert = []; - foreach ($this->data['categories'] as $category) { - $insert[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'user_id' => $category['user_id'], - 'name' => Crypt::encrypt($category['name']), - 'encrypted' => 1, - ]; - } - 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 createExportJobs() - { - $insert = []; - $disk = Storage::disk('export'); - foreach ($this->data['export-jobs'] as $job) { - $insert[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'user_id' => $job['user_id'], - 'key' => $job['key'], - 'status' => $job['status'], - ]; - $disk->put($job['key'] . '.zip', 'Nonsense data for "ziP" file.'); - } - DB::table('export_jobs')->insert($insert); - - // store fake export file: - - } - - /** - * - */ - private function createImportJobs() - { - - $disk = Storage::disk('upload'); - $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'], - 'extended_status' => json_encode($job['extended_status']), - 'configuration' => json_encode($job['configuration']), - ]; - - $disk->put($job['key'] . '.upload', Crypt::encrypt('')); - } - DB::table('import_jobs')->insert($insert); - } - - /** - * - */ - private function createJournals() - { - $current = clone $this->start; - $transactions = []; - while ($current <= $this->end) { - $date = $current->format('Y-m-'); - $month = $current->format('F'); - - // run all monthly withdrawals: - foreach ($this->data['monthly-withdrawals'] as $withdrawal) { - $description = str_replace(':month', $month, $withdrawal['description']); - $journalId = DB::table('transaction_journals')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'user_id' => $withdrawal['user_id'], - 'transaction_type_id' => 1, - 'bill_id' => $withdrawal['bill_id'] ?? null, - 'transaction_currency_id' => 1, - 'description' => Crypt::encrypt($description), - 'completed' => 1, - 'date' => $date . $withdrawal['day-of-month'], - 'interest_date' => $withdrawal['interest_date'] ?? null, - 'book_date' => $withdrawal['book_date'] ?? null, - 'process_date' => $withdrawal['process_date'] ?? null, - 'encrypted' => 1, - 'order' => 0, - 'tag_count' => 0, - ] - ); - $amount = (rand($withdrawal['min_amount'] * 100, $withdrawal['max_amount'] * 100)) / 100; - $transactions[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'transaction_journal_id' => $journalId, - 'account_id' => $withdrawal['source_id'], - 'amount' => $amount * -1, - ]; - $transactions[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'transaction_journal_id' => $journalId, - 'account_id' => $withdrawal['destination_id'], - 'amount' => $amount, - ]; - - // link to budget if set. - if (isset($withdrawal['budget_id'])) { - DB::table('budget_transaction_journal')->insert( - [ - 'budget_id' => $withdrawal['budget_id'], - 'transaction_journal_id' => $journalId, - - ] - ); - } - // link to category if set. - if (isset($withdrawal['category_id'])) { - DB::table('category_transaction_journal')->insert( - [ - 'category_id' => $withdrawal['category_id'], - 'transaction_journal_id' => $journalId, - - ] - ); - } - } - - // run all monthly deposits: - foreach ($this->data['monthly-deposits'] as $deposit) { - $description = str_replace(':month', $month, $deposit['description']); - $journalId = DB::table('transaction_journals')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'user_id' => $deposit['user_id'], - 'transaction_type_id' => 2, - 'bill_id' => $deposit['bill_id'] ?? null, - 'transaction_currency_id' => 1, - 'description' => Crypt::encrypt($description), - 'completed' => 1, - 'date' => $date . $deposit['day-of-month'], - 'interest_date' => $deposit['interest_date'] ?? null, - 'book_date' => $deposit['book_date'] ?? null, - 'process_date' => $deposit['process_date'] ?? null, - 'encrypted' => 1, - 'order' => 0, - 'tag_count' => 0, - ] - ); - $amount = (rand($deposit['min_amount'] * 100, $deposit['max_amount'] * 100)) / 100; - $transactions[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'transaction_journal_id' => $journalId, - 'account_id' => $deposit['source_id'], - 'amount' => $amount * -1, - ]; - $transactions[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'transaction_journal_id' => $journalId, - 'account_id' => $deposit['destination_id'], - 'amount' => $amount, - ]; - - // link to category if set. - if (isset($deposit['category_id'])) { - DB::table('category_transaction_journal')->insert( - [ - 'category_id' => $deposit['category_id'], - 'transaction_journal_id' => $journalId, - - ] - ); - } - } - // run all monthly transfers: - foreach ($this->data['monthly-transfers'] as $transfer) { - $description = str_replace(':month', $month, $transfer['description']); - $journalId = DB::table('transaction_journals')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'user_id' => $transfer['user_id'], - 'transaction_type_id' => 3, - 'bill_id' => $transfer['bill_id'] ?? null, - 'transaction_currency_id' => 1, - 'description' => Crypt::encrypt($description), - 'completed' => 1, - 'date' => $date . $transfer['day-of-month'], - 'interest_date' => $transfer['interest_date'] ?? null, - 'book_date' => $transfer['book_date'] ?? null, - 'process_date' => $transfer['process_date'] ?? null, - 'encrypted' => 1, - 'order' => 0, - 'tag_count' => 0, - ] - ); - $amount = (rand($transfer['min_amount'] * 100, $transfer['max_amount'] * 100)) / 100; - $transactions[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'transaction_journal_id' => $journalId, - 'account_id' => $transfer['source_id'], - 'amount' => $amount * -1, - ]; - $transactions[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'transaction_journal_id' => $journalId, - 'account_id' => $transfer['destination_id'], - 'amount' => $amount, - ]; - // link to category if set. - if (isset($transfer['category_id'])) { - DB::table('category_transaction_journal')->insert( - [ - 'category_id' => $transfer['category_id'], - 'transaction_journal_id' => $journalId, - - ] - ); - } - } - DB::table('transactions')->insert($transactions); - $transactions = []; - $current->addMonth(); - } - - - } - - /** - * - */ - private function createMultiDeposits() - { - foreach ($this->data['multi-deposits'] as $deposit) { - $journalId = DB::table('transaction_journals')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'user_id' => $deposit['user_id'], - 'transaction_type_id' => 2, - 'transaction_currency_id' => 1, - 'description' => Crypt::encrypt($deposit['description']), - 'completed' => 1, - 'date' => $deposit['date'], - 'interest_date' => $deposit['interest_date'] ?? null, - 'book_date' => $deposit['book_date'] ?? null, - 'process_date' => $deposit['process_date'] ?? null, - 'encrypted' => 1, - 'order' => 0, - 'tag_count' => 0, - ] - ); - $identifier = 0; - foreach ($deposit['source_ids'] as $index => $source) { - $description = $deposit['description'] . ' (#' . ($index + 1) . ')'; - $amount = $deposit['amounts'][$index]; - $first = DB::table('transactions')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'account_id' => $deposit['destination_id'], - 'transaction_journal_id' => $journalId, - 'description' => $description, - 'amount' => $amount, - 'identifier' => $identifier, - ] - ); - $second = DB::table('transactions')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'account_id' => $source, - 'transaction_journal_id' => $journalId, - 'description' => $description, - 'amount' => $amount * -1, - 'identifier' => $identifier, - ] - ); - $identifier++; - // link first and second to budget and category, if present. - - if (isset($deposit['category_ids'][$index])) { - DB::table('category_transaction')->insert( - [ - 'category_id' => $deposit['category_ids'][$index], - 'transaction_id' => $first, - ] - ); - DB::table('category_transaction')->insert( - [ - 'category_id' => $deposit['category_ids'][$index], - 'transaction_id' => $second, - ] - ); - } - } - } - } - - private function createMultiTransfers() - { - foreach ($this->data['multi-transfers'] as $transfer) { - $journalId = DB::table('transaction_journals')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'user_id' => $transfer['user_id'], - 'transaction_type_id' => 3, - 'transaction_currency_id' => 1, - 'description' => Crypt::encrypt($transfer['description']), - 'completed' => 1, - 'date' => $transfer['date'], - 'interest_date' => $transfer['interest_date'] ?? null, - 'book_date' => $transfer['book_date'] ?? null, - 'process_date' => $transfer['process_date'] ?? null, - 'encrypted' => 1, - 'order' => 0, - 'tag_count' => 0, - ] - ); - $identifier = 0; - foreach ($transfer['destination_ids'] as $index => $destination) { - $description = $transfer['description'] . ' (#' . ($index + 1) . ')'; - $amount = $transfer['amounts'][$index]; - $source = $transfer['source_ids'][$index]; - $first = DB::table('transactions')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'account_id' => $source, - 'transaction_journal_id' => $journalId, - 'description' => $description, - 'amount' => $amount * -1, - 'identifier' => $identifier, - ] - ); - $second = DB::table('transactions')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'account_id' => $destination, - 'transaction_journal_id' => $journalId, - 'description' => $description, - 'amount' => $amount, - 'identifier' => $identifier, - ] - ); - $identifier++; - if (isset($transfer['category_ids'][$index])) { - DB::table('category_transaction')->insert( - [ - 'category_id' => $transfer['category_ids'][$index], - 'transaction_id' => $first, - ] - ); - DB::table('category_transaction')->insert( - [ - 'category_id' => $transfer['category_ids'][$index], - 'transaction_id' => $second, - ] - ); - } - } - } - } - - /** - * - */ - private function createMultiWithdrawals() - { - foreach ($this->data['multi-withdrawals'] as $withdrawal) { - $journalId = DB::table('transaction_journals')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'user_id' => $withdrawal['user_id'], - 'transaction_type_id' => 1, - 'transaction_currency_id' => 1, - 'description' => Crypt::encrypt($withdrawal['description']), - 'completed' => 1, - 'date' => $withdrawal['date'], - 'interest_date' => $withdrawal['interest_date'] ?? null, - 'book_date' => $withdrawal['book_date'] ?? null, - 'process_date' => $withdrawal['process_date'] ?? null, - 'encrypted' => 1, - 'order' => 0, - 'tag_count' => 0, - ] - ); - $identifier = 0; - foreach ($withdrawal['destination_ids'] as $index => $destination) { - $description = $withdrawal['description'] . ' (#' . ($index + 1) . ')'; - $amount = $withdrawal['amounts'][$index]; - $first = DB::table('transactions')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'account_id' => $withdrawal['source_id'], - 'transaction_journal_id' => $journalId, - 'description' => $description, - 'amount' => $amount * -1, - 'identifier' => $identifier, - ] - ); - $second = DB::table('transactions')->insertGetId( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'account_id' => $destination, - 'transaction_journal_id' => $journalId, - 'description' => $description, - 'amount' => $amount, - 'identifier' => $identifier, - ] - ); - $identifier++; - // link first and second to budget and category, if present. - if (isset($withdrawal['budget_ids'][$index])) { - DB::table('budget_transaction')->insert( - [ - 'budget_id' => $withdrawal['budget_ids'][$index], - 'transaction_id' => $first, - ] - ); - DB::table('budget_transaction')->insert( - [ - 'budget_id' => $withdrawal['budget_ids'][$index], - 'transaction_id' => $second, - ] - ); - } - - if (isset($withdrawal['category_ids'][$index])) { - DB::table('category_transaction')->insert( - [ - 'category_id' => $withdrawal['category_ids'][$index], - 'transaction_id' => $first, - ] - ); - DB::table('category_transaction')->insert( - [ - 'category_id' => $withdrawal['category_ids'][$index], - 'transaction_id' => $second, - ] - ); - } - } - } - } - - /** - * - */ - private function createPiggyBanks() - { - 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'], - 'order' => $piggyBank['order'], - 'encrypted' => 1, - ] - ); - if (isset($piggyBank['currentamount'])) { - DB::table('piggy_bank_repetitions')->insert( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'piggy_bank_id' => $piggyId, - 'startdate' => $piggyBank['startdate'], - 'currentamount' => $piggyBank['currentamount'], - ] - ); - } - } - - foreach ($this->data['piggy-events'] as $event) { - DB::table('piggy_bank_events')->insert( - [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'piggy_bank_id' => $event['piggy_bank_id'], - 'date' => $event['date'], - 'amount' => $event['amount'], - ] - ); - } - } - - /** - * - */ - private function createRules() - { - $insert = []; - foreach ($this->data['rule-groups'] as $group) { - $insert[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'user_id' => $group['user_id'], - 'order' => $group['order'], - 'title' => $group['title'], - 'description' => $group['description'], - 'active' => 1, - ]; - } - DB::table('rule_groups')->insert($insert); - $insert = []; - foreach ($this->data['rules'] as $rule) { - $insert[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'user_id' => $rule['user_id'], - 'rule_group_id' => $rule['rule_group_id'], - 'order' => $rule['order'], - 'active' => $rule['active'], - 'stop_processing' => $rule['stop_processing'], - 'title' => $rule['title'], - 'description' => $rule['description'], - ]; - } - DB::table('rules')->insert($insert); - - $insert = []; - foreach ($this->data['rule-triggers'] as $trigger) { - $insert[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'rule_id' => $trigger['rule_id'], - 'order' => $trigger['order'], - 'active' => $trigger['active'], - 'stop_processing' => $trigger['stop_processing'], - 'trigger_type' => $trigger['trigger_type'], - 'trigger_value' => $trigger['trigger_value'], - ]; - } - DB::table('rule_triggers')->insert($insert); - - $insert = []; - foreach ($this->data['rule-actions'] as $action) { - $insert[] = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'rule_id' => $action['rule_id'], - 'order' => $action['order'], - 'active' => $action['active'], - 'stop_processing' => $action['stop_processing'], - 'action_type' => $action['action_type'], - 'action_value' => $action['action_value'], - ]; - } - DB::table('rule_actions')->insert($insert); - } - - /** - * - */ - private function createTags() - { - $insert = []; - foreach ($this->data['tags'] as $tag) { - $insert[] - = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'user_id' => $tag['user_id'], - 'tag' => Crypt::encrypt($tag['tag']), - 'tagMode' => $tag['tagMode'], - 'date' => $tag['date'] ?? null, - ]; - - } - DB::table('tags')->insert($insert); - } - - /** - * - */ - private function createUsers() - { - $insert = []; - foreach ($this->data['users'] as $user) { - $insert[] - = [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'email' => $user['email'], - 'remember_token' => '', - 'password' => bcrypt($user['password']), - ]; - - } - DB::table('users')->insert($insert); - $insert = []; - foreach ($this->data['roles'] as $role) { - $insert[] - = [ - 'user_id' => $role['user_id'], - 'role_id' => $role['role'], - ]; - } - DB::table('role_user')->insert($insert); - } - - /** - * - */ - private function go() - { - $this->createUsers(); - $this->createAccounts(); - $this->createBills(); - $this->createBudgets(); - $this->createCategories(); - $this->createPiggyBanks(); - $this->createRules(); - $this->createTags(); - $this->createJournals(); - $this->createAttachments(); - $this->createMultiWithdrawals(); - $this->createMultiDeposits(); - $this->createMultiTransfers(); - $this->createImportJobs(); - $this->createCurrencies(); - $this->createExportJobs(); - } - -} diff --git a/app/Support/Search/Search.php b/app/Support/Search/Search.php index a3da570829..d011bdd0fd 100644 --- a/app/Support/Search/Search.php +++ b/app/Support/Search/Search.php @@ -16,6 +16,7 @@ namespace FireflyIII\Support\Search; use FireflyIII\Helpers\Collector\JournalCollector; use FireflyIII\Models\Account; +use FireflyIII\Models\AccountType; use FireflyIII\Models\Budget; use FireflyIII\Models\Category; use FireflyIII\Models\Tag; @@ -56,7 +57,9 @@ class Search implements SearchInterface */ public function searchAccounts(array $words): Collection { - $accounts = $this->user->accounts()->get(); + $accounts = $this->user->accounts() + ->accountTypeIn([AccountType::DEFAULT, AccountType::ASSET, AccountType::EXPENSE, AccountType::REVENUE, AccountType::BENEFICIARY]) + ->get(['accounts.*']); /** @var Collection $result */ $result = $accounts->filter( function (Account $account) use ($words) { diff --git a/app/Support/Twig/Journal.php b/app/Support/Twig/Journal.php index e98f0ee070..65aac8e818 100644 --- a/app/Support/Twig/Journal.php +++ b/app/Support/Twig/Journal.php @@ -16,6 +16,7 @@ namespace FireflyIII\Support\Twig; use Amount; use FireflyIII\Models\Account; +use FireflyIII\Models\AccountType; use FireflyIII\Models\Budget as ModelBudget; use FireflyIII\Models\Category; use FireflyIII\Models\TransactionJournal; @@ -142,7 +143,7 @@ class Journal extends Twig_Extension $array = []; /** @var Account $entry */ foreach ($list as $entry) { - if ($entry->accountType->type == 'Cash account') { + if ($entry->accountType->type == AccountType::CASH) { $array[] = '(cash)'; continue; } @@ -153,7 +154,6 @@ class Journal extends Twig_Extension $cache->store($result); return $result; - } ); } diff --git a/app/User.php b/app/User.php old mode 100755 new mode 100644 index ba57a8ce47..763d33d92c --- a/app/User.php +++ b/app/User.php @@ -51,6 +51,15 @@ class User extends Authenticatable */ protected $table = 'users'; + + /** + * @return HasMany + */ + public function availableBudgets(): HasMany + { + return $this->hasMany('FireflyIII\Models\AvailableBudget'); + } + /** * @return HasMany */ diff --git a/bootstrap/app.php b/bootstrap/app.php old mode 100755 new mode 100644 diff --git a/bootstrap/autoload.php b/bootstrap/autoload.php old mode 100755 new mode 100644 diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore old mode 100755 new mode 100644 diff --git a/composer.json b/composer.json index 7deaaacb03..27a784e1bf 100755 --- a/composer.json +++ b/composer.json @@ -47,7 +47,8 @@ "symfony/css-selector": "3.1.*", "symfony/dom-crawler": "3.1.*", "barryvdh/laravel-debugbar": "2.*", - "barryvdh/laravel-ide-helper": "2.*" + "barryvdh/laravel-ide-helper": "2.*", + "johnkary/phpunit-speedtrap": "^1.0" }, "autoload": { "classmap": [ diff --git a/composer.lock b/composer.lock index b165ea68f1..2c128e7a1a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "a459d7a851be2a23929156fac720aa13", - "content-hash": "19ebf906c75d026c93d83cb8186e5d27", + "content-hash": "38cc0ca42a8c6c518d99045c4bfe5d19", "packages": [ { "name": "bacon/bacon-qr-code", @@ -47,7 +46,7 @@ ], "description": "BaconQrCode is a QR code generator for PHP.", "homepage": "https://github.com/Bacon/BaconQrCode", - "time": "2016-01-09 22:55:35" + "time": "2016-01-09T22:55:35+00:00" }, { "name": "christian-riesen/base32", @@ -101,7 +100,7 @@ "encode", "rfc4648" ], - "time": "2016-05-05 11:49:03" + "time": "2016-05-05T11:49:03+00:00" }, { "name": "classpreloader/classpreloader", @@ -155,7 +154,7 @@ "class", "preload" ], - "time": "2016-09-16 12:50:15" + "time": "2016-09-16T12:50:15+00:00" }, { "name": "davejamesmiller/laravel-breadcrumbs", @@ -204,7 +203,7 @@ "keywords": [ "laravel" ], - "time": "2016-08-28 16:57:03" + "time": "2016-08-28T16:57:03+00:00" }, { "name": "dnoegel/php-xdg-base-dir", @@ -237,7 +236,7 @@ "MIT" ], "description": "implementation of xdg base directory specification for php", - "time": "2014-10-24 07:27:01" + "time": "2014-10-24T07:27:01+00:00" }, { "name": "doctrine/annotations", @@ -305,7 +304,7 @@ "docblock", "parser" ], - "time": "2016-10-24 11:45:47" + "time": "2016-10-24T11:45:47+00:00" }, { "name": "doctrine/cache", @@ -375,7 +374,7 @@ "cache", "caching" ], - "time": "2016-10-29 11:16:17" + "time": "2016-10-29T11:16:17+00:00" }, { "name": "doctrine/collections", @@ -441,7 +440,7 @@ "collections", "iterator" ], - "time": "2015-04-14 22:21:58" + "time": "2015-04-14T22:21:58+00:00" }, { "name": "doctrine/common", @@ -514,7 +513,7 @@ "persistence", "spl" ], - "time": "2016-11-30 16:50:46" + "time": "2016-11-30T16:50:46+00:00" }, { "name": "doctrine/dbal", @@ -585,7 +584,7 @@ "persistence", "queryobject" ], - "time": "2016-09-09 19:13:33" + "time": "2016-09-09T19:13:33+00:00" }, { "name": "doctrine/inflector", @@ -652,7 +651,7 @@ "singularize", "string" ], - "time": "2015-11-06 14:35:42" + "time": "2015-11-06T14:35:42+00:00" }, { "name": "doctrine/lexer", @@ -706,7 +705,7 @@ "lexer", "parser" ], - "time": "2014-09-09 13:34:57" + "time": "2014-09-09T13:34:57+00:00" }, { "name": "jakub-onderka/php-console-color", @@ -749,7 +748,7 @@ "homepage": "http://www.acci.cz" } ], - "time": "2014-04-08 15:00:19" + "time": "2014-04-08T15:00:19+00:00" }, { "name": "jakub-onderka/php-console-highlighter", @@ -793,7 +792,7 @@ "homepage": "http://www.acci.cz/" } ], - "time": "2015-04-20 18:58:01" + "time": "2015-04-20T18:58:01+00:00" }, { "name": "jeremeamia/SuperClosure", @@ -851,7 +850,7 @@ "serialize", "tokenizer" ], - "time": "2016-12-07 09:37:55" + "time": "2016-12-07T09:37:55+00:00" }, { "name": "laravel/framework", @@ -979,7 +978,7 @@ "framework", "laravel" ], - "time": "2016-10-08 01:51:20" + "time": "2016-10-08T01:51:20+00:00" }, { "name": "laravelcollective/html", @@ -1033,20 +1032,20 @@ ], "description": "HTML and Form Builders for the Laravel Framework", "homepage": "http://laravelcollective.com", - "time": "2016-08-27 23:52:43" + "time": "2016-08-27T23:52:43+00:00" }, { "name": "league/commonmark", - "version": "0.15.2", + "version": "0.15.3", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "c3b08b911e7344e45b87529eabc8b559d48093d4" + "reference": "c8b43ee5821362216f8e9ac684f0f59de164edcc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/c3b08b911e7344e45b87529eabc8b559d48093d4", - "reference": "c3b08b911e7344e45b87529eabc8b559d48093d4", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/c8b43ee5821362216f8e9ac684f0f59de164edcc", + "reference": "c8b43ee5821362216f8e9ac684f0f59de164edcc", "shasum": "" }, "require": { @@ -1102,7 +1101,7 @@ "markdown", "parser" ], - "time": "2016-11-22 17:30:29" + "time": "2016-12-19T00:11:43+00:00" }, { "name": "league/csv", @@ -1159,7 +1158,7 @@ "read", "write" ], - "time": "2016-10-27 11:21:24" + "time": "2016-10-27T11:21:24+00:00" }, { "name": "league/flysystem", @@ -1242,7 +1241,7 @@ "sftp", "storage" ], - "time": "2016-10-19 20:38:46" + "time": "2016-10-19T20:38:46+00:00" }, { "name": "monolog/monolog", @@ -1320,7 +1319,7 @@ "logging", "psr-3" ], - "time": "2016-11-26 00:15:39" + "time": "2016-11-26T00:15:39+00:00" }, { "name": "mtdowling/cron-expression", @@ -1364,7 +1363,7 @@ "cron", "schedule" ], - "time": "2016-01-26 21:23:30" + "time": "2016-01-26T21:23:30+00:00" }, { "name": "nesbot/carbon", @@ -1411,7 +1410,7 @@ "datetime", "time" ], - "time": "2015-11-04 20:07:17" + "time": "2015-11-04T20:07:17+00:00" }, { "name": "nikic/php-parser", @@ -1462,7 +1461,7 @@ "parser", "php" ], - "time": "2016-09-16 12:04:44" + "time": "2016-09-16T12:04:44+00:00" }, { "name": "paragonie/random_compat", @@ -1510,7 +1509,7 @@ "pseudorandom", "random" ], - "time": "2016-11-07 23:38:38" + "time": "2016-11-07T23:38:38+00:00" }, { "name": "pragmarx/google2fa", @@ -1571,7 +1570,7 @@ "google2fa", "laravel" ], - "time": "2016-07-18 20:25:04" + "time": "2016-07-18T20:25:04+00:00" }, { "name": "psr/log", @@ -1618,7 +1617,7 @@ "psr", "psr-3" ], - "time": "2016-10-10 12:19:37" + "time": "2016-10-10T12:19:37+00:00" }, { "name": "psy/psysh", @@ -1690,7 +1689,7 @@ "interactive", "shell" ], - "time": "2016-03-09 05:03:14" + "time": "2016-03-09T05:03:14+00:00" }, { "name": "ramsey/uuid", @@ -1772,7 +1771,7 @@ "identifier", "uuid" ], - "time": "2016-11-22 19:21:44" + "time": "2016-11-22T19:21:44+00:00" }, { "name": "rcrowe/twigbridge", @@ -1836,7 +1835,7 @@ "laravel", "twig" ], - "time": "2016-05-01 16:43:38" + "time": "2016-05-01T16:43:38+00:00" }, { "name": "rmccue/requests", @@ -1885,7 +1884,7 @@ "iri", "sockets" ], - "time": "2016-10-13 00:11:37" + "time": "2016-10-13T00:11:37+00:00" }, { "name": "swiftmailer/swiftmailer", @@ -1938,7 +1937,7 @@ "mail", "mailer" ], - "time": "2016-11-24 01:01:23" + "time": "2016-11-24T01:01:23+00:00" }, { "name": "symfony/console", @@ -1999,7 +1998,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-12-08 14:58:14" + "time": "2016-12-08T14:58:14+00:00" }, { "name": "symfony/debug", @@ -2056,7 +2055,7 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2016-11-15 12:55:20" + "time": "2016-11-15T12:55:20+00:00" }, { "name": "symfony/event-dispatcher", @@ -2116,7 +2115,7 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-10-13 06:29:04" + "time": "2016-10-13T06:29:04+00:00" }, { "name": "symfony/finder", @@ -2165,7 +2164,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-12-13 09:38:21" + "time": "2016-12-13T09:38:21+00:00" }, { "name": "symfony/http-foundation", @@ -2218,7 +2217,7 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2016-11-27 04:21:07" + "time": "2016-11-27T04:21:07+00:00" }, { "name": "symfony/http-kernel", @@ -2300,7 +2299,7 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2016-12-13 12:52:10" + "time": "2016-12-13T12:52:10+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -2359,7 +2358,7 @@ "portable", "shim" ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/polyfill-php56", @@ -2415,7 +2414,7 @@ "portable", "shim" ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/polyfill-util", @@ -2467,7 +2466,7 @@ "polyfill", "shim" ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/process", @@ -2516,7 +2515,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-11-24 01:08:05" + "time": "2016-11-24T01:08:05+00:00" }, { "name": "symfony/routing", @@ -2591,7 +2590,7 @@ "uri", "url" ], - "time": "2016-11-25 12:27:14" + "time": "2016-11-25T12:27:14+00:00" }, { "name": "symfony/translation", @@ -2655,7 +2654,7 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2016-11-18 21:15:08" + "time": "2016-11-18T21:15:08+00:00" }, { "name": "symfony/var-dumper", @@ -2718,20 +2717,20 @@ "debug", "dump" ], - "time": "2016-12-08 14:58:14" + "time": "2016-12-08T14:58:14+00:00" }, { "name": "twig/twig", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "74f723e542368ca2080b252740be5f1113ebb898" + "reference": "c6ff71094fde15d12398eaba029434b013dc5e59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/74f723e542368ca2080b252740be5f1113ebb898", - "reference": "74f723e542368ca2080b252740be5f1113ebb898", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/c6ff71094fde15d12398eaba029434b013dc5e59", + "reference": "c6ff71094fde15d12398eaba029434b013dc5e59", "shasum": "" }, "require": { @@ -2744,7 +2743,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.29-dev" + "dev-master": "1.30-dev" } }, "autoload": { @@ -2779,7 +2778,7 @@ "keywords": [ "templating" ], - "time": "2016-12-13 17:28:18" + "time": "2016-12-23T11:06:22+00:00" }, { "name": "vlucas/phpdotenv", @@ -2829,7 +2828,7 @@ "env", "environment" ], - "time": "2016-09-01 10:05:43" + "time": "2016-09-01T10:05:43+00:00" }, { "name": "watson/validating", @@ -2879,7 +2878,7 @@ "laravel", "validation" ], - "time": "2016-10-31 21:53:17" + "time": "2016-10-31T21:53:17+00:00" } ], "packages-dev": [ @@ -2935,7 +2934,7 @@ "profiler", "webprofiler" ], - "time": "2016-09-15 14:05:56" + "time": "2016-09-15T14:05:56+00:00" }, { "name": "barryvdh/laravel-ide-helper", @@ -3001,7 +3000,7 @@ "phpstorm", "sublime" ], - "time": "2016-11-15 08:21:23" + "time": "2016-11-15T08:21:23+00:00" }, { "name": "barryvdh/reflection-docblock", @@ -3050,7 +3049,7 @@ "email": "mike.vanriel@naenius.com" } ], - "time": "2016-06-13 19:28:20" + "time": "2016-06-13T19:28:20+00:00" }, { "name": "doctrine/instantiator", @@ -3104,7 +3103,7 @@ "constructor", "instantiate" ], - "time": "2015-06-14 21:17:01" + "time": "2015-06-14T21:17:01+00:00" }, { "name": "fzaninotto/faker", @@ -3152,7 +3151,7 @@ "faker", "fixtures" ], - "time": "2016-04-29 12:21:54" + "time": "2016-04-29T12:21:54+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -3197,7 +3196,57 @@ "keywords": [ "test" ], - "time": "2015-05-11 14:41:42" + "time": "2015-05-11T14:41:42+00:00" + }, + { + "name": "johnkary/phpunit-speedtrap", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/johnkary/phpunit-speedtrap.git", + "reference": "76a26f8a903a9434608cdad2b41c40cd134ea326" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/johnkary/phpunit-speedtrap/zipball/76a26f8a903a9434608cdad2b41c40cd134ea326", + "reference": "76a26f8a903a9434608cdad2b41c40cd134ea326", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "JohnKary": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Kary", + "email": "john@johnkary.net" + } + ], + "description": "Find slow tests in your PHPUnit test suite", + "homepage": "https://github.com/johnkary/phpunit-speedtrap", + "keywords": [ + "phpunit", + "profile", + "slow" + ], + "time": "2015-09-13T19:01:00+00:00" }, { "name": "maximebf/debugbar", @@ -3258,20 +3307,20 @@ "debug", "debugbar" ], - "time": "2016-09-15 14:01:59" + "time": "2016-09-15T14:01:59+00:00" }, { "name": "mockery/mockery", - "version": "0.9.6", + "version": "0.9.7", "source": { "type": "git", "url": "https://github.com/padraic/mockery.git", - "reference": "65d4ca18e15cb02eeb1e5336f884e46b9b905be0" + "reference": "4de7969f4664da3cef1ccd83866c9f59378c3371" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/padraic/mockery/zipball/65d4ca18e15cb02eeb1e5336f884e46b9b905be0", - "reference": "65d4ca18e15cb02eeb1e5336f884e46b9b905be0", + "url": "https://api.github.com/repos/padraic/mockery/zipball/4de7969f4664da3cef1ccd83866c9f59378c3371", + "reference": "4de7969f4664da3cef1ccd83866c9f59378c3371", "shasum": "" }, "require": { @@ -3323,7 +3372,7 @@ "test double", "testing" ], - "time": "2016-09-30 12:09:40" + "time": "2016-12-19T14:50:55+00:00" }, { "name": "myclabs/deep-copy", @@ -3365,7 +3414,7 @@ "object", "object graph" ], - "time": "2016-10-31 17:19:45" + "time": "2016-10-31T17:19:45+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -3419,7 +3468,7 @@ "reflection", "static analysis" ], - "time": "2015-12-27 11:43:31" + "time": "2015-12-27T11:43:31+00:00" }, { "name": "phpdocumentor/reflection-docblock", @@ -3464,7 +3513,7 @@ } ], "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-09-30 07:12:33" + "time": "2016-09-30T07:12:33+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -3511,7 +3560,7 @@ "email": "me@mikevanriel.com" } ], - "time": "2016-11-25 06:54:22" + "time": "2016-11-25T06:54:22+00:00" }, { "name": "phpspec/prophecy", @@ -3574,20 +3623,20 @@ "spy", "stub" ], - "time": "2016-11-21 14:58:47" + "time": "2016-11-21T14:58:47+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "4.0.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "903fd6318d0a90b4770a009ff73e4a4e9c437929" + "reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/903fd6318d0a90b4770a009ff73e4a4e9c437929", - "reference": "903fd6318d0a90b4770a009ff73e4a4e9c437929", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c14196e64a78570034afd0b7a9f3757ba71c2a0a", + "reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a", "shasum": "" }, "require": { @@ -3637,7 +3686,7 @@ "testing", "xunit" ], - "time": "2016-11-28 16:00:31" + "time": "2016-12-20T15:22:42+00:00" }, { "name": "phpunit/php-file-iterator", @@ -3684,7 +3733,7 @@ "filesystem", "iterator" ], - "time": "2016-10-03 07:40:28" + "time": "2016-10-03T07:40:28+00:00" }, { "name": "phpunit/php-text-template", @@ -3725,7 +3774,7 @@ "keywords": [ "template" ], - "time": "2015-06-21 13:50:34" + "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", @@ -3769,7 +3818,7 @@ "keywords": [ "timer" ], - "time": "2016-05-12 18:03:57" + "time": "2016-05-12T18:03:57+00:00" }, { "name": "phpunit/php-token-stream", @@ -3818,7 +3867,7 @@ "keywords": [ "tokenizer" ], - "time": "2016-11-15 14:06:22" + "time": "2016-11-15T14:06:22+00:00" }, { "name": "phpunit/phpunit", @@ -3900,7 +3949,7 @@ "testing", "xunit" ], - "time": "2016-12-13 16:19:44" + "time": "2016-12-13T16:19:44+00:00" }, { "name": "phpunit/phpunit-mock-objects", @@ -3959,7 +4008,7 @@ "mock", "xunit" ], - "time": "2016-12-08 20:27:08" + "time": "2016-12-08T20:27:08+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -4004,7 +4053,7 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2016-02-13 06:45:14" + "time": "2016-02-13T06:45:14+00:00" }, { "name": "sebastian/comparator", @@ -4068,7 +4117,7 @@ "compare", "equality" ], - "time": "2016-11-19 09:18:40" + "time": "2016-11-19T09:18:40+00:00" }, { "name": "sebastian/diff", @@ -4120,7 +4169,7 @@ "keywords": [ "diff" ], - "time": "2015-12-08 07:14:41" + "time": "2015-12-08T07:14:41+00:00" }, { "name": "sebastian/environment", @@ -4170,7 +4219,7 @@ "environment", "hhvm" ], - "time": "2016-11-26 07:53:53" + "time": "2016-11-26T07:53:53+00:00" }, { "name": "sebastian/exporter", @@ -4237,7 +4286,7 @@ "export", "exporter" ], - "time": "2016-11-19 08:54:04" + "time": "2016-11-19T08:54:04+00:00" }, { "name": "sebastian/global-state", @@ -4288,7 +4337,7 @@ "keywords": [ "global state" ], - "time": "2015-10-12 03:26:01" + "time": "2015-10-12T03:26:01+00:00" }, { "name": "sebastian/object-enumerator", @@ -4334,7 +4383,7 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2016-11-19 07:35:10" + "time": "2016-11-19T07:35:10+00:00" }, { "name": "sebastian/recursion-context", @@ -4387,7 +4436,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2016-11-19 07:33:16" + "time": "2016-11-19T07:33:16+00:00" }, { "name": "sebastian/resource-operations", @@ -4429,7 +4478,7 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28 20:34:47" + "time": "2015-07-28T20:34:47+00:00" }, { "name": "sebastian/version", @@ -4472,7 +4521,7 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03 07:35:21" + "time": "2016-10-03T07:35:21+00:00" }, { "name": "symfony/class-loader", @@ -4528,7 +4577,7 @@ ], "description": "Symfony ClassLoader Component", "homepage": "https://symfony.com", - "time": "2016-11-29 08:26:13" + "time": "2016-11-29T08:26:13+00:00" }, { "name": "symfony/css-selector", @@ -4581,7 +4630,7 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2016-11-03 08:04:31" + "time": "2016-11-03T08:04:31+00:00" }, { "name": "symfony/dom-crawler", @@ -4637,7 +4686,7 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2016-12-10 14:24:45" + "time": "2016-12-10T14:24:45+00:00" }, { "name": "symfony/yaml", @@ -4692,7 +4741,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-12-10 10:07:06" + "time": "2016-12-10T10:07:06+00:00" }, { "name": "webmozart/assert", @@ -4742,7 +4791,7 @@ "check", "validate" ], - "time": "2016-11-23 20:04:58" + "time": "2016-11-23T20:04:58+00:00" } ], "aliases": [], diff --git a/config/auth.php b/config/auth.php old mode 100755 new mode 100644 diff --git a/config/broadcasting.php b/config/broadcasting.php old mode 100755 new mode 100644 diff --git a/config/cache.php b/config/cache.php old mode 100755 new mode 100644 index 14728ed330..b8bc5dc989 --- a/config/cache.php +++ b/config/cache.php @@ -48,36 +48,36 @@ return [ ], 'database' => [ - 'driver' => 'database', - 'table' => 'cache', + 'driver' => 'database', + 'table' => 'cache', 'connection' => null, ], 'file' => [ 'driver' => 'file', - 'path' => storage_path('framework/cache'), + 'path' => storage_path('framework/cache'), ], 'memcached' => [ - 'driver' => 'memcached', + 'driver' => 'memcached', 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), - 'sasl' => [ + 'sasl' => [ env('MEMCACHED_USERNAME'), env('MEMCACHED_PASSWORD'), ], - 'options' => [ + 'options' => [ ], - 'servers' => [ + 'servers' => [ [ - 'host' => env('MEMCACHED_HOST', '127.0.0.1'), - 'port' => env('MEMCACHED_PORT', 11211), + 'host' => env('MEMCACHED_HOST', '127.0.0.1'), + 'port' => env('MEMCACHED_PORT', 11211), 'weight' => 100, ], ], ], 'redis' => [ - 'driver' => 'redis', + 'driver' => 'redis', 'connection' => 'default', ], @@ -94,6 +94,6 @@ return [ | */ - 'prefix' => 'firefly', + 'prefix' => env('CACHE_PREFIX', 'firefly'), ]; diff --git a/config/compile.php b/config/compile.php old mode 100755 new mode 100644 diff --git a/config/database.php b/config/database.php old mode 100755 new mode 100644 diff --git a/config/filesystems.php b/config/filesystems.php old mode 100755 new mode 100644 diff --git a/config/firefly.php b/config/firefly.php index d48a4299cf..ef2ff2280b 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -29,7 +29,7 @@ return [ 'mail_for_blocked_login' => false, ], 'chart' => 'chartjs', - 'version' => '4.2.2', + 'version' => '4.3.0', 'csv_import_enabled' => true, 'maxUploadSize' => 5242880, 'allowedMimes' => ['image/png', 'image/jpeg', 'application/pdf'], @@ -114,6 +114,7 @@ return [ 'languages' => [ 'de_DE' => ['name_locale' => 'Deutsch', 'name_english' => 'German', 'complete' => false], 'en_US' => ['name_locale' => 'English', 'name_english' => 'English', 'complete' => true], + 'es_ES' => ['name_locale' => 'Español', 'name_english' => 'Spanish', 'complete' => false], 'fr_FR' => ['name_locale' => 'Français', 'name_english' => 'French', 'complete' => false], 'hr_HR' => ['name_locale' => 'hrvatski', 'name_english' => 'Croatian', 'complete' => false], 'nl_NL' => ['name_locale' => 'Nederlands', 'name_english' => 'Dutch', 'complete' => true], diff --git a/config/mail.php b/config/mail.php old mode 100755 new mode 100644 diff --git a/config/queue.php b/config/queue.php old mode 100755 new mode 100644 diff --git a/config/services.php b/config/services.php old mode 100755 new mode 100644 diff --git a/config/session.php b/config/session.php old mode 100755 new mode 100644 diff --git a/config/upgrade.php b/config/upgrade.php index 82a97f50a0..a36422fe29 100644 --- a/config/upgrade.php +++ b/config/upgrade.php @@ -11,16 +11,6 @@ declare(strict_types = 1); - -/** - * upgrade.php - * Copyright (C) 2016 thegrumpydictator@gmail.com - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - - return [ 'text' => [ '3.7' => 'Because of the upgrade to Laravel 5.2, several manual changes must be made to your Firefly III installation. ' . diff --git a/config/view.php b/config/view.php old mode 100755 new mode 100644 diff --git a/database/.gitignore b/database/.gitignore old mode 100755 new mode 100644 diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php old mode 100755 new mode 100644 diff --git a/database/migrations/.gitkeep b/database/migrations/.gitkeep old mode 100755 new mode 100644 diff --git a/database/migrations/2016_06_16_000000_create_support_tables.php b/database/migrations/2016_06_16_000000_create_support_tables.php index 2ff3c650f8..6d0234802c 100644 --- a/database/migrations/2016_06_16_000000_create_support_tables.php +++ b/database/migrations/2016_06_16_000000_create_support_tables.php @@ -21,7 +21,6 @@ class CreateSupportTables extends Migration /** * Reverse the migrations. * - * @return void */ public function down() { @@ -42,56 +41,20 @@ class CreateSupportTables extends Migration /** * Run the migrations. * - * @return void + * @SuppressWarnings(PHPMD.ShortMethodName) */ public function up() { - /* - * account_types - */ $this->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(); - } /** diff --git a/database/migrations/2016_06_16_000001_create_users_table.php b/database/migrations/2016_06_16_000001_create_users_table.php index 4b3991bd67..0120a485ed 100644 --- a/database/migrations/2016_06_16_000001_create_users_table.php +++ b/database/migrations/2016_06_16_000001_create_users_table.php @@ -21,7 +21,7 @@ class CreateUsersTable extends Migration /** * Run the migrations. * - * @return void + * @SuppressWarnings(PHPMD.ShortMethodName) */ public function up() { @@ -43,8 +43,6 @@ class CreateUsersTable extends Migration /** * Reverse the migrations. - * - * @return void */ public function down() { diff --git a/database/migrations/2016_06_16_000002_create_main_tables.php b/database/migrations/2016_06_16_000002_create_main_tables.php index 989fa06e10..ddbcd339bc 100644 --- a/database/migrations/2016_06_16_000002_create_main_tables.php +++ b/database/migrations/2016_06_16_000002_create_main_tables.php @@ -55,6 +55,8 @@ class CreateMainTables extends Migration /** * Run the migrations. + * + * @SuppressWarnings(PHPMD.ShortMethodName) */ public function up() { @@ -89,14 +91,9 @@ class CreateMainTables extends Migration $table->string('name', 1024); $table->decimal('virtual_balance', 14, 4)->nullable(); $table->string('iban', 255)->nullable(); - $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'); } ); @@ -110,8 +107,6 @@ class CreateMainTables extends Migration $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'); } ); @@ -183,12 +178,10 @@ class CreateMainTables extends Migration } /** - * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) // cannot be helped. */ private function createBudgetTables() { - - if (!Schema::hasTable('budgets')) { Schema::create( 'budgets', function (Blueprint $table) { @@ -199,8 +192,6 @@ class CreateMainTables extends Migration $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'); @@ -210,7 +201,6 @@ class CreateMainTables extends Migration if (!Schema::hasTable('budget_limits')) { Schema::create( 'budget_limits', function (Blueprint $table) { - $table->increments('id'); $table->timestamps(); $table->integer('budget_id', false, true); @@ -218,8 +208,6 @@ class CreateMainTables extends Migration $table->decimal('amount', 14, 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'); } @@ -234,8 +222,6 @@ class CreateMainTables extends Migration $table->date('startdate'); $table->date('enddate'); $table->decimal('amount', 14, 4); - - // link budget limit id to budget_limitss table $table->foreign('budget_limit_id')->references('id')->on('budget_limits')->onDelete('cascade'); } ); @@ -319,8 +305,6 @@ class CreateMainTables extends Migration $table->integer('order', false, true)->default(0); $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'); } ); @@ -335,13 +319,10 @@ class CreateMainTables extends Migration $table->date('startdate')->nullable(); $table->date('targetdate')->nullable(); $table->decimal('currentamount', 14, 4); - $table->foreign('piggy_bank_id')->references('id')->on('piggy_banks')->onDelete('cascade'); - } ); } - } /** @@ -388,7 +369,8 @@ class CreateMainTables extends Migration } /** - * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) // cannot be helped. + * @SuppressWarnings(PHPMD.CyclomaticComplexity) // its exactly five */ private function createRuleTables() { @@ -503,7 +485,9 @@ class CreateMainTables extends Migration } /** - * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) // cannot be helped. + * @SuppressWarnings(PHPMD.NPathComplexity) // cannot be helped + * @SuppressWarnings(PHPMD.CyclomaticComplexity) // its exactly five */ private function createTransactionTables() { @@ -513,26 +497,19 @@ class CreateMainTables extends Migration $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)->default(0); $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'); @@ -550,7 +527,6 @@ class CreateMainTables extends Migration $table->string('name', 255); $table->text('data'); $table->string('hash', 64); - $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade'); } ); @@ -562,7 +538,6 @@ class CreateMainTables extends Migration $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'); @@ -577,7 +552,6 @@ class CreateMainTables extends Migration $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'); } @@ -590,7 +564,6 @@ class CreateMainTables extends Migration $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'); } diff --git a/database/migrations/2016_08_25_091522_changes_for_3101.php b/database/migrations/2016_08_25_091522_changes_for_3101.php index 15a0c54afd..9d0e38a548 100644 --- a/database/migrations/2016_08_25_091522_changes_for_3101.php +++ b/database/migrations/2016_08_25_091522_changes_for_3101.php @@ -20,8 +20,6 @@ class ChangesFor3101 extends Migration { /** * Reverse the migrations. - * - * @return void */ public function down() { @@ -31,7 +29,7 @@ class ChangesFor3101 extends Migration /** * Run the migrations. * - * @return void + * @SuppressWarnings(PHPMD.ShortMethodName) */ public function up() { diff --git a/database/migrations/2016_09_12_121359_fix_nullables.php b/database/migrations/2016_09_12_121359_fix_nullables.php index ff89047969..54033eac70 100644 --- a/database/migrations/2016_09_12_121359_fix_nullables.php +++ b/database/migrations/2016_09_12_121359_fix_nullables.php @@ -21,8 +21,6 @@ class FixNullables extends Migration /** * Reverse the migrations. - * - * @return void */ public function down() { @@ -32,7 +30,7 @@ class FixNullables extends Migration /** * Run the migrations. * - * @return void + * @SuppressWarnings(PHPMD.ShortMethodName) */ public function up() { diff --git a/database/migrations/2016_10_09_150037_expand_transactions_table.php b/database/migrations/2016_10_09_150037_expand_transactions_table.php index 933bca5545..fdb957ba94 100644 --- a/database/migrations/2016_10_09_150037_expand_transactions_table.php +++ b/database/migrations/2016_10_09_150037_expand_transactions_table.php @@ -11,7 +11,6 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Support\Facades\Schema; /** * Class ExpandTransactionsTable @@ -20,8 +19,6 @@ class ExpandTransactionsTable extends Migration { /** * Reverse the migrations. - * - * @return void */ public function down() { @@ -31,7 +28,7 @@ class ExpandTransactionsTable extends Migration /** * Run the migrations. * - * @return void + * @SuppressWarnings(PHPMD.ShortMethodName) */ public function up() { diff --git a/database/migrations/2016_10_22_075804_changes_for_v410.php b/database/migrations/2016_10_22_075804_changes_for_v410.php index eee0d11372..e89daf743d 100644 --- a/database/migrations/2016_10_22_075804_changes_for_v410.php +++ b/database/migrations/2016_10_22_075804_changes_for_v410.php @@ -11,7 +11,7 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Support\Facades\Schema; + /** * Class ChangesForV410 @@ -20,8 +20,6 @@ class ChangesForV410 extends Migration { /** * Reverse the migrations. - * - * @return void */ public function down() { @@ -31,7 +29,7 @@ class ChangesForV410 extends Migration /** * Run the migrations. * - * @return void + * @SuppressWarnings(PHPMD.ShortMethodName) */ public function up() { diff --git a/database/migrations/2016_11_24_210552_changes_for_v420.php b/database/migrations/2016_11_24_210552_changes_for_v420.php index 14d8b6d7a9..308bd6912a 100644 --- a/database/migrations/2016_11_24_210552_changes_for_v420.php +++ b/database/migrations/2016_11_24_210552_changes_for_v420.php @@ -11,7 +11,6 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Support\Facades\Schema; /** * Class ChangesForV420 @@ -20,8 +19,6 @@ class ChangesForV420 extends Migration { /** * Reverse the migrations. - * - * @return void */ public function down() { @@ -31,7 +28,7 @@ class ChangesForV420 extends Migration /** * Run the migrations. * - * @return void + * @SuppressWarnings(PHPMD.ShortMethodName) */ public function up() { diff --git a/database/migrations/2016_12_22_150431_changes_for_v430.php b/database/migrations/2016_12_22_150431_changes_for_v430.php new file mode 100644 index 0000000000..a01c462713 --- /dev/null +++ b/database/migrations/2016_12_22_150431_changes_for_v430.php @@ -0,0 +1,43 @@ +increments('id'); + $table->timestamps(); + $table->softDeletes(); + $table->integer('user_id', false, true); + $table->integer('transaction_currency_id', false, true); + $table->decimal('amount', 14, 4); + $table->date('start_date'); + $table->date('end_date'); + + + $table->foreign('transaction_currency_id')->references('id')->on('transaction_currencies')->onDelete('cascade'); + $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); + } + ); + } +} diff --git a/database/seeds/.gitkeep b/database/seeds/.gitkeep old mode 100755 new mode 100644 diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php old mode 100755 new mode 100644 index 7902ac315b..a92b556f6a --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -28,7 +28,6 @@ class DatabaseSeeder extends Seeder $this->call(TransactionCurrencySeeder::class); $this->call(TransactionTypeSeeder::class); $this->call(PermissionSeeder::class); - $this->call(TestDataSeeder::class); } } diff --git a/database/seeds/PermissionSeeder.php b/database/seeds/PermissionSeeder.php index 1bf36c21e7..2916470354 100644 --- a/database/seeds/PermissionSeeder.php +++ b/database/seeds/PermissionSeeder.php @@ -29,6 +29,12 @@ class PermissionSeeder extends Seeder $owner->description = 'User runs this instance of FF3'; // optional $owner->save(); + $demo = new Role; + $demo->name ='demo'; + $demo->display_name = 'Demo User'; + $demo->description = 'User is a demo user'; + $demo->save(); + } } diff --git a/database/seeds/TestDataSeeder.php b/database/seeds/TestDataSeeder.php deleted file mode 100644 index a5e814da50..0000000000 --- a/database/seeds/TestDataSeeder.php +++ /dev/null @@ -1,55 +0,0 @@ -exists($fileName)) { - Log::debug('Now seeding ' . $fileName); - $file = json_decode($disk->get($fileName), true); - - 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.coverage.xml b/phpunit.coverage.xml new file mode 100755 index 0000000000..75e3afd143 --- /dev/null +++ b/phpunit.coverage.xml @@ -0,0 +1,42 @@ + + + + + ./tests/acceptance + + + ./tests/unit + + + + + + + + + + ./app + + + vendor/ + + + + + + + + + + + + diff --git a/phpunit.xml b/phpunit.xml index 478d78f2b6..d439428075 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -7,16 +7,28 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" + beStrictAboutOutputDuringTests="true" stopOnFailure="true"> - - ./tests + + ./tests/acceptance + + + ./tests/unit + + + + + - + ./app + + vendor/ + diff --git a/public/android-chrome-144x144.png b/public/android-chrome-144x144.png deleted file mode 100644 index 0fbc935ef5..0000000000 Binary files a/public/android-chrome-144x144.png and /dev/null differ diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png index fb8549caef..e0c3f93dd2 100644 Binary files a/public/android-chrome-192x192.png and b/public/android-chrome-192x192.png differ diff --git a/public/android-chrome-36x36.png b/public/android-chrome-36x36.png deleted file mode 100644 index c101427bd7..0000000000 Binary files a/public/android-chrome-36x36.png and /dev/null differ diff --git a/public/android-chrome-48x48.png b/public/android-chrome-48x48.png deleted file mode 100644 index 3817a33ab7..0000000000 Binary files a/public/android-chrome-48x48.png and /dev/null differ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png new file mode 100644 index 0000000000..b7e4558446 Binary files /dev/null and b/public/android-chrome-512x512.png differ diff --git a/public/android-chrome-72x72.png b/public/android-chrome-72x72.png deleted file mode 100644 index 92ae9f437b..0000000000 Binary files a/public/android-chrome-72x72.png and /dev/null differ diff --git a/public/android-chrome-96x96.png b/public/android-chrome-96x96.png deleted file mode 100644 index 3602979589..0000000000 Binary files a/public/android-chrome-96x96.png and /dev/null differ diff --git a/public/android-chrome-manifest.json b/public/android-chrome-manifest.json deleted file mode 100644 index b07eb63253..0000000000 --- a/public/android-chrome-manifest.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "My app", - "icons": [ - { - "src": "\/android-chrome-36x36.png", - "sizes": "36x36", - "type": "image\/png", - "density": "0.75" - }, - { - "src": "\/android-chrome-48x48.png", - "sizes": "48x48", - "type": "image\/png", - "density": "1.0" - }, - { - "src": "\/android-chrome-72x72.png", - "sizes": "72x72", - "type": "image\/png", - "density": "1.5" - }, - { - "src": "\/android-chrome-96x96.png", - "sizes": "96x96", - "type": "image\/png", - "density": "2.0" - }, - { - "src": "\/android-chrome-144x144.png", - "sizes": "144x144", - "type": "image\/png", - "density": "3.0" - }, - { - "src": "\/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image\/png", - "density": "4.0" - } - ] -} diff --git a/public/apple-touch-icon-114x114.png b/public/apple-touch-icon-114x114.png deleted file mode 100644 index 498ea65bd1..0000000000 Binary files a/public/apple-touch-icon-114x114.png and /dev/null differ diff --git a/public/apple-touch-icon-120x120.png b/public/apple-touch-icon-120x120.png deleted file mode 100644 index 542d5330e4..0000000000 Binary files a/public/apple-touch-icon-120x120.png and /dev/null differ diff --git a/public/apple-touch-icon-144x144.png b/public/apple-touch-icon-144x144.png deleted file mode 100644 index d4aab1e910..0000000000 Binary files a/public/apple-touch-icon-144x144.png and /dev/null differ diff --git a/public/apple-touch-icon-152x152.png b/public/apple-touch-icon-152x152.png deleted file mode 100644 index 9e51ddfb64..0000000000 Binary files a/public/apple-touch-icon-152x152.png and /dev/null differ diff --git a/public/apple-touch-icon-180x180.png b/public/apple-touch-icon-180x180.png deleted file mode 100644 index c0f50f32f5..0000000000 Binary files a/public/apple-touch-icon-180x180.png and /dev/null differ diff --git a/public/apple-touch-icon-57x57.png b/public/apple-touch-icon-57x57.png deleted file mode 100644 index 414e32f2ee..0000000000 Binary files a/public/apple-touch-icon-57x57.png and /dev/null differ diff --git a/public/apple-touch-icon-60x60.png b/public/apple-touch-icon-60x60.png deleted file mode 100644 index e05470b64b..0000000000 Binary files a/public/apple-touch-icon-60x60.png and /dev/null differ diff --git a/public/apple-touch-icon-72x72.png b/public/apple-touch-icon-72x72.png deleted file mode 100644 index d2080d08e2..0000000000 Binary files a/public/apple-touch-icon-72x72.png and /dev/null differ diff --git a/public/apple-touch-icon-76x76.png b/public/apple-touch-icon-76x76.png deleted file mode 100644 index 47bd65a56d..0000000000 Binary files a/public/apple-touch-icon-76x76.png and /dev/null differ diff --git a/public/apple-touch-icon-precomposed.png b/public/apple-touch-icon-precomposed.png deleted file mode 100644 index 0b6bb71456..0000000000 Binary files a/public/apple-touch-icon-precomposed.png and /dev/null differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png index c0f50f32f5..6d2d88d80c 100644 Binary files a/public/apple-touch-icon.png and b/public/apple-touch-icon.png differ diff --git a/public/browserconfig.xml b/public/browserconfig.xml index 6d6066d3f2..74bb89ac30 100644 --- a/public/browserconfig.xml +++ b/public/browserconfig.xml @@ -2,10 +2,7 @@ - - - - + #da532c diff --git a/public/css/firefly.css b/public/css/firefly.css index bd46d1e920..a09432b2c7 100644 --- a/public/css/firefly.css +++ b/public/css/firefly.css @@ -1,3 +1,13 @@ +/* + * firefly.css + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ + #daterange { cursor: pointer; } diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png index 496df9f39a..a53c31ccf4 100644 Binary files a/public/favicon-16x16.png and b/public/favicon-16x16.png differ diff --git a/public/favicon-194x194.png b/public/favicon-194x194.png deleted file mode 100644 index 25d5884833..0000000000 Binary files a/public/favicon-194x194.png and /dev/null differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png index c729437261..da1a8b0f37 100644 Binary files a/public/favicon-32x32.png and b/public/favicon-32x32.png differ diff --git a/public/favicon-96x96.png b/public/favicon-96x96.png deleted file mode 100644 index 555cb24669..0000000000 Binary files a/public/favicon-96x96.png and /dev/null differ diff --git a/public/favicon.ico b/public/favicon.ico index 78c3c142f3..c111de1c1e 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/index.php b/public/index.php index 4415ad6b6c..7f21d36fb5 100644 --- a/public/index.php +++ b/public/index.php @@ -3,19 +3,14 @@ * index.php * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ declare(strict_types = 1); -/** - * Laravel - A PHP Framework For Web Artisans - * - * @package Laravel - * @author Taylor Otwell - */ - /* |-------------------------------------------------------------------------- | Register The Auto Loader diff --git a/public/js/ff/accounts/show.js b/public/js/ff/accounts/show.js index e981faeb55..1d53f11c1b 100644 --- a/public/js/ff/accounts/show.js +++ b/public/js/ff/accounts/show.js @@ -86,7 +86,7 @@ function sortStop(event, ui) { }); // do extra animation when done? - $.post('transaction/reorder', {items: submit, date: thisDate, _token: token}); + $.post('transactions/reorder', {items: submit, date: thisDate, _token: token}); current.animate({backgroundColor: "#5cb85c"}, 200, function () { $(this).animate({backgroundColor: originalBG}, 200); diff --git a/public/js/ff/bills/show.js b/public/js/ff/bills/show.js index ba12284cd3..3964f90dcb 100644 --- a/public/js/ff/bills/show.js +++ b/public/js/ff/bills/show.js @@ -1,3 +1,13 @@ +/* + * show.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ + /* global comboChart, billID */ $(function () { diff --git a/public/js/ff/budgets/index.js b/public/js/ff/budgets/index.js index c8ca145734..95a4eca219 100644 --- a/public/js/ff/budgets/index.js +++ b/public/js/ff/budgets/index.js @@ -1,4 +1,12 @@ -/* globals $, budgeted:true, currencySymbol, budgetIncomeTotal, columnChart, budgetedMuch, budgetedPercentage, token, budgetID, repetitionID, spent, lineChart */ +/* + * index.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ function drawSpentBar() { "use strict"; @@ -23,19 +31,19 @@ function drawBudgetedBar() { "use strict"; if ($('.budgetedBar').length > 0) { - var budgetedMuch = budgeted > budgetIncomeTotal; + var budgetedMuch = budgeted > available; // recalculate percentage: var pct; if (budgetedMuch) { // budgeted too much. - pct = (budgetIncomeTotal / budgeted) * 100; + pct = (available / budgeted) * 100; $('.budgetedBar .progress-bar-warning').css('width', pct + '%'); $('.budgetedBar .progress-bar-danger').css('width', (100 - pct) + '%'); $('.budgetedBar .progress-bar-info').css('width', 0); } else { - pct = (budgeted / budgetIncomeTotal) * 100; + pct = (budgeted / available) * 100; $('.budgetedBar .progress-bar-warning').css('width', 0); $('.budgetedBar .progress-bar-danger').css('width', 0); $('.budgetedBar .progress-bar-info').css('width', pct + '%'); diff --git a/public/js/ff/budgets/show.js b/public/js/ff/budgets/show.js index 8a538bfbcd..1e7fb668dc 100644 --- a/public/js/ff/budgets/show.js +++ b/public/js/ff/budgets/show.js @@ -1,3 +1,13 @@ +/* + * show.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ + $(function () { "use strict"; diff --git a/public/js/ff/categories/index.js b/public/js/ff/categories/index.js index 6bfe805c1f..ca8ef07e42 100644 --- a/public/js/ff/categories/index.js +++ b/public/js/ff/categories/index.js @@ -1,4 +1,13 @@ -/* globals $, categoryID, columnChart, categoryDate */ +/* + * index.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ + $(function () { "use strict"; }); \ No newline at end of file diff --git a/public/js/ff/categories/show-by-date.js b/public/js/ff/categories/show-by-date.js index 931316b0d7..6b5ee6b775 100644 --- a/public/js/ff/categories/show-by-date.js +++ b/public/js/ff/categories/show-by-date.js @@ -1,3 +1,13 @@ +/* + * show-by-date.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ + $(function () { "use strict"; columnChart(specific, 'period-specific-period'); diff --git a/public/js/ff/categories/show.js b/public/js/ff/categories/show.js index 4d668bad25..9d14bc1377 100644 --- a/public/js/ff/categories/show.js +++ b/public/js/ff/categories/show.js @@ -1,3 +1,13 @@ +/* + * show.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ + $(function () { "use strict"; columnChart(all, 'all'); diff --git a/public/js/ff/charts.defaults.js b/public/js/ff/charts.defaults.js index f763bb6c15..bbcce69ccb 100644 --- a/public/js/ff/charts.defaults.js +++ b/public/js/ff/charts.defaults.js @@ -1,3 +1,13 @@ +/* + * charts.defaults.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ + var defaultChartOptions = { scales: { xAxes: [ diff --git a/public/js/ff/charts.js b/public/js/ff/charts.js index 080ac4c93f..7180a9c131 100644 --- a/public/js/ff/charts.js +++ b/public/js/ff/charts.js @@ -2,12 +2,12 @@ * charts.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ -/* globals $, Chart, currencySymbol,mon_decimal_point ,accounting, mon_thousands_sep, frac_digits, noDataForChart */ - var allCharts = {}; /* @@ -81,6 +81,106 @@ function lineChart(URI, container) { drawAChart(URI, container, chartType, options, colorData); } +/** + * Function to draw a chart with double Y Axes and stacked columns. + * + * @param URI + * @param container + */ +function doubleYChart(URI, container) { + "use strict"; + + var colorData = true; + var options = defaultChartOptions; + options.scales.yAxes = [ + // y axis 0: + { + display: true, + ticks: { + callback: function (tickValue, index, ticks) { + "use strict"; + return accounting.formatMoney(tickValue); + + }, + beginAtZero: true + }, + position: "left", + "id": "y-axis-0" + }, + // and y axis 1: + { + display: true, + ticks: { + callback: function (tickValue, index, ticks) { + "use strict"; + return accounting.formatMoney(tickValue); + + }, + beginAtZero: true + }, + position: "right", + "id": "y-axis-1" + } + + ]; + options.stacked = true; + options.scales.xAxes[0].stacked = true; + // console.log(options); + + var chartType = 'bar'; + + drawAChart(URI, container, chartType, options, colorData); +} + +/** + * Function to draw a chart with double Y Axes and non stacked columns. + * + * @param URI + * @param container + */ +function doubleYNonStackedChart(URI, container) { + "use strict"; + + var colorData = true; + var options = defaultChartOptions; + options.scales.yAxes = [ + // y axis 0: + { + display: true, + ticks: { + callback: function (tickValue, index, ticks) { + "use strict"; + return accounting.formatMoney(tickValue); + + }, + beginAtZero: true + }, + position: "left", + "id": "y-axis-0" + }, + // and y axis 1: + { + display: true, + ticks: { + callback: function (tickValue, index, ticks) { + "use strict"; + return accounting.formatMoney(tickValue); + + }, + beginAtZero: true + }, + position: "right", + "id": "y-axis-1" + } + + ]; + var chartType = 'bar'; + + drawAChart(URI, container, chartType, options, colorData); +} + + + /** * * @param URI @@ -107,7 +207,6 @@ function stackedColumnChart(URI, container) { var colorData = true; var options = defaultChartOptions; - options.stacked = true; options.scales.xAxes[0].stacked = true; diff --git a/public/js/ff/export/index.js b/public/js/ff/export/index.js index f4ae67a6b4..eeed44981f 100644 --- a/public/js/ff/export/index.js +++ b/public/js/ff/export/index.js @@ -1,11 +1,11 @@ -/* globals token, jobKey */ - /* * index.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ var intervalId = 0; diff --git a/public/js/ff/firefly.js b/public/js/ff/firefly.js index e57052381a..2b105d4386 100644 --- a/public/js/ff/firefly.js +++ b/public/js/ff/firefly.js @@ -1,4 +1,13 @@ -/* globals token, dateRangeConfig, $, */ +/* + * firefly.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ + $(function () { "use strict"; diff --git a/public/js/ff/guest.js b/public/js/ff/guest.js index 7ba3e6bed9..886d5a1a51 100644 --- a/public/js/ff/guest.js +++ b/public/js/ff/guest.js @@ -1,3 +1,13 @@ +/* + * guest.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ + $(function () { "use strict"; diff --git a/public/js/ff/help.js b/public/js/ff/help.js index 1d6e14e477..536a4c5c2e 100644 --- a/public/js/ff/help.js +++ b/public/js/ff/help.js @@ -1,3 +1,13 @@ +/* + * help.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ + $(function () { "use strict"; $('#help').click(showHelp); diff --git a/public/js/ff/import/status.js b/public/js/ff/import/status.js index 2084858131..0b24c0c7f5 100644 --- a/public/js/ff/import/status.js +++ b/public/js/ff/import/status.js @@ -2,11 +2,11 @@ * status.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ -/* globals $, jobImportUrl, jobStartUrl, token, langImportMultiError, langImportSingleError, langImportFatalError, langImportTimeOutError */ - var startedImport = false; var startInterval = 2000; diff --git a/public/js/ff/index.js b/public/js/ff/index.js index b0cc90b70f..27d69d5bc0 100644 --- a/public/js/ff/index.js +++ b/public/js/ff/index.js @@ -1,4 +1,12 @@ -/* globals $, columnChart,showTour, Tour, google, pieChart, stackedColumnChart, billCount */ +/* + * index.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ $(function () { "use strict"; diff --git a/public/js/ff/piggy-banks/index.js b/public/js/ff/piggy-banks/index.js index 39f516b01b..92b64b0af9 100644 --- a/public/js/ff/piggy-banks/index.js +++ b/public/js/ff/piggy-banks/index.js @@ -2,13 +2,12 @@ * index.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ -/* globals $, lineChart, token, piggyBankID */ - -// Return a helper with preserved width of cells var fixHelper = function (e, tr) { "use strict"; var $originals = tr.children(); diff --git a/public/js/ff/piggy-banks/show.js b/public/js/ff/piggy-banks/show.js index 72cebea8ff..4c02df137c 100644 --- a/public/js/ff/piggy-banks/show.js +++ b/public/js/ff/piggy-banks/show.js @@ -2,12 +2,12 @@ * show.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ -/* globals $, lineChart, piggyBankID */ - $(function () { "use strict"; if (typeof(lineChart) === 'function' && typeof(piggyBankID) !== 'undefined') { diff --git a/public/js/ff/reports/audit/all.js b/public/js/ff/reports/audit/all.js index f9f5a79f41..2c58e0ac54 100644 --- a/public/js/ff/reports/audit/all.js +++ b/public/js/ff/reports/audit/all.js @@ -2,12 +2,12 @@ * all.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ -/* globals hideable */ - $(function () { "use strict"; diff --git a/public/js/ff/reports/budget/month.js b/public/js/ff/reports/budget/month.js index 0eeb33fa93..c103e00dff 100644 --- a/public/js/ff/reports/budget/month.js +++ b/public/js/ff/reports/budget/month.js @@ -28,7 +28,7 @@ function drawChart() { "use strict"; // month view: - stackedColumnChart(mainUri, 'in-out-chart'); + doubleYNonStackedChart(mainUri, 'in-out-chart'); // draw pie chart of income, depending on "show other transactions too": redrawPieChart('budgets-out-pie-chart', budgetExpenseUri); diff --git a/public/js/ff/reports/category/month.js b/public/js/ff/reports/category/month.js index cdbe5420b2..607d635205 100644 --- a/public/js/ff/reports/category/month.js +++ b/public/js/ff/reports/category/month.js @@ -36,7 +36,7 @@ function drawChart() { "use strict"; // month view: - stackedColumnChart(mainUri, 'in-out-chart'); + doubleYChart(mainUri, 'in-out-chart'); // draw pie chart of income, depending on "show other transactions too": redrawPieChart('categories-in-pie-chart', categoryIncomeUri); diff --git a/public/js/ff/reports/default/all.js b/public/js/ff/reports/default/all.js index b19187497b..b5e4bf970e 100644 --- a/public/js/ff/reports/default/all.js +++ b/public/js/ff/reports/default/all.js @@ -1,10 +1,11 @@ -/* globals startDate, showOnlyTop, showFullList, endDate, expenseReportUri, accountIds, incExpReportUri,accountReportUri, incomeReportUri */ /* * all.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ $(function () { diff --git a/public/js/ff/reports/default/month.js b/public/js/ff/reports/default/month.js index a150da25cc..2052997a9b 100644 --- a/public/js/ff/reports/default/month.js +++ b/public/js/ff/reports/default/month.js @@ -1,5 +1,12 @@ -/* globals google, categoryReportUri, budgetReportUri, balanceReportUri */ - +/* + * month.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ $(function () { "use strict"; diff --git a/public/js/ff/reports/default/multi-year.js b/public/js/ff/reports/default/multi-year.js index b1f755a8f1..a6a63a1d3d 100644 --- a/public/js/ff/reports/default/multi-year.js +++ b/public/js/ff/reports/default/multi-year.js @@ -1,3 +1,13 @@ +/* + * multi-year.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ + $(function () { "use strict"; drawChart(); diff --git a/public/js/ff/reports/default/year.js b/public/js/ff/reports/default/year.js index 259b9fa18a..9e521ab4fb 100644 --- a/public/js/ff/reports/default/year.js +++ b/public/js/ff/reports/default/year.js @@ -1,4 +1,12 @@ -/* globals google, accountIds, budgetPeriodReportUri, categoryPeriodReportUri */ +/* + * year.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ $(function () { "use strict"; diff --git a/public/js/ff/reports/index.js b/public/js/ff/reports/index.js index 9de3f79b50..f146d78bf3 100644 --- a/public/js/ff/reports/index.js +++ b/public/js/ff/reports/index.js @@ -1,5 +1,12 @@ -/* globals google, startDate ,reportURL, endDate , reportType ,accountIds , picker:true, minDate, year, month, columnChart, lineChart, stackedColumnChart */ - +/* + * index.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ $(function () { "use strict"; diff --git a/public/js/ff/rules/create-edit.js b/public/js/ff/rules/create-edit.js index 9e836eb3d6..98b77e9b4d 100644 --- a/public/js/ff/rules/create-edit.js +++ b/public/js/ff/rules/create-edit.js @@ -2,8 +2,10 @@ * create-edit.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ var triggerCount = 0; diff --git a/public/js/ff/rules/create.js b/public/js/ff/rules/create.js index 857f5b2617..1ad133f9d7 100644 --- a/public/js/ff/rules/create.js +++ b/public/js/ff/rules/create.js @@ -1,14 +1,13 @@ -/* global $, addNewTrigger, addNewAction, actionCount, triggerCount */ /* - * edit.js + * create.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ -// make a line. - $(function () { "use strict"; console.log("create"); diff --git a/public/js/ff/rules/edit.js b/public/js/ff/rules/edit.js index c66a905d0c..16191e2ae8 100644 --- a/public/js/ff/rules/edit.js +++ b/public/js/ff/rules/edit.js @@ -2,8 +2,10 @@ * edit.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ $(function () { diff --git a/public/js/ff/rules/index.js b/public/js/ff/rules/index.js index 133f770a98..c8642209e2 100644 --- a/public/js/ff/rules/index.js +++ b/public/js/ff/rules/index.js @@ -1,13 +1,13 @@ -/* global comboChart,token, billID */ /* * index.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ -// Return a helper with preserved width of cells var fixHelper = function (e, tr) { "use strict"; var $originals = tr.children(); diff --git a/public/js/ff/split/journal/from-store.js b/public/js/ff/split/journal/from-store.js index 2c5ef2c40c..ef3480f827 100644 --- a/public/js/ff/split/journal/from-store.js +++ b/public/js/ff/split/journal/from-store.js @@ -2,12 +2,12 @@ * from-store.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ -/* globals globalSum */ - var destAccounts = {}; var srcAccounts = {}; var categories = {}; @@ -54,7 +54,6 @@ function removeRow(e) { $('table.split-table tbody tr[data-split="' + index + '"]').remove(); - resetSplits(); return false; @@ -171,8 +170,9 @@ function calculateSum() { for (var i = 0; i < set.length; i++) { var current = $(set[i]); sum += (current.val() == "" ? 0 : parseFloat(current.val())); - } + sum = Math.round(sum * 100) / 100; + console.log("Sum is now " + sum); $('.amount-warning').remove(); if (sum != originalSum) { diff --git a/public/js/ff/tags/create.js b/public/js/ff/tags/create.js index 6ea5731733..77e8224238 100644 --- a/public/js/ff/tags/create.js +++ b/public/js/ff/tags/create.js @@ -1,4 +1,13 @@ -/* globals zoomLevel, token, google, latitude, longitude, doPlaceMarker */ +/* + * create.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ + $(function () { "use strict"; diff --git a/public/js/ff/tags/edit.js b/public/js/ff/tags/edit.js index 6ea5731733..c4f9cd0cfb 100644 --- a/public/js/ff/tags/edit.js +++ b/public/js/ff/tags/edit.js @@ -1,4 +1,13 @@ -/* globals zoomLevel, token, google, latitude, longitude, doPlaceMarker */ +/* + * edit.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ + $(function () { "use strict"; diff --git a/public/js/ff/tags/index.js b/public/js/ff/tags/index.js index 6ea5731733..a24180b4e0 100644 --- a/public/js/ff/tags/index.js +++ b/public/js/ff/tags/index.js @@ -1,4 +1,13 @@ -/* globals zoomLevel, token, google, latitude, longitude, doPlaceMarker */ +/* + * index.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ + $(function () { "use strict"; diff --git a/public/js/ff/transactions/create-edit.js b/public/js/ff/transactions/create-edit.js index 8a83c9968d..ae827d8983 100644 --- a/public/js/ff/transactions/create-edit.js +++ b/public/js/ff/transactions/create-edit.js @@ -2,10 +2,12 @@ * create-edit.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ -/* globals what:true, $, doSwitch, txt, middleCrumbName, title,button, middleCrumbUrl, piggiesLength, breadcrumbs */ + $(document).ready(function () { "use strict"; diff --git a/public/js/ff/transactions/create.js b/public/js/ff/transactions/create.js index f3fc98a09c..e059fdf127 100644 --- a/public/js/ff/transactions/create.js +++ b/public/js/ff/transactions/create.js @@ -2,11 +2,12 @@ * create.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ -/* globals what:true, $, doSwitch, txt, middleCrumbName, title,button, middleCrumbUrl, piggiesLength, breadcrumbs */ $(document).ready(function () { "use strict"; diff --git a/public/js/ff/transactions/edit.js b/public/js/ff/transactions/edit.js index 62a2b4db14..63390bc3e6 100644 --- a/public/js/ff/transactions/edit.js +++ b/public/js/ff/transactions/edit.js @@ -2,11 +2,12 @@ * edit.js * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ -/* globals $ */ $(document).ready(function () { "use strict"; // no special JS for edit transaction. diff --git a/public/js/ff/transactions/list.js b/public/js/ff/transactions/list.js index 42786654a3..7e87446a48 100644 --- a/public/js/ff/transactions/list.js +++ b/public/js/ff/transactions/list.js @@ -1,4 +1,12 @@ -/* globals $, edit_selected_txt, delete_selected_txt */ +/* + * list.js + * Copyright (C) 2016 thegrumpydictator@gmail.com + * + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. + */ $(document).ready(function () { "use strict"; diff --git a/public/manifest.json b/public/manifest.json index 5881f59e5c..0b22ea1677 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -2,44 +2,20 @@ "name": "Firefly III", "short_name": "Firefly III", "icons": [ - { - "src": "\/android-chrome-36x36.png", - "sizes": "36x36", - "type": "image\/png", - "density": 0.75 - }, - { - "src": "\/android-chrome-48x48.png", - "sizes": "48x48", - "type": "image\/png", - "density": 1 - }, - { - "src": "\/android-chrome-72x72.png", - "sizes": "72x72", - "type": "image\/png", - "density": 1.5 - }, - { - "src": "\/android-chrome-96x96.png", - "sizes": "96x96", - "type": "image\/png", - "density": 2 - }, - { - "src": "\/android-chrome-144x144.png", - "sizes": "144x144", - "type": "image\/png", - "density": 3 - }, { "src": "\/android-chrome-192x192.png", "sizes": "192x192", "type": "image\/png", "density": 4 + }, + { + "src": "\/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image\/png" } ], - "start_url": "/", "display": "standalone", + "start_url": "/", "orientation": "portrait" + } diff --git a/public/mstile-144x144.png b/public/mstile-144x144.png deleted file mode 100644 index d27ae1b177..0000000000 Binary files a/public/mstile-144x144.png and /dev/null differ diff --git a/public/mstile-150x150.png b/public/mstile-150x150.png index e03a93a3fc..426408fac6 100644 Binary files a/public/mstile-150x150.png and b/public/mstile-150x150.png differ diff --git a/public/mstile-310x150.png b/public/mstile-310x150.png deleted file mode 100644 index 2c17b9eee8..0000000000 Binary files a/public/mstile-310x150.png and /dev/null differ diff --git a/public/mstile-310x310.png b/public/mstile-310x310.png deleted file mode 100644 index ef719f84ca..0000000000 Binary files a/public/mstile-310x310.png and /dev/null differ diff --git a/public/mstile-70x70.png b/public/mstile-70x70.png deleted file mode 100644 index 3f334b60a3..0000000000 Binary files a/public/mstile-70x70.png and /dev/null differ diff --git a/public/safari-pinned-tab.svg b/public/safari-pinned-tab.svg index 5803c22658..cfa922579b 100644 --- a/public/safari-pinned-tab.svg +++ b/public/safari-pinned-tab.svg @@ -9,40 +9,44 @@ Created by potrace 1.11, written by Peter Selinger 2001-2013 - + + + + diff --git a/resources/lang/de_DE/demo.php b/resources/lang/de_DE/demo.php new file mode 100644 index 0000000000..ed6ae7e543 --- /dev/null +++ b/resources/lang/de_DE/demo.php @@ -0,0 +1,16 @@ + 'Sorry, there is no extra demo-explanation text for this page.', + 'see_help_icon' => 'However, the -icon in the top right corner may tell you more.', + 'index' => 'Welcome to Firefly III! On this page you get a quick overview of your finances. For more information, check out Accounts → Asset Accounts and of course the Budgets and Reports pages. Or just take a look around and see where you end up.', + + +]; \ No newline at end of file diff --git a/resources/lang/de_DE/firefly.php b/resources/lang/de_DE/firefly.php index 8dd703474f..1f95518770 100644 --- a/resources/lang/de_DE/firefly.php +++ b/resources/lang/de_DE/firefly.php @@ -91,6 +91,15 @@ return [ 'expenses_by_budget' => 'Ausgaben nach Budget', 'income_by_category' => 'Einkommen nach Kategorie', 'cannot_redirect_to_account' => 'Entschuldigung. Firefly III kann Sie nicht zur richtigen Seite weiterleiten.', + 'sum_of_expenses' => 'Sum of expenses', + 'sum_of_income' => 'Sum of income', + 'spent_in_specific_budget' => 'Spent in budget ":budget"', + 'sum_of_expenses_in_budget' => 'Spent total in budget ":budget"', + 'left_in_budget_limit' => 'Left to spend according to budgeting', + 'cannot_change_demo' => 'You cannot change the password of the demonstration account.', + 'cannot_delete_demo' => 'You cannot remove the demonstration account.', + 'cannot_reset_demo_user' => 'You cannot reset the password of the demonstration account', + // repeat frequencies: 'repeat_freq_yearly' => 'Jährlich', 'repeat_freq_monthly' => 'monatlich', @@ -194,6 +203,7 @@ return [ 'warning_no_matching_transactions' => 'Keine übereinstimmenden Überweisungen gefunden. Aus Kapazitätgründen werden nur die letzten :num_transactions Überweisungen überprüft.', 'warning_no_valid_triggers' => 'Keine gültigen Trigger gefunden.', 'execute_on_existing_transactions' => 'Führe für bestehende Überweisungen aus', + 'rule_group_select_transactions' => 'Execute rule group ":title" on existing transactions', 'execute_on_existing_transactions_intro' => 'Wenn eine Regel oder eine Gruppe geändert oder hinzugefügt wurde, können Sie für bestehende Überweisungen ausgeführt werden', 'execute_on_existing_transactions_short' => 'Bestehende Überweisungen', 'executed_group_on_existing_transactions' => 'Regelgruppe ":title" wurde für bestehende Überweisungen ausgeführt', @@ -633,10 +643,10 @@ Sollen zusätzlich Ihre Girokonten angezeigt werden?', 'errors' => 'Fehler', // reports: - 'report_default' => 'Standard Finanzbericht für :start bis :end', - 'report_audit' => 'Transaction history overview for :start until :end', - 'report_category' => 'Category report for :start until :end', - 'report_budget' => 'Budget report for :start until :end', + 'report_default' => 'Default financial report between :start and :end', + 'report_audit' => 'Transaction history overview between :start and :end', + 'report_category' => 'Category report between :start and :end', + 'report_budget' => 'Budget report between :start and :end', 'quick_link_reports' => 'Schnellzugriff', 'quick_link_default_report' => 'Standard Finanzbericht', 'quick_link_audit_report' => 'Transaktionshistorie', diff --git a/resources/lang/en_US/demo.php b/resources/lang/en_US/demo.php new file mode 100644 index 0000000000..ed6ae7e543 --- /dev/null +++ b/resources/lang/en_US/demo.php @@ -0,0 +1,16 @@ + 'Sorry, there is no extra demo-explanation text for this page.', + 'see_help_icon' => 'However, the -icon in the top right corner may tell you more.', + 'index' => 'Welcome to Firefly III! On this page you get a quick overview of your finances. For more information, check out Accounts → Asset Accounts and of course the Budgets and Reports pages. Or just take a look around and see where you end up.', + + +]; \ No newline at end of file diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index 226834da8a..1fb53a93b5 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -91,6 +91,15 @@ return [ 'expenses_by_budget' => 'Expenses by budget', 'income_by_category' => 'Income by category', 'cannot_redirect_to_account' => 'Firefly III cannot redirect you to the correct page. Apologies.', + 'sum_of_expenses' => 'Sum of expenses', + 'sum_of_income' => 'Sum of income', + 'spent_in_specific_budget' => 'Spent in budget ":budget"', + 'sum_of_expenses_in_budget' => 'Spent total in budget ":budget"', + 'left_in_budget_limit' => 'Left to spend according to budgeting', + 'cannot_change_demo' => 'You cannot change the password of the demonstration account.', + 'cannot_delete_demo' => 'You cannot remove the demonstration account.', + 'cannot_reset_demo_user' => 'You cannot reset the password of the demonstration account', + // repeat frequencies: 'repeat_freq_yearly' => 'yearly', 'repeat_freq_monthly' => 'monthly', @@ -194,6 +203,7 @@ return [ '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', + 'rule_group_select_transactions' => 'Execute rule group ":title" on 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', @@ -632,10 +642,10 @@ return [ 'errors' => 'Errors', // reports: - 'report_default' => 'Default financial report for :start until :end', - 'report_audit' => 'Transaction history overview for :start until :end', - 'report_category' => 'Category report for :start until :end', - 'report_budget' => 'Budget report for :start until :end', + 'report_default' => 'Default financial report between :start and :end', + 'report_audit' => 'Transaction history overview between :start and :end', + 'report_category' => 'Category report between :start and :end', + 'report_budget' => 'Budget report between :start and :end', 'quick_link_reports' => 'Quick links', 'quick_link_default_report' => 'Default financial report', 'quick_link_audit_report' => 'Transaction history overview', diff --git a/resources/lang/es_ES/auth.php b/resources/lang/es_ES/auth.php new file mode 100644 index 0000000000..5d833b3d68 --- /dev/null +++ b/resources/lang/es_ES/auth.php @@ -0,0 +1,28 @@ + 'These credentials do not match our records.', + 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', + +]; \ No newline at end of file diff --git a/resources/lang/es_ES/breadcrumbs.php b/resources/lang/es_ES/breadcrumbs.php new file mode 100644 index 0000000000..6bcf9b862d --- /dev/null +++ b/resources/lang/es_ES/breadcrumbs.php @@ -0,0 +1,41 @@ + 'Home', + 'edit_currency' => 'Edit currency ":name"', + 'delete_currency' => 'Delete currency ":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', + '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"', +]; \ No newline at end of file diff --git a/resources/lang/es_ES/config.php b/resources/lang/es_ES/config.php new file mode 100644 index 0000000000..58220429bf --- /dev/null +++ b/resources/lang/es_ES/config.php @@ -0,0 +1,23 @@ + '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', + +]; \ No newline at end of file diff --git a/resources/lang/es_ES/csv.php b/resources/lang/es_ES/csv.php new file mode 100644 index 0000000000..4acb52efdc --- /dev/null +++ b/resources/lang/es_ES/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' => 'Basic CSV import options', + '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.', + '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_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)', +]; \ No newline at end of file diff --git a/resources/lang/es_ES/demo.php b/resources/lang/es_ES/demo.php new file mode 100644 index 0000000000..ed6ae7e543 --- /dev/null +++ b/resources/lang/es_ES/demo.php @@ -0,0 +1,16 @@ + 'Sorry, there is no extra demo-explanation text for this page.', + 'see_help_icon' => 'However, the -icon in the top right corner may tell you more.', + 'index' => 'Welcome to Firefly III! On this page you get a quick overview of your finances. For more information, check out Accounts → Asset Accounts and of course the Budgets and Reports pages. Or just take a look around and see where you end up.', + + +]; \ No newline at end of file diff --git a/resources/lang/es_ES/firefly.php b/resources/lang/es_ES/firefly.php new file mode 100644 index 0000000000..e9d4f2d538 --- /dev/null +++ b/resources/lang/es_ES/firefly.php @@ -0,0 +1,953 @@ + 'incomplete translation', + 'close' => 'Close', + 'actions' => 'Actions', + 'edit' => 'Edit', + 'delete' => 'Delete', + 'welcomeBack' => 'What\'s playing?', + 'everything' => 'Everything', + 'customRange' => 'Custom range', + 'apply' => 'Apply', + 'cancel' => 'Cancel', + 'from' => 'From', + 'to' => 'To', + '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.', + '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.', + 'help_may_not_be_your_language' => 'This help text is in English. It is not yet 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', + 'search_found_accounts' => 'Found :count account(s) for your query.', + 'search_found_categories' => 'Found :count category(ies) for your query.', + 'search_found_budgets' => 'Found :count budget(s) for your query.', + 'search_found_tags' => 'Found :count tag(s) for your query.', + 'search_found_transactions' => 'Found :count transaction(s) for your query.', + 'results_limited' => 'The results are limited to :count entries.', + 'tagbalancingAct' => 'Balancing act', + 'tagadvancePayment' => 'Advance payment', + 'tagnothing' => '', + 'Default asset account' => 'Default asset account', + '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.', + 'Savings account' => 'Savings account', + 'Credit card' => 'Credit card', + 'source_accounts' => 'Source account(s)', + 'destination_accounts' => 'Destination account(s)', + 'user_id_is' => 'Your user id is :user', + 'field_supports_markdown' => 'This field supports Markdown.', + 'need_more_help' => 'If you need more help using Firefly III, please open a ticket on Github.', + 'nothing_to_display' => 'There are no transactions to show you', + 'show_all_no_filter' => 'Show all transactions without grouping them by date.', + 'expenses_by_category' => 'Expenses by category', + 'expenses_by_budget' => 'Expenses by budget', + 'income_by_category' => 'Income by category', + 'cannot_redirect_to_account' => 'Firefly III cannot redirect you to the correct page. Apologies.', + 'sum_of_expenses' => 'Sum of expenses', + 'sum_of_income' => 'Sum of income', + 'spent_in_specific_budget' => 'Spent in budget ":budget"', + 'sum_of_expenses_in_budget' => 'Spent total in budget ":budget"', + 'left_in_budget_limit' => 'Left to spend according to budgeting', + 'cannot_change_demo' => 'You cannot change the password of the demonstration account.', + 'cannot_delete_demo' => 'You cannot remove the demonstration account.', + 'cannot_reset_demo_user' => 'You cannot reset the password of the demonstration account', + + // repeat frequencies: + 'repeat_freq_yearly' => 'yearly', + '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_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', + 'rule_group_select_transactions' => 'Execute rule group ":title" on 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 transaction is created', + 'rule_trigger_update_journal' => 'When a transaction 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_action_set_source_account_choice' => 'Set source account to...', + 'rule_action_set_source_account' => 'Set source account to :action_value', + 'rule_action_set_destination_account_choice' => 'Set destination account to...', + 'rule_action_set_destination_account' => 'Set destination account to :action_value', + + // 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_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!', + 'preferences_general' => 'General', + 'preferences_frontpage' => 'Home screen', + 'preferences_security' => 'Security', + 'preferences_layout' => 'Layout', + 'pref_home_show_deposits' => 'Show deposits on the home screen', + 'pref_home_show_deposits_info' => 'The home screen already shows your expense accounts. Should it also show your revenue accounts?', + 'pref_home_do_show_deposits' => 'Yes, show them', + 'successful_count' => 'of which :count successful', + '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', + 'between_dates' => '(:start and :end)', + 'pref_optional_fields_transaction' => 'Optional fields for transactions', + 'pref_optional_fields_transaction_help' => 'By default not all fields are enabled when creating a new transaction (because of the clutter). Below, you can enable these fields if you think they could be useful for you. Of course, any field that is disabled, but already filled in, will be visible regardless of the setting.', + 'optional_tj_date_fields' => 'Date fields', + 'optional_tj_business_fields' => 'Business fields', + 'optional_tj_attachment_fields' => 'Attachment fields', + 'pref_optional_tj_interest_date' => 'Interest date', + 'pref_optional_tj_book_date' => 'Book date', + 'pref_optional_tj_process_date' => 'Processing date', + 'pref_optional_tj_due_date' => 'Due date', + 'pref_optional_tj_payment_date' => 'Payment date', + 'pref_optional_tj_invoice_date' => 'Invoice date', + 'pref_optional_tj_internal_reference' => 'Internal reference', + 'pref_optional_tj_notes' => 'Notes', + 'pref_optional_tj_attachments' => 'Attachments', + 'optional_field_meta_dates' => 'Dates', + 'optional_field_meta_business' => 'Business', + 'optional_field_attachments' => 'Attachments', + 'optional_field_meta_data' => 'Optional meta data', + + + // 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', + + // convert stuff: + 'convert_is_already_type_Withdrawal' => 'This transaction is already a withdrawal', + 'convert_is_already_type_Deposit' => 'This transaction is already a deposit', + 'convert_is_already_type_Transfer' => 'This transaction is already a transfer', + 'convert_to_Withdrawal' => 'Convert ":description" to a withdrawal', + 'convert_to_Deposit' => 'Convert ":description" to a deposit', + 'convert_to_Transfer' => 'Convert ":description" to a transfer', + 'convert_options_WithdrawalDeposit' => 'Convert a withdrawal into a deposit', + 'convert_options_WithdrawalTransfer' => 'Convert a withdrawal into a transfer', + 'convert_options_DepositTransfer' => 'Convert a deposit into a transfer', + 'convert_options_DepositWithdrawal' => 'Convert a deposit into a withdrawal', + 'convert_options_TransferWithdrawal' => 'Convert a transfer into a withdrawal', + 'convert_options_TransferDeposit' => 'Convert a transfer into a deposit', + 'transaction_journal_convert_options' => 'Convert this transaction', + 'convert_Withdrawal_to_deposit' => 'Convert this withdrawal to a deposit', + 'convert_Withdrawal_to_transfer' => 'Convert this withdrawal to a transfer', + 'convert_Deposit_to_withdrawal' => 'Convert this deposit to a withdrawal', + 'convert_Deposit_to_transfer' => 'Convert this deposit to a transfer', + 'convert_Transfer_to_deposit' => 'Convert this transfer to a deposit', + 'convert_Transfer_to_withdrawal' => 'Convert this transfer to a withdrawal', + 'convert_please_set_revenue_source' => 'Please pick the revenue account where the money will come from.', + 'convert_please_set_asset_destination' => 'Please pick the asset account where the money will go to.', + 'convert_please_set_expense_destination' => 'Please pick the expense account where the money will go to.', + 'convert_please_set_asset_source' => 'Please pick the asset account where the money will come from.', + 'convert_explanation_withdrawal_deposit' => 'If you convert this withdrawal into a deposit, :amount will be deposited into :sourceName instead of taken from it.', + 'convert_explanation_withdrawal_transfer' => 'If you convert this withdrawal into a transfer, :amount will be transferred from :sourceName to a new asset account, instead of being paid to :destinationName.', + 'convert_explanation_deposit_withdrawal' => 'If you convert this deposit into a withdrawal, :amount will be removed from :destinationName instead of added to it.', + 'convert_explanation_deposit_transfer' => 'If you convert this deposit into a transfer, :amount will be transferred from an asset account of your choice into :destinationName.', + 'convert_explanation_transfer_withdrawal' => 'If you convert this transfer into a withdrawal, :amount will go from :sourceName to a new destination as an expense, instead of to :destinationName as a transfer.', + 'convert_explanation_transfer_deposit' => 'If you convert this transfer into a deposit, :amount will be deposited into account :destinationName instead of being transferred there.', + 'converted_to_Withdrawal' => 'The transaction has been converted to a withdrawal', + 'converted_to_Deposit' => 'The transaction has been converted to a deposit', + 'converted_to_Transfer' => 'The transaction has been converted to a transfer', + + + // 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', + '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 it is still in use.', + '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', + + // budgets: + 'create_new_budget' => 'Create a new budget', + 'store_new_budget' => 'Store new budget', + 'stored_new_budget' => 'Stored new budget ":name"', + 'available_between' => 'Available between :start and :end', + 'transactionsWithoutBudget' => 'Expenses without budget', + '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.', + 'average_bill_amount_year' => 'Average bill amount (:year)', + 'average_bill_amount_overall' => 'Average bill amount (overall)', + 'not_or_not_yet' => 'Not (yet)', + 'not_expected_period' => 'Not expected this period', + // 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', + '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', + 'no_transactions_account' => 'There are no transactions (in this period) for asset account ":name".', + 'no_data_for_chart' => 'There is not enough information (yet) to generate this chart.', + 'select_more_than_one_account' => 'Please select more than one account', + 'select_more_than_one_category' => 'Please select more than one category', + 'select_more_than_one_budget' => 'Please select more than one budget', + 'from_to' => 'From :start to :end', + + // 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!', + + // 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', + 'divided' => 'divided', + 'toDivide' => 'left to divide', + + // menu and titles, should be recycled as often as possible: + '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', + 'withdrawal' => 'Withdrawal', + 'deposit' => 'Deposit', + 'account' => 'Account', + 'transfer' => 'Transfer', + 'Withdrawal' => 'Withdrawal', + 'Deposit' => 'Deposit', + 'Transfer' => 'Transfer', + 'bill' => 'Bill', + 'yes' => 'Yes', + 'no' => 'No', + 'amount' => 'Amount', + 'overview' => 'Overview', + 'saveOnAccount' => 'Save on account', + 'unknown' => 'Unknown', + 'daily' => 'Daily', + 'monthly' => 'Monthly', + 'profile' => 'Profile', + 'errors' => 'Errors', + + // reports: + 'report_default' => 'Default financial report between :start and :end', + 'report_audit' => 'Transaction history overview between :start and :end', + 'report_category' => 'Category report between :start and :end', + 'report_budget' => 'Budget report between :start and :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', + 'show_full_list' => 'Show entire list', + 'show_only_top' => 'Show only 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_category' => 'Category report', + 'report_type_budget' => 'Budget report', + '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_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', + 'reports_extra_options' => 'Extra options', + 'report_has_no_extra_options' => 'This report has no extra options', + 'reports_submit' => 'View report', + 'end_after_start_date' => 'End date of report must be after start date.', + 'select_category' => 'Select one or more categories.', + 'select_budget' => 'Select one or more budgets.', + 'income_per_category' => 'Income per category', + 'expense_per_category' => 'Expense per category', + 'expense_per_budget' => 'Expense per budget', + 'income_per_account' => 'Income per account', + 'expense_per_account' => 'Expense per account', + 'include_not_in_category' => 'Include categories not selected for this report', + 'include_not_in_budget' => 'Include budgets not selected for this report', + 'everything_else' => 'Everything else', + 'income_and_expenses' => 'Income and expenses', + 'spent_average' => 'Spent (average)', + 'income_average' => 'Income (average)', + 'transaction_count' => 'Transaction count', + 'average_spending_per_account' => 'Average spending per account', + 'average_income_per_account' => 'Average income per account', + 'total' => 'Total', + 'description' => 'Description', + 'sum_of_period' => 'Sum of period', + 'average_in_period' => 'Average in period', + + + // charts: + 'chart' => 'Chart', + 'dayOfMonth' => 'Day of the month', + 'month' => 'Month', + 'budget' => 'Budget', + 'spent' => 'Spent', + 'spent_in_budget' => 'Spent in budget', + 'left_to_spend' => 'Left to spend', + 'earned' => 'Earned', + 'overspent' => 'Overspent', + 'left' => 'Left', + 'no_budget' => '(no budget)', + 'max-amount' => 'Maximum amount', + 'min-amount' => 'Minumum amount', + 'journal-amount' => '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.', + + 'transaction_journal_information' => 'Transaction information', + 'transaction_journal_meta' => 'Meta information', + 'total_amount' => 'Total amount', + + // 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', + 'instance_configuration' => 'Configuration', + 'firefly_instance_configuration' => 'Configuration options for Firefly III', + 'setting_single_user_mode' => 'Single user mode', + 'setting_single_user_mode_explain' => 'By default, Firefly III only accepts one (1) registration: you. This is a security measure, preventing others from using your instance unless you allow them to. Future registrations are blocked. When you uncheck this box, others can use your instance as wel, assuming they can reach it (when it is connected to the internet).', + 'store_configuration' => 'Store configuration', + 'single_user_administration' => 'User administration for :email', + 'edit_user' => 'Edit user :email', + 'hidden_fields_preferences' => 'Not all fields are visible right now. You must enable them in your settings.', + 'user_data_information' => 'User data', + 'user_information' => 'User information', + 'total_size' => 'total size', + 'budget_or_budgets' => 'budget(s)', + 'budgets_with_limits' => 'budget(s) with configured amount', + 'rule_or_rules' => 'rule(s)', + 'rulegroup_or_groups' => 'rule group(s)', + 'setting_must_confirm_account' => 'Account confirmation', + 'setting_must_confirm_account_explain' => 'When this setting is enabled, users must activate their account before it can be used.', + 'configuration_updated' => 'The configuration has been updated', + 'setting_is_demo_site' => 'Demo site', + 'setting_is_demo_site_explain' => 'If you check this box, this installation will behave as if it is the demo site, which can have weird side effects.', + 'setting_send_email_notifications' => 'Send email notifications', + 'setting_send_email_explain' => 'Firefly III can send you email notifications about certain events. They will be sent to :site_owner. This email address can be set in the .env file.', + 'mail_for_lockout_help' => 'When a user is locked out', + 'mail_for_blocked_domain_help' => 'When a user tries to register using a blocked domain', + 'mail_for_blocked_email_help' => 'When a user tries to register using a blocked email address', + 'mail_for_bad_login_help' => 'When a user fails to login', + 'mail_for_blocked_login_help' => 'When a blocked user tries to login', + 'block_code_bounced' => 'Email message(s) bounced', + 'block_code_expired' => 'Demo account expired', + 'no_block_code' => 'No reason for block or user not 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. For some banks, other users have kindly provided their configuration file.', + '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_status' => 'Import status', + 'import_status_text' => 'The import is currently running, or will start momentarily.', + '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 can either execute the following command in your console, or run the web-based import. Depending on your configuration, the console import will give you more feedback.', + 'import_download_config' => 'Download configuration', + 'import_start_import' => 'Start import', + 'import_data' => 'Import data', + 'import_data_full' => 'Import data into Firefly III', + 'import' => 'Import', + 'import_file_help' => 'Select your file', + 'import_status_settings_complete' => 'The import is ready to start.', + 'import_status_import_complete' => 'The import has completed.', + 'import_status_import_running' => 'The import is currently running. Please be patient.', + 'import_status_header' => 'Import status and progress', + 'import_status_errors' => 'Import errors', + 'import_status_report' => 'Import report', + 'import_finished' => 'Import has finished', + 'import_error_single' => 'An error has occured during the import.', + 'import_error_multi' => 'Some errors occured during the import.', + 'import_error_fatal' => 'There was an error during the import routine. Please check the log files. The error seems to be:', + 'import_error_timeout' => 'The import seems to have timed out. If this error persists, please import your data using the console command.', + 'import_double' => 'Row #:row: This row has been imported before, and is stored in :description.', + 'import_finished_all' => 'The import has finished. Please check out the results below.', + 'import_with_key' => 'Import with key \':key\'', + 'import_share_configuration' => 'Please consider downloading your configuration and sharing it at the import configuration center. This will allow other users of Firefly III to import their files more easily.', + 'import_finished_report' => 'The import has finished. Please note any errors in the block above this line. All transactions imported during this particular session have been tagged, and you can check them out below. ', + 'import_finished_link' => 'The transactions imported can be found in tag :tag.', + 'need_at_least_one_account' => 'You need at least one asset account to be able to create piggy banks', + 'see_help_top_right' => 'For more information, please check out the help pages using the icon in the top right corner of the page.', + 'bread_crumb_import_complete' => 'Import ":key" complete', + 'bread_crumb_configure_import' => 'Configure import ":key"', + 'bread_crumb_import_finished' => 'Import ":key" finished', + 'import_finished_intro' => 'The import has finished! You can now see the new transactions in Firefly.', + 'import_finished_text_without_link' => 'It seems there is no tag that points to all your imported transactions. Please look for your imported data in the menu on the left, under "Transactions".', + 'import_finished_text_with_link' => 'You can find a list of your imported transactions on the page of the tag that was created for this import.', +]; \ No newline at end of file diff --git a/resources/lang/es_ES/form.php b/resources/lang/es_ES/form.php new file mode 100644 index 0000000000..af698dcb73 --- /dev/null +++ b/resources/lang/es_ES/form.php @@ -0,0 +1,188 @@ + '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', + 'currency_id' => 'Currency', + 'attachments' => 'Attachments', + 'journal_amount' => 'Amount', + 'journal_asset_source_account' => 'Asset account (source)', + 'journal_source_account_name' => 'Revenue account (source)', + 'journal_source_account_id' => 'Asset account (source)', + 'BIC' => 'BIC', + 'account_from_id' => 'From account', + 'account_to_id' => 'To account', + 'source_account' => 'Source account', + 'destination_account' => 'Destination account', + 'journal_destination_account_id' => 'Asset account (destination)', + 'asset_destination_account' => 'Asset account (destination)', + 'asset_source_account' => 'Asset account (source)', + 'journal_description' => 'Description', + 'note' => 'Notes', + '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', + + 'revenue_account_source' => 'Revenue account (source)', + 'source_account_asset' => 'Source account (asset account)', + 'destination_account_expense' => 'Destination account (expense account)', + 'destination_account_asset' => 'Destination account (asset account)', + 'source_account_revenue' => 'Source account (revenue account)', + 'type' => 'Type', + 'convert_Withdrawal' => 'Convert withdrawal', + 'convert_Deposit' => 'Convert deposit', + 'convert_Transfer' => 'Convert transfer', + + + '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_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.', + + 'email' => 'Email address', + 'password' => 'Password', + 'password_confirmation' => 'Password (again)', + 'blocked' => 'Is blocked?', + 'blocked_code' => 'Reason for block', + + + // admin + 'domain' => 'Domain', + 'single_user_mode' => 'Single user mode', + 'must_confirm_account' => 'New users must activate account', + 'is_demo_site' => 'Is demo site', + 'mail_for_lockout' => 'Locked out', + 'mail_for_blocked_domain' => 'Blocked domain', + 'mail_for_blocked_email' => 'Blocked email address', + 'mail_for_bad_login' => 'Login failure', + 'mail_for_blocked_login' => 'Blocked user', + + + // 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', + + + 'due_date' => 'Due date', + 'payment_date' => 'Payment date', + 'invoice_date' => 'Invoice date', + 'internal_reference' => 'Internal reference', +]; \ No newline at end of file diff --git a/resources/lang/es_ES/help.php b/resources/lang/es_ES/help.php new file mode 100644 index 0000000000..61210ffe41 --- /dev/null +++ b/resources/lang/es_ES/help.php @@ -0,0 +1,33 @@ + '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', +]; \ No newline at end of file diff --git a/resources/lang/es_ES/list.php b/resources/lang/es_ES/list.php new file mode 100644 index 0000000000..90625d54e6 --- /dev/null +++ b/resources/lang/es_ES/list.php @@ -0,0 +1,89 @@ + 'Buttons', + 'icon' => 'Icon', + 'id' => 'ID', + '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', + 'created_at' => 'Created at', + 'new_balance' => 'New balance', + 'account' => 'Account', + 'matchingAmount' => 'Amount', + 'lastMatch' => 'Last match', + 'split_number' => 'Split #', + 'destination' => 'Destination', + 'source' => 'Source', + 'next_expected_match' => 'Next expected match', + 'automatch' => 'Auto match?', + 'repeat_freq' => 'Repeats', + 'description' => 'Description', + 'amount' => 'Amount', + 'internal_reference' => 'Internal reference', + 'date' => 'Date', + 'interest_date' => 'Interest date', + 'book_date' => 'Book date', + 'process_date' => 'Processing date', + 'due_date' => 'Due date', + 'payment_date' => 'Payment date', + 'invoice_date' => 'Invoice date', + 'interal_reference' => 'Internal reference', + 'notes' => 'Notes', + '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', + 'source_account' => 'Source account', + 'destination_account' => 'Destination account', + + 'accounts_count' => 'Number of accounts', + 'journals_count' => 'Number of transactions', + 'attachments_count' => 'Number of attachments', + 'bills_count' => 'Number of bills', + 'categories_count' => 'Number of categories', + 'export_jobs_count' => 'Number of export jobs', + 'import_jobs_count' => 'Number of import jobs', + 'budget_count' => 'Number of budgets', + 'rule_and_groups_count' => 'Number of rules and rule groups', + 'tags_count' => 'Number of tags', +]; \ No newline at end of file diff --git a/resources/lang/es_ES/pagination.php b/resources/lang/es_ES/pagination.php new file mode 100644 index 0000000000..4eeab21dee --- /dev/null +++ b/resources/lang/es_ES/pagination.php @@ -0,0 +1,17 @@ + '« Previous', + 'next' => 'Next »', + +]; \ No newline at end of file diff --git a/resources/lang/es_ES/passwords.php b/resources/lang/es_ES/passwords.php new file mode 100644 index 0000000000..2e11aa92dc --- /dev/null +++ b/resources/lang/es_ES/passwords.php @@ -0,0 +1,19 @@ + '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.', +]; \ No newline at end of file diff --git a/resources/lang/es_ES/validation.php b/resources/lang/es_ES/validation.php new file mode 100644 index 0000000000..6d412f04fe --- /dev/null +++ b/resources/lang/es_ES/validation.php @@ -0,0 +1,90 @@ + 'This is not a valid IBAN.', + 'unique_account_number_for_user' => 'It looks like this account number is already in use.', + 'deleted_user' => 'Due to security constraints, you cannot register using this email address.', + '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.', + 'bic' => 'This is not a valid BIC.', + '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.', + 'dimensions' => 'The :attribute has invalid image dimensions.', + 'distinct' => 'The :attribute field has a duplicate value.', + 'file' => 'The :attribute must be a file.', + 'in_array' => 'The :attribute field does not exist in :other.', + 'present' => 'The :attribute field must be present.', + 'amount_zero' => 'The total amount cannot be zero', +]; \ No newline at end of file diff --git a/resources/lang/fr_FR/auth.php b/resources/lang/fr_FR/auth.php index 5d833b3d68..7fc7beebaa 100644 --- a/resources/lang/fr_FR/auth.php +++ b/resources/lang/fr_FR/auth.php @@ -22,7 +22,7 @@ return [ | */ - 'failed' => 'These credentials do not match our records.', - 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', + 'failed' => 'Ces identifiants n\'ont aucune correspondance.', + 'throttle' => 'Trop de tentatives de connexion. Veuillez essayer à nouveau dans :seconds secondes.', ]; \ No newline at end of file diff --git a/resources/lang/fr_FR/breadcrumbs.php b/resources/lang/fr_FR/breadcrumbs.php index 2b371073db..5211db8cfe 100644 --- a/resources/lang/fr_FR/breadcrumbs.php +++ b/resources/lang/fr_FR/breadcrumbs.php @@ -34,7 +34,7 @@ return [ 'create_transfer' => 'Creer un nouveau virement', 'edit_journal' => 'Éditer la transaction ":description"', 'delete_journal' => 'Supprimer la transaction ":description"', - 'tags' => 'Tags', + 'tags' => 'Mots-clés', 'createTag' => 'Créer un nouveau tag', 'edit_tag' => 'Éditer le tag ":tag"', 'delete_tag' => 'Supprimer le tag ":tag"', diff --git a/resources/lang/fr_FR/csv.php b/resources/lang/fr_FR/csv.php index 37f1a5728d..2da66f7da6 100644 --- a/resources/lang/fr_FR/csv.php +++ b/resources/lang/fr_FR/csv.php @@ -14,27 +14,27 @@ declare(strict_types = 1); return [ 'import_configure_title' => 'Configurer l\'import', - 'import_configure_intro' => 'Il y a des options pour l\'import CSV. Veuillez indiquer si votre fichier CSV contient les en-têtes dans la première colonne, et quel est le format de la date de votre champs date. Cela peut nécessiter quelques essais. Le délimiteur de champ est généralement un «, », mais pourrait également être un « ; ». Cochez cette case avec soin.', + 'import_configure_intro' => 'Il y a des options pour l\'import CSV. Veuillez indiquer si votre fichier CSV contient les en-têtes dans la première colonne, et quel est le format des dates de vos champs date. Cela peut nécessiter quelques essais. Le délimiteur de champ est généralement un « , », mais pourrait également être un « ; ». Cochez cette case avec soin.', 'import_configure_form' => 'Basic CSV import options', 'header_help' => 'Cochez cette case si la première ligne de votre fichier CSV contient les entêtes des colonnes', - 'date_help' => 'Le format de la date et de l’heure dans votre fichier CSV. Utiliser les formats comme indiqué sur cette page. La valeur par défaut va extraire les dates qui ressemblent à ceci: :dateExample.', + 'date_help' => 'Le format de la date et de l’heure dans votre fichier CSV. Utiliser les formats comme indiqué sur cette page. La valeur par défaut va analyser les dates ressemblant à ceci: :dateExample.', 'delimiter_help' => 'Choisissez le délimiteur de champ qui est utilisé dans votre fichier d’entrée. Si vous n’êtes pas certain, la virgule est l’option la plus sûre.', - 'import_account_help' => 'Si votre fichier CSV ne contient AUCUNE informations concernant vos compte(s) actif, utilisez cette liste déroulante pour choisir à quel compte les opérations contenues dans le CSV font référence.', - 'upload_not_writeable' => 'La case grise contient un chemin d’accès. Il devrait être accessible en écriture. Veuillez vous en assurer.', + 'import_account_help' => 'Si votre fichier CSV ne contient AUCUNE information concernant vos compte(s) actif, utilisez cette liste déroulante pour choisir à quel compte les opérations contenues dans le CSV font référence.', + 'upload_not_writeable' => 'Le champ grisé contient un chemin d’accès. Il devrait être accessible en écriture. Veuillez vous en assurer.', // roles 'column_roles_title' => 'Définir le rôle des colonnes', 'column_roles_table' => 'Tableau', 'column_name' => 'Nom de colonne', - 'column_example' => 'Exemple', + 'column_example' => 'Données d’exemple de colonne', 'column_role' => 'Sens de la donnée', 'do_map_value' => 'Mapper ces valeurs', 'column' => 'Colonne', 'no_example_data' => 'Pas de données disponibles', 'store_column_roles' => 'Continuer l\'import', - 'do_not_map' => '(Ne pas mapper)', + 'do_not_map' => '(ne pas mapper)', 'map_title' => 'Lier les données importées aux données Firefly III', - '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.', + 'map_text' => 'Dans les tableaux suivants, la valeur gauche vous montre des informations trouvées dans votre fichier CSV téléchargé. C’est votre rôle de mapper cette valeur, si possible, une valeur déjà présente dans votre base de données. Firefly s’en tiendra à ce mappage. Si il n’y a pas de valeur correspondante, ou vous ne souhaitez pas la valeur spécifique de la carte, ne sélectionnez rien.', 'field_value' => 'Valeur du champ', 'field_mapped_to' => 'Mappé à', @@ -68,11 +68,11 @@ return [ 'column_opposing-id' => 'Compte destination(ID correspondant Firefly)', 'column_external-id' => 'Identifiant externe', 'column_opposing-name' => 'Compte destination (nom)', - 'column_rabo-debet-credit' => 'Rabobank specific debet/credit indicator', - 'column_ing-debet-credit' => 'ING specific debet/credit indicator', + 'column_rabo-debet-credit' => 'Indicateur spécifique débit/crédit à Rabobank', + 'column_ing-debet-credit' => 'Indicateur spécifique débit/crédit à ING', '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_sepa-db' => 'SEPA débit immédiat', 'column_tags-comma' => 'Tags (séparé par des virgules)', 'column_tags-space' => 'Tags(séparé par des espaces)', 'column_account-number' => 'Compte d’actif (numéro de compte)', diff --git a/resources/lang/fr_FR/demo.php b/resources/lang/fr_FR/demo.php new file mode 100644 index 0000000000..ed6ae7e543 --- /dev/null +++ b/resources/lang/fr_FR/demo.php @@ -0,0 +1,16 @@ + 'Sorry, there is no extra demo-explanation text for this page.', + 'see_help_icon' => 'However, the -icon in the top right corner may tell you more.', + 'index' => 'Welcome to Firefly III! On this page you get a quick overview of your finances. For more information, check out Accounts → Asset Accounts and of course the Budgets and Reports pages. Or just take a look around and see where you end up.', + + +]; \ No newline at end of file diff --git a/resources/lang/fr_FR/firefly.php b/resources/lang/fr_FR/firefly.php index 9bd76c4595..6764415fef 100644 --- a/resources/lang/fr_FR/firefly.php +++ b/resources/lang/fr_FR/firefly.php @@ -91,6 +91,15 @@ return [ 'expenses_by_budget' => 'Expenses by budget', 'income_by_category' => 'Income by category', 'cannot_redirect_to_account' => 'Firefly III cannot redirect you to the correct page. Apologies.', + 'sum_of_expenses' => 'Sum of expenses', + 'sum_of_income' => 'Sum of income', + 'spent_in_specific_budget' => 'Spent in budget ":budget"', + 'sum_of_expenses_in_budget' => 'Spent total in budget ":budget"', + 'left_in_budget_limit' => 'Left to spend according to budgeting', + 'cannot_change_demo' => 'You cannot change the password of the demonstration account.', + 'cannot_delete_demo' => 'You cannot remove the demonstration account.', + 'cannot_reset_demo_user' => 'You cannot reset the password of the demonstration account', + // repeat frequencies: 'repeat_freq_yearly' => 'yearly', 'repeat_freq_monthly' => 'mensuel', @@ -194,6 +203,7 @@ return [ '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', + 'rule_group_select_transactions' => 'Execute rule group ":title" on existing transactions', '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' => 'Exécution groupe « : titre » pour les transactions existantes', @@ -632,10 +642,10 @@ return [ 'errors' => 'Erreurs', // reports: - 'report_default' => 'Rapport financier par défaut du :start au :end', - 'report_audit' => 'Historique des transactions du :start au :end', - 'report_category' => 'Category report for :start until :end', - 'report_budget' => 'Budget report for :start until :end', + 'report_default' => 'Default financial report between :start and :end', + 'report_audit' => 'Transaction history overview between :start and :end', + 'report_category' => 'Category report between :start and :end', + 'report_budget' => 'Budget report between :start and :end', 'quick_link_reports' => 'Liens rapides', 'quick_link_default_report' => 'Rapport financier par défaut', 'quick_link_audit_report' => 'Historique des transactions', diff --git a/resources/lang/hr_HR/demo.php b/resources/lang/hr_HR/demo.php new file mode 100644 index 0000000000..ed6ae7e543 --- /dev/null +++ b/resources/lang/hr_HR/demo.php @@ -0,0 +1,16 @@ + 'Sorry, there is no extra demo-explanation text for this page.', + 'see_help_icon' => 'However, the -icon in the top right corner may tell you more.', + 'index' => 'Welcome to Firefly III! On this page you get a quick overview of your finances. For more information, check out Accounts → Asset Accounts and of course the Budgets and Reports pages. Or just take a look around and see where you end up.', + + +]; \ No newline at end of file diff --git a/resources/lang/hr_HR/firefly.php b/resources/lang/hr_HR/firefly.php index 7d587786c5..e9d4f2d538 100644 --- a/resources/lang/hr_HR/firefly.php +++ b/resources/lang/hr_HR/firefly.php @@ -91,6 +91,15 @@ return [ 'expenses_by_budget' => 'Expenses by budget', 'income_by_category' => 'Income by category', 'cannot_redirect_to_account' => 'Firefly III cannot redirect you to the correct page. Apologies.', + 'sum_of_expenses' => 'Sum of expenses', + 'sum_of_income' => 'Sum of income', + 'spent_in_specific_budget' => 'Spent in budget ":budget"', + 'sum_of_expenses_in_budget' => 'Spent total in budget ":budget"', + 'left_in_budget_limit' => 'Left to spend according to budgeting', + 'cannot_change_demo' => 'You cannot change the password of the demonstration account.', + 'cannot_delete_demo' => 'You cannot remove the demonstration account.', + 'cannot_reset_demo_user' => 'You cannot reset the password of the demonstration account', + // repeat frequencies: 'repeat_freq_yearly' => 'yearly', 'repeat_freq_monthly' => 'monthly', @@ -194,6 +203,7 @@ return [ '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', + 'rule_group_select_transactions' => 'Execute rule group ":title" on 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', @@ -632,10 +642,10 @@ return [ 'errors' => 'Errors', // reports: - 'report_default' => 'Default financial report for :start until :end', - 'report_audit' => 'Transaction history overview for :start until :end', - 'report_category' => 'Category report for :start until :end', - 'report_budget' => 'Budget report for :start until :end', + 'report_default' => 'Default financial report between :start and :end', + 'report_audit' => 'Transaction history overview between :start and :end', + 'report_category' => 'Category report between :start and :end', + 'report_budget' => 'Budget report between :start and :end', 'quick_link_reports' => 'Quick links', 'quick_link_default_report' => 'Default financial report', 'quick_link_audit_report' => 'Transaction history overview', diff --git a/resources/lang/nl_NL/demo.php b/resources/lang/nl_NL/demo.php new file mode 100644 index 0000000000..ed6ae7e543 --- /dev/null +++ b/resources/lang/nl_NL/demo.php @@ -0,0 +1,16 @@ + 'Sorry, there is no extra demo-explanation text for this page.', + 'see_help_icon' => 'However, the -icon in the top right corner may tell you more.', + 'index' => 'Welcome to Firefly III! On this page you get a quick overview of your finances. For more information, check out Accounts → Asset Accounts and of course the Budgets and Reports pages. Or just take a look around and see where you end up.', + + +]; \ No newline at end of file diff --git a/resources/lang/nl_NL/firefly.php b/resources/lang/nl_NL/firefly.php index a2abe3ea25..edcd2799ba 100644 --- a/resources/lang/nl_NL/firefly.php +++ b/resources/lang/nl_NL/firefly.php @@ -91,6 +91,15 @@ return [ 'expenses_by_budget' => 'Uitgaven per budget', 'income_by_category' => 'Inkomsten per categorie', 'cannot_redirect_to_account' => 'Firefly III kan je niet naar de goede pagina doorsturen. Sorry!', + 'sum_of_expenses' => 'Som van uitgaven', + 'sum_of_income' => 'Som van inkomsten', + 'spent_in_specific_budget' => 'Uitgegeven in budget ":budget"', + 'sum_of_expenses_in_budget' => 'Totaal uitgegeven in budget ":budget"', + 'left_in_budget_limit' => 'Nog uit te geven volgens budgettering', + 'cannot_change_demo' => 'Je kan het wachtwoord van de demonstratie-account niet wijzigen.', + 'cannot_delete_demo' => 'Je kan de demonstratie-account niet verwijderen.', + 'cannot_reset_demo_user' => 'Je kan het wachtwoord van de demonstratie-account niet resetten', + // repeat frequencies: 'repeat_freq_yearly' => 'jaarlijks', 'repeat_freq_monthly' => 'maandelijks', @@ -194,6 +203,7 @@ return [ 'warning_no_matching_transactions' => 'Niks gevonden in je laatste :num_transactions transacties.', 'warning_no_valid_triggers' => 'Geen geldige triggers gevonden.', 'execute_on_existing_transactions' => 'Toepassen op bestaande transacties', + 'rule_group_select_transactions' => 'Regelgroep ":title" uitvoeren op bestaande transacties', 'execute_on_existing_transactions_intro' => 'Wanneer een regel of groep is veranderd of toegevoegd, kun je hem hier uitvoeren voor bestaande transacties', 'execute_on_existing_transactions_short' => 'Bestaande transacties', 'executed_group_on_existing_transactions' => 'Regelgroep ":title" is uitgevoerd op bestaande transacties', @@ -635,7 +645,7 @@ return [ 'report_default' => 'Standaard financieel rapport (:start tot :end)', 'report_audit' => 'Transactiehistorie-overzicht van :start tot :end', 'report_category' => 'Categorierapport van :start tot :end', - 'report_budget' => 'Budgetrapport van :start tot en met :end', + 'report_budget' => 'Budgetrapport van :start tot :end', 'quick_link_reports' => 'Snelle links', 'quick_link_default_report' => 'Standaard financieel rapport', 'quick_link_audit_report' => 'Transactiehistorie-overzicht', diff --git a/resources/lang/pt_BR/demo.php b/resources/lang/pt_BR/demo.php new file mode 100644 index 0000000000..ed6ae7e543 --- /dev/null +++ b/resources/lang/pt_BR/demo.php @@ -0,0 +1,16 @@ + 'Sorry, there is no extra demo-explanation text for this page.', + 'see_help_icon' => 'However, the -icon in the top right corner may tell you more.', + 'index' => 'Welcome to Firefly III! On this page you get a quick overview of your finances. For more information, check out Accounts → Asset Accounts and of course the Budgets and Reports pages. Or just take a look around and see where you end up.', + + +]; \ No newline at end of file diff --git a/resources/lang/pt_BR/firefly.php b/resources/lang/pt_BR/firefly.php index 71fb3492b6..6ff5b76cca 100644 --- a/resources/lang/pt_BR/firefly.php +++ b/resources/lang/pt_BR/firefly.php @@ -91,6 +91,15 @@ return [ 'expenses_by_budget' => 'Despesas pelo orçamento', 'income_by_category' => 'Receitas por categoria', 'cannot_redirect_to_account' => 'Firefly III não pode redirecioná-lo para a página correta. Minhas desculpas.', + 'sum_of_expenses' => 'Sum of expenses', + 'sum_of_income' => 'Sum of income', + 'spent_in_specific_budget' => 'Spent in budget ":budget"', + 'sum_of_expenses_in_budget' => 'Spent total in budget ":budget"', + 'left_in_budget_limit' => 'Left to spend according to budgeting', + 'cannot_change_demo' => 'You cannot change the password of the demonstration account.', + 'cannot_delete_demo' => 'You cannot remove the demonstration account.', + 'cannot_reset_demo_user' => 'You cannot reset the password of the demonstration account', + // repeat frequencies: 'repeat_freq_yearly' => 'anual', 'repeat_freq_monthly' => 'mensal', @@ -194,6 +203,7 @@ return [ 'warning_no_matching_transactions' => 'Nenhuma transação correspondente encontrada. Por favor note que por motivos de desempenho, apenas as últimas :num_transactions transações tenham sido verificadas.', 'warning_no_valid_triggers' => 'Sem gatilhos válidos fornecidos.', 'execute_on_existing_transactions' => 'Executar transações existentes', + 'rule_group_select_transactions' => 'Execute rule group ":title" on existing transactions', 'execute_on_existing_transactions_intro' => 'Quando uma regra ou um grupo for alterado ou adicionado, você pode executá-lo para transações existentes', 'execute_on_existing_transactions_short' => 'Transações existentes', 'executed_group_on_existing_transactions' => 'Executado o grupo ":title" para transações existentes', @@ -632,10 +642,10 @@ return [ 'errors' => 'Erros', // 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', - 'report_category' => 'Category report for :start until :end', - 'report_budget' => 'Budget report for :start until :end', + 'report_default' => 'Default financial report between :start and :end', + 'report_audit' => 'Transaction history overview between :start and :end', + 'report_category' => 'Category report between :start and :end', + 'report_budget' => 'Budget report between :start and :end', 'quick_link_reports' => 'Ligações rápidas', 'quick_link_default_report' => 'Relatório financeiro padrão', 'quick_link_audit_report' => 'Visão geral do histórico de transação', diff --git a/resources/lang/zh_HK/demo.php b/resources/lang/zh_HK/demo.php new file mode 100644 index 0000000000..ed6ae7e543 --- /dev/null +++ b/resources/lang/zh_HK/demo.php @@ -0,0 +1,16 @@ + 'Sorry, there is no extra demo-explanation text for this page.', + 'see_help_icon' => 'However, the -icon in the top right corner may tell you more.', + 'index' => 'Welcome to Firefly III! On this page you get a quick overview of your finances. For more information, check out Accounts → Asset Accounts and of course the Budgets and Reports pages. Or just take a look around and see where you end up.', + + +]; \ No newline at end of file diff --git a/resources/lang/zh_HK/firefly.php b/resources/lang/zh_HK/firefly.php index 7d587786c5..e9d4f2d538 100644 --- a/resources/lang/zh_HK/firefly.php +++ b/resources/lang/zh_HK/firefly.php @@ -91,6 +91,15 @@ return [ 'expenses_by_budget' => 'Expenses by budget', 'income_by_category' => 'Income by category', 'cannot_redirect_to_account' => 'Firefly III cannot redirect you to the correct page. Apologies.', + 'sum_of_expenses' => 'Sum of expenses', + 'sum_of_income' => 'Sum of income', + 'spent_in_specific_budget' => 'Spent in budget ":budget"', + 'sum_of_expenses_in_budget' => 'Spent total in budget ":budget"', + 'left_in_budget_limit' => 'Left to spend according to budgeting', + 'cannot_change_demo' => 'You cannot change the password of the demonstration account.', + 'cannot_delete_demo' => 'You cannot remove the demonstration account.', + 'cannot_reset_demo_user' => 'You cannot reset the password of the demonstration account', + // repeat frequencies: 'repeat_freq_yearly' => 'yearly', 'repeat_freq_monthly' => 'monthly', @@ -194,6 +203,7 @@ return [ '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', + 'rule_group_select_transactions' => 'Execute rule group ":title" on 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', @@ -632,10 +642,10 @@ return [ 'errors' => 'Errors', // reports: - 'report_default' => 'Default financial report for :start until :end', - 'report_audit' => 'Transaction history overview for :start until :end', - 'report_category' => 'Category report for :start until :end', - 'report_budget' => 'Budget report for :start until :end', + 'report_default' => 'Default financial report between :start and :end', + 'report_audit' => 'Transaction history overview between :start and :end', + 'report_category' => 'Category report between :start and :end', + 'report_budget' => 'Budget report between :start and :end', 'quick_link_reports' => 'Quick links', 'quick_link_default_report' => 'Default financial report', 'quick_link_audit_report' => 'Transaction history overview', diff --git a/resources/lang/zh_TW/demo.php b/resources/lang/zh_TW/demo.php new file mode 100644 index 0000000000..ed6ae7e543 --- /dev/null +++ b/resources/lang/zh_TW/demo.php @@ -0,0 +1,16 @@ + 'Sorry, there is no extra demo-explanation text for this page.', + 'see_help_icon' => 'However, the -icon in the top right corner may tell you more.', + 'index' => 'Welcome to Firefly III! On this page you get a quick overview of your finances. For more information, check out Accounts → Asset Accounts and of course the Budgets and Reports pages. Or just take a look around and see where you end up.', + + +]; \ No newline at end of file diff --git a/resources/lang/zh_TW/firefly.php b/resources/lang/zh_TW/firefly.php index 6e9d309c22..bab689aed8 100644 --- a/resources/lang/zh_TW/firefly.php +++ b/resources/lang/zh_TW/firefly.php @@ -91,6 +91,15 @@ return [ 'expenses_by_budget' => 'Expenses by budget', 'income_by_category' => 'Income by category', 'cannot_redirect_to_account' => 'Firefly III cannot redirect you to the correct page. Apologies.', + 'sum_of_expenses' => 'Sum of expenses', + 'sum_of_income' => 'Sum of income', + 'spent_in_specific_budget' => 'Spent in budget ":budget"', + 'sum_of_expenses_in_budget' => 'Spent total in budget ":budget"', + 'left_in_budget_limit' => 'Left to spend according to budgeting', + 'cannot_change_demo' => 'You cannot change the password of the demonstration account.', + 'cannot_delete_demo' => 'You cannot remove the demonstration account.', + 'cannot_reset_demo_user' => 'You cannot reset the password of the demonstration account', + // repeat frequencies: 'repeat_freq_yearly' => 'yearly', 'repeat_freq_monthly' => '每月', @@ -194,6 +203,7 @@ return [ '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', + 'rule_group_select_transactions' => 'Execute rule group ":title" on 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', @@ -632,10 +642,10 @@ return [ 'errors' => 'Errors', // reports: - 'report_default' => 'Default financial report for :start until :end', - 'report_audit' => 'Transaction history overview for :start until :end', - 'report_category' => 'Category report for :start until :end', - 'report_budget' => 'Budget report for :start until :end', + 'report_default' => 'Default financial report between :start and :end', + 'report_audit' => 'Transaction history overview between :start and :end', + 'report_category' => 'Category report between :start and :end', + 'report_budget' => 'Budget report between :start and :end', 'quick_link_reports' => 'Quick links', 'quick_link_default_report' => 'Default financial report', 'quick_link_audit_report' => 'Transaction history overview', diff --git a/resources/seeds/seed.bill-test.json b/resources/seeds/seed.bill-test.json deleted file mode 100644 index be9d599077..0000000000 --- a/resources/seeds/seed.bill-test.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "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" - } - ], - "account-meta": [ - ], - "bills": [ - { - "name": "Some weird weekly bill", - "match": "weird,weekly,bill", - "amount_min": 30, - "amount_max": 35, - "user_id": 1, - "date": "2016-06-12", - "active": 1, - "automatch": 1, - "repeat_freq": "weekly", - "skip": 0 - }, - - - { - "name": "Rent", - "match": "rent,land,lord", - "amount_min": 795, - "amount_max": 805, - "user_id": 1, - "date": "2015-01-02", - "active": 1, - "automatch": 1, - "repeat_freq": "monthly", - "skip": 0 - }, - - { - "name": "Netflix subscription per quarter", - "match": "netflix,subscription", - "amount_min": 36, - "amount_max": 36, - "user_id": 1, - "date": "2016-09-06", - "active": 1, - "automatch": 1, - "repeat_freq": "quarterly", - "skip": 0 - }, - - { - "name": "Travel insurance", - "match": "abn,travel,insurance", - "amount_min": 55, - "amount_max": 62, - "user_id": 1, - "date": "2015-03-04", - "active": 1, - "automatch": 1, - "repeat_freq": "yearly", - "skip": 0 - }, - - { - "name": "Health insurance", - "match": "insurer,insurance,health", - "amount_min": 120, - "amount_max": 140, - "user_id": 1, - "date": "2015-01-07", - "active": 1, - "automatch": 1, - "repeat_freq": "monthly", - "skip": 0 - } - ], - "budgets": [ - ], - "budget-limits": [ - ], - "monthly-limits": [ - ], - "categories": [ - ], - "piggy-banks": [ - ], - "piggy-events": [ - ], - "rule-groups": [ - ], - "rules": [ - ], - "rule-triggers": [ - ], - "rule-actions": [ - ], - "tags": [ - ], - "monthly-deposits": [ - ], - "monthly-transfers": [ - ], - "monthly-withdrawals": [ - ], - "attachments": [ - ], - "multi-withdrawals": [ - ], - "multi-deposits": [ - ], - "multi-transfers": [ - ], - "import-jobs": [], - "currencies": [] -} \ No newline at end of file diff --git a/resources/seeds/seed.import-test.json b/resources/seeds/seed.import-test.json deleted file mode 100644 index 858b255717..0000000000 --- a/resources/seeds/seed.import-test.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "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 - }, - { - "name": "UnExpected Taxes", - "user_id": 1 - } - ], - "piggy-banks": [], - "piggy-events": [], - "rule-groups": [ - { - "user_id": 1, - "order": 1, - "title": "Default rules", - "description": "All your rules not in a particular group." - }, - { - "user_id": 1, - "order": 2, - "title": "Unexpected rules", - "description": "Group for unexpected rules" - } - ], - "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." - }, - { - "user_id": 1, - "rule_group_id": 2, - "order": 1, - "active": 1, - "stop_processing": 0, - "title": "Onverwachte belastingen", - "description": "Triggers on the storage of onverwachte belastingen." - } - ], - "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_id": 2, - "order": 1, - "active": 1, - "stop_processing": 0, - "trigger_type": "user_action", - "trigger_value": "store-journal" - }, - { - "rule_id": 2, - "order": 2, - "active": 1, - "stop_processing": 0, - "trigger_type": "description_contains", - "trigger_value": "(on)verwachte" - } - ], - "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" - }, - { - "rule_id": 2, - "order": 1, - "active": 1, - "stop_processing": 0, - "action_type": "set_category", - "action_value": "UnExpected Taxes" - } - ], - "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", - "extended_status": { - "steps_done": 0, - "total_steps": 0, - "errors": [], - "import_count": 0, - "importTag": 0 - }, - "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/resources/seeds/seed.local.json b/resources/seeds/seed.local.json deleted file mode 100644 index bd1d17d784..0000000000 --- a/resources/seeds/seed.local.json +++ /dev/null @@ -1,1012 +0,0 @@ -{ - "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": [ - 15, - 34, - 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": [ - 15, - 34, - 51 - ], - "category_ids": [ - 7, - 8, - 9 - ] - } - ], - "multi-transfers": [ - { - "user_id": 1, - "date": "2016-01-18", - "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-03-28", - "description": "Uneven multi-transfer (15,34,51)", - "source_ids": [ - 4, - 4, - 4 - ], - "destination_ids": [ - 5, - 5, - 5 - ], - "amounts": [ - 15, - 34, - 51 - ], - "category_ids": [ - 7, - 8, - 9 - ] - } - ], - "import-jobs": [], - "currencies": [] -} \ No newline at end of file diff --git a/resources/seeds/seed.split.json b/resources/seeds/seed.split.json deleted file mode 100644 index 38fa070988..0000000000 --- a/resources/seeds/seed.split.json +++ /dev/null @@ -1,303 +0,0 @@ -{ - "users": [ - { - "email": "thegrumpydictator@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", - "iban": "NL40UKBK3619908726" - }, - { - "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": 5, - "name": "Work SixtyFive" - }, - { - "user_id": 1, - "account_type_id": 5, - "name": "Work EightyFour" - }, - { - "user_id": 1, - "account_type_id": 5, - "name": "Work Fiftyone" - } - ], - "account-meta": [ - { - "account_id": 1, - "name": "accountRole", - "data": "\"defaultAsset\"" - }, - { - "account_id": 2, - "name": "accountRole", - "data": "\"defaultAsset\"" - } - ], - "bills": [], - "budgets": [ - { - "name": "Groceries", - "user_id": 1 - }, - { - "name": "Bills", - "user_id": 1 - }, - { - "name": "Car", - "user_id": 1 - } - ], - "budget-limits": [], - "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 - } - ], - "categories": [ - { - "name": "Daily groceries", - "user_id": 1 - }, - { - "name": "Car", - "user_id": 1 - }, - { - "name": "Reimbursements", - "user_id": 1 - } - ], - "piggy-banks": [ - { - "account_id": 2, - "name": "New camera", - "targetamount": 1000, - "startdate": "2015-04-01", - "reminder_skip": 0, - "remind_me": 0, - "order": 1, - "currentamount": 0 - }, - { - "account_id": 2, - "name": "New phone", - "targetamount": 600, - "startdate": "2015-04-01", - "reminder_skip": 0, - "remind_me": 0, - "order": 2, - "currentamount": 0 - }, - { - "account_id": 2, - "name": "New couch", - "targetamount": 500, - "startdate": "2015-04-01", - "reminder_skip": 0, - "remind_me": 0, - "order": 3, - "currentamount": 0 - } - ], - "piggy-events": [], - "rule-groups": [], - "rules": [], - "rule-triggers": [], - "rule-actions": [], - "tags": [], - "monthly-deposits": [], - "monthly-transfers": [], - "monthly-withdrawals": [], - "attachments": [], - "multi-withdrawals": [ - { - "user_id": 1, - "date": "2016-03-12", - "description": "Even multi-withdrawal (50, 50)", - "destination_ids": [ - 3, - 4 - ], - "source_id": 1, - "amounts": [ - 50, - 50 - ], - "category_ids": [ - 1, - 2, - 3 - ], - "budget_ids": [ - 1, - 2, - 3 - ] - }, - { - "user_id": 1, - "date": "2016-05-12", - "description": "Uneven multi-withdrawal (15,34,51)", - "destination_ids": [ - 3, - 4, - 5 - ], - "source_id": 1, - "amounts": [ - 15, - 34, - 51 - ], - "category_ids": [ - 1, - 2, - 3 - ], - "budget_ids": [ - 1, - 2, - 3 - ] - } - ], - "multi-deposits": [ - { - "user_id": 1, - "date": "2016-03-02", - "description": "Even multi-deposit (50, 50)", - "source_ids": [ - 6, - 7 - ], - "destination_id": 1, - "amounts": [ - 50, - 50 - ], - "category_ids": [ - 1, - 2, - 3 - ] - }, - { - "user_id": 1, - "date": "2016-05-02", - "description": "Uneven multi-deposit (15,34,51)", - "source_ids": [ - 6, - 7, - 8 - ], - "destination_id": 1, - "amounts": [ - 15, - 34, - 51 - ], - "category_ids": [ - 1, - 2, - 3 - ] - } - ], - "multi-transfers": [ - { - "user_id": 1, - "date": "2016-01-18", - "description": "Even multi-transfer (50, 50)", - "source_ids": [ - 1, - 1 - ], - "destination_ids": [ - 2, - 2 - ], - "amounts": [ - 50, - 50 - ], - "category_ids": [ - 1, - 2 - ] - }, - { - "user_id": 1, - "date": "2016-05-08", - "description": "Uneven multi-transfer (15,34,51)", - "source_ids": [ - 1, - 1, - 1 - ], - "destination_ids": [ - 2, - 2, - 2 - ], - "amounts": [ - 15, - 34, - 51 - ], - "category_ids": [ - 1, - 2, - 3 - ] - } - ], - "import-jobs": [], - "currencies": [] -} \ No newline at end of file diff --git a/resources/seeds/seed.testing.json b/resources/seeds/seed.testing.json deleted file mode 100644 index 5ec4e900f2..0000000000 --- a/resources/seeds/seed.testing.json +++ /dev/null @@ -1,1178 +0,0 @@ -{ - "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": "Some weird weekly bill", - "match": "weird,weekly,bill", - "amount_min": 30, - "amount_max": 35, - "user_id": 1, - "date": "2016-06-12", - "active": 1, - "automatch": 1, - "repeat_freq": "weekly", - "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": [ - { - "user_id": 1, - "key": "testImport", - "file_type": "csv", - "status": "settings_complete", - "extended_status": { - "steps_done": 0, - "total_steps": 0, - "errors": [], - "import_count": 0, - "importTag": 0 - }, - "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 - } - }, - - { - "user_id": 1, - "key": "complete", - "file_type": "csv", - "status": "settings_complete", - "extended_status": { - "steps_done": 0, - "total_steps": 0, - "errors": [], - "import_count": 0, - "importTag": 0 - }, - "configuration": { - "has-headers": false, - "date-format": "Ymd", - "delimiter": ",", - "import-account": 1 - } - }, - { - "user_id": 1, - "key": "configure", - "file_type": "csv", - "status": "import_status_never_started", - "extended_status": { - "steps_done": 0, - "total_steps": 0, - "errors": [], - "import_count": 0, - "importTag": 0 - }, - "configuration": { - } - }, - { - "user_id": 1, - "key": "settings", - "file_type": "csv", - "status": "import_configuration_saved", - "extended_status": { - "steps_done": 0, - "total_steps": 0, - "errors": [], - "import_count": 0, - "importTag": 0 - }, - "configuration": { - } - }, - { - "user_id": 1, - "key": "p-settings", - "file_type": "csv", - "status": "import_configuration_saved", - "extended_status": { - "steps_done": 0, - "total_steps": 0, - "errors": [], - "import_count": 0, - "importTag": 0 - }, - "configuration": { - } - }, - { - "user_id": 1, - "key": "p-configure", - "file_type": "csv", - "status": "import_status_never_started", - "extended_status": { - "steps_done": 0, - "total_steps": 0, - "errors": [], - "import_count": 0, - "importTag": 0 - }, - "configuration": { - } - }, - { - "user_id": 1, - "key": "finished", - "file_type": "csv", - "status": "import_complete", - "extended_status": { - "steps_done": 0, - "total_steps": 0, - "errors": [], - "import_count": 0, - "importTag": 1 - }, - "configuration": { - } - } - ], - "export-jobs": [ - { - "user_id": 1, - "key": "testExport", - "status": "unknown" - } - ], - "currencies": [] -} \ No newline at end of file diff --git a/resources/views/accounts/show.twig b/resources/views/accounts/show.twig index 42068245e4..37f19e9639 100644 --- a/resources/views/accounts/show.twig +++ b/resources/views/accounts/show.twig @@ -75,7 +75,7 @@

{{ 'transactions'|_ }}

@@ -90,8 +90,8 @@

- {% if budget.currentRep.id %} - {{ budget.name }} {% else %} {{ budget.name }} @@ -122,20 +122,16 @@
{{ defaultCurrency.symbol|raw }}
- - + {% if budgetInformation[budget.id]['currentRep'] %} + {% set repAmount = budgetInformation[budget.id]['currentRep'].amount %} + {% else %} + {% set repAmount = '0' %} + {% endif %} +
-
@@ -147,21 +143,23 @@ {{ session('end').formatLocalized(monthAndDayFormat) }} - {{ budget.spent|formatAmount }} + + {{ budgetInformation[budget.id]['spent']|formatAmount }} + - {% if budget.otherRepetitions.count > 0 %} + {% if budgetInformation[budget.id]['otherRepetitions'].count > 0 %}
    - {% for other in budget.otherRepetitions %} - {% if other.id != budget.currentRep.id %} -
  • Budgeted - {{ other.amount|formatAmountPlain }} - between - {{ other.startdate.formatLocalized(monthAndDayFormat) }} - and {{ other.enddate.formatLocalized(monthAndDayFormat) }}. -
  • - {% endif %} + {% for other in budgetInformation[budget.id]['otherRepetitions'] %} +
  • + + Budgeted + {{ other.amount|formatAmountPlain }} + between + {{ other.startdate.formatLocalized(monthAndDayFormat) }} + and {{ other.enddate.formatLocalized(monthAndDayFormat) }}. +
  • {% endfor %}
@@ -206,7 +204,7 @@ // budgeted data: var budgeted = {{ budgeted }}; - var budgetIncomeTotal = {{ budgetIncomeTotal }}; + var available = {{ available }}; diff --git a/resources/views/budgets/show.twig b/resources/views/budgets/show.twig index e7a552c29f..85f8c12f7c 100644 --- a/resources/views/budgets/show.twig +++ b/resources/views/budgets/show.twig @@ -11,15 +11,11 @@

{{ 'overview'|_ }}

- -
+
- -
+ {# Here be a chart with the budget limits as well if relevant.
amount spent vs budget limit reps
over the entire period the amount spent would rise and the budget limit rep would be like a heart beat jumping up and down
- needs to be two axes to work
+ needs to be two axes to work
#}
@@ -261,4 +262,4 @@ {% block styles %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/resources/views/reports/category/month.twig b/resources/views/reports/category/month.twig index 679793d770..76df238013 100644 --- a/resources/views/reports/category/month.twig +++ b/resources/views/reports/category/month.twig @@ -1,7 +1,7 @@ {% extends "./layout/default" %} {% block breadcrumbs %} - {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName) }} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, accountIds, categoryIds, start, end) }} {% endblock %} {% block content %} @@ -400,4 +400,4 @@ {% block styles %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/resources/views/reports/default/month.twig b/resources/views/reports/default/month.twig index 352f5a2d1c..22a7ebe73d 100644 --- a/resources/views/reports/default/month.twig +++ b/resources/views/reports/default/month.twig @@ -1,7 +1,7 @@ {% extends "./layout/default" %} {% block breadcrumbs %} - {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, start, end, reportType, accountIds) }} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, accountIds, start, end) }} {% endblock %} {% block content %} diff --git a/resources/views/reports/default/multi-year.twig b/resources/views/reports/default/multi-year.twig index 527eb84740..7b70416735 100644 --- a/resources/views/reports/default/multi-year.twig +++ b/resources/views/reports/default/multi-year.twig @@ -1,7 +1,7 @@ {% extends "./layout/default" %} {% block breadcrumbs %} - {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, start, end, reportType, accountIds) }} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, accountIds, start, end) }} {% endblock %} {% block content %} diff --git a/resources/views/reports/default/year.twig b/resources/views/reports/default/year.twig index aad882010d..328536ef03 100644 --- a/resources/views/reports/default/year.twig +++ b/resources/views/reports/default/year.twig @@ -1,7 +1,7 @@ {% extends "./layout/default" %} {% block breadcrumbs %} - {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, start, end, reportType, accountIds) }} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, accountIds, start, end) }} {% endblock %} {% block content %} @@ -193,4 +193,4 @@ {% endblock %} {% block styles %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/resources/views/reports/options/no-options.twig b/resources/views/reports/options/no-options.twig index c5fbcb501f..0563b9dca3 100644 --- a/resources/views/reports/options/no-options.twig +++ b/resources/views/reports/options/no-options.twig @@ -1,3 +1,3 @@

{{ 'report_has_no_extra_options'|_ }} -

\ No newline at end of file +

diff --git a/resources/views/reports/partials/budget-period.twig b/resources/views/reports/partials/budget-period.twig index e7774f2461..86d5f98aed 100644 --- a/resources/views/reports/partials/budget-period.twig +++ b/resources/views/reports/partials/budget-period.twig @@ -35,4 +35,4 @@ {% endfor %} - \ No newline at end of file + diff --git a/resources/views/reports/partials/journals-audit.twig b/resources/views/reports/partials/journals-audit.twig deleted file mode 100644 index 117d16bfbb..0000000000 --- a/resources/views/reports/partials/journals-audit.twig +++ /dev/null @@ -1,136 +0,0 @@ -{{ journals.render|raw }} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {% for journal in journals %} - - - - - - - - - - - - - - - - - - - - - - - - - - {% if journal.bill_id %} - - {% else %} - - {% endif %} - - - - - - - - - - - {% endfor %} - -
  {{ trans('list.description') }}{{ trans('list.balance_before') }}{{ trans('list.amount') }}{{ trans('list.balance_after') }}{{ trans('list.date') }}{{ trans('list.book_date') }}{{ trans('list.process_date') }}{{ trans('list.interest_date') }}{{ trans('list.due_date') }}{{ trans('list.payment_date') }}{{ trans('list.invoice_date') }}{{ trans('list.from') }}{{ trans('list.to') }}{{ trans('list.bill') }}{{ trans('list.internal_reference') }}{{ trans('list.notes') }}{{ trans('list.create_date') }}{{ trans('list.update_date') }}
-
- -
-
{{ journal|typeIcon }}{{ journal.description }} - {{ journal.before|formatAmount }}{{ journal|formatJournal }}{{ journal.after|formatAmount }}{{ journal.date.formatLocalized(monthAndDayFormat) }} - {% if journal.hasMeta('book_date') %} - {{ journal.getMeta('book_date').formatLocalized(monthAndDayFormat) }} - {% endif %} - - {% if journal.hasMeta('process_date') %} - {{ journal.getMeta('process_date').formatLocalized(monthAndDayFormat) }} - {% endif %} - - {% if journal.hasMeta('interest_date') %} - {{ journal.getMeta('interest_date').formatLocalized(monthAndDayFormat) }} - {% endif %} - - {% if journal.hasMeta('due_date') %} - {{ journal.getMeta('due_date').formatLocalized(monthAndDayFormat) }} - {% endif %} - - {% if journal.hasMeta('payment_date') %} - {{ journal.getMeta('payment_date').formatLocalized(monthAndDayFormat) }} - {% endif %} - - {% if journal.hasMeta('invoice_date') %} - {{ journal.getMeta('invoice_date').formatLocalized(monthAndDayFormat) }} - {% endif %} - - {{ sourceAccount(journal)|raw }} - - {{ destinationAccount(journal)|raw }} - - {{ journalBudgets(journal)|raw }} - - {{ journalCategories(journal)|raw }} -  {{ journal.bill.name }}  - {% if journal.hasMeta('internal_reference') %} - {{ journal.getMeta('internal_reference') }} - {% endif %} - - {% if journal.hasMeta('notes') %} - {{ journal.getMeta('notes')|nl2br }} - {% endif %} - - {{ journal.created_at.formatLocalized(dateTimeFormat) }} - - {{ journal.updated_at.formatLocalized(dateTimeFormat) }} -
- -{{ journals.render|raw }} diff --git a/resources/views/search/index.twig b/resources/views/search/index.twig index e2e3a76ffe..e166a612c7 100644 --- a/resources/views/search/index.twig +++ b/resources/views/search/index.twig @@ -113,4 +113,4 @@ {% block styles %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/resources/views/transactions/index-all.twig b/resources/views/transactions/index-all.twig index 270afeb6d1..3d63c4e0b1 100644 --- a/resources/views/transactions/index-all.twig +++ b/resources/views/transactions/index-all.twig @@ -20,4 +20,4 @@ {% endblock %} {% block scripts %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/resources/views/transactions/index-date.twig b/resources/views/transactions/index-date.twig index 8250e832f7..149aeeeb27 100644 --- a/resources/views/transactions/index-date.twig +++ b/resources/views/transactions/index-date.twig @@ -20,4 +20,4 @@ {% endblock %} {% block scripts %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/resources/views/vendor/.gitkeep b/resources/views/vendor/.gitkeep old mode 100755 new mode 100644 diff --git a/routes/api.php b/routes/api.php index 5f4cc3f27e..f5c5fdb62b 100755 --- a/routes/api.php +++ b/routes/api.php @@ -3,9 +3,12 @@ * api.php * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ + declare(strict_types = 1); use Illuminate\Http\Request; diff --git a/routes/console.php b/routes/console.php index 6cfd0b721d..f0c08dc0c1 100755 --- a/routes/console.php +++ b/routes/console.php @@ -3,9 +3,12 @@ * console.php * Copyright (C) 2016 thegrumpydictator@gmail.com * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. + * This software may be modified and distributed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International License. + * + * See the LICENSE file for details. */ + declare(strict_types = 1); /* diff --git a/routes/web.php b/routes/web.php index 4573eb6696..e053bf6acd 100755 --- a/routes/web.php +++ b/routes/web.php @@ -287,7 +287,7 @@ Route::group( Route::group( ['middleware' => 'user-full-auth', 'namespace' => 'Chart', 'prefix' => 'chart/category', 'as' => 'chart.category.'], function () { - Route::get('frontpage', ['uses' => 'CategoryController@frontpage']); + Route::get('frontpage', ['uses' => 'CategoryController@frontpage', 'as' => 'frontpage']); Route::get('period/{category}', ['uses' => 'CategoryController@currentPeriod', 'as' => 'current']); Route::get('period/{category}/{date}', ['uses' => 'CategoryController@specificPeriod', 'as' => 'specific']); Route::get('all/{category}', ['uses' => 'CategoryController@all', 'as' => 'all']); @@ -457,6 +457,7 @@ Route::group( Route::get('', ['uses' => 'ProfileController@index', 'as' => 'index']); Route::get('change-password', ['uses' => 'ProfileController@changePassword', 'as' => 'change-password']); Route::get('delete-account', ['uses' => 'ProfileController@deleteAccount', 'as' => 'delete-account']); + Route::post('delete-account', ['uses' => 'ProfileController@postDeleteAccount', 'as' => 'delete-account.post']); Route::post('change-password', ['uses' => 'ProfileController@postChangePassword', 'as' => 'change-password.post']); } diff --git a/storage/database/.gitignore b/storage/database/.gitignore index 2f8355d95c..5382885af6 100644 --- a/storage/database/.gitignore +++ b/storage/database/.gitignore @@ -1,3 +1,3 @@ * !.gitignore -!seed.*.json \ No newline at end of file +!databasecopy.sqlite \ No newline at end of file diff --git a/storage/database/databasecopy.sqlite b/storage/database/databasecopy.sqlite new file mode 100644 index 0000000000..41f250808b Binary files /dev/null and b/storage/database/databasecopy.sqlite differ diff --git a/test.sh b/test.sh index b1e52c6932..befdb1c714 100755 --- a/test.sh +++ b/test.sh @@ -7,16 +7,17 @@ BACKUPENV=./.env.current TESTINGENV=./.env.testing # do something with flags: -resetestflag='' +resetTestFlag='' testflag='' coverageflag='' acceptancetestclass='' verbalflag='' +testsuite='' -while getopts 'vcrta:' flag; do +while getopts 'vcrta:s:' flag; do case "${flag}" in r) - resetestflag='true' + resetTestFlag='true' ;; t) testflag='true' @@ -25,12 +26,17 @@ while getopts 'vcrta:' flag; do coverageflag='true' ;; v) - verbalflag=' -v' + verbalflag=' -v --debug' + echo "Will be verbal about it" ;; a) acceptancetestclass=./tests/acceptance/$OPTARG echo "Will only run acceptance test $OPTARG" ;; + s) + testsuite="--testsuite $OPTARG" + echo "Will only run test suite '$OPTARG'" + ;; *) error "Unexpected option ${flag}" ;; esac done @@ -49,7 +55,7 @@ cp $TESTINGENV $ORIGINALENV php artisan cache:clear # reset database (optional) -if [[ $resetestflag == "true" ]] +if [[ $resetTestFlag == "true" ]] then echo "Must reset database" @@ -63,12 +69,14 @@ then # run migration php artisan migrate:refresh --seed + # call test data generation script + $(which php) /sites/FF3/test-data/artisan generate:data testing sqlite # copy new database over backup (resets backup) cp $DATABASE $DATABASECOPY fi # do not reset database (optional) -if [[ $resetestflag == "" ]] +if [[ $resetTestFlag == "" ]] then echo "Will not reset database" fi @@ -85,11 +93,13 @@ else if [[ $coverageflag == "" ]] then - echo "Must run PHPUnit without coverage" - phpunit --stop-on-error $verbalflag $acceptancetestclass + echo "Must run PHPUnit without coverage:" + echo "phpunit --stop-on-error $verbalflag $acceptancetestclass $testsuite" + phpunit --stop-on-error $verbalflag $acceptancetestclass $testsuite else echo "Must run PHPUnit with coverage" - phpunit --stop-on-error $verbalflag --configuration phpunit.coverage.xml $acceptancetestclass + echo "phpunit --stop-on-error $verbalflag --configuration phpunit.coverage.xml $acceptancetestclass $testsuite" + phpunit --stop-on-error $verbalflag --configuration phpunit.coverage.xml $acceptancetestclass $testsuite fi fi diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php old mode 100755 new mode 100644 diff --git a/tests/TestCase.php b/tests/TestCase.php old mode 100755 new mode 100644 index b4003cb46a..f0aed4568b --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -94,6 +94,15 @@ abstract class TestCase extends Illuminate\Foundation\Testing\TestCase } + /** + * @return User + */ + public function emptyUser() + { + $user = User::find(2); + + return $user; + } /** * @return User diff --git a/tests/acceptance/Controllers/AccountControllerTest.php b/tests/acceptance/Controllers/AccountControllerTest.php index 4120968399..fb03855828 100644 --- a/tests/acceptance/Controllers/AccountControllerTest.php +++ b/tests/acceptance/Controllers/AccountControllerTest.php @@ -8,8 +8,11 @@ * * See the LICENSE file for details. */ +use FireflyIII\Helpers\Collector\JournalCollectorInterface; use FireflyIII\Models\Account; use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\Account\AccountTaskerInterface; +use Illuminate\Pagination\LengthAwarePaginator; /** @@ -105,10 +108,18 @@ class AccountControllerTest extends TestCase public function testShow(string $range) { - $tasker = $this->mock(\FireflyIII\Repositories\Account\AccountTaskerInterface::class); + $tasker = $this->mock(AccountTaskerInterface::class); $tasker->shouldReceive('amountOutInPeriod')->withAnyArgs()->andReturn('-1'); $tasker->shouldReceive('amountInInPeriod')->withAnyArgs()->andReturn('1'); + $collector = $this->mock(JournalCollectorInterface::class); + $collector->shouldReceive('setAccounts')->andReturnSelf(); + $collector->shouldReceive('setRange')->andReturnSelf(); + $collector->shouldReceive('setLimit')->andReturnSelf(); + $collector->shouldReceive('setPage')->andReturnSelf(); + $collector->shouldReceive('getPaginatedJournals')->andReturn(new LengthAwarePaginator([], 0, 10)); + + $this->be($this->user()); $this->changeDateRange($this->user(), $range); $this->call('GET', route('accounts.show', [1])); diff --git a/tests/acceptance/Controllers/Admin/ConfigurationControllerTest.php b/tests/acceptance/Controllers/Admin/ConfigurationControllerTest.php index 0555d656bd..6c3e6f4f44 100644 --- a/tests/acceptance/Controllers/Admin/ConfigurationControllerTest.php +++ b/tests/acceptance/Controllers/Admin/ConfigurationControllerTest.php @@ -48,7 +48,7 @@ class ConfigurationControllerTest extends TestCase FireflyConfig::shouldReceive('get')->withArgs(['single_user_mode', true])->once()->andReturn($trueConfig); FireflyConfig::shouldReceive('get')->withArgs(['must_confirm_account', false])->once()->andReturn($falseConfig); - FireflyConfig::shouldReceive('get')->withArgs(['is_demo_site', false])->once()->andReturn($falseConfig); + FireflyConfig::shouldReceive('get')->withArgs(['is_demo_site', false])->times(2)->andReturn($falseConfig); // new settings: FireflyConfig::shouldReceive('get')->withArgs(['mail_for_lockout', false])->once()->andReturn($falseConfig); @@ -69,7 +69,10 @@ class ConfigurationControllerTest extends TestCase */ public function testPostIndex() { + $falseConfig = new Configuration; + $falseConfig->data = false; + FireflyConfig::shouldReceive('get')->withArgs(['is_demo_site', false])->once()->andReturn($falseConfig); FireflyConfig::shouldReceive('set')->withArgs(['single_user_mode', false])->once(); FireflyConfig::shouldReceive('set')->withArgs(['must_confirm_account', false])->once(); FireflyConfig::shouldReceive('set')->withArgs(['is_demo_site', false])->once(); diff --git a/tests/acceptance/Controllers/AttachmentControllerTest.php b/tests/acceptance/Controllers/AttachmentControllerTest.php index 6f96cf8db5..be401ef04d 100644 --- a/tests/acceptance/Controllers/AttachmentControllerTest.php +++ b/tests/acceptance/Controllers/AttachmentControllerTest.php @@ -58,6 +58,10 @@ class AttachmentControllerTest extends TestCase */ public function testDownload() { + $repository = $this->mock(AttachmentRepositoryInterface::class); + $repository->shouldReceive('exists')->once()->andReturn(true); + $repository->shouldReceive('getContent')->once()->andReturn('This is attachment number one.'); + $this->be($this->user()); $this->call('GET', route('attachments.download', [1])); $this->assertResponseStatus(200); diff --git a/tests/acceptance/Controllers/Auth/ConfirmationControllerTest.php b/tests/acceptance/Controllers/Auth/ConfirmationControllerTest.php index d4dd7aff33..c1e5cfa0cb 100644 --- a/tests/acceptance/Controllers/Auth/ConfirmationControllerTest.php +++ b/tests/acceptance/Controllers/Auth/ConfirmationControllerTest.php @@ -48,6 +48,11 @@ class ConfirmationControllerTest extends TestCase Preferences::shouldReceive('get')->withArgs(['twoFactorAuthEnabled', false])->andReturn($falsePreference); Preferences::shouldReceive('get')->withArgs(['twoFactorAuthSecret'])->andReturn(null); + $falseConfig = new Configuration; + $falseConfig->data = false; + + FireflyConfig::shouldReceive('get')->withArgs(['is_demo_site', false])->once()->andReturn($falseConfig); + FireflyConfig::shouldReceive('get')->withArgs(['must_confirm_account', false])->andReturn($trueConfig); $this->be($this->user()); $this->call('GET', route('confirmation_error')); @@ -94,6 +99,11 @@ class ConfirmationControllerTest extends TestCase $falsePreference = new Preference; $falsePreference->data = false; + $falseConfig = new Configuration; + $falseConfig->data = false; + + FireflyConfig::shouldReceive('get')->withArgs(['is_demo_site', false])->once()->andReturn($falseConfig); + Preferences::shouldReceive('get')->withArgs(['user_confirmed_last_mail', 0])->andReturn($timePreference); Preferences::shouldReceive('get')->withArgs(['twoFactorAuthEnabled', false])->andReturn($falsePreference); Preferences::shouldReceive('get')->withArgs(['twoFactorAuthSecret'])->andReturn(null); diff --git a/tests/acceptance/Controllers/BudgetControllerTest.php b/tests/acceptance/Controllers/BudgetControllerTest.php index 06d86c3bd1..cef5c1cb2e 100644 --- a/tests/acceptance/Controllers/BudgetControllerTest.php +++ b/tests/acceptance/Controllers/BudgetControllerTest.php @@ -129,10 +129,10 @@ class BudgetControllerTest extends TestCase public function testPostUpdateIncome() { $data = [ - 'amount' => 200, + 'amount' => '200', ]; $this->be($this->user()); - $this->call('post', route('budgets.income.post', [1]), $data); + $this->call('post', route('budgets.income.post'), $data); $this->assertResponseStatus(302); } diff --git a/tests/acceptance/Controllers/CategoryControllerTest.php b/tests/acceptance/Controllers/CategoryControllerTest.php index 0d4c0c25d9..856f6b44c8 100644 --- a/tests/acceptance/Controllers/CategoryControllerTest.php +++ b/tests/acceptance/Controllers/CategoryControllerTest.php @@ -168,7 +168,7 @@ class CategoryControllerTest extends TestCase $this->be($this->user()); $this->changeDateRange($this->user(), $range); - $this->call('GET', route('categories.show', [1, '2015-01-01'])); + $this->call('GET', route('categories.show.date', [1, '2015-01-01'])); $this->assertResponseStatus(200); $this->see('