2016-10-29 15:14:33 +02:00
< ? php
/**
* ConvertController . php
2017-10-21 08:40:00 +02:00
* Copyright ( c ) 2017 thegrumpydictator @ gmail . com
2016-10-29 15:14:33 +02:00
*
2017-10-21 08:40:00 +02:00
* This file is part of Firefly III .
2016-10-29 15:14:33 +02:00
*
2017-10-21 08:40:00 +02:00
* Firefly III is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* Firefly III 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 General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2017-12-17 14:41:58 +01:00
* along with Firefly III . If not , see < http :// www . gnu . org / licenses />.
2016-10-29 15:14:33 +02:00
*/
2017-04-09 07:44:22 +02:00
declare ( strict_types = 1 );
2016-10-29 15:14:33 +02:00
namespace FireflyIII\Http\Controllers\Transaction ;
2016-10-30 06:14:07 +01:00
use FireflyIII\Exceptions\FireflyException ;
2016-10-29 15:14:33 +02:00
use FireflyIII\Http\Controllers\Controller ;
2016-10-30 06:14:07 +01:00
use FireflyIII\Models\Account ;
2016-10-29 15:14:33 +02:00
use FireflyIII\Models\TransactionJournal ;
use FireflyIII\Models\TransactionType ;
use FireflyIII\Repositories\Account\AccountRepositoryInterface ;
2016-10-30 06:14:07 +01:00
use FireflyIII\Repositories\Journal\JournalRepositoryInterface ;
2016-10-29 15:14:33 +02:00
use Illuminate\Http\Request ;
2018-07-01 09:27:22 +02:00
use Log ;
2016-10-29 15:14:33 +02:00
use View ;
/**
2017-11-15 12:25:49 +01:00
* Class ConvertController .
2016-10-29 15:14:33 +02:00
*/
class ConvertController extends Controller
{
2018-07-20 20:53:48 +02:00
/** @var JournalRepositoryInterface Journals and transactions overview */
2018-02-25 19:09:05 +01:00
private $repository ;
2016-10-29 15:14:33 +02:00
/**
* ConvertController constructor .
*/
public function __construct ()
{
parent :: __construct ();
// some useful repositories:
$this -> middleware (
function ( $request , $next ) {
2018-02-25 19:09:05 +01:00
$this -> repository = app ( JournalRepositoryInterface :: class );
2016-10-29 15:14:33 +02:00
2018-07-15 09:38:49 +02:00
app ( 'view' ) -> share ( 'title' , ( string ) trans ( 'firefly.transactions' ));
2017-12-16 19:46:36 +01:00
app ( 'view' ) -> share ( 'mainTitleIcon' , 'fa-exchange' );
2016-10-29 15:14:33 +02:00
return $next ( $request );
}
);
}
2018-07-08 12:08:53 +02:00
2016-10-29 15:14:33 +02:00
/**
2018-07-22 08:10:16 +02:00
* Show overview of a to be converted transaction .
*
2016-10-29 15:14:33 +02:00
* @ param TransactionType $destinationType
* @ param TransactionJournal $journal
*
* @ return \Illuminate\Http\RedirectResponse | \Illuminate\Routing\Redirector | View
*/
2016-12-06 08:59:08 +01:00
public function index ( TransactionType $destinationType , TransactionJournal $journal )
2016-10-29 15:14:33 +02:00
{
2017-03-04 07:18:35 +01:00
// @codeCoverageIgnoreStart
2016-11-22 19:10:17 +01:00
if ( $this -> isOpeningBalance ( $journal )) {
2018-07-01 09:27:22 +02:00
Log :: debug ( 'This is an opening balance.' );
2016-11-22 19:10:17 +01:00
return $this -> redirectToAccount ( $journal );
}
2017-03-04 07:18:35 +01:00
// @codeCoverageIgnoreEnd
2018-02-25 19:09:05 +01:00
$positiveAmount = $this -> repository -> getJournalTotal ( $journal );
2016-10-29 15:14:33 +02:00
$sourceType = $journal -> transactionType ;
2018-07-15 09:38:49 +02:00
$subTitle = ( string ) trans ( 'firefly.convert_to_' . $destinationType -> type , [ 'description' => $journal -> description ]);
2016-10-29 17:30:55 +02:00
$subTitleIcon = 'fa-exchange' ;
2016-10-29 15:14:33 +02:00
2018-07-20 14:34:56 +02:00
if ( $sourceType -> type === $destinationType -> type ) { // cannot convert to its own type.
2018-07-01 09:27:22 +02:00
Log :: debug ( 'This is already a transaction of the expected type..' );
2018-07-15 09:38:49 +02:00
session () -> flash ( 'info' , ( string ) trans ( 'firefly.convert_is_already_type_' . $destinationType -> type ));
2016-10-29 15:14:33 +02:00
return redirect ( route ( 'transactions.show' , [ $journal -> id ]));
}
2016-10-29 17:30:55 +02:00
2018-07-20 14:34:56 +02:00
if ( $journal -> transactions () -> count () > 2 ) { // cannot convert split.
2018-07-01 09:27:22 +02:00
Log :: info ( 'This journal has more than two transactions.' );
2018-07-15 09:38:49 +02:00
session () -> flash ( 'error' , ( string ) trans ( 'firefly.cannot_convert_split_journal' ));
2016-10-29 15:14:33 +02:00
return redirect ( route ( 'transactions.show' , [ $journal -> id ]));
}
2016-10-29 17:30:55 +02:00
// get source and destination account:
2018-02-25 19:09:05 +01:00
$sourceAccount = $this -> repository -> getJournalSourceAccounts ( $journal ) -> first ();
$destinationAccount = $this -> repository -> getJournalDestinationAccounts ( $journal ) -> first ();
2016-10-29 15:14:33 +02:00
return view (
2018-04-24 19:48:42 +02:00
'transactions.convert' , compact (
2018-06-06 21:23:00 +02:00
'sourceType' , 'destinationType' , 'journal' , 'positiveAmount' , 'sourceAccount' , 'destinationAccount' , 'sourceType' ,
'subTitle' , 'subTitleIcon'
)
2016-10-29 15:14:33 +02:00
);
}
2018-07-08 12:08:53 +02:00
2016-10-29 17:30:55 +02:00
/**
2018-07-22 08:10:16 +02:00
* Do the conversion .
*
2018-04-24 19:48:42 +02:00
* @ param Request $request
* @ param TransactionType $destinationType
* @ param TransactionJournal $journal
2016-10-30 06:14:07 +01:00
*
* @ return \Illuminate\Http\RedirectResponse | \Illuminate\Routing\Redirector
2017-12-22 18:32:43 +01:00
*
2017-12-17 14:30:53 +01:00
* @ throws FireflyException
2018-07-20 14:34:56 +02:00
* @ SuppressWarnings ( PHPMD . ExcessiveMethodLength )
* @ SuppressWarnings ( PHPMD . CyclomaticComplexity )
2016-10-29 17:30:55 +02:00
*/
2018-04-24 19:48:42 +02:00
public function postIndex ( Request $request , TransactionType $destinationType , TransactionJournal $journal )
2016-10-29 15:14:33 +02:00
{
2017-03-04 11:19:44 +01:00
// @codeCoverageIgnoreStart
2016-11-22 19:10:17 +01:00
if ( $this -> isOpeningBalance ( $journal )) {
2018-07-01 09:27:22 +02:00
Log :: debug ( 'Journal is opening balance, return to account.' );
2018-07-08 12:08:53 +02:00
2016-11-22 19:10:17 +01:00
return $this -> redirectToAccount ( $journal );
}
2017-03-04 11:19:44 +01:00
// @codeCoverageIgnoreEnd
2016-11-22 19:10:17 +01:00
2016-10-30 06:14:07 +01:00
$data = $request -> all ();
2016-10-29 17:30:55 +02:00
2016-10-30 06:14:07 +01:00
if ( $journal -> transactionType -> type === $destinationType -> type ) {
2018-07-01 09:27:22 +02:00
Log :: info ( 'Journal is already of the desired type.' );
2018-07-15 09:38:49 +02:00
session () -> flash ( 'error' , ( string ) trans ( 'firefly.convert_is_already_type_' . $destinationType -> type ));
2016-10-29 17:30:55 +02:00
return redirect ( route ( 'transactions.show' , [ $journal -> id ]));
}
if ( $journal -> transactions () -> count () > 2 ) {
2018-07-01 09:27:22 +02:00
Log :: info ( 'Journal has more than two transactions.' );
2018-07-15 09:38:49 +02:00
session () -> flash ( 'error' , ( string ) trans ( 'firefly.cannot_convert_split_journal' ));
2016-10-29 17:30:55 +02:00
return redirect ( route ( 'transactions.show' , [ $journal -> id ]));
}
2016-10-30 06:14:07 +01:00
// get the new source and destination account:
$source = $this -> getSourceAccount ( $journal , $destinationType , $data );
$destination = $this -> getDestinationAccount ( $journal , $destinationType , $data );
// update the journal:
2018-04-24 19:48:42 +02:00
$errors = $this -> repository -> convert ( $journal , $destinationType , $source , $destination );
2016-10-29 17:30:55 +02:00
2016-10-30 06:14:07 +01:00
if ( $errors -> count () > 0 ) {
2017-02-15 15:12:46 +01:00
return redirect ( route ( 'transactions.convert.index' , [ strtolower ( $destinationType -> type ), $journal -> id ])) -> withErrors ( $errors ) -> withInput ();
2016-10-30 06:14:07 +01:00
}
2016-10-29 17:30:55 +02:00
2018-07-15 09:38:49 +02:00
session () -> flash ( 'success' , ( string ) trans ( 'firefly.converted_to_' . $destinationType -> type ));
2016-10-29 17:30:55 +02:00
2016-10-30 06:14:07 +01:00
return redirect ( route ( 'transactions.show' , [ $journal -> id ]));
}
2016-10-29 17:30:55 +02:00
2018-07-08 12:08:53 +02:00
2016-10-30 06:14:07 +01:00
/**
2018-07-22 08:10:16 +02:00
* Get the destination account . Is complex .
*
2016-10-30 06:14:07 +01:00
* @ param TransactionJournal $journal
* @ param TransactionType $destinationType
* @ param array $data
*
* @ return Account
2017-11-15 12:25:49 +01:00
*
2016-10-30 06:14:07 +01:00
* @ throws FireflyException
2018-07-20 14:34:56 +02:00
*
* @ SuppressWarnings ( PHPMD . ExcessiveMethodLength )
* @ SuppressWarnings ( PHPMD . CyclomaticComplexity )
2016-10-30 06:14:07 +01:00
*/
2018-08-09 16:07:33 +02:00
protected function getDestinationAccount ( TransactionJournal $journal , TransactionType $destinationType , array $data ) : Account // helper for conversion. Get info from obj.
2016-10-30 06:14:07 +01:00
{
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app ( AccountRepositoryInterface :: class );
2018-02-25 19:09:05 +01:00
$sourceAccount = $this -> repository -> getJournalSourceAccounts ( $journal ) -> first ();
$destinationAccount = $this -> repository -> getJournalDestinationAccounts ( $journal ) -> first ();
2016-10-30 06:14:07 +01:00
$sourceType = $journal -> transactionType ;
$joined = $sourceType -> type . '-' . $destinationType -> type ;
switch ( $joined ) {
default :
2017-03-04 11:19:44 +01:00
throw new FireflyException ( 'Cannot handle ' . $joined ); // @codeCoverageIgnore
2017-06-07 07:38:58 +02:00
case TransactionType :: WITHDRAWAL . '-' . TransactionType :: DEPOSIT :
// one
2016-10-30 06:14:07 +01:00
$destination = $sourceAccount ;
break ;
2017-06-07 07:38:58 +02:00
case TransactionType :: WITHDRAWAL . '-' . TransactionType :: TRANSFER :
// two
2018-04-02 15:10:40 +02:00
$destination = $accountRepository -> findNull (( int ) $data [ 'destination_account_asset' ]);
2016-10-30 06:14:07 +01:00
break ;
2017-06-07 07:38:58 +02:00
case TransactionType :: DEPOSIT . '-' . TransactionType :: WITHDRAWAL :
case TransactionType :: TRANSFER . '-' . TransactionType :: WITHDRAWAL :
// three and five
2017-11-15 12:25:49 +01:00
if ( '' === $data [ 'destination_account_expense' ] || null === $data [ 'destination_account_expense' ]) {
2017-05-07 19:45:40 +02:00
// destination is a cash account.
2018-03-26 20:48:47 +02:00
return $accountRepository -> getCashAccount ();
2017-05-07 19:45:40 +02:00
}
2016-10-30 06:14:07 +01:00
$data = [
2018-03-26 20:48:47 +02:00
'name' => $data [ 'destination_account_expense' ],
'accountType' => 'expense' ,
'account_type_id' => null ,
'virtualBalance' => 0 ,
'active' => true ,
'iban' => null ,
2016-10-30 06:14:07 +01:00
];
$destination = $accountRepository -> store ( $data );
break ;
2017-06-07 07:38:58 +02:00
case TransactionType :: DEPOSIT . '-' . TransactionType :: TRANSFER :
case TransactionType :: TRANSFER . '-' . TransactionType :: DEPOSIT :
// four and six
2016-10-30 06:14:07 +01:00
$destination = $destinationAccount ;
break ;
}
2016-10-29 17:30:55 +02:00
2016-10-30 06:14:07 +01:00
return $destination ;
}
2016-10-29 15:14:33 +02:00
2018-07-08 12:08:53 +02:00
2016-10-30 06:14:07 +01:00
/**
2018-07-22 08:10:16 +02:00
* Get the source account .
*
2016-10-30 06:14:07 +01:00
* @ param TransactionJournal $journal
* @ param TransactionType $destinationType
* @ param array $data
*
* @ return Account
2017-11-15 12:25:49 +01:00
*
2016-10-30 06:14:07 +01:00
* @ throws FireflyException
2018-07-20 14:34:56 +02:00
*
* @ SuppressWarnings ( PHPMD . ExcessiveMethodLength )
* @ SuppressWarnings ( PHPMD . CyclomaticComplexity )
2016-10-30 06:14:07 +01:00
*/
2018-08-09 16:07:33 +02:00
protected function getSourceAccount ( TransactionJournal $journal , TransactionType $destinationType , array $data ) : Account // helper for conversion. Get info from obj.
2016-10-30 06:14:07 +01:00
{
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app ( AccountRepositoryInterface :: class );
2018-02-25 19:09:05 +01:00
$sourceAccount = $this -> repository -> getJournalSourceAccounts ( $journal ) -> first ();
$destinationAccount = $this -> repository -> getJournalDestinationAccounts ( $journal ) -> first ();
2016-10-30 06:14:07 +01:00
$sourceType = $journal -> transactionType ;
$joined = $sourceType -> type . '-' . $destinationType -> type ;
switch ( $joined ) {
default :
2017-03-04 11:19:44 +01:00
throw new FireflyException ( 'Cannot handle ' . $joined ); // @codeCoverageIgnore
2017-06-24 13:04:41 +02:00
case TransactionType :: WITHDRAWAL . '-' . TransactionType :: DEPOSIT :
case TransactionType :: TRANSFER . '-' . TransactionType :: DEPOSIT :
2017-05-07 19:45:40 +02:00
2017-11-15 12:25:49 +01:00
if ( '' === $data [ 'source_account_revenue' ] || null === $data [ 'source_account_revenue' ]) {
2017-05-07 19:45:40 +02:00
// destination is a cash account.
2018-03-26 20:48:47 +02:00
return $accountRepository -> getCashAccount ();
2017-05-07 19:45:40 +02:00
}
2016-10-30 06:14:07 +01:00
$data = [
2018-03-26 20:48:47 +02:00
'name' => $data [ 'source_account_revenue' ],
'accountType' => 'revenue' ,
'virtualBalance' => 0 ,
'active' => true ,
'account_type_id' => null ,
'iban' => null ,
2016-10-30 06:14:07 +01:00
];
$source = $accountRepository -> store ( $data );
break ;
2017-06-24 13:04:41 +02:00
case TransactionType :: WITHDRAWAL . '-' . TransactionType :: TRANSFER :
case TransactionType :: TRANSFER . '-' . TransactionType :: WITHDRAWAL :
2016-10-30 06:14:07 +01:00
$source = $sourceAccount ;
break ;
2017-06-24 13:04:41 +02:00
case TransactionType :: DEPOSIT . '-' . TransactionType :: WITHDRAWAL :
2016-10-30 06:14:07 +01:00
$source = $destinationAccount ;
break ;
2017-06-24 13:04:41 +02:00
case TransactionType :: DEPOSIT . '-' . TransactionType :: TRANSFER :
2018-04-02 15:10:40 +02:00
$source = $accountRepository -> findNull (( int ) $data [ 'source_account_asset' ]);
2016-10-30 06:14:07 +01:00
break ;
}
2016-10-29 15:14:33 +02:00
2016-10-30 06:14:07 +01:00
return $source ;
2016-10-29 15:14:33 +02:00
}
2016-12-22 19:42:45 +01:00
}