| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- <?php
- namespace App\Services;
- use App\Enums\CartStatusEnum;
- use App\Enums\PaymentStatusEnum;
- use App\Models\Cart;
- use App\Models\CartItem;
- use App\Models\Payment;
- use App\Models\Schedule;
- use Illuminate\Database\Eloquent\Collection;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Validation\ValidationException;
- class CartItemService
- {
- public function getAll(): Collection
- {
- return CartItem::query()
- ->orderBy('created_at', 'desc')
- ->get();
- }
- public function findById(int $id): ?CartItem
- {
- return CartItem::find($id);
- }
- public function create(array $data): CartItem
- {
- return DB::transaction(function () use ($data) {
- [$cart, $schedule] = $this->validateItem($data['cart_id'], $data['schedule_id']);
- if (! $cart->provider_id) {
- $cart->update(['provider_id' => $schedule->provider_id]);
- }
- return CartItem::create($data);
- });
- }
- public function update(int $id, array $data): ?CartItem
- {
- return DB::transaction(function () use ($id, $data): ?CartItem {
- $model = $this->findById($id);
- if (! $model) {
- return null;
- }
- $cartId = $data['cart_id'] ?? $model->cart_id;
- $scheduleId = $data['schedule_id'] ?? $model->schedule_id;
- [$cart, $schedule] = $this->validateItem($cartId, $scheduleId);
- if (! $cart->provider_id) {
- $cart->update(['provider_id' => $schedule->provider_id]);
- }
- $model->update($data);
- return $model->fresh();
- });
- }
- public function delete(int $id): bool
- {
- $model = $this->findById($id);
- if (!$model) {
- return false;
- }
- return DB::transaction(function () use ($model): bool {
- $this->validateItem($model->cart_id, $model->schedule_id);
- return $model->delete();
- });
- }
- private function validateItem(int $cartId, int $scheduleId): array
- {
- $cart = Cart::query()->lockForUpdate()->findOrFail($cartId);
- $schedule = Schedule::query()->findOrFail($scheduleId);
- if ($cart->status !== CartStatusEnum::OPEN) {
- throw ValidationException::withMessages([
- 'cart_id' => 'Somente carrinhos abertos podem ser alterados.',
- ]);
- }
- if ($schedule->client_id !== $cart->client_id) {
- throw ValidationException::withMessages([
- 'schedule_id' => 'O agendamento precisa pertencer ao mesmo cliente do carrinho.',
- ]);
- }
- if (! $schedule->provider_id || ($cart->provider_id && $schedule->provider_id !== $cart->provider_id)) {
- throw ValidationException::withMessages([
- 'schedule_id' => 'Todos os agendamentos do carrinho precisam ser do mesmo prestador.',
- ]);
- }
- $belongsToAnotherCart = CartItem::query()
- ->where('schedule_id', $scheduleId)
- ->where('cart_id', '!=', $cartId)
- ->exists();
- if ($belongsToAnotherCart) {
- throw ValidationException::withMessages([
- 'schedule_id' => 'O agendamento já pertence a outro carrinho.',
- ]);
- }
- $hasActivePayment = Payment::query()
- ->where('schedule_id', $scheduleId)
- ->whereIn('status', [
- PaymentStatusEnum::PENDING->value,
- PaymentStatusEnum::PROCESSING->value,
- PaymentStatusEnum::AUTHORIZED->value,
- PaymentStatusEnum::PAID->value,
- ])
- ->exists();
- if ($hasActivePayment) {
- throw ValidationException::withMessages([
- 'schedule_id' => 'O agendamento já possui um pagamento e não pode ser adicionado ao carrinho.',
- ]);
- }
- return [$cart, $schedule];
- }
- }
|