diff --git a/app/Console/Commands/Upgrade/AccountCurrencies.php b/app/Console/Commands/Upgrade/AccountCurrencies.php index 1ae44be61f..3a01760f14 100644 --- a/app/Console/Commands/Upgrade/AccountCurrencies.php +++ b/app/Console/Commands/Upgrade/AccountCurrencies.php @@ -64,6 +64,7 @@ class AccountCurrencies extends Command */ public function handle(): int { + Log::debug('Now in handle()'); $this->stupidLaravel(); $start = microtime(true); if ($this->isExecuted() && true !== $this->option('force')) { @@ -71,7 +72,6 @@ class AccountCurrencies extends Command return 0; } - Log::debug('Now in updateAccountCurrencies()'); $this->updateAccountCurrencies(); if (0 === $this->count) { @@ -130,17 +130,23 @@ class AccountCurrencies extends Command */ private function updateAccount(Account $account, TransactionCurrency $currency): void { + Log::debug(sprintf('Now in updateAccount(%d, %s)', $account->id, $currency->code)); $this->accountRepos->setUser($account->user); $accountCurrency = (int)$this->accountRepos->getMetaValue($account, 'currency_id'); + Log::debug(sprintf('Account currency is #%d', $accountCurrency)); + $openingBalance = $this->accountRepos->getOpeningBalance($account); $obCurrency = 0; if (null !== $openingBalance) { $obCurrency = (int)$openingBalance->transaction_currency_id; + Log::debug('Account has opening balance.'); } + Log::debug(sprintf('Account OB currency is #%d.', $obCurrency)); // both 0? set to default currency: if (0 === $accountCurrency && 0 === $obCurrency) { + Log::debug(sprintf('Both currencies are 0, so reset to #%d (%s)', $currency->id, $currency->code)); AccountMeta::where('account_id', $account->id)->where('name', 'currency_id')->forceDelete(); AccountMeta::create(['account_id' => $account->id, 'name' => 'currency_id', 'data' => $currency->id]); $this->line(sprintf('Account #%d ("%s") now has a currency setting (%s).', $account->id, $account->name, $currency->code)); @@ -151,6 +157,7 @@ class AccountCurrencies extends Command // account is set to 0, opening balance is not? if (0 === $accountCurrency && $obCurrency > 0) { + Log::debug(sprintf('Account is #0, OB is #%d, so set account to OB as well', $obCurrency)); AccountMeta::create(['account_id' => $account->id, 'name' => 'currency_id', 'data' => $obCurrency]); $this->line(sprintf('Account #%d ("%s") now has a currency setting (#%d).', $account->id, $account->name, $obCurrency)); $this->count++; @@ -161,6 +168,7 @@ class AccountCurrencies extends Command // do not match and opening balance id is not null. if ($accountCurrency !== $obCurrency && null !== $openingBalance) { + Log::debug(sprintf('Account (#%d) and OB currency (#%d) are different. Overrule OB, set to account currency.', $accountCurrency, $obCurrency)); // update opening balance: $openingBalance->transaction_currency_id = $accountCurrency; $openingBalance->save(); @@ -174,6 +182,7 @@ class AccountCurrencies extends Command return; } + Log::debug('No changes necessary for this account.'); } /** @@ -181,8 +190,10 @@ class AccountCurrencies extends Command */ private function updateAccountCurrencies(): void { + Log::debug('Now in updateAccountCurrencies()'); $users = $this->userRepos->all(); $defaultCurrencyCode = (string)config('firefly.default_currency', 'EUR'); + Log::debug(sprintf('Default currency is %s', $defaultCurrencyCode)); foreach ($users as $user) { $this->updateCurrenciesForUser($user, $defaultCurrencyCode); } @@ -194,6 +205,7 @@ class AccountCurrencies extends Command */ private function updateCurrenciesForUser(User $user, string $systemCurrencyCode): void { + Log::debug(sprintf('Now in updateCurrenciesForUser(%s, %s)', $user->email, $systemCurrencyCode)); $this->accountRepos->setUser($user); $accounts = $this->accountRepos->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]); @@ -202,10 +214,13 @@ class AccountCurrencies extends Command if (!is_string($defaultCurrencyCode)) { $defaultCurrencyCode = $systemCurrencyCode; } + Log::debug(sprintf('Users currency pref is %s', $defaultCurrencyCode)); + /** @var TransactionCurrency $defaultCurrency */ $defaultCurrency = TransactionCurrency::where('code', $defaultCurrencyCode)->first(); if (null === $defaultCurrency) { + Log::error(sprintf('Users currency pref "%s" does not exist!', $defaultCurrencyCode)); $this->error(sprintf('User has a preference for "%s", but this currency does not exist.', $defaultCurrencyCode)); return; diff --git a/app/Console/Commands/Upgrade/OtherCurrenciesCorrections.php b/app/Console/Commands/Upgrade/OtherCurrenciesCorrections.php index 1ce062030b..0a6c6412d5 100644 --- a/app/Console/Commands/Upgrade/OtherCurrenciesCorrections.php +++ b/app/Console/Commands/Upgrade/OtherCurrenciesCorrections.php @@ -119,7 +119,7 @@ class OtherCurrenciesCorrections extends Command return null; // @codeCoverageIgnore } if (isset($this->accountCurrencies[$accountId]) && $this->accountCurrencies[$accountId] instanceof TransactionCurrency) { - return $this->accountCurrencies[$accountId]; + return $this->accountCurrencies[$accountId]; // @codeCoverageIgnore } $currencyId = (int)$this->accountRepos->getMetaValue($account, 'currency_id'); $result = $this->currencyRepos->findNull($currencyId); diff --git a/app/Factory/TransactionGroupFactory.php b/app/Factory/TransactionGroupFactory.php index 6a17eb1b54..5a6135c01e 100644 --- a/app/Factory/TransactionGroupFactory.php +++ b/app/Factory/TransactionGroupFactory.php @@ -53,7 +53,6 @@ class TransactionGroupFactory * @param array $data * * @return TransactionGroup - * @throws FireflyException */ public function create(array $data): TransactionGroup { diff --git a/app/Factory/TransactionJournalFactory.php b/app/Factory/TransactionJournalFactory.php index 61e2e3fbe1..acf1a0749f 100644 --- a/app/Factory/TransactionJournalFactory.php +++ b/app/Factory/TransactionJournalFactory.php @@ -119,7 +119,6 @@ class TransactionJournalFactory * @param array $data * * @return Collection - * @throws FireflyException */ public function create(array $data): Collection { @@ -217,7 +216,6 @@ class TransactionJournalFactory * @param NullArrayObject $row * * @return TransactionJournal|null - * @throws FireflyException */ private function createJournal(NullArrayObject $row): ?TransactionJournal { @@ -239,12 +237,19 @@ class TransactionJournalFactory /** Get source + destination account */ Log::debug(sprintf('Source info: ID #%d, name "%s"', $row['source_id'], $row['source_name'])); Log::debug(sprintf('Destination info: ID #%d, name "%s"', $row['destination_id'], $row['destination_name'])); - // validate source and destination using a new Validator. - $this->validateAccounts($row); - /** create or get source and destination accounts */ - $sourceAccount = $this->getAccount($type->type, 'source', (int)$row['source_id'], $row['source_name']); - $destinationAccount = $this->getAccount($type->type, 'destination', (int)$row['destination_id'], $row['destination_name']); + + try { + // validate source and destination using a new Validator. + $this->validateAccounts($row); + /** create or get source and destination accounts */ + $sourceAccount = $this->getAccount($type->type, 'source', (int)$row['source_id'], $row['source_name']); + $destinationAccount = $this->getAccount($type->type, 'destination', (int)$row['destination_id'], $row['destination_name']); + } catch (FireflyException $e) { + Log::error($e->getMessage()); + + return null; + } // TODO After 4.8.0 better handling below: diff --git a/app/Http/Controllers/Import/JobStatusController.php b/app/Http/Controllers/Import/JobStatusController.php index 83a87fc2a5..abde77bc25 100644 --- a/app/Http/Controllers/Import/JobStatusController.php +++ b/app/Http/Controllers/Import/JobStatusController.php @@ -106,7 +106,7 @@ class JobStatusController extends Controller // if count is zero: if (null !== $importJob->tag_id) { - $count = $importJob->tag->transactionJournals->count(); + $count = $this->repository->countByTag($importJob); } if (0 === $count) { $json['report_txt'] = (string)trans('import.result_no_transactions'); diff --git a/app/Jobs/CreateRecurringTransactions.php b/app/Jobs/CreateRecurringTransactions.php index 7979698499..95ebf86877 100644 --- a/app/Jobs/CreateRecurringTransactions.php +++ b/app/Jobs/CreateRecurringTransactions.php @@ -48,7 +48,6 @@ namespace FireflyIII\Jobs; use Carbon\Carbon; use FireflyIII\Events\RequestedReportOnJournals; use FireflyIII\Events\StoredTransactionGroup; -use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\PiggyBankEventFactory; use FireflyIII\Factory\PiggyBankFactory; use FireflyIII\Models\Recurrence; @@ -59,10 +58,7 @@ use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; -use FireflyIII\Repositories\Rule\RuleRepositoryInterface; use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface; -use FireflyIII\TransactionRules\Engine\RuleEngine; -use FireflyIII\User; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; @@ -73,8 +69,8 @@ use Log; /** * Class CreateRecurringTransactions. - * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * */ class CreateRecurringTransactions implements ShouldQueue { @@ -88,13 +84,19 @@ class CreateRecurringTransactions implements ShouldQueue private $groupRepository; /** @var RecurringRepositoryInterface Recurring transactions repository. */ private $repository; - /** @var array The users rules. */ - private $rules = []; /** @var bool Force the transaction to be created no matter what. */ private $force; + /** @var int Number of recurrences submitted */ + public $submitted; + /** @var int Number of recurrences actually fired */ + public $executed; + /** @var int Transaction groups created */ + public $created; + /** * Create a new job instance. + * @codeCoverageIgnore * * @param Carbon $date */ @@ -106,6 +108,9 @@ class CreateRecurringTransactions implements ShouldQueue $this->journalRepository = app(JournalRepositoryInterface::class); $this->groupRepository = app(TransactionGroupRepositoryInterface::class); $this->force = false; + $this->submitted = 0; + $this->executed = 0; + $this->created = 0; Log::debug(sprintf('Created new CreateRecurringTransactions("%s")', $this->date->format('Y-m-d'))); @@ -121,22 +126,18 @@ class CreateRecurringTransactions implements ShouldQueue /** * Execute the job. - * - * @throws FireflyException */ public function handle(): void { Log::debug(sprintf('Now at start of CreateRecurringTransactions() job for %s.', $this->date->format('D d M Y'))); - $recurrences = $this->repository->getAll(); - $result = []; - Log::debug(sprintf('Count of collection is %d', $recurrences->count())); + $recurrences = $this->repository->getAll(); + $result = []; + $count = $recurrences->count(); + $this->submitted = $count; + Log::debug(sprintf('Count of collection is %d', $count)); - /** @var Collection $filtered */ - $filtered = $recurrences->filter( - function (Recurrence $recurrence) { - return $this->validRecurrence($recurrence); - } - ); + // filter recurrences: + $filtered = $this->filterRecurrences($recurrences); Log::debug(sprintf('Left after filtering is %d', $filtered->count())); /** @var Recurrence $recurrence */ foreach ($filtered as $recurrence) { @@ -150,6 +151,7 @@ class CreateRecurringTransactions implements ShouldQueue $created = $this->handleRepetitions($recurrence); Log::debug(sprintf('Done with recurrence #%d', $recurrence->id)); $result[$recurrence->user_id] = $result[$recurrence->user_id]->merge($created); + $this->executed++; } Log::debug('Now running report thing.'); @@ -176,36 +178,6 @@ class CreateRecurringTransactions implements ShouldQueue return $recurrence->active; } - /** - * Apply the users rules to newly created journals. - * - * @param User $user - * @param Collection $groups - * - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - */ - private function applyRules(User $user, Collection $groups): void - { - $userId = $user->id; - if (!isset($this->rules[$userId])) { - $this->rules[$userId] = $this->getRules($user); - } - - /** @var RuleEngine $ruleEngine */ - $ruleEngine = app(RuleEngine::class); - $ruleEngine->setUser($user); - $ruleEngine->setAllRules(true); - - // run the rules: - /** @var TransactionGroup $group */ - foreach ($groups as $group) { - /** @var TransactionJournal $journal */ - foreach ($group->transactionJournals as $journal) { - //$ruleEngine->processTransactionJournal($journal); - } - } - } - /** * Helper function for debug information. * @@ -223,43 +195,6 @@ class CreateRecurringTransactions implements ShouldQueue return $return; } - /** - * @param Recurrence $recurrence - * - * @return int - */ - private function getPiggyId(Recurrence $recurrence): int - { - $meta = $recurrence->recurrenceMeta; - /** @var RecurrenceMeta $metaEntry */ - foreach ($meta as $metaEntry) { - if ('piggy_bank_id' === $metaEntry->name) { - return (int)$metaEntry->value; - } - } - - return 0; - } - - /** - * Get the users rule groups. - * - * @param User $user - * - * @return Collection - */ - private function getRules(User $user): Collection - { - /** @var RuleRepositoryInterface $repository */ - $repository = app(RuleRepositoryInterface::class); - $repository->setUser($user); - $set = $repository->getForImport(); - - Log::debug(sprintf('Found %d user rules.', $set->count())); - - return $set; - } - /** * Get the start date of a recurrence. * @@ -284,6 +219,7 @@ class CreateRecurringTransactions implements ShouldQueue * @param Carbon $date * * @return array + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ private function getTransactionData(Recurrence $recurrence, Carbon $date): array { @@ -334,82 +270,80 @@ class CreateRecurringTransactions implements ShouldQueue * @param array $occurrences * * @return Collection - * @throws \FireflyIII\Exceptions\FireflyException - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ private function handleOccurrences(Recurrence $recurrence, array $occurrences): Collection { $collection = new Collection; /** @var Carbon $date */ foreach ($occurrences as $date) { - Log::debug(sprintf('Now at date %s.', $date->format('Y-m-d'))); - if ($date->ne($this->date)) { - Log::debug(sprintf('%s is not not today (%s)', $date->format('Y-m-d'), $this->date->format('Y-m-d'))); - - continue; + $result = $this->handleOccurrence($recurrence, $date); + if (null !== $result) { + $collection->push($result); } - Log::debug(sprintf('%s IS today (%s)', $date->format('Y-m-d'), $this->date->format('Y-m-d'))); - - // count created journals on THIS day. - $journalCount = $this->repository->getJournalCount($recurrence, $date, $date); - if ($journalCount > 0 && false === $this->force) { - Log::info(sprintf('Already created %d journal(s) for date %s', $journalCount, $date->format('Y-m-d'))); - continue; - } - if ($journalCount > 0 && true === $this->force) { - Log::warning(sprintf('Already created %d groups for date %s but FORCED to continue.', $journalCount, $date->format('Y-m-d'))); - } - - // create transaction array and send to factory. - $groupTitle = null; - if ($recurrence->recurrenceTransactions->count() > 0) { - /** @var RecurrenceTransaction $first */ - $first = $recurrence->recurrenceTransactions()->first(); - $groupTitle = $first->description; - } - $array = [ - 'user' => $recurrence->user_id, - 'group_title' => $groupTitle, - 'transactions' => $this->getTransactionData($recurrence, $date), - ]; - /** @var TransactionGroup $group */ - $group = $this->groupRepository->store($array); - Log::info(sprintf('Created new transaction group #%d', $group->id)); - - /** @var TransactionJournal $journal */ - foreach ($group->transactionJournals as $journal) { - // get piggy bank ID from meta data: - $piggyBankId = $this->getPiggyId($recurrence); - Log::debug(sprintf('Piggy bank ID for recurrence #%d is #%d', $recurrence->id, $piggyBankId)); - - // link to piggy bank: - /** @var PiggyBankFactory $factory */ - $factory = app(PiggyBankFactory::class); - $factory->setUser($recurrence->user); - - $piggyBank = $factory->find($piggyBankId, null); - if (null !== $piggyBank) { - /** @var PiggyBankEventFactory $factory */ - $factory = app(PiggyBankEventFactory::class); - $factory->create($journal, $piggyBank); - } - - } - - - // trigger event: - event(new StoredTransactionGroup($group, $recurrence->apply_rules)); - - // update recurring thing: - $recurrence->latest_date = $date; - $recurrence->save(); - $collection->push($group); } return $collection; } + /** + * @param Recurrence $recurrence + * @param Carbon $date + * @return TransactionGroup|null + */ + private function handleOccurrence(Recurrence $recurrence, Carbon $date): ?TransactionGroup + { + Log::debug(sprintf('Now at date %s.', $date->format('Y-m-d'))); + if ($date->ne($this->date)) { + Log::debug(sprintf('%s is not not today (%s)', $date->format('Y-m-d'), $this->date->format('Y-m-d'))); + + return null; + } + Log::debug(sprintf('%s IS today (%s)', $date->format('Y-m-d'), $this->date->format('Y-m-d'))); + + // count created journals on THIS day. + $journalCount = $this->repository->getJournalCount($recurrence, $date, $date); + if ($journalCount > 0 && false === $this->force) { + Log::info(sprintf('Already created %d journal(s) for date %s', $journalCount, $date->format('Y-m-d'))); + + return null; + } + + if ($journalCount > 0 && true === $this->force) { + Log::warning(sprintf('Already created %d groups for date %s but FORCED to continue.', $journalCount, $date->format('Y-m-d'))); + } + + // create transaction array and send to factory. + $groupTitle = null; + if ($recurrence->recurrenceTransactions->count() > 1) { + /** @var RecurrenceTransaction $first */ + // @codeCoverageIgnoreStart + $first = $recurrence->recurrenceTransactions()->first(); + $groupTitle = $first->description; + // @codeCoverageIgnoreEnd + } + $array = [ + 'user' => $recurrence->user_id, + 'group_title' => $groupTitle, + 'transactions' => $this->getTransactionData($recurrence, $date), + ]; + /** @var TransactionGroup $group */ + $group = $this->groupRepository->store($array); + $this->created++; + Log::info(sprintf('Created new transaction group #%d', $group->id)); + + // link to piggy: + $this->linkGroupToPiggies($recurrence, $group); + + // trigger event: + event(new StoredTransactionGroup($group, $recurrence->apply_rules)); + + // update recurring thing: + $recurrence->latest_date = $date; + $recurrence->save(); + + return $group; + } + /** * Separate method that will loop all repetitions and do something with it. Will return * all created transaction journals. @@ -417,8 +351,6 @@ class CreateRecurringTransactions implements ShouldQueue * @param Recurrence $recurrence * * @return Collection - * - * @throws \FireflyIII\Exceptions\FireflyException */ private function handleRepetitions(Recurrence $recurrence): Collection { @@ -549,7 +481,7 @@ class CreateRecurringTransactions implements ShouldQueue } // already fired today (with success): - if ($this->hasFiredToday($recurrence) && false === $this->force) { + if (false === $this->force && $this->hasFiredToday($recurrence)) { Log::info(sprintf('Recurrence #%d has already fired today. Skipped.', $recurrence->id)); return false; @@ -558,4 +490,37 @@ class CreateRecurringTransactions implements ShouldQueue return true; } + + /** + * @param Collection $recurrences + * @return Collection + */ + private function filterRecurrences(Collection $recurrences): Collection + { + return $recurrences->filter( + function (Recurrence $recurrence) { + return $this->validRecurrence($recurrence); + } + ); + } + + /*** + * @param Recurrence $recurrence + * @param TransactionGroup $group + */ + private function linkGroupToPiggies(Recurrence $recurrence, TransactionGroup $group): void + { + /** @var TransactionJournal $journal */ + foreach ($group->transactionJournals as $journal) { + // get piggy bank ID from meta data: + $piggyBank = $this->repository->getPiggyBank($recurrence); + if (null !== $piggyBank) { + /** @var PiggyBankEventFactory $factory */ + $factory = app(PiggyBankEventFactory::class); + $factory->create($journal, $piggyBank); + } + + } + + } } diff --git a/app/Repositories/ImportJob/ImportJobRepository.php b/app/Repositories/ImportJob/ImportJobRepository.php index f393e9b7be..bd8bf775f7 100644 --- a/app/Repositories/ImportJob/ImportJobRepository.php +++ b/app/Repositories/ImportJob/ImportJobRepository.php @@ -467,4 +467,14 @@ class ImportJobRepository implements ImportJobRepositoryInterface return $size > $this->maxUploadSize; } + + /** + * @param ImportJob $job + * + * @return int + */ + public function countByTag(ImportJob $job): int + { + return $job->tag->transactionJournals->count(); + } } diff --git a/app/Repositories/ImportJob/ImportJobRepositoryInterface.php b/app/Repositories/ImportJob/ImportJobRepositoryInterface.php index 8f33c31ed6..980421554e 100644 --- a/app/Repositories/ImportJob/ImportJobRepositoryInterface.php +++ b/app/Repositories/ImportJob/ImportJobRepositoryInterface.php @@ -62,6 +62,13 @@ interface ImportJobRepositoryInterface */ public function countTransactions(ImportJob $job): int; + /** + * @param ImportJob $job + * + * @return int + */ + public function countByTag(ImportJob $job): int; + /** * @param string $importProvider * diff --git a/app/Repositories/Recurring/RecurringRepository.php b/app/Repositories/Recurring/RecurringRepository.php index 4248272e2e..62c75bab04 100644 --- a/app/Repositories/Recurring/RecurringRepository.php +++ b/app/Repositories/Recurring/RecurringRepository.php @@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\RecurrenceFactory; use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\Note; +use FireflyIII\Models\PiggyBank; use FireflyIII\Models\Preference; use FireflyIII\Models\Recurrence; use FireflyIII\Models\RecurrenceMeta; @@ -208,6 +209,24 @@ class RecurringRepository implements RecurringRepositoryInterface return ''; } + /** + * @param Recurrence $recurrence + * @return PiggyBank|null + */ + public function getPiggyBank(Recurrence $recurrence): ?PiggyBank + { + $meta = $recurrence->recurrenceMeta; + /** @var RecurrenceMeta $metaEntry */ + foreach ($meta as $metaEntry) { + if ('piggy_bank_id' === $metaEntry->name) { + $piggyId = (int)$metaEntry->value; + return $this->user->piggyBanks()->where('id', $piggyId)->first(['piggy_banks.*']); + } + } + + return null; + } + /** * Generate events in the date range. * diff --git a/app/Repositories/Recurring/RecurringRepositoryInterface.php b/app/Repositories/Recurring/RecurringRepositoryInterface.php index ee609f685b..b18caa5e93 100644 --- a/app/Repositories/Recurring/RecurringRepositoryInterface.php +++ b/app/Repositories/Recurring/RecurringRepositoryInterface.php @@ -25,6 +25,7 @@ namespace FireflyIII\Repositories\Recurring; use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Models\PiggyBank; use FireflyIII\Models\Recurrence; use FireflyIII\Models\RecurrenceRepetition; use FireflyIII\Models\RecurrenceTransaction; @@ -114,12 +115,16 @@ interface RecurringRepositoryInterface * @param Carbon $start * @param Carbon $end * - * @throws FireflyException - * * @return array */ public function getOccurrencesInRange(RecurrenceRepetition $repetition, Carbon $start, Carbon $end): array; + /** + * @param Recurrence $recurrence + * @return PiggyBank|null + */ + public function getPiggyBank(Recurrence $recurrence): ?PiggyBank; + /** * Get the tags from the recurring transaction. * diff --git a/app/Repositories/TransactionGroup/TransactionGroupRepository.php b/app/Repositories/TransactionGroup/TransactionGroupRepository.php index d606ec5a7c..c98255e2e5 100644 --- a/app/Repositories/TransactionGroup/TransactionGroupRepository.php +++ b/app/Repositories/TransactionGroup/TransactionGroupRepository.php @@ -288,8 +288,6 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface * @param array $data * * @return TransactionGroup - * - * @throws FireflyException */ public function store(array $data): TransactionGroup { diff --git a/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php b/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php index 73045993f6..034b802fcf 100644 --- a/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php +++ b/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php @@ -112,7 +112,6 @@ interface TransactionGroupRepositoryInterface * @param array $data * * @return TransactionGroup - * @throws FireflyException */ public function store(array $data): TransactionGroup; diff --git a/app/Services/Internal/Support/JournalServiceTrait.php b/app/Services/Internal/Support/JournalServiceTrait.php index e769280e67..eedb149300 100644 --- a/app/Services/Internal/Support/JournalServiceTrait.php +++ b/app/Services/Internal/Support/JournalServiceTrait.php @@ -87,7 +87,6 @@ trait JournalServiceTrait * @param string|null $accountName * * @return Account - * @throws FireflyException */ protected function getAccount(string $transactionType, string $direction, ?int $accountId, ?string $accountName): Account { diff --git a/routes/breadcrumbs.php b/routes/breadcrumbs.php index 1c654fa0cc..9f9559b23e 100644 --- a/routes/breadcrumbs.php +++ b/routes/breadcrumbs.php @@ -287,8 +287,8 @@ try { $object = $attachment->attachable; if ($object instanceof TransactionJournal) { $group = $object->transactionGroup; - if (null !== $group) { - $breadcrumbs->parent('transactions.show', [$object->transactionGroup]); + if (null !== $group && $group instanceof TransactionGroup) { + $breadcrumbs->parent('transactions.show', $object->transactionGroup); } $breadcrumbs->push(limitStringLength($attachment->filename), route('attachments.edit', [$attachment])); } diff --git a/tests/Api/V1/Controllers/AvailableBudgetControllerTest.php b/tests/Api/V1/Controllers/AvailableBudgetControllerTest.php index 2c43cf0a6f..922057e351 100644 --- a/tests/Api/V1/Controllers/AvailableBudgetControllerTest.php +++ b/tests/Api/V1/Controllers/AvailableBudgetControllerTest.php @@ -216,7 +216,7 @@ class AvailableBudgetControllerTest extends TestCase // mock calls: $repository->shouldReceive('setUser'); $repository->shouldReceive('updateAvailableBudget')->once()->andReturn($availableBudget); - $currencyRepository->shouldReceive('findNull')->andReturn(TransactionCurrency::find(1)); + $currencyRepository->shouldReceive('findNull')->andReturn($this->getEuro()); // data to submit $data = [ diff --git a/tests/Api/V1/Controllers/CurrencyControllerTest.php b/tests/Api/V1/Controllers/CurrencyControllerTest.php index b384d739f2..3dda5deaa9 100644 --- a/tests/Api/V1/Controllers/CurrencyControllerTest.php +++ b/tests/Api/V1/Controllers/CurrencyControllerTest.php @@ -62,7 +62,7 @@ class CurrencyControllerTest extends TestCase public function testStore(): void { - $currency = TransactionCurrency::first(); + $currency = $this->getEuro(); $repository = $this->mock(CurrencyRepositoryInterface::class); $transformer = $this->mock(CurrencyTransformer::class); $this->mock(UserRepositoryInterface::class); @@ -105,7 +105,7 @@ class CurrencyControllerTest extends TestCase */ public function testStoreWithDefault(): void { - $currency = TransactionCurrency::first(); + $currency = $this->getEuro(); $repository = $this->mock(CurrencyRepositoryInterface::class); $transformer = $this->mock(CurrencyTransformer::class); $userRepository = $this->mock(UserRepositoryInterface::class); @@ -151,7 +151,7 @@ class CurrencyControllerTest extends TestCase */ public function testUpdate(): void { - $currency = TransactionCurrency::first(); + $currency = $this->getEuro(); $repository = $this->mock(CurrencyRepositoryInterface::class); $transformer = $this->mock(CurrencyTransformer::class); $this->mock(UserRepositoryInterface::class); @@ -191,7 +191,7 @@ class CurrencyControllerTest extends TestCase */ public function testUpdateWithDefault(): void { - $currency = TransactionCurrency::first(); + $currency = $this->getEuro(); $repository = $this->mock(CurrencyRepositoryInterface::class); $transformer = $this->mock(CurrencyTransformer::class); $this->mock(UserRepositoryInterface::class); diff --git a/tests/Api/V1/Controllers/PiggyBankControllerTest.php b/tests/Api/V1/Controllers/PiggyBankControllerTest.php index 555c8ffe3a..6b20a2ee59 100644 --- a/tests/Api/V1/Controllers/PiggyBankControllerTest.php +++ b/tests/Api/V1/Controllers/PiggyBankControllerTest.php @@ -154,7 +154,7 @@ class PiggyBankControllerTest extends TestCase $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1'); $currencyRepos->shouldReceive('setUser'); - $currencyRepos->shouldReceive('findNull')->withArgs([1])->andReturn(TransactionCurrency::first()); + $currencyRepos->shouldReceive('findNull')->withArgs([1])->andReturn($this->getEuro()); $data = [ 'name' => 'new pigy bank ' . $this->randomInt(), diff --git a/tests/Api/V1/Controllers/SummaryControllerTest.php b/tests/Api/V1/Controllers/SummaryControllerTest.php index f58d171589..8b1a8f196f 100644 --- a/tests/Api/V1/Controllers/SummaryControllerTest.php +++ b/tests/Api/V1/Controllers/SummaryControllerTest.php @@ -69,7 +69,7 @@ class SummaryControllerTest extends TestCase $netWorth = $this->mock(NetWorthInterface::class); // data - $euro = TransactionCurrency::find(1); + $euro = $this->getEuro(); $budget = $this->user()->budgets()->inRandomOrder()->first(); $account = $this->getRandomAsset(); $journals = [ @@ -162,7 +162,7 @@ class SummaryControllerTest extends TestCase $date->addWeek(); // data - $euro = TransactionCurrency::find(1); + $euro = $this->getEuro(); $budget = $this->user()->budgets()->inRandomOrder()->first(); $account = $this->getRandomAsset(); $journals = [ diff --git a/tests/Feature/Controllers/Chart/ReportControllerTest.php b/tests/Feature/Controllers/Chart/ReportControllerTest.php index 0ed0ea43ae..1b555df8dd 100644 --- a/tests/Feature/Controllers/Chart/ReportControllerTest.php +++ b/tests/Feature/Controllers/Chart/ReportControllerTest.php @@ -71,7 +71,7 @@ class ReportControllerTest extends TestCase $netWorth->shouldReceive('getNetWorthByCurrency')->andReturn( [ [ - 'currency' => TransactionCurrency::first(), + 'currency' => $this->getEuro(), 'balance' => '123', ], ] diff --git a/tests/Feature/Controllers/HomeControllerTest.php b/tests/Feature/Controllers/HomeControllerTest.php index b2680f7774..bb83a7b10e 100644 --- a/tests/Feature/Controllers/HomeControllerTest.php +++ b/tests/Feature/Controllers/HomeControllerTest.php @@ -111,8 +111,6 @@ class HomeControllerTest extends TestCase $pref = new Preference; $pref->data = [$account->id]; Preferences::shouldReceive('get')->withArgs(['frontPageAccounts', [$account->id]])->atLeast()->once()->andReturn($pref); - //Preferences::shouldReceive('lastActivity')->atLeast()->once()->andReturn('md512345'); - //FireflyConfig::shouldReceive('set')->withArgs(['last_update_check', Mockery::any()])->once()->andReturn(new Configuration); Amount::shouldReceive('formatAnything')->atLeast()->once()->andReturn('x'); Steam::shouldReceive('balance')->atLeast()->once()->andReturn('5'); // mock stuff @@ -123,9 +121,6 @@ class HomeControllerTest extends TestCase $euro = $this->getEuro(); -// $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); -// -// $userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true); $accountRepos->shouldReceive('count')->andReturn(1)->atLeast()->once(); $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1'); diff --git a/tests/Feature/Controllers/Import/JobStatusControllerTest.php b/tests/Feature/Controllers/Import/JobStatusControllerTest.php index bf87f1c4c3..01544a6c85 100644 --- a/tests/Feature/Controllers/Import/JobStatusControllerTest.php +++ b/tests/Feature/Controllers/Import/JobStatusControllerTest.php @@ -128,6 +128,7 @@ class JobStatusControllerTest extends TestCase $this->mockDefaultSession(); $importRepos->shouldReceive('countTransactions')->once()->andReturn(0); + $importRepos->shouldReceive('countByTag')->atLeast()->once()->andReturn(0); // call thing. $this->be($this->user()); @@ -155,6 +156,7 @@ class JobStatusControllerTest extends TestCase $this->mockDefaultSession(); $importRepos->shouldReceive('countTransactions')->once()->andReturn(2); + $importRepos->shouldReceive('countByTag')->atLeast()->once()->andReturn(2); $job = new ImportJob; $job->user_id = $this->user()->id; @@ -191,6 +193,7 @@ class JobStatusControllerTest extends TestCase $this->mockDefaultSession(); $importRepos->shouldReceive('countTransactions')->once()->andReturn(1); + $importRepos->shouldReceive('countByTag')->atLeast()->once()->andReturn(1); $job = new ImportJob; $job->user_id = $this->user()->id; diff --git a/tests/Feature/Controllers/PiggyBankControllerTest.php b/tests/Feature/Controllers/PiggyBankControllerTest.php index db2efd49c5..2b88d32b08 100644 --- a/tests/Feature/Controllers/PiggyBankControllerTest.php +++ b/tests/Feature/Controllers/PiggyBankControllerTest.php @@ -130,7 +130,7 @@ class PiggyBankControllerTest extends TestCase $userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true); // new account list thing. - $currency = TransactionCurrency::first(); + $currency = $this->getEuro(); $currencyRepos->shouldReceive('findNull')->andReturn($currency); Amount::shouldReceive('getDefaultCurrency')->andReturn($currency); @@ -207,7 +207,7 @@ class PiggyBankControllerTest extends TestCase // mock stuff for new account list thing. - $currency = TransactionCurrency::first(); + $currency = $this->getEuro(); $account = $this->getRandomAsset(); $currencyRepos->shouldReceive('findNull')->andReturn($currency); diff --git a/tests/TestCase.php b/tests/TestCase.php index 9985b2cf9e..bca8c6354a 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -41,6 +41,7 @@ use FireflyIII\Models\Configuration; use FireflyIII\Models\CurrencyExchangeRate; use FireflyIII\Models\PiggyBank; use FireflyIII\Models\Preference; +use FireflyIII\Models\Recurrence; use FireflyIII\Models\Rule; use FireflyIII\Models\Tag; use FireflyIII\Models\TransactionCurrency; @@ -64,6 +65,15 @@ use RuntimeException; */ abstract class TestCase extends BaseTestCase { + + /** + * @return Recurrence + */ + public function getRandomRecurrence(): Recurrence + { + return $this->user()->recurrences()->inRandomOrder()->first(); + } + /** * @return CurrencyExchangeRate */ diff --git a/tests/Unit/Console/Commands/Upgrade/AccountCurrenciesTest.php b/tests/Unit/Console/Commands/Upgrade/AccountCurrenciesTest.php index cec13c77a5..87642d6f2e 100644 --- a/tests/Unit/Console/Commands/Upgrade/AccountCurrenciesTest.php +++ b/tests/Unit/Console/Commands/Upgrade/AccountCurrenciesTest.php @@ -27,7 +27,6 @@ use FireflyIII\Models\AccountMeta; use FireflyIII\Models\Configuration; use FireflyIII\Models\Preference; use FireflyIII\Models\Transaction; -use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\User\UserRepositoryInterface; @@ -133,18 +132,24 @@ class AccountCurrenciesTest extends TestCase * Perfect run with opening balance. * * TODO this method crashes some times but not sure why. + * 2019-07-27 should be fixed. * * @covers \FireflyIII\Console\Commands\Upgrade\AccountCurrencies */ public function testHandleOpeningBalance(): void { - $false = new Configuration; - $false->data = false; - $pref = new Preference; - $pref->data = 'EUR'; - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $journal = $this->getRandomWithdrawal(); + $false = new Configuration; + $false->data = false; + $pref = new Preference; + $pref->data = 'EUR'; + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $userRepos = $this->mock(UserRepositoryInterface::class); + $journal = $this->getRandomWithdrawal(); + $euro = $this->getEuro(); + $journal->transaction_currency_id = $euro->id; + $journal->save(); + $journal->refresh(); + $account = $this->getRandomAsset(); // mock calls $accountRepos->shouldReceive('setUser')->atLeast()->once(); @@ -227,7 +232,7 @@ class AccountCurrenciesTest extends TestCase $accountRepos = $this->mock(AccountRepositoryInterface::class); $userRepos = $this->mock(UserRepositoryInterface::class); $account = $this->getRandomAsset(); - $euro = TransactionCurrency::where('code', 'EUR')->first(); + $euro = $this->getEuro(); // mock calls $accountRepos->shouldReceive('setUser')->atLeast()->once(); $accountRepos->shouldReceive('getMetaValue')->atLeast()->once()->andReturn('0'); diff --git a/tests/Unit/Generator/Report/Audit/MonthReportGeneratorTest.php b/tests/Unit/Generator/Report/Audit/MonthReportGeneratorTest.php index fe84bb407b..72a4fa9d21 100644 --- a/tests/Unit/Generator/Report/Audit/MonthReportGeneratorTest.php +++ b/tests/Unit/Generator/Report/Audit/MonthReportGeneratorTest.php @@ -117,146 +117,4 @@ class MonthReportGeneratorTest extends TestCase $this->assertTrue($result['exists']); $this->assertEquals('100', $result['endBalance']); } -// -// /** -// * @covers \FireflyIII\Generator\Report\Audit\MonthReportGenerator -// */ -// public function testBasicNoCurrency(): void -// { -// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); -// -// return; -// /** @var Account $account */ -// $account = $this->user()->accounts()->where('account_type_id', 3)->first(); -// $date = new Carbon; -// $start = Carbon::now()->startOfMonth(); -// $end = Carbon::now()->endOfMonth(); -// $generator = new MonthReportGenerator(); -// $generator->setStartDate($start); -// $generator->setEndDate($end); -// -// $collection = new Collection; -// -// // mock stuff -// $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); -// $accountRepos = $this->mock(AccountRepositoryInterface::class); -// $collector = $this->mock(TransactionCollectorInterface::class); -// Steam::shouldReceive('balance')->times(1)->andReturn('100'); -// -// // mock calls: -// $accountRepos->shouldReceive('setUser')->once(); -// $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1')->once(); -// -// $currencyRepos->shouldReceive('findNull')->withArgs([1])->andReturn(null)->once(); -// -// $collector->shouldReceive('setAccounts')->andReturnSelf(); -// $collector->shouldReceive('setRange')->andReturnSelf(); -// $collector->shouldReceive('getTransactions')->andReturn($collection); -// -// -// try { -// $generator->getAuditReport($account, $date); -// } catch (FireflyException $e) { -// $this->assertEquals('Unexpected NULL value in account currency preference.', $e->getMessage()); -// } -// } -// -// /** -// * @covers \FireflyIII\Generator\Report\Audit\MonthReportGenerator -// */ -// public function testBasicWithForeign(): void -// { -// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); -// -// return; -// /** @var Account $account */ -// $account = $this->user()->accounts()->where('account_type_id', 3)->first(); -// $date = new Carbon; -// $start = Carbon::now()->startOfMonth(); -// $end = Carbon::now()->endOfMonth(); -// $generator = new MonthReportGenerator(); -// $generator->setStartDate($start); -// $generator->setEndDate($end); -// -// $collection = new Collection; -// $transaction = $this->user()->transactions()->first(); -// $transaction->transaction_amount = '30'; -// $transaction->foreign_currency_id = 1; -// $transaction->transaction_foreign_amount = '30'; -// $collection->push($transaction); -// -// // mock stuff -// $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); -// $accountRepos = $this->mock(AccountRepositoryInterface::class); -// $collector = $this->mock(TransactionCollectorInterface::class); -// Steam::shouldReceive('balance')->times(2)->andReturn('100'); -// -// // mock calls: -// $accountRepos->shouldReceive('setUser')->once(); -// $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1')->once(); -// -// $currencyRepos->shouldReceive('findNull')->withArgs([1])->andReturn(TransactionCurrency::first())->once(); -// -// $collector->shouldReceive('setAccounts')->andReturnSelf(); -// $collector->shouldReceive('setRange')->andReturnSelf(); -// $collector->shouldReceive('getTransactions')->andReturn($collection); -// -// -// try { -// $result = $generator->getAuditReport($account, $date); -// } catch (FireflyException $e) { -// $this->assertTrue(false, $e->getMessage()); -// } -// $this->assertTrue($result['exists']); -// $this->assertEquals('100', $result['endBalance']); -// } -// -// /** -// * @covers \FireflyIII\Generator\Report\Audit\MonthReportGenerator -// */ -// public function testBasicWithTransactions(): void -// { -// $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); -// -// return; -// /** @var Account $account */ -// $account = $this->user()->accounts()->where('account_type_id', 3)->first(); -// $date = new Carbon; -// $start = Carbon::now()->startOfMonth(); -// $end = Carbon::now()->endOfMonth(); -// $generator = new MonthReportGenerator(); -// $generator->setStartDate($start); -// $generator->setEndDate($end); -// -// $collection = new Collection; -// $transaction = $this->user()->transactions()->first(); -// $transaction->transaction_amount = '30'; -// $collection->push($transaction); -// -// // mock stuff -// $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); -// $accountRepos = $this->mock(AccountRepositoryInterface::class); -// $collector = $this->mock(TransactionCollectorInterface::class); -// Steam::shouldReceive('balance')->times(2)->andReturn('100'); -// -// // mock calls: -// $accountRepos->shouldReceive('setUser')->once(); -// $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1')->once(); -// -// $currencyRepos->shouldReceive('findNull')->withArgs([1])->andReturn(TransactionCurrency::first())->once(); -// -// $collector->shouldReceive('setAccounts')->andReturnSelf(); -// $collector->shouldReceive('setRange')->andReturnSelf(); -// $collector->shouldReceive('getTransactions')->andReturn($collection); -// -// -// try { -// $result = $generator->getAuditReport($account, $date); -// } catch (FireflyException $e) { -// $this->assertTrue(false, $e->getMessage()); -// } -// $this->assertTrue($result['exists']); -// $this->assertEquals('100', $result['endBalance']); -// } - } diff --git a/tests/Unit/Jobs/CreateRecurringTransactionsTest.php b/tests/Unit/Jobs/CreateRecurringTransactionsTest.php new file mode 100644 index 0000000000..861f06754a --- /dev/null +++ b/tests/Unit/Jobs/CreateRecurringTransactionsTest.php @@ -0,0 +1,550 @@ +. + */ + +namespace Tests\Unit\Jobs; + + +use Carbon\Carbon; +use FireflyIII\Events\StoredTransactionGroup; +use FireflyIII\Factory\PiggyBankEventFactory; +use FireflyIII\Factory\PiggyBankFactory; +use FireflyIII\Jobs\CreateRecurringTransactions; +use FireflyIII\Repositories\Journal\JournalRepositoryInterface; +use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; +use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface; +use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Event; +use Log; +use Preferences; +use Tests\TestCase; + +/** + * Class CreateRecurringTransactionsTest + */ +class CreateRecurringTransactionsTest extends TestCase +{ + /** + * + */ + public function setUp(): void + { + parent::setUp(); + Log::info(sprintf('Now in %s.', get_class($this))); + } + + /** + * Submit nothing. + * + * @covers \FireflyIII\Jobs\CreateRecurringTransactions + */ + public function testBasic(): void + { + // mock classes + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $this->mock(JournalRepositoryInterface::class); + $this->mock(TransactionGroupRepositoryInterface::class); + + // mocks: + $recurringRepos->shouldReceive('getAll')->atLeast()->once()->andReturn(new Collection); + Preferences::shouldReceive('mark')->atLeast()->once(); + + $date = new Carbon(); + $job = new CreateRecurringTransactions($date); + $job->setForce(false); + $job->handle(); + + $this->assertEquals(0, $job->created); + $this->assertEquals(0, $job->executed); + $this->assertEquals(0, $job->submitted); + + } + + /** + * Submit one, but offer no occurrences. + * + * @covers \FireflyIII\Jobs\CreateRecurringTransactions + */ + public function testSingle(): void + { + // mock classes + $recurrence = $this->getRandomRecurrence(); + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $groupRepos = $this->mock(TransactionGroupRepositoryInterface::class); + + // mocks: + $groupRepos->shouldReceive('setUser')->atLeast()->once(); + $journalRepos->shouldReceive('setUser')->atLeast()->once(); + $recurringRepos->shouldReceive('setUser')->atLeast()->once(); + $recurringRepos->shouldReceive('getOccurrencesInRange')->atLeast()->once()->andReturn([]); + $recurringRepos->shouldReceive('getAll')->atLeast()->once()->andReturn(new Collection([$recurrence])); + $recurringRepos->shouldReceive('getJournalCount')->atLeast()->once()->andReturn(0); + Preferences::shouldReceive('mark')->atLeast()->once(); + + + $date = new Carbon(); + $job = new CreateRecurringTransactions($date); + + $job->handle(); + + $this->assertEquals(0, $job->created); + $this->assertEquals(1, $job->executed); + $this->assertEquals(1, $job->submitted); + } + + + + /** + * Submit one, but has already fired today + * + * @covers \FireflyIII\Jobs\CreateRecurringTransactions + */ + public function testSingleFiredToday(): void + { + // mock classes + $recurrence = $this->getRandomRecurrence(); + $recurrence->latest_date = new Carbon; + $recurrence->save(); + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $this->mock(JournalRepositoryInterface::class); + $this->mock(TransactionGroupRepositoryInterface::class); + + // mocks: + $recurringRepos->shouldReceive('getAll')->atLeast()->once()->andReturn(new Collection([$recurrence])); + $recurringRepos->shouldReceive('getJournalCount')->atLeast()->once()->andReturn(0); + Preferences::shouldReceive('mark')->atLeast()->once(); + + + $date = new Carbon(); + $job = new CreateRecurringTransactions($date); + + $job->handle(); + + $this->assertEquals(0, $job->created); + $this->assertEquals(0, $job->executed); + $this->assertEquals(1, $job->submitted); + $recurrence->latest_date =null; + $recurrence->save(); + } + + + /** + * Submit one, but offer no occurrences. + * + * @covers \FireflyIII\Jobs\CreateRecurringTransactions + */ + public function testSingleFuture(): void + { + // mock classes + $future = new Carbon; + $future->addDays(4); + $recurrence = $this->getRandomRecurrence(); + $recurrence->first_date =$future; + $recurrence->save(); + + + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $this->mock(JournalRepositoryInterface::class); + $this->mock(TransactionGroupRepositoryInterface::class); + + // mocks: + $recurringRepos->shouldReceive('getAll')->atLeast()->once()->andReturn(new Collection([$recurrence])); + $recurringRepos->shouldReceive('getJournalCount')->atLeast()->once()->andReturn(0); + Preferences::shouldReceive('mark')->atLeast()->once(); + + + $date = new Carbon(); + $job = new CreateRecurringTransactions($date); + + $job->handle(); + + $this->assertEquals(0, $job->created); + $this->assertEquals(0, $job->executed); + $this->assertEquals(1, $job->submitted); + + $recurrence->first_date =$date; + $recurrence->save(); + } + + + /** + * Submit one, but should no longer run. + * + * @covers \FireflyIII\Jobs\CreateRecurringTransactions + */ + public function testSingleOverDue(): void + { + // mock classes + $date = new Carbon(); + $yesterday = clone $date; + $yesterday->subDays(3); + $recurrence = $this->getRandomRecurrence(); + + $recurrence->repeat_until =$yesterday; + $recurrence->save(); + + + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $this->mock(JournalRepositoryInterface::class); + $this->mock(TransactionGroupRepositoryInterface::class); + + // mocks: + $recurringRepos->shouldReceive('getAll')->atLeast()->once()->andReturn(new Collection([$recurrence])); + $recurringRepos->shouldReceive('getJournalCount')->atLeast()->once()->andReturn(0); + Preferences::shouldReceive('mark')->atLeast()->once(); + + + $job = new CreateRecurringTransactions($date); + + $job->handle(); + + $this->assertEquals(0, $job->created); + $this->assertEquals(0, $job->executed); + $this->assertEquals(1, $job->submitted); + + $recurrence->repeat_until =null; + $recurrence->save(); + } + + + /** + * Submit one, but it has fired enough times already. + * + * @covers \FireflyIII\Jobs\CreateRecurringTransactions + */ + public function testSingleOccurrences(): void + { + // mock classes + $recurrence = $this->getRandomRecurrence(); + $recurrence->repetitions = 1; + $recurrence->save(); + + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $this->mock(JournalRepositoryInterface::class); + $this->mock(TransactionGroupRepositoryInterface::class); + + // mocks: + $recurringRepos->shouldReceive('getAll')->atLeast()->once()->andReturn(new Collection([$recurrence])); + $recurringRepos->shouldReceive('getJournalCount')->atLeast()->once()->andReturn(1); + Preferences::shouldReceive('mark')->atLeast()->once(); + + + $date = new Carbon(); + $job = new CreateRecurringTransactions($date); + + $job->handle(); + + $this->assertEquals(0, $job->created); + $this->assertEquals(0, $job->executed); + $this->assertEquals(1, $job->submitted); + + $recurrence->repetitions = 0; + $recurrence->save(); + } + + /** + * Submit one, but it's inactive. + * + * @covers \FireflyIII\Jobs\CreateRecurringTransactions + */ + public function testSingleInactive(): void + { + + // mock classes + $recurrence = $this->getRandomRecurrence(); + + $recurrence->active = false; + $recurrence->save(); + + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $this->mock(JournalRepositoryInterface::class); + $this->mock(TransactionGroupRepositoryInterface::class); + + // mocks: + $recurringRepos->shouldReceive('getAll')->atLeast()->once()->andReturn(new Collection([$recurrence])); + Preferences::shouldReceive('mark')->atLeast()->once(); + + + $date = new Carbon(); + $job = new CreateRecurringTransactions($date); + + $job->handle(); + + $this->assertEquals(0, $job->created); + $this->assertEquals(0, $job->executed); + $this->assertEquals(1, $job->submitted); + + $recurrence->active = true; + $recurrence->save(); + } + + + /** + * Submit one, offer occurence for today. + * + * @covers \FireflyIII\Jobs\CreateRecurringTransactions + */ + public function testSingleToday(): void + { + Event::fake(); + $date = new Carbon(); + $this->expectsEvents([StoredTransactionGroup::class]); + + $recurrence = $this->getRandomRecurrence(); + $group = $this->getRandomWithdrawalGroup(); + + // overrule some fields in the recurrence to make it seem it hasnt fired yet. + $recurrence->latest_date = null; + $recurrence->save(); + + // mock classes + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $groupRepos = $this->mock(TransactionGroupRepositoryInterface::class); + $piggyFactory = $this->mock(PiggyBankFactory::class); + $piggyEventFactory = $this->mock(PiggyBankEventFactory::class); + + // mocks: + $groupRepos->shouldReceive('setUser')->atLeast()->once(); + $journalRepos->shouldReceive('setUser')->atLeast()->once(); + $recurringRepos->shouldReceive('setUser')->atLeast()->once(); + + $recurringRepos->shouldReceive('getOccurrencesInRange')->atLeast()->once()->andReturn([$date]); + $recurringRepos->shouldReceive('getAll')->atLeast()->once()->andReturn(new Collection([$recurrence])); + $recurringRepos->shouldReceive('getJournalCount')->atLeast()->once()->andReturn(0); + $recurringRepos->shouldReceive('getPiggyBank')->atLeast()->once()->andReturnNull(); + Preferences::shouldReceive('mark')->atLeast()->once(); + + // return data: + $recurringRepos->shouldReceive('getBudget')->atLeast()->once()->andReturnNull(); + $recurringRepos->shouldReceive('getCategory')->atLeast()->once()->andReturnNull(); + $recurringRepos->shouldReceive('getTags')->atLeast()->once()->andReturn([]); + + // store journal + $groupRepos->shouldReceive('store')->atLeast()->once()->andReturn($group); + + //Event::assertDispatched(StoredTransactionGroup::class); + + $job = new CreateRecurringTransactions($date); + $job->handle(); + + $this->assertEquals(1, $job->created); + $this->assertEquals(1, $job->executed); + $this->assertEquals(1, $job->submitted); + } + + + /** + * Submit one, offer occurence for today. + * + * @covers \FireflyIII\Jobs\CreateRecurringTransactions + */ + public function testForced(): void + { + Event::fake(); + $date = new Carbon(); + $this->expectsEvents([StoredTransactionGroup::class]); + + $recurrence = $this->getRandomRecurrence(); + $group = $this->getRandomWithdrawalGroup(); + + // overrule some fields in the recurrence to make it seem it hasnt fired yet. + $recurrence->latest_date = null; + $recurrence->save(); + + // mock classes + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $groupRepos = $this->mock(TransactionGroupRepositoryInterface::class); + $piggyFactory = $this->mock(PiggyBankFactory::class); + $piggyEventFactory = $this->mock(PiggyBankEventFactory::class); + + // mocks: + $groupRepos->shouldReceive('setUser')->atLeast()->once(); + $journalRepos->shouldReceive('setUser')->atLeast()->once(); + $recurringRepos->shouldReceive('setUser')->atLeast()->once(); + + $recurringRepos->shouldReceive('getOccurrencesInRange')->atLeast()->once()->andReturn([$date]); + $recurringRepos->shouldReceive('getAll')->atLeast()->once()->andReturn(new Collection([$recurrence])); + $recurringRepos->shouldReceive('getJournalCount')->atLeast()->once()->andReturn(3); + $recurringRepos->shouldReceive('getPiggyBank')->atLeast()->once()->andReturnNull(); + Preferences::shouldReceive('mark')->atLeast()->once(); + + // return data: + $recurringRepos->shouldReceive('getBudget')->atLeast()->once()->andReturnNull(); + $recurringRepos->shouldReceive('getCategory')->atLeast()->once()->andReturnNull(); + $recurringRepos->shouldReceive('getTags')->atLeast()->once()->andReturn([]); + + // store journal + $groupRepos->shouldReceive('store')->atLeast()->once()->andReturn($group); + + //Event::assertDispatched(StoredTransactionGroup::class); + + $job = new CreateRecurringTransactions($date); + $job->setForce(true); + $job->handle(); + + $this->assertEquals(1, $job->created); + $this->assertEquals(1, $job->executed); + $this->assertEquals(1, $job->submitted); + } + + + /** + * Submit one, offer occurence for today. + * + * @covers \FireflyIII\Jobs\CreateRecurringTransactions + */ + public function testBadJournalCount(): void + { + Event::fake(); + $date = new Carbon(); + + $recurrence = $this->getRandomRecurrence(); + $group = $this->getRandomWithdrawalGroup(); + + // overrule some fields in the recurrence to make it seem it hasnt fired yet. + $recurrence->latest_date = null; + $recurrence->save(); + + // mock classes + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $groupRepos = $this->mock(TransactionGroupRepositoryInterface::class); + $piggyFactory = $this->mock(PiggyBankFactory::class); + $piggyEventFactory = $this->mock(PiggyBankEventFactory::class); + + // mocks: + $groupRepos->shouldReceive('setUser')->atLeast()->once(); + $journalRepos->shouldReceive('setUser')->atLeast()->once(); + $recurringRepos->shouldReceive('setUser')->atLeast()->once(); + + $recurringRepos->shouldReceive('getOccurrencesInRange')->atLeast()->once()->andReturn([$date]); + $recurringRepos->shouldReceive('getAll')->atLeast()->once()->andReturn(new Collection([$recurrence])); + $recurringRepos->shouldReceive('getJournalCount')->atLeast()->once()->andReturn(3); + Preferences::shouldReceive('mark')->atLeast()->once(); + + $job = new CreateRecurringTransactions($date); + $job->handle(); + + $this->assertEquals(0, $job->created); + $this->assertEquals(1, $job->executed); + $this->assertEquals(1, $job->submitted); + } + + /** + * @covers \FireflyIII\Jobs\CreateRecurringTransactions + */ + public function testSingleNotToday(): void + { + $date = new Carbon(); + $tomorrow = new Carbon(); + $tomorrow->addDays(2); + + $recurrence = $this->getRandomRecurrence(); + $group = $this->getRandomWithdrawalGroup(); + + // overrule some fields in the recurrence to make it seem it hasnt fired yet. + $recurrence->latest_date = null; + $recurrence->save(); + + // mock classes + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $groupRepos = $this->mock(TransactionGroupRepositoryInterface::class); + $piggyFactory = $this->mock(PiggyBankFactory::class); + $piggyEventFactory = $this->mock(PiggyBankEventFactory::class); + + // mocks: + $groupRepos->shouldReceive('setUser')->atLeast()->once(); + $journalRepos->shouldReceive('setUser')->atLeast()->once(); + $recurringRepos->shouldReceive('setUser')->atLeast()->once(); + + $recurringRepos->shouldReceive('getOccurrencesInRange')->atLeast()->once()->andReturn([$tomorrow]); + $recurringRepos->shouldReceive('getAll')->atLeast()->once()->andReturn(new Collection([$recurrence])); + $recurringRepos->shouldReceive('getJournalCount')->atLeast()->once()->andReturn(0); + Preferences::shouldReceive('mark')->atLeast()->once(); + + $job = new CreateRecurringTransactions($date); + $job->handle(); + + $this->assertEquals(0, $job->created); + $this->assertEquals(1, $job->executed); + $this->assertEquals(1, $job->submitted); + + } + + /** + * Submit one, offer occurence for today, with piggy + * + * @covers \FireflyIII\Jobs\CreateRecurringTransactions + */ + public function testSingleTodayPiggy(): void + { + Event::fake(); + $date = new Carbon(); + $this->expectsEvents([StoredTransactionGroup::class]); + + $recurrence = $this->getRandomRecurrence(); + $group = $this->getRandomWithdrawalGroup(); + $piggy = $this->getRandomPiggyBank(); + + // overrule some fields in the recurrence to make it seem it hasnt fired yet. + $recurrence->latest_date = null; + $recurrence->save(); + + // mock classes + $recurringRepos = $this->mock(RecurringRepositoryInterface::class); + $journalRepos = $this->mock(JournalRepositoryInterface::class); + $groupRepos = $this->mock(TransactionGroupRepositoryInterface::class); + $piggyEventFactory = $this->mock(PiggyBankEventFactory::class); + + // mocks: + $groupRepos->shouldReceive('setUser')->atLeast()->once(); + $journalRepos->shouldReceive('setUser')->atLeast()->once(); + $recurringRepos->shouldReceive('setUser')->atLeast()->once(); + + $recurringRepos->shouldReceive('getOccurrencesInRange')->atLeast()->once()->andReturn([$date]); + $recurringRepos->shouldReceive('getAll')->atLeast()->once()->andReturn(new Collection([$recurrence])); + $recurringRepos->shouldReceive('getJournalCount')->atLeast()->once()->andReturn(0); + $recurringRepos->shouldReceive('getPiggyBank')->atLeast()->once()->andReturn($piggy); + $piggyEventFactory->shouldReceive('create')->once(); + Preferences::shouldReceive('mark')->atLeast()->once(); + + // return data: + $recurringRepos->shouldReceive('getBudget')->atLeast()->once()->andReturnNull(); + $recurringRepos->shouldReceive('getCategory')->atLeast()->once()->andReturnNull(); + $recurringRepos->shouldReceive('getTags')->atLeast()->once()->andReturn([]); + + // store journal + $groupRepos->shouldReceive('store')->atLeast()->once()->andReturn($group); + + //Event::assertDispatched(StoredTransactionGroup::class); + + $job = new CreateRecurringTransactions($date); + $job->handle(); + + $this->assertEquals(1, $job->created); + $this->assertEquals(1, $job->executed); + $this->assertEquals(1, $job->submitted); + + } +} \ No newline at end of file diff --git a/tests/Unit/Support/Import/JobConfiguration/Bunq/ChooseAccountsHandlerTest.php b/tests/Unit/Support/Import/JobConfiguration/Bunq/ChooseAccountsHandlerTest.php index 6e864883d1..6395e5ef31 100644 --- a/tests/Unit/Support/Import/JobConfiguration/Bunq/ChooseAccountsHandlerTest.php +++ b/tests/Unit/Support/Import/JobConfiguration/Bunq/ChooseAccountsHandlerTest.php @@ -352,7 +352,7 @@ class ChooseAccountsHandlerTest extends TestCase $collection = new Collection; $account = $this->user()->accounts()->first(); - $euro = TransactionCurrency::first(); + $euro = $this->getEuro(); $collection->push($account); @@ -415,7 +415,7 @@ class ChooseAccountsHandlerTest extends TestCase $collection = new Collection; $account = $this->user()->accounts()->first(); - $euro = TransactionCurrency::first(); + $euro = $this->getEuro(); $collection->push($account); diff --git a/tests/Unit/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandlerTest.php b/tests/Unit/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandlerTest.php index 019d6656f9..0956c5175a 100644 --- a/tests/Unit/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandlerTest.php +++ b/tests/Unit/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandlerTest.php @@ -469,8 +469,8 @@ class ChooseAccountsHandlerTest extends TestCase $currencyRepos->shouldReceive('setUser')->once(); $importRepos->shouldReceive('setUser')->once(); - $euro = TransactionCurrency::where('code', 'EUR')->first(); - $usd = TransactionCurrency::where('code', 'USD')->first(); + $euro = $this->getEuro(); + $usd = $this->getDollar(); $first = $this->user()->accounts()->where('account_type_id', 3)->first(); $second = $this->user()->accounts()->where('account_type_id', 3)->where('id', '!=', $first->id)->first(); $accountRepos->shouldReceive('getAccountsByType')->withArgs([[AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE]]) @@ -622,8 +622,8 @@ class ChooseAccountsHandlerTest extends TestCase $currencyRepos->shouldReceive('setUser')->once(); $importRepos->shouldReceive('setUser')->once(); - $euro = TransactionCurrency::where('code', 'EUR')->first(); - $usd = TransactionCurrency::where('code', 'USD')->first(); + $euro = $this->getEuro(); + $usd = $this->getDollar(); $first = $this->user()->accounts()->where('account_type_id', 3)->first(); $second = $this->user()->accounts()->where('account_type_id', 3)->where('id', '!=', $first->id)->first(); $accountRepos->shouldReceive('getAccountsByType')->withArgs([[AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE]]) diff --git a/tests/Unit/Transformers/CurrencyTransformerTest.php b/tests/Unit/Transformers/CurrencyTransformerTest.php index 008c04369d..6038cf9868 100644 --- a/tests/Unit/Transformers/CurrencyTransformerTest.php +++ b/tests/Unit/Transformers/CurrencyTransformerTest.php @@ -53,7 +53,7 @@ class CurrencyTransformerTest extends TestCase { // mocks and prep: $parameters = new ParameterBag; - $currency = TransactionCurrency::first(); + $currency = $this->getEuro(); $transformer = app(CurrencyTransformer::class); $transformer->setParameters($parameters); @@ -75,7 +75,7 @@ class CurrencyTransformerTest extends TestCase { // mocks and prep: $parameters = new ParameterBag; - $currency = TransactionCurrency::first(); + $currency = $this->getEuro(); $parameters->set('defaultCurrency', $currency); $transformer = app(CurrencyTransformer::class); $transformer->setParameters($parameters);