diff --git a/app/Export/Entry.php b/app/Export/Entry.php index eea850edbb..40f2d84f46 100644 --- a/app/Export/Entry.php +++ b/app/Export/Entry.php @@ -80,7 +80,7 @@ class Entry $entry = new self; $entry->setDescription($journal->description); $entry->setDate($journal->date->format('Y-m-d')); - $entry->setAmount($journal->amount); // TODO TransactionJournal cannot deliver "amount". + $entry->setAmount(TransactionJournal::amount($journal)); /** @var Budget $budget */ $budget = $journal->budgets->first(); @@ -102,14 +102,14 @@ class Entry } /** @var Account $sourceAccount */ - $sourceAccount = $journal->source_account; // TODO TransactionJournal cannot deliver "source_account" + $sourceAccount = TransactionJournal::sourceAccount($journal); $entry->setFromAccountId($sourceAccount->id); $entry->setFromAccountName($sourceAccount->name); $entry->setFromAccountIban($sourceAccount->iban); $entry->setFromAccountType($sourceAccount->accountType->type); /** @var Account $destination */ - $destination = $journal->destination_account; // TODO TransactionJournal cannot deliver "destination_account" + $destination = TransactionJournal::destinationAccount($journal); $entry->setToAccountId($destination->id); $entry->setToAccountName($destination->name); $entry->setToAccountIban($destination->iban); diff --git a/app/Handlers/Events/ConnectJournalToPiggyBank.php b/app/Handlers/Events/ConnectJournalToPiggyBank.php index 5d13b25735..287ae8de3e 100644 --- a/app/Handlers/Events/ConnectJournalToPiggyBank.php +++ b/app/Handlers/Events/ConnectJournalToPiggyBank.php @@ -44,9 +44,9 @@ class ConnectJournalToPiggyBank } bcscale(2); - $amount = $journal->amount_positive; // TODO TransactionJournal cannot deliver "amount_positive". + $amount = TransactionJournal::amountPositive($journal); // if piggy account matches source account, the amount is positive - if ($piggyBank->account_id == $journal->source_account->id) {// TODO TransactionJournal cannot deliver "source_account" + if ($piggyBank->account_id == TransactionJournal::sourceAccount($journal)->id) { $amount = bcmul($amount, '-1'); } diff --git a/app/Handlers/Events/UpdateJournalConnection.php b/app/Handlers/Events/UpdateJournalConnection.php index 7f8487a092..fe1a961fb4 100644 --- a/app/Handlers/Events/UpdateJournalConnection.php +++ b/app/Handlers/Events/UpdateJournalConnection.php @@ -5,6 +5,7 @@ namespace FireflyIII\Handlers\Events; use FireflyIII\Events\TransactionJournalUpdated; use FireflyIII\Models\PiggyBankEvent; use FireflyIII\Models\PiggyBankRepetition; +use FireflyIII\Models\TransactionJournal; /** * Class UpdateJournalConnection @@ -44,7 +45,7 @@ class UpdateJournalConnection } bcscale(2); - $amount = $journal->amount; // TODO TransactionJournal cannot deliver "amount". + $amount = TransactionJournal::amount($journal); $diff = bcsub($amount, $event->amount); // update current repetition $repetition->currentamount = bcadd($repetition->currentamount, $diff); diff --git a/app/Http/Controllers/TransactionController.php b/app/Http/Controllers/TransactionController.php index 31f9d2639d..7d448d2fe0 100644 --- a/app/Http/Controllers/TransactionController.php +++ b/app/Http/Controllers/TransactionController.php @@ -19,7 +19,6 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use Illuminate\Support\Collection; use Input; -use Log; use Preferences; use Response; use Session; @@ -141,10 +140,6 @@ class TransactionController extends Controller */ public function edit(ARI $repository, TransactionJournal $journal) { - // get journal again: - /** @var TransactionJournal $journal */ - $journal = TransactionJournal::expanded()->where('transaction_journals.id', $journal->id)->first(TransactionJournal::QUERYFIELDS); - // TODO REMOVE this in favour of something static in TransactionJournal. // cannot edit opening balance if ($journal->isOpeningBalance()) { throw new FireflyException('Cannot edit this transaction (#' . $journal->id . '). Edit the account instead!'); @@ -154,11 +149,11 @@ class TransactionController extends Controller $maxFileSize = Steam::phpBytes(ini_get('upload_max_filesize')); $maxPostSize = Steam::phpBytes(ini_get('post_max_size')); $uploadSize = min($maxFileSize, $maxPostSize); - $what = strtolower($journal->transaction_type_type ?? $journal->transactionType->type); + $what = strtolower(TransactionJournal::transactionTypeStr($journal)); $accounts = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account'])); - $budgets = ExpandedForm::makeSelectList(Auth::user()->budgets()->get()); + $budgets = ExpandedForm::makeSelectList(Auth::user()->budgets()->get()); // TODO this must be a repository call $budgets[0] = trans('form.noBudget'); - $piggies = ExpandedForm::makeSelectList(Auth::user()->piggyBanks()->get()); + $piggies = ExpandedForm::makeSelectList(Auth::user()->piggyBanks()->get()); // TODO this must be a repository call $piggies[0] = trans('form.noPiggybank'); $subTitle = trans('breadcrumbs.edit_journal', ['description' => $journal->description]); $preFilled = [ @@ -184,22 +179,22 @@ class TransactionController extends Controller $preFilled['piggy_bank_id'] = $journal->piggyBankEvents()->orderBy('date', 'DESC')->first()->piggy_bank_id; } - $preFilled['amount'] = $journal->amount_positive; // TODO TransactionJournal cannot deliver "amount_positive". + $preFilled['amount'] = TransactionJournal::amountPositive($journal); if ($journal->isWithdrawal()) { - $preFilled['account_id'] = $journal->source_account_id; - if ($journal->destination_account_type != 'Cash account') { - $preFilled['expense_account'] = $journal->destination_account_name; + $preFilled['account_id'] = TransactionJournal::sourceAccount($journal)->id; + if (TransactionJournal::destinationAccountTypeStr($journal) != 'Cash account') { + $preFilled['expense_account'] = TransactionJournal::destinationAccount($journal)->name; } } else { - $preFilled['account_id'] = $journal->destination_account_id; - if ($journal->source_account_type != 'Cash account') { - $preFilled['revenue_account'] = $journal->source_account_name; + $preFilled['account_id'] = TransactionJournal::destinationAccount($journal)->id; + if (TransactionJournal::sourceAccountTypeStr($journal) != 'Cash account') { + $preFilled['revenue_account'] = TransactionJournal::sourceAccount($journal)->name; } } - $preFilled['account_from_id'] = $journal->source_account_id; - $preFilled['account_to_id'] = $journal->destination_account_id; + $preFilled['account_from_id'] = TransactionJournal::sourceAccount($journal)->id; + $preFilled['account_to_id'] = TransactionJournal::destinationAccount($journal)->id; Session::flash('preFilled', $preFilled); Session::flash('gaEventCategory', 'transactions'); diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index c263e29c51..9267844b54 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -212,7 +212,7 @@ class AccountRepository implements AccountRepositoryInterface $offset = ($page - 1) * 50; $query = Auth::user() ->transactionJournals() - ->expanded()// TODO firefly will crash here. + ->expanded() ->where( function (Builder $q) use ($account) { $q->where('destination.account_id', $account->id); diff --git a/app/Repositories/Bill/BillRepository.php b/app/Repositories/Bill/BillRepository.php index 1aa35b62d9..e78e59dc62 100644 --- a/app/Repositories/Bill/BillRepository.php +++ b/app/Repositories/Bill/BillRepository.php @@ -443,13 +443,6 @@ class BillRepository implements BillRepositoryInterface */ public function scan(Bill $bill, TransactionJournal $journal): bool { - // grab the expanded info for this journal. - // looks weird, but is useful: - /** @var TransactionJournal $journal */ - $journal = TransactionJournal::expanded()->where('transaction_journals.id', $journal->id)->get(TransactionJournal::QUERYFIELDS)->first(); - // TODO REMOVE this in favour of something static in TransactionJournal. - - /* * Can only support withdrawals. */ @@ -458,9 +451,9 @@ class BillRepository implements BillRepositoryInterface } $matches = explode(',', $bill->match); - $description = strtolower($journal->description) . ' ' . strtolower($journal->destination_account_name); + $description = strtolower($journal->description) . ' ' . strtolower(TransactionJournal::destinationAccount($journal)->name); $wordMatch = $this->doWordMatch($matches, $description); - $amountMatch = $this->doAmountMatch($journal->destination_amount, $bill->amount_min, $bill->amount_max); + $amountMatch = $this->doAmountMatch(TransactionJournal::amountPositive($journal), $bill->amount_min, $bill->amount_max); Log::debug('Journal #' . $journal->id . ' has description "' . $description . '"'); diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index 292bbf7997..a587374f1a 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -416,7 +416,7 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn { $offset = intval(Input::get('page')) > 0 ? intval(Input::get('page')) * $take : 0; $setQuery = $budget->transactionjournals()->expanded() - ->take($take)->offset($offset)// TODO firefly will crash here. + ->take($take)->offset($offset) ->orderBy('transaction_journals.date', 'DESC') ->orderBy('transaction_journals.order', 'ASC') ->orderBy('transaction_journals.id', 'DESC'); diff --git a/app/Repositories/Tag/TagRepository.php b/app/Repositories/Tag/TagRepository.php index 6c8812770e..7f0bdd30b3 100644 --- a/app/Repositories/Tag/TagRepository.php +++ b/app/Repositories/Tag/TagRepository.php @@ -129,8 +129,8 @@ class TagRepository implements TagRepositoryInterface /** @var TransactionJournal $journal */ foreach ($journals as $journal) { - if ($journal->destination_account->id == $account->id) { // TODO TransactionJournal cannot deliver "destination_account" - $amount = bcadd($amount, $journal->amount); // TODO TransactionJournal cannot deliver "amount". + if (TransactionJournal::destinationAccount($journal)->id == $account->id) { + $amount = bcadd($amount, TransactionJournal::amount($journal)); } } } @@ -376,10 +376,11 @@ class TagRepository implements TagRepositoryInterface foreach ($tag->transactionjournals as $check) { // $checkAccount is the source_account for a withdrawal // $checkAccount is the destination_account for a deposit - if ($check->isWithdrawal() && $check->source_account->id != $journal->destination_account->id) { // TODO TransactionJournal cannot deliver "source_account" + + if ($check->isWithdrawal() && TransactionJournal::sourceAccount($check)->id != TransactionJournal::destinationAccount($journal)->id) { $match = false; } - if ($check->isDeposit() && $check->destination_account->id != $journal->destination_account->id) { // TODO TransactionJournal cannot deliver "destination_account" + if ($check->isDeposit() && TransactionJournal::destinationAccount($check)->id != TransactionJournal::destinationAccount($journal)->id) { $match = false; } diff --git a/app/Rules/Triggers/AmountExactly.php b/app/Rules/Triggers/AmountExactly.php index b52c54b413..de16741252 100644 --- a/app/Rules/Triggers/AmountExactly.php +++ b/app/Rules/Triggers/AmountExactly.php @@ -54,7 +54,7 @@ final class AmountExactly extends AbstractTrigger implements TriggerInterface */ public function triggered(TransactionJournal $journal) { - $amount = $journal->amount_positive; // TODO TransactionJournal cannot deliver "amount_positive". + $amount = TransactionJournal::amountPositive($journal); $compare = $this->triggerValue; $result = bccomp($amount, $compare, 4); if ($result === 0) { diff --git a/app/Rules/Triggers/AmountLess.php b/app/Rules/Triggers/AmountLess.php index 1366b4c8af..aae6245491 100644 --- a/app/Rules/Triggers/AmountLess.php +++ b/app/Rules/Triggers/AmountLess.php @@ -54,7 +54,7 @@ final class AmountLess extends AbstractTrigger implements TriggerInterface */ public function triggered(TransactionJournal $journal) { - $amount = $journal->amount_positive; // TODO TransactionJournal cannot deliver "amount_positive". + $amount = TransactionJournal::amountPositive($journal); $compare = $this->triggerValue; $result = bccomp($amount, $compare, 4); if ($result === -1) { diff --git a/app/Rules/Triggers/AmountMore.php b/app/Rules/Triggers/AmountMore.php index 8bda7fefa1..697526194c 100644 --- a/app/Rules/Triggers/AmountMore.php +++ b/app/Rules/Triggers/AmountMore.php @@ -54,7 +54,7 @@ final class AmountMore extends AbstractTrigger implements TriggerInterface */ public function triggered(TransactionJournal $journal) { - $amount = $journal->amount_positive; // TODO TransactionJournal cannot deliver "amount_positive". + $amount = TransactionJournal::amountPositive($journal); $compare = $this->triggerValue; $result = bccomp($amount, $compare, 4); if ($result === 1) { diff --git a/app/Rules/Triggers/FromAccountContains.php b/app/Rules/Triggers/FromAccountContains.php index cd368bc6b7..a204357270 100644 --- a/app/Rules/Triggers/FromAccountContains.php +++ b/app/Rules/Triggers/FromAccountContains.php @@ -53,7 +53,7 @@ final class FromAccountContains extends AbstractTrigger implements TriggerInterf */ public function triggered(TransactionJournal $journal) { - $fromAccountName = strtolower($journal->source_account->name);// TODO TransactionJournal cannot deliver "source_account" + $fromAccountName = strtolower(TransactionJournal::sourceAccount($journal)->name); $search = strtolower($this->triggerValue); $strpos = strpos($fromAccountName, $search); diff --git a/app/Rules/Triggers/FromAccountEnds.php b/app/Rules/Triggers/FromAccountEnds.php index 47682a120a..f35faa27c9 100644 --- a/app/Rules/Triggers/FromAccountEnds.php +++ b/app/Rules/Triggers/FromAccountEnds.php @@ -53,7 +53,7 @@ final class FromAccountEnds extends AbstractTrigger implements TriggerInterface */ public function triggered(TransactionJournal $journal) { - $name = strtolower($journal->source_account->name);// TODO TransactionJournal cannot deliver "source_account" + $name = strtolower(TransactionJournal::sourceAccount($journal)->name); $nameLength = strlen($name); $search = strtolower($this->triggerValue); $searchLength = strlen($search); diff --git a/app/Rules/Triggers/FromAccountStarts.php b/app/Rules/Triggers/FromAccountStarts.php index 4238215995..a020b415e7 100644 --- a/app/Rules/Triggers/FromAccountStarts.php +++ b/app/Rules/Triggers/FromAccountStarts.php @@ -53,7 +53,7 @@ final class FromAccountStarts extends AbstractTrigger implements TriggerInterfac */ public function triggered(TransactionJournal $journal) { - $fromAccountName = strtolower($journal->source_account->name);// TODO TransactionJournal cannot deliver "source_account" + $fromAccountName = strtolower(TransactionJournal::sourceAccount($journal)->name); $search = strtolower($this->triggerValue); $part = substr($fromAccountName, 0, strlen($search)); diff --git a/app/Rules/Triggers/ToAccountContains.php b/app/Rules/Triggers/ToAccountContains.php index 50f38a1ec6..dcaa85676f 100644 --- a/app/Rules/Triggers/ToAccountContains.php +++ b/app/Rules/Triggers/ToAccountContains.php @@ -53,7 +53,7 @@ final class ToAccountContains extends AbstractTrigger implements TriggerInterfac */ public function triggered(TransactionJournal $journal) { - $toAccountName = strtolower($journal->destination_account->name); // TODO TransactionJournal cannot deliver "destination_account" + $toAccountName = strtolower(TransactionJournal::destinationAccount($journal)->name); $search = strtolower($this->triggerValue); $strpos = strpos($toAccountName, $search); diff --git a/app/Rules/Triggers/ToAccountEnds.php b/app/Rules/Triggers/ToAccountEnds.php index 17dbb05233..bba6cc7915 100644 --- a/app/Rules/Triggers/ToAccountEnds.php +++ b/app/Rules/Triggers/ToAccountEnds.php @@ -53,7 +53,7 @@ final class ToAccountEnds extends AbstractTrigger implements TriggerInterface */ public function triggered(TransactionJournal $journal) { - $toAccountName = strtolower($journal->destination_account->name); // TODO TransactionJournal cannot deliver "destination_account" + $toAccountName = strtolower(TransactionJournal::destinationAccount($journal)->name); $toAccountNameLength = strlen($toAccountName); $search = strtolower($this->triggerValue); $searchLength = strlen($search); diff --git a/app/Rules/Triggers/ToAccountIs.php b/app/Rules/Triggers/ToAccountIs.php index 206ed27515..93fcd718ae 100644 --- a/app/Rules/Triggers/ToAccountIs.php +++ b/app/Rules/Triggers/ToAccountIs.php @@ -53,7 +53,7 @@ final class ToAccountIs extends AbstractTrigger implements TriggerInterface */ public function triggered(TransactionJournal $journal) { - $toAccountName = strtolower($journal->destination_account->name); // TODO TransactionJournal cannot deliver "destination_account" + $toAccountName = strtolower(TransactionJournal::destinationAccount($journal)->name); $search = strtolower($this->triggerValue); if ($toAccountName == $search) { diff --git a/app/Rules/Triggers/ToAccountStarts.php b/app/Rules/Triggers/ToAccountStarts.php index 21f4133354..ccc53f12fa 100644 --- a/app/Rules/Triggers/ToAccountStarts.php +++ b/app/Rules/Triggers/ToAccountStarts.php @@ -53,7 +53,7 @@ final class ToAccountStarts extends AbstractTrigger implements TriggerInterface */ public function triggered(TransactionJournal $journal) { - $toAccountName = strtolower($journal->destination_account->name); // TODO TransactionJournal cannot deliver "destination_account" + $toAccountName = strtolower(TransactionJournal::destinationAccount($journal)->name); $search = strtolower($this->triggerValue); $part = substr($toAccountName, 0, strlen($search)); diff --git a/app/Support/Models/TransactionJournalSupport.php b/app/Support/Models/TransactionJournalSupport.php index 178d7a192c..d3329614e1 100644 --- a/app/Support/Models/TransactionJournalSupport.php +++ b/app/Support/Models/TransactionJournalSupport.php @@ -10,6 +10,10 @@ namespace FireflyIII\Support\Models; +use FireflyIII\Models\Account; +use FireflyIII\Models\Transaction; +use FireflyIII\Models\TransactionJournal; +use FireflyIII\Support\CacheProperties; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; @@ -20,6 +24,84 @@ use Illuminate\Database\Eloquent\Model; */ class TransactionJournalSupport extends Model { + /** + * @param TransactionJournal $journal + * + * @return string + */ + public static function amount(TransactionJournal $journal): string + { + $cache = new CacheProperties; + $cache->addProperty($journal->id); + $cache->addProperty('amount'); + if ($cache->has()) { + return $cache->get(); // @codeCoverageIgnore + } + + bcscale(2); + $transaction = $journal->transactions->sortByDesc('amount')->first(); + $amount = $transaction->amount; + if ($journal->isWithdrawal()) { + $amount = bcmul($amount, '-1'); + } + $cache->store($amount); + + return $amount; + + + } + + /** + * @param TransactionJournal $journal + * + * @return string + */ + public static function amountPositive(TransactionJournal $journal): string + { + $cache = new CacheProperties; + $cache->addProperty($journal->id); + $cache->addProperty('amount-positive'); + if ($cache->has()) { + return $cache->get(); // @codeCoverageIgnore + } + + $amount = '0'; + /** @var Transaction $t */ + foreach ($journal->transactions as $t) { + if ($t->amount > 0) { + $amount = $t->amount; + } + } + $cache->store($amount); + + return $amount; + } + + /** + * @param TransactionJournal $journal + * + * @return Account + */ + public static function destinationAccount(TransactionJournal $journal): Account + { + $account = $journal->transactions()->where('amount', '>', 0)->first()->account; + + return $account ?? new Account; + } + + /** + * @param TransactionJournal $journal + * + * @return string + */ + public static function destinationAccountTypeStr(TransactionJournal $journal): string + { + $account = self::destinationAccount($journal); + $type = $account->accountType ? $account->accountType->type : '(unknown)'; + + return $type; + } + /** * @param Builder $query * @param string $table @@ -41,4 +123,40 @@ class TransactionJournalSupport extends Model return false; } + /** + * @param TransactionJournal $journal + * + * @return Account + */ + public static function sourceAccount(TransactionJournal $journal): Account + { + $account = $journal->transactions()->where('amount', '<', 0)->first()->account; + + return $account ?? new Account; + } + + /** + * @param TransactionJournal $journal + * + * @return string + */ + public static function sourceAccountTypeStr(TransactionJournal $journal): string + { + $account = self::sourceAccount($journal); + $type = $account->accountType ? $account->accountType->type : '(unknown)'; + + return $type; + } + + /** + * @param TransactionJournal $journal + * + * @return string + */ + public static function transactionTypeStr(TransactionJournal $journal): string + { + return $journal->transaction_type_type ?? $journal->transactionType->type; + } + + } \ No newline at end of file