Fix some edge cases in recurrences.

This commit is contained in:
James Cole
2021-03-15 19:51:55 +01:00
parent a0b46d9d8a
commit d5ee87ddee
8 changed files with 92 additions and 23 deletions

View File

@@ -111,7 +111,9 @@ trait RecurringTransactionTrait
*/
protected function createTransactions(Recurrence $recurrence, array $transactions): void
{
foreach ($transactions as $array) {
Log::debug('Now in createTransactions()');
foreach ($transactions as $index => $array) {
Log::debug(sprintf('Now at transaction #%d', $index));
$sourceTypes = config(sprintf('firefly.expected_source_types.source.%s', $recurrence->transactionType->type));
$destTypes = config(sprintf('firefly.expected_source_types.destination.%s', $recurrence->transactionType->type));
$source = $this->findAccount($sourceTypes, $array['source_id'], null);
@@ -125,11 +127,17 @@ trait RecurringTransactionTrait
$currency = app('amount')->getDefaultCurrencyByUser($recurrence->user);
}
Log::debug(
sprintf('Will set the validator type to %s based on the type of the recurrence (#%d).', $recurrence->transactionType->type, $recurrence->id)
);
// once the accounts have been determined, we still verify their validity:
/** @var AccountValidator $validator */
$validator = app(AccountValidator::class);
$validator->setUser($recurrence->user);
$validator->setTransactionType($recurrence->transactionType->type);
if (!$validator->validateSource($source->id, null, null)) {
throw new FireflyException(sprintf('Source invalid: %s', $validator->sourceError)); // @codeCoverageIgnore
}
@@ -335,6 +343,7 @@ trait RecurringTransactionTrait
*/
protected function deleteTransactions(Recurrence $recurrence): void
{
Log::debug('deleteTransactions()');
/** @var RecurrenceTransaction $transaction */
foreach ($recurrence->recurrenceTransactions as $transaction) {
$transaction->recurrenceTransactionMeta()->delete();

View File

@@ -25,6 +25,7 @@ namespace FireflyIII\Services\Internal\Update;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\TransactionCurrencyFactory;
use FireflyIII\Models\Note;
use FireflyIII\Models\Recurrence;
use FireflyIII\Models\RecurrenceRepetition;
@@ -155,7 +156,7 @@ class RecurrenceUpdateService
}
// user added or removed repetitions, delete all and recreate:
if ($originalCount !== count($repetitions)) {
Log::debug('Del + recreate');
Log::debug('Delete existing repetitions and create new ones.');
$this->deleteRepetitions($recurrence);
$this->createRepetitions($recurrence, $repetitions);
@@ -232,12 +233,15 @@ class RecurrenceUpdateService
}
// user added or removed repetitions, delete all and recreate:
if ($originalCount !== count($transactions)) {
Log::debug('Del + recreate');
Log::debug('Delete existing transactions and create new ones.');
$this->deleteTransactions($recurrence);
$this->createTransactions($recurrence, $transactions);
return;
}
$currencyFactory = app(TransactionCurrencyFactory::class);
// loop all and try to match them:
if ($originalCount === count($transactions)) {
Log::debug('Loop and find');
@@ -246,16 +250,36 @@ class RecurrenceUpdateService
if (null === $match) {
throw new FireflyException('Cannot match recurring transaction to existing transaction. Not sure what to do. Break.');
}
// TODO find currency
// TODO find foreign currency
$currency = null;
$foreignCurrency = null;
if (array_key_exists('currency_id', $current) || array_key_exists('currency_code', $current)) {
$currency = $currencyFactory->find($current['currency_id'] ?? null, $currency['currency_code'] ?? null);
}
if (null === $currency) {
unset($current['currency_id'], $currency['currency_code']);
}
if (null !== $currency) {
$current['currency_id'] = (int)$currency->id;
}
if (array_key_exists('foreign_currency_id', $current) || array_key_exists('foreign_currency_code', $current)) {
$foreignCurrency = $currencyFactory->find($current['foreign_currency_id'] ?? null, $currency['foreign_currency_code'] ?? null);
}
if (null === $foreignCurrency) {
unset($current['foreign_currency_id'], $currency['foreign_currency_code']);
}
if (null !== $foreignCurrency) {
$current['foreign_currency_id'] = (int)$foreignCurrency->id;
}
// update fields
$fields = [
'source_id' => 'source_id',
'destination_id' => 'destination_id',
'amount' => 'amount',
'foreign_amount' => 'foreign_amount',
'description' => 'description',
'source_id' => 'source_id',
'destination_id' => 'destination_id',
'amount' => 'amount',
'foreign_amount' => 'foreign_amount',
'description' => 'description',
'currency_id' => 'transaction_currency_id',
'foreign_currency_id' => 'foreign_currency_id',
];
foreach ($fields as $field => $column) {
if (array_key_exists($field, $current)) {