2016-10-29 02:03:14 -05:00
< ? php
/**
* SetSourceAccount . php
2020-02-16 06:57:05 -06:00
* Copyright ( c ) 2019 james @ firefly - iii . org
2016-10-29 02:03:14 -05:00
*
2019-10-01 23:37:26 -05:00
* This file is part of Firefly III ( https :// github . com / firefly - iii ) .
2016-10-29 02:03:14 -05:00
*
2019-10-01 23:37:26 -05:00
* 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 .
2017-10-21 01:40:00 -05:00
*
2019-10-01 23:37:26 -05:00
* This program is distributed in the hope that it will be useful ,
2017-10-21 01:40:00 -05:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
2019-10-01 23:37:26 -05:00
* GNU Affero General Public License for more details .
2017-10-21 01:40:00 -05:00
*
2019-10-01 23:37:26 -05:00
* 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 />.
2016-10-29 02:03:14 -05:00
*/
2017-04-09 00:44:22 -05:00
declare ( strict_types = 1 );
2016-10-29 02:03:14 -05:00
2017-09-13 00:49:58 -05:00
namespace FireflyIII\TransactionRules\Actions ;
2016-10-29 02:03:14 -05:00
2020-08-23 09:12:16 -05:00
use DB ;
2016-10-29 02:03:14 -05:00
use FireflyIII\Models\Account ;
use FireflyIII\Models\RuleAction ;
use FireflyIII\Models\TransactionType ;
use FireflyIII\Repositories\Account\AccountRepositoryInterface ;
2020-08-23 09:12:16 -05:00
use FireflyIII\User ;
2016-10-29 02:03:14 -05:00
use Log ;
/**
2017-11-15 05:25:49 -06:00
* Class SetSourceAccount .
2016-10-29 02:03:14 -05:00
*/
class SetSourceAccount implements ActionInterface
{
2020-08-23 09:12:16 -05:00
private RuleAction $action ;
private AccountRepositoryInterface $repository ;
2016-10-29 02:03:14 -05:00
/**
* TriggerInterface constructor .
*
* @ param RuleAction $action
*/
public function __construct ( RuleAction $action )
{
$this -> action = $action ;
}
/**
2020-03-22 11:28:25 -05:00
* @ param string $type
*
2020-08-23 09:12:16 -05:00
* @ return Account | null
2016-10-29 02:03:14 -05:00
*/
2020-08-23 09:12:16 -05:00
private function findAssetAccount ( string $type ) : ? Account
2016-10-29 02:03:14 -05:00
{
2020-03-22 11:28:25 -05:00
// switch on type:
$allowed = config ( sprintf ( 'firefly.expected_source_types.source.%s' , $type ));
2020-04-18 23:05:39 -05:00
$allowed = is_array ( $allowed ) ? $allowed : [];
Log :: debug ( sprintf ( 'Check config for expected_source_types.source.%s, result is' , $type ), $allowed );
2020-08-23 09:12:16 -05:00
return $this -> repository -> findByName ( $this -> action -> action_value , $allowed );
2016-10-29 02:03:14 -05:00
}
/**
2020-08-23 09:12:16 -05:00
* @ return Account | null
2016-10-29 02:03:14 -05:00
*/
2020-08-23 09:12:16 -05:00
private function findRevenueAccount () : ? Account
2016-10-29 02:03:14 -05:00
{
2020-03-22 11:28:25 -05:00
$allowed = config ( 'firefly.expected_source_types.source.Deposit' );
$account = $this -> repository -> findByName ( $this -> action -> action_value , $allowed );
2018-02-16 08:19:19 -06:00
if ( null === $account ) {
2016-10-29 02:03:14 -05:00
// create new revenue account with this name:
$data = [
2018-02-23 09:21:28 -06:00
'name' => $this -> action -> action_value ,
2019-08-17 03:47:29 -05:00
'account_type' => 'revenue' ,
2018-02-23 09:21:28 -06:00
'account_type_id' => null ,
2019-08-17 03:47:29 -05:00
'virtual_balance' => 0 ,
2018-02-23 09:21:28 -06:00
'active' => true ,
'iban' => null ,
2016-10-29 02:03:14 -05:00
];
$account = $this -> repository -> store ( $data );
}
Log :: debug ( sprintf ( 'Found or created revenue account #%d ("%s")' , $account -> id , $account -> name ));
2020-08-23 09:12:16 -05:00
return $account ;
2016-10-29 02:03:14 -05:00
}
2020-08-23 00:42:14 -05:00
/**
* @ inheritDoc
*/
public function actOnArray ( array $journal ) : bool
{
2020-08-23 09:12:16 -05:00
$user = User :: find ( $journal [ 'user_id' ]);
$type = $journal [ 'transaction_type_type' ];
$this -> repository = app ( AccountRepositoryInterface :: class );
$this -> repository -> setUser ( $user );
// if this is a transfer or a withdrawal, the new source account must be an asset account or a default account, and it MUST exist:
$newAccount = $this -> findAssetAccount ( $type );
if (( TransactionType :: WITHDRAWAL === $type || TransactionType :: TRANSFER === $type ) && null === $newAccount ) {
Log :: error ( sprintf ( 'Cannot change source account of journal #%d because no asset account with name "%s" exists.' , $journal [ 'transaction_journal_id' ], $this -> action -> action_value ));
return false ;
}
// if this is a deposit, the new source account must be a revenue account and may be created:
if ( TransactionType :: DEPOSIT === $type ) {
$newAccount = $this -> findRevenueAccount ();
}
if ( null === $newAccount ) {
Log :: error ( 'New account is NULL' );
return false ;
}
Log :: debug ( sprintf ( 'New source account is #%d ("%s").' , $newAccount -> id , $newAccount -> name ));
// update source transaction with new source account:
// get source transaction:
DB :: table ( 'transactions' )
-> where ( 'transaction_journal_id' , '=' , $journal [ 'transaction_journal_id' ])
-> where ( 'amount' , '<' , 0 )
-> update ([ 'account_id' => $newAccount -> id ]);
Log :: debug ( sprintf ( 'Updated journal #%d and gave it new source account ID.' , $journal [ 'transaction_journal_id' ]));
return true ;
2020-08-23 00:42:14 -05:00
}
2016-10-29 02:03:14 -05:00
}