49 lines
1.4 KiB
PHP
49 lines
1.4 KiB
PHP
<?php
|
|
|
|
namespace App\Actions\Order;
|
|
|
|
use App\Data\Order\OrderRequestDTO;
|
|
use App\Enums\Cart\CartStatus;
|
|
use App\Exceptions\StaleCartException;
|
|
use App\Models\Address;
|
|
use App\Models\Cart;
|
|
use App\Models\Order;
|
|
use App\Models\User;
|
|
|
|
final readonly class CreateOrderAction
|
|
{
|
|
/**
|
|
* Execute the action.
|
|
*
|
|
* @throws StaleCartException
|
|
*/
|
|
public function execute(OrderRequestDTO $dto, User $user): Order
|
|
{
|
|
/** @var Cart $cart */
|
|
$cart = $user->carts()->where('id', $dto->cartId)->sole();
|
|
|
|
if ($cart->status !== CartStatus::Active) {
|
|
throw new StaleCartException(userId: $user->id, cartId: $cart->id);
|
|
}
|
|
|
|
/** @var Address $address */
|
|
$address = $user->addresses()->where('id', $dto->addressId)->sole();
|
|
|
|
// Check if user has already created an order with the same cart. If yes, then take that order.
|
|
/** @var Order $order */
|
|
$order = $user->orders()->firstOrNew(['cart_id' => $cart->id]);
|
|
|
|
$order->cart_id = $cart->id;
|
|
$order->shipping_first_name = $address->first_name;
|
|
$order->shipping_last_name = $address->last_name;
|
|
$order->shipping_street = $address->street;
|
|
$order->shipping_city = $address->city;
|
|
$order->shipping_state = $address->state;
|
|
$order->shipping_pin = $address->pin;
|
|
|
|
$order->save();
|
|
|
|
return $order;
|
|
}
|
|
}
|