middleware( function ($request, $next) { $this->accounts = app(AccountRepositoryInterface::class); View::share('title', trans('firefly.transactions')); View::share('mainTitleIcon', 'fa-exchange'); return $next($request); } ); } /** * @param TransactionType $destinationType * @param TransactionJournal $journal * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View */ public function index(TransactionType $destinationType, TransactionJournal $journal) { // @codeCoverageIgnoreStart if ($this->isOpeningBalance($journal)) { return $this->redirectToAccount($journal); } // @codeCoverageIgnoreEnd $positiveAmount = $journal->amountPositive(); $assetAccounts = ExpandedForm::makeSelectList($this->accounts->getActiveAccountsByType([AccountType::DEFAULT, AccountType::ASSET])); $sourceType = $journal->transactionType; $subTitle = trans('firefly.convert_to_' . $destinationType->type, ['description' => $journal->description]); $subTitleIcon = 'fa-exchange'; // cannot convert to its own type. if ($sourceType->type === $destinationType->type) { Session::flash('info', trans('firefly.convert_is_already_type_' . $destinationType->type)); return redirect(route('transactions.show', [$journal->id])); } // cannot convert split. if ($journal->transactions()->count() > 2) { Session::flash('error', trans('firefly.cannot_convert_split_journl')); return redirect(route('transactions.show', [$journal->id])); } // get source and destination account: $sourceAccount = $journal->sourceAccountList()->first(); $destinationAccount = $journal->destinationAccountList()->first(); return view( 'transactions.convert', compact( 'sourceType', 'destinationType', 'journal', 'assetAccounts', 'positiveAmount', 'sourceAccount', 'destinationAccount', 'sourceType', 'subTitle', 'subTitleIcon' ) ); // convert withdrawal to deposit requires a new source account () // or to transfer requires } /** * @param Request $request * @param JournalRepositoryInterface $repository * @param TransactionType $destinationType * @param TransactionJournal $journal * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ public function postIndex(Request $request, JournalRepositoryInterface $repository, TransactionType $destinationType, TransactionJournal $journal) { if ($this->isOpeningBalance($journal)) { return $this->redirectToAccount($journal); } $data = $request->all(); // cannot convert to its own type. if ($journal->transactionType->type === $destinationType->type) { Session::flash('error', trans('firefly.convert_is_already_type_' . $destinationType->type)); return redirect(route('transactions.show', [$journal->id])); } // cannot convert split. if ($journal->transactions()->count() > 2) { Session::flash('error', trans('firefly.cannot_convert_split_journl')); return redirect(route('transactions.show', [$journal->id])); } // get the new source and destination account: $source = $this->getSourceAccount($journal, $destinationType, $data); $destination = $this->getDestinationAccount($journal, $destinationType, $data); // update the journal: $errors = $repository->convert($journal, $destinationType, $source, $destination); if ($errors->count() > 0) { return redirect(route('transactions.convert.index', [strtolower($destinationType->type), $journal->id]))->withErrors($errors)->withInput(); } Session::flash('success', trans('firefly.converted_to_' . $destinationType->type)); return redirect(route('transactions.show', [$journal->id])); } /** * @param TransactionJournal $journal * @param TransactionType $destinationType * @param array $data * * @return Account * @throws FireflyException */ private function getDestinationAccount(TransactionJournal $journal, TransactionType $destinationType, array $data): Account { /** @var AccountRepositoryInterface $accountRepository */ $accountRepository = app(AccountRepositoryInterface::class); $sourceAccount = $journal->sourceAccountList()->first(); $destinationAccount = $journal->destinationAccountList()->first(); $sourceType = $journal->transactionType; $joined = $sourceType->type . '-' . $destinationType->type; switch ($joined) { default: throw new FireflyException('Cannot handle ' . $joined); case TransactionType::WITHDRAWAL . '-' . TransactionType::DEPOSIT: // one $destination = $sourceAccount; break; case TransactionType::WITHDRAWAL . '-' . TransactionType::TRANSFER: // two $destination = $accountRepository->find(intval($data['destination_account_asset'])); break; case TransactionType::DEPOSIT . '-' . TransactionType::WITHDRAWAL: // three case TransactionType::TRANSFER . '-' . TransactionType::WITHDRAWAL: // five $data = [ 'name' => $data['destination_account_expense'], 'accountType' => 'expense', 'virtualBalance' => 0, 'active' => true, 'iban' => null, ]; $destination = $accountRepository->store($data); break; case TransactionType::DEPOSIT . '-' . TransactionType::TRANSFER: // four case TransactionType::TRANSFER . '-' . TransactionType::DEPOSIT: // six $destination = $destinationAccount; break; } return $destination; } /** * @param TransactionJournal $journal * @param TransactionType $destinationType * @param array $data * * @return Account * @throws FireflyException */ private function getSourceAccount(TransactionJournal $journal, TransactionType $destinationType, array $data): Account { /** @var AccountRepositoryInterface $accountRepository */ $accountRepository = app(AccountRepositoryInterface::class); $sourceAccount = $journal->sourceAccountList()->first(); $destinationAccount = $journal->destinationAccountList()->first(); $sourceType = $journal->transactionType; $joined = $sourceType->type . '-' . $destinationType->type; switch ($joined) { default: throw new FireflyException('Cannot handle ' . $joined); case TransactionType::WITHDRAWAL . '-' . TransactionType::DEPOSIT: // one case TransactionType::TRANSFER . '-' . TransactionType::DEPOSIT: // six $data = [ 'name' => $data['source_account_revenue'], 'accountType' => 'revenue', 'virtualBalance' => 0, 'active' => true, 'iban' => null, ]; $source = $accountRepository->store($data); break; case TransactionType::WITHDRAWAL . '-' . TransactionType::TRANSFER: // two case TransactionType::TRANSFER . '-' . TransactionType::WITHDRAWAL: // five $source = $sourceAccount; break; case TransactionType::DEPOSIT . '-' . TransactionType::WITHDRAWAL: // three $source = $destinationAccount; break; case TransactionType::DEPOSIT . '-' . TransactionType::TRANSFER: // four $source = $accountRepository->find(intval($data['source_account_asset'])); break; } return $source; } }