From eb616f36ea76781b5cf638c4645a1f4e0429d084 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 15 Nov 2020 14:02:29 +0100 Subject: [PATCH] Expand API. --- .../BudgetLimit/IndexController.php | 92 +++++++++++++++++++ .../V1/Controllers/BudgetLimitController.php | 15 ++- app/Models/BudgetLimit.php | 15 +-- app/Transformers/BudgetLimitTransformer.php | 30 +++++- app/Transformers/BudgetTransformer.php | 16 ++-- routes/api.php | 11 +++ 6 files changed, 152 insertions(+), 27 deletions(-) create mode 100644 app/Api/V1/Controllers/BudgetLimit/IndexController.php diff --git a/app/Api/V1/Controllers/BudgetLimit/IndexController.php b/app/Api/V1/Controllers/BudgetLimit/IndexController.php new file mode 100644 index 0000000000..5ffae39e56 --- /dev/null +++ b/app/Api/V1/Controllers/BudgetLimit/IndexController.php @@ -0,0 +1,92 @@ +. + */ + +namespace FireflyIII\Api\V1\Controllers\BudgetLimit; + + +use FireflyIII\Api\V1\Controllers\Controller; +use FireflyIII\Api\V1\Requests\DateRequest; +use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface; +use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; +use FireflyIII\Transformers\BudgetLimitTransformer; +use FireflyIII\User; +use Illuminate\Http\JsonResponse; +use Illuminate\Pagination\LengthAwarePaginator; +use League\Fractal\Pagination\IlluminatePaginatorAdapter; +use League\Fractal\Resource\Collection as FractalCollection; + +/** + * Class IndexController + */ +class IndexController extends Controller +{ + + private BudgetLimitRepositoryInterface $blRepository; + private BudgetRepositoryInterface $repository; + + /** + * IndexController constructor. + * + * @codeCoverageIgnore + */ + public function __construct() + { + parent::__construct(); + $this->middleware( + function ($request, $next) { + /** @var User $user */ + $user = auth()->user(); + $this->repository = app(BudgetRepositoryInterface::class); + $this->blRepository = app(BudgetLimitRepositoryInterface::class); + $this->repository->setUser($user); + $this->blRepository->setUser($user); + + return $next($request); + } + ); + } + + /** + * Return all budget limits in a range. + * + * @return JsonResponse + */ + public function index(DateRequest $request): JsonResponse + { + $dates = $request->getAll(); + $manager = $this->getManager(); + $manager->parseIncludes('budget'); + $budgetLimits = $this->blRepository->getAllBudgetLimits($dates['start'], $dates['end']); + $budgetLimits = $budgetLimits->slice(0, 5); + /** @var BudgetLimitTransformer $transformer */ + $transformer = app(BudgetLimitTransformer::class); + $transformer->setParameters($this->parameters); + + $paginator = new LengthAwarePaginator($budgetLimits, $budgetLimits->count(), 1000, $this->parameters->get('page')); + $paginator->setPath(route('api.v1.budget_limits.index') . $this->buildParams()); + + $resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits'); + $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); + + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); + } +} \ No newline at end of file diff --git a/app/Api/V1/Controllers/BudgetLimitController.php b/app/Api/V1/Controllers/BudgetLimitController.php index d4fbd34567..353277b03c 100644 --- a/app/Api/V1/Controllers/BudgetLimitController.php +++ b/app/Api/V1/Controllers/BudgetLimitController.php @@ -50,11 +50,8 @@ class BudgetLimitController extends Controller { use TransactionFilter; - /** @var BudgetLimitRepositoryInterface */ - private $blRepository; - - /** @var BudgetRepositoryInterface The budget repository */ - private $repository; + private BudgetLimitRepositoryInterface $blRepository; + private BudgetRepositoryInterface $repository; /** @@ -105,9 +102,9 @@ class BudgetLimitController extends Controller public function index(Request $request): JsonResponse { $manager = $this->getManager(); - $budgetId = (int) ($request->get('budget_id') ?? 0); + $budgetId = (int)($request->get('budget_id') ?? 0); $budget = $this->repository->findNull($budgetId); - $pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; + $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; $this->parameters->set('budget_id', $budgetId); $collection = new Collection; @@ -193,7 +190,7 @@ class BudgetLimitController extends Controller */ public function transactions(Request $request, BudgetLimit $budgetLimit): JsonResponse { - $pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; + $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; $type = $request->get('type') ?? 'default'; $this->parameters->set('type', $type); @@ -239,7 +236,7 @@ class BudgetLimitController extends Controller * Update the specified resource in storage. * * @param BudgetLimitUpdateRequest $request - * @param BudgetLimit $budgetLimit + * @param BudgetLimit $budgetLimit * * @return JsonResponse */ diff --git a/app/Models/BudgetLimit.php b/app/Models/BudgetLimit.php index 4b924ff245..350ef2a261 100644 --- a/app/Models/BudgetLimit.php +++ b/app/Models/BudgetLimit.php @@ -43,6 +43,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @property string spent * @property int $transaction_currency_id * @property TransactionCurrency $transactionCurrency + * @property string $repeat_freq + * @property bool @auto_budget * @method static Builder|BudgetLimit newModelQuery() * @method static Builder|BudgetLimit newQuery() * @method static Builder|BudgetLimit query() @@ -65,10 +67,11 @@ class BudgetLimit extends Model */ protected $casts = [ - 'created_at' => 'datetime', - 'updated_at' => 'datetime', - 'start_date' => 'date', - 'end_date' => 'date', + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + 'start_date' => 'date', + 'end_date' => 'date', + 'auto_budget' => 'boolean', ]; /** @var array Fields that can be filled */ @@ -79,13 +82,13 @@ class BudgetLimit extends Model * * @param string $value * - * @throws NotFoundHttpException * @return mixed + * @throws NotFoundHttpException */ public static function routeBinder(string $value): BudgetLimit { if (auth()->check()) { - $budgetLimitId = (int) $value; + $budgetLimitId = (int)$value; $budgetLimit = self::where('budget_limits.id', $budgetLimitId) ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') ->where('budgets.user_id', auth()->user()->id) diff --git a/app/Transformers/BudgetLimitTransformer.php b/app/Transformers/BudgetLimitTransformer.php index cd174b39a1..a30444dec5 100644 --- a/app/Transformers/BudgetLimitTransformer.php +++ b/app/Transformers/BudgetLimitTransformer.php @@ -24,12 +24,31 @@ declare(strict_types=1); namespace FireflyIII\Transformers; use FireflyIII\Models\BudgetLimit; +use League\Fractal\Resource\Item; /** * Class BudgetLimitTransformer */ class BudgetLimitTransformer extends AbstractTransformer { + /** @var string[] */ + protected $availableIncludes + = [ + 'budget', + ]; + + /** + * Include Budget + * + * @param BudgetLimit $limit + * + * @return Item + */ + public function includeBudget(BudgetLimit $limit) + { + return $this->item($limit->budget, new BudgetTransformer,'budgets '); + } + /** * Transform the note. * @@ -48,26 +67,29 @@ class BudgetLimitTransformer extends AbstractTransformer $currencySymbol = null; if (null !== $currency) { $amount = $budgetLimit->amount; - $currencyId = (int) $currency->id; + $currencyId = (int)$currency->id; $currencyName = $currency->name; $currencyCode = $currency->code; $currencySymbol = $currency->symbol; $currencyDecimalPlaces = $currency->decimal_places; } - $amount = number_format((float) $amount, $currencyDecimalPlaces, '.', ''); + $amount = number_format((float)$amount, $currencyDecimalPlaces, '.', ''); + return [ - 'id' => (int) $budgetLimit->id, + 'id' => (int)$budgetLimit->id, 'created_at' => $budgetLimit->created_at->toAtomString(), 'updated_at' => $budgetLimit->updated_at->toAtomString(), 'start' => $budgetLimit->start_date->format('Y-m-d'), 'end' => $budgetLimit->end_date->format('Y-m-d'), - 'budget_id' => (int) $budgetLimit->budget_id, + 'budget_id' => (int)$budgetLimit->budget_id, 'currency_id' => $currencyId, 'currency_code' => $currencyCode, 'currency_name' => $currencyName, 'currency_decimal_places' => $currencyName, 'currency_symbol' => $currencySymbol, 'amount' => $amount, + 'repeat_freq' => $budgetLimit->repeat_freq, + 'auto_budget' => $budgetLimit->auto_budget, 'links' => [ [ 'rel' => 'self', diff --git a/app/Transformers/BudgetTransformer.php b/app/Transformers/BudgetTransformer.php index c4047f8aaf..cc0cd4705b 100644 --- a/app/Transformers/BudgetTransformer.php +++ b/app/Transformers/BudgetTransformer.php @@ -29,16 +29,15 @@ use FireflyIII\Models\Budget; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Budget\OperationsRepositoryInterface; use Illuminate\Support\Collection; +use Symfony\Component\HttpFoundation\ParameterBag; /** * Class BudgetTransformer */ class BudgetTransformer extends AbstractTransformer { - /** @var OperationsRepositoryInterface */ - private $opsRepository; - /** @var BudgetRepositoryInterface */ - private $repository; + private OperationsRepositoryInterface $opsRepository; + private BudgetRepositoryInterface $repository; /** * BudgetTransformer constructor. @@ -49,6 +48,7 @@ class BudgetTransformer extends AbstractTransformer { $this->opsRepository = app(OperationsRepositoryInterface::class); $this->repository = app(BudgetRepositoryInterface::class); + $this->parameters = new ParameterBag(); } /** @@ -66,7 +66,7 @@ class BudgetTransformer extends AbstractTransformer $autoBudget = $this->repository->getAutoBudget($budget); $spent = []; if (null !== $start && null !== $end) { - $spent = $this->beautify($this->opsRepository->sumExpenses($start, $end, null, new Collection([$budget]))); + $spent = $this->beautify($this->opsRepository->sumExpenses($start, $end, null, new Collection([$budget]))); } $abCurrencyId = null; @@ -81,10 +81,10 @@ class BudgetTransformer extends AbstractTransformer ]; if (null !== $autoBudget) { - $abCurrencyId = (int) $autoBudget->transactionCurrency->id; + $abCurrencyId = (int)$autoBudget->transactionCurrency->id; $abCurrencyCode = $autoBudget->transactionCurrency->code; $abType = $types[$autoBudget->auto_budget_type]; - $abAmount = number_format((float) $autoBudget->amount, $autoBudget->transactionCurrency->decimal_places, '.', ''); + $abAmount = number_format((float)$autoBudget->amount, $autoBudget->transactionCurrency->decimal_places, '.', ''); $abPeriod = $autoBudget->period; } @@ -118,7 +118,7 @@ class BudgetTransformer extends AbstractTransformer { $return = []; foreach ($array as $data) { - $data['sum'] = number_format((float) $data['sum'], (int) $data['currency_decimal_places'], '.', ''); + $data['sum'] = number_format((float)$data['sum'], (int)$data['currency_decimal_places'], '.', ''); $return[] = $data; } diff --git a/routes/api.php b/routes/api.php index b2cd3eb29b..969ca5a72c 100644 --- a/routes/api.php +++ b/routes/api.php @@ -175,6 +175,17 @@ Route::group( } ); + +Route::group( + ['namespace' => 'FireflyIII\Api\V1\Controllers\BudgetLimit', 'prefix' => 'limits', + 'as' => 'api.v1.limits.',], + static function () { + + // Budget API routes: + Route::get('', ['uses' => 'IndexController@index', 'as' => 'index']); + } +); + Route::group( ['namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'categories', 'as' => 'api.v1.categories.',],