diff --git a/app/Validation/Account/WithdrawalValidation.php b/app/Validation/Account/WithdrawalValidation.php index bb5d758f76..191f03087b 100644 --- a/app/Validation/Account/WithdrawalValidation.php +++ b/app/Validation/Account/WithdrawalValidation.php @@ -108,6 +108,7 @@ trait WithdrawalValidation if (null !== $found) { $type = $found->accountType->type; if (in_array($type, $validTypes, true)) { + $this->destination = $found; return true; } $this->destError = (string)trans('validation.withdrawal_dest_bad_data', ['id' => $accountId, 'name' => $accountName]); diff --git a/app/Validation/CurrencyValidation.php b/app/Validation/CurrencyValidation.php index 7af3da4668..a867a7946a 100644 --- a/app/Validation/CurrencyValidation.php +++ b/app/Validation/CurrencyValidation.php @@ -43,6 +43,9 @@ trait CurrencyValidation */ protected function validateForeignCurrencyInformation(Validator $validator): void { + if($validator->errors()->count() > 0) { + return; + } Log::debug('Now in validateForeignCurrencyInformation()'); $transactions = $this->getTransactionsArray($validator); diff --git a/app/Validation/GroupValidation.php b/app/Validation/GroupValidation.php index eede3b3b91..25ed4c50a1 100644 --- a/app/Validation/GroupValidation.php +++ b/app/Validation/GroupValidation.php @@ -90,6 +90,9 @@ trait GroupValidation */ protected function validateDescriptions(Validator $validator): void { + if($validator->errors()->count() > 0) { + return; + } Log::debug('Now in GroupValidation::validateDescriptions()'); $transactions = $this->getTransactionsArray($validator); $validDescriptions = 0; @@ -113,6 +116,9 @@ trait GroupValidation */ protected function validateGroupDescription(Validator $validator): void { + if($validator->errors()->count() > 0) { + return; + } Log::debug('Now in validateGroupDescription()'); $data = $validator->getData(); $transactions = $this->getTransactionsArray($validator); diff --git a/app/Validation/TransactionValidation.php b/app/Validation/TransactionValidation.php index 0c5dcfb61e..e89c0f0b41 100644 --- a/app/Validation/TransactionValidation.php +++ b/app/Validation/TransactionValidation.php @@ -43,6 +43,9 @@ trait TransactionValidation */ public function validateAccountInformation(Validator $validator): void { + if ($validator->errors()->count() > 0) { + return; + } Log::debug('Now in validateAccountInformation (TransactionValidation) ()'); $transactions = $this->getTransactionsArray($validator); $data = $validator->getData(); @@ -137,9 +140,49 @@ trait TransactionValidation $validator->errors()->add(sprintf('transactions.%d.destination_id', $index), $accountValidator->destError); $validator->errors()->add(sprintf('transactions.%d.destination_name', $index), $accountValidator->destError); } - // sanity check for reconciliation accounts. They can't both be null. $this->sanityCheckReconciliation($validator, $transactionType, $index, $source, $destination); + + // deposit and the source is a liability or an asset account with a different + // currency than submitted? then the foreign currency info must be present as well (and filled in). + if (0 === $validator->errors()->count() && null !== $accountValidator->source && TransactionType::DEPOSIT === ucfirst($transactionType)) { + $accountType = $accountValidator?->source?->accountType?->type; + if (in_array($accountType, config('firefly.valid_currency_account_types'), true) && !$this->hasForeignCurrencyInfo($transaction)) { + $validator->errors()->add(sprintf('transactions.%d.foreign_amount', $index), (string)trans('validation.require_foreign_currency')); + } + } + + // withdrawal or transfer and the destination is a liability or an asset account with a different + // currency than submitted? then the foreign currency info must be present as well (and filled in). + if (0 === $validator->errors()->count() && null !== $accountValidator->destination && + (TransactionType::WITHDRAWAL === ucfirst($transactionType) || (TransactionType::TRANSFER === ucfirst($transactionType)))) { + $accountType = $accountValidator?->destination?->accountType?->type; + if (in_array($accountType, config('firefly.valid_currency_account_types'), true) && !$this->hasForeignCurrencyInfo($transaction)) { + $validator->errors()->add(sprintf('transactions.%d.foreign_amount', $index), (string)trans('validation.require_foreign_currency')); + } + } + // account validator has a valid source and a valid destination + } + + /** + * @param array $transaction + * @return bool + */ + private function hasForeignCurrencyInfo(array $transaction): bool + { + if (!array_key_exists('foreign_currency_code', $transaction) && !array_key_exists('foreign_currency_id', $transaction)) { + return false; + } + if (!array_key_exists('foreign_amount', $transaction)) { + return false; + } + if ('' === $transaction['foreign_amount']) { + return false; + } + if (bccomp('0', $transaction['foreign_amount']) === 0) { + return false; + } + return true; } /** @@ -324,6 +367,9 @@ trait TransactionValidation */ public function validateOneTransaction(Validator $validator): void { + if ($validator->errors()->count() > 0) { + return; + } Log::debug('Now in validateOneTransaction()'); $transactions = $this->getTransactionsArray($validator); // need at least one transaction @@ -341,6 +387,9 @@ trait TransactionValidation */ public function validateTransactionArray(Validator $validator): void { + if ($validator->errors()->count() > 0) { + return; + } $transactions = $this->getTransactionsArray($validator); foreach ($transactions as $key => $value) { if (!is_int($key)) { @@ -359,6 +408,9 @@ trait TransactionValidation */ public function validateTransactionTypes(Validator $validator): void { + if ($validator->errors()->count() > 0) { + return; + } Log::debug('Now in validateTransactionTypes()'); $transactions = $this->getTransactionsArray($validator); @@ -427,6 +479,9 @@ trait TransactionValidation */ private function validateEqualAccounts(Validator $validator): void { + if ($validator->errors()->count() > 0) { + return; + } Log::debug('Now in validateEqualAccounts()'); $transactions = $this->getTransactionsArray($validator); diff --git a/resources/lang/en_US/validation.php b/resources/lang/en_US/validation.php index 53f28bda3d..924831adc8 100644 --- a/resources/lang/en_US/validation.php +++ b/resources/lang/en_US/validation.php @@ -56,6 +56,7 @@ return [ 'require_currency_info' => 'The content of this field is invalid without currency information.', 'not_transfer_account' => 'This account is not an account that can be used for transfers.', 'require_currency_amount' => 'The content of this field is invalid without foreign amount information.', + 'require_foreign_currency' => 'This field requires a number', 'equal_description' => 'Transaction description should not equal global description.', 'file_invalid_mime' => 'File ":name" is of type ":mime" which is not accepted as a new upload.', 'file_too_large' => 'File ":name" is too large.',