This commit is contained in:
James Cole
2022-09-18 16:28:04 +02:00
parent c120a908f3
commit c25b63d87b
10 changed files with 71 additions and 437 deletions

View File

@@ -1,267 +0,0 @@
<?php
/**
* AvailableBudgetController.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* 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/>.
*/
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Budget;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidDateException;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\AvailableBudget;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\View\View;
use Log;
use ValueError;
/**
*
* Class AvailableBudgetController
*/
class AvailableBudgetController extends Controller
{
/** @var AvailableBudgetRepositoryInterface */
private $abRepository;
/** @var CurrencyRepositoryInterface */
private $currencyRepos;
/**
* AmountController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
app('view')->share('title', (string) trans('firefly.budgets'));
app('view')->share('mainTitleIcon', 'fa-pie-chart');
$this->abRepository = app(AvailableBudgetRepositoryInterface::class);
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
return $next($request);
}
);
}
/**
* Create will always assume the user's default currency, if it's not set.
*
* This method will check if there is no AB, and refuse to continue if it exists.
*
* @param Request $request
* @param Carbon $start
* @param Carbon $end
* @param TransactionCurrency|null $currency
*
* @return Factory|RedirectResponse|Redirector|View
*/
public function create(Request $request, Carbon $start, Carbon $end, ?TransactionCurrency $currency = null)
{
$currency = $currency ?? app('amount')->getDefaultCurrency();
$collection = $this->abRepository->get($start, $end);
$filtered = $collection->filter(
static function (AvailableBudget $budget) use ($currency) {
return $currency->id === $budget->transaction_currency_id;
}
);
if ($filtered->count() > 0) {
/** @var AvailableBudget $first */
$first = $filtered->first();
return redirect(route('available-budgets.edit', [$first->id]));
}
$page = (int) ($request->get('page') ?? 1);
return view('budgets.available-budgets.create', compact('start', 'end', 'page', 'currency'));
}
/**
* createAlternative will show a list of enabled currencies so the user can pick one.
*
* @param Request $request
* @param Carbon $start
* @param Carbon $end
*
* @return Factory|View
*/
public function createAlternative(Request $request, Carbon $start, Carbon $end)
{
$currencies = $this->currencyRepos->get();
$availableBudgets = $this->abRepository->get($start, $end);
// remove already budgeted currencies:
$currencies = $currencies->filter(
static function (TransactionCurrency $currency) use ($availableBudgets) {
/** @var AvailableBudget $budget */
foreach ($availableBudgets as $budget) {
if ($budget->transaction_currency_id === $currency->id) {
return false;
}
}
return true;
}
);
$page = (int) ($request->get('page') ?? 1);
return view('budgets.available-budgets.create-alternative', compact('start', 'end', 'page', 'currencies'));
}
/**
* @param Request $request
*
* @return RedirectResponse|Redirector
*/
public function delete(Request $request)
{
$id = (int) $request->get('id');
if (0 !== $id) {
$availableBudget = $this->abRepository->findById($id);
if (null !== $availableBudget) {
$this->abRepository->destroyAvailableBudget($availableBudget);
session()->flash('success', trans('firefly.deleted_ab'));
}
}
return redirect(route('budgets.index'));
}
/**
* @param AvailableBudget $availableBudget
*
* @param Carbon $start
* @param Carbon $end
*
* @return Factory|View
*/
public function edit(AvailableBudget $availableBudget, Carbon $start, Carbon $end)
{
$availableBudget->amount = number_format((float) $availableBudget->amount, $availableBudget->transactionCurrency->decimal_places, '.', '');
return view('budgets.available-budgets.edit', compact('availableBudget', 'start', 'end'));
}
/**
* @param Request $request
*
* @return RedirectResponse|Redirector
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function store(Request $request)
{
// make dates.
try {
$start = Carbon::createFromFormat('Y-m-d', $request->get('start'));
$end = Carbon::createFromFormat('Y-m-d', $request->get('end'));
} catch (InvalidDateException $e) {
$start = session()->get('start');
$end = session()->get('end');
Log::info($e->getMessage());
}
// validate amount
$amount = (string) $request->get('amount');
if ('' === $amount) {
session()->flash('error', trans('firefly.invalid_amount'));
return redirect(route('budgets.index', [$start->format('Y-m-d'), $end->format('Y-m-d')]));
}
if (bccomp($amount, '0') <= 0) {
session()->flash('error', trans('firefly.invalid_amount'));
return redirect(route('budgets.index', [$start->format('Y-m-d'), $end->format('Y-m-d')]));
}
// find currency
$currency = $this->currencyRepos->find((int) $request->get('currency_id'));
if (null === $currency) {
session()->flash('error', trans('firefly.invalid_currency'));
return redirect(route('budgets.index', [$start->format('Y-m-d'), $end->format('Y-m-d')]));
}
$start->startOfDay();
$end->endOfDay();
// find existing AB
$existing = $this->abRepository->find($currency, $start, $end);
if (null === $existing) {
$this->abRepository->store(
[
'amount' => $amount,
'currency_id' => $currency->id,
'start' => $start,
'end' => $end,
]
);
}
if (null !== $existing) {
// update amount:
$this->abRepository->update($existing, ['amount' => $amount]);
}
session()->flash('success', trans('firefly.set_ab'));
return redirect(route('budgets.index', [$start->format('Y-m-d'), $end->format('Y-m-d')]));
}
/**
* @param Request $request
* @param AvailableBudget $availableBudget
*
* @param Carbon $start
* @param Carbon $end
*
* @return RedirectResponse|Redirector
*/
public function update(Request $request, AvailableBudget $availableBudget, Carbon $start, Carbon $end)
{
// validate amount
$amount = (string) $request->get('amount');
if ('' === $amount) {
session()->flash('error', trans('firefly.invalid_amount'));
return redirect(route('budgets.index', [$start->format('Y-m-d'), $end->format('Y-m-d')]));
}
try {
if (bccomp($amount, '0') <= 0) {
session()->flash('error', trans('firefly.invalid_amount'));
return redirect(route('budgets.index', [$start->format('Y-m-d'), $end->format('Y-m-d')]));
}
} catch (ValueError $e) {
Log::error(sprintf('Value "%s" is not a number: %s', $amount, $e->getMessage()));
session()->flash('error', trans('firefly.invalid_amount'));
return redirect(route('budgets.index', [$start->format('Y-m-d'), $end->format('Y-m-d')]));
}
$this->abRepository->update($availableBudget, ['amount' => $amount]);
session()->flash('success', trans('firefly.updated_ab'));
return redirect(route('budgets.index', [$start->format('Y-m-d'), $end->format('Y-m-d')]));
}
}

View File

@@ -129,9 +129,6 @@ class IndexController extends Controller
unset($spentArr);
}
// count the number of enabled currencies. This determines if we display a "+" button.
$enableAddButton = $currencies->count() > count($availableBudgets);
// number of days for consistent budgeting.
$activeDaysPassed = $this->activeDaysPassed($start, $end); // see method description.
$activeDaysLeft = $this->activeDaysLeft($start, $end); // see method description.
@@ -141,7 +138,7 @@ class IndexController extends Controller
return view(
'budgets.index', compact(
'availableBudgets', 'budgeted', 'spent', 'prevLoop', 'nextLoop', 'budgets', 'currencies', 'enableAddButton', 'periodTitle',
'availableBudgets', 'budgeted', 'spent', 'prevLoop', 'nextLoop', 'budgets', 'currencies', 'periodTitle',
'defaultCurrency', 'activeDaysPassed', 'activeDaysLeft', 'inactive', 'budgets', 'start', 'end', 'sums'
)
);