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