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

@@ -166,7 +166,6 @@ class IndexController extends Controller
$accounts->each(
function (Account $account) use ($activities, $startBalances, $endBalances) {
$interest = (string)$this->repository->getMetaValue($account, 'interest');
$interest = '' === $interest ? '0' : $interest;

View File

@@ -125,7 +125,7 @@ class ReconcileController extends Controller
$startDate = clone $start;
$startDate->subDay();
$startBalance = app('steam')->bcround(app('steam')->balance($account, $startDate), $currency->decimal_places);
$endBalance = app('steam')->bcround( app('steam')->balance($account, $end), $currency->decimal_places);
$endBalance = app('steam')->bcround(app('steam')->balance($account, $end), $currency->decimal_places);
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type));
$subTitle = (string) trans('firefly.reconcile_account', ['account' => $account->name]);

View File

@@ -77,7 +77,7 @@ class AmountController extends Controller
$leftOnAccount = $this->piggyRepos->leftOnAccount($piggyBank, today(config('app.timezone')));
$savedSoFar = $this->piggyRepos->getCurrentAmount($piggyBank);
$maxAmount = $leftOnAccount;
if (0 !== bccomp($piggyBank->targetamount,'0')) {
if (0 !== bccomp($piggyBank->targetamount, '0')) {
$leftToSave = bcsub($piggyBank->targetamount, $savedSoFar);
$maxAmount = min($leftOnAccount, $leftToSave);
}
@@ -101,7 +101,7 @@ class AmountController extends Controller
$savedSoFar = $this->piggyRepos->getCurrentAmount($piggyBank);
$maxAmount = $leftOnAccount;
if (0 !== bccomp($piggyBank->targetamount,'0')) {
if (0 !== bccomp($piggyBank->targetamount, '0')) {
$leftToSave = bcsub($piggyBank->targetamount, $savedSoFar);
$maxAmount = min($leftOnAccount, $leftToSave);
}

View File

@@ -59,7 +59,7 @@ class ShowController extends Controller
$this->middleware(
function ($request, $next) {
app('view')->share('mainTitleIcon', 'fa-paint-brush');
app('view')->share('title', (string) trans('firefly.recurrences'));
app('view')->share('title', (string)trans('firefly.recurrences'));
$this->recurring = app(RecurringRepositoryInterface::class);
@@ -71,7 +71,7 @@ class ShowController extends Controller
/**
* Show a single recurring transaction.
*
* @param Recurrence $recurrence
* @param Recurrence $recurrence
*
* @return Factory|View
* @throws FireflyException
@@ -87,14 +87,19 @@ class ShowController extends Controller
$today = today(config('app.timezone'));
$array['repeat_until'] = null !== $array['repeat_until'] ? new Carbon($array['repeat_until']) : null;
// transform dates back to Carbon objects:
// transform dates back to Carbon objects and expand information
foreach ($array['repetitions'] as $index => $repetition) {
foreach ($repetition['occurrences'] as $item => $occurrence) {
$array['repetitions'][$index]['occurrences'][$item] = new Carbon($occurrence);
$date = (new Carbon($occurrence))->startOfDay();
$set = [
'date' => $date,
'fired' => $this->recurring->createdPreviously($recurrence, $date) || $this->recurring->getJournalCount($recurrence, $date) > 0,
];
$array['repetitions'][$index]['occurrences'][$item] = $set;
}
}
$subTitle = (string) trans('firefly.overview_for_recurrence', ['title' => $recurrence->title]);
$subTitle = (string)trans('firefly.overview_for_recurrence', ['title' => $recurrence->title]);
return view('recurring.show', compact('recurrence', 'subTitle', 'array', 'groups', 'today'));
}

View File

@@ -0,0 +1,89 @@
<?php
/*
* TriggerController.php
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Http\Controllers\Recurring;
use Carbon\Carbon;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Requests\TriggerRecurrenceRequest;
use FireflyIII\Jobs\CreateRecurringTransactions;
use FireflyIII\Models\Recurrence;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
/**
* Class TriggerController
*/
class TriggerController extends Controller
{
/**
* @param Recurrence $recurrence
* @param TriggerRecurrenceRequest $request
* @return RedirectResponse
*/
public function trigger(Recurrence $recurrence, TriggerRecurrenceRequest $request): RedirectResponse
{
$all = $request->getAll();
$date = $all['date'];
// grab the date from the last time the recurrence fired:
$backupDate = $recurrence->latest_date;
// fire the recurring cron job on the given date, then post-date the created transaction.
Log::info(sprintf('Trigger: will now fire recurring cron job task for date "%s".', $date->format('Y-m-d H:i:s')));
/** @var CreateRecurringTransactions $job */
$job = app(CreateRecurringTransactions::class);
$job->setRecurrences(new Collection([$recurrence]));
$job->setDate($date);
$job->setForce(false);
$job->handle();
Log::debug('Done with recurrence.');
$groups = $job->getGroups();
/** @var TransactionGroup $group */
foreach ($groups as $group) {
/** @var TransactionJournal $journal */
foreach ($group->transactionJournals as $journal) {
Log::debug(sprintf('Set date of journal #%d to today!', $journal->id, $date));
$journal->date = Carbon::today();
$journal->save();
}
}
$recurrence->latest_date = $backupDate;
$recurrence->save();
app('preferences')->mark();
if (0 === $groups->count()) {
$request->session()->flash('info', (string)trans('firefly.no_new_transaction_in_recurrence'));
}
if (1 === $groups->count()) {
$first = $groups->first();
$request->session()->flash('success', (string)trans('firefly.stored_journal_no_descr'));
$request->session()->flash('success_url', route('transactions.show', [$first->id]));
}
return redirect(route('recurring.show', [$recurrence->id]));
}
}

View File

@@ -0,0 +1,56 @@
<?php
/*
* TriggerRecurrenceRequest.php
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
class TriggerRecurrenceRequest extends FormRequest
{
use ConvertsDataTypes;
use ChecksLogin;
/**
* Returns the data required by the controller.
*
* @return array
*/
public function getAll(): array
{
return [
'date' => $this->getCarbonDate('date'),
];
}
/**
* Rules for this request.
*
* @return array
*/
public function rules(): array
{
return [
'date' => 'required|date',
];
}
}