Skip to content

Commit

Permalink
added checkOrder to Convertim
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasLudvik committed Oct 30, 2024
1 parent 7ab54c9 commit 5e67ca0
Show file tree
Hide file tree
Showing 6 changed files with 455 additions and 1 deletion.
27 changes: 27 additions & 0 deletions src/Controller/OrderController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

namespace Shopsys\ConvertimBundle\Controller;

use Convertim\Order\ConvertimOrderDataFactory;
use Shopsys\ConvertimBundle\Model\Convertim\ConvertimConfigProvider;
use Shopsys\ConvertimBundle\Model\Convertim\ConvertimLogger;
use Shopsys\ConvertimBundle\Model\Convertim\Exception\ConvertimException;
use Shopsys\ConvertimBundle\Model\Order\OrderDetailFactory;
use Shopsys\ConvertimBundle\Model\Order\OrderValidator;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand All @@ -19,11 +21,13 @@ class OrderController extends AbstractConvertimController
/**
* @param \Shopsys\ConvertimBundle\Model\Order\OrderDetailFactory $orderDetailFactory
* @param \Shopsys\ConvertimBundle\Model\Convertim\ConvertimLogger $convertimLogger
* @param \Shopsys\ConvertimBundle\Model\Order\OrderValidator $orderValidator
* @param \Shopsys\ConvertimBundle\Model\Convertim\ConvertimConfigProvider $convertimConfigProvider
*/
public function __construct(
protected readonly OrderDetailFactory $orderDetailFactory,
protected readonly ConvertimLogger $convertimLogger,
protected readonly OrderValidator $orderValidator,
ConvertimConfigProvider $convertimConfigProvider,
) {
parent::__construct($convertimConfigProvider);
Expand All @@ -48,4 +52,27 @@ public function getLastOrderDetail(Request $request): Response
return $this->convertimLogger->logGenericException($e);
}
}

/**
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
#[Route('/check-order')]
public function checkOrder(Request $request): Response
{
if ($this->isProtectedRequest($request) === false) {
return $this->invalidAuthorizationResponse();
}

try {
$rawData = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR);
$convertimOrderDataFactory = new ConvertimOrderDataFactory();
$convertimOrderData = $convertimOrderDataFactory->createConvertimOrderDataFromJsonArray($rawData);
$validationResult = $this->orderValidator->validateOrder($convertimOrderData);

return new JsonResponse($validationResult);
} catch (Throwable $e) {
return $this->convertimLogger->logGenericException($e);
}
}
}
107 changes: 107 additions & 0 deletions src/Model/Order/ConvertimOrderDataToCartMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

declare(strict_types=1);

namespace Shopsys\ConvertimBundle\Model\Order;

use Convertim\Order\ConvertimOrderData;
use Shopsys\FrameworkBundle\Component\Domain\Domain;
use Shopsys\FrameworkBundle\Component\Money\Money;
use Shopsys\FrameworkBundle\Model\Cart\Cart;
use Shopsys\FrameworkBundle\Model\Cart\CartFacade;
use Shopsys\FrameworkBundle\Model\Cart\Payment\CartPaymentDataFactory;
use Shopsys\FrameworkBundle\Model\Cart\Transport\CartTransportDataFactory;
use Shopsys\FrameworkBundle\Model\Order\PromoCode\PromoCodeFacade;
use Shopsys\FrameworkBundle\Model\Payment\PaymentFacade;
use Shopsys\FrameworkBundle\Model\Product\ProductFacade;
use Shopsys\FrameworkBundle\Model\Transport\TransportFacade;
use Shopsys\FrontendApiBundle\Model\Cart\CartApiFacade;

class ConvertimOrderDataToCartMapper
{
/**
* @param \Shopsys\FrontendApiBundle\Model\Cart\CartApiFacade $cartApiFacade
* @param \Shopsys\FrameworkBundle\Model\Product\ProductFacade $productFacade
* @param \Shopsys\FrameworkBundle\Model\Cart\CartFacade $cartFacade
* @param \Shopsys\FrameworkBundle\Model\Order\PromoCode\PromoCodeFacade $promoCodeFacade
* @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain
* @param \Shopsys\FrameworkBundle\Model\Payment\PaymentFacade $paymentFacade
* @param \Shopsys\FrameworkBundle\Model\Cart\Payment\CartPaymentDataFactory $cartPaymentDataFactory
* @param \Shopsys\FrameworkBundle\Model\Transport\TransportFacade $transportFacade
* @param \Shopsys\FrameworkBundle\Model\Cart\Transport\CartTransportDataFactory $cartTransportDataFactory
*/
public function __construct(
protected readonly CartApiFacade $cartApiFacade,
protected readonly ProductFacade $productFacade,
protected readonly CartFacade $cartFacade,
protected readonly PromoCodeFacade $promoCodeFacade,
protected readonly Domain $domain,
protected readonly PaymentFacade $paymentFacade,
protected readonly CartPaymentDataFactory $cartPaymentDataFactory,
protected readonly TransportFacade $transportFacade,
protected readonly CartTransportDataFactory $cartTransportDataFactory,
) {
}

/**
* @param \Convertim\Order\ConvertimOrderData $convertimOrderData
* @return \Shopsys\FrameworkBundle\Model\Cart\Cart
*/
public function mapConvertimOrderDataToCart(ConvertimOrderData $convertimOrderData): Cart
{
$cart = $this->cartApiFacade->getCartCreateIfNotExists(null, null);

foreach ($convertimOrderData->getOrderItemsData() as $orderItemData) {
$product = $this->productFacade->getByUuid($orderItemData->getProductId());
$result = $this->cartFacade->addProductToExistingCart($product, (int)$orderItemData->getQuantity(), $cart, true);
$result->getCartItem()->setWatchedPrice(Money::create($orderItemData->getPriceWithVat()));
}

$this->applyConvertimPromoCodesToCart($convertimOrderData->getPromoCodes(), $cart);
$this->applyConvertimPaymentToCart($convertimOrderData, $cart);
$this->applyConvertimTransportToCart($convertimOrderData, $cart);

return $cart;
}

/**
* @param \Convertim\Order\ConvertimOrderPromoCodesData[] $convertimOrderPromoCodesData
* @param \Shopsys\FrameworkBundle\Model\Cart\Cart $cart
*/
protected function applyConvertimPromoCodesToCart(array $convertimOrderPromoCodesData, Cart $cart): void
{
foreach ($convertimOrderPromoCodesData as $convertimOrderPromoCodeData) {
$promoCode = $this->promoCodeFacade->findPromoCodeByCodeAndDomain($convertimOrderPromoCodeData->getCode(), $this->domain->getId());

if ($promoCode !== null) {
$cart->applyPromoCode($promoCode);
}
}
}

/**
* @param \Convertim\Order\ConvertimOrderData $convertimOrderData
* @param \Shopsys\FrameworkBundle\Model\Cart\Cart $cart
*/
protected function applyConvertimPaymentToCart(ConvertimOrderData $convertimOrderData, Cart $cart): void
{
$payment = $this->paymentFacade->getByUuid($convertimOrderData->getPaymentData()->getUuid());
$cartPaymentData = $this->cartPaymentDataFactory->create($cart, $payment->getUuid(), null);
$cartPaymentData->watchedPrice = Money::create($convertimOrderData->getPaymentData()->getPriceWithVat());

$cart->editCartPayment($cartPaymentData);
}

/**
* @param \Convertim\Order\ConvertimOrderData $convertimOrderData
* @param \Shopsys\FrameworkBundle\Model\Cart\Cart $cart
*/
protected function applyConvertimTransportToCart(ConvertimOrderData $convertimOrderData, Cart $cart): void
{
$transport = $this->transportFacade->getByUuid($convertimOrderData->getTransportData()->getUuid());
$cartTransportData = $this->cartTransportDataFactory->create($cart, $transport->getUuid(), null);
$cartTransportData->watchedPrice = Money::create($convertimOrderData->getTransportData()->getPriceWithVat());

$cart->editCartTransport($cartTransportData);
}
}
236 changes: 236 additions & 0 deletions src/Model/Order/OrderValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
<?php

declare(strict_types=1);

namespace Shopsys\ConvertimBundle\Model\Order;

use Convertim\Order\ConvertimOrderData;
use Convertim\Order\ConvertimValidationResult;
use Shopsys\FrameworkBundle\Model\Cart\CartFacade;
use Shopsys\FrontendApiBundle\Model\Cart\CartWatcherFacade;

class OrderValidator
{
/**
* @param \Shopsys\ConvertimBundle\Model\Order\ConvertimOrderDataToCartMapper $convertimOrderDataToCartMapper
* @param \Shopsys\FrontendApiBundle\Model\Cart\CartWatcherFacade $cartWatcherFacade
* @param \Shopsys\FrameworkBundle\Model\Cart\CartFacade $cartFacade
*/
public function __construct(
protected readonly ConvertimOrderDataToCartMapper $convertimOrderDataToCartMapper,
protected readonly CartWatcherFacade $cartWatcherFacade,
protected readonly CartFacade $cartFacade,
) {
}

/**
* @param \Convertim\Order\ConvertimOrderData $convertimOrderData
* @return \Convertim\Order\ConvertimValidationResult
*/
public function validateOrder(ConvertimOrderData $convertimOrderData): ConvertimValidationResult
{
$cart = $this->convertimOrderDataToCartMapper->mapConvertimOrderDataToCart($convertimOrderData);

$validationResult = new ConvertimValidationResult();

$cartWithModifications = $this->cartWatcherFacade->getCheckedCartWithModifications($cart);

if ($cartWithModifications->isCartModified()) {
$modifications = $cartWithModifications->getModifications();

$this->addCartItemModificationsToValidationResult($modifications['itemModifications'], $validationResult);
$this->addTransportModificationsToValidationResult($modifications['transportModifications'], $validationResult);
$this->addPaymentModificationsToValidationResult($modifications['paymentModifications'], $validationResult);
$this->addPromoCodeModificationsToValidationResult($modifications['promoCodeModifications'], $validationResult);
$this->addMultipleAddedProductModificationsToValidationResult($modifications['multipleAddedProductModifications'], $validationResult);
}

$this->cartFacade->deleteCart($cart);

return $validationResult;
}

/**
* @param \Shopsys\FrameworkBundle\Model\Cart\Item\CartItem[] $noLongerListableCartItems
* @param \Convertim\Order\ConvertimValidationResult $validationResult
*/
protected function addNoLongerListableCartItemsToValidationResult(
array $noLongerListableCartItems,
ConvertimValidationResult $validationResult,
): void {
foreach ($noLongerListableCartItems as $noLongerListableCartItem) {
$validationResult->addError(
t(
'Item {{ name }} can no longer be bought.',
[
'{{ name }}' => $noLongerListableCartItem->getProduct()->getName(),
],
),
);
}
}

/**
* @param \Shopsys\FrameworkBundle\Model\Cart\Item\CartItem[] $cartItemsWithModifiedPrice
* @param \Convertim\Order\ConvertimValidationResult $validationResult
*/
protected function addCartItemsWithModifiedPriceToValidationResult(
array $cartItemsWithModifiedPrice,
ConvertimValidationResult $validationResult,
): void {
foreach ($cartItemsWithModifiedPrice as $cartItemWithModifiedPrice) {
$validationResult->addError(
t(
'The price of item {{ name }} has changed.',
[
'{{ name }}' => $cartItemWithModifiedPrice->getProduct()->getName(),
],
),
);
}
}

/**
* @param \Shopsys\FrameworkBundle\Model\Cart\Item\CartItem[] $cartItemsWithChangedQuantity
* @param \Convertim\Order\ConvertimValidationResult $validationResult
*/
protected function addCartItemsWithChangedQuantityToValidationResult(
array $cartItemsWithChangedQuantity,
ConvertimValidationResult $validationResult,
): void {
foreach ($cartItemsWithChangedQuantity as $cartItemWithChangedQuantity) {
$validationResult->addError(
t(
'The quantity of item {{ name }} has changed.',
[
'{{ name }}' => $cartItemWithChangedQuantity->getProduct()->getName(),
],
),
);
}
}

/**
* @param \Shopsys\FrameworkBundle\Model\Cart\Item\CartItem[] $noLongerAvailableCartItemsDueToQuantity
* @param \Convertim\Order\ConvertimValidationResult $validationResult
*/
protected function addNoLongerAvailableCartItemsDueToQuantity(
array $noLongerAvailableCartItemsDueToQuantity,
ConvertimValidationResult $validationResult,
): void {
foreach ($noLongerAvailableCartItemsDueToQuantity as $noLongerAvailableCartItemDueToQuantity) {
$validationResult->addError(
t(
'Item {{ name }} has been sold out.',
[
'{{ name }}' => $noLongerAvailableCartItemDueToQuantity->getProduct()->getName(),
],
),
);
}
}

/**
* @param array<string, array> $itemModifications
* @param \Convertim\Order\ConvertimValidationResult $validationResult
*/
protected function addCartItemModificationsToValidationResult(
array $itemModifications,
ConvertimValidationResult $validationResult,
): void {
if (count($itemModifications) > 0) {
$this->addNoLongerListableCartItemsToValidationResult($itemModifications['noLongerListableCartItems'], $validationResult);
$this->addCartItemsWithModifiedPriceToValidationResult($itemModifications['cartItemsWithModifiedPrice'], $validationResult);
$this->addCartItemsWithChangedQuantityToValidationResult($itemModifications['cartItemsWithChangedQuantity'], $validationResult);
$this->addNoLongerAvailableCartItemsDueToQuantity($itemModifications['noLongerAvailableCartItemsDueToQuantity'], $validationResult);
}
}

/**
* @param array<string, bool> $transportModifications
* @param \Convertim\Order\ConvertimValidationResult $validationResult
*/
protected function addTransportModificationsToValidationResult(
array $transportModifications,
ConvertimValidationResult $validationResult,
): void {
if (count($transportModifications) > 0) {
if ($transportModifications['transportPriceChanged']) {
$validationResult->addError(t('The price of the transport you selected has changed.'));
}

if ($transportModifications['transportUnavailable']) {
$validationResult->addError(t('The transport you selected is no longer available.'));
}

if ($transportModifications['transportWeightLimitExceeded']) {
$validationResult->addError(t('You have exceeded the weight limit of the selected transport.'));
}

if ($transportModifications['personalPickupStoreUnavailable']) {
$validationResult->addError(t('The store you selected is no longer available.'));
}
}
}

/**
* @param array<string, bool> $paymentModifications
* @param \Convertim\Order\ConvertimValidationResult $validationResult
*/
protected function addPaymentModificationsToValidationResult(
array $paymentModifications,
ConvertimValidationResult $validationResult,
): void {
if (count($paymentModifications) > 0) {
if ($paymentModifications['paymentPriceChanged']) {
$validationResult->addError(t('The price of the payment you selected has changed.'));
}

if ($paymentModifications['paymentUnavailable']) {
$validationResult->addError(t('The payment you selected is no longer available.'));
}
}
}

/**
* @param array<string, array<int, string>> $promoCodeModifications
* @param \Convertim\Order\ConvertimValidationResult $validationResult
*/
protected function addPromoCodeModificationsToValidationResult(
array $promoCodeModifications,
ConvertimValidationResult $validationResult,
): void {
if (count($promoCodeModifications) > 0) {
/** @var string $noLongerApplicablePromoCode */
foreach ($promoCodeModifications['noLongerApplicablePromoCode'] as $noLongerApplicablePromoCode) {
$validationResult->addError(t(
'The promo code {{ code }} is no longer applicable.',
[
'{{ code }}' => $noLongerApplicablePromoCode,
],
));
}
}
}

/**
* @param array<string, array<int, string>> $multipleAddedProductModifications
* @param \Convertim\Order\ConvertimValidationResult $validationResult
*/
protected function addMultipleAddedProductModificationsToValidationResult(
array $multipleAddedProductModifications,
ConvertimValidationResult $validationResult,
): void {
if (count($multipleAddedProductModifications) > 0) {
/** @var \Shopsys\FrameworkBundle\Model\Product\Product $notAddedProduct */
foreach ($multipleAddedProductModifications['notAddedProducts'] as $notAddedProduct) {
$validationResult->addError(t(
'The product {{ name }} is not available.',
[
'{{ name }}' => $notAddedProduct->getName(),
],
));
}
}
}
}
Loading

0 comments on commit 5e67ca0

Please sign in to comment.