Implement custom trigger for recurring transactions

This commit is contained in:
James Cole
2022-12-29 15:42:02 +01:00
parent 85a2a87806
commit 8c320fd199
16 changed files with 604 additions and 234 deletions

View File

@@ -63,26 +63,27 @@ class CreateRecurringTransactions implements ShouldQueue
private TransactionGroupRepositoryInterface $groupRepository;
private JournalRepositoryInterface $journalRepository;
private RecurringRepositoryInterface $repository;
private Collection $recurrences;
private Collection $groups;
/**
* Create a new job instance.
*
* @codeCoverageIgnore
*
* @param Carbon|null $date
* @param Carbon|null $date
*/
public function __construct(?Carbon $date)
{
$newDate = new Carbon();
$newDate->startOfDay();
$this->date = $newDate;
if (null !== $date) {
$newDate = clone $date;
$newDate->startOfDay();
$this->date = $newDate;
}
if (null === $date) {
$newDate = new Carbon();
$newDate->startOfDay();
$this->date = $newDate;
}
$this->repository = app(RecurringRepositoryInterface::class);
$this->journalRepository = app(JournalRepositoryInterface::class);
$this->groupRepository = app(TransactionGroupRepositoryInterface::class);
@@ -90,6 +91,8 @@ class CreateRecurringTransactions implements ShouldQueue
$this->submitted = 0;
$this->executed = 0;
$this->created = 0;
$this->recurrences = new Collection();
$this->groups = new Collection();
Log::debug(sprintf('Created new CreateRecurringTransactions("%s")', $this->date->format('Y-m-d')));
}
@@ -100,14 +103,23 @@ class CreateRecurringTransactions implements ShouldQueue
public function handle(): void
{
Log::debug(sprintf('Now at start of CreateRecurringTransactions() job for %s.', $this->date->format('D d M Y')));
$recurrences = $this->repository->getAll();
// only use recurrences from database if there is no collection submitted.
if (0 !== count($this->recurrences)) {
Log::debug('Using predetermined set of recurrences.');
}
if (0 === count($this->recurrences)) {
Log::debug('Grab all recurrences from the database.');
$this->recurrences = $this->repository->getAll();
}
$result = [];
$count = $recurrences->count();
$count = $this->recurrences->count();
$this->submitted = $count;
Log::debug(sprintf('Count of collection is %d', $count));
// filter recurrences:
$filtered = $this->filterRecurrences($recurrences);
$filtered = $this->filterRecurrences($this->recurrences);
Log::debug(sprintf('Left after filtering is %d', $filtered->count()));
/** @var Recurrence $recurrence */
foreach ($filtered as $recurrence) {
@@ -141,7 +153,7 @@ class CreateRecurringTransactions implements ShouldQueue
}
/**
* @param Collection $recurrences
* @param Collection $recurrences
*
* @return Collection
*/
@@ -157,7 +169,7 @@ class CreateRecurringTransactions implements ShouldQueue
/**
* Is the info in the recurrence valid?
*
* @param Recurrence $recurrence
* @param Recurrence $recurrence
*
* @return bool
*
@@ -179,6 +191,7 @@ class CreateRecurringTransactions implements ShouldQueue
return false;
}
// is no longer running
if ($this->repeatUntilHasPassed($recurrence)) {
Log::info(
@@ -221,7 +234,7 @@ class CreateRecurringTransactions implements ShouldQueue
/**
* Return recurring transaction is active.
*
* @param Recurrence $recurrence
* @param Recurrence $recurrence
*
* @return bool
*/
@@ -233,7 +246,7 @@ class CreateRecurringTransactions implements ShouldQueue
/**
* Return true if the $repeat_until date is in the past.
*
* @param Recurrence $recurrence
* @param Recurrence $recurrence
*
* @return bool
*/
@@ -246,7 +259,7 @@ class CreateRecurringTransactions implements ShouldQueue
/**
* Has the recurrence started yet?
*
* @param Recurrence $recurrence
* @param Recurrence $recurrence
*
* @return bool
*/
@@ -261,7 +274,7 @@ class CreateRecurringTransactions implements ShouldQueue
/**
* Get the start date of a recurrence.
*
* @param Recurrence $recurrence
* @param Recurrence $recurrence
*
* @return Carbon
*/
@@ -278,7 +291,7 @@ class CreateRecurringTransactions implements ShouldQueue
/**
* Has the recurrence fired today.
*
* @param Recurrence $recurrence
* @param Recurrence $recurrence
*
* @return bool
*/
@@ -291,7 +304,7 @@ class CreateRecurringTransactions implements ShouldQueue
* Separate method that will loop all repetitions and do something with it. Will return
* all created transaction journals.
*
* @param Recurrence $recurrence
* @param Recurrence $recurrence
*
* @return Collection
* @throws DuplicateTransactionException
@@ -312,7 +325,7 @@ class CreateRecurringTransactions implements ShouldQueue
);
// start looping from $startDate to today perhaps we have a hit?
// add two days to $this->date so we always include the weekend.
// add two days to $this->date, so we always include the weekend.
$includeWeekend = clone $this->date;
$includeWeekend->addDays(2);
$occurrences = $this->repository->getOccurrencesInRange($repetition, $recurrence->first_date, $includeWeekend);
@@ -329,9 +342,9 @@ class CreateRecurringTransactions implements ShouldQueue
/**
* Check if the occurences should be executed.
*
* @param Recurrence $recurrence
* @param RecurrenceRepetition $repetition
* @param array $occurrences
* @param Recurrence $recurrence
* @param RecurrenceRepetition $repetition
* @param array $occurrences
*
* @return Collection
* @throws DuplicateTransactionException
@@ -352,9 +365,9 @@ class CreateRecurringTransactions implements ShouldQueue
}
/**
* @param Recurrence $recurrence
* @param RecurrenceRepetition $repetition
* @param Carbon $date
* @param Recurrence $recurrence
* @param RecurrenceRepetition $repetition
* @param Carbon $date
*
* @return TransactionGroup|null
* @throws DuplicateTransactionException
@@ -376,13 +389,20 @@ class CreateRecurringTransactions implements ShouldQueue
return null;
}
if ($this->repository->createdPreviously($recurrence, $date) && false === $this->force) {
Log::info('There is a transaction already made for this date, so will not be created now');
return null;
}
if ($journalCount > 0 && true === $this->force) {
app('log')->warning(sprintf('Already created %d groups for date %s but FORCED to continue.', $journalCount, $date->format('Y-m-d')));
}
// create transaction array and send to factory.
$groupTitle = null;
$count = $recurrence->recurrenceTransactions->count();
$count = $recurrence->recurrenceTransactions->count();
if ($count > 1) {
/** @var RecurrenceTransaction $first */
@@ -408,6 +428,7 @@ class CreateRecurringTransactions implements ShouldQueue
// trigger event:
event(new StoredTransactionGroup($group, $recurrence->apply_rules, true));
$this->groups->push($group);
// update recurring thing:
$recurrence->latest_date = $date;
@@ -419,9 +440,9 @@ class CreateRecurringTransactions implements ShouldQueue
/**
* Get transaction information from a recurring transaction.
*
* @param Recurrence $recurrence
* @param RecurrenceRepetition $repetition
* @param Carbon $date
* @param Recurrence $recurrence
* @param RecurrenceRepetition $repetition
* @param Carbon $date
*
* @return array
*
@@ -439,7 +460,7 @@ class CreateRecurringTransactions implements ShouldQueue
'type' => strtolower($recurrence->transactionType->type),
'date' => $date,
'user' => $recurrence->user_id,
'currency_id' => (int) $transaction->transaction_currency_id,
'currency_id' => (int)$transaction->transaction_currency_id,
'currency_code' => null,
'description' => $transactions->first()->description,
'amount' => $transaction->amount,
@@ -456,9 +477,9 @@ class CreateRecurringTransactions implements ShouldQueue
'foreign_amount' => $transaction->foreign_amount,
'reconciled' => false,
'identifier' => $index,
'recurrence_id' => (int) $recurrence->id,
'recurrence_id' => (int)$recurrence->id,
'order' => $index,
'notes' => (string) trans('firefly.created_from_recurrence', ['id' => $recurrence->id, 'title' => $recurrence->title]),
'notes' => (string)trans('firefly.created_from_recurrence', ['id' => $recurrence->id, 'title' => $recurrence->title]),
'tags' => $this->repository->getTags($transaction),
'piggy_bank_id' => $this->repository->getPiggyBank($transaction),
'piggy_bank_name' => null,
@@ -466,6 +487,7 @@ class CreateRecurringTransactions implements ShouldQueue
'bill_name' => null,
'recurrence_total' => $total,
'recurrence_count' => $count,
'recurrence_date' => $date,
];
$return[] = $single;
}
@@ -474,7 +496,7 @@ class CreateRecurringTransactions implements ShouldQueue
}
/**
* @param Carbon $date
* @param Carbon $date
*/
public function setDate(Carbon $date): void
{
@@ -484,10 +506,26 @@ class CreateRecurringTransactions implements ShouldQueue
}
/**
* @param bool $force
* @param bool $force
*/
public function setForce(bool $force): void
{
$this->force = $force;
}
/**
* @param Collection $recurrences
*/
public function setRecurrences(Collection $recurrences): void
{
$this->recurrences = $recurrences;
}
/**
* @return Collection
*/
public function getGroups(): Collection
{
return $this->groups;
}
}