| 
									
										
										
										
											2015-02-22 09:46:21 +01:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-20 12:41:23 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * BudgetRepository.php | 
					
						
							| 
									
										
										
										
											2020-02-16 14:00:57 +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-22 09:46:21 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace FireflyIII\Repositories\Budget; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use Carbon\Carbon; | 
					
						
							| 
									
										
										
										
											2025-01-03 14:56:06 +01:00
										 |  |  | use FireflyIII\Enums\AutoBudgetType; | 
					
						
							| 
									
										
										
										
											2025-01-03 09:05:19 +01:00
										 |  |  | use FireflyIII\Enums\TransactionTypeEnum; | 
					
						
							| 
									
										
										
										
											2019-10-30 20:02:21 +01:00
										 |  |  | use FireflyIII\Exceptions\FireflyException; | 
					
						
							| 
									
										
										
										
											2022-06-06 16:41:54 +02:00
										 |  |  | use FireflyIII\Helpers\Collector\GroupCollectorInterface; | 
					
						
							|  |  |  | use FireflyIII\Models\Account; | 
					
						
							| 
									
										
										
										
											2020-05-07 06:44:01 +02:00
										 |  |  | use FireflyIII\Models\Attachment; | 
					
						
							| 
									
										
										
										
											2020-03-14 07:30:55 +01:00
										 |  |  | use FireflyIII\Models\AutoBudget; | 
					
						
							| 
									
										
										
										
											2015-02-22 09:46:21 +01:00
										 |  |  | use FireflyIII\Models\Budget; | 
					
						
							|  |  |  | use FireflyIII\Models\BudgetLimit; | 
					
						
							| 
									
										
										
										
											2022-03-19 11:38:02 +01:00
										 |  |  | use FireflyIII\Models\Note; | 
					
						
							| 
									
										
										
										
											2019-09-27 21:35:21 +02:00
										 |  |  | use FireflyIII\Models\RecurrenceTransactionMeta; | 
					
						
							| 
									
										
										
										
											2018-07-22 08:27:18 +02:00
										 |  |  | use FireflyIII\Models\RuleAction; | 
					
						
							|  |  |  | use FireflyIII\Models\RuleTrigger; | 
					
						
							| 
									
										
										
										
											2022-06-06 16:41:54 +02:00
										 |  |  | use FireflyIII\Repositories\Account\AccountRepositoryInterface; | 
					
						
							| 
									
										
										
										
											2025-02-23 12:35:13 +01:00
										 |  |  | use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | 
					
						
							| 
									
										
										
										
											2019-01-11 16:57:40 +01:00
										 |  |  | use FireflyIII\Services\Internal\Destroy\BudgetDestroyService; | 
					
						
							| 
									
										
										
										
											2023-12-30 14:39:44 +01:00
										 |  |  | use FireflyIII\Support\Http\Api\ExchangeRateConverter; | 
					
						
							| 
									
										
										
										
											2025-02-23 12:28:27 +01:00
										 |  |  | use FireflyIII\Support\Repositories\UserGroup\UserGroupInterface; | 
					
						
							| 
									
										
										
										
											2025-02-09 09:30:44 +01:00
										 |  |  | use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait; | 
					
						
							| 
									
										
										
										
											2019-10-30 20:02:21 +01:00
										 |  |  | use Illuminate\Database\QueryException; | 
					
						
							| 
									
										
										
										
											2015-04-05 10:36:28 +02:00
										 |  |  | use Illuminate\Support\Collection; | 
					
						
							| 
									
										
										
										
											2025-02-23 12:47:04 +01:00
										 |  |  | use Illuminate\Support\Facades\DB; | 
					
						
							| 
									
										
										
										
											2024-01-05 10:55:46 +01:00
										 |  |  | use Illuminate\Support\Facades\Log; | 
					
						
							| 
									
										
										
										
											2025-02-23 12:47:04 +01:00
										 |  |  | use Illuminate\Support\Facades\Storage; | 
					
						
							| 
									
										
										
										
											2015-02-22 09:46:21 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |  * Class BudgetRepository. | 
					
						
							| 
									
										
										
										
											2015-02-22 09:46:21 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-02-23 12:28:27 +01:00
										 |  |  | class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface | 
					
						
							| 
									
										
										
										
											2015-02-22 09:46:21 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-02-09 09:30:44 +01:00
										 |  |  |     use UserGroupTrait; | 
					
						
							| 
									
										
										
										
											2016-03-03 08:44:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  |     public function budgetEndsWith(string $query, int $limit): Collection | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $search = $this->user->budgets(); | 
					
						
							|  |  |  |         if ('' !== $query) { | 
					
						
							| 
									
										
										
										
											2024-10-10 06:30:05 +02:00
										 |  |  |             $search->whereLike('name', sprintf('%%%s', $query)); | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         $search->orderBy('order', 'ASC') | 
					
						
							| 
									
										
										
										
											2023-12-31 06:20:29 +01:00
										 |  |  |             ->orderBy('name', 'ASC')->where('active', true) | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $search->take($limit)->get(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function budgetStartsWith(string $query, int $limit): Collection | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $search = $this->user->budgets(); | 
					
						
							|  |  |  |         if ('' !== $query) { | 
					
						
							| 
									
										
										
										
											2024-10-14 05:14:52 +02:00
										 |  |  |             $search->whereLike('name', sprintf('%s%%', $query)); | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         $search->orderBy('order', 'ASC') | 
					
						
							| 
									
										
										
										
											2023-12-31 06:20:29 +01:00
										 |  |  |             ->orderBy('name', 'ASC')->where('active', true) | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $search->take($limit)->get(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-06 14:40:19 +02:00
										 |  |  |     public function budgetedInPeriod(Carbon $start, Carbon $end): array | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('Now in budgetedInPeriod("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d'))); | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $return          = []; | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-06 14:40:19 +02:00
										 |  |  |         /** @var BudgetLimitRepository $limitRepository */ | 
					
						
							|  |  |  |         $limitRepository = app(BudgetLimitRepository::class); | 
					
						
							|  |  |  |         $limitRepository->setUser($this->user); | 
					
						
							| 
									
										
										
										
											2023-12-30 14:39:44 +01:00
										 |  |  |         $budgets         = $this->getActiveBudgets(); | 
					
						
							| 
									
										
										
										
											2025-01-19 19:07:19 +01:00
										 |  |  |         $defaultCurrency = app('amount')->getNativeCurrency(); | 
					
						
							| 
									
										
										
										
											2023-12-30 14:39:44 +01:00
										 |  |  |         $converter       = new ExchangeRateConverter(); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-06 14:40:19 +02:00
										 |  |  |         /** @var Budget $budget */ | 
					
						
							|  |  |  |         foreach ($budgets as $budget) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('Budget #%d: "%s"', $budget->id, $budget->name)); | 
					
						
							| 
									
										
										
										
											2022-06-06 14:40:19 +02:00
										 |  |  |             $limits = $limitRepository->getBudgetLimits($budget, $start, $end); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-06 14:40:19 +02:00
										 |  |  |             /** @var BudgetLimit $limit */ | 
					
						
							|  |  |  |             foreach ($limits as $limit) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |                 app('log')->debug(sprintf('Budget limit #%d', $limit->id)); | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |                 $currency                            = $limit->transactionCurrency; | 
					
						
							|  |  |  |                 $rate                                = $converter->getCurrencyRate($currency, $defaultCurrency, $end); | 
					
						
							|  |  |  |                 $currencyCode                        = $currency->code; | 
					
						
							| 
									
										
										
										
											2023-12-30 14:39:44 +01:00
										 |  |  |                 $return[$currencyCode] ??= [ | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |                     'currency_id'                    => (string) $currency->id, | 
					
						
							| 
									
										
										
										
											2023-12-30 14:39:44 +01:00
										 |  |  |                     'currency_name'                  => $currency->name, | 
					
						
							|  |  |  |                     'currency_symbol'                => $currency->symbol, | 
					
						
							|  |  |  |                     'currency_code'                  => $currency->code, | 
					
						
							|  |  |  |                     'currency_decimal_places'        => $currency->decimal_places, | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |                     'native_currency_id'             => (string) $defaultCurrency->id, | 
					
						
							| 
									
										
										
										
											2023-12-30 14:39:44 +01:00
										 |  |  |                     'native_currency_name'           => $defaultCurrency->name, | 
					
						
							|  |  |  |                     'native_currency_symbol'         => $defaultCurrency->symbol, | 
					
						
							|  |  |  |                     'native_currency_code'           => $defaultCurrency->code, | 
					
						
							|  |  |  |                     'native_currency_decimal_places' => $defaultCurrency->decimal_places, | 
					
						
							|  |  |  |                     'sum'                            => '0', | 
					
						
							|  |  |  |                     'native_sum'                     => '0', | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |                 ]; | 
					
						
							| 
									
										
										
										
											2022-06-06 14:40:19 +02:00
										 |  |  |                 // same period
 | 
					
						
							|  |  |  |                 if ($limit->start_date->isSameDay($start) && $limit->end_date->isSameDay($end)) { | 
					
						
							| 
									
										
										
										
											2023-12-30 14:39:44 +01:00
										 |  |  |                     $return[$currencyCode]['sum']        = bcadd($return[$currencyCode]['sum'], $limit->amount); | 
					
						
							|  |  |  |                     $return[$currencyCode]['native_sum'] = bcmul($rate, $return[$currencyCode]['sum']); | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |                     app('log')->debug(sprintf('Add full amount [1]: %s', $limit->amount)); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-06 14:40:19 +02:00
										 |  |  |                     continue; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 // limit is inside of date range
 | 
					
						
							|  |  |  |                 if ($start->lte($limit->start_date) && $end->gte($limit->end_date)) { | 
					
						
							| 
									
										
										
										
											2023-12-30 14:39:44 +01:00
										 |  |  |                     $return[$currencyCode]['sum']        = bcadd($return[$currencyCode]['sum'], $limit->amount); | 
					
						
							|  |  |  |                     $return[$currencyCode]['native_sum'] = bcmul($rate, $return[$currencyCode]['sum']); | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |                     app('log')->debug(sprintf('Add full amount [2]: %s', $limit->amount)); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-06 14:40:19 +02:00
										 |  |  |                     continue; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-03-17 12:00:28 +01:00
										 |  |  |                 $total                               = $limit->start_date->diffInDays($limit->end_date, true) + 1; // include the day itself.
 | 
					
						
							| 
									
										
										
										
											2023-12-30 14:39:44 +01:00
										 |  |  |                 $days                                = $this->daysInOverlap($limit, $start, $end); | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |                 $amount                              = bcmul(bcdiv($limit->amount, (string) $total), (string) $days); | 
					
						
							| 
									
										
										
										
											2023-12-30 14:39:44 +01:00
										 |  |  |                 $return[$currencyCode]['sum']        = bcadd($return[$currencyCode]['sum'], $amount); | 
					
						
							|  |  |  |                 $return[$currencyCode]['native_sum'] = bcmul($rate, $return[$currencyCode]['sum']); | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |                 app('log')->debug( | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |                     sprintf( | 
					
						
							|  |  |  |                         'Amount per day: %s (%s over %d days). Total amount for %d days: %s', | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |                         bcdiv($limit->amount, (string) $total), | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |                         $limit->amount, | 
					
						
							|  |  |  |                         $total, | 
					
						
							|  |  |  |                         $days, | 
					
						
							|  |  |  |                         $amount | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                 ); | 
					
						
							| 
									
										
										
										
											2022-06-06 14:40:19 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-06 14:40:19 +02:00
										 |  |  |         return $return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     public function getActiveBudgets(): Collection | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->user->budgets()->where('active', true) | 
					
						
							| 
									
										
										
										
											2023-12-31 06:20:29 +01:00
										 |  |  |             ->orderBy('order', 'ASC') | 
					
						
							|  |  |  |             ->orderBy('name', 'ASC') | 
					
						
							|  |  |  |             ->get() | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-22 20:11:09 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * How many days of this budget limit are between start and end? | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function daysInOverlap(BudgetLimit $limit, Carbon $start, Carbon $end): int | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // start1 = $start
 | 
					
						
							|  |  |  |         // start2 = $limit->start_date
 | 
					
						
							|  |  |  |         // start1 = $end
 | 
					
						
							|  |  |  |         // start2 = $limit->end_date
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // limit is larger than start and end (inclusive)
 | 
					
						
							|  |  |  |         //    |-----------|
 | 
					
						
							|  |  |  |         //  |----------------|
 | 
					
						
							|  |  |  |         if ($start->gte($limit->start_date) && $end->lte($limit->end_date)) { | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             return (int) $start->diffInDays($end, true) + 1; // add one day
 | 
					
						
							| 
									
										
										
										
											2024-02-22 20:11:09 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         // limit starts earlier and limit ends first:
 | 
					
						
							|  |  |  |         //    |-----------|
 | 
					
						
							|  |  |  |         // |-------|
 | 
					
						
							|  |  |  |         if ($limit->start_date->lte($start) && $limit->end_date->lte($end)) { | 
					
						
							|  |  |  |             // return days in the range $start-$limit_end
 | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             return (int) $start->diffInDays($limit->end_date, true) + 1; // add one day, the day itself
 | 
					
						
							| 
									
										
										
										
											2024-02-22 20:11:09 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         // limit starts later and limit ends earlier
 | 
					
						
							|  |  |  |         //    |-----------|
 | 
					
						
							|  |  |  |         //           |-------|
 | 
					
						
							|  |  |  |         if ($limit->start_date->gte($start) && $limit->end_date->gte($end)) { | 
					
						
							|  |  |  |             // return days in the range $limit_start - $end
 | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             return (int) $limit->start_date->diffInDays($end, true) + 1; // add one day, the day itself
 | 
					
						
							| 
									
										
										
										
											2024-02-22 20:11:09 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |     public function budgetedInPeriodForBudget(Budget $budget, Carbon $start, Carbon $end): array | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('Now in budgetedInPeriod(#%d, "%s", "%s")', $budget->id, $start->format('Y-m-d'), $end->format('Y-m-d'))); | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $return          = []; | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |         /** @var BudgetLimitRepository $limitRepository */ | 
					
						
							|  |  |  |         $limitRepository = app(BudgetLimitRepository::class); | 
					
						
							|  |  |  |         $limitRepository->setUser($this->user); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('Budget #%d: "%s"', $budget->id, $budget->name)); | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $limits          = $limitRepository->getBudgetLimits($budget, $start, $end); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |         /** @var BudgetLimit $limit */ | 
					
						
							|  |  |  |         foreach ($limits as $limit) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('Budget limit #%d', $limit->id)); | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |             $currency                     = $limit->transactionCurrency; | 
					
						
							| 
									
										
										
										
											2023-12-10 06:45:59 +01:00
										 |  |  |             $return[$currency->id] ??= [ | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |                 'id'             => (string) $currency->id, | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |                 'name'           => $currency->name, | 
					
						
							|  |  |  |                 'symbol'         => $currency->symbol, | 
					
						
							|  |  |  |                 'code'           => $currency->code, | 
					
						
							|  |  |  |                 'decimal_places' => $currency->decimal_places, | 
					
						
							|  |  |  |                 'sum'            => '0', | 
					
						
							|  |  |  |             ]; | 
					
						
							|  |  |  |             // same period
 | 
					
						
							|  |  |  |             if ($limit->start_date->isSameDay($start) && $limit->end_date->isSameDay($end)) { | 
					
						
							| 
									
										
										
										
											2023-11-05 19:41:37 +01:00
										 |  |  |                 $return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], $limit->amount); | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |                 app('log')->debug(sprintf('Add full amount [1]: %s', $limit->amount)); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // limit is inside of date range
 | 
					
						
							|  |  |  |             if ($start->lte($limit->start_date) && $end->gte($limit->end_date)) { | 
					
						
							| 
									
										
										
										
											2023-11-05 19:41:37 +01:00
										 |  |  |                 $return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], $limit->amount); | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |                 app('log')->debug(sprintf('Add full amount [2]: %s', $limit->amount)); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             $total                        = $limit->start_date->diffInDays($limit->end_date) + 1; // include the day itself.
 | 
					
						
							|  |  |  |             $days                         = $this->daysInOverlap($limit, $start, $end); | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $amount                       = bcmul(bcdiv($limit->amount, (string) $total), (string) $days); | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |             $return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], $amount); | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug( | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |                 sprintf( | 
					
						
							|  |  |  |                     'Amount per day: %s (%s over %d days). Total amount for %d days: %s', | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |                     bcdiv($limit->amount, (string) $total), | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |                     $limit->amount, | 
					
						
							|  |  |  |                     $total, | 
					
						
							|  |  |  |                     $days, | 
					
						
							|  |  |  |                     $amount | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |         return $return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-22 18:04:26 +02:00
										 |  |  |     public function cleanupBudgets(): bool | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // delete limits with amount 0:
 | 
					
						
							| 
									
										
										
										
											2022-12-30 20:25:04 +01:00
										 |  |  |         BudgetLimit::where('amount', 0)->delete(); | 
					
						
							| 
									
										
										
										
											2019-09-01 10:48:18 +02:00
										 |  |  |         $budgets = $this->getActiveBudgets(); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-01 10:48:18 +02:00
										 |  |  |         /** | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |          * @var int    $index | 
					
						
							| 
									
										
										
										
											2019-09-01 10:48:18 +02:00
										 |  |  |          * @var Budget $budget | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         foreach ($budgets as $index => $budget) { | 
					
						
							|  |  |  |             $budget->order = $index + 1; | 
					
						
							|  |  |  |             $budget->save(); | 
					
						
							| 
									
										
										
										
											2019-08-22 18:04:26 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-04-26 06:57:59 +02:00
										 |  |  |         // other budgets, set to 0.
 | 
					
						
							|  |  |  |         $this->user->budgets()->where('active', 0)->update(['order' => 0]); | 
					
						
							| 
									
										
										
										
											2019-08-22 18:04:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * @throws FireflyException | 
					
						
							| 
									
										
										
										
											2023-12-22 20:12:38 +01:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     public function update(Budget $budget, array $data): Budget | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug('Now in update()'); | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $oldName        = $budget->name; | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         if (array_key_exists('name', $data)) { | 
					
						
							|  |  |  |             $budget->name = $data['name']; | 
					
						
							|  |  |  |             $this->updateRuleActions($oldName, $budget->name); | 
					
						
							|  |  |  |             $this->updateRuleTriggers($oldName, $budget->name); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (array_key_exists('active', $data)) { | 
					
						
							|  |  |  |             $budget->active = $data['active']; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (array_key_exists('notes', $data)) { | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $this->setNoteText($budget, (string) $data['notes']); | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         $budget->save(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // update or create auto-budget:
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $autoBudget     = $this->getAutoBudget($budget); | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // first things first: delete when no longer required:
 | 
					
						
							|  |  |  |         $autoBudgetType = array_key_exists('auto_budget_type', $data) ? $data['auto_budget_type'] : null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (0 === $autoBudgetType && null !== $autoBudget) { | 
					
						
							|  |  |  |             // delete!
 | 
					
						
							|  |  |  |             $autoBudget->delete(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return $budget; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (0 === $autoBudgetType && null === $autoBudget) { | 
					
						
							|  |  |  |             return $budget; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (null === $autoBudgetType && null === $autoBudget) { | 
					
						
							|  |  |  |             return $budget; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $this->updateAutoBudget($budget, $data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $budget; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-22 20:11:09 +01:00
										 |  |  |     private function updateRuleActions(string $oldName, string $newName): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $types   = ['set_budget']; | 
					
						
							|  |  |  |         $actions = RuleAction::leftJoin('rules', 'rules.id', '=', 'rule_actions.rule_id') | 
					
						
							|  |  |  |             ->where('rules.user_id', $this->user->id) | 
					
						
							|  |  |  |             ->whereIn('rule_actions.action_type', $types) | 
					
						
							|  |  |  |             ->where('rule_actions.action_value', $oldName) | 
					
						
							|  |  |  |             ->get(['rule_actions.*']) | 
					
						
							|  |  |  |         ; | 
					
						
							|  |  |  |         app('log')->debug(sprintf('Found %d actions to update.', $actions->count())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** @var RuleAction $action */ | 
					
						
							|  |  |  |         foreach ($actions as $action) { | 
					
						
							|  |  |  |             $action->action_value = $newName; | 
					
						
							|  |  |  |             $action->save(); | 
					
						
							|  |  |  |             app('log')->debug(sprintf('Updated action %d: %s', $action->id, $action->action_value)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private function updateRuleTriggers(string $oldName, string $newName): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $types    = ['budget_is']; | 
					
						
							|  |  |  |         $triggers = RuleTrigger::leftJoin('rules', 'rules.id', '=', 'rule_triggers.rule_id') | 
					
						
							|  |  |  |             ->where('rules.user_id', $this->user->id) | 
					
						
							|  |  |  |             ->whereIn('rule_triggers.trigger_type', $types) | 
					
						
							|  |  |  |             ->where('rule_triggers.trigger_value', $oldName) | 
					
						
							|  |  |  |             ->get(['rule_triggers.*']) | 
					
						
							|  |  |  |         ; | 
					
						
							|  |  |  |         app('log')->debug(sprintf('Found %d triggers to update.', $triggers->count())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** @var RuleTrigger $trigger */ | 
					
						
							|  |  |  |         foreach ($triggers as $trigger) { | 
					
						
							|  |  |  |             $trigger->trigger_value = $newName; | 
					
						
							|  |  |  |             $trigger->save(); | 
					
						
							|  |  |  |             app('log')->debug(sprintf('Updated trigger %d: %s', $trigger->id, $trigger->trigger_value)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private function setNoteText(Budget $budget, string $text): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $dbNote = $budget->notes()->first(); | 
					
						
							|  |  |  |         if ('' !== $text) { | 
					
						
							|  |  |  |             if (null === $dbNote) { | 
					
						
							|  |  |  |                 $dbNote = new Note(); | 
					
						
							|  |  |  |                 $dbNote->noteable()->associate($budget); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             $dbNote->text = trim($text); | 
					
						
							|  |  |  |             $dbNote->save(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (null !== $dbNote) { | 
					
						
							|  |  |  |             $dbNote->delete(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     public function getAutoBudget(Budget $budget): ?AutoBudget | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-01-04 07:39:16 +01:00
										 |  |  |         /** @var null|AutoBudget */ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         return $budget->autoBudgets()->first(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-22 20:11:09 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @throws FireflyException | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function updateAutoBudget(Budget $budget, array $data): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // update or create auto-budget:
 | 
					
						
							|  |  |  |         $autoBudget = $this->getAutoBudget($budget); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // grab default currency:
 | 
					
						
							| 
									
										
										
										
											2025-01-19 11:54:40 +01:00
										 |  |  |         $currency   = app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup); | 
					
						
							| 
									
										
										
										
											2024-02-22 20:11:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (null === $autoBudget) { | 
					
						
							|  |  |  |             // at this point it's a blind assumption auto_budget_type is 1 or 2.
 | 
					
						
							|  |  |  |             $autoBudget                          = new AutoBudget(); | 
					
						
							|  |  |  |             $autoBudget->auto_budget_type        = $data['auto_budget_type']; | 
					
						
							|  |  |  |             $autoBudget->budget_id               = $budget->id; | 
					
						
							|  |  |  |             $autoBudget->transaction_currency_id = $currency->id; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // set or update the currency.
 | 
					
						
							|  |  |  |         if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) { | 
					
						
							|  |  |  |             /** @var CurrencyRepositoryInterface $repos */ | 
					
						
							|  |  |  |             $repos        = app(CurrencyRepositoryInterface::class); | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $currencyId   = (int) ($data['currency_id'] ?? 0); | 
					
						
							|  |  |  |             $currencyCode = (string) ($data['currency_code'] ?? ''); | 
					
						
							| 
									
										
										
										
											2024-02-22 20:11:09 +01:00
										 |  |  |             $currency     = $repos->find($currencyId); | 
					
						
							|  |  |  |             if (null === $currency) { | 
					
						
							|  |  |  |                 $currency = $repos->findByCode($currencyCode); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (null !== $currency) { | 
					
						
							|  |  |  |                 $autoBudget->transaction_currency_id = $currency->id; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // change values if submitted or presented:
 | 
					
						
							|  |  |  |         if (array_key_exists('auto_budget_type', $data)) { | 
					
						
							|  |  |  |             $autoBudget->auto_budget_type = $data['auto_budget_type']; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (array_key_exists('auto_budget_amount', $data)) { | 
					
						
							|  |  |  |             $autoBudget->amount = $data['auto_budget_amount']; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (array_key_exists('auto_budget_period', $data)) { | 
					
						
							|  |  |  |             $autoBudget->period = $data['auto_budget_period']; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $autoBudget->save(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Find a budget or return NULL | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |      * @param null|int $budgetId |null | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2024-03-18 20:25:30 +01:00
										 |  |  |     public function find(?int $budgetId = null): ?Budget | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-01-04 07:39:16 +01:00
										 |  |  |         /** @var null|Budget */ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         return $this->user->budgets()->find($budgetId); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 22:00:03 +02:00
										 |  |  |     public function destroy(Budget $budget): bool | 
					
						
							| 
									
										
										
										
											2015-02-22 15:40:13 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-01-11 16:57:40 +01:00
										 |  |  |         /** @var BudgetDestroyService $service */ | 
					
						
							|  |  |  |         $service = app(BudgetDestroyService::class); | 
					
						
							|  |  |  |         $service->destroy($budget); | 
					
						
							| 
									
										
										
										
											2015-02-22 15:40:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Destroy all budgets. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function destroyAll(): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $budgets = $this->getBudgets(); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  |         /** @var Budget $budget */ | 
					
						
							|  |  |  |         foreach ($budgets as $budget) { | 
					
						
							| 
									
										
										
										
											2025-02-23 12:47:04 +01:00
										 |  |  |             DB::table('budget_transaction')->where('budget_id', $budget->id)->delete(); | 
					
						
							|  |  |  |             DB::table('budget_transaction_journal')->where('budget_id', $budget->id)->delete(); | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             RecurrenceTransactionMeta::where('name', 'budget_id')->where('value', (string) $budget->id)->delete(); | 
					
						
							|  |  |  |             RuleAction::where('action_type', 'set_budget')->where('action_value', (string) $budget->id)->delete(); | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  |             $budget->delete(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-01-05 10:55:46 +01:00
										 |  |  |         Log::channel('audit')->info('Delete all budgets through destroyAll'); | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     public function getBudgets(): Collection | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->user->budgets()->orderBy('order', 'ASC') | 
					
						
							| 
									
										
										
										
											2023-12-31 06:20:29 +01:00
										 |  |  |             ->orderBy('name', 'ASC')->get() | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  |     public function destroyAutoBudget(Budget $budget): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         /** @var AutoBudget $autoBudget */ | 
					
						
							|  |  |  |         foreach ($budget->autoBudgets()->get() as $autoBudget) { | 
					
						
							|  |  |  |             $autoBudget->delete(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-06 08:10:50 +02:00
										 |  |  |     public function findBudget(?int $budgetId, ?string $budgetName): ?Budget | 
					
						
							| 
									
										
										
										
											2019-03-17 17:05:16 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug('Now in findBudget()'); | 
					
						
							|  |  |  |         app('log')->debug(sprintf('Searching for budget with ID #%d...', $budgetId)); | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |         $result = $this->find((int) $budgetId); | 
					
						
							| 
									
										
										
										
											2019-05-24 05:28:41 +02:00
										 |  |  |         if (null === $result && null !== $budgetName && '' !== $budgetName) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('Searching for budget with name %s...', $budgetName)); | 
					
						
							| 
									
										
										
										
											2023-11-05 08:15:17 +01:00
										 |  |  |             $result = $this->findByName($budgetName); | 
					
						
							| 
									
										
										
										
											2019-03-17 17:05:16 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (null !== $result) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('Found budget #%d: %s', $result->id, $result->name)); | 
					
						
							| 
									
										
										
										
											2019-03-17 17:05:16 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('Found result is null? %s', var_export(null === $result, true))); | 
					
						
							| 
									
										
										
										
											2019-03-17 17:05:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $result; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2019-08-22 18:04:26 +02:00
										 |  |  |      * Find budget by name. | 
					
						
							| 
									
										
										
										
											2019-03-17 17:05:16 +01:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-08-22 18:04:26 +02:00
										 |  |  |     public function findByName(?string $name): ?Budget | 
					
						
							| 
									
										
										
										
											2019-03-17 17:05:16 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-08-22 18:04:26 +02:00
										 |  |  |         if (null === $name) { | 
					
						
							| 
									
										
										
										
											2019-03-17 17:05:16 +01:00
										 |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-08-22 18:04:26 +02:00
										 |  |  |         $query = sprintf('%%%s%%', $name); | 
					
						
							| 
									
										
										
										
											2025-01-04 07:39:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /** @var null|Budget */ | 
					
						
							| 
									
										
										
										
											2024-10-14 05:14:52 +02:00
										 |  |  |         return $this->user->budgets()->whereLike('name', $query)->first(); | 
					
						
							| 
									
										
										
										
											2019-03-17 17:05:16 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 10:32:26 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * This method returns the oldest journal or transaction date known to this budget. | 
					
						
							|  |  |  |      * Will cache result. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2018-07-23 21:49:15 +02:00
										 |  |  |     public function firstUseDate(Budget $budget): ?Carbon | 
					
						
							| 
									
										
										
										
											2016-05-06 10:32:26 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-08-26 09:30:52 +02:00
										 |  |  |         $journal = $budget->transactionJournals()->orderBy('date', 'ASC')->first(); | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |         if (null !== $journal) { | 
					
						
							| 
									
										
										
										
											2020-08-08 11:07:08 +02:00
										 |  |  |             return $journal->date; | 
					
						
							| 
									
										
										
										
											2016-05-06 10:32:26 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-28 06:14:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-08 11:07:08 +02:00
										 |  |  |         return null; | 
					
						
							| 
									
										
										
										
											2016-05-06 10:32:26 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  |     public function getAttachments(Budget $budget): Collection | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $set  = $budget->attachments()->get(); | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-23 12:47:04 +01:00
										 |  |  |         $disk = Storage::disk('upload'); | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $set->each( | 
					
						
							| 
									
										
										
										
											2025-01-04 09:15:39 +01:00
										 |  |  |             static function (Attachment $attachment) use ($disk) { // @phpstan-ignore-line
 | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  |                 $notes                   = $attachment->notes()->first(); | 
					
						
							|  |  |  |                 $attachment->file_exists = $disk->exists($attachment->fileName()); | 
					
						
							| 
									
										
										
										
											2023-11-05 09:40:45 +01:00
										 |  |  |                 $attachment->notes_text  = null !== $notes ? $notes->text : ''; | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 return $attachment; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-07 20:35:14 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get all budgets with these ID's. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getByIds(array $budgetIds): Collection | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->user->budgets()->whereIn('id', $budgetIds)->get(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 10:32:26 +02:00
										 |  |  |     public function getInactiveBudgets(): Collection | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-10-23 19:11:25 +02:00
										 |  |  |         return $this->user->budgets() | 
					
						
							| 
									
										
										
										
											2023-12-31 06:20:29 +01:00
										 |  |  |             ->orderBy('order', 'ASC') | 
					
						
							|  |  |  |             ->orderBy('name', 'ASC')->where('active', 0)->get() | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2016-05-06 10:32:26 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  |     public function getNoteText(Budget $budget): ?string | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  |         $note = $budget->notes()->first(); | 
					
						
							|  |  |  |         if (null === $note) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $note->text; | 
					
						
							| 
									
										
										
										
											2021-03-12 06:20:01 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 06:23:37 +02:00
										 |  |  |     public function searchBudget(string $query, int $limit): Collection | 
					
						
							| 
									
										
										
										
											2019-03-02 14:12:09 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-07-01 20:22:35 +02:00
										 |  |  |         $search = $this->user->budgets(); | 
					
						
							|  |  |  |         if ('' !== $query) { | 
					
						
							| 
									
										
										
										
											2024-10-10 06:30:05 +02:00
										 |  |  |             $search->whereLike('name', sprintf('%%%s%%', $query)); | 
					
						
							| 
									
										
										
										
											2019-07-01 20:22:35 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-01-08 18:13:42 +01:00
										 |  |  |         $search->orderBy('order', 'ASC') | 
					
						
							| 
									
										
										
										
											2023-12-31 06:20:29 +01:00
										 |  |  |             ->orderBy('name', 'ASC')->where('active', true) | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2019-07-01 20:22:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 06:23:37 +02:00
										 |  |  |         return $search->take($limit)->get(); | 
					
						
							| 
									
										
										
										
											2019-03-02 14:12:09 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-17 15:18:09 +02:00
										 |  |  |     public function setBudgetOrder(Budget $budget, int $order): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $budget->order = $order; | 
					
						
							|  |  |  |         $budget->save(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-06 16:41:54 +02:00
										 |  |  |     public function spentInPeriod(Carbon $start, Carbon $end): array | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('Now in %s', __METHOD__)); | 
					
						
							| 
									
										
										
										
											2022-06-06 16:41:54 +02:00
										 |  |  |         $start->startOfDay(); | 
					
						
							|  |  |  |         $end->endOfDay(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // exclude specific liabilities
 | 
					
						
							|  |  |  |         $repository = app(AccountRepositoryInterface::class); | 
					
						
							|  |  |  |         $repository->setUser($this->user); | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $subset     = $repository->getAccountsByType(config('firefly.valid_liabilities')); | 
					
						
							|  |  |  |         $selection  = new Collection(); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-06 16:41:54 +02:00
										 |  |  |         /** @var Account $account */ | 
					
						
							|  |  |  |         foreach ($subset as $account) { | 
					
						
							|  |  |  |             if ('credit' === $repository->getMetaValue($account, 'liability_direction')) { | 
					
						
							|  |  |  |                 $selection->push($account); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // start collecting:
 | 
					
						
							|  |  |  |         /** @var GroupCollectorInterface $collector */ | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $collector  = app(GroupCollectorInterface::class); | 
					
						
							| 
									
										
										
										
											2022-06-06 16:41:54 +02:00
										 |  |  |         $collector->setUser($this->user) | 
					
						
							| 
									
										
										
										
											2023-12-31 06:20:29 +01:00
										 |  |  |             ->setRange($start, $end) | 
					
						
							|  |  |  |             ->excludeDestinationAccounts($selection) | 
					
						
							| 
									
										
										
										
											2025-01-03 09:05:19 +01:00
										 |  |  |             ->setTypes([TransactionTypeEnum::WITHDRAWAL->value]) | 
					
						
							| 
									
										
										
										
											2023-12-31 06:20:29 +01:00
										 |  |  |             ->setBudgets($this->getActiveBudgets()) | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2022-06-06 16:41:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $journals   = $collector->getExtractedJournals(); | 
					
						
							|  |  |  |         $array      = []; | 
					
						
							| 
									
										
										
										
											2022-06-06 16:41:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         foreach ($journals as $journal) { | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $currencyId                = (int) $journal['currency_id']; | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |             $array[$currencyId] ??= [ | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |                 'id'             => (string) $currencyId, | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |                 'name'           => $journal['currency_name'], | 
					
						
							|  |  |  |                 'symbol'         => $journal['currency_symbol'], | 
					
						
							|  |  |  |                 'code'           => $journal['currency_code'], | 
					
						
							|  |  |  |                 'decimal_places' => $journal['currency_decimal_places'], | 
					
						
							|  |  |  |                 'sum'            => '0', | 
					
						
							|  |  |  |             ]; | 
					
						
							| 
									
										
										
										
											2022-06-06 16:41:54 +02:00
										 |  |  |             $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->negative($journal['amount'])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // also do foreign amount:
 | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $foreignId                 = (int) $journal['foreign_currency_id']; | 
					
						
							| 
									
										
										
										
											2022-06-06 16:41:54 +02:00
										 |  |  |             if (0 !== $foreignId) { | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |                 $array[$foreignId] ??= [ | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |                     'id'             => (string) $foreignId, | 
					
						
							| 
									
										
										
										
											2022-12-29 19:42:26 +01:00
										 |  |  |                     'name'           => $journal['foreign_currency_name'], | 
					
						
							|  |  |  |                     'symbol'         => $journal['foreign_currency_symbol'], | 
					
						
							|  |  |  |                     'code'           => $journal['foreign_currency_code'], | 
					
						
							|  |  |  |                     'decimal_places' => $journal['foreign_currency_decimal_places'], | 
					
						
							|  |  |  |                     'sum'            => '0', | 
					
						
							|  |  |  |                 ]; | 
					
						
							| 
									
										
										
										
											2022-06-06 16:41:54 +02:00
										 |  |  |                 $array[$foreignId]['sum'] = bcadd($array[$foreignId]['sum'], app('steam')->negative($journal['foreign_amount'])); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $array; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |     public function spentInPeriodForBudget(Budget $budget, Carbon $start, Carbon $end): array | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('Now in %s', __METHOD__)); | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |         $start->startOfDay(); | 
					
						
							|  |  |  |         $end->endOfDay(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // exclude specific liabilities
 | 
					
						
							|  |  |  |         $repository = app(AccountRepositoryInterface::class); | 
					
						
							|  |  |  |         $repository->setUser($this->user); | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $subset     = $repository->getAccountsByType(config('firefly.valid_liabilities')); | 
					
						
							|  |  |  |         $selection  = new Collection(); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |         /** @var Account $account */ | 
					
						
							|  |  |  |         foreach ($subset as $account) { | 
					
						
							|  |  |  |             if ('credit' === $repository->getMetaValue($account, 'liability_direction')) { | 
					
						
							|  |  |  |                 $selection->push($account); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // start collecting:
 | 
					
						
							|  |  |  |         /** @var GroupCollectorInterface $collector */ | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $collector  = app(GroupCollectorInterface::class); | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |         $collector->setUser($this->user) | 
					
						
							| 
									
										
										
										
											2023-12-31 06:20:29 +01:00
										 |  |  |             ->setRange($start, $end) | 
					
						
							|  |  |  |             ->excludeDestinationAccounts($selection) | 
					
						
							| 
									
										
										
										
											2025-01-03 09:05:19 +01:00
										 |  |  |             ->setTypes([TransactionTypeEnum::WITHDRAWAL->value]) | 
					
						
							| 
									
										
										
										
											2023-12-31 06:20:29 +01:00
										 |  |  |             ->setBudget($budget) | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $journals   = $collector->getExtractedJournals(); | 
					
						
							|  |  |  |         $array      = []; | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         foreach ($journals as $journal) { | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $currencyId                = (int) $journal['currency_id']; | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |             $array[$currencyId] ??= [ | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |                 'id'             => (string) $currencyId, | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |                 'name'           => $journal['currency_name'], | 
					
						
							|  |  |  |                 'symbol'         => $journal['currency_symbol'], | 
					
						
							|  |  |  |                 'code'           => $journal['currency_code'], | 
					
						
							|  |  |  |                 'decimal_places' => $journal['currency_decimal_places'], | 
					
						
							|  |  |  |                 'sum'            => '0', | 
					
						
							|  |  |  |             ]; | 
					
						
							|  |  |  |             $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->negative($journal['amount'])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // also do foreign amount:
 | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $foreignId                 = (int) $journal['foreign_currency_id']; | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |             if (0 !== $foreignId) { | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |                 $array[$foreignId] ??= [ | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |                     'id'             => (string) $foreignId, | 
					
						
							| 
									
										
										
										
											2023-02-22 18:14:14 +01:00
										 |  |  |                     'name'           => $journal['foreign_currency_name'], | 
					
						
							|  |  |  |                     'symbol'         => $journal['foreign_currency_symbol'], | 
					
						
							|  |  |  |                     'code'           => $journal['foreign_currency_code'], | 
					
						
							|  |  |  |                     'decimal_places' => $journal['foreign_currency_decimal_places'], | 
					
						
							|  |  |  |                     'sum'            => '0', | 
					
						
							|  |  |  |                 ]; | 
					
						
							|  |  |  |                 $array[$foreignId]['sum'] = bcadd($array[$foreignId]['sum'], app('steam')->negative($journal['foreign_amount'])); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $array; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-20 15:21:27 +01:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2019-10-30 20:02:21 +01:00
										 |  |  |      * @throws FireflyException | 
					
						
							| 
									
										
										
										
											2023-12-22 20:12:38 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2025-01-03 15:53:10 +01:00
										 |  |  |      * @SuppressWarnings("PHPMD.NPathComplexity") | 
					
						
							| 
									
										
										
										
											2023-12-22 20:12:38 +01:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-04-05 22:00:03 +02:00
										 |  |  |     public function store(array $data): Budget | 
					
						
							| 
									
										
										
										
											2016-01-20 15:21:27 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $order                               = $this->getMaxOrder(); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-30 20:02:21 +01:00
										 |  |  |         try { | 
					
						
							|  |  |  |             $newBudget = Budget::create( | 
					
						
							|  |  |  |                 [ | 
					
						
							| 
									
										
										
										
											2023-08-01 19:38:53 +02:00
										 |  |  |                     'user_id'       => $this->user->id, | 
					
						
							|  |  |  |                     'user_group_id' => $this->user->user_group_id, | 
					
						
							|  |  |  |                     'name'          => $data['name'], | 
					
						
							|  |  |  |                     'order'         => $order + 1, | 
					
						
							|  |  |  |                     'active'        => array_key_exists('active', $data) ? $data['active'] : true, | 
					
						
							| 
									
										
										
										
											2019-10-30 20:02:21 +01:00
										 |  |  |                 ] | 
					
						
							|  |  |  |             ); | 
					
						
							| 
									
										
										
										
											2020-03-13 21:35:22 +01:00
										 |  |  |         } catch (QueryException $e) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:32:00 +01:00
										 |  |  |             app('log')->error($e->getMessage()); | 
					
						
							|  |  |  |             app('log')->error($e->getTraceAsString()); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-07 07:28:43 +02:00
										 |  |  |             throw new FireflyException('400002: Could not store budget.', 0, $e); | 
					
						
							| 
									
										
										
										
											2019-10-30 20:02:21 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-03-19 11:38:02 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // set notes
 | 
					
						
							| 
									
										
										
										
											2022-03-29 14:59:58 +02:00
										 |  |  |         if (array_key_exists('notes', $data)) { | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $this->setNoteText($newBudget, (string) $data['notes']); | 
					
						
							| 
									
										
										
										
											2022-03-19 11:38:02 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 06:03:06 +02:00
										 |  |  |         if (!array_key_exists('auto_budget_type', $data) || !array_key_exists('auto_budget_amount', $data) || !array_key_exists('auto_budget_period', $data)) { | 
					
						
							| 
									
										
										
										
											2021-03-13 19:03:08 +01:00
										 |  |  |             return $newBudget; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $type                                = $data['auto_budget_type']; | 
					
						
							| 
									
										
										
										
											2021-03-13 19:03:08 +01:00
										 |  |  |         if ('none' === $type) { | 
					
						
							| 
									
										
										
										
											2020-03-13 21:35:22 +01:00
										 |  |  |             return $newBudget; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-03-15 07:45:46 +01:00
										 |  |  |         if (0 === $type) { | 
					
						
							|  |  |  |             return $newBudget; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-03-13 19:03:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-14 07:30:55 +01:00
										 |  |  |         if ('reset' === $type) { | 
					
						
							| 
									
										
										
										
											2025-01-03 14:56:06 +01:00
										 |  |  |             $type = AutoBudgetType::AUTO_BUDGET_RESET->value; | 
					
						
							| 
									
										
										
										
											2020-03-14 07:30:55 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         if ('rollover' === $type) { | 
					
						
							| 
									
										
										
										
											2025-01-03 14:56:06 +01:00
										 |  |  |             $type = AutoBudgetType::AUTO_BUDGET_ROLLOVER->value; | 
					
						
							| 
									
										
										
										
											2020-03-14 07:30:55 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-05-29 13:56:55 +02:00
										 |  |  |         if ('adjusted' === $type) { | 
					
						
							| 
									
										
										
										
											2025-01-03 14:56:06 +01:00
										 |  |  |             $type = AutoBudgetType::AUTO_BUDGET_ADJUSTED->value; | 
					
						
							| 
									
										
										
										
											2023-05-15 06:18:02 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-03-14 07:30:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-28 14:59:16 +02:00
										 |  |  |         /** @var CurrencyRepositoryInterface $repos */ | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $repos                               = app(CurrencyRepositoryInterface::class); | 
					
						
							|  |  |  |         $currency                            = null; | 
					
						
							| 
									
										
										
										
											2021-03-13 19:03:08 +01:00
										 |  |  |         if (array_key_exists('currency_id', $data)) { | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $currency = $repos->find((int) $data['currency_id']); | 
					
						
							| 
									
										
										
										
											2021-03-13 19:03:08 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (array_key_exists('currency_code', $data)) { | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $currency = $repos->findByCode((string) $data['currency_code']); | 
					
						
							| 
									
										
										
										
											2020-03-14 07:30:55 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-28 06:14:12 +01:00
										 |  |  |         if (null === $currency) { | 
					
						
							| 
									
										
										
										
											2025-01-19 11:54:40 +01:00
										 |  |  |             $currency = app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup); | 
					
						
							| 
									
										
										
										
											2020-03-14 07:30:55 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $autoBudget                          = new AutoBudget(); | 
					
						
							| 
									
										
										
										
											2020-03-13 21:35:22 +01:00
										 |  |  |         $autoBudget->budget()->associate($newBudget); | 
					
						
							| 
									
										
										
										
											2020-03-14 07:30:55 +01:00
										 |  |  |         $autoBudget->transaction_currency_id = $currency->id; | 
					
						
							|  |  |  |         $autoBudget->auto_budget_type        = $type; | 
					
						
							| 
									
										
										
										
											2020-03-13 21:35:22 +01:00
										 |  |  |         $autoBudget->amount                  = $data['auto_budget_amount'] ?? '1'; | 
					
						
							|  |  |  |         $autoBudget->period                  = $data['auto_budget_period'] ?? 'monthly'; | 
					
						
							|  |  |  |         $autoBudget->save(); | 
					
						
							| 
									
										
										
										
											2020-03-14 07:30:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-14 15:18:32 +01:00
										 |  |  |         // create initial budget limit.
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $today                               = today(config('app.timezone')); | 
					
						
							|  |  |  |         $start                               = app('navigation')->startOfPeriod($today, $autoBudget->period); | 
					
						
							|  |  |  |         $end                                 = app('navigation')->endOfPeriod($start, $autoBudget->period); | 
					
						
							| 
									
										
										
										
											2020-03-14 15:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $limitRepos                          = app(BudgetLimitRepositoryInterface::class); | 
					
						
							| 
									
										
										
										
											2020-03-14 15:18:32 +01:00
										 |  |  |         $limitRepos->setUser($this->user); | 
					
						
							|  |  |  |         $limitRepos->store( | 
					
						
							|  |  |  |             [ | 
					
						
							| 
									
										
										
										
											2020-10-28 06:14:12 +01:00
										 |  |  |                 'budget_id'   => $newBudget->id, | 
					
						
							|  |  |  |                 'currency_id' => $autoBudget->transaction_currency_id, | 
					
						
							|  |  |  |                 'start_date'  => $start, | 
					
						
							|  |  |  |                 'end_date'    => $end, | 
					
						
							|  |  |  |                 'amount'      => $autoBudget->amount, | 
					
						
							| 
									
										
										
										
											2020-03-14 15:18:32 +01:00
										 |  |  |             ] | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-20 15:21:27 +01:00
										 |  |  |         return $newBudget; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     public function getMaxOrder(): int | 
					
						
							| 
									
										
										
										
											2023-05-29 13:56:55 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |         return (int) $this->user->budgets()->max('order'); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-03-29 08:14:32 +02:00
										 |  |  | } |