Can now create auto budget over API

This commit is contained in:
James Cole 2020-03-14 07:30:55 +01:00
parent 309633069c
commit d1d11ae717
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
15 changed files with 183 additions and 47 deletions

View File

@ -25,7 +25,8 @@ namespace FireflyIII\Api\V1\Controllers;
use Exception;
use FireflyIII\Api\V1\Requests\BudgetLimitRequest;
use FireflyIII\Api\V1\Requests\BudgetRequest;
use FireflyIII\Api\V1\Requests\BudgetStoreRequest;
use FireflyIII\Api\V1\Requests\BudgetUpdateRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Budget;
@ -179,13 +180,13 @@ class BudgetController extends Controller
/**
* Store a budget.
*
* @param BudgetRequest $request
* @param BudgetStoreRequest $request
*
* @return JsonResponse
* @throws FireflyException
*
*/
public function store(BudgetRequest $request): JsonResponse
public function store(BudgetStoreRequest $request): JsonResponse
{
$budget = $this->repository->store($request->getAll());
$manager = $this->getManager();
@ -291,12 +292,12 @@ class BudgetController extends Controller
/**
* Update a budget.
*
* @param BudgetRequest $request
* @param BudgetUpdateRequest $request
* @param Budget $budget
*
* @return JsonResponse
*/
public function update(BudgetRequest $request, Budget $budget): JsonResponse
public function update(BudgetUpdateRequest $request, Budget $budget): JsonResponse
{
$data = $request->getAll();
$budget = $this->repository->update($budget, $data);

View File

@ -85,7 +85,7 @@ class AvailableBudgetController extends Controller
}
$left = bcadd($availableBudget->amount, (string)$spent);
// left less than zero? Set to zero.
if (bccomp($left, '0') === -1) {
if (-1 === bccomp($left, '0')) {
$left = '0';
}

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* AccountController.php
* Copyright (c) 2019 james@firefly-iii.org

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* TransactionController.php
* Copyright (c) 2019 james@firefly-iii.org
@ -23,8 +24,6 @@ namespace FireflyIII\Api\V1\Controllers\Search;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Support\Search\SearchInterface;
use FireflyIII\Support\Search\TransactionSearch;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
@ -35,13 +34,13 @@ use Illuminate\Http\Response;
class TransactionController extends Controller
{
/** @var string */
const SEARCH_ALL = 'all';
public const SEARCH_ALL = 'all';
/** @var string */
const SEARCH_DESCRIPTION = 'description';
public const SEARCH_DESCRIPTION = 'description';
/** @var string */
const SEARCH_NOTES = 'notes';
public const SEARCH_NOTES = 'notes';
/** @var string */
const SEARCH_ACCOUNTS = 'accounts';
public const SEARCH_ACCOUNTS = 'accounts';
/** @var array */
private $validFields;
@ -59,7 +58,7 @@ class TransactionController extends Controller
/**
* @param Request $request
*
* @return JsonResponse|Response
* @return void
*/
public function search(Request $request)
{

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* TransferController.php
* Copyright (c) 2019 james@firefly-iii.org
@ -41,10 +42,9 @@ use League\Fractal\Resource\Collection as FractalCollection;
class TransferController extends Controller
{
/**
* @param Request $request
* @param TransferRequest $request
*
* @return JsonResponse|Response
* @throws FireflyException
*/
public function search(TransferRequest $request)
{

View File

@ -42,7 +42,6 @@ use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Collection;
/**
* Class SummaryController

View File

@ -0,0 +1,106 @@
<?php
/**
* BudgetStoreRequest.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\Api\V1\Requests;
use FireflyIII\Rules\IsBoolean;
use Illuminate\Validation\Validator;
/**
* Class BudgetStoreRequest
*
* @codeCoverageIgnore
*/
class BudgetStoreRequest extends Request
{
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
$active = true;
if (null !== $this->get('active')) {
$active = $this->boolean('active');
}
return [
'name' => $this->string('name'),
'active' => $active,
'order' => 0,
'auto_budget_type' => $this->string('auto_budget_type'),
'transaction_currency_id' => $this->integer('auto_budget_currency_id'),
'transaction_currency_code' => $this->string('auto_budget_currency_code'),
'auto_budget_amount' => $this->string('auto_budget_amount'),
'auto_budget_period' => $this->string('auto_budget_period'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
return [
'name' => 'required|between:1,100|uniqueObjectForUser:budgets,name',
'active' => [new IsBoolean],
'auto_budget_type' => 'in:reset,rollover',
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
'auto_budget_currency_code' => 'exists:transaction_currencies,code',
'auto_budget_amount' => 'min:0|max:1000000000',
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly',
];
}
/**
* Configure the validator instance with special rules for after the basic validation rules.
*
* @param Validator $validator
*
* @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
function (Validator $validator) {
// validate all account info
$this->validateAutoBudgetAmount($validator);
}
);
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
* BudgetRequest.php
* BudgetUpdateRequest.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
@ -23,16 +23,14 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\Budget;
use FireflyIII\Rules\IsBoolean;
/**
* Class BudgetRequest
* Class BudgetUpdateRequest
*
* @codeCoverageIgnore
* TODO AFTER 4.8,0: split this into two request classes.
*/
class BudgetRequest extends Request
class BudgetUpdateRequest extends Request
{
/**
* Authorize logged in users.
@ -71,21 +69,11 @@ class BudgetRequest extends Request
*/
public function rules(): array
{
$rules = [
'name' => 'required|between:1,100|uniqueObjectForUser:budgets,name',
$budget = $this->route()->parameter('budget');
return [
'name' => sprintf('required|between:1,100|uniqueObjectForUser:budgets,name,%d', $budget->id),
'active' => [new IsBoolean],
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
/** @var Budget $budget */
$budget = $this->route()->parameter('budget');
$rules['name'] = sprintf('required|between:1,100|uniqueObjectForUser:budgets,name,%d', $budget->id);
break;
}
return $rules;
}
}

View File

@ -34,4 +34,5 @@ use FireflyIII\Http\Requests\Request as FireflyIIIRequest;
*/
class Request extends FireflyIIIRequest
{
}

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* TransferRequest.php
* Copyright (c) 2019 james@firefly-iii.org

View File

@ -50,7 +50,7 @@ class BudgetFormStoreRequest extends Request
return [
'name' => $this->string('name'),
'active' => $this->boolean('active'),
'auto_budget_option' => $this->integer('auto_budget_option'),
'auto_budget_type' => $this->integer('auto_budget_type'),
'transaction_currency_id' => $this->integer('transaction_currency_id'),
'auto_budget_amount' => $this->string('auto_budget_amount'),
'auto_budget_period' => $this->string('auto_budget_period'),

View File

@ -387,17 +387,27 @@ class Request extends FormRequest
return $data;
}
/**
* @param Validator $validator
*/
protected function validateAutoBudgetAmount(Validator $validator): void
{
$data = $validator->getData();
$option = (int)$data['auto_budget_option'];
$amount = $data['auto_budget_amount'] ?? '';
switch ($option) {
$data = $validator->getData();
$type = $data['auto_budget_type'] ?? '';
$amount = $data['auto_budget_amount'] ?? '';
$period = (string)($data['auto_budget_period'] ?? '');
$currencyId = $data['auto_budget_currency_id'] ?? '';
$currencyCode = $data['auto_budget_currency_code'] ?? '';
if (is_numeric($type)) {
$type = (int)$type;
}
switch ($type) {
case AutoBudget::AUTO_BUDGET_RESET:
case AutoBudget::AUTO_BUDGET_ROLLOVER:
case 'reset':
case 'rollover':
// basic float check:
if ('' === $amount) {
$validator->errors()->add('auto_budget_amount', (string)trans('validation.amount_required_for_auto_budget'));
@ -405,8 +415,16 @@ class Request extends FormRequest
if (1 !== bccomp((string)$amount, '0')) {
$validator->errors()->add('auto_budget_amount', (string)trans('validation.auto_budget_amount_positive'));
}
if ('' === $period) {
$validator->errors()->add('auto_budget_period', (string)trans('validation.auto_budget_period_mandatory'));
}
if('' === $currencyCode && '' === $currencyId) {
$validator->errors()->add('auto_budget_amount', (string)trans('validation.require_currency_info'));
}
break;
}
}
}

View File

@ -25,13 +25,14 @@ namespace FireflyIII\Repositories\Budget;
use Carbon\Carbon;
use DB;
use Exception;
use FireflyIII\Models\AutoBudget;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\AutoBudget;
use FireflyIII\Models\Budget;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\RecurrenceTransactionMeta;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\RuleTrigger;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Services\Internal\Destroy\BudgetDestroyService;
use FireflyIII\User;
use Illuminate\Database\QueryException;
@ -290,17 +291,37 @@ class BudgetRepository implements BudgetRepositoryInterface
}
// try to create associated auto budget:
$option = $data['auto_budget_option'] ?? 0;
if (0 === $option) {
$type = $data['auto_budget_type'] ?? 0;
if (0 === $type) {
return $newBudget;
}
if ('reset' === $type) {
$type = AutoBudget::AUTO_BUDGET_RESET;
}
if ('rollover' === $type) {
$type = AutoBudget::AUTO_BUDGET_ROLLOVER;
}
$repos = app(CurrencyRepositoryInterface::class);
$currencyId = (int)($data['transaction_currency_id'] ?? 0);
$currencyCode = (string)($data['transaction_currency_code'] ?? '');
$currency = $repos->findNull($currencyId);
if(null === $currency) {
$currency = $repos->findByCodeNull($currencyCode);
}
if(null === $currency) {
$currency = app('amount')->getDefaultCurrencyByUser($this->user);
}
$autoBudget = new AutoBudget;
$autoBudget->budget()->associate($newBudget);
$autoBudget->transaction_currency_id = $data['transaction_currency_id'] ?? 1;
$autoBudget->auto_budget_type = $option;
$autoBudget->transaction_currency_id = $currency->id;
$autoBudget->auto_budget_type = $type;
$autoBudget->amount = $data['auto_budget_amount'] ?? '1';
$autoBudget->period = $data['auto_budget_period'] ?? 'monthly';
$autoBudget->save();
return $newBudget;
}

View File

@ -98,11 +98,11 @@ class BudgetTransformer extends AbstractTransformer
'updated_at' => $budget->updated_at->toAtomString(),
'active' => $budget->active,
'name' => $budget->name,
'auto_budget_type' => $abType,
'auto_budget_period' => $abPeriod,
'auto_budget_currency_id' => $abCurrencyId,
'auto_budget_currency_code' => $abCurrencyCode,
'auto_budget_type' => $abType,
'auto_budget_amount' => $abAmount,
'auto_budget_period' => $abPeriod,
'spent' => $spent,
'links' => [
[

View File

@ -204,4 +204,5 @@ return [
'amount_required_for_auto_budget' => 'The amount is required.',
'auto_budget_amount_positive' => 'The amount must be more than zero.',
'auto_budget_period_mandatory' => 'The auto budget period is a mandatory field.',
];