. */ declare(strict_types=1); namespace FireflyIII\Repositories\Budget; use Carbon\Carbon; use FireflyIII\Models\AvailableBudget; use FireflyIII\Models\TransactionCurrency; use FireflyIII\User; use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Log; /** * Class AvailableBudgetRepository */ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface { private User $user; public function cleanup(): void { $exists = []; $availableBudgets = $this->user->availableBudgets()->get(); /** @var AvailableBudget $availableBudget */ foreach ($availableBudgets as $availableBudget) { $start = $availableBudget->start_date->format('Y-m-d'); $end = $availableBudget->end_date->format('Y-m-d'); $key = sprintf('%s-%s-%s', $availableBudget->transaction_currency_id, $start, $end); if (array_key_exists($key, $exists)) { app('log')->debug(sprintf('Found duplicate AB: %s %s, %s-%s. Has been deleted', $availableBudget->transaction_currency_id, $availableBudget->amount, $start, $end)); $availableBudget->delete(); } $exists[$key] = true; } } /** * Return a list of all available budgets (in all currencies) (for the selected period). */ public function get(?Carbon $start = null, ?Carbon $end = null): Collection { $query = $this->user->availableBudgets()->with(['transactionCurrency']); if (null !== $start && null !== $end) { $query->where( static function (Builder $q1) use ($start, $end): void { // @phpstan-ignore-line $q1->where('start_date', '=', $start->format('Y-m-d')); $q1->where('end_date', '=', $end->format('Y-m-d')); } ); } return $query->get(['available_budgets.*']); } /** * Delete all available budgets. */ public function destroyAll(): void { Log::channel('audit')->info('Delete all available budgets through destroyAll'); $this->user->availableBudgets()->delete(); } public function destroyAvailableBudget(AvailableBudget $availableBudget): void { $availableBudget->delete(); } public function findById(int $id): ?AvailableBudget { return $this->user->availableBudgets->find($id); } /** * Find existing AB. */ public function find(TransactionCurrency $currency, Carbon $start, Carbon $end): ?AvailableBudget { return $this->user->availableBudgets() ->where('transaction_currency_id', $currency->id) ->where('start_date', $start->format('Y-m-d')) ->where('end_date', $end->format('Y-m-d')) ->first() ; } public function getAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end): string { $amount = '0'; /** @var null|AvailableBudget $availableBudget */ $availableBudget = $this->user->availableBudgets() ->where('transaction_currency_id', $currency->id) ->where('start_date', $start->format('Y-m-d')) ->where('end_date', $end->format('Y-m-d'))->first() ; if (null !== $availableBudget) { $amount = $availableBudget->amount; } return $amount; } public function getAvailableBudgetWithCurrency(Carbon $start, Carbon $end): array { $return = []; $availableBudgets = $this->user->availableBudgets() ->where('start_date', $start->format('Y-m-d')) ->where('end_date', $end->format('Y-m-d'))->get() ; /** @var AvailableBudget $availableBudget */ foreach ($availableBudgets as $availableBudget) { $return[$availableBudget->transaction_currency_id] = $availableBudget->amount; } return $return; } /** * Returns all available budget objects. */ public function getAvailableBudgetsByCurrency(TransactionCurrency $currency): Collection { return $this->user->availableBudgets()->where('transaction_currency_id', $currency->id)->get(); } /** * Returns all available budget objects. */ public function getAvailableBudgetsByDate(?Carbon $start, ?Carbon $end): Collection { $query = $this->user->availableBudgets(); if (null !== $start) { $query->where('start_date', '>=', $start->format('Y-m-d')); } if (null !== $end) { $query->where('end_date', '<=', $end->format('Y-m-d')); } return $query->get(); } /** * Returns all available budget objects. */ public function getAvailableBudgetsByExactDate(Carbon $start, Carbon $end): Collection { return $this->user->availableBudgets() ->where('start_date', '=', $start->format('Y-m-d')) ->where('end_date', '=', $end->format('Y-m-d')) ->get() ; } public function getByCurrencyDate(Carbon $start, Carbon $end, TransactionCurrency $currency): ?AvailableBudget { return $this->user ->availableBudgets() ->where('transaction_currency_id', $currency->id) ->where('start_date', $start->format('Y-m-d')) ->where('end_date', $end->format('Y-m-d'))->first() ; } /** * @deprecated */ public function setAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end, string $amount): AvailableBudget { $availableBudget = $this->user->availableBudgets() ->where('transaction_currency_id', $currency->id) ->where('start_date', $start->format('Y-m-d')) ->where('end_date', $end->format('Y-m-d'))->first() ; if (null === $availableBudget) { $availableBudget = new AvailableBudget(); $availableBudget->user()->associate($this->user); $availableBudget->transactionCurrency()->associate($currency); $availableBudget->start_date = $start->startOfDay()->format('Y-m-d'); // @phpstan-ignore-line $availableBudget->end_date = $end->endOfDay()->format('Y-m-d'); // @phpstan-ignore-line } $availableBudget->amount = $amount; $availableBudget->save(); return $availableBudget; } public function setUser(null|Authenticatable|User $user): void { if ($user instanceof User) { $this->user = $user; } } public function store(array $data): ?AvailableBudget { $start = $data['start']; if ($start instanceof Carbon) { $start = $data['start']->startOfDay(); } $end = $data['end']; if ($end instanceof Carbon) { $end = $data['end']->endOfDay(); } return AvailableBudget::create( [ 'user_id' => $this->user->id, 'user_group_id' => $this->user->user_group_id, 'transaction_currency_id' => $data['currency_id'], 'amount' => $data['amount'], 'start_date' => $start->format('Y-m-d'), 'end_date' => $end->format('Y-m-d'), ] ); } public function update(AvailableBudget $availableBudget, array $data): AvailableBudget { if (array_key_exists('amount', $data)) { $availableBudget->amount = $data['amount']; } $availableBudget->save(); return $availableBudget; } public function updateAvailableBudget(AvailableBudget $availableBudget, array $data): AvailableBudget { if (array_key_exists('start', $data)) { $start = $data['start']; if ($start instanceof Carbon) { $start = $data['start']->startOfDay(); $availableBudget->start_date = $start->format('Y-m-d'); $availableBudget->save(); } } if (array_key_exists('end', $data)) { $end = $data['end']; if ($end instanceof Carbon) { $end = $data['end']->endOfDay(); $availableBudget->end_date = $end->format('Y-m-d'); $availableBudget->save(); } } if (array_key_exists('currency_id', $data)) { $availableBudget->transaction_currency_id = $data['currency_id']; $availableBudget->save(); } if (array_key_exists('amount', $data)) { $availableBudget->amount = $data['amount']; $availableBudget->save(); } return $availableBudget; } }