diff --git a/app/Http/Controllers/BudgetController.php b/app/Http/Controllers/BudgetController.php index 7b0942d0ba..fe7e001209 100644 --- a/app/Http/Controllers/BudgetController.php +++ b/app/Http/Controllers/BudgetController.php @@ -3,6 +3,7 @@ use Amount; use Auth; use Carbon\Carbon; +use Config; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Http\Requests\BudgetFormRequest; use FireflyIII\Models\Budget; @@ -142,18 +143,22 @@ class BudgetController extends Controller */ public function index(BudgetRepositoryInterface $repository, ARI $accountRepository) { - $budgets = $repository->getActiveBudgets(); - $inactive = $repository->getInactiveBudgets(); - $spent = '0'; - $budgeted = '0'; - $range = Preferences::get('viewRange', '1M')->data; + $budgets = $repository->getActiveBudgets(); + $inactive = $repository->getInactiveBudgets(); + $spent = '0'; + $budgeted = '0'; + $range = Preferences::get('viewRange', '1M')->data; + $repeatFreq = Config::get('firefly.range_to_repeat_freq.' . $range); /** @var Carbon $date */ - $date = session('start', new Carbon); - $start = Navigation::startOfPeriod($date, $range); - $end = Navigation::endOfPeriod($start, $range); + /** @var Carbon $start */ + $start = session('start', new Carbon); + /** @var Carbon $end */ + $end = session('end', new Carbon); $key = 'budgetIncomeTotal' . $start->format('Ymd') . $end->format('Ymd'); $budgetIncomeTotal = Preferences::get($key, 1000)->data; $period = Navigation::periodShow($start, $range); + $periodStart = $start->formatLocalized($this->monthAndDayFormat); + $periodEnd = $end->formatLocalized($this->monthAndDayFormat); $accounts = $accountRepository->getAccounts(['Default account', 'Asset account', 'Cash account']); /** @@ -164,8 +169,9 @@ class BudgetController extends Controller // loop the budgets: /** @var Budget $budget */ foreach ($budgets as $budget) { - $budget->spent = $repository->balanceInPeriod($budget, $start, $end, $accounts); - $budget->currentRep = $repository->getCurrentRepetition($budget, $start, $end); + $budget->spent = $repository->balanceInPeriod($budget, $start, $end, $accounts); + $budget->currentRep = $repository->getCurrentRepetition($budget, $repeatFreq, $start, $end); + $budget->otherRepetitions = $repository->getValidRepetitions($budget, $start, $end, $budget->currentRep); if (!is_null($budget->currentRep->id)) { $budgeted = bcadd($budgeted, $budget->currentRep->amount); } @@ -178,7 +184,12 @@ class BudgetController extends Controller $defaultCurrency = Amount::getDefaultCurrency(); return view( - 'budgets.index', compact('budgetMaximum', 'period', 'range', 'budgetIncomeTotal', 'defaultCurrency', 'inactive', 'budgets', 'spent', 'budgeted') + 'budgets.index', compact( + 'budgetMaximum', 'periodStart', 'periodEnd', + 'period', 'range', 'budgetIncomeTotal', + 'defaultCurrency', 'inactive', 'budgets', + 'spent', 'budgeted' + ) ); } diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index f90d15065e..232cba03de 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -408,14 +408,16 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn /** * @param Budget $budget + * @param string $repeatFreq * @param Carbon $start * @param Carbon $end * * @return LimitRepetition */ - public function getCurrentRepetition(Budget $budget, Carbon $start, Carbon $end): LimitRepetition + public function getCurrentRepetition(Budget $budget, string $repeatFreq, Carbon $start, Carbon $end): LimitRepetition { $data = $budget->limitrepetitions() + ->where('budget_limits.repeat_freq', $repeatFreq) ->where('limit_repetitions.startdate', $start->format('Y-m-d 00:00:00')) ->where('limit_repetitions.enddate', $end->format('Y-m-d 00:00:00')) ->first(['limit_repetitions.*']); @@ -844,4 +846,44 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn return $limit; } + + /** + * Returns a list of budget limits that are valid in the current given range. + * $ignore is optional. Send an empty limit rep. + * + * @param Budget $budget + * @param Carbon $start + * @param Carbon $end + * @param LimitRepetition $ignore + * + * @return Collection + */ + public function getValidRepetitions(Budget $budget, Carbon $start, Carbon $end, LimitRepetition $ignore) : Collection + { + $query = $budget->limitrepetitions() + ->where( // valid when either of these are true: + function ($q) use ($start, $end) { + $q->where( + function ($query) use ($start, $end) { + // starts before start time, and the end also after start time. + $query->where('limit_repetitions.startdate', '<=', $start->format('Y-m-d 00:00:00')); + $query->where('limit_repetitions.enddate', '>=', $start->format('Y-m-d 00:00:00')); + } + ); + $q->orWhere( + function ($query) use ($start, $end) { + // end after end time, and start is before end time + $query->where('limit_repetitions.startdate', '<=', $end->format('Y-m-d 00:00:00')); + $query->where('limit_repetitions.enddate', '>=', $end->format('Y-m-d 00:00:00')); + } + ); + } + ); + if (!is_null($ignore->id)) { + $query->where('limit_repetitions.id', '!=', $ignore->id); + } + $data = $query->get(['limit_repetitions.*']); + + return $data; + } } diff --git a/app/Repositories/Budget/BudgetRepositoryInterface.php b/app/Repositories/Budget/BudgetRepositoryInterface.php index 51b252ad8e..5671c6860b 100644 --- a/app/Repositories/Budget/BudgetRepositoryInterface.php +++ b/app/Repositories/Budget/BudgetRepositoryInterface.php @@ -146,14 +146,27 @@ interface BudgetRepositoryInterface */ public function getBudgetsAndLimitsInRange(Carbon $start, Carbon $end): Collection; + /** + * Returns a list of budget limits that are valid in the current given range. + * + * @param Budget $budget + * @param Carbon $start + * @param Carbon $end + * @param LimitRepetition $ignore + * + * @return Collection + */ + public function getValidRepetitions(Budget $budget, Carbon $start, Carbon $end, LimitRepetition $ignore) : Collection; + /** * @param Budget $budget + * @param string $repeatFreq * @param Carbon $start * @param Carbon $end * * @return LimitRepetition */ - public function getCurrentRepetition(Budget $budget, Carbon $start, Carbon $end): LimitRepetition; + public function getCurrentRepetition(Budget $budget, string $repeatFreq, Carbon $start, Carbon $end): LimitRepetition; /** * Returns all expenses for the given budget and the given accounts, in the given period. diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index fc3d38f165..4fd6ca302f 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -459,8 +459,11 @@ return [ 'store_new_budget' => 'Store new budget', 'stored_new_budget' => 'Stored new budget ":name"', 'availableIn' => 'Available in :date', + 'available_between' => 'Available between :start and :end', 'transactionsWithoutBudget' => 'Expenses without budget', 'transactionsWithoutBudgetDate' => 'Expenses without budget in :date', + 'transactions_no_budget' => 'Expenses without budget between :start and :end', + 'spent_between' => 'Spent between :start and :end', 'createBudget' => 'New budget', 'inactiveBudgets' => 'Inactive budgets', 'without_budget_between' => 'Transactions without a budget between :start and :end', diff --git a/resources/views/budgets/index.twig b/resources/views/budgets/index.twig index dfa90e0f6e..cfc1363153 100644 --- a/resources/views/budgets/index.twig +++ b/resources/views/budgets/index.twig @@ -9,7 +9,7 @@
Bla bla bla