From 46b780758ee87f76846547a3f2d976d6c54b9465 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 15 Jun 2024 09:38:19 +0200 Subject: [PATCH] Fix https://github.com/firefly-iii/firefly-iii/issues/8927 --- .../Transaction/ConvertController.php | 96 +++++++++++-------- 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/app/Http/Controllers/Transaction/ConvertController.php b/app/Http/Controllers/Transaction/ConvertController.php index 7d4ceadecea..3391e9d48ab 100644 --- a/app/Http/Controllers/Transaction/ConvertController.php +++ b/app/Http/Controllers/Transaction/ConvertController.php @@ -23,7 +23,6 @@ namespace FireflyIII\Http\Controllers\Transaction; -use Exception; use FireflyIII\Events\UpdatedTransactionGroup; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Http\Controllers\Controller; @@ -65,7 +64,7 @@ public function __construct() $this->middleware( function ($request, $next) { $this->accountRepository = app(AccountRepositoryInterface::class); - app('view')->share('title', (string)trans('firefly.transactions')); + app('view')->share('title', (string) trans('firefly.transactions')); app('view')->share('mainTitleIcon', 'fa-exchange'); return $next($request); @@ -87,16 +86,16 @@ public function index(TransactionType $destinationType, TransactionGroup $group) } /** @var TransactionGroupTransformer $transformer */ - $transformer = app(TransactionGroupTransformer::class); + $transformer = app(TransactionGroupTransformer::class); /** @var TransactionJournal $first */ - $first = $group->transactionJournals()->first(); - $sourceType = $first->transactionType; + $first = $group->transactionJournals()->first(); + $sourceType = $first->transactionType; - $groupTitle = $group->title ?? $first->description; - $groupArray = $transformer->transformObject($group); - $subTitle = (string)trans('firefly.convert_to_'.$destinationType->type, ['description' => $groupTitle]); - $subTitleIcon = 'fa-exchange'; + $groupTitle = $group->title ?? $first->description; + $groupArray = $transformer->transformObject($group); + $subTitle = (string) trans('firefly.convert_to_' . $destinationType->type, ['description' => $groupTitle]); + $subTitleIcon = 'fa-exchange'; // get a list of asset accounts and liabilities and stuff, in various combinations: $validDepositSources = $this->getValidDepositSources(); @@ -105,13 +104,13 @@ public function index(TransactionType $destinationType, TransactionGroup $group) $assets = $this->getAssetAccounts(); // old input variables: - $preFilled = [ + $preFilled = [ 'source_name' => old('source_name'), ]; if ($sourceType->type === $destinationType->type) { // cannot convert to its own type. app('log')->debug('This is already a transaction of the expected type..'); - session()->flash('info', (string)trans('firefly.convert_is_already_type_'.$destinationType->type)); + session()->flash('info', (string) trans('firefly.convert_is_already_type_' . $destinationType->type)); return redirect(route('transactions.show', [$group->id])); } @@ -140,22 +139,21 @@ private function getValidDepositSources(): array // make repositories $liabilityTypes = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN]; $accountList = $this->accountRepository - ->getActiveAccountsByType([AccountType::REVENUE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]) - ; + ->getActiveAccountsByType([AccountType::REVENUE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]); $grouped = []; // group accounts: /** @var Account $account */ foreach ($accountList as $account) { - $role = (string)$this->accountRepository->getMetaValue($account, 'account_role'); - $name = $account->name; + $role = (string) $this->accountRepository->getMetaValue($account, 'account_role'); + $name = $account->name; if ('' === $role) { $role = 'no_account_type'; } // maybe it's a liability thing: if (in_array($account->accountType->type, $liabilityTypes, true)) { - $role = 'l_'.$account->accountType->type; + $role = 'l_' . $account->accountType->type; } if (AccountType::CASH === $account->accountType->type) { $role = 'cash_account'; @@ -165,7 +163,7 @@ private function getValidDepositSources(): array $role = 'revenue_account'; } - $key = (string)trans('firefly.opt_group_'.$role); + $key = (string) trans('firefly.opt_group_' . $role); $grouped[$key][$account->id] = $name; } @@ -184,15 +182,15 @@ private function getValidWithdrawalDests(): array // group accounts: /** @var Account $account */ foreach ($accountList as $account) { - $role = (string)$this->accountRepository->getMetaValue($account, 'account_role'); - $name = $account->name; + $role = (string) $this->accountRepository->getMetaValue($account, 'account_role'); + $name = $account->name; if ('' === $role) { $role = 'no_account_type'; } // maybe it's a liability thing: if (in_array($account->accountType->type, $liabilityTypes, true)) { - $role = 'l_'.$account->accountType->type; + $role = 'l_' . $account->accountType->type; } if (AccountType::CASH === $account->accountType->type) { $role = 'cash_account'; @@ -202,7 +200,7 @@ private function getValidWithdrawalDests(): array $role = 'expense_account'; } - $key = (string)trans('firefly.opt_group_'.$role); + $key = (string) trans('firefly.opt_group_' . $role); $grouped[$key][$account->id] = $name; } @@ -224,9 +222,9 @@ private function getLiabilities(): array foreach ($accountList as $account) { $balance = app('steam')->balance($account, today()); $currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency; - $role = 'l_'.$account->accountType->type; - $key = (string)trans('firefly.opt_group_'.$role); - $grouped[$key][$account->id] = $account->name.' ('.app('amount')->formatAnything($currency, $balance, false).')'; + $role = 'l_' . $account->accountType->type; + $key = (string) trans('firefly.opt_group_' . $role); + $grouped[$key][$account->id] = $account->name . ' (' . app('amount')->formatAnything($currency, $balance, false) . ')'; } return $grouped; @@ -245,15 +243,15 @@ private function getAssetAccounts(): array // group accounts: /** @var Account $account */ foreach ($accountList as $account) { - $balance = app('steam')->balance($account, today()); - $currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency; - $role = (string)$this->accountRepository->getMetaValue($account, 'account_role'); + $balance = app('steam')->balance($account, today()); + $currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency; + $role = (string) $this->accountRepository->getMetaValue($account, 'account_role'); if ('' === $role) { $role = 'no_account_type'; } - $key = (string)trans('firefly.opt_group_'.$role); - $grouped[$key][$account->id] = $account->name.' ('.app('amount')->formatAnything($currency, $balance, false).')'; + $key = (string) trans('firefly.opt_group_' . $role); + $grouped[$key][$account->id] = $account->name . ' (' . app('amount')->formatAnything($currency, $balance, false) . ')'; } return $grouped; @@ -285,7 +283,7 @@ public function postIndex(Request $request, TransactionType $destinationType, Tr // correct transfers: $group->refresh(); - session()->flash('success', (string)trans('firefly.converted_to_'.$destinationType->type)); + session()->flash('success', (string) trans('firefly.converted_to_' . $destinationType->type)); event(new UpdatedTransactionGroup($group, true, true)); return redirect(route('transactions.show', [$group->id])); @@ -297,20 +295,20 @@ public function postIndex(Request $request, TransactionType $destinationType, Tr private function convertJournal(TransactionJournal $journal, TransactionType $transactionType, array $data): TransactionJournal { /** @var AccountValidator $validator */ - $validator = app(AccountValidator::class); + $validator = app(AccountValidator::class); $validator->setUser(auth()->user()); $validator->setTransactionType($transactionType->type); - $sourceId = $data['source_id'][$journal->id] ?? null; - $sourceName = $data['source_name'][$journal->id] ?? null; - $destinationId = $data['destination_id'][$journal->id] ?? null; - $destinationName = $data['destination_name'][$journal->id] ?? null; + $sourceId = $data['source_id'][$journal->id] ?? null; + $sourceName = $data['source_name'][$journal->id] ?? null; + $destinationId = $data['destination_id'][$journal->id] ?? null; + $destinationName = $data['destination_name'][$journal->id] ?? null; - // double check its not an empty string. - $sourceId = '' === $sourceId || null === $sourceId ? null : (int)$sourceId; - $sourceName = '' === $sourceName ? null : (string)$sourceName; - $destinationId = '' === $destinationId || null === $destinationId ? null : (int)$destinationId; - $destinationName = '' === $destinationName ? null : (string)$destinationName; + // double check it's not an empty string. + $sourceId = '' === $sourceId || null === $sourceId ? null : (int) $sourceId; + $sourceName = '' === $sourceName ? null : (string) $sourceName; + $destinationId = '' === $destinationId || null === $destinationId ? null : (int) $destinationId; + $destinationName = '' === $destinationName ? null : (string) $destinationName; $validSource = $validator->validateSource(['id' => $sourceId, 'name' => $sourceName]); $validDestination = $validator->validateDestination(['id' => $destinationId, 'name' => $destinationName]); @@ -323,7 +321,7 @@ private function convertJournal(TransactionJournal $journal, TransactionType $tr // TODO typeOverrule: the account validator may have another opinion on the transaction type. - $update = [ + $update = [ 'source_id' => $sourceId, 'source_name' => $sourceName, 'destination_id' => $destinationId, @@ -331,8 +329,22 @@ private function convertJournal(TransactionJournal $journal, TransactionType $tr 'type' => $transactionType->type, ]; + // also set the currency to the currency of the source account, in case you're converting a deposit into a transfer. + if (TransactionType::TRANSFER === $transactionType->type && TransactionType::DEPOSIT === $journal->transactionType->type) { + $source = $this->accountRepository->find((int) $sourceId); + $sourceCurrency = $this->accountRepository->getAccountCurrency($source); + $dest = $this->accountRepository->find((int) $destinationId); + $destCurrency = $this->accountRepository->getAccountCurrency($dest); + if (null !== $sourceCurrency && null !== $destCurrency && $sourceCurrency->code !== $destCurrency->code) { + $update['currency_id'] = $sourceCurrency->id; + $update['foreign_currency_id'] = $destCurrency->id; + $update['foreign_amount'] = '1'; // not the best solution but at this point the amount is hard to get. + } + } + + /** @var JournalUpdateService $service */ - $service = app(JournalUpdateService::class); + $service = app(JournalUpdateService::class); $service->setTransactionJournal($journal); $service->setData($update); $service->update();