2015-02-06 21:23:14 +01:00
< ? php
2022-12-29 19:42:26 +01:00
2016-05-20 12:41:23 +02:00
/**
* Navigation . php
2020-02-16 13:56:52 +01:00
* Copyright ( c ) 2019 james @ firefly - iii . org
2016-05-20 12:41:23 +02:00
*
2019-10-02 06:37:26 +02:00
* This file is part of Firefly III ( https :// github . com / firefly - iii ) .
2016-10-05 06:52:15 +02: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 .
2017-10-21 08:40:00 +02:00
*
2019-10-02 06:37:26 +02:00
* This program is distributed in the hope that it will be useful ,
2017-10-21 08:40:00 +02: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 .
2017-10-21 08:40:00 +02: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 />.
2016-05-20 12:41:23 +02:00
*/
2017-04-09 07:44:22 +02:00
declare ( strict_types = 1 );
2015-02-06 21:23:14 +01:00
namespace FireflyIII\Support ;
use Carbon\Carbon ;
2015-02-22 09:46:21 +01:00
use FireflyIII\Exceptions\FireflyException ;
2023-10-29 17:41:14 +01:00
use FireflyIII\Exceptions\IntervalException ;
2019-06-21 19:10:02 +02:00
use FireflyIII\Helpers\Fiscal\FiscalHelperInterface ;
2023-07-03 00:59:01 -03:00
use FireflyIII\Support\Calendar\Calculator ;
use FireflyIII\Support\Calendar\Periodicity ;
2023-11-03 05:52:35 +01:00
use Illuminate\Support\Facades\Log ;
2025-05-27 16:57:36 +02:00
use Throwable ;
2015-02-06 21:23:14 +01:00
/**
2017-11-15 12:25:49 +01:00
* Class Navigation .
2015-02-06 21:23:14 +01:00
*/
class Navigation
{
2025-05-04 13:47:00 +02:00
private readonly Calculator $calculator ;
2023-07-03 00:59:01 -03:00
2024-03-18 20:25:30 +01:00
public function __construct ( ? Calculator $calculator = null )
2023-07-03 00:59:01 -03:00
{
2023-11-05 08:15:17 +01:00
$this -> calculator = $calculator instanceof Calculator ? $calculator : new Calculator ();
2023-07-03 00:59:01 -03:00
}
public function addPeriod ( Carbon $theDate , string $repeatFreq , int $skip = 0 ) : Carbon
2015-02-22 15:40:13 +01:00
{
2023-10-28 15:03:33 +02:00
$date = clone $theDate ;
2015-02-25 15:19:14 +01:00
$functionMap = [
2023-07-03 00:59:01 -03:00
'1D' => Periodicity :: Daily ,
'daily' => Periodicity :: Daily ,
'1W' => Periodicity :: Weekly ,
'weekly' => Periodicity :: Weekly ,
'week' => Periodicity :: Weekly ,
'1M' => Periodicity :: Monthly ,
'month' => Periodicity :: Monthly ,
'monthly' => Periodicity :: Monthly ,
'3M' => Periodicity :: Quarterly ,
'quarter' => Periodicity :: Quarterly ,
'quarterly' => Periodicity :: Quarterly ,
'6M' => Periodicity :: HalfYearly ,
'half-year' => Periodicity :: HalfYearly ,
'year' => Periodicity :: Yearly ,
'yearly' => Periodicity :: Yearly ,
'1Y' => Periodicity :: Yearly ,
'custom' => Periodicity :: Monthly , // custom? just add one month.
2023-05-19 05:43:50 +02:00
// last X periods? Jump the relevant month / quarter / year
2023-07-03 00:59:01 -03:00
'last7' => Periodicity :: Weekly ,
'last30' => Periodicity :: Monthly ,
'last90' => Periodicity :: Quarterly ,
'last365' => Periodicity :: Yearly ,
'MTD' => Periodicity :: Monthly ,
'QTD' => Periodicity :: Quarterly ,
'YTD' => Periodicity :: Yearly ,
2015-02-25 15:19:14 +01:00
];
2015-06-06 23:09:12 +02:00
2021-04-06 17:00:16 +02:00
if ( ! array_key_exists ( $repeatFreq , $functionMap )) {
2023-10-30 07:27:43 +01:00
Log :: error ( sprintf (
2025-11-26 18:43:50 +01:00
'The periodicity %s is unknown. Choose one of available periodicity: %s' ,
$repeatFreq ,
implode ( ', ' , array_keys ( $functionMap ))
));
2023-12-20 19:35:52 +01:00
2019-08-12 18:19:06 +02:00
return $theDate ;
2015-02-22 15:40:13 +01:00
}
2017-09-25 07:32:29 +02:00
2023-10-27 17:47:12 +02:00
return $this -> nextDateByInterval ( $date , $functionMap [ $repeatFreq ], $skip );
2015-02-22 15:40:13 +01:00
}
2021-05-24 08:57:02 +02:00
public function blockPeriods ( Carbon $start , Carbon $end , string $range ) : array
2018-01-14 10:48:17 +01:00
{
2018-02-09 16:47:01 +01:00
if ( $end < $start ) {
2018-04-02 14:50:17 +02:00
[ $start , $end ] = [ $end , $start ];
2018-02-09 16:47:01 +01:00
}
2025-11-26 18:43:50 +01:00
$periods = [];
2020-01-26 07:15:47 +01:00
// first, 13 periods of [range]
$loopCount = 0 ;
$loopDate = clone $end ;
$workStart = clone $loopDate ;
$workEnd = clone $loopDate ;
while ( $loopCount < 13 ) {
// make range:
2023-10-29 17:41:14 +01:00
$workStart = $this -> startOfPeriod ( $workStart , $range );
$workEnd = $this -> endOfPeriod ( $workStart , $range );
2020-01-26 07:15:47 +01:00
// make sure we don't go overboard
if ( $workEnd -> gt ( $start )) {
2018-01-14 10:48:17 +01:00
$periods [] = [
2020-01-26 07:15:47 +01:00
'start' => clone $workStart ,
'end' => clone $workEnd ,
2018-01-14 10:48:17 +01:00
'period' => $range ,
];
}
2020-01-26 07:15:47 +01:00
// skip to the next period:
$workStart -> subDay () -> startOfDay ();
2023-12-20 19:35:52 +01:00
++ $loopCount ;
2018-01-14 10:48:17 +01:00
}
2020-01-26 07:15:47 +01:00
// if $workEnd is still before $start, continue on a yearly basis:
$loopCount = 0 ;
if ( $workEnd -> gt ( $start )) {
while ( $workEnd -> gt ( $start ) && $loopCount < 20 ) {
// make range:
2025-11-26 06:54:11 +01:00
$workStart = Facades\Navigation :: startOfPeriod ( $workStart , '1Y' );
$workEnd = Facades\Navigation :: endOfPeriod ( $workStart , '1Y' );
2018-01-14 10:48:17 +01:00
2020-01-26 07:15:47 +01:00
// make sure we don't go overboard
if ( $workEnd -> gt ( $start )) {
$periods [] = [
'start' => clone $workStart ,
'end' => clone $workEnd ,
'period' => '1Y' ,
];
}
// skip to the next period:
$workStart -> subDay () -> startOfDay ();
2023-12-20 19:35:52 +01:00
++ $loopCount ;
2018-01-14 10:48:17 +01:00
}
}
2021-04-06 17:00:16 +02:00
2018-01-14 10:48:17 +01:00
return $periods ;
}
2025-09-26 06:05:37 +02:00
public function daysUntilEndOfMonth ( Carbon $date ) : int
2023-06-21 12:34:58 +02:00
{
2025-09-26 06:05:37 +02:00
$endOfMonth = $date -> copy () -> endOfMonth ();
2024-03-17 12:26:56 +01:00
2025-09-26 06:05:37 +02:00
return ( int ) $date -> diffInDays ( $endOfMonth , true );
}
2024-03-17 12:26:56 +01:00
2025-09-26 06:05:37 +02:00
public function diffInPeriods ( string $period , int $skip , Carbon $beginning , Carbon $end ) : int
{
Log :: debug ( sprintf (
2025-11-26 18:43:50 +01:00
'diffInPeriods: %s (skip: %d), between %s and %s.' ,
$period ,
$skip ,
$beginning -> format ( 'Y-m-d' ),
$end -> format ( 'Y-m-d' )
));
$map = [
2025-09-26 06:05:37 +02:00
'daily' => 'diffInDays' ,
'weekly' => 'diffInWeeks' ,
'monthly' => 'diffInMonths' ,
'quarterly' => 'diffInMonths' ,
'half-year' => 'diffInMonths' ,
'yearly' => 'diffInYears' ,
];
if ( ! array_key_exists ( $period , $map )) {
Log :: warning ( sprintf ( 'No diffInPeriods for period "%s"' , $period ));
2023-06-21 12:34:58 +02:00
2025-09-26 06:05:37 +02:00
return 1 ;
2023-06-21 12:34:58 +02:00
}
2025-11-26 18:43:50 +01:00
$func = $map [ $period ];
2025-09-26 06:05:37 +02:00
// first do the diff
$floatDiff = $beginning -> { $func }( $end , true ); // @phpstan-ignore-line
2023-06-21 12:34:58 +02:00
2025-09-26 06:05:37 +02:00
// then correct for quarterly or half-year
if ( 'quarterly' === $period ) {
Log :: debug ( sprintf ( 'Q: Corrected %f to %f' , $floatDiff , $floatDiff / 3 ));
$floatDiff /= 3 ;
2023-06-21 12:34:58 +02:00
}
2025-09-26 06:05:37 +02:00
if ( 'half-year' === $period ) {
Log :: debug ( sprintf ( 'H: Corrected %f to %f' , $floatDiff , $floatDiff / 6 ));
$floatDiff /= 6 ;
2023-06-21 12:34:58 +02:00
}
2025-09-26 06:05:37 +02:00
// then do ceil()
2025-11-26 18:43:50 +01:00
$diff = ceil ( $floatDiff );
2024-03-18 01:30:56 +01:00
2025-09-26 06:05:37 +02:00
Log :: debug ( sprintf ( 'Diff is %f periods (%d rounded up)' , $floatDiff , $diff ));
if ( $skip > 0 ) {
$parameter = $skip + 1 ;
$diff = ceil ( $diff / $parameter ) * $parameter ;
Log :: debug ( sprintf (
2025-11-26 18:43:50 +01:00
'diffInPeriods: skip is %d, so param is %d, and diff becomes %d' ,
$skip ,
$parameter ,
$diff
));
2023-06-21 12:34:58 +02:00
}
2025-09-26 06:05:37 +02:00
return ( int ) $diff ;
2023-06-21 12:34:58 +02:00
}
2021-05-24 08:57:02 +02:00
public function endOfPeriod ( Carbon $end , string $repeatFreq ) : Carbon
2015-02-25 15:19:14 +01:00
{
2025-11-26 18:43:50 +01:00
$currentEnd = clone $end ;
2024-12-21 12:27:07 +01:00
// Log::debug(sprintf('Now in endOfPeriod("%s", "%s").', $currentEnd->toIso8601String(), $repeatFreq));
2015-02-25 15:19:14 +01:00
$functionMap = [
2019-03-02 08:05:15 +01:00
'1D' => 'endOfDay' ,
'daily' => 'endOfDay' ,
'1W' => 'addWeek' ,
'week' => 'addWeek' ,
'weekly' => 'addWeek' ,
'1M' => 'addMonth' ,
'month' => 'addMonth' ,
'monthly' => 'addMonth' ,
2024-03-31 16:51:53 +02:00
'3M' => 'addQuarter' ,
'quarter' => 'addQuarter' ,
'quarterly' => 'addQuarter' ,
2019-03-02 08:05:15 +01:00
'6M' => 'addMonths' ,
'half-year' => 'addMonths' ,
2020-03-14 10:25:12 +01:00
'half_year' => 'addMonths' ,
2019-03-02 08:05:15 +01:00
'year' => 'addYear' ,
'yearly' => 'addYear' ,
'1Y' => 'addYear' ,
2015-02-25 15:19:14 +01:00
];
2024-03-31 16:51:53 +02:00
$modifierMap = [ 'half-year' => 6 , 'half_year' => 6 , '6M' => 6 ];
2024-01-01 14:43:56 +01:00
$subDay = [ 'week' , 'weekly' , '1W' , 'month' , 'monthly' , '1M' , '3M' , 'quarter' , 'quarterly' , '6M' , 'half-year' , 'half_year' , '1Y' , 'year' , 'yearly' ];
2015-02-25 15:19:14 +01:00
2017-11-15 12:25:49 +01:00
if ( 'custom' === $repeatFreq ) {
2024-02-03 10:08:34 +01:00
// if the repeat frequency is "custom", use the current session start/end to see how large the range is,
// and use that to "add" another period.
// if there is no session data available use "30 days" as a default.
$diffInDays = 30 ;
if ( null !== session ( 'start' ) && null !== session ( 'end' )) {
Log :: debug ( 'Session data available.' );
2023-12-20 19:35:52 +01:00
2024-02-03 10:08:34 +01:00
/** @var Carbon $tStart */
2025-11-26 18:43:50 +01:00
$tStart = session ( 'start' , today ( config ( 'app.timezone' )) -> startOfMonth ());
2024-02-03 10:08:34 +01:00
/** @var Carbon $tEnd */
$tEnd = session ( 'end' , today ( config ( 'app.timezone' )) -> endOfMonth ());
2025-09-26 06:05:37 +02:00
$diffInDays = ( int ) $tStart -> diffInDays ( $tEnd , true );
2024-02-03 10:08:34 +01:00
}
Log :: debug ( sprintf ( 'Diff in days is %d' , $diffInDays ));
2016-02-05 07:16:55 +01:00
$currentEnd -> addDays ( $diffInDays );
2025-11-26 18:35:56 +01:00
// add sanity check.
if ( $currentEnd -> lt ( $end )) {
throw new FireflyException ( sprintf ( '[a] endOfPeriod(%s, %s) failed, because it resulted in %s.' , $end -> toW3cString (), $repeatFreq , $currentEnd -> toW3cString ()));
}
2016-02-05 07:16:55 +01:00
return $currentEnd ;
}
2024-08-19 05:06:45 +02:00
if ( 'MTD' === $repeatFreq ) {
2024-08-16 09:39:29 +02:00
$today = today ();
2024-08-19 05:06:45 +02:00
if ( $today -> isSameMonth ( $end )) {
2025-11-26 18:35:56 +01:00
$res = $today -> endOfDay () -> milli ( 0 );
// add sanity check.
2025-11-26 18:43:50 +01:00
if ( $res -> lt ( $end )) {
2025-11-26 18:35:56 +01:00
throw new FireflyException ( sprintf ( '[b] endOfPeriod(%s, %s) failed, because it resulted in %s.' , $end -> toW3cString (), $repeatFreq , $res -> toW3cString ()));
}
2025-11-26 18:43:50 +01:00
2025-11-26 18:35:56 +01:00
return $res ;
2024-08-16 09:39:29 +02:00
}
2024-08-19 05:06:45 +02:00
2025-11-26 18:35:56 +01:00
// add sanity check.
if ( $currentEnd -> lt ( $end )) {
throw new FireflyException ( sprintf ( '[c] endOfPeriod(%s, %s) failed, because it resulted in %s.' , $end -> toW3cString (), $repeatFreq , $currentEnd -> toW3cString ()));
}
2025-11-26 18:43:50 +01:00
2024-08-16 09:39:29 +02:00
return $end -> endOfMonth ();
}
2023-05-06 15:29:29 +02:00
2025-11-26 18:43:50 +01:00
$result = match ( $repeatFreq ) {
2023-07-15 16:02:42 +02:00
'last7' => $currentEnd -> addDays ( 7 ) -> startOfDay (),
'last30' => $currentEnd -> addDays ( 30 ) -> startOfDay (),
'last90' => $currentEnd -> addDays ( 90 ) -> startOfDay (),
2023-05-06 15:29:29 +02:00
'last365' => $currentEnd -> addDays ( 365 ) -> startOfDay (),
2023-07-15 16:02:42 +02:00
'MTD' => $currentEnd -> startOfMonth () -> startOfDay (),
'QTD' => $currentEnd -> firstOfQuarter () -> startOfDay (),
'YTD' => $currentEnd -> startOfYear () -> startOfDay (),
default => null ,
2023-05-06 15:29:29 +02:00
};
if ( null !== $result ) {
2025-11-26 18:35:56 +01:00
// add sanity check.
if ( $currentEnd -> lt ( $end )) {
throw new FireflyException ( sprintf ( '[d] endOfPeriod(%s, %s) failed, because it resulted in %s.' , $end -> toW3cString (), $repeatFreq , $currentEnd -> toW3cString ()));
}
2023-05-06 15:29:29 +02:00
return $result ;
}
unset ( $result );
2021-04-06 17:00:16 +02:00
if ( ! array_key_exists ( $repeatFreq , $functionMap )) {
2023-10-30 07:27:43 +01:00
Log :: error ( sprintf ( 'Cannot do endOfPeriod for $repeat_freq "%s"' , $repeatFreq ));
2019-08-12 18:19:06 +02:00
2025-11-26 18:35:56 +01:00
// add sanity check.
if ( $currentEnd -> lt ( $end )) {
throw new FireflyException ( sprintf ( '[e] endOfPeriod(%s, %s) failed, because it resulted in %s.' , $end -> toW3cString (), $repeatFreq , $currentEnd -> toW3cString ()));
}
2019-08-12 18:19:06 +02:00
return $end ;
2015-02-25 15:19:14 +01:00
}
2025-11-26 18:43:50 +01:00
$function = $functionMap [ $repeatFreq ];
2018-06-02 18:19:35 +02:00
2021-04-06 17:00:16 +02:00
if ( array_key_exists ( $repeatFreq , $modifierMap )) {
2025-09-26 06:05:37 +02:00
$currentEnd -> { $function }( $modifierMap [ $repeatFreq ]) -> milli ( 0 ); // @phpstan-ignore-line
2019-06-21 19:10:02 +02:00
if ( in_array ( $repeatFreq , $subDay , true )) {
2016-05-20 17:53:03 +02:00
$currentEnd -> subDay ();
}
2025-09-26 06:05:37 +02:00
$currentEnd -> endOfDay () -> milli ( 0 );
2016-05-20 17:53:03 +02:00
2025-11-26 18:35:56 +01:00
// add sanity check.
if ( $currentEnd -> lt ( $end )) {
throw new FireflyException ( sprintf ( '[f] endOfPeriod(%s, %s) failed, because it resulted in %s.' , $end -> toW3cString (), $repeatFreq , $currentEnd -> toW3cString ()));
}
2016-05-20 17:53:03 +02:00
return $currentEnd ;
2015-02-25 15:19:14 +01:00
}
2023-12-20 19:35:52 +01:00
$currentEnd -> { $function }(); // @phpstan-ignore-line
2025-09-26 06:05:37 +02:00
$currentEnd -> endOfDay () -> milli ( 0 );
2019-06-21 19:10:02 +02:00
if ( in_array ( $repeatFreq , $subDay , true )) {
2015-02-25 15:19:14 +01:00
$currentEnd -> subDay ();
}
2024-12-21 12:27:07 +01:00
// Log::debug(sprintf('Final result: %s', $currentEnd->toIso8601String()));
2015-02-25 15:19:14 +01:00
2025-11-26 18:35:56 +01:00
// add sanity check.
if ( $currentEnd -> lt ( $end )) {
throw new FireflyException ( sprintf ( '[g] endOfPeriod(%s, %s) failed, because it resulted in %s.' , $end -> toW3cString (), $repeatFreq , $currentEnd -> toW3cString ()));
}
2015-02-25 15:19:14 +01:00
return $currentEnd ;
}
2015-02-22 15:40:13 +01:00
2017-07-23 19:06:24 +02:00
public function endOfX ( Carbon $theCurrentEnd , string $repeatFreq , ? Carbon $maxDate ) : Carbon
2015-02-27 11:02:08 +01:00
{
$functionMap = [
2015-09-25 17:28:42 +02:00
'1D' => 'endOfDay' ,
2015-02-27 11:02:08 +01:00
'daily' => 'endOfDay' ,
2015-09-25 17:28:42 +02:00
'1W' => 'endOfWeek' ,
2015-02-27 11:02:08 +01:00
'week' => 'endOfWeek' ,
'weekly' => 'endOfWeek' ,
'month' => 'endOfMonth' ,
2015-09-25 16:00:14 +02:00
'1M' => 'endOfMonth' ,
2015-02-27 11:02:08 +01:00
'monthly' => 'endOfMonth' ,
2015-09-25 17:28:42 +02:00
'3M' => 'lastOfQuarter' ,
2015-02-27 11:02:08 +01:00
'quarter' => 'lastOfQuarter' ,
'quarterly' => 'lastOfQuarter' ,
2015-09-25 17:28:42 +02:00
'1Y' => 'endOfYear' ,
2015-02-27 11:02:08 +01:00
'year' => 'endOfYear' ,
'yearly' => 'endOfYear' ,
];
2025-11-26 18:43:50 +01:00
$currentEnd = clone $theCurrentEnd ;
2015-02-27 11:02:08 +01:00
2021-04-06 17:00:16 +02:00
if ( array_key_exists ( $repeatFreq , $functionMap )) {
2015-02-27 11:02:08 +01:00
$function = $functionMap [ $repeatFreq ];
2023-12-20 19:35:52 +01:00
$currentEnd -> { $function }(); // @phpstan-ignore-line
2015-02-27 11:02:08 +01:00
}
2015-06-29 09:14:39 +02:00
2025-05-27 17:06:15 +02:00
if ( $maxDate instanceof Carbon && $currentEnd > $maxDate ) {
2015-02-27 11:02:08 +01:00
return clone $maxDate ;
}
return $currentEnd ;
}
2023-02-22 18:14:14 +01:00
/**
* Returns the user ' s view range and if necessary , corrects the dynamic view
* range to a normal range .
*/
public function getViewRange ( bool $correct ) : string
{
2025-01-04 08:42:06 +01:00
$range = app ( 'preferences' ) -> get ( 'viewRange' , '1M' ) -> data ? ? '1M' ;
2023-11-28 05:31:26 +01:00
if ( is_array ( $range )) {
$range = '1M' ;
}
2025-09-26 06:05:37 +02:00
$range = ( string ) $range ;
2023-02-22 18:14:14 +01:00
if ( ! $correct ) {
return $range ;
}
2023-12-20 19:35:52 +01:00
2025-05-04 13:47:00 +02:00
return match ( $range ) {
2025-05-04 17:41:26 +02:00
'last7' => '1W' ,
'last30' , 'MTD' => '1M' ,
'last90' , 'QTD' => '3M' ,
2025-05-04 13:47:00 +02:00
'last365' , 'YTD' => '1Y' ,
2025-05-04 17:41:26 +02:00
default => $range ,
2025-05-04 13:47:00 +02:00
};
2023-02-22 18:14:14 +01:00
}
2016-11-19 13:37:44 +01:00
/**
2022-03-29 15:10:05 +02:00
* @ throws FireflyException
2016-11-19 13:37:44 +01:00
*/
public function listOfPeriods ( Carbon $start , Carbon $end ) : array
{
2025-11-26 18:43:50 +01:00
$locale = app ( 'steam' ) -> getLocale ();
2016-11-19 13:37:44 +01:00
// define period to increment
$increment = 'addDay' ;
2018-01-25 18:41:27 +01:00
$format = $this -> preferredCarbonFormat ( $start , $end );
2025-09-26 06:05:37 +02:00
$displayFormat = ( string ) trans ( 'config.month_and_day_js' , [], $locale );
2024-04-21 17:23:16 +02:00
$diff = $start -> diffInMonths ( $end , true );
2016-11-19 13:37:44 +01:00
// increment by month (for year)
2025-08-16 14:10:24 +02:00
if ( $diff >= 1.0001 && $diff < 12.001 ) {
2016-11-19 13:37:44 +01:00
$increment = 'addMonth' ;
2025-09-26 06:05:37 +02:00
$displayFormat = ( string ) trans ( 'config.month_js' );
2016-11-19 13:37:44 +01:00
}
2024-03-17 12:00:28 +01:00
// increment by year (for multi-year)
2024-04-21 07:07:06 +02:00
if ( $diff >= 12.0001 ) {
2016-11-19 13:37:44 +01:00
$increment = 'addYear' ;
2025-09-26 06:05:37 +02:00
$displayFormat = ( string ) trans ( 'config.year_js' );
2016-11-19 13:37:44 +01:00
}
2025-11-26 18:43:50 +01:00
$begin = clone $start ;
$entries = [];
2016-11-19 13:37:44 +01:00
while ( $begin < $end ) {
$formatted = $begin -> format ( $format );
2022-03-27 20:24:13 +02:00
$displayed = $begin -> isoFormat ( $displayFormat );
2016-11-19 13:37:44 +01:00
$entries [ $formatted ] = $displayed ;
2023-12-20 19:35:52 +01:00
$begin -> { $increment }(); // @phpstan-ignore-line
2016-11-19 13:37:44 +01:00
}
2020-01-25 23:29:26 +01:00
2016-11-19 13:37:44 +01:00
return $entries ;
}
2025-09-26 06:05:37 +02:00
public function nextDateByInterval ( Carbon $epoch , Periodicity $periodicity , int $skipInterval = 0 ) : Carbon
2023-06-21 12:34:58 +02:00
{
2025-09-26 06:05:37 +02:00
try {
return $this -> calculator -> nextDateByInterval ( $epoch , $periodicity , $skipInterval );
} catch ( IntervalException $exception ) {
Log :: warning ( $exception -> getMessage (), [ 'exception' => $exception ]);
} catch ( Throwable $exception ) {
Log :: error ( $exception -> getMessage (), [ 'exception' => $exception ]);
2023-06-21 12:34:58 +02:00
}
2025-09-26 06:05:37 +02:00
Log :: debug (
'Any error occurred to calculate the next date.' ,
[ 'date' => $epoch , 'periodicity' => $periodicity -> name , 'skipInterval' => $skipInterval ]
);
2023-06-21 12:34:58 +02:00
2025-09-26 06:05:37 +02:00
return $epoch ;
2023-06-21 12:34:58 +02:00
}
2021-05-24 08:57:02 +02:00
public function periodShow ( Carbon $theDate , string $repeatFrequency ) : string
2015-02-25 15:19:14 +01:00
{
2017-11-01 15:34:08 +01:00
$date = clone $theDate ;
2015-02-25 15:19:14 +01:00
$formatMap = [
2025-11-26 18:35:56 +01:00
'1D' => ( string ) trans ( 'config.specific_day_js' ),
'daily' => ( string ) trans ( 'config.specific_day_js' ),
'custom' => ( string ) trans ( 'config.specific_day_js' ),
'1W' => ( string ) trans ( 'config.week_in_year_js' ),
'week' => ( string ) trans ( 'config.week_in_year_js' ),
'weekly' => ( string ) trans ( 'config.week_in_year_js' ),
'1M' => ( string ) trans ( 'config.month_js' ),
'MTD' => ( string ) trans ( 'config.month_js' ),
'month' => ( string ) trans ( 'config.month_js' ),
'monthly' => ( string ) trans ( 'config.month_js' ),
'1Y' => ( string ) trans ( 'config.year_js' ),
'YTD' => ( string ) trans ( 'config.year_js' ),
'year' => ( string ) trans ( 'config.year_js' ),
'yearly' => ( string ) trans ( 'config.year_js' ),
'6M' => ( string ) trans ( 'config.half_year_js' ),
'last7' => ( string ) trans ( 'config.specific_day_js' ),
'last30' => ( string ) trans ( 'config.month_js' ),
'last90' => ( string ) trans ( 'config.month_js' ),
'last365' => ( string ) trans ( 'config.year_js' ),
'QTD' => ( string ) trans ( 'config.month_js' ),
2015-02-25 15:19:14 +01:00
];
2015-05-25 21:17:36 +02:00
2021-04-06 17:00:16 +02:00
if ( array_key_exists ( $repeatFrequency , $formatMap )) {
2023-11-05 08:15:17 +01:00
return $date -> isoFormat ( $formatMap [ $repeatFrequency ]);
2015-02-25 15:19:14 +01:00
}
2017-11-15 12:25:49 +01:00
if ( '3M' === $repeatFrequency || 'quarter' === $repeatFrequency ) {
2017-11-01 15:34:08 +01:00
$quarter = ceil ( $theDate -> month / 3 );
return sprintf ( 'Q%d %d' , $quarter , $theDate -> year );
}
// special formatter for quarter of year
2023-10-30 07:27:43 +01:00
Log :: error ( sprintf ( 'No date formats for frequency "%s"!' , $repeatFrequency ));
2025-09-26 19:43:39 +02:00
2025-09-26 06:05:37 +02:00
throw new FireflyException ( sprintf ( 'No date formats for frequency "%s"!' , $repeatFrequency ));
2015-02-25 15:19:14 +01:00
}
2025-09-26 06:05:37 +02:00
/**
* If the date difference between start and end is less than a month , method returns " Y-m-d " . If the difference is
* less than a year , method returns " Y-m " . If the date difference is larger , method returns " Y " .
*/
public function preferredCarbonFormat ( Carbon $start , Carbon $end ) : string
{
$format = 'Y-m-d' ;
$diff = $start -> diffInMonths ( $end , true );
// Log::debug(sprintf('preferredCarbonFormat(%s, %s) = %f', $start->format('Y-m-d'), $end->format('Y-m-d'), $diff));
if ( $diff >= 1.001 && $diff < 12.001 ) {
// Log::debug(sprintf('Return Y-m because %s', $diff));
$format = 'Y-m' ;
}
if ( $diff >= 12.001 ) {
// Log::debug(sprintf('Return Y because %s', $diff));
return 'Y' ;
}
return $format ;
}
2023-08-01 09:27:39 +02:00
/**
* Same as preferredCarbonFormat but by string
*/
public function preferredCarbonFormatByPeriod ( string $period ) : string
{
return match ( $period ) {
default => 'Y-m-d' ,
2023-12-20 19:35:52 +01:00
// '1D' => 'Y-m-d',
2023-08-01 09:27:39 +02:00
'1W' => '\WW,Y' ,
'1M' => 'Y-m' ,
'3M' , '6M' => '\QQ,Y' ,
'1Y' => 'Y' ,
};
}
2023-05-29 13:56:55 +02:00
/**
2023-06-21 12:34:58 +02:00
* If the date difference between start and end is less than a month , method returns trans ( config . month_and_day ) .
* If the difference is less than a year , method returns " config.month " . If the date difference is larger , method
* returns " config.year " .
2016-11-26 08:41:15 +01:00
*/
2016-12-30 13:47:23 +01:00
public function preferredCarbonLocalizedFormat ( Carbon $start , Carbon $end ) : string
2016-11-26 08:41:15 +01:00
{
2020-04-19 06:51:40 +02:00
$locale = app ( 'steam' ) -> getLocale ();
2025-08-05 11:02:26 +02:00
$diff = $start -> diffInMonths ( $end , true );
2025-08-16 14:10:24 +02:00
if ( $diff >= 1.001 && $diff < 12.001 ) {
2025-09-26 06:05:37 +02:00
return ( string ) trans ( 'config.month_js' , [], $locale );
2016-11-26 08:41:15 +01:00
}
2025-08-05 11:02:26 +02:00
if ( $diff >= 12.001 ) {
2025-09-26 06:05:37 +02:00
return ( string ) trans ( 'config.year_js' , [], $locale );
2016-11-26 08:41:15 +01:00
}
2016-12-30 13:47:23 +01:00
2025-09-26 06:05:37 +02:00
return ( string ) trans ( 'config.month_and_day_js' , [], $locale );
2016-12-15 13:47:28 +01:00
}
/**
2023-06-21 12:34:58 +02:00
* If the date difference between start and end is less than a month , method returns " endOfDay " . If the difference
* is less than a year , method returns " endOfMonth " . If the date difference is larger , method returns " endOfYear " .
2016-12-15 13:47:28 +01:00
*/
2016-12-30 13:47:23 +01:00
public function preferredEndOfPeriod ( Carbon $start , Carbon $end ) : string
2016-12-15 13:47:28 +01:00
{
2025-08-05 13:53:33 +02:00
$diff = $start -> diffInMonths ( $end , true );
2025-08-16 14:10:24 +02:00
if ( $diff >= 1.001 && $diff < 12.001 ) {
2025-05-27 17:06:15 +02:00
return 'endOfMonth' ;
2016-12-15 13:47:28 +01:00
}
2025-08-05 11:02:26 +02:00
if ( $diff >= 12.001 ) {
2025-05-27 17:06:15 +02:00
return 'endOfYear' ;
2016-12-15 13:47:28 +01:00
}
2016-11-26 08:41:15 +01:00
2025-05-27 17:06:15 +02:00
return 'endOfDay' ;
2016-11-26 08:41:15 +01:00
}
/**
2023-06-21 12:34:58 +02:00
* If the date difference between start and end is less than a month , method returns " 1D " . If the difference is
* less than a year , method returns " 1M " . If the date difference is larger , method returns " 1Y " .
2016-11-26 08:41:15 +01:00
*/
public function preferredRangeFormat ( Carbon $start , Carbon $end ) : string
{
2025-08-05 13:53:33 +02:00
$diff = $start -> diffInMonths ( $end , true );
2025-08-16 14:10:24 +02:00
if ( $diff >= 1.001 && $diff < 12.001 ) {
2025-05-27 17:06:15 +02:00
return '1M' ;
2016-11-26 08:41:15 +01:00
}
2025-08-05 11:02:26 +02:00
if ( $diff >= 12.001 ) {
2025-05-27 17:06:15 +02:00
return '1Y' ;
2016-11-26 08:41:15 +01:00
}
2025-05-27 17:06:15 +02:00
return '1D' ;
2016-11-26 08:41:15 +01:00
}
/**
2023-06-21 12:34:58 +02:00
* If the date difference between start and end is less than a month , method returns " %Y-%m-%d " . If the difference
* is less than a year , method returns " %Y-%m " . If the date difference is larger , method returns " %Y " .
2016-11-26 08:41:15 +01:00
*/
public function preferredSqlFormat ( Carbon $start , Carbon $end ) : string
{
2025-08-05 13:53:33 +02:00
$diff = $start -> diffInMonths ( $end , true );
2025-08-16 14:10:24 +02:00
if ( $diff >= 1.001 && $diff < 12.001 ) {
2025-05-27 17:06:15 +02:00
return '%Y-%m' ;
2016-11-26 08:41:15 +01:00
}
2025-08-05 11:02:26 +02:00
if ( $diff >= 12.001 ) {
2025-05-27 17:06:15 +02:00
return '%Y' ;
2016-11-26 08:41:15 +01:00
}
2025-05-27 17:06:15 +02:00
return '%Y-%m-%d' ;
2016-11-26 08:41:15 +01:00
}
2025-09-26 06:05:37 +02:00
public function startOfPeriod ( Carbon $theDate , string $repeatFreq ) : Carbon
{
2025-11-26 18:43:50 +01:00
$date = clone $theDate ;
2025-09-26 06:05:37 +02:00
// Log::debug(sprintf('Now in startOfPeriod("%s", "%s")', $date->toIso8601String(), $repeatFreq));
2025-11-26 18:43:50 +01:00
$functionMap = [
2025-09-26 06:05:37 +02:00
'1D' => 'startOfDay' ,
'daily' => 'startOfDay' ,
'1W' => 'startOfWeek' ,
'week' => 'startOfWeek' ,
'weekly' => 'startOfWeek' ,
'month' => 'startOfMonth' ,
'1M' => 'startOfMonth' ,
'monthly' => 'startOfMonth' ,
'3M' => 'firstOfQuarter' ,
'quarter' => 'firstOfQuarter' ,
'quarterly' => 'firstOfQuarter' ,
'year' => 'startOfYear' ,
'yearly' => 'startOfYear' ,
'1Y' => 'startOfYear' ,
'MTD' => 'startOfMonth' ,
];
$parameterMap = [
'startOfWeek' => [ Carbon :: MONDAY ],
];
if ( array_key_exists ( $repeatFreq , $functionMap )) {
$function = $functionMap [ $repeatFreq ];
// Log::debug(sprintf('Function is ->%s()', $function));
if ( array_key_exists ( $function , $parameterMap )) {
// Log::debug(sprintf('Parameter map, function becomes ->%s(%s)', $function, implode(', ', $parameterMap[$function])));
$date -> { $function }( $parameterMap [ $function ][ 0 ]); // @phpstan-ignore-line
// Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
return $date ;
}
$date -> { $function }(); // @phpstan-ignore-line
// Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
return $date ;
}
if ( 'half-year' === $repeatFreq || '6M' === $repeatFreq ) {
$skipTo = $date -> month > 7 ? 6 : 0 ;
$date -> startOfYear () -> addMonths ( $skipTo );
// Log::debug(sprintf('Custom call for "%s": addMonths(%d)', $repeatFreq, $skipTo));
// Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
return $date ;
}
2025-11-26 18:43:50 +01:00
$result = match ( $repeatFreq ) {
2025-09-26 06:05:37 +02:00
'last7' => $date -> subDays ( 7 ) -> startOfDay (),
'last30' => $date -> subDays ( 30 ) -> startOfDay (),
'last90' => $date -> subDays ( 90 ) -> startOfDay (),
'last365' => $date -> subDays ( 365 ) -> startOfDay (),
'MTD' => $date -> startOfMonth () -> startOfDay (),
'QTD' => $date -> firstOfQuarter () -> startOfDay (),
'YTD' => $date -> startOfYear () -> startOfDay (),
default => null ,
};
if ( null !== $result ) {
// Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
return $result ;
}
if ( 'custom' === $repeatFreq ) {
// Log::debug(sprintf('Custom, result is "%s"', $date->toIso8601String()));
return $date ; // the date is already at the start.
}
Log :: error ( sprintf ( 'Cannot do startOfPeriod for $repeat_freq "%s"' , $repeatFreq ));
return $theDate ;
}
2023-05-29 13:56:55 +02:00
/**
2021-05-24 08:57:02 +02:00
* @ throws FireflyException
2015-03-29 21:27:51 +02:00
*/
2024-03-18 20:25:30 +01:00
public function subtractPeriod ( Carbon $theDate , string $repeatFreq , ? int $subtract = null ) : Carbon
2015-03-29 21:27:51 +02:00
{
2023-12-10 06:45:59 +01:00
$subtract ? ? = 1 ;
2025-11-26 18:43:50 +01:00
$date = clone $theDate ;
2015-09-25 17:28:42 +02:00
// 1D 1W 1M 3M 6M 1Y
2015-03-29 21:27:51 +02:00
$functionMap = [
2015-09-25 17:28:42 +02:00
'1D' => 'subDays' ,
2015-03-29 21:27:51 +02:00
'daily' => 'subDays' ,
'week' => 'subWeeks' ,
2015-09-25 17:28:42 +02:00
'1W' => 'subWeeks' ,
2015-03-29 21:27:51 +02:00
'weekly' => 'subWeeks' ,
'month' => 'subMonths' ,
2015-09-25 16:00:14 +02:00
'1M' => 'subMonths' ,
2015-03-29 21:27:51 +02:00
'monthly' => 'subMonths' ,
'year' => 'subYears' ,
2016-02-05 06:56:10 +01:00
'1Y' => 'subYears' ,
2015-03-29 21:27:51 +02:00
'yearly' => 'subYears' ,
];
$modifierMap = [
'quarter' => 3 ,
2016-02-05 06:56:10 +01:00
'3M' => 3 ,
2015-03-29 21:27:51 +02:00
'quarterly' => 3 ,
'half-year' => 6 ,
2016-02-05 06:56:10 +01:00
'6M' => 6 ,
2015-03-29 21:27:51 +02:00
];
2021-04-06 17:00:16 +02:00
if ( array_key_exists ( $repeatFreq , $functionMap )) {
2015-03-29 21:27:51 +02:00
$function = $functionMap [ $repeatFreq ];
2023-12-20 19:35:52 +01:00
$date -> { $function }( $subtract ); // @phpstan-ignore-line
2015-03-29 21:27:51 +02:00
return $date ;
}
2021-04-06 17:00:16 +02:00
if ( array_key_exists ( $repeatFreq , $modifierMap )) {
2018-03-29 19:01:47 +02:00
$subtract *= $modifierMap [ $repeatFreq ];
2015-03-29 21:27:51 +02:00
$date -> subMonths ( $subtract );
2017-12-29 09:05:35 +01:00
2015-03-29 21:27:51 +02:00
return $date ;
}
2016-02-05 07:21:51 +01:00
// a custom range requires the session start
// and session end to calculate the difference in days.
// this is then subtracted from $theDate (* $subtract).
2017-11-15 12:25:49 +01:00
if ( 'custom' === $repeatFreq ) {
2016-02-05 07:21:51 +01:00
/** @var Carbon $tStart */
2025-11-26 18:43:50 +01:00
$tStart = session ( 'start' , today ( config ( 'app.timezone' )) -> startOfMonth ());
2023-12-20 19:35:52 +01:00
2016-02-05 07:21:51 +01:00
/** @var Carbon $tEnd */
2023-02-11 07:36:45 +01:00
$tEnd = session ( 'end' , today ( config ( 'app.timezone' )) -> endOfMonth ());
2025-09-26 06:05:37 +02:00
$diffInDays = ( int ) $tStart -> diffInDays ( $tEnd , true );
2016-02-05 07:21:51 +01:00
$date -> subDays ( $diffInDays * $subtract );
2021-04-06 17:00:16 +02:00
2016-02-05 07:21:51 +01:00
return $date ;
}
2023-12-20 19:35:52 +01:00
2022-04-03 16:23:49 +02:00
switch ( $repeatFreq ) {
default :
break ;
2023-12-20 19:35:52 +01:00
2022-10-30 14:24:37 +01:00
case 'last7' :
2022-11-02 05:02:09 +01:00
$date -> subDays ( 7 );
2023-12-20 19:35:52 +01:00
2022-11-02 05:02:09 +01:00
return $date ;
2023-12-20 19:35:52 +01:00
2022-10-30 14:24:37 +01:00
case 'last30' :
2022-11-02 05:02:09 +01:00
$date -> subDays ( 30 );
2023-12-20 19:35:52 +01:00
2022-11-02 05:02:09 +01:00
return $date ;
2023-12-20 19:35:52 +01:00
2022-04-03 16:23:49 +02:00
case 'last90' :
$date -> subDays ( 90 );
2023-12-20 19:35:52 +01:00
2022-04-03 16:23:49 +02:00
return $date ;
2023-12-20 19:35:52 +01:00
2022-04-03 16:23:49 +02:00
case 'last365' :
$date -> subDays ( 365 );
2023-12-20 19:35:52 +01:00
2022-04-03 16:23:49 +02:00
return $date ;
2023-12-20 19:35:52 +01:00
2022-04-03 16:23:49 +02:00
case 'YTD' :
$date -> subYear ();
2023-12-20 19:35:52 +01:00
2022-04-03 16:23:49 +02:00
return $date ;
2023-12-20 19:35:52 +01:00
2022-04-03 16:23:49 +02:00
case 'QTD' :
$date -> subQuarter ();
2023-12-20 19:35:52 +01:00
2022-04-03 16:23:49 +02:00
return $date ;
2023-12-20 19:35:52 +01:00
2022-04-03 16:23:49 +02:00
case 'MTD' :
$date -> subMonth ();
2023-12-20 19:35:52 +01:00
2022-04-03 16:23:49 +02:00
return $date ;
}
2016-11-03 21:54:07 +01:00
throw new FireflyException ( sprintf ( 'Cannot do subtractPeriod for $repeat_freq "%s"' , $repeatFreq ));
2015-03-29 21:27:51 +02:00
}
2015-02-11 07:35:10 +01:00
/**
2021-05-24 08:57:02 +02:00
* @ throws FireflyException
2015-02-11 07:35:10 +01:00
*/
2016-04-05 22:00:03 +02:00
public function updateEndDate ( string $range , Carbon $start ) : Carbon
2015-02-06 21:23:14 +01:00
{
2023-10-30 07:27:43 +01:00
Log :: debug ( sprintf ( 'updateEndDate("%s", "%s")' , $range , $start -> format ( 'Y-m-d' )));
2015-02-06 21:23:14 +01:00
$functionMap = [
2016-11-20 07:24:18 +01:00
'1D' => 'endOfDay' ,
'1W' => 'endOfWeek' ,
'1M' => 'endOfMonth' ,
'3M' => 'lastOfQuarter' ,
'custom' => 'startOfMonth' , // this only happens in test situations.
2015-02-06 21:23:14 +01:00
];
2015-06-05 16:49:16 +02:00
$end = clone $start ;
2015-02-06 21:23:14 +01:00
2021-04-06 17:00:16 +02:00
if ( array_key_exists ( $range , $functionMap )) {
2015-02-06 21:23:14 +01:00
$function = $functionMap [ $range ];
2023-12-20 19:35:52 +01:00
$end -> { $function }(); // @phpstan-ignore-line
2015-02-06 21:23:14 +01:00
2024-07-10 11:55:02 +02:00
Log :: debug ( sprintf ( 'updateEndDate returns "%s"' , $end -> format ( 'Y-m-d' )));
2015-02-06 21:23:14 +01:00
return $end ;
}
2017-11-15 12:25:49 +01:00
if ( '6M' === $range ) {
2015-05-05 10:30:39 +02:00
if ( $start -> month >= 7 ) {
2015-02-06 21:23:14 +01:00
$end -> endOfYear ();
2016-05-20 17:58:10 +02:00
return $end ;
2015-02-06 21:23:14 +01:00
}
2016-05-20 17:58:10 +02:00
$end -> startOfYear () -> addMonths ( 6 );
2015-02-06 21:23:14 +01:00
return $end ;
}
2018-12-31 13:44:24 +01:00
// make sure 1Y takes the fiscal year into account.
if ( '1Y' === $range ) {
/** @var FiscalHelperInterface $fiscalHelper */
$fiscalHelper = app ( FiscalHelperInterface :: class );
2019-01-04 17:10:16 +01:00
2018-12-31 13:44:24 +01:00
return $fiscalHelper -> endOfFiscalYear ( $end );
}
2025-11-26 18:43:50 +01:00
$list = [
2022-12-30 20:25:04 +01:00
'last7' ,
'last30' ,
'last90' ,
'last365' ,
'YTD' ,
'QTD' ,
'MTD' ,
];
if ( in_array ( $range , $list , true )) {
2023-02-11 07:37:05 +01:00
$end = today ( config ( 'app.timezone' ));
2023-02-11 07:36:45 +01:00
$end -> endOfDay ();
2023-10-30 07:27:43 +01:00
Log :: debug ( sprintf ( 'updateEndDate returns "%s"' , $end -> format ( 'Y-m-d' )));
2023-12-20 19:35:52 +01:00
2022-12-30 20:25:04 +01:00
return $end ;
2022-04-03 14:48:22 +02:00
}
2016-11-03 21:54:07 +01:00
throw new FireflyException ( sprintf ( 'updateEndDate cannot handle range "%s"' , $range ));
2015-02-06 21:23:14 +01:00
}
2015-02-11 07:35:10 +01:00
/**
2021-05-24 08:57:02 +02:00
* @ throws FireflyException
2015-02-11 07:35:10 +01:00
*/
2016-04-05 22:00:03 +02:00
public function updateStartDate ( string $range , Carbon $start ) : Carbon
2015-02-06 21:23:14 +01:00
{
2023-10-30 07:27:43 +01:00
Log :: debug ( sprintf ( 'updateStartDate("%s", "%s")' , $range , $start -> format ( 'Y-m-d' )));
2015-02-06 21:23:14 +01:00
$functionMap = [
2016-11-20 07:24:18 +01:00
'1D' => 'startOfDay' ,
'1W' => 'startOfWeek' ,
'1M' => 'startOfMonth' ,
'3M' => 'firstOfQuarter' ,
'custom' => 'startOfMonth' , // this only happens in test situations.
2015-02-06 21:23:14 +01:00
];
2021-04-06 17:00:16 +02:00
if ( array_key_exists ( $range , $functionMap )) {
2015-02-06 21:23:14 +01:00
$function = $functionMap [ $range ];
2023-12-20 19:35:52 +01:00
$start -> { $function }(); // @phpstan-ignore-line
2024-07-10 11:55:02 +02:00
Log :: debug ( sprintf ( 'updateStartDate returns "%s"' , $start -> format ( 'Y-m-d' )));
2015-02-06 21:23:14 +01:00
return $start ;
}
2017-11-15 12:25:49 +01:00
if ( '6M' === $range ) {
2015-05-05 10:30:39 +02:00
if ( $start -> month >= 7 ) {
2015-02-06 21:23:14 +01:00
$start -> startOfYear () -> addMonths ( 6 );
2016-05-20 17:53:03 +02:00
return $start ;
2015-02-06 21:23:14 +01:00
}
2016-05-20 17:53:03 +02:00
$start -> startOfYear ();
2015-02-06 21:23:14 +01:00
return $start ;
}
2018-12-31 13:44:24 +01:00
// make sure 1Y takes the fiscal year into account.
if ( '1Y' === $range ) {
/** @var FiscalHelperInterface $fiscalHelper */
$fiscalHelper = app ( FiscalHelperInterface :: class );
2019-01-04 17:10:16 +01:00
2018-12-31 13:44:24 +01:00
return $fiscalHelper -> startOfFiscalYear ( $start );
}
2023-12-20 19:35:52 +01:00
2022-04-03 14:48:22 +02:00
switch ( $range ) {
default :
break ;
2023-12-20 19:35:52 +01:00
2022-10-30 14:24:37 +01:00
case 'last7' :
2022-11-02 05:02:09 +01:00
$start -> subDays ( 7 );
2023-12-20 19:35:52 +01:00
2022-11-02 05:02:09 +01:00
return $start ;
2023-12-20 19:35:52 +01:00
2022-10-30 14:24:37 +01:00
case 'last30' :
2022-11-02 05:02:09 +01:00
$start -> subDays ( 30 );
2023-12-20 19:35:52 +01:00
2022-11-02 05:02:09 +01:00
return $start ;
2023-12-20 19:35:52 +01:00
2022-04-03 14:48:22 +02:00
case 'last90' :
$start -> subDays ( 90 );
2023-12-20 19:35:52 +01:00
2022-04-03 14:48:22 +02:00
return $start ;
2023-12-20 19:35:52 +01:00
2022-04-03 14:48:22 +02:00
case 'last365' :
$start -> subDays ( 365 );
2023-12-20 19:35:52 +01:00
2022-04-03 14:48:22 +02:00
return $start ;
2023-12-20 19:35:52 +01:00
2022-04-03 14:48:22 +02:00
case 'YTD' :
$start -> startOfYear ();
2023-12-20 19:35:52 +01:00
2022-04-03 14:48:22 +02:00
return $start ;
2023-12-20 19:35:52 +01:00
2022-04-03 14:48:22 +02:00
case 'QTD' :
$start -> startOfQuarter ();
2023-12-20 19:35:52 +01:00
2022-04-03 14:48:22 +02:00
return $start ;
2023-12-20 19:35:52 +01:00
2022-04-03 14:48:22 +02:00
case 'MTD' :
$start -> startOfMonth ();
2023-12-20 19:35:52 +01:00
2022-04-03 14:48:22 +02:00
return $start ;
}
2023-12-20 19:35:52 +01:00
2016-11-03 21:54:07 +01:00
throw new FireflyException ( sprintf ( 'updateStartDate cannot handle range "%s"' , $range ));
2015-02-06 21:23:14 +01:00
}
2015-03-29 08:14:32 +02:00
}