Skip to content

Commit

Permalink
feat: using existing bold order instead of always creating a new one …
Browse files Browse the repository at this point in the history
…[CSE-28] (#307)
  • Loading branch information
allanmfx authored Aug 16, 2024
1 parent 19fffea commit a0b0003
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 10 deletions.
21 changes: 21 additions & 0 deletions Api/BoldQuoteRepositoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
declare(strict_types = 1);

//phpcs:disable Magento2.Annotation.MethodArguments.NoCommentBlock
//phpcs:disable Magento2.Annotation.MethodArguments.ParamMissing
//phpcs:disable Magento2.Annotation.MethodAnnotationStructure.MethodAnnotation

namespace Bold\Checkout\Api;

use Bold\Checkout\Api\Data\BoldQuoteInterface;
use Magento\Framework\Exception\NoSuchEntityException;

interface BoldQuoteRepositoryInterface
{
/**
* @param int $cartId
* @return BoldQuoteInterface
* @throws NoSuchEntityException
*/
public function getByCartId(int $cartId): BoldQuoteInterface;
}
29 changes: 29 additions & 0 deletions Api/Data/BoldQuoteInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
declare(strict_types = 1);

//phpcs:disable Magento2.Annotation.MethodArguments.NoCommentBlock
//phpcs:disable Magento2.Annotation.MethodArguments.ParamMissing
//phpcs:disable Magento2.Annotation.MethodAnnotationStructure.MethodAnnotation

namespace Bold\Checkout\Api\Data;

interface BoldQuoteInterface
{
public function getId();

public function getQuoteId(): ?int;

public function setQuoteId(int $quoteId): void;

public function getOrderCreated(): ?bool;

public function setOrderCreated(bool $orderCreated): void;

public function getApiType(): ?string;

public function setApiType(string $apiType): void;

public function getPublicOrderId(): ?string;

public function setPublicOrderId(string $publicOrderId): void;
}
49 changes: 49 additions & 0 deletions Model/BoldQuoteRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
declare(strict_types = 1);

//phpcs:disable Magento2.Annotation.MethodArguments.NoCommentBlock
//phpcs:disable Magento2.Annotation.MethodArguments.ParamMissing
//phpcs:disable Magento2.Annotation.MethodAnnotationStructure.MethodAnnotation

namespace Bold\Checkout\Model;

use Bold\Checkout\Api\BoldQuoteRepositoryInterface;
use Bold\Checkout\Api\Data\BoldQuoteInterface;
use Bold\Checkout\Model\ResourceModel\Quote\QuoteExtensionData as QuoteExtensionDataResource;
use Bold\Checkout\Model\Quote\QuoteExtensionDataFactory;
use Magento\Framework\Exception\NoSuchEntityException;

class BoldQuoteRepository implements BoldQuoteRepositoryInterface
{
/**
* @var QuoteExtensionDataResource
*/
private $boldQuoteResource;

/**
* @var QuoteExtensionDataFactory
*/
private $quoteExtensionDataFactory;

public function __construct(
QuoteExtensionDataResource $boldQuoteResource,
QuoteExtensionDataFactory $quoteExtensionDataFactory,
) {
$this->boldQuoteResource = $boldQuoteResource;
$this->quoteExtensionDataFactory = $quoteExtensionDataFactory;
}

/**
* @inheritDoc
*/
public function getByCartId(int $cartId): BoldQuoteInterface
{
$boldQuote = $this->quoteExtensionDataFactory->create();
$this->boldQuoteResource->load($boldQuote, $cartId, QuoteExtensionDataResource::QUOTE_ID);
if ($boldQuote->getId() === null) {
throw new NoSuchEntityException(__('No Bold Quote found for ID: %1.', $cartId));
}

return $boldQuote;
}
}
1 change: 1 addition & 0 deletions Model/Order/InitOrderFromQuote.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ public function init(CartInterface $quote, string $flowId = self::FLOW_ID): arra
[
QuoteExtensionData::ORDER_CREATED => false,
QuoteExtensionData::API_TYPE => InitOrderFromQuote::API_TYPE_DEFAULT,
QuoteExtensionData::PUBLIC_ORDER_ID => $publicOrderId,
]
);

Expand Down
18 changes: 17 additions & 1 deletion Model/Quote/QuoteExtensionData.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@

namespace Bold\Checkout\Model\Quote;

use Bold\Checkout\Api\Data\BoldQuoteInterface;
use Bold\Checkout\Model\ResourceModel\Quote\QuoteExtensionData as QuoteExtensionDataResource;
use Magento\Framework\Model\AbstractModel;

/**
* Bold quote data entity.
*/
class QuoteExtensionData extends AbstractModel
class QuoteExtensionData extends AbstractModel implements BoldQuoteInterface
{
/**
* @inheritDoc
Expand Down Expand Up @@ -72,4 +73,19 @@ public function getApiType(): ?string
{
return $this->getData(QuoteExtensionDataResource::API_TYPE);
}

public function setApiType(string $apiType): void
{
$this->setData(QuoteExtensionDataResource::API_TYPE, $apiType);
}

public function getPublicOrderId(): ?string
{
return $this->getData(QuoteExtensionDataResource::PUBLIC_ORDER_ID);
}

public function setPublicOrderId(string $publicOrderId): void
{
$this->setData(QuoteExtensionDataResource::PUBLIC_ORDER_ID, $publicOrderId);
}
}
1 change: 1 addition & 0 deletions Model/ResourceModel/Quote/QuoteExtensionData.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class QuoteExtensionData extends AbstractDb
public const TABLE = 'bold_checkout_quote';
public const ID = 'id';
public const QUOTE_ID = 'quote_id';
public const PUBLIC_ORDER_ID = 'public_order_id';
public const ORDER_CREATED = 'order_created';
public const API_TYPE = 'api_type';

Expand Down
81 changes: 73 additions & 8 deletions Observer/Checkout/RedirectToBoldCheckoutObserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@

namespace Bold\Checkout\Observer\Checkout;

use Bold\Checkout\Api\BoldQuoteRepositoryInterface;
use Bold\Checkout\Api\Http\ClientInterface;
use Bold\Checkout\Model\ConfigInterface;
use Bold\Checkout\Model\Order\InitOrderFromQuote;
use Bold\Checkout\Model\Order\ResumeOrder;
use Bold\Checkout\Model\Quote\QuoteExtensionDataFactory;
use Bold\Checkout\Model\RedirectToBoldCheckout\IsOrderInitializationAllowedInterface;
use Bold\Checkout\Model\RedirectToBoldCheckout\IsRedirectToBoldCheckoutAllowedInterface;
use Exception;
use Magento\Checkout\Model\Session;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Quote\Api\Data\CartInterface;
use Psr\Log\LoggerInterface;

/**
Expand Down Expand Up @@ -54,6 +60,16 @@ class RedirectToBoldCheckoutObserver implements ObserverInterface
*/
private $isRedirectToBoldCheckoutAllowed;

/**
* @var BoldQuoteRepositoryInterface
*/
private $boldQuoteRepository;

/**
* @var ResumeOrder
*/
private $resumeOrder;

/**
* @param Session $session
* @param InitOrderFromQuote $initOrderFromQuote
Expand All @@ -62,6 +78,8 @@ class RedirectToBoldCheckoutObserver implements ObserverInterface
* @param ClientInterface $client
* @param IsOrderInitializationAllowedInterface $isOrderInitializationAllowed
* @param IsRedirectToBoldCheckoutAllowedInterface $isRedirectToBoldCheckoutAllowed
* @param BoldQuoteRepositoryInterface $boldQuoteRepository
* @param ResumeOrder $resumeOrder
*/
public function __construct(
Session $session,
Expand All @@ -70,7 +88,9 @@ public function __construct(
LoggerInterface $logger,
ClientInterface $client,
IsOrderInitializationAllowedInterface $isOrderInitializationAllowed,
IsRedirectToBoldCheckoutAllowedInterface $isRedirectToBoldCheckoutAllowed
IsRedirectToBoldCheckoutAllowedInterface $isRedirectToBoldCheckoutAllowed,
BoldQuoteRepositoryInterface $boldQuoteRepository,
ResumeOrder $resumeOrder
) {
$this->session = $session;
$this->initOrderFromQuote = $initOrderFromQuote;
Expand All @@ -79,6 +99,8 @@ public function __construct(
$this->client = $client;
$this->isOrderInitializationAllowed = $isOrderInitializationAllowed;
$this->isRedirectToBoldCheckoutAllowed = $isRedirectToBoldCheckoutAllowed;
$this->boldQuoteRepository = $boldQuoteRepository;
$this->resumeOrder = $resumeOrder;
}

/**
Expand All @@ -94,21 +116,64 @@ public function execute(Observer $observer): void
if (!$this->isOrderInitializationAllowed->isAllowed($quote, $request)) {
return;
}
$checkoutData = $this->initOrderFromQuote->init($quote);

$checkoutData = $this->resumeExistingCart($quote);
if ($checkoutData === null) {
$checkoutData = $this->initOrderFromQuote->init($quote);
}

$this->session->setBoldCheckoutData($checkoutData);
if (!$this->isRedirectToBoldCheckoutAllowed->isAllowed($quote, $request)) {
return;
}

$this->client->get($websiteId, 'refresh');
$orderId = $checkoutData['data']['public_order_id'];
$token = $checkoutData['data']['jwt_token'];
$shopName = $checkoutData['data']['initial_data']['shop_name'];
$checkoutApiUrl = rtrim($this->config->getCheckoutUrl($websiteId), '/') . '/bold_platform/';
$checkoutUrl = $checkoutApiUrl . $shopName . '/experience/resume?public_order_id=' . $orderId
. '&token=' . $token;

$orderId = $checkoutData['data']['public_order_id'] ?? '';
$token = $checkoutData['data']['jwt_token'] ?? '';
$shopName = $checkoutData['data']['initial_data']['shop_name'] ?? '';

$checkoutUrl = $this->getCheckoutUrl(
$websiteId,
$shopName,
$orderId,
$token
);

$observer->getControllerAction()->getResponse()->setRedirect($checkoutUrl);
} catch (Exception $exception) {
$this->logger->critical($exception);
}
}

/**
* @throws NoSuchEntityException
*/
private function getPublicOrderIdForCart(int $cartId): string
{
return $this->boldQuoteRepository
->getByCartId($cartId)
->getPublicOrderId() ?? '';
}

private function resumeExistingCart(CartInterface $cart): array|null
{
try {
$publicOrderId = $this->getPublicOrderIdForCart((int) $cart->getId());
return $this->resumeOrder->resume($cart, $publicOrderId);
} catch (NoSuchEntityException|LocalizedException) {
return null;
}
}

private function getCheckoutUrl(int $websiteId, string $shopName, string $publicOrderId, string $token): string
{
return \sprintf(
'%s/bold_platform/%s/experience/resume?public_order_id=%s&jwt_token=%s',
rtrim($this->config->getCheckoutUrl($websiteId), '/'),
$shopName,
$publicOrderId,
$token
);
}
}
1 change: 1 addition & 0 deletions etc/db_schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<table name="bold_checkout_quote" resource="default" engine="innodb" comment="Bold Checkout Quote Additional Data">
<column xsi:type="int" name="id" unsigned="true" nullable="false" identity="true" comment="ID"/>
<column xsi:type="int" name="quote_id" unsigned="true" nullable="false" identity="false" comment="Magento Quote ID"/>
<column xsi:type="varchar" name="public_order_id" nullable="true" length="255" comment="Bold Order Public ID"/>
<column xsi:type="smallint" name="order_created" default="0" comment="Magento Order Should Be Created On Magento Side"/>
<column xsi:type="varchar" name="api_type" nullable="true" length="15" comment="Bold Checkout API Type"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
Expand Down
3 changes: 2 additions & 1 deletion etc/db_schema_whitelist.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@
"column": {
"id": true,
"quote_id": true,
"public_order_id": true,
"order_created": true,
"api_type": true
},
"constraint": {
"PRIMARY": true,
"PRIMARY": true,
"BOLD_CHECKOUT_QUOTE_QUOTE_ID": true
}
}
Expand Down
3 changes: 3 additions & 0 deletions etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
<preference for="Bold\Checkout\Api\Data\ModuleVersion\ResultInterface" type="Bold\Checkout\Model\Data\ModuleVersion\Result"/>
<preference for="Bold\Checkout\Api\Data\ModuleVersion\ModuleVersionInterface" type="Bold\Checkout\Model\Data\ModuleVersion\ModuleVersion"/>
<preference for="Bold\Checkout\Model\Order\CompleteOrderInterface" type="Bold\Checkout\Model\Order\CompleteOrderPool"/>
<preference for="Bold\Checkout\Api\Data\BoldQuoteInterface" type="Bold\Checkout\Model\Quote\QuoteExtensionData"/>
<preference for="Bold\Checkout\Api\BoldQuoteRepositoryInterface" type="Bold\Checkout\Model\BoldQuoteRepository"/>

<type name="Bold\Checkout\Model\Order\CompleteOrderPool">
<arguments>
<argument name="pool" xsi:type="array">
Expand Down

0 comments on commit a0b0003

Please sign in to comment.