From 91701473af51ac4cef742758cc2261a3a3d75526 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 24 Jun 2018 08:33:06 +0200 Subject: [PATCH] Expand API with available budgets. --- .../V1/Controllers/AttachmentController.php | 10 +- .../Controllers/AvailableBudgetController.php | 183 ++++++++++++++++++ .../V1/Requests/AvailableBudgetRequest.php | 69 +++++++ app/Models/AvailableBudget.php | 32 ++- app/Repositories/Budget/BudgetRepository.php | 66 ++++++- .../Budget/BudgetRepositoryInterface.php | 26 ++- app/Transformers/AccountTransformer.php | 2 +- app/Transformers/AttachmentTransformer.php | 2 +- .../AvailableBudgetTransformer.php | 117 +++++++++++ app/Transformers/RecurrenceTransformer.php | 2 +- config/firefly.php | 23 +-- routes/api.php | 17 +- 12 files changed, 522 insertions(+), 27 deletions(-) create mode 100644 app/Api/V1/Controllers/AvailableBudgetController.php create mode 100644 app/Api/V1/Requests/AvailableBudgetRequest.php create mode 100644 app/Transformers/AvailableBudgetTransformer.php diff --git a/app/Api/V1/Controllers/AttachmentController.php b/app/Api/V1/Controllers/AttachmentController.php index 5c67f0e387..cdc5a8cd75 100644 --- a/app/Api/V1/Controllers/AttachmentController.php +++ b/app/Api/V1/Controllers/AttachmentController.php @@ -69,13 +69,15 @@ class AttachmentController extends Controller /** * Remove the specified resource from storage. * - * @param int $id + * @param Attachment $attachment * - * @return \Illuminate\Http\Response + * @return JsonResponse */ - public function destroy($id) + public function delete(Attachment $attachment): JsonResponse { - // + $this->repository->destroy($attachment); + + return response()->json([], 204); } /** diff --git a/app/Api/V1/Controllers/AvailableBudgetController.php b/app/Api/V1/Controllers/AvailableBudgetController.php new file mode 100644 index 0000000000..c209802979 --- /dev/null +++ b/app/Api/V1/Controllers/AvailableBudgetController.php @@ -0,0 +1,183 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Api\V1\Controllers; + +use FireflyIII\Api\V1\Requests\AvailableBudgetRequest; +use FireflyIII\Models\AvailableBudget; +use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; +use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; +use FireflyIII\Transformers\AvailableBudgetTransformer; +use FireflyIII\User; +use Illuminate\Http\JsonResponse; +use Illuminate\Http\Request; +use Illuminate\Pagination\LengthAwarePaginator; +use League\Fractal\Manager; +use League\Fractal\Pagination\IlluminatePaginatorAdapter; +use League\Fractal\Resource\Collection as FractalCollection; +use League\Fractal\Resource\Item; +use League\Fractal\Serializer\JsonApiSerializer; + +/** + * Class AvailableBudgetController + */ +class AvailableBudgetController extends Controller +{ + /** @var CurrencyRepositoryInterface */ + private $currencyRepository; + /** @var BudgetRepositoryInterface */ + private $repository; + + /** + * AccountController constructor. + */ + public function __construct() + { + parent::__construct(); + $this->middleware( + function ($request, $next) { + /** @var User $user */ + $user = auth()->user(); + $this->repository = app(BudgetRepositoryInterface::class); + $this->currencyRepository = app(CurrencyRepositoryInterface::class); + $this->repository->setUser($user); + + return $next($request); + } + ); + } + + /** + * Remove the specified resource from storage. + * + * @param AvailableBudget $availableBudget + * + * @return JsonResponse + */ + public function delete(AvailableBudget $availableBudget): JsonResponse + { + $this->repository->destroyAvailableBudget($availableBudget); + + return response()->json([], 204); + } + + /** + * Display a listing of the resource. + * + * @param Request $request + * + * @return JsonResponse + */ + public function index(Request $request): JsonResponse + { + // create some objects: + $manager = new Manager; + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + + // types to get, page size: + $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; + + // get list of accounts. Count it and split it. + $collection = $this->repository->getAvailableBudgets(); + $count = $collection->count(); + $availableBudgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); + + // make paginator: + $paginator = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page')); + $paginator->setPath(route('api.v1.available_budgets.index') . $this->buildParams()); + + // present to user. + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + $resource = new FractalCollection($availableBudgets, new AvailableBudgetTransformer($this->parameters), 'available_budgets'); + $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); + } + + /** + * Display the specified resource. + * + * @param Request $request + * @param AvailableBudget $availableBudget + * + * @return JsonResponse + */ + public function show(Request $request, AvailableBudget $availableBudget): JsonResponse + { + + $manager = new Manager; + + // add include parameter: + $include = $request->get('include') ?? ''; + $manager->parseIncludes($include); + + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + $resource = new Item($availableBudget, new AvailableBudgetTransformer($this->parameters), 'available_budgets'); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); + } + + /** + * Store a newly created resource in storage. + * + * @param AvailableBudgetRequest $request + * + * @return JsonResponse + */ + public function store(AvailableBudgetRequest $request): JsonResponse + { + $data = $request->getAll(); + $currency = $this->currencyRepository->findNull($data['transaction_currency_id']); + $availableBudget = $this->repository->setAvailableBudget($currency, $data['start_date'], $data['end_date'], $data['amount']); + $manager = new Manager; + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + + $resource = new Item($availableBudget, new AvailableBudgetTransformer($this->parameters), 'available_budgets'); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); + } + + /** + * Update the specified resource in storage. + * + * @param AvailableBudgetRequest $request + * @param AvailableBudget $availableBudget + * + * @return JsonResponse + */ + public function update(AvailableBudgetRequest $request, AvailableBudget $availableBudget): JsonResponse + { + $data = $request->getAll(); + $this->repository->updateAvailableBudget($availableBudget, $data); + $manager = new Manager; + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + + $resource = new Item($availableBudget, new AvailableBudgetTransformer($this->parameters), 'available_budgets'); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); + + } +} \ No newline at end of file diff --git a/app/Api/V1/Requests/AvailableBudgetRequest.php b/app/Api/V1/Requests/AvailableBudgetRequest.php new file mode 100644 index 0000000000..5631f5acc1 --- /dev/null +++ b/app/Api/V1/Requests/AvailableBudgetRequest.php @@ -0,0 +1,69 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Api\V1\Requests; + +/** + * Class AvailableBudgetRequest + */ +class AvailableBudgetRequest extends Request +{ + /** + * @return bool + */ + public function authorize(): bool + { + // Only allow authenticated users + return auth()->check(); + } + + /** + * @return array + */ + public function getAll(): array + { + return [ + 'transaction_currency_id' => $this->integer('transaction_currency_id'), + 'amount' => $this->string('amount'), + 'start_date' => $this->date('start_date'), + 'end_date' => $this->date('end_date'), + ]; + } + + /** + * @return array + */ + public function rules(): array + { + $rules = [ + 'transaction_currency_id' => 'required|numeric|exists:transaction_currencies,id', + 'amount' => 'required|numeric|more:0', + 'start_date' => 'required|date|before:end_date', + 'end_date' => 'required|date|after:start_date', + ]; + + return $rules; + } + + +} \ No newline at end of file diff --git a/app/Models/AvailableBudget.php b/app/Models/AvailableBudget.php index 2f023f4ad5..6cfbc53862 100644 --- a/app/Models/AvailableBudget.php +++ b/app/Models/AvailableBudget.php @@ -22,13 +22,25 @@ declare(strict_types=1); namespace FireflyIII\Models; +use Carbon\Carbon; use FireflyIII\User; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\SoftDeletes; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Class AvailableBudget. + * + * @property int $id + * @property Carbon $created_at + * @property Carbon $updated_at + * @property User $user + * @property TransactionCurrency $transactionCurrency + * @property int $transaction_currency_id + * @property Carbon $start_date + * @property Carbon $end_date + * @property string $amount */ class AvailableBudget extends Model { @@ -49,11 +61,29 @@ class AvailableBudget extends Model /** @var array */ protected $fillable = ['user_id', 'transaction_currency_id', 'amount', 'start_date', 'end_date']; + /** + * @param string $value + * + * @return AvailableBudget + * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException + */ + public static function routeBinder(string $value): AvailableBudget + { + if (auth()->check()) { + $availableBudgetId = (int)$value; + $availableBudget = auth()->user()->availableBudgets()->find($availableBudgetId); + if (null !== $availableBudget) { + return $availableBudget; + } + } + throw new NotFoundHttpException; + } + /** * @codeCoverageIgnore * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function transactionCurrency() + public function transactionCurrency(): BelongsTo { return $this->belongsTo(TransactionCurrency::class); } diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index c0ee968441..8fb69c57c5 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace FireflyIII\Repositories\Budget; use Carbon\Carbon; +use Exception; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Helpers\Collector\JournalCollectorInterface; use FireflyIII\Models\AccountType; use FireflyIII\Models\AvailableBudget; @@ -156,15 +158,30 @@ class BudgetRepository implements BudgetRepositoryInterface * @param Budget $budget * * @return bool - * @throws \Exception */ public function destroy(Budget $budget): bool { - $budget->delete(); + try { + $budget->delete(); + } catch (Exception $e) { + Log::error(sprintf('Could not delete budget: %s', $e->getMessage())); + } return true; } + /** + * @param AvailableBudget $availableBudget + */ + public function destroyAvailableBudget(AvailableBudget $availableBudget): void + { + try { + $availableBudget->delete(); + } catch (Exception $e) { + Log::error(sprintf('Could not delete available budget: %s', $e->getMessage())); + } + } + /** * Filters entries from the result set generated by getBudgetPeriodReport. * @@ -355,6 +372,16 @@ class BudgetRepository implements BudgetRepositoryInterface return $amount; } + /** + * Returns all available budget objects. + * + * @return Collection + */ + public function getAvailableBudgets(): Collection + { + return $this->user->availableBudgets()->get(); + } + /** * @param Budget $budget * @param Carbon $start @@ -527,9 +554,9 @@ class BudgetRepository implements BudgetRepositoryInterface * @param Carbon $end * @param string $amount * - * @return bool + * @return AvailableBudget */ - public function setAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end, string $amount): bool + public function setAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end, string $amount): AvailableBudget { $availableBudget = $this->user->availableBudgets() ->where('transaction_currency_id', $currency->id) @@ -545,7 +572,7 @@ class BudgetRepository implements BudgetRepositoryInterface $availableBudget->amount = $amount; $availableBudget->save(); - return true; + return $availableBudget; } /** @@ -652,6 +679,35 @@ class BudgetRepository implements BudgetRepositoryInterface return $budget; } + /** + * @param AvailableBudget $availableBudget + * @param array $data + * + * @return AvailableBudget + * @throws FireflyException + */ + public function updateAvailableBudget(AvailableBudget $availableBudget, array $data): AvailableBudget + { + $existing = $this->user->availableBudgets() + ->where('transaction_currency_id', $data['transaction_currency_id']) + ->where('start_date', $data['start_date']->format('Y-m-d 00:00:00')) + ->where('end_date', $data['end_date']->format('Y-m-d 00:00:00')) + ->where('id', '!=', $availableBudget->id) + ->first(); + + if (null !== $existing) { + throw new FireflyException(sprintf('An entry already exists for these parameters: available budget object with ID #%d', $existing->id)); + } + $availableBudget->transaction_currency_id = $data['transaction_currency_id']; + $availableBudget->start_date = $data['start_date']; + $availableBudget->end_date = $data['end_date']; + $availableBudget->amount = $data['amount']; + $availableBudget->save(); + + return $availableBudget; + + } + /** * @param Budget $budget * @param Carbon $start diff --git a/app/Repositories/Budget/BudgetRepositoryInterface.php b/app/Repositories/Budget/BudgetRepositoryInterface.php index e2197b76ba..cbc9b224a3 100644 --- a/app/Repositories/Budget/BudgetRepositoryInterface.php +++ b/app/Repositories/Budget/BudgetRepositoryInterface.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Repositories\Budget; use Carbon\Carbon; +use FireflyIII\Models\AvailableBudget; use FireflyIII\Models\Budget; use FireflyIII\Models\BudgetLimit; use FireflyIII\Models\TransactionCurrency; @@ -69,6 +70,11 @@ interface BudgetRepositoryInterface */ public function destroy(Budget $budget): bool; + /** + * @param AvailableBudget $availableBudget + */ + public function destroyAvailableBudget(AvailableBudget $availableBudget): void; + /** * Filters entries from the result set generated by getBudgetPeriodReport. * @@ -141,6 +147,13 @@ interface BudgetRepositoryInterface */ public function getAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end): string; + /** + * Returns all available budget objects. + * + * @return Collection + */ + public function getAvailableBudgets(): Collection; + /** * @param Budget $budget * @param Carbon $start @@ -194,9 +207,9 @@ interface BudgetRepositoryInterface * @param Carbon $end * @param string $amount * - * @return bool + * @return AvailableBudget */ - public function setAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end, string $amount): bool; + public function setAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end, string $amount): AvailableBudget; /** * @param User $user @@ -213,6 +226,7 @@ interface BudgetRepositoryInterface */ public function spentInPeriod(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): string; + /** * @param Collection $accounts * @param Carbon $start @@ -237,6 +251,14 @@ interface BudgetRepositoryInterface */ public function update(Budget $budget, array $data): Budget; + /** + * @param AvailableBudget $availableBudget + * @param array $data + * + * @return AvailableBudget + */ + public function updateAvailableBudget(AvailableBudget $availableBudget, array $data): AvailableBudget; + /** * @param Budget $budget * @param Carbon $start diff --git a/app/Transformers/AccountTransformer.php b/app/Transformers/AccountTransformer.php index c238a28dd8..64ec626911 100644 --- a/app/Transformers/AccountTransformer.php +++ b/app/Transformers/AccountTransformer.php @@ -132,7 +132,7 @@ class AccountTransformer extends TransformerAbstract */ public function includeUser(Account $account): Item { - return $this->item($account->user, new UserTransformer($this->parameters), 'user'); + return $this->item($account->user, new UserTransformer($this->parameters), 'users'); } /** diff --git a/app/Transformers/AttachmentTransformer.php b/app/Transformers/AttachmentTransformer.php index 81ba473173..f1c6ac01bd 100644 --- a/app/Transformers/AttachmentTransformer.php +++ b/app/Transformers/AttachmentTransformer.php @@ -74,7 +74,7 @@ class AttachmentTransformer extends TransformerAbstract */ public function includeUser(Attachment $attachment): Item { - return $this->item($attachment->user, new UserTransformer($this->parameters), 'user'); + return $this->item($attachment->user, new UserTransformer($this->parameters), 'users'); } /** diff --git a/app/Transformers/AvailableBudgetTransformer.php b/app/Transformers/AvailableBudgetTransformer.php new file mode 100644 index 0000000000..0f46939267 --- /dev/null +++ b/app/Transformers/AvailableBudgetTransformer.php @@ -0,0 +1,117 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Transformers; + + +use FireflyIII\Models\AvailableBudget; +use League\Fractal\Resource\Item; +use League\Fractal\TransformerAbstract; +use Symfony\Component\HttpFoundation\ParameterBag; + +class AvailableBudgetTransformer extends TransformerAbstract +{ + /** + * List of resources possible to include + * + * @var array + */ + protected $availableIncludes = ['transaction_currency', 'user']; + /** + * List of resources to automatically include + * + * @var array + */ + protected $defaultIncludes = ['transaction_currency']; + + /** @var ParameterBag */ + protected $parameters; + + /** + * CurrencyTransformer constructor. + * + * @codeCoverageIgnore + * + * @param ParameterBag $parameters + */ + public function __construct(ParameterBag $parameters) + { + $this->parameters = $parameters; + } + + /** + * Attach the currency. + * + * @codeCoverageIgnore + * + * @param AvailableBudget $availableBudget + * + * @return Item + */ + public function includeTransactionCurrency(AvailableBudget $availableBudget): Item + { + return $this->item($availableBudget->transactionCurrency, new CurrencyTransformer($this->parameters), 'transaction_currencies'); + } + + /** + * Attach the user. + * + * @codeCoverageIgnore + * + * @param AvailableBudget $availableBudget + * + * @return Item + */ + public function includeUser(AvailableBudget $availableBudget): Item + { + return $this->item($availableBudget->user, new UserTransformer($this->parameters), 'users'); + } + + /** + * Transform the note. + * + * @param AvailableBudget $availableBudget + * + * @return array + */ + public function transform(AvailableBudget $availableBudget): array + { + $data = [ + 'id' => (int)$availableBudget->id, + 'updated_at' => $availableBudget->updated_at->toAtomString(), + 'created_at' => $availableBudget->created_at->toAtomString(), + 'start_date' => $availableBudget->start_date->format('Y-m-d'), + 'end_date' => $availableBudget->end_date->format('Y-m-d'), + 'amount' => round($availableBudget->amount, $availableBudget->transactionCurrency->decimal_places), + 'links' => [ + [ + 'rel' => 'self', + 'uri' => '/available_budgets/' . $availableBudget->id, + ], + ], + ]; + + return $data; + } + +} \ No newline at end of file diff --git a/app/Transformers/RecurrenceTransformer.php b/app/Transformers/RecurrenceTransformer.php index 1d60824b8c..8a0bba3a1c 100644 --- a/app/Transformers/RecurrenceTransformer.php +++ b/app/Transformers/RecurrenceTransformer.php @@ -84,7 +84,7 @@ class RecurrenceTransformer extends TransformerAbstract */ public function includeUser(Recurrence $recurrence): Item { - return $this->item($recurrence->user, new UserTransformer($this->parameters), 'user'); + return $this->item($recurrence->user, new UserTransformer($this->parameters), 'users'); } /** diff --git a/config/firefly.php b/config/firefly.php index 7721649b9b..0878d882da 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -83,16 +83,16 @@ use FireflyIII\TransactionRules\Triggers\UserAction; */ return [ - 'configuration' => [ + 'configuration' => [ 'single_user_mode' => true, 'is_demo_site' => false, ], - 'encryption' => null === env('USE_ENCRYPTION') || env('USE_ENCRYPTION') === true, - 'version' => '4.7.4', - 'api_version' => '0.3', - 'db_version' => 4, - 'maxUploadSize' => 15242880, - 'allowedMimes' => [ + 'encryption' => null === env('USE_ENCRYPTION') || env('USE_ENCRYPTION') === true, + 'version' => '4.7.4', + 'api_version' => '0.3', + 'db_version' => 4, + 'maxUploadSize' => 15242880, + 'allowedMimes' => [ /* plain files */ 'text/plain', @@ -154,8 +154,8 @@ return [ 'application/vnd.oasis.opendocument.database', 'application/vnd.oasis.opendocument.image', ], - 'list_length' => 10, - 'export_formats' => [ + 'list_length' => 10, + 'export_formats' => [ 'csv' => CsvExporter::class, ], 'default_export_format' => 'csv', @@ -260,6 +260,7 @@ return [ // models 'account' => \FireflyIII\Models\Account::class, 'attachment' => \FireflyIII\Models\Attachment::class, + 'availableBudget' => \FireflyIII\Models\AvailableBudget::class, 'bill' => \FireflyIII\Models\Bill::class, 'budget' => \FireflyIII\Models\Budget::class, 'budgetLimit' => \FireflyIII\Models\BudgetLimit::class, @@ -271,7 +272,7 @@ return [ 'piggyBank' => \FireflyIII\Models\PiggyBank::class, 'tj' => \FireflyIII\Models\TransactionJournal::class, 'tag' => \FireflyIII\Models\Tag::class, - 'recurrence' => \FireflyIII\Models\Recurrence::class, + 'recurrence' => \FireflyIII\Models\Recurrence::class, 'rule' => \FireflyIII\Models\Rule::class, 'ruleGroup' => \FireflyIII\Models\RuleGroup::class, 'exportJob' => \FireflyIII\Models\ExportJob::class, @@ -280,7 +281,7 @@ return [ 'user' => \FireflyIII\User::class, // strings - 'import_provider' => \FireflyIII\Support\Binder\ImportProvider::class, + 'import_provider' => \FireflyIII\Support\Binder\ImportProvider::class, // dates 'start_date' => \FireflyIII\Support\Binder\Date::class, diff --git a/routes/api.php b/routes/api.php index 6db99723e3..d4bc282787 100644 --- a/routes/api.php +++ b/routes/api.php @@ -47,7 +47,7 @@ Route::group( ['middleware' => ['auth:api', 'bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'attachments', 'as' => 'api.v1.attachments.'], function () { - // Accounts API routes: + // Attachment API routes: Route::get('', ['uses' => 'AttachmentController@index', 'as' => 'index']); Route::post('', ['uses' => 'AttachmentController@store', 'as' => 'store']); Route::get('{attachment}', ['uses' => 'AttachmentController@show', 'as' => 'show']); @@ -58,6 +58,21 @@ Route::group( } ); +Route::group( + ['middleware' => ['auth:api', 'bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'available_budgets', 'as' => 'api.v1.available_budgets.'], + function () { + + // Available Budget API routes: + Route::get('', ['uses' => 'AvailableBudgetController@index', 'as' => 'index']); + Route::post('', ['uses' => 'AvailableBudgetController@store', 'as' => 'store']); + Route::get('{availableBudget}', ['uses' => 'AvailableBudgetController@show', 'as' => 'show']); + Route::get('{availableBudget}/download', ['uses' => 'AvailableBudgetController@download', 'as' => 'download']); + Route::post('{availableBudget}/upload', ['uses' => 'AvailableBudgetController@upload', 'as' => 'upload']); + Route::put('{availableBudget}', ['uses' => 'AvailableBudgetController@update', 'as' => 'update']); + Route::delete('{availableBudget}', ['uses' => 'AvailableBudgetController@delete', 'as' => 'delete']); + } +); + Route::group( ['middleware' => ['auth:api', 'bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'bills', 'as' => 'api.v1.bills.'], function () {