2021-04-10 07:59:54 +02:00
< ? php
2021-08-10 19:31:55 +02:00
2021-04-10 07:59:54 +02: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 19:31:55 +02:00
declare ( strict_types = 1 );
2021-04-10 07:59:54 +02:00
namespace FireflyIII\Services\Internal\Support ;
use FireflyIII\Exceptions\FireflyException ;
2021-04-10 17:26:36 +02:00
use FireflyIII\Factory\AccountMetaFactory ;
2021-04-10 07:59:54 +02:00
use FireflyIII\Models\Account ;
use FireflyIII\Models\Transaction ;
2023-12-22 09:09:58 +01:00
use FireflyIII\Models\TransactionCurrency ;
2021-04-10 07:59:54 +02:00
use FireflyIII\Models\TransactionGroup ;
use FireflyIII\Models\TransactionJournal ;
2021-04-11 06:41:21 +02:00
use FireflyIII\Models\TransactionType ;
2021-04-10 07:59:54 +02:00
use FireflyIII\Repositories\Account\AccountRepositoryInterface ;
2024-01-06 14:40:06 +01:00
use Illuminate\Support\Facades\Log ;
2021-04-10 07:59:54 +02:00
2023-07-04 13:29:19 +02:00
/**
* Class CreditRecalculateService
*/
2021-04-10 07:59:54 +02:00
class CreditRecalculateService
{
2021-04-10 17:26:36 +02:00
private ? Account $account ;
private ? TransactionGroup $group ;
private AccountRepositoryInterface $repository ;
2021-09-18 10:26:12 +02:00
private array $work ;
2021-04-10 17:26:36 +02:00
/**
* CreditRecalculateService constructor .
*/
public function __construct ()
{
$this -> group = null ;
$this -> account = null ;
$this -> work = [];
}
2021-04-10 07:59:54 +02:00
public function recalculate () : void
{
if ( true !== config ( 'firefly.feature_flags.handle_debts' )) {
return ;
}
2021-04-10 17:26:36 +02: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-04 05:11:05 +01:00
if ( 0 === count ( $this -> work )) {
2021-04-10 17:26:36 +02:00
return ;
2021-04-10 07:59:54 +02:00
}
2021-04-26 07:29:39 +02:00
$this -> processWork ();
2021-04-10 07:59:54 +02:00
}
2023-06-21 12:34:58 +02:00
private function processGroup () : void
2023-05-29 13:56:55 +02:00
{
2023-06-21 12:34:58 +02:00
/** @var TransactionJournal $journal */
foreach ( $this -> group -> transactionJournals as $journal ) {
try {
$this -> findByJournal ( $journal );
} catch ( FireflyException $e ) {
2023-10-29 06:32:00 +01: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 12:34:58 +02:00
}
}
2021-04-10 07:59:54 +02:00
}
/**
* @ throws FireflyException
*/
2021-04-10 17:26:36 +02:00
private function findByJournal ( TransactionJournal $journal ) : void
2021-04-10 07:59:54 +02:00
{
2021-04-10 17:26:36 +02:00
$source = $this -> getSourceAccount ( $journal );
$destination = $this -> getDestinationAccount ( $journal );
// destination or source must be liability.
2024-01-06 14:44:50 +01:00
$valid = config ( 'firefly.valid_liabilities' );
2022-10-30 14:24:37 +01:00
if ( in_array ( $destination -> accountType -> type , $valid , true )) {
2021-04-10 17:26:36 +02:00
$this -> work [] = $destination ;
}
2022-10-30 14:24:37 +01:00
if ( in_array ( $source -> accountType -> type , $valid , true )) {
2021-04-10 17:26:36 +02:00
$this -> work [] = $source ;
}
2021-04-10 07:59:54 +02:00
}
/**
2023-06-21 12:34:58 +02:00
* @ throws FireflyException
*/
private function getSourceAccount ( TransactionJournal $journal ) : Account
{
return $this -> getAccountByDirection ( $journal , '<' );
}
/**
2021-04-10 07:59:54 +02:00
* @ throws FireflyException
*/
2021-04-10 17:26:36 +02:00
private function getAccountByDirection ( TransactionJournal $journal , string $direction ) : Account
2021-04-10 07:59:54 +02:00
{
2023-12-20 19:35:52 +01:00
/** @var null|Transaction $transaction */
2024-01-06 14:44:50 +01:00
$transaction = $journal -> transactions () -> where ( 'amount' , $direction , '0' ) -> first ();
2021-04-10 07:59:54 +02:00
if ( null === $transaction ) {
throw new FireflyException ( sprintf ( 'Cannot find "%s"-transaction of journal #%d' , $direction , $journal -> id ));
}
2023-12-20 19:35:52 +01:00
/** @var null|Account $foundAccount */
2021-05-24 08:06:56 +02:00
$foundAccount = $transaction -> account ;
if ( null === $foundAccount ) {
2021-04-10 07:59:54 +02:00
throw new FireflyException ( sprintf ( 'Cannot find "%s"-account of transaction #%d of journal #%d' , $direction , $transaction -> id , $journal -> id ));
}
2021-05-24 08:06:56 +02:00
return $foundAccount ;
2021-04-10 07:59:54 +02:00
}
2021-04-10 17:26:36 +02:00
/**
* @ throws FireflyException
*/
private function getDestinationAccount ( TransactionJournal $journal ) : Account
{
return $this -> getAccountByDirection ( $journal , '>' );
}
2023-06-21 12:34:58 +02:00
private function processAccount () : void
2023-05-29 13:56:55 +02:00
{
2023-06-21 12:34:58 +02:00
$valid = config ( 'firefly.valid_liabilities' );
if ( in_array ( $this -> account -> accountType -> type , $valid , true )) {
$this -> work [] = $this -> account ;
}
2023-05-29 13:56:55 +02:00
}
2023-06-21 12:34:58 +02:00
private function processWork () : void
2021-04-10 17:26:36 +02:00
{
2023-06-21 12:34:58 +02:00
$this -> repository = app ( AccountRepositoryInterface :: class );
foreach ( $this -> work as $account ) {
$this -> processWorkAccount ( $account );
2021-04-10 17:26:36 +02:00
}
}
2023-06-21 12:34:58 +02:00
private function processWorkAccount ( Account $account ) : void
2021-04-10 17:26:36 +02:00
{
2023-12-22 09:09:58 +01:00
app ( 'log' ) -> debug ( sprintf ( 'Now processing account #%d ("%s"). All amounts with 2 decimals!' , $account -> id , $account -> name ));
2023-06-21 12:34:58 +02:00
// get opening balance (if present)
$this -> repository -> setUser ( $account -> user );
2024-02-22 20:11:09 +01:00
$direction = ( string ) $this -> repository -> getMetaValue ( $account , 'liability_direction' );
2023-10-04 19:14:47 +02:00
$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 );
}
}
2024-01-06 14:44:50 +01:00
$startOfDebt = $this -> repository -> getOpeningBalanceAmount ( $account ) ? ? '0' ;
$leftOfDebt = app ( 'steam' ) -> positive ( $startOfDebt );
2023-12-22 10:16:10 +01:00
app ( 'log' ) -> debug ( sprintf ( 'Start of debt is "%s", so initial left of debt is "%s"' , app ( 'steam' ) -> bcround ( $startOfDebt , 2 ), app ( 'steam' ) -> bcround ( $leftOfDebt , 2 )));
2023-08-06 07:03:39 +02:00
2023-06-21 12:34:58 +02:00
/** @var AccountMetaFactory $factory */
2024-01-06 14:44:50 +01:00
$factory = app ( AccountMetaFactory :: class );
2023-06-21 12:34:58 +02:00
// amount is positive or negative, doesn't matter.
$factory -> crud ( $account , 'start_of_debt' , $startOfDebt );
2023-08-06 07:03:39 +02:00
app ( 'log' ) -> debug ( sprintf ( 'Debt direction is "%s"' , $direction ));
2023-06-21 12:34:58 +02:00
// now loop all transactions (except opening balance and credit thing)
2024-01-06 14:44:50 +01:00
$transactions = $account -> transactions ()
-> leftJoin ( 'transaction_journals' , 'transaction_journals.id' , '=' , 'transactions.transaction_journal_id' )
-> orderBy ( 'transaction_journals.date' , 'ASC' )
-> get ([ 'transactions.*' ])
;
$total = $transactions -> count ();
2023-08-06 07:03:39 +02:00
app ( 'log' ) -> debug ( sprintf ( 'Found %d transaction(s) to process.' , $total ));
2023-12-20 19:35:52 +01:00
2023-06-21 12:34:58 +02:00
/** @var Transaction $transaction */
2023-08-06 07:03:39 +02:00
foreach ( $transactions as $index => $transaction ) {
app ( 'log' ) -> debug ( sprintf ( '[%d/%d] Processing transaction.' , $index + 1 , $total ));
2023-06-21 12:34:58 +02:00
$leftOfDebt = $this -> processTransaction ( $account , $direction , $transaction , $leftOfDebt );
2021-09-18 10:26:12 +02:00
}
2023-06-21 12:34:58 +02:00
$factory -> crud ( $account , 'current_debt' , $leftOfDebt );
2023-08-06 07:03:39 +02:00
app ( 'log' ) -> debug ( sprintf ( 'Done processing account #%d ("%s")' , $account -> id , $account -> name ));
2021-04-10 17:26:36 +02:00
}
2023-10-04 19:14:47 +02:00
/**
* If account direction is " debit " ( " I owe this amount " ) the opening balance must always be AWAY from the account :
*/
2023-12-21 05:07:26 +01:00
private function validateOpeningBalance ( Account $account , TransactionJournal $openingBalance ) : void
2023-10-04 19:14:47 +02:00
{
/** @var Transaction $source */
$source = $openingBalance -> transactions () -> where ( 'amount' , '<' , 0 ) -> first ();
2023-12-20 19:35:52 +01:00
2023-10-04 19:14:47 +02:00
/** @var Transaction $dest */
2024-01-06 14:44:50 +01:00
$dest = $openingBalance -> transactions () -> where ( 'amount' , '>' , 0 ) -> first ();
2023-11-05 19:41:37 +01:00
if ( $source -> account_id !== $account -> id ) {
2023-10-04 19:14:47 +02: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 );
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 ();
2023-12-20 19:35:52 +01:00
2023-10-04 19:14:47 +02:00
return ;
}
app ( 'log' ) -> debug ( 'Opening balance is valid' );
}
2023-12-22 17:28:42 +01:00
/**
2023-12-22 20:12:38 +01:00
* A complex and long method , but rarely used luckily .
*
2023-12-22 17:28:42 +01:00
* @ SuppressWarnings ( PHPMD . ExcessiveMethodLength )
2023-12-22 20:12:38 +01:00
* @ SuppressWarnings ( PHPMD . NPathComplexity )
* @ SuppressWarnings ( PHPMD . CyclomaticComplexity )
2023-12-22 17:28:42 +01:00
*/
2023-01-15 06:58:09 +01:00
private function processTransaction ( Account $account , string $direction , Transaction $transaction , string $leftOfDebt ) : string
2021-04-11 06:41:21 +02:00
{
2022-12-24 05:48:04 +01:00
$journal = $transaction -> transactionJournal ;
$foreignCurrency = $transaction -> foreignCurrency ;
$accountCurrency = $this -> repository -> getAccountCurrency ( $account );
$type = $journal -> transactionType -> type ;
2023-12-22 09:09:58 +01:00
app ( 'log' ) -> debug ( sprintf ( 'Left of debt is: %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , 2 )));
2023-10-14 14:52:21 +02:00
2021-05-15 09:16:54 +02:00
if ( '' === $direction ) {
2023-08-06 07:03:39 +02:00
app ( 'log' ) -> warning ( 'Direction is empty, so do nothing.' );
2023-12-20 19:35:52 +01:00
2023-01-15 06:58:09 +01:00
return $leftOfDebt ;
2021-05-15 09:16:54 +02:00
}
2023-01-15 06:58:09 +01:00
if ( TransactionType :: LIABILITY_CREDIT === $type || TransactionType :: OPENING_BALANCE === $type ) {
2023-08-06 07:03:39 +02:00
app ( 'log' ) -> warning ( sprintf ( 'Transaction type is "%s", so do nothing.' , $type ));
2023-12-20 19:35:52 +01:00
2023-01-15 06:58:09 +01:00
return $leftOfDebt ;
}
2024-01-06 14:40:06 +01:00
Log :: debug ( sprintf ( 'Liability direction is "%s"' , $direction ));
2023-01-15 06:58:09 +01:00
2022-12-24 05:48:04 +01:00
// amount to use depends on the currency:
2024-01-06 14:44:50 +01:00
$usedAmount = $this -> getAmountToUse ( $transaction , $accountCurrency , $foreignCurrency );
$isSameAccount = $account -> id === $transaction -> account_id ;
$isDebit = 'debit' === $direction ;
$isCredit = 'credit' === $direction ;
2022-12-24 05:48:04 +01:00
2023-12-22 09:09:58 +01:00
if ( $isSameAccount && $isCredit && $this -> isWithdrawalIn ( $usedAmount , $type )) { // case 1
2023-08-06 07:03:39 +02:00
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcadd ( $leftOfDebt , $usedAmount );
2023-12-22 10:16:10 +01:00
app ( 'log' ) -> debug ( sprintf ( 'Case 1 (withdrawal into credit liability): %s + %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , 2 ), app ( 'steam' ) -> bcround ( $usedAmount , 2 ), app ( 'steam' ) -> bcround ( $result , 2 )));
2023-12-20 19:35:52 +01:00
2023-08-06 07:03:39 +02:00
return $result ;
2023-01-15 06:58:09 +01:00
}
2023-12-22 09:09:58 +01:00
if ( $isSameAccount && $isCredit && $this -> isWithdrawalOut ( $usedAmount , $type )) { // case 2
2023-08-06 07:03:39 +02:00
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcsub ( $leftOfDebt , $usedAmount );
2023-12-22 10:16:10 +01:00
app ( 'log' ) -> debug ( sprintf ( 'Case 2 (withdrawal away from liability): %s - %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , 2 ), app ( 'steam' ) -> bcround ( $usedAmount , 2 ), app ( 'steam' ) -> bcround ( $result , 2 )));
2023-12-20 19:35:52 +01:00
2023-08-06 07:03:39 +02:00
return $result ;
2021-04-26 07:29:39 +02:00
}
2021-05-15 09:16:54 +02:00
2023-12-22 09:09:58 +01:00
if ( $isSameAccount && $isCredit && $this -> isDepositOut ( $usedAmount , $type )) { // case 3
2023-08-06 07:03:39 +02:00
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcsub ( $leftOfDebt , $usedAmount );
2023-12-22 10:16:10 +01:00
app ( 'log' ) -> debug ( sprintf ( 'Case 3 (deposit away from liability): %s - %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , 2 ), app ( 'steam' ) -> bcround ( $usedAmount , 2 ), app ( 'steam' ) -> bcround ( $result , 2 )));
2023-12-20 19:35:52 +01:00
2023-08-06 07:03:39 +02:00
return $result ;
2021-04-26 07:29:39 +02:00
}
2023-12-22 09:09:58 +01:00
if ( $isSameAccount && $isCredit && $this -> isDepositIn ( $usedAmount , $type )) { // case 4
2023-08-06 07:03:39 +02:00
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcadd ( $leftOfDebt , $usedAmount );
2023-12-22 10:16:10 +01:00
app ( 'log' ) -> debug ( sprintf ( 'Case 4 (deposit into credit liability): %s + %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , 2 ), app ( 'steam' ) -> bcround ( $usedAmount , 2 ), app ( 'steam' ) -> bcround ( $result , 2 )));
2023-12-20 19:35:52 +01:00
2023-08-06 07:03:39 +02:00
return $result ;
}
2023-12-22 09:09:58 +01:00
if ( $isSameAccount && $isCredit && $this -> isTransferIn ( $usedAmount , $type )) { // case 5
2023-08-06 07:03:39 +02:00
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcadd ( $leftOfDebt , $usedAmount );
2023-12-22 10:16:10 +01:00
app ( 'log' ) -> debug ( sprintf ( 'Case 5 (transfer into credit liability): %s + %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , 2 ), app ( 'steam' ) -> bcround ( $usedAmount , 2 ), app ( 'steam' ) -> bcround ( $result , 2 )));
2023-12-20 19:35:52 +01:00
2023-08-06 07:03:39 +02:00
return $result ;
2023-01-15 07:52:05 +01:00
}
2023-12-22 09:09:58 +01:00
if ( $isSameAccount && $isDebit && $this -> isWithdrawalIn ( $usedAmount , $type )) { // case 6
2023-09-18 17:43:20 +02:00
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcsub ( $leftOfDebt , $usedAmount );
2024-01-21 15:00:51 +01:00
app ( 'log' ) -> debug ( sprintf ( 'Case 6 (withdrawal into debit liability): %s - %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , 2 ), app ( 'steam' ) -> bcround ( $usedAmount , 2 ), app ( 'steam' ) -> bcround ( $result , 2 )));
2023-12-20 19:35:52 +01:00
2023-09-18 17:43:20 +02:00
return $result ;
}
2023-12-22 17:28:42 +01:00
if ( $isSameAccount && $isDebit && $this -> isDepositOut ( $usedAmount , $type )) { // case 7
2023-09-18 17:43:20 +02:00
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcadd ( $leftOfDebt , $usedAmount );
2024-01-21 15:00:51 +01:00
app ( 'log' ) -> debug ( sprintf ( 'Case 7 (deposit away from liability): %s + %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , 2 ), app ( 'steam' ) -> bcround ( $usedAmount , 2 ), app ( 'steam' ) -> bcround ( $result , 2 )));
2023-12-20 19:35:52 +01:00
2023-09-18 17:43:20 +02:00
return $result ;
}
2023-12-22 17:28:42 +01:00
if ( $isSameAccount && $isDebit && $this -> isWithdrawalOut ( $usedAmount , $type )) { // case 8
2023-10-05 12:36:37 -04:00
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
$result = bcadd ( $leftOfDebt , $usedAmount );
2023-12-22 10:16:10 +01:00
app ( 'log' ) -> debug ( sprintf ( 'Case 8 (withdrawal away from liability): %s + %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , 2 ), app ( 'steam' ) -> bcround ( $usedAmount , 2 ), app ( 'steam' ) -> bcround ( $result , 2 )));
2023-12-20 19:35:52 +01:00
2023-10-05 12:36:37 -04:00
return $result ;
}
2024-01-06 14:40:06 +01:00
if ( $isSameAccount && $isDebit && $this -> isTransferIn ( $usedAmount , $type )) { // case 9
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
2024-10-05 10:44:29 +02:00
$result = bcsub ( $leftOfDebt , $usedAmount );
// 2024-10-05, #9225 this used to say you would owe more, but a transfer INTO a debit from wherever means you owe LESS.
app ( 'log' ) -> debug ( sprintf ( 'Case 9 (transfer into debit liability, means you owe LESS): %s - %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , 2 ), app ( 'steam' ) -> bcround ( $usedAmount , 2 ), app ( 'steam' ) -> bcround ( $result , 2 )));
2024-01-06 14:44:50 +01:00
2024-01-06 14:40:06 +01:00
return $result ;
}
if ( $isSameAccount && $isDebit && $this -> isTransferOut ( $usedAmount , $type )) { // case 10
$usedAmount = app ( 'steam' ) -> positive ( $usedAmount );
2024-10-05 10:44:29 +02:00
$result = bcadd ( $leftOfDebt , $usedAmount );
// 2024-10-05, #9225 this used to say you would owe less, but a transfer OUT OF a debit from wherever means you owe MORE.
app ( 'log' ) -> debug ( sprintf ( 'Case 10 (transfer out of debit liability, means you owe MORE): %s + %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , 2 ), app ( 'steam' ) -> bcround ( $usedAmount , 2 ), app ( 'steam' ) -> bcround ( $result , 2 )));
2024-01-06 14:40:06 +01:00
return $result ;
}
2023-01-15 06:58:09 +01:00
// in any other case, remove amount from left of debt.
2021-04-11 06:41:21 +02:00
if ( in_array ( $type , [ TransactionType :: WITHDRAWAL , TransactionType :: DEPOSIT , TransactionType :: TRANSFER ], true )) {
2023-08-06 07:03:39 +02:00
$usedAmount = app ( 'steam' ) -> negative ( $usedAmount );
$result = bcadd ( $leftOfDebt , $usedAmount );
2023-12-22 10:16:10 +01:00
app ( 'log' ) -> debug ( sprintf ( 'Case X (all other cases): %s + %s = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , 2 ), app ( 'steam' ) -> bcround ( $usedAmount , 2 ), app ( 'steam' ) -> bcround ( $result , 2 )));
2023-12-20 19:35:52 +01:00
2023-08-06 07:03:39 +02:00
return $result ;
2021-04-11 06:41:21 +02:00
}
2023-12-22 10:16:10 +01:00
app ( 'log' ) -> warning ( sprintf ( '[-1] Catch-all, should not happen. Left of debt = %s' , app ( 'steam' ) -> bcround ( $leftOfDebt , 2 )));
2023-01-15 06:58:09 +01:00
return $leftOfDebt ;
2021-04-11 06:41:21 +02:00
}
2023-12-22 09:09:58 +01:00
private function getAmountToUse ( Transaction $transaction , TransactionCurrency $accountCurrency , ? TransactionCurrency $foreignCurrency ) : string
{
$usedAmount = $transaction -> amount ;
app ( 'log' ) -> debug ( sprintf ( 'Amount of transaction is %s' , app ( 'steam' ) -> bcround ( $usedAmount , 2 )));
if ( null !== $foreignCurrency && $foreignCurrency -> id === $accountCurrency -> id ) {
$usedAmount = $transaction -> foreign_amount ;
app ( 'log' ) -> debug ( sprintf ( 'Overruled by foreign amount. Amount of transaction is now %s' , app ( 'steam' ) -> bcround ( $usedAmount , 2 )));
}
return $usedAmount ;
}
/**
* It ' s a withdrawal into this liability ( from asset ) .
*
* Case 1 = credit
* if it ' s a credit ( " I am owed " ), this increases the amount due ,
* because we ' re lending person X more money
*
* Case 6 = debit
* if it ' s a debit ( " I owe this amount " ), this decreases the amount due ,
* because we ' re paying off the debt
*/
private function isWithdrawalIn ( string $amount , string $transactionType ) : bool
{
return TransactionType :: WITHDRAWAL === $transactionType && 1 === bccomp ( $amount , '0' );
}
/**
* it ' s a withdrawal away from this liability ( into expense account ) .
*
* Case 2
* 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 )
*
* Case 8
* if it ' s a debit ( " I owe this amount " ) this increase the amount due .
* because we are paying interest .
*/
private function isWithdrawalOut ( string $amount , string $transactionType ) : bool
{
return TransactionType :: WITHDRAWAL === $transactionType && - 1 === bccomp ( $amount , '0' );
}
/**
* it ' s a deposit out of this liability ( to asset ) .
*
* case 3
* if it ' s a credit ( " I am owed " ) this decreases the amount due .
* because the person is paying us back .
*
* case 7
2024-01-06 14:40:06 +01:00
* if it ' s a debit ( " I owe " ) this increases the amount due .
2023-12-22 09:09:58 +01:00
* because we are borrowing more money .
*/
private function isDepositOut ( string $amount , string $transactionType ) : bool
{
return TransactionType :: DEPOSIT === $transactionType && - 1 === bccomp ( $amount , '0' );
}
/**
* 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 .
*/
private function isDepositIn ( string $amount , string $transactionType ) : bool
{
return TransactionType :: DEPOSIT === $transactionType && 1 === bccomp ( $amount , '0' );
}
/**
* 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 .
2024-01-06 14:40:06 +01:00
*
* case 8 : transfer into loan ( from other loan ) .
* if it ' s a debit ( " I owe " ) this decreases the amount due .
* because the person has to pay more back .
2023-12-22 09:09:58 +01:00
*/
private function isTransferIn ( string $amount , string $transactionType ) : bool
{
return TransactionType :: TRANSFER === $transactionType && 1 === bccomp ( $amount , '0' );
}
2024-01-06 14:40:06 +01:00
/**
* it ' s a transfer out of loan ( from other loan )
*
* case 9
* if it ' s a debit ( " I owe " ) this decreases the amount due .
* because we remove money from the amount left to owe
*/
private function isTransferOut ( string $amount , string $transactionType ) : bool
{
2024-01-21 15:58:40 +01:00
return TransactionType :: TRANSFER === $transactionType && - 1 === bccomp ( $amount , '0' );
2024-01-06 14:40:06 +01:00
}
2024-02-22 20:11:09 +01:00
public function setAccount ( ? Account $account ) : void
{
$this -> account = $account ;
}
public function setGroup ( TransactionGroup $group ) : void
{
$this -> group = $group ;
}
2021-05-13 06:17:53 +02:00
}