2019-03-24 09:23:36 +01:00
< ? php
/**
* GroupCollector . php
2020-01-28 08:46:01 +01:00
* Copyright ( c ) 2019 james @ firefly - iii . org
2019-03-24 09:23:36 +01:00
*
2019-10-02 06:37:26 +02:00
* This file is part of Firefly III ( https :// github . com / firefly - iii ) .
2019-03-24 09:23:36 +01:00
*
2019-10-02 06:37:26 +02: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 .
2019-03-24 09:23:36 +01:00
*
2019-10-02 06:37:26 +02:00
* This program is distributed in the hope that it will be useful ,
2019-03-24 09:23:36 +01:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
2019-10-02 06:37:26 +02:00
* GNU Affero General Public License for more details .
2019-03-24 09:23:36 +01:00
*
2019-10-02 06:37:26 +02: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 />.
2019-03-24 09:23:36 +01:00
*/
declare ( strict_types = 1 );
namespace FireflyIII\Helpers\Collector ;
use Carbon\Carbon ;
2023-01-03 06:48:53 +01:00
use Carbon\Exceptions\InvalidFormatException ;
2022-11-02 06:25:37 +01:00
use FireflyIII\Exceptions\FireflyException ;
2020-03-21 08:54:38 +01:00
use FireflyIII\Helpers\Collector\Extensions\AccountCollection ;
2020-03-21 09:01:14 +01:00
use FireflyIII\Helpers\Collector\Extensions\AmountCollection ;
2022-03-28 07:54:52 +02:00
use FireflyIII\Helpers\Collector\Extensions\AttachmentCollection ;
2020-03-21 08:54:38 +01:00
use FireflyIII\Helpers\Collector\Extensions\CollectorProperties ;
2020-03-21 09:41:04 +01:00
use FireflyIII\Helpers\Collector\Extensions\MetaCollection ;
2020-03-21 09:01:14 +01:00
use FireflyIII\Helpers\Collector\Extensions\TimeCollection ;
2019-03-25 15:14:09 +01:00
use FireflyIII\Models\TransactionCurrency ;
2019-03-24 09:23:36 +01:00
use FireflyIII\Models\TransactionGroup ;
2019-08-23 09:41:31 +02:00
use FireflyIII\Models\TransactionJournal ;
2023-03-07 19:54:58 +01:00
use FireflyIII\Models\TransactionType ;
2023-08-01 19:38:53 +02:00
use FireflyIII\Models\UserGroup ;
2019-03-24 09:23:36 +01:00
use FireflyIII\User ;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder ;
use Illuminate\Database\Query\JoinClause ;
2019-03-24 14:48:12 +01:00
use Illuminate\Pagination\LengthAwarePaginator ;
2019-03-24 09:23:36 +01:00
use Illuminate\Support\Collection ;
2024-01-01 11:31:14 +01:00
use Illuminate\Support\Facades\Log ;
2019-03-24 09:23:36 +01:00
/**
* Class GroupCollector
*/
class GroupCollector implements GroupCollectorInterface
{
2022-10-30 14:24:19 +01:00
use AccountCollection ;
use AmountCollection ;
use AttachmentCollection ;
2023-11-04 14:18:49 +01:00
use CollectorProperties ;
use MetaCollection ;
use TimeCollection ;
2019-03-24 09:23:36 +01:00
/**
* Group collector constructor .
*/
public function __construct ()
{
2024-02-07 06:14:40 +01:00
$this -> postFilters = [];
$this -> tags = [];
$this -> user = null ;
$this -> userGroup = null ;
$this -> limit = null ;
$this -> page = null ;
2024-02-10 08:28:59 +01:00
$this -> startRow = null ;
$this -> endRow = null ;
2022-03-20 17:11:33 +01:00
2019-06-21 19:10:02 +02:00
$this -> hasAccountInfo = false ;
$this -> hasCatInformation = false ;
$this -> hasBudgetInformation = false ;
$this -> hasBillInformation = false ;
2020-06-09 17:40:09 +02:00
$this -> hasNotesInformation = false ;
2019-06-21 19:10:02 +02:00
$this -> hasJoinedTagTables = false ;
2020-02-23 06:59:41 +01:00
$this -> hasJoinedAttTables = false ;
2023-07-18 06:30:45 +02:00
$this -> expandGroupSearch = false ;
2020-06-23 20:18:59 +02:00
$this -> hasJoinedMetaTables = false ;
2020-02-23 06:59:41 +01:00
$this -> integerFields = [
2019-11-09 08:07:42 +01:00
'transaction_group_id' ,
'user_id' ,
2023-08-01 19:38:53 +02:00
'user_group_id' ,
2019-11-09 08:07:42 +01:00
'transaction_journal_id' ,
'transaction_type_id' ,
'order' ,
'source_transaction_id' ,
'source_account_id' ,
'currency_id' ,
'currency_decimal_places' ,
'foreign_currency_id' ,
'foreign_currency_decimal_places' ,
'destination_transaction_id' ,
'destination_account_id' ,
'category_id' ,
2020-02-23 06:59:41 +01:00
'budget_id' ,
2019-11-09 08:07:42 +01:00
];
2022-06-01 19:23:40 +02:00
$this -> stringFields = [ 'amount' , 'foreign_amount' ];
2020-02-23 06:59:41 +01:00
$this -> total = 0 ;
$this -> fields = [
2023-12-20 19:35:52 +01:00
// group
2019-03-24 09:23:36 +01:00
'transaction_groups.id as transaction_group_id' ,
2019-03-31 13:36:49 +02:00
'transaction_groups.user_id as user_id' ,
2023-08-01 19:38:53 +02:00
'transaction_groups.user_group_id as user_group_id' ,
2019-03-24 14:48:12 +01:00
'transaction_groups.created_at as created_at' ,
'transaction_groups.updated_at as updated_at' ,
2019-03-24 09:23:36 +01:00
'transaction_groups.title as transaction_group_title' ,
2024-01-06 07:26:03 +01:00
'transaction_groups.created_at as group_created_at' ,
'transaction_groups.updated_at as group_updated_at' ,
2023-12-20 19:35:52 +01:00
// journal
2019-03-24 09:23:36 +01:00
'transaction_journals.id as transaction_journal_id' ,
'transaction_journals.transaction_type_id' ,
'transaction_journals.description' ,
'transaction_journals.date' ,
2019-04-06 08:10:50 +02:00
'transaction_journals.order' ,
2019-03-31 13:36:49 +02:00
2023-12-20 19:35:52 +01:00
// types
2019-08-23 06:42:49 +02:00
'transaction_types.type as transaction_type_type' ,
2023-12-20 19:35:52 +01:00
// source info (always present)
2019-03-24 09:23:36 +01:00
'source.id as source_transaction_id' ,
'source.account_id as source_account_id' ,
2019-03-31 13:36:49 +02:00
'source.reconciled' ,
2019-03-24 09:23:36 +01:00
2023-12-20 19:35:52 +01:00
// currency info:
2019-03-24 09:23:36 +01:00
'source.amount as amount' ,
2019-03-25 15:14:09 +01:00
'source.transaction_currency_id as currency_id' ,
'currency.code as currency_code' ,
2019-04-18 20:05:40 +02:00
'currency.name as currency_name' ,
2019-03-24 09:23:36 +01:00
'currency.symbol as currency_symbol' ,
2019-03-25 15:14:09 +01:00
'currency.decimal_places as currency_decimal_places' ,
2019-03-24 09:23:36 +01:00
2023-12-20 19:35:52 +01:00
// foreign currency info
2019-03-24 09:23:36 +01:00
'source.foreign_amount as foreign_amount' ,
'source.foreign_currency_id as foreign_currency_id' ,
2019-03-25 15:14:09 +01:00
'foreign_currency.code as foreign_currency_code' ,
2019-06-22 10:25:34 +02:00
'foreign_currency.name as foreign_currency_name' ,
2019-03-24 09:23:36 +01:00
'foreign_currency.symbol as foreign_currency_symbol' ,
2019-03-25 15:14:09 +01:00
'foreign_currency.decimal_places as foreign_currency_decimal_places' ,
2019-03-24 09:23:36 +01:00
2023-12-20 19:35:52 +01:00
// destination account info (always present)
2019-03-24 09:23:36 +01:00
'destination.account_id as destination_account_id' ,
];
}
2022-09-25 15:31:58 +02:00
public function descriptionDoesNotEnd ( array $array ) : GroupCollectorInterface
2019-08-23 09:41:31 +02:00
{
2021-03-21 09:15:40 +01:00
$this -> query -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q ) use ( $array ) : void { // @phpstan-ignore-line
2021-03-21 09:15:40 +01:00
$q -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q1 ) use ( $array ) : void {
2021-03-21 09:15:40 +01:00
foreach ( $array as $word ) {
$keyword = sprintf ( '%%%s' , $word );
2022-09-25 15:31:58 +02:00
$q1 -> where ( 'transaction_journals.description' , 'NOT LIKE' , $keyword );
2021-03-21 09:15:40 +01:00
}
}
);
2022-09-25 15:31:58 +02:00
$q -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q2 ) use ( $array ) : void {
2021-03-21 09:15:40 +01:00
foreach ( $array as $word ) {
$keyword = sprintf ( '%%%s' , $word );
2022-09-25 15:31:58 +02:00
$q2 -> where ( 'transaction_groups.title' , 'NOT LIKE' , $keyword );
$q2 -> orWhereNull ( 'transaction_groups.title' );
2021-03-21 09:15:40 +01:00
}
}
);
}
);
return $this ;
}
2022-09-25 15:31:58 +02:00
public function descriptionDoesNotStart ( array $array ) : GroupCollectorInterface
2022-09-25 15:31:07 +02:00
{
$this -> query -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q ) use ( $array ) : void { // @phpstan-ignore-line
2022-09-25 15:31:07 +02:00
$q -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q1 ) use ( $array ) : void {
2022-09-25 15:31:07 +02:00
foreach ( $array as $word ) {
2022-09-25 15:31:58 +02:00
$keyword = sprintf ( '%s%%' , $word );
2022-09-25 15:31:07 +02:00
$q1 -> where ( 'transaction_journals.description' , 'NOT LIKE' , $keyword );
}
}
);
$q -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q2 ) use ( $array ) : void {
2022-09-25 15:31:07 +02:00
foreach ( $array as $word ) {
2022-09-25 15:31:58 +02:00
$keyword = sprintf ( '%s%%' , $word );
2022-09-25 15:31:07 +02:00
$q2 -> where ( 'transaction_groups.title' , 'NOT LIKE' , $keyword );
$q2 -> orWhereNull ( 'transaction_groups.title' );
}
}
);
}
);
return $this ;
}
2022-09-25 15:31:58 +02:00
public function descriptionEnds ( array $array ) : GroupCollectorInterface
{
$this -> query -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q ) use ( $array ) : void { // @phpstan-ignore-line
2022-09-25 15:31:58 +02:00
$q -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q1 ) use ( $array ) : void {
2022-09-25 15:31:58 +02:00
foreach ( $array as $word ) {
$keyword = sprintf ( '%%%s' , $word );
$q1 -> where ( 'transaction_journals.description' , 'LIKE' , $keyword );
}
}
);
$q -> orWhere (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q2 ) use ( $array ) : void {
2022-09-25 15:31:58 +02:00
foreach ( $array as $word ) {
$keyword = sprintf ( '%%%s' , $word );
$q2 -> where ( 'transaction_groups.title' , 'LIKE' , $keyword );
}
}
);
}
);
return $this ;
}
2021-03-21 09:15:40 +01:00
public function descriptionIs ( string $value ) : GroupCollectorInterface
{
$this -> query -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q ) use ( $value ) : void { // @phpstan-ignore-line
2021-03-21 09:15:40 +01:00
$q -> where ( 'transaction_journals.description' , '=' , $value );
$q -> orWhere ( 'transaction_groups.title' , '=' , $value );
}
);
return $this ;
}
2022-09-25 15:31:07 +02:00
public function descriptionIsNot ( string $value ) : GroupCollectorInterface
{
$this -> query -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q ) use ( $value ) : void { // @phpstan-ignore-line
2022-09-25 15:31:07 +02:00
$q -> where ( 'transaction_journals.description' , '!=' , $value );
$q -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q2 ) use ( $value ) : void {
2022-09-25 15:31:07 +02:00
$q2 -> where ( 'transaction_groups.title' , '!=' , $value );
$q2 -> orWhereNull ( 'transaction_groups.title' );
}
);
}
);
return $this ;
}
2021-03-21 09:15:40 +01:00
public function descriptionStarts ( array $array ) : GroupCollectorInterface
{
$this -> query -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q ) use ( $array ) : void { // @phpstan-ignore-line
2021-03-21 09:15:40 +01:00
$q -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q1 ) use ( $array ) : void {
2021-03-21 09:15:40 +01:00
foreach ( $array as $word ) {
$keyword = sprintf ( '%s%%' , $word );
$q1 -> where ( 'transaction_journals.description' , 'LIKE' , $keyword );
}
}
);
$q -> orWhere (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q2 ) use ( $array ) : void {
2021-03-21 09:15:40 +01:00
foreach ( $array as $word ) {
$keyword = sprintf ( '%s%%' , $word );
$q2 -> where ( 'transaction_groups.title' , 'LIKE' , $keyword );
}
}
);
}
);
return $this ;
2019-08-23 09:41:31 +02:00
}
2022-09-25 15:31:58 +02:00
public function dumpQuery () : void
{
2023-08-01 19:38:53 +02:00
$query = $this -> query -> select ( $this -> fields ) -> toSql ();
$params = $this -> query -> getBindings ();
foreach ( $params as $param ) {
$replace = sprintf ( '"%s"' , $param );
if ( is_int ( $param )) {
2024-01-12 18:57:38 +01:00
$replace = ( string ) $param ;
2023-08-01 19:38:53 +02:00
}
2024-02-08 01:29:34 +01:00
$pos = strpos ( $query , '?' );
2023-12-20 19:35:52 +01:00
if ( false !== $pos ) {
2023-08-01 19:38:53 +02:00
$query = substr_replace ( $query , $replace , $pos , 1 );
}
}
echo $query ;
2022-09-25 15:31:58 +02:00
echo '<pre>' ;
print_r ( $this -> query -> getBindings ());
echo '</pre>' ;
}
public function dumpQueryInLogs () : void
{
2023-10-29 06:33:43 +01:00
app ( 'log' ) -> debug ( $this -> query -> select ( $this -> fields ) -> toSql ());
app ( 'log' ) -> debug ( 'Bindings' , $this -> query -> getBindings ());
2022-09-25 15:31:58 +02:00
}
/**
* Limit results to NOT a specific currency , either foreign or normal one .
*/
public function excludeCurrency ( TransactionCurrency $currency ) : GroupCollectorInterface
{
$this -> query -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q ) use ( $currency ) : void { // @phpstan-ignore-line
2022-09-25 15:31:58 +02:00
$q -> where ( 'source.transaction_currency_id' , '!=' , $currency -> id );
$q -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q2 ) use ( $currency ) : void {
2022-09-25 15:31:58 +02:00
$q2 -> where ( 'source.foreign_currency_id' , '!=' , $currency -> id );
$q2 -> orWhereNull ( 'source.foreign_currency_id' );
}
);
}
);
return $this ;
}
public function excludeForeignCurrency ( TransactionCurrency $currency ) : GroupCollectorInterface
{
2023-12-21 05:07:26 +01:00
$this -> query -> where ( static function ( EloquentBuilder $q2 ) use ( $currency ) : void { // @phpstan-ignore-line
2022-09-25 15:31:58 +02:00
$q2 -> where ( 'source.foreign_currency_id' , '!=' , $currency -> id );
$q2 -> orWhereNull ( 'source.foreign_currency_id' );
});
return $this ;
}
/**
* Limit the result to NOT a set of specific transaction groups .
*/
public function excludeIds ( array $groupIds ) : GroupCollectorInterface
{
$this -> query -> whereNotIn ( 'transaction_groups.id' , $groupIds );
return $this ;
}
/**
* Limit the result to NOT a set of specific journals .
*/
public function excludeJournalIds ( array $journalIds ) : GroupCollectorInterface
{
2022-11-04 05:11:05 +01:00
if ( 0 !== count ( $journalIds )) {
2022-09-25 15:31:58 +02:00
// make all integers.
$integerIDs = array_map ( 'intval' , $journalIds );
$this -> query -> whereNotIn ( 'transaction_journals.id' , $integerIDs );
}
return $this ;
}
/**
* Search for words in descriptions .
*/
public function excludeSearchWords ( array $array ) : GroupCollectorInterface
2022-09-25 15:31:07 +02:00
{
2022-09-25 15:31:58 +02:00
if ( 0 === count ( $array )) {
return $this ;
}
2022-09-25 15:31:07 +02:00
$this -> query -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q ) use ( $array ) : void { // @phpstan-ignore-line
2022-09-25 15:31:07 +02:00
$q -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q1 ) use ( $array ) : void {
2022-09-25 15:31:07 +02:00
foreach ( $array as $word ) {
2022-09-25 15:31:58 +02:00
$keyword = sprintf ( '%%%s%%' , $word );
2022-09-25 15:31:07 +02:00
$q1 -> where ( 'transaction_journals.description' , 'NOT LIKE' , $keyword );
}
}
);
$q -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q2 ) use ( $array ) : void {
2022-09-25 15:31:07 +02:00
foreach ( $array as $word ) {
2022-09-25 15:31:58 +02:00
$keyword = sprintf ( '%%%s%%' , $word );
2022-09-25 15:31:07 +02:00
$q2 -> where ( 'transaction_groups.title' , 'NOT LIKE' , $keyword );
$q2 -> orWhereNull ( 'transaction_groups.title' );
}
}
);
}
);
return $this ;
}
2022-09-25 15:31:58 +02:00
public function excludeTypes ( array $types ) : GroupCollectorInterface
2022-03-21 06:31:38 +01:00
{
2022-09-25 15:31:58 +02:00
$this -> query -> whereNotIn ( 'transaction_types.type' , $types );
return $this ;
2022-03-21 06:31:38 +01:00
}
2022-09-25 15:31:58 +02:00
public function exists () : GroupCollectorInterface
2022-03-21 06:31:38 +01:00
{
2022-09-25 15:31:58 +02:00
$this -> query -> whereNull ( 'transaction_groups.deleted_at' );
2023-03-07 19:54:58 +01:00
$this -> query -> whereNotIn (
'transaction_types.type' ,
[ TransactionType :: LIABILITY_CREDIT , TransactionType :: OPENING_BALANCE , TransactionType :: RECONCILIATION ]
);
2023-12-20 19:35:52 +01:00
2022-09-25 15:31:58 +02:00
return $this ;
2022-03-21 06:31:38 +01:00
}
2021-09-18 10:26:12 +02:00
public function findNothing () : GroupCollectorInterface
{
$this -> query -> where ( 'transaction_groups.id' , - 1 );
return $this ;
}
2023-07-18 06:30:45 +02:00
public function getExpandGroupSearch () : bool
{
return $this -> expandGroupSearch ;
}
2019-08-23 09:41:31 +02:00
/**
* Return the transaction journals without group information . Is useful in some instances .
*/
public function getExtractedJournals () : array
{
$selection = $this -> getGroups ();
$return = [];
2023-12-20 19:35:52 +01:00
2019-08-23 09:41:31 +02:00
/** @var array $group */
foreach ( $selection as $group ) {
$count = count ( $group [ 'transactions' ]);
foreach ( $group [ 'transactions' ] as $journalId => $journal ) {
$journal [ 'group_title' ] = $group [ 'title' ];
$journal [ 'journals_in_group' ] = $count ;
$return [ $journalId ] = $journal ;
}
}
return $return ;
2019-03-30 07:09:52 +01:00
}
2019-03-24 09:23:36 +01:00
/**
* Return the groups .
*/
public function getGroups () : Collection
{
2023-07-18 06:30:45 +02:00
if ( $this -> expandGroupSearch ) {
// get group ID's for the query:
$groupIds = $this -> getCollectedGroupIds ();
// add to query:
$this -> query -> orWhereIn ( 'transaction_journals.transaction_group_id' , $groupIds );
}
2024-02-08 01:29:34 +01:00
$result = $this -> query -> get ( $this -> fields );
2019-03-24 09:23:36 +01:00
// now to parse this into an array.
2024-02-08 01:29:34 +01:00
$collection = $this -> parseArray ( $result );
2022-03-20 17:11:33 +01:00
// filter the array using all available post filters:
2024-02-08 01:29:34 +01:00
$collection = $this -> postFilterCollection ( $collection );
2022-03-20 17:11:33 +01:00
// count it and continue:
2019-03-24 14:48:12 +01:00
$this -> total = $collection -> count ();
2019-03-24 09:23:36 +01:00
2019-08-17 07:47:39 +02:00
// now filter the array according to the page and the limit (if necessary)
2021-05-24 08:06:56 +02:00
if ( null !== $this -> limit && null !== $this -> page ) {
$offset = ( $this -> page - 1 ) * $this -> limit ;
2019-05-29 21:52:08 +02:00
2021-05-24 08:06:56 +02:00
return $collection -> slice ( $offset , $this -> limit );
2019-08-17 07:47:39 +02:00
}
2024-02-10 08:28:59 +01:00
// OR filter the array according to the start and end row variable
if ( null !== $this -> startRow && null !== $this -> endRow ) {
return $collection -> slice (( int ) $this -> startRow , ( int ) $this -> endRow );
}
2019-08-17 07:47:39 +02:00
return $collection ;
2019-03-24 09:23:36 +01:00
}
2023-07-18 06:30:45 +02:00
/**
2023-12-20 19:35:52 +01:00
* Same as getGroups but everything is in a paginator .
*/
public function getPaginatedGroups () : LengthAwarePaginator
{
$set = $this -> getGroups ();
if ( 0 === $this -> limit ) {
$this -> setLimit ( 50 );
}
2024-02-10 08:28:59 +01:00
if ( null !== $this -> startRow && null !== $this -> endRow ) {
$total = ( int )( $this -> endRow - $this -> startRow );
return new LengthAwarePaginator ( $set , $this -> total , $total , 1 );
}
2023-12-20 19:35:52 +01:00
return new LengthAwarePaginator ( $set , $this -> total , $this -> limit , $this -> page );
}
/**
* Limit the number of returned entries .
*/
public function setLimit ( int $limit ) : GroupCollectorInterface
{
$this -> limit = $limit ;
// app('log')->debug(sprintf('GroupCollector: The limit is now %d', $limit));
return $this ;
}
public function isNotReconciled () : GroupCollectorInterface
{
$this -> query -> where ( 'source.reconciled' , 0 ) -> where ( 'destination.reconciled' , 0 );
return $this ;
}
public function isReconciled () : GroupCollectorInterface
{
$this -> query -> where ( 'source.reconciled' , 1 ) -> where ( 'destination.reconciled' , 1 );
return $this ;
}
/**
* Limit results to a specific currency , either foreign or normal one .
*/
public function setCurrency ( TransactionCurrency $currency ) : GroupCollectorInterface
{
$this -> query -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q ) use ( $currency ) : void { // @phpstan-ignore-line
2023-12-20 19:35:52 +01:00
$q -> where ( 'source.transaction_currency_id' , $currency -> id );
$q -> orWhere ( 'source.foreign_currency_id' , $currency -> id );
}
);
return $this ;
}
public function setExpandGroupSearch ( bool $expandGroupSearch ) : GroupCollectorInterface
{
$this -> expandGroupSearch = $expandGroupSearch ;
return $this ;
}
public function setForeignCurrency ( TransactionCurrency $currency ) : GroupCollectorInterface
{
$this -> query -> where ( 'source.foreign_currency_id' , $currency -> id );
return $this ;
}
/**
* Limit the result to a set of specific transaction groups .
*/
public function setIds ( array $groupIds ) : GroupCollectorInterface
{
$this -> query -> whereIn ( 'transaction_groups.id' , $groupIds );
return $this ;
}
/**
* Limit the result to a set of specific journals .
*/
public function setJournalIds ( array $journalIds ) : GroupCollectorInterface
{
if ( 0 !== count ( $journalIds )) {
// make all integers.
$integerIDs = array_map ( 'intval' , $journalIds );
2024-01-01 14:36:31 +01:00
Log :: debug ( sprintf ( 'GroupCollector: setJournalIds: %s' , implode ( ', ' , $integerIDs )));
2023-12-20 19:35:52 +01:00
$this -> query -> whereIn ( 'transaction_journals.id' , $integerIDs );
}
return $this ;
}
/**
* Set the page to get .
*/
public function setPage ( int $page ) : GroupCollectorInterface
{
$page = 0 === $page ? 1 : $page ;
$this -> page = $page ;
// app('log')->debug(sprintf('GroupCollector: page is now %d', $page));
return $this ;
}
/**
* Search for words in descriptions .
*/
public function setSearchWords ( array $array ) : GroupCollectorInterface
{
if ( 0 === count ( $array )) {
return $this ;
}
$this -> query -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q ) use ( $array ) : void { // @phpstan-ignore-line
2023-12-20 19:35:52 +01:00
$q -> where (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q1 ) use ( $array ) : void {
2023-12-20 19:35:52 +01:00
foreach ( $array as $word ) {
$keyword = sprintf ( '%%%s%%' , $word );
$q1 -> where ( 'transaction_journals.description' , 'LIKE' , $keyword );
}
}
);
$q -> orWhere (
2023-12-21 05:07:26 +01:00
static function ( EloquentBuilder $q2 ) use ( $array ) : void {
2023-12-20 19:35:52 +01:00
foreach ( $array as $word ) {
$keyword = sprintf ( '%%%s%%' , $word );
$q2 -> where ( 'transaction_groups.title' , 'LIKE' , $keyword );
}
}
);
}
);
return $this ;
}
/**
* Limit the search to one specific transaction group .
2023-07-18 06:30:45 +02:00
*/
2023-12-20 19:35:52 +01:00
public function setTransactionGroup ( TransactionGroup $transactionGroup ) : GroupCollectorInterface
{
$this -> query -> where ( 'transaction_groups.id' , $transactionGroup -> id );
return $this ;
}
/**
* Limit the included transaction types .
*/
public function setTypes ( array $types ) : GroupCollectorInterface
{
$this -> query -> whereIn ( 'transaction_types.type' , $types );
return $this ;
}
/**
* Set the user object and start the query .
*/
public function setUser ( User $user ) : GroupCollectorInterface
{
if ( null === $this -> user ) {
$this -> user = $user ;
$this -> startQuery ();
}
return $this ;
}
/**
* Set the user object and start the query .
*/
public function setUserGroup ( UserGroup $userGroup ) : GroupCollectorInterface
{
if ( null === $this -> userGroup ) {
$this -> userGroup = $userGroup ;
$this -> startQueryForGroup ();
}
return $this ;
}
/**
* Automatically include all stuff required to make API calls work .
*/
public function withAPIInformation () : GroupCollectorInterface
{
// include source + destination account name and type.
$this -> withAccountInformation ()
// include category ID + name (if any)
2024-02-08 01:29:34 +01:00
-> withCategoryInformation ()
2023-12-20 19:35:52 +01:00
// include budget ID + name (if any)
2024-02-08 01:29:34 +01:00
-> withBudgetInformation ()
2023-12-20 19:35:52 +01:00
// include bill ID + name (if any)
2024-02-08 01:29:34 +01:00
-> withBillInformation ()
;
2023-12-20 19:35:52 +01:00
return $this ;
}
2023-07-18 06:30:45 +02:00
private function getCollectedGroupIds () : array
{
return $this -> query -> get ([ 'transaction_journals.transaction_group_id' ]) -> pluck ( 'transaction_group_id' ) -> toArray ();
}
2023-05-29 13:56:55 +02:00
/**
2023-02-22 18:03:31 +01:00
* @ throws FireflyException
2019-08-23 09:41:31 +02:00
*/
2022-03-21 06:31:38 +01:00
private function parseArray ( Collection $collection ) : Collection
2019-08-23 09:41:31 +02:00
{
2022-03-21 06:31:38 +01:00
$groups = [];
2023-12-20 19:35:52 +01:00
2022-03-21 06:31:38 +01:00
/** @var TransactionJournal $augumentedJournal */
foreach ( $collection as $augumentedJournal ) {
2024-02-08 01:29:34 +01:00
$groupId = ( int ) $augumentedJournal -> transaction_group_id ;
2022-03-21 06:31:38 +01:00
if ( ! array_key_exists ( $groupId , $groups )) {
// make new array
2024-02-08 01:29:34 +01:00
$parsedGroup = $this -> parseAugmentedJournal ( $augumentedJournal );
$groupArray = [
2024-01-12 18:57:38 +01:00
'id' => ( int ) $augumentedJournal -> transaction_group_id ,
2023-11-05 19:41:37 +01:00
'user_id' => $augumentedJournal -> user_id ,
'user_group_id' => $augumentedJournal -> user_group_id ,
2022-12-31 06:57:05 +01:00
// Field transaction_group_title was added by the query.
'title' => $augumentedJournal -> transaction_group_title , // @phpstan-ignore-line
2024-01-06 07:26:03 +01:00
'created_at' => new Carbon ( $augumentedJournal -> group_created_at , config ( 'app.timezone' )),
'updated_at' => new Carbon ( $augumentedJournal -> group_updated_at , config ( 'app.timezone' )),
2022-03-21 06:31:38 +01:00
'transaction_type' => $parsedGroup [ 'transaction_type_type' ],
'count' => 1 ,
'sums' => [],
'transactions' => [],
];
2022-12-31 06:57:05 +01:00
// Field transaction_journal_id was added by the query.
2024-01-12 18:57:38 +01:00
$journalId = ( int ) $augumentedJournal -> transaction_journal_id ; // @phpstan-ignore-line
2022-03-21 06:31:38 +01:00
$groupArray [ 'transactions' ][ $journalId ] = $parsedGroup ;
$groups [ $groupId ] = $groupArray ;
2023-12-20 19:35:52 +01:00
2022-03-21 06:31:38 +01:00
continue ;
}
// or parse the rest.
2022-12-31 06:57:05 +01:00
// Field transaction_journal_id was added by the query.
2024-01-12 18:57:38 +01:00
$journalId = ( int ) $augumentedJournal -> transaction_journal_id ; // @phpstan-ignore-line
2022-03-21 06:31:38 +01:00
if ( array_key_exists ( $journalId , $groups [ $groupId ][ 'transactions' ])) {
// append data to existing group + journal (for multiple tags or multiple attachments)
$groups [ $groupId ][ 'transactions' ][ $journalId ] = $this -> mergeTags ( $groups [ $groupId ][ 'transactions' ][ $journalId ], $augumentedJournal );
$groups [ $groupId ][ 'transactions' ][ $journalId ] = $this -> mergeAttachments ( $groups [ $groupId ][ 'transactions' ][ $journalId ], $augumentedJournal );
}
if ( ! array_key_exists ( $journalId , $groups [ $groupId ][ 'transactions' ])) {
// create second, third, fourth split:
2023-12-20 19:35:52 +01:00
++ $groups [ $groupId ][ 'count' ];
2022-03-21 06:31:38 +01:00
$groups [ $groupId ][ 'transactions' ][ $journalId ] = $this -> parseAugmentedJournal ( $augumentedJournal );
}
2020-10-23 12:33:53 +02:00
}
2020-12-11 05:17:32 +01:00
2022-03-21 06:31:38 +01:00
$groups = $this -> parseSums ( $groups );
return new Collection ( $groups );
2019-08-23 09:41:31 +02:00
}
2021-03-21 09:15:40 +01:00
/**
2023-02-22 18:03:31 +01:00
* @ throws FireflyException
2021-03-21 09:15:40 +01:00
*/
2022-03-21 06:31:38 +01:00
private function parseAugmentedJournal ( TransactionJournal $augumentedJournal ) : array
2021-03-21 09:15:40 +01:00
{
2022-03-27 08:48:30 +02:00
$result = $augumentedJournal -> toArray ();
$result [ 'tags' ] = [];
$result [ 'attachments' ] = [];
$result [ 'interest_date' ] = null ;
$result [ 'payment_date' ] = null ;
$result [ 'invoice_date' ] = null ;
$result [ 'book_date' ] = null ;
$result [ 'due_date' ] = null ;
$result [ 'process_date' ] = null ;
2023-12-20 19:35:52 +01:00
2022-03-21 06:31:38 +01:00
try {
$result [ 'date' ] = new Carbon ( $result [ 'date' ], 'UTC' );
$result [ 'created_at' ] = new Carbon ( $result [ 'created_at' ], 'UTC' );
$result [ 'updated_at' ] = new Carbon ( $result [ 'updated_at' ], 'UTC' );
2021-03-21 09:15:40 +01:00
2022-03-21 06:31:38 +01:00
// this is going to happen a lot:
$result [ 'date' ] -> setTimezone ( config ( 'app.timezone' ));
$result [ 'created_at' ] -> setTimezone ( config ( 'app.timezone' ));
$result [ 'updated_at' ] -> setTimezone ( config ( 'app.timezone' ));
2023-12-20 19:35:52 +01:00
} catch ( \Exception $e ) { // intentional generic exception
2023-10-29 06:32:00 +01:00
app ( 'log' ) -> error ( $e -> getMessage ());
2023-12-20 19:35:52 +01:00
2022-11-02 06:25:37 +01:00
throw new FireflyException ( $e -> getMessage (), 0 , $e );
2022-03-21 06:31:38 +01:00
}
2019-08-23 09:41:31 +02:00
2022-03-27 08:48:30 +02:00
// try to process meta date value (if present)
2024-02-08 01:29:34 +01:00
$dates = [ 'interest_date' , 'payment_date' , 'invoice_date' , 'book_date' , 'due_date' , 'process_date' ];
2022-03-27 08:48:30 +02:00
if ( array_key_exists ( 'meta_name' , $result ) && in_array ( $result [ 'meta_name' ], $dates , true )) {
$name = $result [ 'meta_name' ];
2024-01-12 18:57:38 +01:00
if ( array_key_exists ( 'meta_data' , $result ) && '' !== ( string ) $result [ 'meta_data' ]) {
2022-03-27 08:48:30 +02:00
$result [ $name ] = Carbon :: createFromFormat ( '!Y-m-d' , substr ( json_decode ( $result [ 'meta_data' ]), 0 , 10 ));
}
}
2022-03-21 06:31:38 +01:00
// convert values to integers:
2024-02-08 01:29:34 +01:00
$result = $this -> convertToInteger ( $result );
2022-03-21 06:31:38 +01:00
2022-06-01 19:23:40 +02:00
// convert back to strings because SQLite is dumb like that.
2024-02-08 01:29:34 +01:00
$result = $this -> convertToStrings ( $result );
2022-06-01 19:23:40 +02:00
2024-02-08 01:29:34 +01:00
$result [ 'reconciled' ] = 1 === ( int ) $result [ 'reconciled' ];
2022-03-21 06:31:38 +01:00
if ( array_key_exists ( 'tag_id' , $result ) && null !== $result [ 'tag_id' ]) { // assume the other fields are present as well.
2024-02-08 01:29:34 +01:00
$tagId = ( int ) $augumentedJournal [ 'tag_id' ];
$tagDate = null ;
2023-12-20 19:35:52 +01:00
2022-03-21 06:31:38 +01:00
try {
$tagDate = Carbon :: parse ( $augumentedJournal [ 'tag_date' ]);
2023-01-03 06:48:53 +01:00
} catch ( InvalidFormatException $e ) {
2023-10-29 06:33:43 +01:00
app ( 'log' ) -> debug ( sprintf ( 'Could not parse date: %s' , $e -> getMessage ()));
2019-03-25 15:14:09 +01:00
}
2023-05-29 13:56:55 +02:00
$result [ 'tags' ][ $tagId ] = [
2024-01-12 18:57:38 +01:00
'id' => ( int ) $result [ 'tag_id' ],
2023-05-29 13:56:55 +02:00
'name' => $result [ 'tag_name' ],
'date' => $tagDate ,
'description' => $result [ 'tag_description' ],
2022-03-21 06:31:38 +01:00
];
}
2023-06-21 12:34:58 +02:00
// also merge attachments:
if ( array_key_exists ( 'attachment_id' , $result )) {
2024-01-12 18:57:38 +01:00
$uploaded = 1 === ( int ) $result [ 'attachment_uploaded' ];
$attachmentId = ( int ) $augumentedJournal [ 'attachment_id' ];
2023-06-21 12:34:58 +02:00
if ( 0 !== $attachmentId && $uploaded ) {
$result [ 'attachments' ][ $attachmentId ] = [
'id' => $attachmentId ,
'filename' => $augumentedJournal [ 'attachment_filename' ],
'title' => $augumentedJournal [ 'attachment_title' ],
];
}
}
// unset various fields:
unset (
$result [ 'tag_id' ], $result [ 'meta_data' ], $result [ 'meta_name' ],
$result [ 'tag_name' ], $result [ 'tag_date' ], $result [ 'tag_description' ],
$result [ 'tag_latitude' ], $result [ 'tag_longitude' ], $result [ 'tag_zoom_level' ],
$result [ 'attachment_filename' ], $result [ 'attachment_id' ]
);
return $result ;
}
/**
* Convert a selected set of fields to arrays .
*/
private function convertToInteger ( array $array ) : array
{
foreach ( $this -> integerFields as $field ) {
2024-01-12 18:57:38 +01:00
$array [ $field ] = array_key_exists ( $field , $array ) ? ( int ) $array [ $field ] : null ;
2023-06-21 12:34:58 +02:00
}
return $array ;
}
private function convertToStrings ( array $array ) : array
{
foreach ( $this -> stringFields as $field ) {
2024-01-12 18:57:38 +01:00
$array [ $field ] = array_key_exists ( $field , $array ) && null !== $array [ $field ] ? ( string ) $array [ $field ] : null ;
2023-06-21 12:34:58 +02:00
}
return $array ;
}
private function mergeTags ( array $existingJournal , TransactionJournal $newJournal ) : array
{
$newArray = $newJournal -> toArray ();
if ( array_key_exists ( 'tag_id' , $newArray )) { // assume the other fields are present as well.
2024-02-08 01:29:34 +01:00
$tagId = ( int ) $newJournal [ 'tag_id' ];
2023-06-21 12:34:58 +02:00
2024-02-08 01:29:34 +01:00
$tagDate = null ;
2023-12-20 19:35:52 +01:00
2023-06-21 12:34:58 +02:00
try {
$tagDate = Carbon :: parse ( $newArray [ 'tag_date' ]);
} catch ( InvalidFormatException $e ) {
2023-10-29 06:33:43 +01:00
app ( 'log' ) -> debug ( sprintf ( 'Could not parse date: %s' , $e -> getMessage ()));
2023-06-21 12:34:58 +02:00
}
$existingJournal [ 'tags' ][ $tagId ] = [
2024-01-12 18:57:38 +01:00
'id' => ( int ) $newArray [ 'tag_id' ],
2023-06-21 12:34:58 +02:00
'name' => $newArray [ 'tag_name' ],
'date' => $tagDate ,
'description' => $newArray [ 'tag_description' ],
];
}
return $existingJournal ;
}
2023-05-29 13:56:55 +02:00
2023-06-21 12:34:58 +02:00
private function mergeAttachments ( array $existingJournal , TransactionJournal $newJournal ) : array
{
$newArray = $newJournal -> toArray ();
if ( array_key_exists ( 'attachment_id' , $newArray )) {
2024-02-08 01:29:34 +01:00
$attachmentId = ( int ) $newJournal [ 'attachment_id' ];
2023-05-29 13:56:55 +02:00
2023-06-21 12:34:58 +02:00
$existingJournal [ 'attachments' ][ $attachmentId ] = [
'id' => $attachmentId ,
];
}
return $existingJournal ;
2019-03-24 09:23:36 +01:00
}
2022-03-21 06:31:38 +01:00
private function parseSums ( array $groups ) : array
2019-03-24 09:23:36 +01:00
{
2022-03-21 06:31:38 +01:00
/**
2023-06-21 12:34:58 +02:00
* @ var int $groudId
2022-03-21 06:31:38 +01:00
* @ var array $group
*/
foreach ( $groups as $groudId => $group ) {
/** @var array $transaction */
foreach ( $group [ 'transactions' ] as $transaction ) {
2024-02-08 01:29:34 +01:00
$currencyId = ( int ) $transaction [ 'currency_id' ];
2023-11-28 18:57:10 +01:00
if ( null === $transaction [ 'amount' ]) {
2023-11-19 02:15:04 +01:00
throw new FireflyException ( sprintf ( 'Amount is NULL for a transaction in group #%d, please investigate.' , $groudId ));
}
2019-03-24 09:23:36 +01:00
2022-03-21 06:31:38 +01:00
// set default:
if ( ! array_key_exists ( $currencyId , $groups [ $groudId ][ 'sums' ])) {
$groups [ $groudId ][ 'sums' ][ $currencyId ][ 'currency_id' ] = $currencyId ;
$groups [ $groudId ][ 'sums' ][ $currencyId ][ 'currency_code' ] = $transaction [ 'currency_code' ];
$groups [ $groudId ][ 'sums' ][ $currencyId ][ 'currency_symbol' ] = $transaction [ 'currency_symbol' ];
$groups [ $groudId ][ 'sums' ][ $currencyId ][ 'currency_decimal_places' ] = $transaction [ 'currency_decimal_places' ];
$groups [ $groudId ][ 'sums' ][ $currencyId ][ 'amount' ] = '0' ;
}
2022-06-01 19:23:40 +02:00
$groups [ $groudId ][ 'sums' ][ $currencyId ][ 'amount' ] = bcadd ( $groups [ $groudId ][ 'sums' ][ $currencyId ][ 'amount' ], $transaction [ 'amount' ]);
2019-03-24 09:23:36 +01:00
2022-03-21 06:31:38 +01:00
if ( null !== $transaction [ 'foreign_amount' ] && null !== $transaction [ 'foreign_currency_id' ]) {
2024-02-08 01:29:34 +01:00
$currencyId = ( int ) $transaction [ 'foreign_currency_id' ];
2022-03-21 06:31:38 +01:00
// set default:
if ( ! array_key_exists ( $currencyId , $groups [ $groudId ][ 'sums' ])) {
$groups [ $groudId ][ 'sums' ][ $currencyId ][ 'currency_id' ] = $currencyId ;
$groups [ $groudId ][ 'sums' ][ $currencyId ][ 'currency_code' ] = $transaction [ 'foreign_currency_code' ];
$groups [ $groudId ][ 'sums' ][ $currencyId ][ 'currency_symbol' ] = $transaction [ 'foreign_currency_symbol' ];
$groups [ $groudId ][ 'sums' ][ $currencyId ][ 'currency_decimal_places' ] = $transaction [ 'foreign_currency_decimal_places' ];
$groups [ $groudId ][ 'sums' ][ $currencyId ][ 'amount' ] = '0' ;
2019-08-23 09:41:31 +02:00
}
2023-01-03 06:48:53 +01:00
$groups [ $groudId ][ 'sums' ][ $currencyId ][ 'amount' ] = bcadd ( $groups [ $groudId ][ 'sums' ][ $currencyId ][ 'amount' ], $transaction [ 'foreign_amount' ]);
2022-03-21 06:31:38 +01:00
}
2019-08-23 09:41:31 +02:00
}
2022-03-21 06:31:38 +01:00
}
2019-08-23 09:41:31 +02:00
2022-03-21 06:31:38 +01:00
return $groups ;
2019-08-23 09:41:31 +02:00
}
2022-03-21 06:31:38 +01:00
private function postFilterCollection ( Collection $collection ) : Collection
2019-03-30 07:09:52 +01:00
{
2022-03-27 16:03:50 +02:00
$currentCollection = $collection ;
2024-02-07 06:14:40 +01:00
$countFilters = count ( $this -> postFilters );
$countCollection = count ( $currentCollection );
if ( 0 === $countFilters && 0 === $countCollection ) {
return $currentCollection ;
}
2023-12-24 15:53:24 +01:00
app ( 'log' ) -> debug ( sprintf ( 'GroupCollector: postFilterCollection has %d filter(s) and %d transaction(s).' , count ( $this -> postFilters ), count ( $currentCollection )));
2023-12-03 07:02:23 +01:00
2022-03-27 16:03:50 +02:00
/**
2023-12-20 19:35:52 +01:00
* @ var \Closure $function
2022-03-27 16:03:50 +02:00
*/
2022-03-30 20:09:19 +02:00
foreach ( $this -> postFilters as $function ) {
2023-12-03 07:02:23 +01:00
app ( 'log' ) -> debug ( 'Applying filter...' );
2024-02-08 01:29:34 +01:00
$nextCollection = new Collection ();
2023-12-20 19:35:52 +01:00
2022-03-27 16:03:50 +02:00
// loop everything in the current collection
// and save it (or not) in the new collection.
// that new collection is the next current collection
/**
* @ var array $item
*/
2023-11-28 18:57:10 +01:00
foreach ( $currentCollection as $item ) {
$result = $function ( $item );
2022-03-27 16:03:50 +02:00
if ( false === $result ) {
2022-03-21 06:31:38 +01:00
// skip other filters, continue to next item.
2022-03-27 16:03:50 +02:00
continue ;
2022-03-21 06:31:38 +01:00
}
2024-01-01 11:31:14 +01:00
// if the result is a bool, use the unedited results.
2024-01-06 07:26:03 +01:00
if ( true === $result ) {
2024-01-01 11:31:14 +01:00
$nextCollection -> push ( $item );
}
// if the result is an array, the filter has changed what's being returned.
2024-01-06 07:26:03 +01:00
if ( is_array ( $result )) {
2024-01-01 11:31:14 +01:00
$nextCollection -> push ( $result );
}
2022-03-21 06:31:38 +01:00
}
2022-03-27 16:03:50 +02:00
$currentCollection = $nextCollection ;
2023-12-03 07:02:23 +01:00
app ( 'log' ) -> debug ( sprintf ( 'GroupCollector: postFilterCollection has %d transaction(s) left.' , count ( $currentCollection )));
2022-03-21 06:31:38 +01:00
}
2023-06-21 12:34:58 +02:00
2023-12-20 19:35:52 +01:00
return $currentCollection ;
2023-06-21 12:34:58 +02:00
}
2019-05-31 13:35:33 +02:00
/**
2022-03-21 06:31:38 +01:00
* Build the query .
2019-05-31 13:35:33 +02:00
*/
2022-03-21 06:31:38 +01:00
private function startQuery () : void
2019-05-31 13:35:33 +02:00
{
2023-12-20 19:35:52 +01:00
// app('log')->debug('GroupCollector::startQuery');
2022-03-21 06:31:38 +01:00
$this -> query = $this -> user
2023-12-20 19:35:52 +01:00
// ->transactionGroups()
// ->leftJoin('transaction_journals', 'transaction_journals.transaction_group_id', 'transaction_groups.id')
2022-03-21 06:31:38 +01:00
-> transactionJournals ()
-> leftJoin ( 'transaction_groups' , 'transaction_journals.transaction_group_id' , 'transaction_groups.id' )
2019-05-31 13:35:33 +02:00
2023-08-01 19:38:53 +02:00
// join source transaction.
-> leftJoin (
'transactions as source' ,
2023-12-21 05:07:26 +01:00
static function ( JoinClause $join ) : void {
2023-08-01 19:38:53 +02:00
$join -> on ( 'source.transaction_journal_id' , '=' , 'transaction_journals.id' )
2024-02-08 01:29:34 +01:00
-> where ( 'source.amount' , '<' , 0 )
;
2023-08-01 19:38:53 +02:00
}
)
// join destination transaction
-> leftJoin (
'transactions as destination' ,
2023-12-21 05:07:26 +01:00
static function ( JoinClause $join ) : void {
2023-08-01 19:38:53 +02:00
$join -> on ( 'destination.transaction_journal_id' , '=' , 'transaction_journals.id' )
2024-02-08 01:29:34 +01:00
-> where ( 'destination.amount' , '>' , 0 )
;
2023-08-01 19:38:53 +02:00
}
)
// left join transaction type.
-> leftJoin ( 'transaction_types' , 'transaction_types.id' , '=' , 'transaction_journals.transaction_type_id' )
-> leftJoin ( 'transaction_currencies as currency' , 'currency.id' , '=' , 'source.transaction_currency_id' )
-> leftJoin ( 'transaction_currencies as foreign_currency' , 'foreign_currency.id' , '=' , 'source.foreign_currency_id' )
-> whereNull ( 'transaction_groups.deleted_at' )
-> whereNull ( 'transaction_journals.deleted_at' )
-> whereNull ( 'source.deleted_at' )
-> whereNull ( 'destination.deleted_at' )
-> orderBy ( 'transaction_journals.date' , 'DESC' )
-> orderBy ( 'transaction_journals.order' , 'ASC' )
-> orderBy ( 'transaction_journals.id' , 'DESC' )
-> orderBy ( 'transaction_journals.description' , 'DESC' )
2024-02-08 01:29:34 +01:00
-> orderBy ( 'source.amount' , 'DESC' )
;
2023-08-01 19:38:53 +02:00
}
/**
* Build the query .
*/
private function startQueryForGroup () : void
{
2023-12-20 19:35:52 +01:00
// app('log')->debug('GroupCollector::startQuery');
2023-08-01 19:38:53 +02:00
$this -> query = $this -> userGroup
-> transactionJournals ()
-> leftJoin ( 'transaction_groups' , 'transaction_journals.transaction_group_id' , 'transaction_groups.id' )
2022-03-21 06:31:38 +01:00
// join source transaction.
-> leftJoin (
'transactions as source' ,
2023-12-21 05:07:26 +01:00
static function ( JoinClause $join ) : void {
2022-03-21 06:31:38 +01:00
$join -> on ( 'source.transaction_journal_id' , '=' , 'transaction_journals.id' )
2024-02-08 01:29:34 +01:00
-> where ( 'source.amount' , '<' , 0 )
;
2019-05-31 13:35:33 +02:00
}
2022-03-21 06:31:38 +01:00
)
// join destination transaction
-> leftJoin (
'transactions as destination' ,
2023-12-21 05:07:26 +01:00
static function ( JoinClause $join ) : void {
2022-03-21 06:31:38 +01:00
$join -> on ( 'destination.transaction_journal_id' , '=' , 'transaction_journals.id' )
2024-02-08 01:29:34 +01:00
-> where ( 'destination.amount' , '>' , 0 )
;
2019-05-31 13:35:33 +02:00
}
2022-03-21 06:31:38 +01:00
)
// left join transaction type.
-> leftJoin ( 'transaction_types' , 'transaction_types.id' , '=' , 'transaction_journals.transaction_type_id' )
-> leftJoin ( 'transaction_currencies as currency' , 'currency.id' , '=' , 'source.transaction_currency_id' )
-> leftJoin ( 'transaction_currencies as foreign_currency' , 'foreign_currency.id' , '=' , 'source.foreign_currency_id' )
-> whereNull ( 'transaction_groups.deleted_at' )
-> whereNull ( 'transaction_journals.deleted_at' )
-> whereNull ( 'source.deleted_at' )
-> whereNull ( 'destination.deleted_at' )
-> orderBy ( 'transaction_journals.date' , 'DESC' )
-> orderBy ( 'transaction_journals.order' , 'ASC' )
-> orderBy ( 'transaction_journals.id' , 'DESC' )
-> orderBy ( 'transaction_journals.description' , 'DESC' )
2024-02-07 06:14:40 +01:00
-> orderBy ( 'source.amount' , 'DESC' );
2022-03-21 06:31:38 +01:00
}
2024-02-10 08:28:59 +01:00
public function setEndRow ( int $endRow ) : self
{
$this -> endRow = $endRow ;
return $this ;
}
public function setStartRow ( int $startRow ) : self
{
$this -> startRow = $startRow ;
return $this ;
}
2019-08-17 12:09:03 +02:00
}