From f5c56e02da25dc178f4f691907cb2e0af0403b84 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 30 Nov 2024 05:42:59 +0100 Subject: [PATCH] API allows update/set of budget limit notes. https://github.com/firefly-iii/firefly-iii/issues/5523 --- .../Models/BudgetLimit/StoreController.php | 9 +- .../Models/BudgetLimit/StoreRequest.php | 2 + .../Models/BudgetLimit/UpdateRequest.php | 9 +- app/Models/Account.php | 2 +- app/Models/BudgetLimit.php | 9 + .../Budget/BudgetLimitRepository.php | 280 ++++++++++-------- .../Budget/BudgetLimitRepositoryInterface.php | 3 + app/Transformers/BudgetLimitTransformer.php | 17 +- 8 files changed, 187 insertions(+), 144 deletions(-) diff --git a/app/Api/V1/Controllers/Models/BudgetLimit/StoreController.php b/app/Api/V1/Controllers/Models/BudgetLimit/StoreController.php index 6f899b19ce..6f4cd02427 100644 --- a/app/Api/V1/Controllers/Models/BudgetLimit/StoreController.php +++ b/app/Api/V1/Controllers/Models/BudgetLimit/StoreController.php @@ -69,16 +69,17 @@ class StoreController extends Controller $data = $request->getAll(); $data['start_date'] = $data['start']; $data['end_date'] = $data['end']; + $data['notes'] = $data['notes']; $data['budget_id'] = $budget->id; - $budgetLimit = $this->blRepository->store($data); - $manager = $this->getManager(); + $budgetLimit = $this->blRepository->store($data); + $manager = $this->getManager(); /** @var BudgetLimitTransformer $transformer */ - $transformer = app(BudgetLimitTransformer::class); + $transformer = app(BudgetLimitTransformer::class); $transformer->setParameters($this->parameters); - $resource = new Item($budgetLimit, $transformer, 'budget_limits'); + $resource = new Item($budgetLimit, $transformer, 'budget_limits'); return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); } diff --git a/app/Api/V1/Requests/Models/BudgetLimit/StoreRequest.php b/app/Api/V1/Requests/Models/BudgetLimit/StoreRequest.php index 4fc0e8bf5b..48c77cf2a2 100644 --- a/app/Api/V1/Requests/Models/BudgetLimit/StoreRequest.php +++ b/app/Api/V1/Requests/Models/BudgetLimit/StoreRequest.php @@ -48,6 +48,7 @@ class StoreRequest extends FormRequest 'amount' => $this->convertString('amount'), 'currency_id' => $this->convertInteger('currency_id'), 'currency_code' => $this->convertString('currency_code'), + 'notes' => $this->stringWithNewlines('notes'), ]; } @@ -62,6 +63,7 @@ class StoreRequest extends FormRequest 'amount' => ['required', new IsValidPositiveAmount()], 'currency_id' => 'numeric|exists:transaction_currencies,id', 'currency_code' => 'min:3|max:51|exists:transaction_currencies,code', + 'notes' => 'nullable|min:0|max:32768', ]; } } diff --git a/app/Api/V1/Requests/Models/BudgetLimit/UpdateRequest.php b/app/Api/V1/Requests/Models/BudgetLimit/UpdateRequest.php index f93cebb012..08f2a160be 100644 --- a/app/Api/V1/Requests/Models/BudgetLimit/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/BudgetLimit/UpdateRequest.php @@ -51,8 +51,12 @@ class UpdateRequest extends FormRequest 'amount' => ['amount', 'convertString'], 'currency_id' => ['currency_id', 'convertInteger'], 'currency_code' => ['currency_code', 'convertString'], + 'notes' => ['notes', 'stringWithNewlines'], ]; - + if(false === $this->has('notes')) { + // ignore notes, not submitted. + unset($fields['notes']); + } return $this->getAllData($fields); } @@ -67,6 +71,7 @@ class UpdateRequest extends FormRequest 'amount' => ['nullable', new IsValidPositiveAmount()], 'currency_id' => 'numeric|exists:transaction_currencies,id', 'currency_code' => 'min:3|max:51|exists:transaction_currencies,code', + 'notes' => 'nullable|min:0|max:32768', ]; } @@ -84,7 +89,7 @@ class UpdateRequest extends FormRequest $start = new Carbon($data['start']); $end = new Carbon($data['end']); if ($end->isBefore($start)) { - $validator->errors()->add('end', (string)trans('validation.date_after')); + $validator->errors()->add('end', (string) trans('validation.date_after')); } } } diff --git a/app/Models/Account.php b/app/Models/Account.php index 39b5e1f8ed..fe523e2fe4 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -144,7 +144,7 @@ class Account extends Model } /** - * Get all of the notes. + * Get all the notes. */ public function notes(): MorphMany { diff --git a/app/Models/BudgetLimit.php b/app/Models/BudgetLimit.php index 22f3c0de2d..1f20c69482 100644 --- a/app/Models/BudgetLimit.php +++ b/app/Models/BudgetLimit.php @@ -31,6 +31,7 @@ use FireflyIII\Support\Models\ReturnsIntegerIdTrait; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\MorphMany; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** @@ -90,6 +91,14 @@ class BudgetLimit extends Model return $this->belongsTo(TransactionCurrency::class); } + /** + * Get all the notes. + */ + public function notes(): MorphMany + { + return $this->morphMany(Note::class, 'noteable'); + } + /** * Get the amount */ diff --git a/app/Repositories/Budget/BudgetLimitRepository.php b/app/Repositories/Budget/BudgetLimitRepository.php index 6921968dc3..f98b3da334 100644 --- a/app/Repositories/Budget/BudgetLimitRepository.php +++ b/app/Repositories/Budget/BudgetLimitRepository.php @@ -29,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\TransactionCurrencyFactory; use FireflyIII\Models\Budget; use FireflyIII\Models\BudgetLimit; +use FireflyIII\Models\Note; use FireflyIII\Models\TransactionCurrency; use FireflyIII\User; use Illuminate\Contracts\Auth\Authenticatable; @@ -49,10 +50,10 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface */ public function budgeted(Carbon $start, Carbon $end, TransactionCurrency $currency, ?Collection $budgets = null): string { - $query = BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') + $query = BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') // same complex where query as below. - ->where( + ->where( static function (Builder $q5) use ($start, $end): void { $q5->where( static function (Builder $q1) use ($start, $end): void { @@ -62,30 +63,27 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface $q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d')); } ) - ->orWhere( - static function (Builder $q3) use ($start, $end): void { - $q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d')); - $q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d')); - } - ) - ; + ->orWhere( + static function (Builder $q3) use ($start, $end): void { + $q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d')); + $q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d')); + } + ); } ) - ->orWhere( - static function (Builder $q4) use ($start, $end): void { - // or start is before start AND end is after end. - $q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d')); - $q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d')); - } - ) - ; + ->orWhere( + static function (Builder $q4) use ($start, $end): void { + // or start is before start AND end is after end. + $q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d')); + $q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d')); + } + ); } ) - ->where('budget_limits.transaction_currency_id', $currency->id) - ->whereNull('budgets.deleted_at') - ->where('budgets.active', true) - ->where('budgets.user_id', $this->user->id) - ; + ->where('budget_limits.transaction_currency_id', $currency->id) + ->whereNull('budgets.deleted_at') + ->where('budgets.active', true) + ->where('budgets.user_id', $this->user->id); if (null !== $budgets && $budgets->count() > 0) { $query->whereIn('budget_limits.budget_id', $budgets->pluck('id')->toArray()); } @@ -137,19 +135,17 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface // both are NULL: if (null === $start && null === $end) { return BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') - ->with(['budget']) - ->where('budgets.user_id', $this->user->id) - ->whereNull('budgets.deleted_at') - ->get(['budget_limits.*']) - ; + ->with(['budget']) + ->where('budgets.user_id', $this->user->id) + ->whereNull('budgets.deleted_at') + ->get(['budget_limits.*']); } // one of the two is NULL. if (null === $start xor null === $end) { $query = BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') - ->with(['budget']) - ->whereNull('budgets.deleted_at') - ->where('budgets.user_id', $this->user->id) - ; + ->with(['budget']) + ->whereNull('budgets.deleted_at') + ->where('budgets.user_id', $this->user->id); if (null !== $end) { // end date must be before $end. $query->where('end_date', '<=', $end->format('Y-m-d 00:00:00')); @@ -164,39 +160,36 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface // neither are NULL: return BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id') - ->with(['budget']) - ->where('budgets.user_id', $this->user->id) - ->whereNull('budgets.deleted_at') - ->where( - static function (Builder $q5) use ($start, $end): void { - $q5->where( - static function (Builder $q1) use ($start, $end): void { - $q1->where( - static function (Builder $q2) use ($start, $end): void { - $q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d')); - $q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d')); - } - ) - ->orWhere( - static function (Builder $q3) use ($start, $end): void { - $q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d')); - $q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d')); - } - ) - ; - } - ) - ->orWhere( - static function (Builder $q4) use ($start, $end): void { - // or start is before start AND end is after end. - $q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d')); - $q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d')); - } - ) - ; - } - )->get(['budget_limits.*']) - ; + ->with(['budget']) + ->where('budgets.user_id', $this->user->id) + ->whereNull('budgets.deleted_at') + ->where( + static function (Builder $q5) use ($start, $end): void { + $q5->where( + static function (Builder $q1) use ($start, $end): void { + $q1->where( + static function (Builder $q2) use ($start, $end): void { + $q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d')); + $q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d')); + } + ) + ->orWhere( + static function (Builder $q3) use ($start, $end): void { + $q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d')); + $q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d')); + } + ); + } + ) + ->orWhere( + static function (Builder $q4) use ($start, $end): void { + // or start is before start AND end is after end. + $q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d')); + $q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d')); + } + ); + } + )->get(['budget_limits.*']); } public function getBudgetLimits(Budget $budget, ?Carbon $start = null, ?Carbon $end = null): Collection @@ -221,41 +214,38 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface // when both dates are set: return $budget->budgetlimits() - ->where( - static function (Builder $q5) use ($start, $end): void { // @phpstan-ignore-line - $q5->where( - static function (Builder $q1) use ($start, $end): void { - // budget limit ends within period - $q1->where( - static function (Builder $q2) use ($start, $end): void { - $q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d 00:00:00')); - $q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d 23:59:59')); - } - ) - // budget limit start within period - ->orWhere( - static function (Builder $q3) use ($start, $end): void { - $q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d 00:00:00')); - $q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d 23:59:59')); - } - ) - ; - } - ) - ->orWhere( - static function (Builder $q4) use ($start, $end): void { - // or start is before start AND end is after end. - $q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d 23:59:59')); - $q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d 00:00:00')); - } - ) - ; - } - )->orderBy('budget_limits.start_date', 'DESC')->get(['budget_limits.*']) - ; + ->where( + static function (Builder $q5) use ($start, $end): void { // @phpstan-ignore-line + $q5->where( + static function (Builder $q1) use ($start, $end): void { + // budget limit ends within period + $q1->where( + static function (Builder $q2) use ($start, $end): void { + $q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d 00:00:00')); + $q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d 23:59:59')); + } + ) + // budget limit start within period + ->orWhere( + static function (Builder $q3) use ($start, $end): void { + $q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d 00:00:00')); + $q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d 23:59:59')); + } + ); + } + ) + ->orWhere( + static function (Builder $q4) use ($start, $end): void { + // or start is before start AND end is after end. + $q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d 23:59:59')); + $q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d 00:00:00')); + } + ); + } + )->orderBy('budget_limits.start_date', 'DESC')->get(['budget_limits.*']); } - public function setUser(null|Authenticatable|User $user): void + public function setUser(null | Authenticatable | User $user): void { if ($user instanceof User) { $this->user = $user; @@ -269,52 +259,57 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface { // if no currency has been provided, use the user's default currency: /** @var TransactionCurrencyFactory $factory */ - $factory = app(TransactionCurrencyFactory::class); - $currency = $factory->find($data['currency_id'] ?? null, $data['currency_code'] ?? null); + $factory = app(TransactionCurrencyFactory::class); + $currency = $factory->find($data['currency_id'] ?? null, $data['currency_code'] ?? null); if (null === $currency) { $currency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup); } - $currency->enabled = true; + $currency->enabled = true; $currency->save(); // find the budget: - $budget = $this->user->budgets()->find((int) $data['budget_id']); + $budget = $this->user->budgets()->find((int) $data['budget_id']); if (null === $budget) { throw new FireflyException('200004: Budget does not exist.'); } // find limit with same date range and currency. - $limit = $budget->budgetlimits() - ->where('budget_limits.start_date', $data['start_date']->format('Y-m-d')) - ->where('budget_limits.end_date', $data['end_date']->format('Y-m-d')) - ->where('budget_limits.transaction_currency_id', $currency->id) - ->first(['budget_limits.*']) - ; + $limit = $budget->budgetlimits() + ->where('budget_limits.start_date', $data['start_date']->format('Y-m-d')) + ->where('budget_limits.end_date', $data['end_date']->format('Y-m-d')) + ->where('budget_limits.transaction_currency_id', $currency->id) + ->first(['budget_limits.*']); if (null !== $limit) { throw new FireflyException('200027: Budget limit already exists.'); } app('log')->debug('No existing budget limit, create a new one'); // or create one and return it. - $limit = new BudgetLimit(); + $limit = new BudgetLimit(); $limit->budget()->associate($budget); $limit->start_date = $data['start_date']->format('Y-m-d'); $limit->end_date = $data['end_date']->format('Y-m-d'); $limit->amount = $data['amount']; $limit->transaction_currency_id = $currency->id; $limit->save(); + + $noteText = (string) ($data['notes'] ?? ''); + if ('' !== $noteText) { + $this->setNoteText($limit, $noteText); + } + app('log')->debug(sprintf('Created new budget limit with ID #%d and amount %s', $limit->id, $data['amount'])); return $limit; } + public function find(Budget $budget, TransactionCurrency $currency, Carbon $start, Carbon $end): ?BudgetLimit { return $budget->budgetlimits() - ->where('transaction_currency_id', $currency->id) - ->where('start_date', $start->format('Y-m-d')) - ->where('end_date', $end->format('Y-m-d'))->first() - ; + ->where('transaction_currency_id', $currency->id) + ->where('start_date', $start->format('Y-m-d')) + ->where('end_date', $end->format('Y-m-d'))->first(); } /** @@ -322,8 +317,8 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface */ public function update(BudgetLimit $budgetLimit, array $data): BudgetLimit { - $budgetLimit->amount = array_key_exists('amount', $data) ? $data['amount'] : $budgetLimit->amount; - $budgetLimit->budget_id = array_key_exists('budget_id', $data) ? $data['budget_id'] : $budgetLimit->budget_id; + $budgetLimit->amount = array_key_exists('amount', $data) ? $data['amount'] : $budgetLimit->amount; + $budgetLimit->budget_id = array_key_exists('budget_id', $data) ? $data['budget_id'] : $budgetLimit->budget_id; if (array_key_exists('start', $data)) { $budgetLimit->start_date = $data['start']->startOfDay(); @@ -335,7 +330,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface } // if no currency has been provided, use the user's default currency: - $currency = null; + $currency = null; // update if relevant: if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) { @@ -347,41 +342,43 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface if (null === $currency) { $currency = $budgetLimit->transactionCurrency ?? app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup); } - $currency->enabled = true; + $currency->enabled = true; $currency->save(); $budgetLimit->transaction_currency_id = $currency->id; $budgetLimit->save(); + // update notes if they exist. + if(array_key_exists('notes', $data)) { + $this->setNoteText($budgetLimit, (string)$data['notes']); + } + return $budgetLimit; } public function updateLimitAmount(Budget $budget, Carbon $start, Carbon $end, string $amount): ?BudgetLimit { // count the limits: - $limits = $budget->budgetlimits() - ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00')) - ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00')) - ->count('budget_limits.*') - ; + $limits = $budget->budgetlimits() + ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00')) + ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00')) + ->count('budget_limits.*'); app('log')->debug(sprintf('Found %d budget limits.', $limits)); // there might be a budget limit for these dates: /** @var null|BudgetLimit $limit */ - $limit = $budget->budgetlimits() - ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00')) - ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00')) - ->first(['budget_limits.*']) - ; + $limit = $budget->budgetlimits() + ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00')) + ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00')) + ->first(['budget_limits.*']); // if more than 1 limit found, delete the others: if ($limits > 1 && null !== $limit) { app('log')->debug(sprintf('Found more than 1, delete all except #%d', $limit->id)); $budget->budgetlimits() - ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00')) - ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00')) - ->where('budget_limits.id', '!=', $limit->id)->delete() - ; + ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00')) + ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00')) + ->where('budget_limits.id', '!=', $limit->id)->delete(); } // delete if amount is zero. @@ -403,7 +400,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface } app('log')->debug('No existing budget limit, create a new one'); // or create one and return it. - $limit = new BudgetLimit(); + $limit = new BudgetLimit(); $limit->budget()->associate($budget); $limit->start_date = $start->startOfDay(); $limit->start_date_tz = $start->format('e'); @@ -415,4 +412,25 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface return $limit; } + + #[\Override] public function getNoteText(BudgetLimit $budgetLimit): string + { + return (string) $budgetLimit->notes()->first()?->text; + } + + #[\Override] public function setNoteText(BudgetLimit $budgetLimit, string $text): void + { + $dbNote = $budgetLimit->notes()->first(); + if ('' !== $text) { + if (null === $dbNote) { + $dbNote = new Note(); + $dbNote->noteable()->associate($budgetLimit); + } + $dbNote->text = trim($text); + $dbNote->save(); + + return; + } + $dbNote?->delete(); + } } diff --git a/app/Repositories/Budget/BudgetLimitRepositoryInterface.php b/app/Repositories/Budget/BudgetLimitRepositoryInterface.php index 9bb52abb15..12cbcd9da4 100644 --- a/app/Repositories/Budget/BudgetLimitRepositoryInterface.php +++ b/app/Repositories/Budget/BudgetLimitRepositoryInterface.php @@ -48,6 +48,9 @@ interface BudgetLimitRepositoryInterface */ public function destroyAll(): void; + public function getNoteText(BudgetLimit $budgetLimit): string; + public function setNoteText(BudgetLimit $budgetLimit, string $text): void; + /** * Destroy a budget limit. */ diff --git a/app/Transformers/BudgetLimitTransformer.php b/app/Transformers/BudgetLimitTransformer.php index ad8225ceec..d75440a8fd 100644 --- a/app/Transformers/BudgetLimitTransformer.php +++ b/app/Transformers/BudgetLimitTransformer.php @@ -25,6 +25,7 @@ declare(strict_types=1); namespace FireflyIII\Transformers; use FireflyIII\Models\BudgetLimit; +use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface; use FireflyIII\Repositories\Budget\OperationsRepository; use Illuminate\Support\Collection; use League\Fractal\Resource\Item; @@ -54,8 +55,10 @@ class BudgetLimitTransformer extends AbstractTransformer */ public function transform(BudgetLimit $budgetLimit): array { - $repository = app(OperationsRepository::class); + $repository = app(OperationsRepository::class); + $limitRepos = app(BudgetLimitRepositoryInterface::class); $repository->setUser($budgetLimit->budget->user); + $limitRepos->setUser($budgetLimit->budget->user); $expenses = $repository->sumExpenses( $budgetLimit->start_date, $budgetLimit->end_date, @@ -65,6 +68,7 @@ class BudgetLimitTransformer extends AbstractTransformer ); $currency = $budgetLimit->transactionCurrency; $amount = $budgetLimit->amount; + $notes = $limitRepos->getNoteText($budgetLimit); $currencyDecimalPlaces = 2; $currencyId = null; $currencyName = null; @@ -78,16 +82,16 @@ class BudgetLimitTransformer extends AbstractTransformer $currencySymbol = $currency->symbol; $currencyDecimalPlaces = $currency->decimal_places; } - $amount = app('steam')->bcround($amount, $currencyDecimalPlaces); + $amount = app('steam')->bcround($amount, $currencyDecimalPlaces); return [ - 'id' => (string)$budgetLimit->id, + 'id' => (string) $budgetLimit->id, 'created_at' => $budgetLimit->created_at->toAtomString(), 'updated_at' => $budgetLimit->updated_at->toAtomString(), 'start' => $budgetLimit->start_date->toAtomString(), 'end' => $budgetLimit->end_date->endOfDay()->toAtomString(), - 'budget_id' => (string)$budgetLimit->budget_id, - 'currency_id' => (string)$currencyId, + 'budget_id' => (string) $budgetLimit->budget_id, + 'currency_id' => (string) $currencyId, 'currency_code' => $currencyCode, 'currency_name' => $currencyName, 'currency_decimal_places' => $currencyDecimalPlaces, @@ -95,10 +99,11 @@ class BudgetLimitTransformer extends AbstractTransformer 'amount' => $amount, 'period' => $budgetLimit->period, 'spent' => $expenses[$currencyId]['sum'] ?? '0', + 'notes' => '' === $notes ? null : $notes, 'links' => [ [ 'rel' => 'self', - 'uri' => '/budgets/limits/'.$budgetLimit->id, + 'uri' => '/budgets/limits/' . $budgetLimit->id, ], ], ];