diff --git a/app/Http/Controllers/Budget/BudgetLimitController.php b/app/Http/Controllers/Budget/BudgetLimitController.php index effd7ac2cb..c1dbe62020 100644 --- a/app/Http/Controllers/Budget/BudgetLimitController.php +++ b/app/Http/Controllers/Budget/BudgetLimitController.php @@ -63,7 +63,7 @@ class BudgetLimitController extends Controller parent::__construct(); $this->middleware( function ($request, $next) { - app('view')->share('title', (string)trans('firefly.budgets')); + app('view')->share('title', (string) trans('firefly.budgets')); app('view')->share('mainTitleIcon', 'fa-pie-chart'); $this->repository = app(BudgetRepositoryInterface::class); $this->opsRepository = app(OperationsRepositoryInterface::class); @@ -84,7 +84,7 @@ class BudgetLimitController extends Controller $budgetLimits = $this->blRepository->getBudgetLimits($budget, $start, $end); // remove already budgeted currencies with the same date range - $currencies = $collection->filter( + $currencies = $collection->filter( static function (TransactionCurrency $currency) use ($budgetLimits, $start, $end) { /** @var BudgetLimit $limit */ foreach ($budgetLimits as $limit) { @@ -101,6 +101,24 @@ class BudgetLimitController extends Controller return view('budgets.budget-limits.create', compact('start', 'end', 'currencies', 'budget')); } + /** + * @return Factory|View + */ + public function show(BudgetLimit $budgetLimit) + { + $notes = $this->blRepository->getNoteText($budgetLimit); + return view('budgets.budget-limits.show', compact('budgetLimit', 'notes')); + } + + /** + * @return Factory|View + */ + public function edit(BudgetLimit $budgetLimit) + { + $notes = $this->blRepository->getNoteText($budgetLimit); + return view('budgets.budget-limits.edit', compact('budgetLimit', 'notes')); + } + /** * @return Redirector|RedirectResponse */ @@ -117,23 +135,23 @@ class BudgetLimitController extends Controller * * @throws FireflyException */ - public function store(Request $request): JsonResponse|RedirectResponse + public function store(Request $request): JsonResponse | RedirectResponse { app('log')->debug('Going to store new budget-limit.', $request->all()); // first search for existing one and update it if necessary. - $currency = $this->currencyRepos->find((int)$request->get('transaction_currency_id')); - $budget = $this->repository->find((int)$request->get('budget_id')); + $currency = $this->currencyRepos->find((int) $request->get('transaction_currency_id')); + $budget = $this->repository->find((int) $request->get('budget_id')); if (null === $currency || null === $budget) { throw new FireflyException('No valid currency or budget.'); } - $start = Carbon::createFromFormat('Y-m-d', $request->get('start')); - $end = Carbon::createFromFormat('Y-m-d', $request->get('end')); + $start = Carbon::createFromFormat('Y-m-d', $request->get('start')); + $end = Carbon::createFromFormat('Y-m-d', $request->get('end')); if (null === $start || null === $end) { return response()->json([]); } - $amount = (string)$request->get('amount'); + $amount = (string) $request->get('amount'); $start->startOfDay(); $end->startOfDay(); @@ -143,7 +161,7 @@ class BudgetLimitController extends Controller app('log')->debug(sprintf('Start: %s, end: %s', $start->format('Y-m-d'), $end->format('Y-m-d'))); - $limit = $this->blRepository->find($budget, $currency, $start, $end); + $limit = $this->blRepository->find($budget, $currency, $start, $end); // sanity check on amount: if (0 === bccomp($amount, '0')) { @@ -154,7 +172,7 @@ class BudgetLimitController extends Controller // return empty=ish array: return response()->json([]); } - if ((int)$amount > 268435456) { // intentional cast to integer + if ((int) $amount > 268435456) { // intentional cast to integer $amount = '268435456'; } if (-1 === bccomp($amount, '0')) { @@ -169,41 +187,47 @@ class BudgetLimitController extends Controller $limit = $this->blRepository->store( [ 'budget_id' => $request->get('budget_id'), - 'currency_id' => (int)$request->get('transaction_currency_id'), + 'currency_id' => (int) $request->get('transaction_currency_id'), 'start_date' => $start, 'end_date' => $end, 'amount' => $amount, ] ); } + // parse notes, if any. + $notes = (string) $request->get('notes'); + $this->blRepository->setNoteText($limit, $notes); if ($request->expectsJson()) { - $array = $limit->toArray(); + $array = $limit->toArray(); // add some extra metadata: - $spentArr = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection([$budget]), $currency); - $array['spent'] = $spentArr[$currency->id]['sum'] ?? '0'; - $array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], $array['amount'])); - $array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']); - $array['days_left'] = (string)$this->activeDaysLeft($start, $end); + $spentArr = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection([$budget]), $currency); + $array['spent'] = $spentArr[$currency->id]['sum'] ?? '0'; + $array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], $array['amount'])); + $array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']); + $array['days_left'] = (string) $this->activeDaysLeft($start, $end); // left per day: - $array['left_per_day'] = 0 === bccomp('0', $array['days_left']) ? bcadd($array['spent'], $array['amount']) : bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']); + $array['left_per_day'] = 0 === bccomp('0', $array['days_left']) ? bcadd($array['spent'], $array['amount']) : bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']); // left per day formatted. $array['left_per_day_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $array['left_per_day']); + // notes: + $array['notes'] = $this->blRepository->getNoteText($limit); + return response()->json($array); } return redirect(route('budgets.index')); } - public function update(Request $request, BudgetLimit $budgetLimit): JsonResponse + public function update(Request $request, BudgetLimit $budgetLimit): JsonResponse|RedirectResponse { - $amount = (string)$request->get('amount'); + $amount = (string) $request->get('amount'); if ('' === $amount) { $amount = '0'; } - if ((int)$amount > 268435456) { // 268 million, intentional integer + if ((int) $amount > 268435456) { // 268 million, intentional integer $amount = '268435456'; } // sanity check on amount: @@ -211,7 +235,7 @@ class BudgetLimitController extends Controller $budgetId = $budgetLimit->budget_id; $currency = $budgetLimit->transactionCurrency; $this->blRepository->destroyBudgetLimit($budgetLimit); - $array = [ + $array = [ 'budget_id' => $budgetId, 'left_formatted' => app('amount')->formatAnything($currency, '0'), 'left_per_day_formatted' => app('amount')->formatAnything($currency, '0'), @@ -224,29 +248,36 @@ class BudgetLimitController extends Controller if (-1 === bccomp($amount, '0')) { $amount = bcmul($amount, '-1'); } + $notes = (string)$request->get('notes'); + if(strlen($notes) > 32768) { + $notes = substr($notes, 0, 32768); + } - $limit = $this->blRepository->update($budgetLimit, ['amount' => $amount]); + + $limit = $this->blRepository->update($budgetLimit, ['amount' => $amount,'notes' => $notes]); app('preferences')->mark(); - $array = $limit->toArray(); + $array = $limit->toArray(); - $spentArr = $this->opsRepository->sumExpenses( + $spentArr = $this->opsRepository->sumExpenses( $limit->start_date, $limit->end_date, null, new Collection([$budgetLimit->budget]), $budgetLimit->transactionCurrency ); - $daysLeft = $this->activeDaysLeft($limit->start_date, $limit->end_date); - $array['spent'] = $spentArr[$budgetLimit->transactionCurrency->id]['sum'] ?? '0'; - $array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], $array['amount'])); - $array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']); - $array['days_left'] = (string)$daysLeft; - $array['left_per_day'] = 0 === $daysLeft ? bcadd($array['spent'], $array['amount']) : bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']); + $daysLeft = $this->activeDaysLeft($limit->start_date, $limit->end_date); + $array['spent'] = $spentArr[$budgetLimit->transactionCurrency->id]['sum'] ?? '0'; + $array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], $array['amount'])); + $array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']); + $array['days_left'] = (string) $daysLeft; + $array['left_per_day'] = 0 === $daysLeft ? bcadd($array['spent'], $array['amount']) : bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']); // left per day formatted. $array['amount'] = app('steam')->bcround($limit['amount'], $limit->transactionCurrency->decimal_places); $array['left_per_day_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $array['left_per_day']); - + if ('true' === $request->get('redirect')) { + return redirect(route('budgets.index')); + } return response()->json($array); } } diff --git a/app/Http/Controllers/Budget/IndexController.php b/app/Http/Controllers/Budget/IndexController.php index fd182e9212..5fde689d96 100644 --- a/app/Http/Controllers/Budget/IndexController.php +++ b/app/Http/Controllers/Budget/IndexController.php @@ -213,6 +213,7 @@ class IndexController extends Controller $array['budgeted'][] = [ 'id' => $limit->id, 'amount' => $amount, + 'notes' => $this->blRepository->getNoteText($limit), 'start_date' => $limit->start_date->isoFormat($this->monthAndDayFormat), 'end_date' => $limit->end_date->isoFormat($this->monthAndDayFormat), 'in_range' => $limit->start_date->isSameDay($start) && $limit->end_date->isSameDay($end), diff --git a/public/v1/js/ff/budgets/index.js b/public/v1/js/ff/budgets/index.js index b6d702fa95..63444d096b 100644 --- a/public/v1/js/ff/budgets/index.js +++ b/public/v1/js/ff/budgets/index.js @@ -35,6 +35,8 @@ $(function () { $('.budget_amount').on('change', updateBudgetedAmount); $('.create_bl').on('click', createBudgetLimit); + $('.edit_bl').on('click', editBudgetLimit); + $('.show_bl').on('click', showBudgetLimit); $('.delete_bl').on('click', deleteBudgetLimit); @@ -216,6 +218,24 @@ function createBudgetLimit(e) { return false; } +function editBudgetLimit(e) { + var button = $(e.currentTarget); + var budgetLimitId = button.data('id'); + $('#defaultModal').empty().load(editBudgetLimitUrl.replace('REPLACEME', budgetLimitId.toString()), function () { + $('#defaultModal').modal('show'); + }); + return false; +} + +function showBudgetLimit(e) { + var button = $(e.currentTarget); + var budgetLimitId = button.data('id'); + $('#defaultModal').empty().load(showBudgetLimitUrl.replace('REPLACEME', budgetLimitId.toString()), function () { + $('#defaultModal').modal('show'); + }); + return false; +} + function deleteBudgetLimit(e) { e.preventDefault(); var button = $(e.currentTarget); diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index e472b7484a..aa395cd3da 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -2068,6 +2068,10 @@ return [ 'opt_group_l_Mortgage' => 'Liability: Mortgage', 'opt_group_l_Credit card' => 'Liability: Credit card', 'notes' => 'Notes', + 'view_notes' => 'View notes', + 'set_budget_limit_notes' => 'View the notes for this budgeted amount', + 'edit_bl_notes' => 'Edit notes', + 'update_bl_notes' => 'Update notes', 'unknown_journal_error' => 'Could not store the transaction. Please check the log files.', 'attachment_not_found' => 'This attachment could not be found.', 'journal_link_bill' => 'This transaction is linked to bill :name. To remove the connection, uncheck the checkbox. Use rules to connect it to another bill.', diff --git a/resources/views/budgets/budget-limits/create.twig b/resources/views/budgets/budget-limits/create.twig index ce0c05d06a..112bd739e7 100644 --- a/resources/views/budgets/budget-limits/create.twig +++ b/resources/views/budgets/budget-limits/create.twig @@ -25,6 +25,10 @@