2021-04-10 00:59:54 -05:00
< ? php
2021-08-10 12:31:55 -05:00
2021-04-10 00:59:54 -05:00
/*
* CreditRecalculateService . php
* Copyright ( c ) 2021 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 />.
*/
2021-08-10 12:31:55 -05:00
declare ( strict_types = 1 );
2021-04-10 00:59:54 -05:00
namespace FireflyIII\Services\Internal\Support ;
use FireflyIII\Exceptions\FireflyException ;
2021-04-10 10:26:36 -05:00
use FireflyIII\Factory\AccountMetaFactory ;
2021-04-10 00:59:54 -05:00
use FireflyIII\Models\Account ;
use FireflyIII\Models\Transaction ;
use FireflyIII\Models\TransactionGroup ;
use FireflyIII\Models\TransactionJournal ;
2021-04-10 23:41:21 -05:00
use FireflyIII\Models\TransactionType ;
2021-04-10 00:59:54 -05:00
use FireflyIII\Repositories\Account\AccountRepositoryInterface ;
2023-07-04 06:29:19 -05:00
/**
* Class CreditRecalculateService
*/
2021-04-10 00:59:54 -05:00
class CreditRecalculateService
{
2021-04-10 10:26:36 -05:00
private ? Account $account ;
private ? TransactionGroup $group ;
private AccountRepositoryInterface $repository ;
2021-09-18 03:26:12 -05:00
private array $work ;
2021-04-10 10:26:36 -05:00
/**
* CreditRecalculateService constructor .
*/
public function __construct ()
{
$this -> group = null ;
$this -> account = null ;
$this -> work = [];
}
2021-04-10 00:59:54 -05:00
/**
*
*/
public function recalculate () : void
{
if ( true !== config ( 'firefly.feature_flags.handle_debts' )) {
return ;
}
2021-04-10 10:26:36 -05:00
if ( null !== $this -> group && null === $this -> account ) {
$this -> processGroup ();
}
if ( null !== $this -> account && null === $this -> group ) {
// work based on account.
$this -> processAccount ();
}
2022-11-03 23:11:05 -05:00
if ( 0 === count ( $this -> work )) {
2021-04-10 10:26:36 -05:00
return ;
2021-04-10 00:59:54 -05:00
}
2021-04-26 00:29:39 -05:00
$this -> processWork ();
2021-04-10 00:59:54 -05:00
}
2021-04-10 10:26:36 -05:00
/**
2023-06-21 05:34:58 -05:00
*
2023-05-29 06:56:55 -05:00
*/
2023-06-21 05:34:58 -05:00
private function processGroup () : void
2023-05-29 06:56:55 -05:00
{
2023-06-21 05:34:58 -05:00
/** @var TransactionJournal $journal */
foreach ( $this -> group -> transactionJournals as $journal ) {
try {
$this -> findByJournal ( $journal );
} catch ( FireflyException $e ) {
2023-10-29 00:32:00 -05:00
app ( 'log' ) -> error ( $e -> getTraceAsString ());
app ( 'log' ) -> error ( sprintf ( 'Could not find work account for transaction group #%d.' , $this -> group -> id ));
2023-06-21 05:34:58 -05:00
}
}
2021-04-10 00:59:54 -05:00
}
/**
2023-06-21 05:34:58 -05:00
* @ param TransactionJournal $journal
2021-04-10 00:59:54 -05:00
*
* @ throws FireflyException
*/
2021-04-10 10:26:36 -05:00
private function findByJournal ( TransactionJournal $journal ) : void
2021-04-10 00:59:54 -05:00
{
2021-04-10 10:26:36 -05:00
$source = $this -> getSourceAccount ( $journal );
$destination = $this -> getDestinationAccount ( $journal );
// destination or source must be liability.
$valid = config ( 'firefly.valid_liabilities' );
2022-10-30 08:24:37 -05:00
if ( in_array ( $destination -> accountType -> type , $valid , true )) {
2021-04-10 10:26:36 -05:00
$this -> work [] = $destination ;
}
2022-10-30 08:24:37 -05:00
if ( in_array ( $source -> accountType -> type , $valid , true )) {
2021-04-10 10:26:36 -05:00
$this -> work [] = $source ;
}
2021-04-10 00:59:54 -05:00
}
/**
2023-06-21 05:34:58 -05:00
* @ param TransactionJournal $journal
*
* @ return Account
* @ throws FireflyException
*/
private function getSourceAccount ( TransactionJournal $journal ) : Account
{
return $this -> getAccountByDirection ( $journal , '<' );
}
/**
* @ param TransactionJournal $journal
* @ param string $direction
2021-04-10 00:59:54 -05:00
*
* @ return Account
* @ throws FireflyException
*/
2021-04-10 10:26:36 -05:00
private function getAccountByDirection ( TransactionJournal $journal , string $direction ) : Account
2021-04-10 00:59:54 -05:00
{
2023-11-04 01:18:03 -05:00
/** @var Transaction|null $transaction */
2021-04-10 00:59:54 -05:00
$transaction = $journal -> transactions () -> where ( 'amount' , $direction , '0' ) -> first ();
if ( null === $transaction ) {
throw new FireflyException ( sprintf ( 'Cannot find "%s"-transaction of journal #%d' , $direction , $journal -> id ));
}
2023-11-04 01:18:03 -05:00
/** @var Account|null $foundAccount */
2021-05-24 01:06:56 -05:00
$foundAccount = $transaction -> account ;
if ( null === $foundAccount ) {
2021-04-10 00:59:54 -05:00
throw new FireflyException ( sprintf ( 'Cannot find "%s"-account of transaction #%d of journal #%d' , $direction , $transaction -> id , $journal -> id ));
}
2021-05-24 01:06:56 -05:00
return $foundAccount ;
2021-04-10 00:59:54 -05:00
}
2021-04-10 10:26:36 -05:00
/**
2023-06-21 05:34:58 -05:00
* @ param TransactionJournal $journal
2021-04-10 10:26:36 -05:00
*
* @ return Account
* @ throws FireflyException
*/
private function getDestinationAccount ( TransactionJournal $journal ) : Account
{
return $this -> getAccountByDirection ( $journal , '>' );
}
2023-05-29 06:56:55 -05:00
/**
*
*/
2023-06-21 05:34:58 -05:00
private function processAccount () : void
2023-05-29 06:56:55 -05:00
{
2023-06-21 05:34:58 -05:00
$valid = config ( 'firefly.valid_liabilities' );
if ( in_array ( $this -> account -> accountType -> type , $valid , true )) {
$this -> work [] = $this -> account ;
}
2023-05-29 06:56:55 -05:00
}
2021-04-10 10:26:36 -05:00
/**
*
*/
2023-06-21 05:34:58 -05:00
private function processWork () : void
2021-04-10 10:26:36 -05:00
{
2023-06-21 05:34:58 -05:00
$this -> repository = app ( AccountRepositoryInterface :: class );
foreach ( $this -> work as $account ) {
$this -> processWorkAccount ( $account );
2021-04-10 10:26:36 -05:00
}
}
/**
2023-06-21 05:34:58 -05:00
* @ param Account $account
2021-04-10 10:26:36 -05:00
*/
2023-06-21 05:34:58 -05:00
private function processWorkAccount ( Account $account ) : void
2021-04-10 10:26:36 -05:00
{
2023-08-06 00:03:39 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Now processing account #%d ("%s")' , $account -> id , $account -> name ));
2023-06-21 05:34:58 -05:00
// get opening balance (if present)
$this -> repository -> setUser ( $account -> user );
2023-10-04 12:14:47 -05:00
$direction = ( string ) $this -> repository -> getMetaValue ( $account , 'liability_direction' );
$openingBalance = $this -> repository -> getOpeningBalance ( $account );
if ( null !== $openingBalance ) {
app ( 'log' ) -> debug ( sprintf ( 'Found opening balance transaction journal #%d' , $openingBalance -> id ));
// if account direction is "debit" ("I owe this amount") the opening balance must always be AWAY from the account:
if ( 'debit' === $direction ) {
$this -> validateOpeningBalance ( $account , $openingBalance );
}
}
2023-06-21 05:34:58 -05:00
$startOfDebt = $this -> repository -> getOpeningBalanceAmount ( $account ) ? ? '0' ;
$leftOfDebt = app ( 'steam' ) -> positive ( $startOfDebt );
2023-10-14 07:52:21 -05:00
$currency = $this -> repository -> getAccountCurrency ( $account );
2023-11-26 05:24:37 -06:00
$decimals = $currency ? -> decimal_places ? ? 2 ;
2023-10-14 07:52:21 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Start of debt is "%s", so initial left of debt is "%s"' , app ( 'steam' ) -> bcround ( $startOfDebt , $decimals ), app ( 'steam' ) -> bcround ( $leftOfDebt , $decimals )));
2023-08-06 00:03:39 -05:00
2023-06-21 05:34:58 -05:00
/** @var AccountMetaFactory $factory */
$factory = app ( AccountMetaFactory :: class );
// amount is positive or negative, doesn't matter.
$factory -> crud ( $account , 'start_of_debt' , $startOfDebt );
2023-08-06 00:03:39 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Debt direction is "%s"' , $direction ));
2023-06-21 05:34:58 -05:00
// now loop all transactions (except opening balance and credit thing)
2023-08-06 00:03:39 -05:00
$transactions = $account -> transactions ()
-> leftJoin ( 'transaction_journals' , 'transaction_journals.id' , '=' , 'transactions.transaction_journal_id' )
-> orderBy ( 'transaction_journals.date' , 'ASC' )
-> get ([ 'transactions.*' ]);
$total = $transactions -> count ();
app ( 'log' ) -> debug ( sprintf ( 'Found %d transaction(s) to process.' , $total ));
2023-06-21 05:34:58 -05:00
/** @var Transaction $transaction */
2023-08-06 00:03:39 -05:00
foreach ( $transactions as $index => $transaction ) {
app ( 'log' ) -> debug ( sprintf ( '[%d/%d] Processing transaction.' , $index + 1 , $total ));
2023-06-21 05:34:58 -05:00
$leftOfDebt = $this -> processTransaction ( $account , $direction , $transaction , $leftOfDebt );
2021-09-18 03:26:12 -05:00
}
2023-06-21 05:34:58 -05:00
$factory -> crud ( $account , 'current_debt' , $leftOfDebt );
2023-08-06 00:03:39 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Done processing account #%d ("%s")' , $account -> id , $account -> name ));
2021-04-10 10:26:36 -05:00
}
2023-10-04 12:14:47 -05:00
/**
* If account direction is " debit " ( " I owe this amount " ) the opening balance must always be AWAY from the account :
*
* @ param Account $account
* @ param TransactionJournal $openingBalance
*
* @ return void
*/
private function validateOpeningBalance ( Account $account , TransactionJournal $openingBalance )
{
/** @var Transaction $source */
$source = $openingBalance -> transactions () -> where ( 'amount' , '<' , 0 ) -> first ();
/** @var Transaction $dest */
$dest = $openingBalance -> transactions () -> where ( 'amount' , '>' , 0 ) -> first ();
2023-11-05 12:41:37 -06:00
if ( $source -> account_id !== $account -> id ) {
2023-10-04 12:14:47 -05:00
app ( 'log' ) -> info ( sprintf ( 'Liability #%d has a reversed opening balance. Will fix this now.' , $account -> id ));
app ( 'log' ) -> debug ( sprintf ( 'Source amount "%s" is now "%s"' , $source -> amount , app ( 'steam' ) -> positive ( $source -> amount )));
app ( 'log' ) -> debug ( sprintf ( 'Destination amount "%s" is now "%s"' , $dest -> amount , app ( 'steam' ) -> negative ( $dest -> amount )));
$source -> amount = app ( 'steam' ) -> positive ( $source -> amount );
$dest -> amount = app ( 'steam' ) -> negative ( $source -> amount );
var_dump ( $source -> foreign_amount );
if ( null !== $source -> foreign_amount && '' !== $source -> foreign_amount ) {
$source -> foreign_amount = app ( 'steam' ) -> positive ( $source -> foreign_amount );
app ( 'log' ) -> debug ( sprintf ( 'Source foreign amount "%s" is now "%s"' , $source -> foreign_amount , app ( 'steam' ) -> positive ( $source -> foreign_amount )));
}
if ( null !== $dest -> foreign_amount && '' !== $dest -> foreign_amount ) {
$dest -> foreign_amount = app ( 'steam' ) -> negative ( $dest -> foreign_amount );
app ( 'log' ) -> debug ( sprintf ( 'Destination amount "%s" is now "%s"' , $dest -> foreign_amount , app ( 'steam' ) -> negative ( $dest -> foreign_amount )));
}
$source -> save ();
$dest -> save ();
return ;
}
app ( 'log' ) -> debug ( 'Opening balance is valid' );
}
2021-04-10 23:41:21 -05:00
/**
2023-07-15 09:02:42 -05:00
* @ param Account $account
* @ param string $direction
2023-06-21 05:34:58 -05:00
* @ param Transaction $transaction
2023-07-15 09:02:42 -05:00
* @ param string $leftOfDebt
*
2021-04-10 23:41:21 -05:00
* @ return string
*/
2023-01-14 23:58:09 -06:00
private function processTransaction ( Account $account , string $direction , Transaction $transaction , string $leftOfDebt ) : string
2021-04-10 23:41:21 -05:00
{
2022-12-23 22:48:04 -06:00
$journal = $transaction -> transactionJournal ;
$foreignCurrency = $transaction -> foreignCurrency ;
$accountCurrency = $this -> repository -> getAccountCurrency ( $account );
$groupId = $journal -> transaction_group_id ;
2023-11-26 05:24:37 -06:00
$decimals = $accountCurrency -> decimal_places ;
2022-12-23 22:48:04 -06:00
$type = $journal -> transactionType -> type ;
2023-01-14 23:58:09 -06:00
/** @var Transaction $destTransaction */
$destTransaction = $journal -> transactions () -> where ( 'amount' , '>' , '0' ) -> first ();
/** @var Transaction $sourceTransaction */
$sourceTransaction = $journal -> transactions () -> where ( 'amount' , '<' , '0' ) -> first ();
2022-12-23 22:48:04 -06:00
2023-10-14 07:52:21 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Left of debt is: %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , $decimals )));
2021-05-15 02:16:54 -05:00
if ( '' === $direction ) {
2023-08-06 00:03:39 -05:00
app ( 'log' ) -> warning ( 'Direction is empty, so do nothing.' );
2023-01-14 23:58:09 -06:00
return $leftOfDebt ;
2021-05-15 02:16:54 -05:00
}
2023-01-14 23:58:09 -06:00
if ( TransactionType :: LIABILITY_CREDIT === $type || TransactionType :: OPENING_BALANCE === $type ) {
2023-08-06 00:03:39 -05:00
app ( 'log' ) -> warning ( sprintf ( 'Transaction type is "%s", so do nothing.' , $type ));
2023-01-14 23:58:09 -06:00
return $leftOfDebt ;
}
2022-12-23 22:48:04 -06:00
// amount to use depends on the currency:
$usedAmount = $transaction -> amount ;
2023-10-14 07:42:06 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Amount of transaction is %s' , app ( 'steam' ) -> bcround ( $usedAmount , $decimals )));
2022-12-23 22:48:04 -06:00
if ( null !== $foreignCurrency && $foreignCurrency -> id === $accountCurrency -> id ) {
$usedAmount = $transaction -> foreign_amount ;
2023-10-14 07:42:06 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Overruled by foreign amount. Amount of transaction is now %s' , app ( 'steam' ) -> bcround ( $usedAmount , $decimals )));
2022-12-23 22:48:04 -06:00
}
2023-01-14 23:58:09 -06:00
// Case 1
2021-05-15 02:16:54 -05:00
// it's a withdrawal into this liability (from asset).
2022-12-27 00:01:13 -06:00
// if it's a credit ("I am owed"), this increases the amount due,
// because we're lending person X more money
2021-05-15 02:16:54 -05:00
if (
2021-09-18 03:21:29 -05:00
$type === TransactionType :: WITHDRAWAL
2023-11-05 12:41:37 -06:00
&& $account -> id === $transaction -> account_id
2022-12-23 22:48:04 -06:00
&& 1 === bccomp ( $usedAmount , '0' )
2021-05-15 02:16:54 -05:00
&& 'credit' === $direction
) {
2023-08-06 00:03:39 -05:00
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcadd ( $leftOfDebt , $usedAmount );
2023-10-14 07:42:06 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Case 1 (withdrawal into credit liability): %s + %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , $decimals ), app ( 'steam' ) -> bcround ( $usedAmount , $decimals ), app ( 'steam' ) -> bcround ( $result , $decimals )));
2023-08-06 00:03:39 -05:00
return $result ;
2023-01-14 23:58:09 -06:00
}
// Case 2
// it's a withdrawal away from this liability (into expense account).
// if it's a credit ("I am owed"), this decreases the amount due,
// because we're sending money away from the loan (like loan forgiveness)
if (
$type === TransactionType :: WITHDRAWAL
2023-11-05 12:41:37 -06:00
&& $account -> id === $sourceTransaction -> account_id
2023-01-14 23:58:09 -06:00
&& - 1 === bccomp ( $usedAmount , '0' )
&& 'credit' === $direction
) {
2023-08-06 00:03:39 -05:00
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcsub ( $leftOfDebt , $usedAmount );
2023-10-14 07:42:06 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Case 2 (withdrawal away from liability): %s - %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , $decimals ), app ( 'steam' ) -> bcround ( $usedAmount , $decimals ), app ( 'steam' ) -> bcround ( $result , $decimals )));
2023-08-06 00:03:39 -05:00
return $result ;
2021-04-26 00:29:39 -05:00
}
2021-05-15 02:16:54 -05:00
2023-01-14 23:58:09 -06:00
// case 3
2022-12-27 00:05:56 -06:00
// it's a deposit out of this liability (to asset).
// if it's a credit ("I am owed") this decreases the amount due.
// because the person is paying us back.
2021-05-15 02:16:54 -05:00
if (
2021-09-18 03:21:29 -05:00
$type === TransactionType :: DEPOSIT
2023-11-05 12:41:37 -06:00
&& $account -> id === $transaction -> account_id
2022-12-23 22:48:04 -06:00
&& - 1 === bccomp ( $usedAmount , '0' )
2021-05-15 02:16:54 -05:00
&& 'credit' === $direction
) {
2023-08-06 00:03:39 -05:00
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcsub ( $leftOfDebt , $usedAmount );
2023-10-14 07:42:06 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Case 3 (deposit away from liability): %s - %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , $decimals ), app ( 'steam' ) -> bcround ( $usedAmount , $decimals ), app ( 'steam' ) -> bcround ( $result , $decimals )));
2023-08-06 00:03:39 -05:00
return $result ;
2021-04-26 00:29:39 -05:00
}
2023-01-15 00:52:05 -06:00
// case 4
// it's a deposit into this liability (from revenue account).
// if it's a credit ("I am owed") this increases the amount due.
// because the person is having to pay more money.
if (
$type === TransactionType :: DEPOSIT
2023-11-05 12:41:37 -06:00
&& $account -> id === $destTransaction -> account_id
2023-01-15 00:52:05 -06:00
&& 1 === bccomp ( $usedAmount , '0' )
&& 'credit' === $direction
) {
2023-08-06 00:03:39 -05:00
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcadd ( $leftOfDebt , $usedAmount );
2023-10-14 07:42:06 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Case 4 (deposit into credit liability): %s + %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , $decimals ), app ( 'steam' ) -> bcround ( $usedAmount , $decimals ), app ( 'steam' ) -> bcround ( $result , $decimals )));
2023-08-06 00:03:39 -05:00
return $result ;
}
// case 5: transfer into loan (from other loan).
// if it's a credit ("I am owed") this increases the amount due,
// because the person has to pay more back.
if (
$type === TransactionType :: TRANSFER
2023-11-05 12:41:37 -06:00
&& $account -> id === $destTransaction -> account_id
2023-08-06 00:03:39 -05:00
&& 1 === bccomp ( $usedAmount , '0' )
&& 'credit' === $direction
) {
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcadd ( $leftOfDebt , $usedAmount );
2023-10-14 07:42:06 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Case 5 (transfer into credit liability): %s + %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , $decimals ), app ( 'steam' ) -> bcround ( $usedAmount , $decimals ), app ( 'steam' ) -> bcround ( $result , $decimals )));
2023-08-06 00:03:39 -05:00
return $result ;
2023-01-15 00:52:05 -06:00
}
2023-09-18 10:43:20 -05:00
// Case 6
// it's a withdrawal into this liability (from asset).
// if it's a debit ("I owe this amount"), this decreases the amount due,
// because we're paying off the debt
if (
$type === TransactionType :: WITHDRAWAL
2023-11-05 12:41:37 -06:00
&& $account -> id === $transaction -> account_id
2023-09-18 10:43:20 -05:00
&& 1 === bccomp ( $usedAmount , '0' )
&& 'debit' === $direction
) {
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcsub ( $leftOfDebt , $usedAmount );
2023-10-14 07:42:06 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Case 6 (withdrawal into debit liability): %s + %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , $decimals ), app ( 'steam' ) -> bcround ( $usedAmount , $decimals ), app ( 'steam' ) -> bcround ( $result , $decimals )));
2023-09-18 10:43:20 -05:00
return $result ;
}
// case 7
// it's a deposit out of this liability (to asset).
// if it's a credit ("I am owed") this increases the amount due.
// because we are borrowing more money.
if (
$type === TransactionType :: DEPOSIT
2023-11-05 12:41:37 -06:00
&& $account -> id === $transaction -> account_id
2023-09-18 10:43:20 -05:00
&& - 1 === bccomp ( $usedAmount , '0' )
&& 'debit' === $direction
) {
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcadd ( $leftOfDebt , $usedAmount );
2023-10-14 07:42:06 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Case 7 (deposit away from liability): %s - %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , $decimals ), app ( 'steam' ) -> bcround ( $usedAmount , $decimals ), app ( 'steam' ) -> bcround ( $result , $decimals )));
2023-09-18 10:43:20 -05:00
return $result ;
}
2023-10-05 11:36:37 -05:00
// case 8
// it's a withdrawal from this liability (to expense account).
// if it's a debit ("I owe this amount") this increase the amount due.
// because we are paying interest.
if (
$type === TransactionType :: WITHDRAWAL
2023-11-05 12:41:37 -06:00
&& $account -> id === $transaction -> account_id
2023-10-05 11:36:37 -05:00
&& - 1 === bccomp ( $usedAmount , '0' )
&& 'debit' === $direction
) {
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcadd ( $leftOfDebt , $usedAmount );
2023-10-14 07:42:06 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Case 8 (withdrawal away from liability): %s + %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , $decimals ), app ( 'steam' ) -> bcround ( $usedAmount , $decimals ), app ( 'steam' ) -> bcround ( $result , $decimals )));
2023-10-05 11:36:37 -05:00
return $result ;
}
2023-01-15 00:52:05 -06:00
2023-01-14 23:58:09 -06:00
// in any other case, remove amount from left of debt.
2021-04-10 23:41:21 -05:00
if ( in_array ( $type , [ TransactionType :: WITHDRAWAL , TransactionType :: DEPOSIT , TransactionType :: TRANSFER ], true )) {
2023-08-06 00:03:39 -05:00
$usedAmount = app ( 'steam' ) -> negative ( $usedAmount );
$result = bcadd ( $leftOfDebt , $usedAmount );
2023-10-14 07:42:06 -05:00
app ( 'log' ) -> debug ( sprintf ( 'Case X (all other cases): %s + %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , $decimals ), app ( 'steam' ) -> bcround ( $usedAmount , $decimals ), app ( 'steam' ) -> bcround ( $result , $decimals )));
2023-08-06 00:03:39 -05:00
return $result ;
2021-04-10 23:41:21 -05:00
}
2023-10-29 00:31:13 -05:00
app ( 'log' ) -> warning ( sprintf ( '[-1] Catch-all, should not happen. Left of debt = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , $decimals )));
2023-01-14 23:58:09 -06:00
return $leftOfDebt ;
2021-04-10 23:41:21 -05:00
}
2021-09-18 03:26:12 -05:00
/**
2023-06-21 05:34:58 -05:00
* @ param Account | null $account
2021-09-18 03:26:12 -05:00
*/
2023-06-21 05:34:58 -05:00
public function setAccount ( ? Account $account ) : void
2021-09-18 03:26:12 -05:00
{
2023-06-21 05:34:58 -05:00
$this -> account = $account ;
2021-09-18 03:26:12 -05:00
}
/**
2023-06-21 05:34:58 -05:00
* @ param TransactionGroup $group
2021-09-18 03:26:12 -05:00
*/
2023-06-21 05:34:58 -05:00
public function setGroup ( TransactionGroup $group ) : void
2021-09-18 03:26:12 -05:00
{
2023-06-21 05:34:58 -05:00
$this -> group = $group ;
2021-09-18 03:26:12 -05:00
}
2021-05-12 23:17:53 -05:00
}