mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-31 18:54:58 +00:00
Allow unreconcile and expand API to block reconciled transactions.
This commit is contained in:
@@ -417,15 +417,22 @@ class UpdateRequest extends FormRequest
|
||||
// all transaction types must be equal:
|
||||
$this->validateTransactionTypesForUpdate($validator);
|
||||
|
||||
|
||||
// user wants to update a reconciled transaction.
|
||||
// source, destination, amount + foreign_amount cannot be changed
|
||||
// and must be omitted from the request.
|
||||
$this->preventUpdateReconciled($validator, $transactionGroup);
|
||||
|
||||
// validate source/destination is equal, depending on the transaction journal type.
|
||||
$this->validateEqualAccountsForUpdate($validator, $transactionGroup);
|
||||
|
||||
// a catch when users submit splits with no source or destination info at all.
|
||||
$this->preventNoAccountInfo($validator, );
|
||||
// see method:
|
||||
//$this->preventNoAccountInfo($validator, );
|
||||
|
||||
// validate that the currency fits the source and/or destination account.
|
||||
// validate all account info
|
||||
$this->validateAccountInformationUpdate($validator, $transactionGroup);
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -25,8 +25,11 @@ namespace FireflyIII\Http\Controllers\Transaction;
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Illuminate\View\View;
|
||||
@@ -36,8 +39,11 @@ use Illuminate\View\View;
|
||||
*/
|
||||
class EditController extends Controller
|
||||
{
|
||||
|
||||
private JournalRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* EditController constructor.
|
||||
* IndexController constructor.
|
||||
*
|
||||
|
||||
*/
|
||||
@@ -45,17 +51,30 @@ class EditController extends Controller
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// some useful repositories:
|
||||
// translations:
|
||||
$this->middleware(
|
||||
static function ($request, $next) {
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string)trans('firefly.transactions'));
|
||||
app('view')->share('mainTitleIcon', 'fa-exchange');
|
||||
|
||||
$this->repository = app(JournalRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function unreconcile(TransactionJournal $journal): JsonResponse
|
||||
{
|
||||
$this->repository->unreconcileById($journal->id);
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionGroup $transactionGroup
|
||||
*
|
||||
|
||||
@@ -46,7 +46,7 @@ use Illuminate\Support\Collection;
|
||||
class JournalRepository implements JournalRepositoryInterface
|
||||
{
|
||||
/** @var User */
|
||||
private $user;
|
||||
private User $user;
|
||||
|
||||
/**
|
||||
* @param TransactionGroup $transactionGroup
|
||||
@@ -334,4 +334,14 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
|
||||
return $journal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function unreconcileById(int $journalId): void
|
||||
{
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = $this->user->transactionJournals()->find($journalId);
|
||||
$journal?->transactions()->update(['reconciled' => false]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +133,13 @@ interface JournalRepositoryInterface
|
||||
*/
|
||||
public function reconcileById(int $journalId): void;
|
||||
|
||||
/**
|
||||
* TODO Maybe to account repository? Do this wen reconcile is API only.
|
||||
*
|
||||
* @param int $journalId
|
||||
*/
|
||||
public function unreconcileById(int $journalId): void;
|
||||
|
||||
/**
|
||||
* Search in journal descriptions.
|
||||
*
|
||||
|
||||
@@ -25,7 +25,9 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Validation;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
@@ -37,6 +39,50 @@ use Illuminate\Validation\Validator;
|
||||
trait GroupValidation
|
||||
{
|
||||
/**
|
||||
* @param Validator $validator
|
||||
* @param TransactionGroup $transactionGroup
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function preventUpdateReconciled(Validator $validator, TransactionGroup $transactionGroup): void
|
||||
{
|
||||
app('log')->debug(sprintf('Now in %s', __METHOD__));
|
||||
|
||||
$count = Transaction
|
||||
::leftJoin('transaction_journals', 'transaction_journals.id', 'transactions.transaction_journal_id')
|
||||
->leftJoin('transaction_groups', 'transaction_groups.id', 'transaction_journals.transaction_group_id')
|
||||
->where('transaction_journals.transaction_group_id', $transactionGroup->id)
|
||||
->where('transactions.reconciled', 1)->where('transactions.amount', '<', 0)->count(['transactions.id']);
|
||||
if (0 === $count) {
|
||||
app('log')->debug(sprintf('Transaction is not reconciled, done with %s', __METHOD__));
|
||||
return;
|
||||
}
|
||||
$data = $validator->getData();
|
||||
$forbidden = ['amount','foreign_amount','currency_code','currency_id','foreign_currency_code','foreign_currency_id',
|
||||
'source_id','source_name','source_number','source_iban',
|
||||
'destination_id','destination_name','destination_number','destination_iban',
|
||||
];
|
||||
foreach($data['transactions'] as $index => $row) {
|
||||
foreach($forbidden as $key) {
|
||||
if(array_key_exists($key, $row)) {
|
||||
$validator->errors()->add(
|
||||
sprintf('transactions.%d.%s', $index, $key),
|
||||
(string)trans('validation.reconciled_forbidden_field', ['field' => $key])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
app('log')->debug(sprintf('Done with %s', __METHOD__));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A catch when users submit splits with no source or destination info at all.
|
||||
*
|
||||
* TODO This should prevent errors down the road but I'm not yet sure what I'm validating here
|
||||
* TODO so I disabled this on 2023-10-22 to see if it causes any issues.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*
|
||||
* @throws FireflyException
|
||||
|
||||
@@ -376,6 +376,11 @@ trait TransactionValidation
|
||||
public function validateAccountInformationUpdate(Validator $validator, TransactionGroup $transactionGroup): void
|
||||
{
|
||||
Log::debug('Now in validateAccountInformationUpdate()');
|
||||
if ($validator->errors()->count() > 0) {
|
||||
Log::debug('Validator already has errors, so return.');
|
||||
return;
|
||||
}
|
||||
|
||||
$transactions = $this->getTransactionsArray($validator);
|
||||
|
||||
/**
|
||||
@@ -699,6 +704,11 @@ trait TransactionValidation
|
||||
*/
|
||||
private function validateEqualAccountsForUpdate(Validator $validator, TransactionGroup $transactionGroup): void
|
||||
{
|
||||
if ($validator->errors()->count() > 0) {
|
||||
Log::debug('Validator already has errors, so return.');
|
||||
return;
|
||||
}
|
||||
|
||||
Log::debug('Now in validateEqualAccountsForUpdate()');
|
||||
$transactions = $this->getTransactionsArray($validator);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user