| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-07-03 00:59:01 -03:00
										 |  |  |     private Calculator $calculator; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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( | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +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
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-15 16:02:42 +02:00
										 |  |  |     public function nextDateByInterval(Carbon $epoch, Periodicity $periodicity, int $skipInterval = 0): Carbon | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             return $this->calculator->nextDateByInterval($epoch, $periodicity, $skipInterval); | 
					
						
							|  |  |  |         } catch (IntervalException $exception) { | 
					
						
							| 
									
										
										
										
											2023-10-30 07:27:43 +01:00
										 |  |  |             Log::warning($exception->getMessage(), ['exception' => $exception]); | 
					
						
							| 
									
										
										
										
											2025-01-04 19:43:58 +01:00
										 |  |  |         } catch (\Throwable $exception) { | 
					
						
							| 
									
										
										
										
											2023-10-30 07:27:43 +01:00
										 |  |  |             Log::error($exception->getMessage(), ['exception' => $exception]); | 
					
						
							| 
									
										
										
										
											2023-07-15 16:02:42 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-30 07:27:43 +01:00
										 |  |  |         Log::debug( | 
					
						
							| 
									
										
										
										
											2023-07-15 16:02:42 +02:00
										 |  |  |             'Any error occurred to calculate the next date.', | 
					
						
							|  |  |  |             ['date' => $epoch, 'periodicity' => $periodicity->name, 'skipInterval' => $skipInterval] | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $epoch; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +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:
 | 
					
						
							|  |  |  |                 $workStart = app('navigation')->startOfPeriod($workStart, '1Y'); | 
					
						
							|  |  |  |                 $workEnd   = app('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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     public function startOfPeriod(Carbon $theDate, string $repeatFreq): Carbon | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +01:00
										 |  |  |         $date         = clone $theDate; | 
					
						
							| 
									
										
										
										
											2024-12-21 12:27:07 +01:00
										 |  |  |         // Log::debug(sprintf('Now in startOfPeriod("%s", "%s")', $date->toIso8601String(), $repeatFreq));
 | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +01:00
										 |  |  |         $functionMap  = [ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +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', | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |             'MTD'       => 'startOfMonth', | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         ]; | 
					
						
							| 
									
										
										
										
											2024-03-17 12:26:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $parameterMap = [ | 
					
						
							|  |  |  |             'startOfWeek' => [Carbon::MONDAY], | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         if (array_key_exists($repeatFreq, $functionMap)) { | 
					
						
							|  |  |  |             $function = $functionMap[$repeatFreq]; | 
					
						
							| 
									
										
										
										
											2024-12-21 12:27:07 +01:00
										 |  |  |             //            Log::debug(sprintf('Function is ->%s()', $function));
 | 
					
						
							| 
									
										
										
										
											2024-03-18 01:30:56 +01:00
										 |  |  |             if (array_key_exists($function, $parameterMap)) { | 
					
						
							| 
									
										
										
										
											2024-12-21 12:27:07 +01:00
										 |  |  |                 //                Log::debug(sprintf('Parameter map, function becomes ->%s(%s)', $function, implode(', ', $parameterMap[$function])));
 | 
					
						
							| 
									
										
										
										
											2024-04-02 15:40:33 +02:00
										 |  |  |                 $date->{$function}($parameterMap[$function][0]); // @phpstan-ignore-line
 | 
					
						
							| 
									
										
										
										
											2024-12-21 12:27:07 +01:00
										 |  |  |                 //                Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
 | 
					
						
							| 
									
										
										
										
											2024-03-17 12:26:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 return $date; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |             $date->{$function}(); // @phpstan-ignore-line
 | 
					
						
							| 
									
										
										
										
											2024-12-21 12:27:07 +01:00
										 |  |  |             //            Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             return $date; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if ('half-year' === $repeatFreq || '6M' === $repeatFreq) { | 
					
						
							| 
									
										
										
										
											2023-07-04 14:11:56 -03:00
										 |  |  |             $skipTo = $date->month > 7 ? 6 : 0; | 
					
						
							|  |  |  |             $date->startOfYear()->addMonths($skipTo); | 
					
						
							| 
									
										
										
										
											2024-12-21 12:27:07 +01:00
										 |  |  |             //            Log::debug(sprintf('Custom call for "%s": addMonths(%d)', $repeatFreq, $skipTo));
 | 
					
						
							|  |  |  |             //            Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             return $date; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +01:00
										 |  |  |         $result       = match ($repeatFreq) { | 
					
						
							| 
									
										
										
										
											2023-07-15 16:02:42 +02:00
										 |  |  |             'last7'   => $date->subDays(7)->startOfDay(), | 
					
						
							|  |  |  |             'last30'  => $date->subDays(30)->startOfDay(), | 
					
						
							|  |  |  |             'last90'  => $date->subDays(90)->startOfDay(), | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             'last365' => $date->subDays(365)->startOfDay(), | 
					
						
							| 
									
										
										
										
											2023-07-15 16:02:42 +02:00
										 |  |  |             'MTD'     => $date->startOfMonth()->startOfDay(), | 
					
						
							|  |  |  |             'QTD'     => $date->firstOfQuarter()->startOfDay(), | 
					
						
							|  |  |  |             'YTD'     => $date->startOfYear()->startOfDay(), | 
					
						
							|  |  |  |             default   => null, | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         }; | 
					
						
							|  |  |  |         if (null !== $result) { | 
					
						
							| 
									
										
										
										
											2024-12-21 12:27:07 +01:00
										 |  |  |             //            Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
 | 
					
						
							| 
									
										
										
										
											2024-03-18 01:30:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             return $result; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ('custom' === $repeatFreq) { | 
					
						
							| 
									
										
										
										
											2024-12-21 12:27:07 +01:00
										 |  |  |             //            Log::debug(sprintf('Custom, result is "%s"', $date->toIso8601String()));
 | 
					
						
							| 
									
										
										
										
											2024-03-18 01:30:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             return $date; // the date is already at the start.
 | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-10-30 07:27:43 +01:00
										 |  |  |         Log::error(sprintf('Cannot do startOfPeriod for $repeat_freq "%s"', $repeatFreq)); | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $theDate; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-24 08:57:02 +02:00
										 |  |  |     public function endOfPeriod(Carbon $end, string $repeatFreq): Carbon | 
					
						
							| 
									
										
										
										
											2015-02-25 15:19:14 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +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 */ | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +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()); | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +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); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             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)) { | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |                 return $today->endOfDay(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-08-19 05:06:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |             return $end->endOfMonth(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-05-06 15:29:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +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) { | 
					
						
							|  |  |  |             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
										 |  |  | 
 | 
					
						
							|  |  |  |             return $end; | 
					
						
							| 
									
										
										
										
											2015-02-25 15:19:14 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +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)) { | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |             $currentEnd->{$function}($modifierMap[$repeatFreq]); // @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(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-03-02 08:05:15 +01:00
										 |  |  |             $currentEnd->endOfDay(); | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							| 
									
										
										
										
											2019-03-02 08:05:15 +01:00
										 |  |  |         $currentEnd->endOfDay(); | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							|  |  |  |         return $currentEnd; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-02-22 15:40:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-17 20:23:02 +01:00
										 |  |  |     public function daysUntilEndOfMonth(Carbon $date): int | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $endOfMonth = $date->copy()->endOfMonth(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |         return (int) $date->diffInDays($endOfMonth, true); | 
					
						
							| 
									
										
										
										
											2024-01-17 20:23:02 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-27 17:47:12 +02:00
										 |  |  |     public function diffInPeriods(string $period, int $skip, Carbon $beginning, Carbon $end): int | 
					
						
							| 
									
										
										
										
											2023-10-06 18:21:49 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-10-30 07:27:43 +01:00
										 |  |  |         Log::debug(sprintf( | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +01:00
										 |  |  |             'diffInPeriods: %s (skip: %d), between %s and %s.', | 
					
						
							|  |  |  |             $period, | 
					
						
							|  |  |  |             $skip, | 
					
						
							|  |  |  |             $beginning->format('Y-m-d'), | 
					
						
							|  |  |  |             $end->format('Y-m-d') | 
					
						
							|  |  |  |         )); | 
					
						
							|  |  |  |         $map       = [ | 
					
						
							| 
									
										
										
										
											2024-03-17 12:00:28 +01:00
										 |  |  |             'daily'     => 'diffInDays', | 
					
						
							|  |  |  |             'weekly'    => 'diffInWeeks', | 
					
						
							|  |  |  |             'monthly'   => 'diffInMonths', | 
					
						
							|  |  |  |             'quarterly' => 'diffInMonths', | 
					
						
							|  |  |  |             'half-year' => 'diffInMonths', | 
					
						
							|  |  |  |             'yearly'    => 'diffInYears', | 
					
						
							| 
									
										
										
										
											2023-10-06 18:21:49 +02:00
										 |  |  |         ]; | 
					
						
							|  |  |  |         if (!array_key_exists($period, $map)) { | 
					
						
							| 
									
										
										
										
											2023-10-30 07:27:43 +01:00
										 |  |  |             Log::warning(sprintf('No diffInPeriods for period "%s"', $period)); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-06 18:21:49 +02:00
										 |  |  |             return 1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +01:00
										 |  |  |         $func      = $map[$period]; | 
					
						
							| 
									
										
										
										
											2023-10-27 18:07:56 +02:00
										 |  |  |         // first do the diff
 | 
					
						
							| 
									
										
										
										
											2024-03-17 12:00:28 +01:00
										 |  |  |         $floatDiff = $beginning->{$func}($end, true); // @phpstan-ignore-line
 | 
					
						
							| 
									
										
										
										
											2023-10-27 18:07:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // then correct for quarterly or half-year
 | 
					
						
							| 
									
										
										
										
											2023-10-28 15:03:33 +02:00
										 |  |  |         if ('quarterly' === $period) { | 
					
						
							| 
									
										
										
										
											2023-11-03 05:52:35 +01:00
										 |  |  |             Log::debug(sprintf('Q: Corrected %f to %f', $floatDiff, $floatDiff / 3)); | 
					
						
							| 
									
										
										
										
											2023-11-07 20:06:56 +01:00
										 |  |  |             $floatDiff /= 3; | 
					
						
							| 
									
										
										
										
											2023-10-27 18:07:56 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-10-28 15:03:33 +02:00
										 |  |  |         if ('half-year' === $period) { | 
					
						
							| 
									
										
										
										
											2023-11-03 05:52:35 +01:00
										 |  |  |             Log::debug(sprintf('H: Corrected %f to %f', $floatDiff, $floatDiff / 6)); | 
					
						
							| 
									
										
										
										
											2023-11-07 20:06:56 +01:00
										 |  |  |             $floatDiff /= 6; | 
					
						
							| 
									
										
										
										
											2023-10-06 18:21:49 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-10-27 17:47:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-27 18:07:56 +02:00
										 |  |  |         // then do ceil()
 | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +01:00
										 |  |  |         $diff      = ceil($floatDiff); | 
					
						
							| 
									
										
										
										
											2023-10-27 18:07:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-03 05:52:35 +01:00
										 |  |  |         Log::debug(sprintf('Diff is %f periods (%d rounded up)', $floatDiff, $diff)); | 
					
						
							| 
									
										
										
										
											2023-10-27 18:07:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-28 15:03:33 +02:00
										 |  |  |         if ($skip > 0) { | 
					
						
							| 
									
										
										
										
											2023-10-27 17:47:12 +02:00
										 |  |  |             $parameter = $skip + 1; | 
					
						
							| 
									
										
										
										
											2023-10-28 15:03:33 +02:00
										 |  |  |             $diff      = ceil($diff / $parameter) * $parameter; | 
					
						
							| 
									
										
										
										
											2023-10-30 07:27:43 +01:00
										 |  |  |             Log::debug(sprintf( | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +01:00
										 |  |  |                 'diffInPeriods: skip is %d, so param is %d, and diff becomes %d', | 
					
						
							|  |  |  |                 $skip, | 
					
						
							|  |  |  |                 $parameter, | 
					
						
							|  |  |  |                 $diff | 
					
						
							|  |  |  |             )); | 
					
						
							| 
									
										
										
										
											2023-10-27 17:47:12 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |         return (int) $diff; | 
					
						
							| 
									
										
										
										
											2023-10-06 18:21:49 +02: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', | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null !== $maxDate && $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'; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |         switch ($range) { | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |                 return $range; | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |             case 'last7': | 
					
						
							|  |  |  |                 return '1W'; | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |             case 'last30': | 
					
						
							|  |  |  |             case 'MTD': | 
					
						
							|  |  |  |                 return '1M'; | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |             case 'last90': | 
					
						
							|  |  |  |             case 'QTD': | 
					
						
							|  |  |  |                 return '3M'; | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |             case 'last365': | 
					
						
							|  |  |  |             case 'YTD': | 
					
						
							|  |  |  |                 return '1Y'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +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); | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +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)
 | 
					
						
							| 
									
										
										
										
											2024-04-21 07:07:06 +02:00
										 |  |  |         if ($diff >= 1.0001) { | 
					
						
							| 
									
										
										
										
											2016-11-19 13:37:44 +01:00
										 |  |  |             $increment     = 'addMonth'; | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +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'; | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |             $displayFormat = (string) trans('config.year_js'); | 
					
						
							| 
									
										
										
										
											2016-11-19 13:37:44 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-25 15:19:14 +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". | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function preferredCarbonFormat(Carbon $start, Carbon $end): string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $format = 'Y-m-d'; | 
					
						
							| 
									
										
										
										
											2024-04-21 17:23:16 +02:00
										 |  |  |         $diff   = $start->diffInMonths($end, true); | 
					
						
							| 
									
										
										
										
											2025-01-05 09:23:02 +01:00
										 |  |  |         // Log::debug(sprintf('preferredCarbonFormat(%s, %s) = %f', $start->format('Y-m-d'), $end->format('Y-m-d'), $diff));
 | 
					
						
							| 
									
										
										
										
											2024-04-21 07:07:06 +02:00
										 |  |  |         if ($diff >= 1.001) { | 
					
						
							| 
									
										
										
										
											2024-12-30 04:12:18 +01:00
										 |  |  |             //            Log::debug(sprintf('Return Y-m because %s', $diff));
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             $format = 'Y-m'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-21 07:07:06 +02:00
										 |  |  |         if ($diff >= 12.001) { | 
					
						
							| 
									
										
										
										
											2024-12-30 04:12:18 +01:00
										 |  |  |             //            Log::debug(sprintf('Return Y because %s', $diff));
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             $format = 'Y'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $format; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 = [ | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02: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'), | 
					
						
							|  |  |  |             'month'   => (string) trans('config.month_js'), | 
					
						
							|  |  |  |             'monthly' => (string) trans('config.month_js'), | 
					
						
							|  |  |  |             '1Y'      => (string) trans('config.year_js'), | 
					
						
							|  |  |  |             'year'    => (string) trans('config.year_js'), | 
					
						
							|  |  |  |             'yearly'  => (string) trans('config.year_js'), | 
					
						
							|  |  |  |             '6M'      => (string) trans('config.half_year_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)); | 
					
						
							| 
									
										
										
										
											2019-08-12 18:19:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $date->format('Y-m-d'); | 
					
						
							| 
									
										
										
										
											2015-02-25 15:19:14 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |         $format = (string) trans('config.month_and_day_js', [], $locale); | 
					
						
							| 
									
										
										
										
											2024-03-17 12:00:28 +01:00
										 |  |  |         if ($start->diffInMonths($end, true) > 1) { | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |             $format = (string) trans('config.month_js', [], $locale); | 
					
						
							| 
									
										
										
										
											2016-11-26 08:41:15 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-17 12:00:28 +01:00
										 |  |  |         if ($start->diffInMonths($end, true) > 12) { | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |             $format = (string) trans('config.year_js', [], $locale); | 
					
						
							| 
									
										
										
										
											2016-11-26 08:41:15 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-12-30 13:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-15 13:47:28 +01:00
										 |  |  |         return $format; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											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
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-12-30 13:47:23 +01:00
										 |  |  |         $format = 'endOfDay'; | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |         if ((int) $start->diffInMonths($end, true) > 1) { | 
					
						
							| 
									
										
										
										
											2016-12-30 13:47:23 +01:00
										 |  |  |             $format = 'endOfMonth'; | 
					
						
							| 
									
										
										
										
											2016-12-15 13:47:28 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |         if ((int) $start->diffInMonths($end, true) > 12) { | 
					
						
							| 
									
										
										
										
											2016-12-30 13:47:23 +01:00
										 |  |  |             $format = 'endOfYear'; | 
					
						
							| 
									
										
										
										
											2016-12-15 13:47:28 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-11-26 08:41:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $format; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $format = '1D'; | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |         if ((int) $start->diffInMonths($end, true) > 1) { | 
					
						
							| 
									
										
										
										
											2016-11-26 08:41:15 +01:00
										 |  |  |             $format = '1M'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |         if ((int) $start->diffInMonths($end, true) > 12) { | 
					
						
							| 
									
										
										
										
											2016-11-26 08:41:15 +01:00
										 |  |  |             $format = '1Y'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $format; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $format = '%Y-%m-%d'; | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |         if ((int) $start->diffInMonths($end, true) > 1) { | 
					
						
							| 
									
										
										
										
											2016-11-26 08:41:15 +01:00
										 |  |  |             $format = '%Y-%m'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +02:00
										 |  |  |         if ((int) $start->diffInMonths($end, true) > 12) { | 
					
						
							| 
									
										
										
										
											2016-11-26 08:41:15 +01:00
										 |  |  |             $format = '%Y'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $format; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +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 */ | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +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()); | 
					
						
							| 
									
										
										
										
											2024-08-16 09:39:29 +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); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +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
										 |  |  | } |