<?php
declare(strict_types=1);
namespace App\Controller\Front;
use App\Application\Service\Cart\ProductCartFulfillmentService;
use App\Application\Service\Helper\LegacyTranslator;
use App\Application\Service\Order\OrderReferenceValidationService;
use App\Application\Service\Serializer\SerializerService;
use App\Application\Service\Session\SessionService;
use App\Application\Service\Validator\AddressValidator;
use App\Entity\System\Customer;
use App\Factory\Address\AddressFactory;
use App\Manager\System\AddressManager;
use App\Manager\System\CartManager;
use App\Model\Order\OrderShippingAddressRequest;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Contracts\Translation\TranslatorInterface;
class CartController extends AbstractController
{
public function __construct(
private readonly CartManager $cartManager,
private readonly TranslatorInterface $translatorService,
private readonly SessionService $sessionService,
private readonly AddressFactory $addressFactory,
private readonly AddressManager $addressManager,
private readonly AddressValidator $addressValidator,
private readonly OrderReferenceValidationService $orderReferenceValidationService,
private readonly LegacyTranslator $legacyTranslator,
private readonly SerializerService $serializerService,
) {
}
/**
* @param Request $request
* @param ProductCartFulfillmentService $productCartFulfillmentService
*
* @return JsonResponse
*
* @Route("cart/delete-product-fba-not-allowed", name="cart_delete_product_fba_not_allowed", priority="5", methods={"GET"})
*/
public function deleteProductFbaNotAllowed(
Request $request,
ProductCartFulfillmentService $productCartFulfillmentService,
): JsonResponse {
try {
$productsFbaNotAllowed = json_decode($request->get('items'), true);
$productCartFulfillmentService->deleteProductsWithoutFulfillment($productsFbaNotAllowed);
return new JsonResponse(true);
} catch (\Exception $exception) {
return new JsonResponse(false);
}
}
/**
* @param Request $request
*
* @return JsonResponse
*
* @Route("cart/add-shipment-choices", name="cart_add_shipment_choices", methods={"POST"})
*/
public function addShipmentChoices(Request $request): JsonResponse
{
if (!$this->sessionService->get('id_cart')) {
return $this->json($this->translatorService->trans('global.error_page_not_found.message.title'), JsonResponse::HTTP_NOT_FOUND);
}
$cartId = $this->sessionService->get('id_cart');
$cart = $this->cartManager->findOneById((int)$cartId);
if (!$cart) {
return $this->json($this->translatorService->trans('global.error_page_not_found.message.title'), JsonResponse::HTTP_NOT_FOUND);
}
$cart->setShipmentChoices($request->get('shipmentChoices'));
$this->cartManager->save($cart);
return new JsonResponse(true);
}
/**
* @param Request $request
*
* @return JsonResponse
*
* @Route("cart/add-delivery-address", name="cart_add_delivery_address", methods={"POST"})
*
* @throws \Exception
*/
public function addDeliveryAddress(Request $request): JsonResponse
{
if (!$this->sessionService->get('id_cart')) {
return $this->json($this->translatorService->trans('global.error_page_not_found.message.title'), JsonResponse::HTTP_NOT_FOUND);
}
$cartId = $this->sessionService->get('id_cart');
$cart = $this->cartManager->findOneById((int)$cartId);
if (!$cart) {
return new JsonResponse($this->translatorService->trans('global.error_page_not_found.message.title'), Response::HTTP_NOT_FOUND);
}
try {
$deliveryAddressRequest = $this->serializerService->deserialize(\json_encode($request->request->all(), JSON_THROW_ON_ERROR), OrderShippingAddressRequest::class, JsonEncoder::FORMAT);
} catch (\Throwable $exception) {
return new JsonResponse('invalid format request', Response::HTTP_BAD_REQUEST);
}
if ($deliveryAddressRequest->phone === null
|| !$this->addressValidator->isValidPhoneNumber($deliveryAddressRequest->phone)
|| !$this->addressValidator->isPhoneLengthValid($deliveryAddressRequest->phone)) {
return new JsonResponse('phone_invalid_length', Response::HTTP_BAD_REQUEST);
}
if (!$this->addressValidator->isValidName($deliveryAddressRequest->name)) {
return new JsonResponse('name_invalid_format', Response::HTTP_BAD_REQUEST);
}
if (!$this->addressValidator->isValidAddress($deliveryAddressRequest->address1)) {
return new JsonResponse('address_invalid_format', Response::HTTP_BAD_REQUEST);
}
try {
$deliveryAddress = $this->addressFactory->createDeliveryAddress(
$deliveryAddressRequest,
$cart
);
} catch (\Exception $exception) {
return new JsonResponse('country_invalid_format', Response::HTTP_BAD_REQUEST);
}
$this->addressManager->save($deliveryAddress);
$cart->setAddressDelivery($deliveryAddress);
$this->cartManager->save($cart);
return new JsonResponse(true);
}
/**
* @Route("order/validateRefOrderSupplier", name="validateRefOrderSupplier")
* @Route("cart/validate-order-reference", name="validate_order_reference", methods={"POST"})
*/
public function validateOrderReference(Request $request): Response
{
$customerOrderReference = $request->get('ref_interna');
/** @var ?Customer $user */
$user = $this->getUser();
if (!$user || !$customerOrderReference) {
return new JsonResponse(['error' => false]);
}
if (!$this->orderReferenceValidationService->isReferenceAvailable((string)$user->getId(), $customerOrderReference)) {
return new Response(
\json_encode(
[
'error' => true,
'msg' => $this->legacyTranslator->translate(
'La referencia interna o identificador del pedido ya existe',
'orderController'
),
]
)
);
}
if ($cartId = $this->sessionService->get('id_cart')) {
$cart = $this->cartManager->findOneById($cartId);
$cart->setRefOrderSupplier($customerOrderReference);
$this->cartManager->save($cart);
}
return new Response(json_encode(['error' => false]));
}
}