/** * @param Account $account * @param TransactionJournal $journal * @param array $data * * @return TransactionJournal */ protected function updateInitialBalance(Account $account, TransactionJournal $journal, array $data) { $journal->date = $data['openingBalanceDate']; /** @var Transaction $transaction */ foreach ($journal->transactions()->get() as $transaction) { if ($account->id == $transaction->account_id) { $transaction->amount = $data['openingBalance']; $transaction->save(); } if ($account->id != $transaction->account_id) { $transaction->amount = $data['openingBalance'] * -1; $transaction->save(); } } return $journal; }
/** * @param TransactionJournal $journal * @param Account $account * * @return Transaction */ public function getFirstTransaction(TransactionJournal $journal, Account $account) : Transaction { $transaction = $journal->transactions()->where('account_id', $account->id)->first(); if (is_null($transaction)) { $transaction = new Transaction(); } return $transaction; }
/** * @param TransactionJournal $journal * @param array $data * * @return TransactionJournal */ public function updateJournal(TransactionJournal $journal, array $data) : TransactionJournal { $journal->description = $data['journal_description']; $journal->transaction_currency_id = $data['journal_currency_id']; $journal->date = $data['date']; $journal->interest_date = $data['interest_date']; $journal->book_date = $data['book_date']; $journal->process_date = $data['process_date']; $journal->save(); // delete original transactions, and recreate them. $journal->transactions()->delete(); foreach ($data['transactions'] as $transaction) { $this->storeTransaction($journal, $transaction); } $journal->completed = true; $journal->save(); return $journal; }
/** * @param TransactionJournal $journal * @param array $data * * @return TransactionJournal */ public function update(TransactionJournal $journal, array $data) : TransactionJournal { // update actual journal. $journal->transaction_currency_id = $data['amount_currency_id_amount']; $journal->description = $data['description']; $journal->date = $data['date']; // unlink all categories, recreate them: $journal->categories()->detach(); if (strlen($data['category']) > 0) { $category = Category::firstOrCreateEncrypted(['name' => $data['category'], 'user_id' => $data['user']]); $journal->categories()->save($category); } // unlink all budgets and recreate them: $journal->budgets()->detach(); if (intval($data['budget_id']) > 0 && $journal->transactionType->type !== TransactionType::TRANSFER) { /** @var \FireflyIII\Models\Budget $budget */ $budget = Budget::where('user_id', $this->user->id)->where('id', $data['budget_id'])->first(); $journal->budgets()->save($budget); } // store accounts (depends on type) list($fromAccount, $toAccount) = $this->storeAccounts($journal->transactionType, $data); // update the from and to transaction. /** @var Transaction $transaction */ foreach ($journal->transactions()->get() as $transaction) { if ($transaction->amount < 0) { // this is the from transaction, negative amount: $transaction->amount = $data['amount'] * -1; $transaction->account_id = $fromAccount->id; $transaction->save(); } if ($transaction->amount > 0) { $transaction->amount = $data['amount']; $transaction->account_id = $toAccount->id; $transaction->save(); } } $journal->save(); // update tags: if (isset($data['tags']) && is_array($data['tags'])) { $this->updateTags($journal, $data['tags']); } // update meta fields: $result = $journal->save(); if ($result) { foreach ($data as $key => $value) { if (in_array($key, $this->validMetaFields)) { $journal->setMeta($key, $value); continue; } Log::debug(sprintf('Could not store meta field "%s" with value "%s" for journal #%d', json_encode($key), json_encode($value), $journal->id)); } return $journal; } return $journal; }
/** * @param TransactionJournal $journal * @param array $data * * @return TransactionJournal */ public function update(TransactionJournal $journal, array $data) { // update actual journal. $journal->transaction_currency_id = $data['amount_currency_id']; $journal->description = $data['description']; $journal->date = $data['date']; // unlink all categories, recreate them: $journal->categories()->detach(); if (strlen($data['category']) > 0) { $category = Category::firstOrCreateEncrypted(['name' => $data['category'], 'user_id' => $data['user']]); $journal->categories()->save($category); } // unlink all budgets and recreate them: $journal->budgets()->detach(); if (intval($data['budget_id']) > 0) { /** @var \FireflyIII\Models\Budget $budget */ $budget = Budget::find($data['budget_id']); $journal->budgets()->save($budget); } // store accounts (depends on type) list($from, $to) = $this->storeAccounts($journal->transactionType, $data); // update the from and to transaction. /** @var Transaction $transaction */ foreach ($journal->transactions()->get() as $transaction) { if (floatval($transaction->amount) < 0) { // this is the from transaction, negative amount: $transaction->amount = $data['amount'] * -1; $transaction->account_id = $from->id; $transaction->save(); } if (floatval($transaction->amount) > 0) { $transaction->amount = $data['amount']; $transaction->account_id = $to->id; $transaction->save(); } } $journal->save(); // update tags: if (isset($data['tags']) && is_array($data['tags'])) { $this->updateTags($journal, $data['tags']); } return $journal; }
/** * @param Request $request * @param TransactionJournal $journal * * @return array */ private function transactionsFromJournal(Request $request, TransactionJournal $journal) : array { /** @var Collection $transactions */ $transactions = $journal->transactions()->get(); /* * Splitted journals always have ONE source OR ONE destination. * Withdrawals have ONE source (asset account) * Deposits have ONE destination (asset account) * Transfers have ONE of both (asset account) */ /** @var Account $singular */ $singular = TransactionJournal::sourceAccountList($journal)->first(); if ($journal->transactionType->type == TransactionType::DEPOSIT) { /** @var Account $singular */ $singular = TransactionJournal::destinationAccountList($journal)->first(); } /* * Loop all transactions. Collect info ONLY from the transaction that is NOT related to * the singular account. */ $index = 0; $return = ['description' => [], 'source_account_id' => [], 'source_account_name' => [], 'destination_account_id' => [], 'destination_account_name' => [], 'amount' => [], 'budget_id' => [], 'category' => []]; Log::debug('now at transactionsFromJournal'); /** * @var int $current * @var Transaction $transaction */ foreach ($transactions as $current => $transaction) { $budget = $transaction->budgets()->first(); $category = $transaction->categories()->first(); $budgetId = 0; $categoryName = ''; if (!is_null($budget)) { $budgetId = $budget->id; } if (!is_null($category)) { $categoryName = $category->name; } $budgetId = $request->old('budget_id')[$index] ?? $budgetId; $categoryName = $request->old('category')[$index] ?? $categoryName; $amount = $request->old('amount')[$index] ?? $transaction->amount; $description = $request->old('description')[$index] ?? $transaction->description; $destinationName = $request->old('destination_account_name')[$index] ?? $transaction->account->name; $sourceName = $request->old('source_account_name')[$index] ?? $transaction->account->name; $amount = bccomp($amount, '0') === -1 ? bcmul($amount, '-1') : $amount; if ($transaction->account_id !== $singular->id) { $return['description'][] = $description; $return['destination_account_id'][] = $transaction->account_id; $return['destination_account_name'][] = $destinationName; $return['source_account_name'][] = $sourceName; $return['amount'][] = $amount; $return['budget_id'][] = intval($budgetId); $return['category'][] = $categoryName; // only add one when "valid" transaction $index++; } } return $return; }
/** * @param TransactionJournal $journal * * @return mixed */ public function edit(TransactionJournal $journal) { $count = $journal->transactions()->count(); if ($count > 2) { return redirect(route('split.journal.edit', [$journal->id])); } // code to get list data: $budgetRepository = app('FireflyIII\\Repositories\\Budget\\BudgetRepositoryInterface'); $piggyRepository = app('FireflyIII\\Repositories\\PiggyBank\\PiggyBankRepositoryInterface'); $crud = app('FireflyIII\\Crud\\Account\\AccountCrudInterface'); $assetAccounts = ExpandedForm::makeSelectList($crud->getAccountsByType(['Default account', 'Asset account'])); $budgetList = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets()); $piggyBankList = ExpandedForm::makeSelectListWithEmpty($piggyRepository->getPiggyBanks()); // view related code $subTitle = trans('breadcrumbs.edit_journal', ['description' => $journal->description]); $what = strtolower(TransactionJournal::transactionTypeStr($journal)); // journal related code $sourceAccounts = TransactionJournal::sourceAccountList($journal); $destinationAccounts = TransactionJournal::destinationAccountList($journal); $optionalFields = Preferences::get('transaction_journal_optional_fields', [])->data; $preFilled = ['date' => TransactionJournal::dateAsString($journal), 'interest_date' => TransactionJournal::dateAsString($journal, 'interest_date'), 'book_date' => TransactionJournal::dateAsString($journal, 'book_date'), 'process_date' => TransactionJournal::dateAsString($journal, 'process_date'), 'category' => TransactionJournal::categoryAsString($journal), 'budget_id' => TransactionJournal::budgetId($journal), 'piggy_bank_id' => TransactionJournal::piggyBankId($journal), 'tags' => join(',', $journal->tags->pluck('tag')->toArray()), 'source_account_id' => $sourceAccounts->first()->id, 'source_account_name' => $sourceAccounts->first()->name, 'destination_account_id' => $destinationAccounts->first()->id, 'destination_account_name' => $destinationAccounts->first()->name, 'amount' => TransactionJournal::amountPositive($journal), 'due_date' => TransactionJournal::dateAsString($journal, 'due_date'), 'payment_date' => TransactionJournal::dateAsString($journal, 'payment_date'), 'invoice_date' => TransactionJournal::dateAsString($journal, 'invoice_date'), 'interal_reference' => $journal->getMeta('internal_reference'), 'notes' => $journal->getMeta('notes')]; if ($journal->isWithdrawal() && $destinationAccounts->first()->accountType->type == AccountType::CASH) { $preFilled['destination_account_name'] = ''; } if ($journal->isDeposit() && $sourceAccounts->first()->accountType->type == AccountType::CASH) { $preFilled['source_account_name'] = ''; } Session::flash('preFilled', $preFilled); Session::flash('gaEventCategory', 'transactions'); Session::flash('gaEventAction', 'edit-' . $what); // put previous url in session if not redirect from store (not "return_to_edit"). if (session('transactions.edit.fromUpdate') !== true) { Session::put('transactions.edit.url', URL::previous()); } Session::forget('transactions.edit.fromUpdate'); return view('transactions.edit', compact('journal', 'optionalFields', 'assetAccounts', 'what', 'budgetList', 'piggyBankList', 'subTitle'))->with('data', $preFilled); }
/** * @param TransactionJournal $journal * * @return Collection */ public static function sourceTransactionList(TransactionJournal $journal) : Collection { $cache = new CacheProperties(); $cache->addProperty($journal->id); $cache->addProperty('transaction-journal'); $cache->addProperty('source-transaction-list'); if ($cache->has()) { return $cache->get(); } $list = $journal->transactions()->where('amount', '<', 0)->with('account')->get(); $cache->store($list); return $list; }
/** * @param Account $account * @param TransactionJournal $journal * @param Carbon $date * @param float $amount * * @return bool */ private function updateJournal(Account $account, TransactionJournal $journal, Carbon $date, float $amount) : bool { // update date: $journal->date = $date; $journal->save(); // update transactions: /** @var Transaction $transaction */ foreach ($journal->transactions()->get() as $transaction) { if ($account->id == $transaction->account_id) { $transaction->amount = $amount; $transaction->save(); } if ($account->id != $transaction->account_id) { $transaction->amount = $amount * -1; $transaction->save(); } } return true; }