mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-20 19:35:16 +00:00
Fix #9784
This commit is contained in:
@@ -25,6 +25,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Console\Commands\Correction;
|
namespace FireflyIII\Console\Commands\Correction;
|
||||||
|
|
||||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Models\AutoBudget;
|
use FireflyIII\Models\AutoBudget;
|
||||||
use FireflyIII\Models\AvailableBudget;
|
use FireflyIII\Models\AvailableBudget;
|
||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
@@ -33,8 +34,14 @@ use FireflyIII\Models\CurrencyExchangeRate;
|
|||||||
use FireflyIII\Models\PiggyBank;
|
use FireflyIII\Models\PiggyBank;
|
||||||
use FireflyIII\Models\RecurrenceTransaction;
|
use FireflyIII\Models\RecurrenceTransaction;
|
||||||
use FireflyIII\Models\RuleTrigger;
|
use FireflyIII\Models\RuleTrigger;
|
||||||
|
use FireflyIII\Models\Transaction;
|
||||||
|
use FireflyIII\Models\TransactionJournal;
|
||||||
|
use FireflyIII\Models\TransactionType;
|
||||||
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class CorrectsAmounts extends Command
|
class CorrectsAmounts extends Command
|
||||||
{
|
{
|
||||||
@@ -45,6 +52,8 @@ class CorrectsAmounts extends Command
|
|||||||
|
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
|
// transfers must not have foreign currency info if both accounts have the same currency.
|
||||||
|
$this->correctTransfers();
|
||||||
// auto budgets must be positive
|
// auto budgets must be positive
|
||||||
$this->fixAutoBudgets();
|
$this->fixAutoBudgets();
|
||||||
// available budgets must be positive
|
// available budgets must be positive
|
||||||
@@ -62,6 +71,7 @@ class CorrectsAmounts extends Command
|
|||||||
// rule_triggers must be positive or zero (amount_less, amount_more, amount_is)
|
// rule_triggers must be positive or zero (amount_less, amount_more, amount_is)
|
||||||
$this->fixRuleTriggers();
|
$this->fixRuleTriggers();
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,4 +192,60 @@ class CorrectsAmounts extends Command
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function correctTransfers(): void
|
||||||
|
{
|
||||||
|
/** @var AccountRepositoryInterface $repository */
|
||||||
|
$repository = app(AccountRepositoryInterface::class);
|
||||||
|
$type = TransactionType::where('type', TransactionTypeEnum::TRANSFER->value)->first();
|
||||||
|
$journals = TransactionJournal::where('transaction_type_id', $type->id)->get();
|
||||||
|
|
||||||
|
/** @var TransactionJournal $journal */
|
||||||
|
foreach ($journals as $journal) {
|
||||||
|
$repository->setUser($journal->user);
|
||||||
|
$native = Amount::getNativeCurrencyByUserGroup($journal->userGroup);
|
||||||
|
/** @var Transaction|null $source */
|
||||||
|
$source = $journal->transactions()->where('amount', '<', 0)->first();
|
||||||
|
/** @var Transaction|null $destination */
|
||||||
|
$destination = $journal->transactions()->where('amount', '>', 0)->first();
|
||||||
|
if (null === $source || null === $destination) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (null === $source->foreign_currency_id || null === $destination->foreign_currency_id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$sourceAccount = $source->account;
|
||||||
|
$destAccount = $destination->account;
|
||||||
|
if (null === $sourceAccount || null === $destAccount) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$sourceCurrency = $repository->getAccountCurrency($sourceAccount) ?? $native;
|
||||||
|
$destCurrency = $repository->getAccountCurrency($destAccount) ?? $native;
|
||||||
|
|
||||||
|
if($sourceCurrency->id === $destCurrency->id) {
|
||||||
|
Log::debug('Both accounts have the same currency. Removing foreign currency info.');
|
||||||
|
$source->foreign_currency_id = null;
|
||||||
|
$source->foreign_amount = null;
|
||||||
|
$source->save();
|
||||||
|
$destination->foreign_currency_id = null;
|
||||||
|
$destination->foreign_amount = null;
|
||||||
|
$destination->save();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate source
|
||||||
|
if ($destCurrency->id !== $source->foreign_currency_id) {
|
||||||
|
Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $source->id, $source->foreignCurrency->code, $destCurrency->code));
|
||||||
|
$source->foreign_currency_id = $destCurrency->id;
|
||||||
|
$source->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate destination:
|
||||||
|
if ($sourceCurrency->id !== $destination->foreign_currency_id) {
|
||||||
|
Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $destination->id, $destination->foreignCurrency->code, $sourceCurrency->code));
|
||||||
|
$destination->foreign_currency_id = $sourceCurrency->id;
|
||||||
|
$destination->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -111,6 +111,10 @@ class TransactionJournal extends Model
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(User::class);
|
return $this->belongsTo(User::class);
|
||||||
}
|
}
|
||||||
|
public function userGroup(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(UserGroup::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function attachments(): MorphMany
|
public function attachments(): MorphMany
|
||||||
{
|
{
|
||||||
|
@@ -137,7 +137,7 @@ class ExchangeRateConverter
|
|||||||
|
|
||||||
// combined (if present), they can be used to calculate the necessary conversion rate.
|
// combined (if present), they can be used to calculate the necessary conversion rate.
|
||||||
if (0 === bccomp('0', $first) || 0 === bccomp('0', $second)) {
|
if (0 === bccomp('0', $first) || 0 === bccomp('0', $second)) {
|
||||||
Log::warning(sprintf('There is not enough information to convert %s to %s on date %d', $from->code, $to->code, $date->format('Y-m-d')));
|
Log::warning(sprintf('There is not enough information to convert %s to %s on date %s', $from->code, $to->code, $date->format('Y-m-d')));
|
||||||
|
|
||||||
return '1';
|
return '1';
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user