diff --git a/Api/Data/Order/OrderReferenceInterface.php b/Api/Data/Order/OrderReferenceInterface.php index a6fb7b8..a4b4105 100755 --- a/Api/Data/Order/OrderReferenceInterface.php +++ b/Api/Data/Order/OrderReferenceInterface.php @@ -65,4 +65,23 @@ public function getExtSentAt(); * @return bool */ public function isSent(); + + /** + * Can resend order again after successful send. + * + * @return bool + */ + public function canResend(); + + /** + * Can resend order again after failed send. + * + * @return bool + */ + public function canRetry(); + + /** + * @return bool + */ + public function canEdit(); } diff --git a/Api/Data/Quote/QuoteReferenceInterface.php b/Api/Data/Quote/QuoteReferenceInterface.php index 7ed39a1..de1ab3f 100644 --- a/Api/Data/Quote/QuoteReferenceInterface.php +++ b/Api/Data/Quote/QuoteReferenceInterface.php @@ -73,4 +73,11 @@ public function setTokenExpiresAt($value); * @return string */ public function getTokenExpiresAt(); + + /** + * @param \DateTime|null $now + * + * @return bool + */ + public function isTokenExpired(\DateTime $now = null); } diff --git a/Api/QuoteReferenceRepositoryInterface.php b/Api/QuoteReferenceRepositoryInterface.php index 2dfdd7e..613d2bf 100644 --- a/Api/QuoteReferenceRepositoryInterface.php +++ b/Api/QuoteReferenceRepositoryInterface.php @@ -18,7 +18,7 @@ interface QuoteReferenceRepositoryInterface { /** - * @param $quoteId + * @param int $quoteId * * @return QuoteReferenceInterface * @throws NoSuchEntityException diff --git a/Block/Adminhtml/Order/Create/Shipping/Method/Paazl/Widget/Config.php b/Block/Adminhtml/Order/Create/Shipping/Method/Paazl/Widget/Config.php new file mode 100755 index 0000000..be2d760 --- /dev/null +++ b/Block/Adminhtml/Order/Create/Shipping/Method/Paazl/Widget/Config.php @@ -0,0 +1,75 @@ +configProvider = $configProvider; + $this->serializer = $serializer; + parent::__construct($context, $data); + } + + /** + * Retrieves order configuration + * + * @return array + */ + public function getWidgetConfig() + { + return $this->configProvider->getConfig(); + } + + /** + * Retrieves serialized order config. + * + * @return bool|string + */ + public function getSerializedWidgetConfig() + { + return $this->serializer->serialize($this->getWidgetConfig()); + } +} diff --git a/Block/Adminhtml/Order/Create/Shipping/Method/Paazl/Widget/Modal.php b/Block/Adminhtml/Order/Create/Shipping/Method/Paazl/Widget/Modal.php new file mode 100755 index 0000000..d79fac4 --- /dev/null +++ b/Block/Adminhtml/Order/Create/Shipping/Method/Paazl/Widget/Modal.php @@ -0,0 +1,124 @@ +sessionQuote = $sessionQuote; + $this->serializer = $serializer; + parent::__construct($context, $data); + } + + /** + * Retrieve quote session object + * + * @return SessionQuote + */ + protected function getSession() + { + return $this->sessionQuote; + } + + /** + * Retrieve quote model object + * + * @return Quote + */ + public function getQuote() + { + return $this->getSession()->getQuote(); + } + + /** + * Retrieve customer identifier + * + * @return int + */ + public function getCustomerId() + { + return $this->getSession()->getCustomerId(); + } + + /** + * Retrieve store model object + * + * @return Store + */ + public function getStore() + { + return $this->getSession()->getStore(); + } + + /** + * Retrieve store identifier + * + * @return int + */ + public function getStoreId() + { + return $this->getSession()->getStoreId(); + } + + /** + * Initialize paazl modal widget + * + * @return string + */ + public function getPaazlWidgetModalJson() + { + return $this->serializer->serialize( + [ + 'paazlWidgetModal' => [ + 'modalClass' => 'ui-dialog-active ui-popup paazl-widget-modal' + ], + ] + ); + } +} diff --git a/Block/Adminhtml/Order/View/ShippingAndHandling/PaazlEdit.php b/Block/Adminhtml/Order/View/ShippingAndHandling/PaazlEdit.php index e188ef5..2b2e591 100644 --- a/Block/Adminhtml/Order/View/ShippingAndHandling/PaazlEdit.php +++ b/Block/Adminhtml/Order/View/ShippingAndHandling/PaazlEdit.php @@ -113,4 +113,4 @@ public function getSaveUrl() ] ); } -} \ No newline at end of file +} diff --git a/Block/Adminhtml/Order/View/ShippingAndHandling/PaazlStatus.php b/Block/Adminhtml/Order/View/ShippingAndHandling/PaazlStatus.php index 7a7bdc9..b962df0 100644 --- a/Block/Adminhtml/Order/View/ShippingAndHandling/PaazlStatus.php +++ b/Block/Adminhtml/Order/View/ShippingAndHandling/PaazlStatus.php @@ -67,8 +67,9 @@ protected function _prepareLayout() return parent::_prepareLayout(); } - if ($this->getPaazlOrder()->isSent()) { - $onclick = "submitAndReloadArea($('paazl-order-status').parentNode.parentNode, '" . $this->getResendUrl() . "')"; + if ($this->getPaazlOrder()->canResend()) { + $onclick = "submitAndReloadArea($('paazl-order-status').parentNode.parentNode, '" . + $this->getResendUrl() . "')"; $resendButton = $this->getLayout() ->createBlock(Button::class) ->setData([ @@ -80,18 +81,24 @@ protected function _prepareLayout() return parent::_prepareLayout(); } - $onclick = "submitAndReloadArea($('paazl-order-status').parentNode.parentNode, '" . $this->getRetryUrl() . "')"; - $retryButton = $this->getLayout() - ->createBlock(Button::class) - ->setData([ - 'label' => __('Retry'), - 'class' => 'action-retry action-secondary', - 'onclick' => $onclick - ]); - $editBlock = $this->getLayout() - ->createBlock(PaazlEdit::class); - $this->setChild('retry_button', $retryButton); - $this->setChild('edit_block', $editBlock); + if ($this->getPaazlOrder()->canEdit()) { + $editBlock = $this->getLayout()->createBlock(PaazlEdit::class); + $this->setChild('edit_block', $editBlock); + } + + if ($this->getPaazlOrder()->canRetry()) { + $onclick = "submitAndReloadArea($('paazl-order-status').parentNode.parentNode, '" . + $this->getRetryUrl() . "')"; + $retryButton = $this->getLayout() + ->createBlock(Button::class) + ->setData([ + 'label' => __('Retry'), + 'class' => 'action-retry action-secondary', + 'onclick' => $onclick + ]); + + $this->setChild('retry_button', $retryButton); + } return parent::_prepareLayout(); } @@ -158,7 +165,8 @@ public function getPaazlOrder() { if (null === $this->paazlOrder) { try { - $this->paazlOrder = $this->getOrderReferenceRepository()->getByOrderId($this->getOrder()->getEntityId()); + $this->paazlOrder = + $this->getOrderReferenceRepository()->getByOrderId($this->getOrder()->getEntityId()); } catch (NoSuchEntityException $exception) { $this->paazlOrder = false; } diff --git a/Block/Checkout/Widget.php b/Block/Checkout/Widget.php index 7298bbc..8974502 100755 --- a/Block/Checkout/Widget.php +++ b/Block/Checkout/Widget.php @@ -8,6 +8,7 @@ use Magento\Framework\View\Element\Template; use Paazl\CheckoutWidget\Model\Api\UrlProvider; +use Paazl\CheckoutWidget\Model\Api\UrlProviderFactory; use Paazl\CheckoutWidget\Model\Checkout\WidgetConfigProvider; use Paazl\CheckoutWidget\Model\Config; use Magento\Framework\View\Element\Template\Context; @@ -40,31 +41,23 @@ class Widget extends Template * * @param Context $context * @param Config $scopeConfig - * @param UrlProvider $urlProvider + * @param UrlProviderFactory $urlProviderFactory * @param WidgetConfigProvider $widgetConfigProvider * @param array $data */ public function __construct( Context $context, Config $scopeConfig, - UrlProvider $urlProvider, + UrlProviderFactory $urlProviderFactory, WidgetConfigProvider $widgetConfigProvider, array $data = [] ) { $this->scopeConfig = $scopeConfig; $this->widgetConfigProvider = $widgetConfigProvider; - $this->urlProvider = $urlProvider; + $this->urlProvider = $urlProviderFactory->create(); parent::__construct($context, $data); } - /** - * @return string - */ - public function getWidgetConfigJson() - { - return json_encode($this->widgetConfigProvider->getConfig()); - } - // --- /** diff --git a/Controller/Adminhtml/Order.php b/Controller/Adminhtml/Order.php index 40849f7..bc7620a 100644 --- a/Controller/Adminhtml/Order.php +++ b/Controller/Adminhtml/Order.php @@ -17,7 +17,9 @@ abstract class Order extends Action { - /** @var JsonFactory */ + /** + * @var JsonFactory + */ protected $resultJsonFactory; /** @@ -30,7 +32,9 @@ abstract class Order extends Action */ protected $orderRepository; - /** @var SendToService */ + /** + * @var SendToService + */ protected $sendToService; /** @@ -75,4 +79,4 @@ protected function _initOrder() } return $order; } -} \ No newline at end of file +} diff --git a/Controller/Adminhtml/Order/Data/Save.php b/Controller/Adminhtml/Order/Data/Save.php index 783a1e6..9f67a2d 100644 --- a/Controller/Adminhtml/Order/Data/Save.php +++ b/Controller/Adminhtml/Order/Data/Save.php @@ -7,7 +7,7 @@ namespace Paazl\CheckoutWidget\Controller\Adminhtml\Order\Data; use Magento\Backend\App\Action; -use Magento\Backend\Model\Session\Proxy as Session; +use Magento\Backend\Model\Session; use Magento\Backend\Model\View\Result\Redirect; use Magento\Framework\Controller\Result\Json; use Magento\Framework\Controller\Result\JsonFactory; @@ -26,10 +26,10 @@ use Paazl\CheckoutWidget\Controller\Adminhtml\Order; use Paazl\CheckoutWidget\Model\Api\Field\DeliveryType; use Paazl\CheckoutWidget\Model\Api\Processor\SendToService; -use Paazl\CheckoutWidget\Model\Api\PaazlApi; use Paazl\CheckoutWidget\Model\Api\Builder\Order as OrderBuilder; use Paazl\CheckoutWidget\Model\ExtInfoHandler; use Paazl\CheckoutWidget\Model\Config; +use Paazl\CheckoutWidget\Model\ShippingInfoFactory; /** * Edit Data Controller @@ -38,45 +38,62 @@ class Save extends Order { const DEFAULT_MESSAGE_KEY = 'message'; - /** @var PaazlApi */ - protected $paazlApi; - - /** @var SerializerInterface */ + /** + * @var SerializerInterface + */ protected $serializer; - /** @var LayoutFactory */ + /** + * @var LayoutFactory + */ private $layoutFactory; - /** @var Session */ + /** + * @var Session + */ private $session; - /** @var OrderReferenceRepositoryInterface */ + /** + * @var OrderReferenceRepositoryInterface + */ private $orderReferenceRepository; - /** @var OrderBuilder */ + /** + * @var OrderBuilder + */ private $orderBuilder; - /** @var ExtInfoHandler */ + /** + * @var ExtInfoHandler + */ private $extInfoHandler; + /** + * @var Config + */ private $scopeConfig; + /** + * @var ShippingInfoFactory + */ + private $shippingInfoFactory; + /** * Constructor * - * @param Action\Context $context - * @param JsonFactory $resultJsonFactory - * @param PageFactory $resultPageFactory - * @param OrderRepositoryInterface $orderRepository - * @param SendToService $sendToService - * @param PaazlApi $paazlApi - * @param SerializerInterface $serializer - * @param LayoutFactory $layoutFactory - * @param Session $session + * @param Action\Context $context + * @param JsonFactory $resultJsonFactory + * @param PageFactory $resultPageFactory + * @param OrderRepositoryInterface $orderRepository + * @param SendToService $sendToService + * @param SerializerInterface $serializer + * @param LayoutFactory $layoutFactory + * @param Session $session * @param OrderReferenceRepositoryInterface $orderReferenceRepository - * @param OrderBuilder $orderBuilder - * @param ExtInfoHandler $extInfoHandler - * @param Config $scopeConfig + * @param OrderBuilder $orderBuilder + * @param ExtInfoHandler $extInfoHandler + * @param ShippingInfoFactory $shippingInfoFactory + * @param Config $scopeConfig */ public function __construct( Action\Context $context, @@ -84,13 +101,13 @@ public function __construct( PageFactory $resultPageFactory, OrderRepositoryInterface $orderRepository, SendToService $sendToService, - PaazlApi $paazlApi, SerializerInterface $serializer, LayoutFactory $layoutFactory, Session $session, OrderReferenceRepositoryInterface $orderReferenceRepository, OrderBuilder $orderBuilder, ExtInfoHandler $extInfoHandler, + ShippingInfoFactory $shippingInfoFactory, Config $scopeConfig ) { parent::__construct( @@ -100,7 +117,6 @@ public function __construct( $orderRepository, $sendToService ); - $this->paazlApi = $paazlApi; $this->serializer = $serializer; $this->layoutFactory = $layoutFactory; $this->session = $session; @@ -108,6 +124,7 @@ public function __construct( $this->orderBuilder = $orderBuilder; $this->extInfoHandler = $extInfoHandler; $this->scopeConfig = $scopeConfig; + $this->shippingInfoFactory = $shippingInfoFactory; } /** @@ -126,6 +143,11 @@ public function execute() $order = $this->_initOrder(); $orderReference = $this->orderReferenceRepository->getByOrderId($order->getEntityId()); $shippingInfo = $this->extInfoHandler->getInfoFromOrderReference($orderReference); + + if (!$shippingInfo) { + $shippingInfo = $this->shippingInfoFactory->create(); + } + $shippingInfo->setType(DeliveryType::DELIVERY); $shippingInfo->setIdenfifier($shippingOption['identifier']); $shippingInfo->setOptionTitle($shippingOption['name']); diff --git a/Controller/Adminhtml/Order/Data/Validate.php b/Controller/Adminhtml/Order/Data/Validate.php index a957182..eccbfc1 100644 --- a/Controller/Adminhtml/Order/Data/Validate.php +++ b/Controller/Adminhtml/Order/Data/Validate.php @@ -13,7 +13,7 @@ use Magento\Framework\View\Result\PageFactory; use Magento\Framework\Serialize\SerializerInterface; use Magento\Sales\Api\OrderRepositoryInterface; -use Magento\Backend\Model\Session\Proxy as Session; +use Magento\Backend\Model\Session; use Paazl\CheckoutWidget\Controller\Adminhtml\Order; use Paazl\CheckoutWidget\Model\Api\Processor\SendToService; @@ -24,10 +24,14 @@ class Validate extends Order { const DEFAULT_MESSAGE_KEY = 'message'; - /** @var SerializerInterface */ + /** + * @var SerializerInterface + */ protected $serializer; - /** @var Session */ + /** + * @var Session + */ private $session; /** diff --git a/Controller/Adminhtml/Order/Resend.php b/Controller/Adminhtml/Order/Resend.php index 2a83e72..9ccd761 100644 --- a/Controller/Adminhtml/Order/Resend.php +++ b/Controller/Adminhtml/Order/Resend.php @@ -62,7 +62,8 @@ public function __construct( LoggerInterface $logger ) { $this->sendToService = $sendToService; - parent::__construct($context, + parent::__construct( + $context, $coreRegistry, $fileFactory, $translateInline, diff --git a/Controller/Adminhtml/Order/Retry.php b/Controller/Adminhtml/Order/Retry.php index 6552382..5b427f9 100644 --- a/Controller/Adminhtml/Order/Retry.php +++ b/Controller/Adminhtml/Order/Retry.php @@ -62,7 +62,8 @@ public function __construct( LoggerInterface $logger ) { $this->sendToService = $sendToService; - parent::__construct($context, + parent::__construct( + $context, $coreRegistry, $fileFactory, $translateInline, diff --git a/Helper/General.php b/Helper/General.php index d9d14aa..60d96dc 100755 --- a/Helper/General.php +++ b/Helper/General.php @@ -91,8 +91,8 @@ public function getMagentoVersion() } /** - * @param $type - * @param $data + * @param string $type + * @param mixed $data */ public function addTolog($type, $data) { diff --git a/Helper/Order.php b/Helper/Order.php index fc3d1a9..7a6bae8 100755 --- a/Helper/Order.php +++ b/Helper/Order.php @@ -23,8 +23,17 @@ class Order */ public function isPaazlOrder(OrderInterface $order) { - $shippingMethod = $order->getShippingMethod(); + return $this->isPaazlShippingMethod($order->getShippingMethod()); + } - return $shippingMethod == Paazlshipping::CODE . '_' . Paazlshipping::CODE; + /** + * @param string $shippingMethod + * + * @return bool + */ + public function isPaazlShippingMethod(string $shippingMethod) + { + $params = explode('_', $shippingMethod, 2); + return !empty($params[0]) && ($params[0] === Paazlshipping::CODE); } } diff --git a/Logger/PaazlLogger.php b/Logger/PaazlLogger.php index 30e7664..6985109 100755 --- a/Logger/PaazlLogger.php +++ b/Logger/PaazlLogger.php @@ -17,8 +17,8 @@ class PaazlLogger extends Logger { /** - * @param $type - * @param $data + * @param string $type + * @param mixed $data */ public function add($type, $data) { diff --git a/Model/Admin/Order/Create/LanguageProvider.php b/Model/Admin/Order/Create/LanguageProvider.php new file mode 100755 index 0000000..6834efe --- /dev/null +++ b/Model/Admin/Order/Create/LanguageProvider.php @@ -0,0 +1,52 @@ +resolver = $resolver; + } + + /** + * Retrieve assoc array of checkout configuration + * + * @return array + */ + public function getConfig() + { + $languageCode = 'en'; + if ($this->resolver->getLocale()) { + $locale = $this->resolver->getLocale(); + $languageCode = explode('_', $locale)[0]; + } + + return [ + 'language' => $languageCode, + ]; + } +} diff --git a/Model/Admin/Order/Create/PaazlConfigProvider.php b/Model/Admin/Order/Create/PaazlConfigProvider.php new file mode 100755 index 0000000..af368d6 --- /dev/null +++ b/Model/Admin/Order/Create/PaazlConfigProvider.php @@ -0,0 +1,91 @@ +config = $config; + $this->urlProvider = $urlProviderFactory->create($sessionQuote->getQuote()->getStoreId()); + $this->widgetConfigProvider = $widgetConfigProvider; + $this->sessionQuote = $sessionQuote; + } + + /** + * Retrieve assoc array of checkout configuration + * + * @return array + */ + public function getConfig() + { + $config = []; + $storeId = $this->sessionQuote->getQuote()->getStoreId(); + if (!$this->config->isEnabled($storeId) || !$this->sessionQuote->getQuote()->getId()) { + return $config; + } + + $config['hideOtherMethods'] = $this->config->isHideOtherShippingMethods($storeId); + $config['carrierCode'] = Paazlshipping::CODE; + $config['methodCode'] = Paazlshipping::CODE; + $config['baseApiUrl'] = $this->urlProvider->getBaseUrl(); + $config['googleMapKey'] = $this->config->getGoogleMapKey($storeId); + $config['widgetConfig'] = $this->widgetConfigProvider->getConfig(); + $config['mode'] = $this->config->isProductionApiMode($storeId) ? 'live' : 'test'; + + if (empty($config['widgetConfig']['token'])) { + // We were unable to obtain a token - enabling other methods if they're available + $config['hideOtherMethods'] = false; + } + + return [ + 'paazlshipping' => $config + ]; + } +} diff --git a/Model/Admin/Order/Create/WidgetConfigProvider.php b/Model/Admin/Order/Create/WidgetConfigProvider.php new file mode 100755 index 0000000..aa35a49 --- /dev/null +++ b/Model/Admin/Order/Create/WidgetConfigProvider.php @@ -0,0 +1,396 @@ +scopeConfig = $scopeConfig; + $this->sessionQuote = $sessionQuote; + $this->order = $order; + $this->generalHelper = $generalHelper; + $this->tokenRetriever = $tokenRetriever; + $this->languageProvider = $languageProvider; + $this->productRepository = $productRepository; + } + + /** + * {@inheritDoc} + */ + public function getConfig() + { + $countryId = $this->getDefaultCountry(); + $postcode = $this->getDefaultPostcode(); + + $shippingAddress = $this->getQuote()->getShippingAddress(); + if ($shippingAddress->getCountryId() && + $shippingAddress->getPostcode()) { + $countryId = $shippingAddress->getCountryId(); + $postcode = $shippingAddress->getPostcode(); + } + + $numberOfProcessingDays = self::DEFAULT_NUMBER_OF_PROCESSING_DAYS; + $goods = []; + foreach ($this->getQuote()->getAllVisibleItems() as $item) { + $goodsItem = [ + "quantity" => (int)$item->getQty(), + "weight" => doubleval($item->getWeight()), + "price" => $this->formatPrice($item->getPrice()) + ]; + + if (($itemNumberOfProcessingDays = $this->getProductNumberOfProcessingDays($item)) + && $itemNumberOfProcessingDays > $numberOfProcessingDays) { + $numberOfProcessingDays = (int)$itemNumberOfProcessingDays; + } + + if ($deliveryMatrixCode = $this->getProductDeliveryMatrix($item)) { + $goodsItem["startMatrix"] = $deliveryMatrixCode; + } + $goods[] = $goodsItem; + } + + $config = [ + "mountElementId" => "widget_paazlshipping_paazlshipping", + "apiKey" => $this->getApiKey(), + "token" => $this->getApiToken(), + "loadPaazlBasedData" => true, + "loadCarrierBasedData" => true, + "availableTabs" => $this->getAvailableTabs(), + "defaultTab" => $this->getDefaultTab(), + "style" => $this->getWidgetTheme(), + "nominatedDateEnabled" => $this->getNominatedDateEnabled(), + "consigneeCountryCode" => $countryId, + "consigneePostalCode" => $postcode, + "numberOfProcessingDays" => $numberOfProcessingDays, + "deliveryDateOptions" => [ + "startDate" => date("Y-m-d"), + "numberOfDays" => 10 + ], + "currency" => $this->getQuote()->getQuoteCurrencyCode(), + "deliveryOptionDateFormat" => "ddd DD MMM", + "deliveryEstimateDateFormat" => "dddd DD MMMM", + "pickupOptionDateFormat" => "ddd DD MMM", + "pickupEstimateDateFormat" => "dddd DD MMMM", + "sortingModel" => [ + "orderBy" => "PRICE", + "sortOrder" => "ASC" + ], + "shipmentParameters" => [ + "totalWeight" => $this->getTotalWeight(), + "totalPrice" => $this->formatPrice($this->getQuote()->getSubtotal()), + "numberOfGoods" => $this->getProductsCount(), + "goods" => $goods + ], + "shippingOptionsLimit" => $this->getShippingOptionsLimit(), + "pickupLocationsPageLimit" => $this->getPickupLocationsPageLimit(), + "pickupLocationsLimit" => $this->getPickupLocationsLimit(), + "initialPickupLocations" => $this->getInitialPickupLocations() + ]; + + $config = array_merge($config, $this->languageProvider->getConfig()); + + $this->generalHelper->addTolog('config', $config); + + return $config; + } + + /** + * @return Quote + */ + public function getQuote() + { + return $this->sessionQuote->getQuote(); + } + + /** + * @return mixed + */ + public function getDefaultCountry() + { + return $this->scopeConfig->getDefaultCountry($this->getQuote()->getStoreId()); + } + + /** + * @return mixed + */ + public function getDefaultPostcode() + { + return $this->scopeConfig->getDefaultPostcode($this->getQuote()->getStoreId()); + } + + /** + * @param double $price + * + * @return string + */ + public function formatPrice($price) + { + return number_format($price, 2, '.', ''); + } + + /** + * @return mixed + */ + public function getApiKey() + { + return $this->scopeConfig->getApiKey($this->getQuote()->getStoreId()); + } + + /** + * @return mixed + */ + public function getApiToken() + { + try { + return $this->tokenRetriever->retrieveByQuote($this->getQuote()); + } catch (LocalizedException $e) { + $this->generalHelper->addTolog('exception', $e->getMessage()); + } + + return null; + } + + /** + * @return array + */ + public function getAvailableTabs() + { + return $this->scopeConfig->getAvailableTabs($this->getQuote()->getStoreId()); + } + + /** + * @return mixed + */ + public function getDefaultTab() + { + return $this->scopeConfig->getDefaultTab($this->getQuote()->getStoreId()); + } + + /** + * @return string + */ + public function getWidgetTheme() + { + $widgetTheme = $this->scopeConfig->getWidgetTheme($this->getQuote()->getStoreId()); + return $widgetTheme == 'CUSTOM' ? 'DEFAULT' : $widgetTheme; + } + + /** + * @return bool + */ + public function getNominatedDateEnabled() + { + return $this->scopeConfig->getNominatedDateEnabled($this->getQuote()->getStoreId()); + } + + /** + * @return float + */ + public function getTotalWeight() + { + $weight = 0; + $quote = $this->getQuote(); + foreach ($quote->getAllVisibleItems() as $_item) { + $weight += $_item->getWeight(); + } + return $weight; + } + + /** + * @return float + */ + public function getProductsCount() + { + $count = 0; + $quote = $this->getQuote(); + foreach ($quote->getAllVisibleItems() as $_item) { + $count += $_item->getQty(); + } + return $count; + } + + /** + * Gets number of processing days from product + * + * @param AbstractItem $item + * @return int|mixed|null + * @throws NoSuchEntityException + */ + public function getProductNumberOfProcessingDays(AbstractItem $item) + { + $product = $this->productRepository->get($item->getSku()); + + $attribute = $this->scopeConfig + ->getProductAttributeNumberOfProcessingDays($this->getQuote()->getStoreId()); + if ($attribute) { + if (($numberOfProcessingDays = $product->getData($attribute)) !== null) { + if (is_numeric($numberOfProcessingDays) + && $numberOfProcessingDays >= Config::MIN_NUMBER_OF_PROCESSING_DAYS + && $numberOfProcessingDays <= Config::MAX_NUMBER_OF_PROCESSING_DAYS + ) { + return $numberOfProcessingDays; + } + } + } + + return null; + } + + /** + * @return int + */ + public function getShippingOptionsLimit() + { + return $this->scopeConfig->getShippingOptionsLimit($this->getQuote()->getStoreId()); + } + + /** + * @return int + */ + public function getPickupLocationsPageLimit() + { + return $this->scopeConfig->getPickupLocationsPageLimit($this->getQuote()->getStoreId()); + } + + /** + * @return int + */ + public function getPickupLocationsLimit() + { + return $this->scopeConfig->getPickupLocationsLimit($this->getQuote()->getStoreId()); + } + + /** + * @return int + */ + public function getInitialPickupLocations() + { + return $this->scopeConfig->getInitialPickupLocations($this->getQuote()->getStoreId()); + } + + /** + * @return boolean + */ + public function isEnabled() + { + return $this->scopeConfig->isEnabled($this->getQuote()->getStoreId()); + } + + /** + * Gets delivery matrix from product + * + * @param AbstractItem $item + * @return int|mixed|null + * @throws NoSuchEntityException + */ + public function getProductDeliveryMatrix(AbstractItem $item) + { + $product = $this->productRepository->get($item->getSku()); + + $attribute = $this->scopeConfig + ->getProductAttributeDeliveryMatrix($this->getQuote()->getStoreId()); + if ($attribute) { + if (($deliveryMatrixCode = $product->getData($attribute)) !== null + && $this->validateDeliveryMatrixCode($deliveryMatrixCode) + ) { + return $deliveryMatrixCode; + } + } + + return null; + } + + /** + * Validates matrix code according to Paazl instructions + * + * @param string $value + * @return bool + */ + protected function validateDeliveryMatrixCode(string $value) + { + preg_match('/^[A-Z]{1,2}$/', $value, $matches); + + return count($matches) === 1; + } +} diff --git a/Model/Api/ApiException.php b/Model/Api/ApiException.php index fe54f64..0c9fca6 100755 --- a/Model/Api/ApiException.php +++ b/Model/Api/ApiException.php @@ -23,14 +23,15 @@ public static function error(\Exception $previous = null) } /** - * @param $message - * @param $code + * @param string $message + * @param int|string $code * @param \Exception|null $previous * @return ApiException */ public static function fromErrorResponse($message, $code, \Exception $previous = null) { // Parsing errors + $code = (int)$code; $errors = json_decode($message, true); $message = 'API error'; if ($errors !== null && !empty($errors['errors']) && is_array($errors['errors'])) { diff --git a/Model/Api/Builder/Order.php b/Model/Api/Builder/Order.php index 0b268c8..7d23db9 100755 --- a/Model/Api/Builder/Order.php +++ b/Model/Api/Builder/Order.php @@ -94,6 +94,10 @@ public function getCreateOrderData(OrderInterface $order) } $extInformation = $this->extInfoHandler->getInfoFromOrderReference($reference); + if ($extInformation === null) { + throw new NotFoundException(__('Reference information not found')); + } + /** @var Address $shippingAddress */ $shippingAddress = $order->getShippingAddress(); if ($extInformation->getType() === DeliveryType::PICKUP) { @@ -211,7 +215,7 @@ private function parseAddress(Address $shippingAddress) } $address = implode(' ', $shippingAddress->getStreet()); - $pattern = '/^(?[\w[:alpha:]]+[ \w[:alpha:]]*) (?\d{1,5})((?[\-\/\s]*\w+)*)/'; + $pattern = '/^(?.+) (?[0-9]{1,5})(?[[:punct:]\s]*.+)*$/'; preg_match($pattern, $address, $matches); $parsedAddress = array_filter($matches, function ($key) { return !is_int($key); @@ -221,7 +225,7 @@ private function parseAddress(Address $shippingAddress) } /** - * @param $order + * @param OrderInterface $order * * @return array * @throws LocalizedException @@ -252,6 +256,7 @@ private function getProducts(OrderInterface $order) } if ($dimensions = $this->getProductDimemension($item)) { + // phpcs:ignore Magento2.Performance $itemData = array_merge($itemData, $dimensions); } diff --git a/Model/Api/Builder/Reference.php b/Model/Api/Builder/Reference.php index 70110be..fb1feab 100755 --- a/Model/Api/Builder/Reference.php +++ b/Model/Api/Builder/Reference.php @@ -41,7 +41,7 @@ public function __construct( */ public function getQuoteReference(Quote $quote) { - return $this->config->getReferencePrefix() . $quote->getId(); + return $this->config->getReferencePrefix($quote->getStoreId()) . $quote->getId(); } /** @@ -51,6 +51,6 @@ public function getQuoteReference(Quote $quote) */ public function getOrderReference(OrderInterface $order) { - return $this->config->getReferencePrefix() . $order->getIncrementId(); + return $this->config->getReferencePrefix($order->getStoreId()) . $order->getIncrementId(); } } diff --git a/Model/Api/Configuration.php b/Model/Api/Configuration.php new file mode 100644 index 0000000..f42d98a --- /dev/null +++ b/Model/Api/Configuration.php @@ -0,0 +1,113 @@ +timeout; + } + + /** + * @param int $timeout + * + * @return Configuration + */ + public function setTimeout(int $timeout): Configuration + { + if ($timeout > 0) { + $this->timeout = $timeout; + } + return $this; + } + + /** + * @return string + */ + public function getKey(): string + { + return $this->key; + } + + /** + * @param string $key + * + * @return Configuration + */ + public function setKey(string $key): Configuration + { + $this->key = $key; + return $this; + } + + /** + * @return string + */ + public function getSecret(): string + { + return $this->secret; + } + + /** + * @param string $secret + * + * @return Configuration + */ + public function setSecret(string $secret): Configuration + { + $this->secret = $secret; + return $this; + } + + /** + * @return int + */ + public function getMode(): int + { + return $this->mode; + } + + /** + * @param int $mode + * + * @return Configuration + */ + public function setMode(int $mode): Configuration + { + $this->mode = $mode; + return $this; + } +} diff --git a/Model/Api/Http/Client.php b/Model/Api/Http/Client.php new file mode 100644 index 0000000..304c4ee --- /dev/null +++ b/Model/Api/Http/Client.php @@ -0,0 +1,68 @@ +skipNextHeader) { + $this->skipNextHeader = false; + return strlen($data); + } + if ($this->_headerCount == 0) { + $line = explode(" ", trim($data), 3); + if (count($line) != 3) { + $this->doError("Invalid response line returned from server: " . $data); + } + $code = intval($line[1]); + if ($code === 100) { + // Handle status 100 Continue + $this->skipNextHeader = true; + return strlen($data); + } + $this->_responseStatus = intval($line[1]); + } else { + $name = $value = ''; + $out = explode(": ", trim($data), 2); + if (count($out) == 2) { + $name = $out[0]; + $value = $out[1]; + } + + if (strlen($name)) { + if ("Set-Cookie" == $name) { + if (!isset($this->_responseHeaders[$name])) { + $this->_responseHeaders[$name] = []; + } + $this->_responseHeaders[$name][] = $value; + } else { + $this->_responseHeaders[$name] = $value; + } + } + } + $this->_headerCount++; + + return strlen($data); + } +} diff --git a/Model/Api/PaazlApi.php b/Model/Api/PaazlApi.php index 75c5331..b1d748c 100644 --- a/Model/Api/PaazlApi.php +++ b/Model/Api/PaazlApi.php @@ -6,12 +6,11 @@ namespace Paazl\CheckoutWidget\Model\Api; -use Magento\Framework\HTTP\ClientFactory; use Magento\Framework\HTTP\ClientInterface; use Paazl\CheckoutWidget\Helper\General as GeneralHelper; +use Paazl\CheckoutWidget\Model\Api\Http\ClientFactory; use Paazl\CheckoutWidget\Model\Api\Response\Data\Token; use Paazl\CheckoutWidget\Model\Api\Response\Data\TokenBuilder; -use Paazl\CheckoutWidget\Model\Config; /** * Class PaazlApi @@ -22,9 +21,9 @@ class PaazlApi { /** - * @var Config + * @var Configuration */ - private $scopeConfig; + private $configuration; /** * @var array @@ -54,20 +53,20 @@ class PaazlApi /** * PaazlApi constructor. * - * @param Config $scopeConfig + * @param Configuration $configuration * @param GeneralHelper $generalHelper * @param ClientFactory $httpClientFactory * @param TokenBuilder $tokenBuilder * @param UrlProvider $urlProvider */ public function __construct( - Config $scopeConfig, + Configuration $configuration, GeneralHelper $generalHelper, ClientFactory $httpClientFactory, TokenBuilder $tokenBuilder, UrlProvider $urlProvider ) { - $this->scopeConfig = $scopeConfig; + $this->configuration = $configuration; $this->generalHelper = $generalHelper; $this->httpClientFactory = $httpClientFactory; $this->tokenBuilder = $tokenBuilder; @@ -89,7 +88,7 @@ public function getApiToken($reference) try { $this->request['reference'] = $reference; - $this->generalHelper->addTolog('Token request', $this->request); + $this->generalHelper->addTolog('Token request: ', $this->request); $httpClient->addHeader('Content-Type', 'application/json;charset=UTF-8'); $httpClient->addHeader('Accept', 'application/json;charset=UTF-8'); @@ -98,7 +97,8 @@ public function getApiToken($reference) $body = $httpClient->getBody(); $status = $httpClient->getStatus(); - $this->generalHelper->addTolog('Token response', $body); + $this->generalHelper->addTolog('Token response status: ', $status); + $this->generalHelper->addTolog('Token response: ', $body); if ($status >= 200 && $status < 300) { /** @var Token $token */ $token = $this->tokenBuilder->setResponse($body)->create(); @@ -124,7 +124,7 @@ public function addOrder(array $orderData) $httpClient = $this->getAuthorizedClient(); - $this->generalHelper->addTolog('Order request', $orderData); + $this->generalHelper->addTolog('AddOrder request: ', $orderData); $httpClient->addHeader('Content-Type', 'application/json;charset=UTF-8'); $httpClient->addHeader('Accept', 'application/json;charset=UTF-8'); @@ -133,7 +133,8 @@ public function addOrder(array $orderData) $body = $httpClient->getBody(); $status = $httpClient->getStatus(); - $this->generalHelper->addTolog('debug', $body); + $this->generalHelper->addTolog('AddOrder response status: ', $status); + $this->generalHelper->addTolog('AddOrder response body: ', $body); if ($status >= 400 && $status < 500) { throw ApiException::fromErrorResponse($body, $status); } @@ -145,13 +146,19 @@ public function addOrder(array $orderData) throw ApiException::error(); } + /** + * @param array $orderData + * + * @return string + * @throws ApiException + */ public function getShippingOptions(array $orderData) { $url = $this->urlProvider->getShippingOptionsUrl(); $httpClient = $this->getAuthorizedClient(); - $this->generalHelper->addTolog('Order request', $orderData); + $this->generalHelper->addTolog('getShippingOptions request: ', $orderData); $httpClient->addHeader('Content-Type', 'application/json;charset=UTF-8'); $httpClient->addHeader('Accept', 'application/json;charset=UTF-8'); @@ -160,7 +167,8 @@ public function getShippingOptions(array $orderData) $body = $httpClient->getBody(); $status = $httpClient->getStatus(); - $this->generalHelper->addTolog('debug', $body); + $this->generalHelper->addTolog('getShippingOptions response status: ', $status); + $this->generalHelper->addTolog('getShippingOptions response: ', $body); if ($status >= 400 && $status < 500) { throw ApiException::fromErrorResponse($body, $status); } @@ -173,7 +181,7 @@ public function getShippingOptions(array $orderData) } /** - * @param $reference + * @param string $reference * * @return mixed|null * @throws ApiException @@ -191,15 +199,18 @@ public function fetchCheckoutData($reference) $httpClient->addHeader('Accept', 'application/json;charset=UTF-8'); + $this->generalHelper->addTolog('fetchCheckoutData URL: ', $url); + $httpClient->get($url); $status = $httpClient->getStatus(); $body = $httpClient->getBody(); + $this->generalHelper->addTolog('fetchCheckoutData response status: ', $body); + $this->generalHelper->addTolog('fetchCheckoutData response: ', $body); if ($status !== 200) { // @codingStandardsIgnoreLine throw new \Exception('Cannot obtain checkout info'); } $result = json_decode($body, true); - $this->generalHelper->addTolog('debug', $body); } catch (\Exception $e) { $this->generalHelper->addTolog('exception', $e->getMessage()); throw ApiException::error($e); @@ -213,23 +224,7 @@ public function fetchCheckoutData($reference) */ private function buildAuthorizationHeader() { - return 'Bearer ' . $this->getApiKey() . ':' . $this->getApiSecret(); - } - - /** - * @return mixed - */ - public function getApiKey() - { - return $this->scopeConfig->getApiKey(); - } - - /** - * @return mixed - */ - public function getApiSecret() - { - return $this->scopeConfig->getApiSecret(); + return 'Bearer ' . $this->configuration->getKey() . ':' . $this->configuration->getSecret(); } /** @@ -242,7 +237,7 @@ private function getAuthorizedClient(): ClientInterface 'Authorization' => $this->buildAuthorizationHeader() ]); - $timeout = $this->scopeConfig->getApiTimeout(); + $timeout = $this->configuration->getTimeout(); if ($timeout > 0) { $httpClient->setTimeout($timeout); } diff --git a/Model/Api/PaazlApiFactory.php b/Model/Api/PaazlApiFactory.php new file mode 100644 index 0000000..9078a44 --- /dev/null +++ b/Model/Api/PaazlApiFactory.php @@ -0,0 +1,65 @@ +objectManager = $objectManager; + $this->config = $config; + } + + /** + * @param null|int $storeId + * + * @return PaazlApi + */ + public function create($storeId = null): PaazlApi + { + /** @var Configuration $configuration */ + $configuration = $this->objectManager->create(Configuration::class); + $configuration + ->setKey($this->config->getApiKey($storeId)) + ->setSecret($this->config->getApiSecret($storeId)) + ->setMode($this->config->getApiMode($storeId)) + ->setTimeout($this->config->getApiTimeout($storeId)); + + return $this->objectManager->create( + PaazlApi::class, + [ + 'configuration' => $configuration, + 'urlProvider' => $this->objectManager->get(UrlProviderFactory::class)->create($storeId) + ] + ); + } +} diff --git a/Model/Api/Processor/CheckoutInfoToQuote.php b/Model/Api/Processor/CheckoutInfoToQuote.php index bcd93bf..edaa0bc 100755 --- a/Model/Api/Processor/CheckoutInfoToQuote.php +++ b/Model/Api/Processor/CheckoutInfoToQuote.php @@ -13,6 +13,7 @@ use Paazl\CheckoutWidget\Model\Api\Builder\Reference; use Paazl\CheckoutWidget\Model\Api\Converter\Checkout\ToShippingInfo; use Paazl\CheckoutWidget\Model\Api\PaazlApi; +use Paazl\CheckoutWidget\Model\Api\PaazlApiFactory; use Paazl\CheckoutWidget\Model\ExtInfoHandler; /** @@ -24,9 +25,9 @@ class CheckoutInfoToQuote { /** - * @var PaazlApi + * @var PaazlApiFactory */ - private $api; + private $paazlApiFactory; /** * @var Reference @@ -51,20 +52,20 @@ class CheckoutInfoToQuote /** * CheckoutInfoToQuote constructor. * - * @param PaazlApi $api - * @param Reference $referenceBuilder - * @param ToShippingInfo $shippingInfo - * @param ExtInfoHandler $extInfoHandler - * @param General $generalHelper + * @param PaazlApiFactory $paazlApiFactory + * @param Reference $referenceBuilder + * @param ToShippingInfo $shippingInfo + * @param ExtInfoHandler $extInfoHandler + * @param General $generalHelper */ public function __construct( - PaazlApi $api, + PaazlApiFactory $paazlApiFactory, Reference $referenceBuilder, ToShippingInfo $shippingInfo, ExtInfoHandler $extInfoHandler, General $generalHelper ) { - $this->api = $api; + $this->paazlApiFactory = $paazlApiFactory; $this->referenceBuilder = $referenceBuilder; $this->shippingInfo = $shippingInfo; $this->extInfoHandler = $extInfoHandler; @@ -80,7 +81,9 @@ public function process(Quote $quote) { try { // Getting the checkout information from Paazl - $result = $this->api->fetchCheckoutData($this->referenceBuilder->getQuoteReference($quote)); + /** @var PaazlApi $paazlApi */ + $paazlApi = $this->paazlApiFactory->create($quote->getStoreId()); + $result = $paazlApi->fetchCheckoutData($this->referenceBuilder->getQuoteReference($quote)); // Converting response to extInfo $info = $this->shippingInfo->convert($result); diff --git a/Model/Api/Processor/SendToService.php b/Model/Api/Processor/SendToService.php index f0059c7..f1cab49 100755 --- a/Model/Api/Processor/SendToService.php +++ b/Model/Api/Processor/SendToService.php @@ -14,6 +14,7 @@ use Paazl\CheckoutWidget\Helper\Order as OrderHelper; use Paazl\CheckoutWidget\Model\Api\Builder\Order; use Paazl\CheckoutWidget\Model\Api\PaazlApi; +use Paazl\CheckoutWidget\Model\Api\PaazlApiFactory; /** * Class SendToService @@ -29,9 +30,9 @@ class SendToService private $orderBuilder; /** - * @var PaazlApi + * @var PaazlApiFactory */ - private $paazlApi; + private $paazlApiFactory; /** * @var OrderHelper @@ -57,7 +58,7 @@ class SendToService * SendToService constructor. * * @param Order $orderBuilder - * @param PaazlApi $paazlApi + * @param PaazlApiFactory $paazlApiFactory * @param OrderHelper $orderHelper * @param GeneralHelper $generalHelper * @param MarkOrderAsSent $markOrderAsSent @@ -65,14 +66,14 @@ class SendToService */ public function __construct( Order $orderBuilder, - PaazlApi $paazlApi, + PaazlApiFactory $paazlApiFactory, OrderHelper $orderHelper, GeneralHelper $generalHelper, MarkOrderAsSent $markOrderAsSent, OrderReferenceRepositoryInterface $orderReferenceRepository ) { $this->orderBuilder = $orderBuilder; - $this->paazlApi = $paazlApi; + $this->paazlApiFactory = $paazlApiFactory; $this->orderHelper = $orderHelper; $this->generalHelper = $generalHelper; $this->markOrderAsSent = $markOrderAsSent; @@ -104,7 +105,9 @@ public function process(OrderInterface $order, $force = false) try { $orderInfo = $this->orderBuilder->getCreateOrderData($order); - $this->paazlApi->addOrder($orderInfo); + /** @var PaazlApi $paazlApi */ + $paazlApi = $this->paazlApiFactory->create($order->getStoreId()); + $paazlApi->addOrder($orderInfo); $this->markOrderAsSent->process($order); } catch (\Exception $e) { $this->generalHelper->addTolog('exception', $e->getMessage()); diff --git a/Model/Api/UrlProvider.php b/Model/Api/UrlProvider.php index a77fef4..eb84c6b 100755 --- a/Model/Api/UrlProvider.php +++ b/Model/Api/UrlProvider.php @@ -6,7 +6,7 @@ namespace Paazl\CheckoutWidget\Model\Api; -use Paazl\CheckoutWidget\Model\Config; +use Paazl\CheckoutWidget\Model\System\Config\Source\ApiMode; /** * UrlProvider @@ -21,18 +21,18 @@ class UrlProvider /**#@- */ /** - * @var Config + * @var int */ - private $config; + private $mode; /** * UrlProvider constructor. * - * @param Config $config + * @param int $mode */ - public function __construct(Config $config) + public function __construct($mode) { - $this->config = $config; + $this->mode = $mode; } /** @@ -41,7 +41,7 @@ public function __construct(Config $config) public function getBaseUrl() { $result = self::BASE_URL_TEST; - if ($this->config->isProductionApiMode()) { + if ($this->mode === ApiMode::MODE_PRODUCTION) { $result = self::BASE_URL_LIVE; } diff --git a/Model/Api/UrlProviderFactory.php b/Model/Api/UrlProviderFactory.php new file mode 100644 index 0000000..97a2916 --- /dev/null +++ b/Model/Api/UrlProviderFactory.php @@ -0,0 +1,51 @@ +objectManager = $objectManager; + $this->config = $config; + } + + /** + * @param null|int|string $storeId + * + * @return UrlProvider + */ + public function create($storeId = null): UrlProvider + { + return $this->objectManager->create(UrlProvider::class, ['mode' => $this->config->getApiMode($storeId)]); + } +} diff --git a/Model/Carrier/Paazlshipping.php b/Model/Carrier/Paazlshipping.php index 692a26b..cc4dba4 100755 --- a/Model/Carrier/Paazlshipping.php +++ b/Model/Carrier/Paazlshipping.php @@ -8,17 +8,20 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\DataObject; +use Magento\Framework\Exception\LocalizedException; +use Magento\Quote\Model\Quote\Item; use Magento\Shipping\Model\Carrier\AbstractCarrier; use Magento\Shipping\Model\Carrier\CarrierInterface; use Magento\Shipping\Model\Rate\ResultFactory; use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory; use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory; use Magento\Quote\Model\Quote\Address\RateRequest; +use Paazl\CheckoutWidget\Logger\PaazlLogger; use Paazl\CheckoutWidget\Model\ExtInfoHandler; -use Magento\Checkout\Helper\Data as CheckoutHelper; use Paazl\CheckoutWidget\Model\Config; use Magento\Framework\App\State as AppState; use Magento\Framework\App\Area; +use Paazl\CheckoutWidget\Model\TokenRetriever; use Psr\Log\LoggerInterface; /** @@ -58,12 +61,7 @@ class Paazlshipping extends AbstractCarrier implements CarrierInterface private $rateMethodFactory; /** - * @var CheckoutHelper - */ - private $checkoutHelper; - - /** - * @var LoggerInterface + * @var PaazlLogger */ private $logger; @@ -82,6 +80,11 @@ class Paazlshipping extends AbstractCarrier implements CarrierInterface */ private $appState; + /** + * @var TokenRetriever + */ + private $tokenRetriever; + /** * Paazlshipping constructor. * @@ -91,9 +94,10 @@ class Paazlshipping extends AbstractCarrier implements CarrierInterface * @param AppState $appState * @param ResultFactory $rateResultFactory * @param MethodFactory $rateMethodFactory - * @param CheckoutHelper $checkoutHelper * @param Config $config * @param ExtInfoHandler $extInfoHandler + * @param TokenRetriever $tokenRetriever + * @param PaazlLogger $paazlLogger * @param array $data */ public function __construct( @@ -103,20 +107,21 @@ public function __construct( AppState $appState, ResultFactory $rateResultFactory, MethodFactory $rateMethodFactory, - CheckoutHelper $checkoutHelper, Config $config, ExtInfoHandler $extInfoHandler, + TokenRetriever $tokenRetriever, + PaazlLogger $paazlLogger, array $data = [] ) { $this->rateResultFactory = $rateResultFactory; $this->rateMethodFactory = $rateMethodFactory; - $this->checkoutHelper = $checkoutHelper; - $this->logger = $logger; + $this->logger = $paazlLogger; parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data); $this->extInfoHandler = $extInfoHandler; $this->config = $config; $this->appState = $appState; + $this->tokenRetriever = $tokenRetriever; } /** @@ -132,12 +137,6 @@ public function getCarrierCode() */ public function isActive() { - $areaCode = $this->appState->getAreaCode(); - if ($areaCode === Area::AREA_ADMIN || - $areaCode === Area::AREA_ADMINHTML) { - return false; - } - return parent::isActive() && $this->config->isEnabled(); } @@ -160,13 +159,13 @@ public function getAllowedMethods() */ public function collectRates(RateRequest $request) { - if (!$this->isActive()) { + if (!$this->getConfigFlag('active')) { return false; } /** @var \Magento\Shipping\Model\Rate\Result $result */ $result = $this->rateResultFactory->create(); - $shippingPrice = $this->getConfigData('price'); + $shippingPrice = 0; $method = $this->rateMethodFactory->create(); /** @@ -176,20 +175,59 @@ public function collectRates(RateRequest $request) $method->setMethodTitle($this->getConfigData('name')); // Recalculate shipping price - $info = $this->extInfoHandler->getInfoFromQuote($quote = $this->checkoutHelper->getQuote()); + $quote = $this->extractQuote($request); + if (!$quote || (!$quote->getId())) { + /* + * No quote. Can happen when 1st product was added to quote. + * Return method's "placeholder", we'll obtain a token at a later stage. + */ + $method->setCarrier($this->getCarrierCode()); + $method->setCarrierTitle($this->getConfigData('title')); + $method->setPrice($shippingPrice); + $method->setCost($shippingPrice); + $result->append($method); + return $result; + } + + try { + $this->tokenRetriever->retrieveByQuote($quote); - if ($info && $info->getType()) { - $shippingPrice = $info->getPrice(); - if ($info->getOptionTitle()) { - $method->setMethodTitle($info->getOptionTitle()); + $info = $this->extInfoHandler->getInfoFromQuote($quote); + + if ($info && $info->getType()) { + $shippingPrice = $info->getPrice(); + if ($info->getOptionTitle()) { + $method->setMethodTitle($info->getOptionTitle()); + } } + + $method->setCarrier($this->getCarrierCode()); + $method->setCarrierTitle($this->getConfigData('title')); + $method->setPrice($shippingPrice); + $method->setCost($shippingPrice); + $result->append($method); + return $result; + } catch (LocalizedException $e) { + $this->logger->add('exception', $e->getLogMessage()); + } + + return null; + } + + /** + * @param RateRequest $request + * + * @return \Magento\Quote\Model\Quote|null + */ + private function extractQuote(RateRequest $request) + { + $quote = null; + $items = $request->getAllItems(); + $current = current($items); + if ($current instanceof Item) { + $quote = $current->getQuote(); } - $method->setCarrier($this->getCarrierCode()); - $method->setCarrierTitle($this->getConfigData('title')); - $method->setPrice($shippingPrice); - $method->setCost($shippingPrice); - $result->append($method); - return $result; + return $quote; } -} +} \ No newline at end of file diff --git a/Model/Checkout/PaazlConfigProvider.php b/Model/Checkout/PaazlConfigProvider.php index d730ce0..3309477 100755 --- a/Model/Checkout/PaazlConfigProvider.php +++ b/Model/Checkout/PaazlConfigProvider.php @@ -8,6 +8,7 @@ use Magento\Checkout\Model\ConfigProviderInterface; use Paazl\CheckoutWidget\Model\Api\UrlProvider; +use Paazl\CheckoutWidget\Model\Api\UrlProviderFactory; use Paazl\CheckoutWidget\Model\Carrier\Paazlshipping; use Paazl\CheckoutWidget\Model\Config; @@ -37,16 +38,16 @@ class PaazlConfigProvider implements ConfigProviderInterface * PaazlConfigProvider constructor. * * @param Config $config - * @param UrlProvider $urlProvider + * @param UrlProviderFactory $urlProviderFactory * @param WidgetConfigProvider $widgetConfigProvider */ public function __construct( Config $config, - UrlProvider $urlProvider, + UrlProviderFactory $urlProviderFactory, WidgetConfigProvider $widgetConfigProvider ) { $this->config = $config; - $this->urlProvider = $urlProvider; + $this->urlProvider = $urlProviderFactory->create(); $this->widgetConfigProvider = $widgetConfigProvider; } @@ -66,6 +67,8 @@ public function getConfig() $config['carrierCode'] = Paazlshipping::CODE; $config['methodCode'] = Paazlshipping::CODE; $config['baseApiUrl'] = $this->urlProvider->getBaseUrl(); + $config['checkoutApiUrl'] = $this->urlProvider->getCheckoutUrl(); + $config['saveShippingInfoInstantly'] = $this->config->saveShippingInformationInstantly(); $config['googleMapKey'] = $this->config->getGoogleMapKey(); $config['widgetConfig'] = $this->widgetConfigProvider->getConfig(); $config['mode'] = $this->config->isProductionApiMode() ? 'live' : 'test'; diff --git a/Model/Checkout/WidgetConfigProvider.php b/Model/Checkout/WidgetConfigProvider.php index f28dcd7..882d33b 100644 --- a/Model/Checkout/WidgetConfigProvider.php +++ b/Model/Checkout/WidgetConfigProvider.php @@ -16,8 +16,6 @@ use Magento\Catalog\Model\ProductRepository; use Magento\Framework\Exception\NoSuchEntityException; use Paazl\CheckoutWidget\Helper\General as GeneralHelper; -use Paazl\CheckoutWidget\Model\Api\PaazlApiFactory; -use Paazl\CheckoutWidget\Model\Api\UrlProvider; use Paazl\CheckoutWidget\Model\Config; use Paazl\CheckoutWidget\Model\Handler\Item as ItemHandler; use Paazl\CheckoutWidget\Model\TokenRetriever; @@ -50,11 +48,6 @@ class WidgetConfigProvider implements ConfigProviderInterface */ private $order; - /** - * @var PaazlApiFactory - */ - private $paazlApi; - /** * @var GeneralHelper */ @@ -70,17 +63,14 @@ class WidgetConfigProvider implements ConfigProviderInterface */ private $tokenRetriever; - /** - * @var UrlProvider - */ - private $urlProvider; - /** * @var LanguageProvider */ private $languageProvider; - /** @var ProductRepository */ + /** + * @var ProductRepository + */ private $productRepository; /** @@ -89,11 +79,9 @@ class WidgetConfigProvider implements ConfigProviderInterface * @param Config $scopeConfig * @param Data $checkoutHelper * @param OrderFactory $order - * @param PaazlApiFactory $paazlApi * @param GeneralHelper $generalHelper * @param ItemHandler $itemHandler * @param TokenRetriever $tokenRetriever - * @param UrlProvider $urlProvider * @param LanguageProvider $languageProvider * @param ProductRepository $productRepository */ @@ -101,22 +89,18 @@ public function __construct( Config $scopeConfig, Data $checkoutHelper, OrderFactory $order, - PaazlApiFactory $paazlApi, GeneralHelper $generalHelper, ItemHandler $itemHandler, TokenRetriever $tokenRetriever, - UrlProvider $urlProvider, LanguageProvider $languageProvider, ProductRepository $productRepository ) { $this->scopeConfig = $scopeConfig; $this->checkoutHelper = $checkoutHelper; $this->order = $order; - $this->paazlApi = $paazlApi; $this->generalHelper = $generalHelper; $this->itemHandler = $itemHandler; $this->tokenRetriever = $tokenRetriever; - $this->urlProvider = $urlProvider; $this->languageProvider = $languageProvider; $this->productRepository = $productRepository; } @@ -175,7 +159,7 @@ public function getConfig() "startDate" => date("Y-m-d"), "numberOfDays" => 10 ], - "currency" => $this->scopeConfig->getValue(Currency::XML_PATH_CURRENCY_DEFAULT), + "currency" => $this->getQuote()->getQuoteCurrencyCode(), "deliveryOptionDateFormat" => "ddd DD MMM", "deliveryEstimateDateFormat" => "dddd DD MMMM", "pickupOptionDateFormat" => "ddd DD MMM", @@ -228,13 +212,13 @@ public function getDefaultPostcode() } /** - * @param $price + * @param double $price * - * @return double + * @return string */ public function formatPrice($price) { - return number_format($price, 2); + return number_format($price, 2, '.', ''); } /** @@ -242,7 +226,7 @@ public function formatPrice($price) */ public function getApiKey() { - return $this->scopeConfig->getApiKey(); + return $this->scopeConfig->getApiKey($this->getQuote()->getStoreId()); } /** @@ -276,7 +260,7 @@ public function getDefaultTab() } /** - * @return boolean + * @return string */ public function getWidgetTheme() { @@ -285,7 +269,7 @@ public function getWidgetTheme() } /** - * @return string + * @return bool */ public function getNominatedDateEnabled() { @@ -329,7 +313,9 @@ public function getProductNumberOfProcessingDays(AbstractItem $item) { $product = $this->productRepository->getById($item->getProduct()->getId()); - if ($attribute = $this->scopeConfig->getProductAttributeNumberOfProcessingDays()) { + $attribute = $this->scopeConfig + ->getProductAttributeNumberOfProcessingDays(); + if ($attribute) { if (($numberOfProcessingDays = $product->getData($attribute)) !== null) { if (is_numeric($numberOfProcessingDays) && $numberOfProcessingDays >= Config::MIN_NUMBER_OF_PROCESSING_DAYS @@ -375,14 +361,6 @@ public function getInitialPickupLocations() return $this->scopeConfig->getInitialPickupLocations(); } - /** - * @return mixed - */ - public function getCustomCss() - { - return $this->scopeConfig->getCustomCss(); - } - /** * @return boolean */ @@ -391,14 +369,6 @@ public function isEnabled() return $this->scopeConfig->isEnabled(); } - /** - * @return string - */ - public function getApiBaseUrl() - { - return $this->urlProvider->getBaseUrl(); - } - /** * Gets delivery matrix from product * @@ -410,7 +380,9 @@ public function getProductDeliveryMatrix(AbstractItem $item) { $product = $this->productRepository->getById($item->getProduct()->getId()); - if ($attribute = $this->scopeConfig->getProductAttributeDeliveryMatrix()) { + $attribute = $this->scopeConfig + ->getProductAttributeDeliveryMatrix(); + if ($attribute) { if (($deliveryMatrixCode = $product->getData($attribute)) !== null && $this->validateDeliveryMatrixCode($deliveryMatrixCode) ) { diff --git a/Model/CompositeConfigProvider.php b/Model/CompositeConfigProvider.php new file mode 100755 index 0000000..42bc60b --- /dev/null +++ b/Model/CompositeConfigProvider.php @@ -0,0 +1,44 @@ +configProviders = $configProviders; + } + + /** + * {@inheritdoc} + */ + public function getConfig() + { + $config = []; + foreach ($this->configProviders as $configProvider) { + $config = array_merge_recursive($config, $configProvider->getConfig()); + } + return $config; + } +} diff --git a/Model/Config.php b/Model/Config.php index 23fb80a..6a73ea4 100644 --- a/Model/Config.php +++ b/Model/Config.php @@ -8,7 +8,9 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\Store; use Paazl\CheckoutWidget\Model\Carrier\Paazlshipping; +use Paazl\CheckoutWidget\Model\System\Config\Source\ApiMode; /** * Class Config @@ -17,6 +19,7 @@ */ class Config { + /**#@+ * Constants */ @@ -42,61 +45,79 @@ public function __construct( } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getApiKey() + public function getApiKey($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/api_key'); + return $this->getValue(self::API_CONFIG_PATH . '/api_key', $store); } /** - * @param $key + * @param string $key + * @param null|Store|int|string $store * * @return mixed */ - public function getValue($key) + public function getValue($key, $store = null) { - return $this->scopeConfig->getValue($key, ScopeInterface::SCOPE_STORE); + return $this->scopeConfig->getValue($key, ScopeInterface::SCOPE_STORE, $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getApiSecret() + public function getApiSecret($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/api_secret'); + return $this->getValue(self::API_CONFIG_PATH . '/api_secret', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getReferencePrefix() + public function getReferencePrefix($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/reference_prefix'); + return $this->getValue(self::API_CONFIG_PATH . '/reference_prefix', $store); } /** + * @param null|Store|int|string $store + * * @return bool */ - public function isProductionApiMode() + public function isProductionApiMode($store = null) { - return $this->getApiMode() == 1; + return $this->getApiMode($store) == ApiMode::MODE_PRODUCTION; } /** - * @return mixed + * @param null|Store|int|string $store + * + * @return int */ - public function getApiMode() + public function getApiMode($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/api_modus'); + $mode = $this->getValue(self::API_CONFIG_PATH . '/api_modus', $store); + if ($mode != ApiMode::MODE_PRODUCTION) { + $mode = ApiMode::MODE_STAGING; + } + + return $mode; } /** + * @param null|Store|int|string $store + * * @return int */ - public function getApiTimeout() + public function getApiTimeout($store = null) { - $result = (int)$this->getValue(self::API_CONFIG_PATH . '/api_timeout'); + $result = (int)$this->getValue(self::API_CONFIG_PATH . '/api_timeout', $store); if ($result <= 0) { $result = 300; } @@ -105,245 +126,317 @@ public function getApiTimeout() } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getDefaultCountry() + public function getDefaultCountry($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/default_country'); + return $this->getValue(self::API_CONFIG_PATH . '/default_country', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getDefaultPostcode() + public function getDefaultPostcode($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/default_postcode'); + return $this->getValue(self::API_CONFIG_PATH . '/default_postcode', $store); } /** + * @param null|Store|int|string $store + * * @return array */ - public function getAvailableTabs() + public function getAvailableTabs($store = null) { - return explode(',', $this->getValue(self::API_CONFIG_PATH . '/widget_tabs')); + return explode(',', $this->getValue(self::API_CONFIG_PATH . '/widget_tabs', $store)); } /** - * @return string + * @param null|Store|int|string $store + * + * @return bool */ - public function getNominatedDateEnabled() + public function getNominatedDateEnabled($store = null) { - return $this->scopeConfig->isSetFlag(self::API_CONFIG_PATH . '/widget_nominated_date'); + return $this->scopeConfig->isSetFlag( + self::API_CONFIG_PATH . '/widget_nominated_date', + ScopeInterface::SCOPE_STORE, + $store + ); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getDefaultTab() + public function getDefaultTab($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/widget_default_tab'); + return $this->getValue(self::API_CONFIG_PATH . '/widget_default_tab', $store); } /** + * @param null|Store|int|string $store + * * @return int */ - public function getShippingOptionsLimit() + public function getShippingOptionsLimit($store = null) { - return (int)$this->getValue(self::API_CONFIG_PATH . '/widget_shipping_options_limit'); + return (int)$this->getValue(self::API_CONFIG_PATH . '/widget_shipping_options_limit', $store); } /** + * @param null|Store|int|string $store + * * @return int */ - public function getPickupLocationsPageLimit() + public function getPickupLocationsPageLimit($store = null) { - return (int)$this->getValue(self::API_CONFIG_PATH . '/widget_pickup_locations_page_limit'); + return (int)$this->getValue(self::API_CONFIG_PATH . '/widget_pickup_locations_page_limit', $store); } /** + * @param null|Store|int|string $store + * * @return int */ - public function getPickupLocationsLimit() + public function getPickupLocationsLimit($store = null) { - return (int)$this->getValue(self::API_CONFIG_PATH . '/widget_pickup_locations_limit'); + return (int)$this->getValue(self::API_CONFIG_PATH . '/widget_pickup_locations_limit', $store); } /** + * @param null|Store|int|string $store + * * @return int */ - public function getInitialPickupLocations() + public function getInitialPickupLocations($store = null) { - return (int)$this->getValue(self::API_CONFIG_PATH . '/widget_initial_pickup_locations'); + return (int)$this->getValue(self::API_CONFIG_PATH . '/widget_initial_pickup_locations', $store); } /** - * @return string + * @param null|Store|int|string $store + * + * @return string|null */ - public function getCustomCss() + public function getCustomCss($store = null) { - if ($this->getWidgetTheme() == 'CUSTOM') { - return $this->getValue(self::API_CONFIG_PATH . '/custom_css'); + if ($this->getWidgetTheme($store) == 'CUSTOM') { + return $this->getValue(self::API_CONFIG_PATH . '/custom_css', $store); } return null; } /** + * @param null|Store|int|string $store + * * @return string */ - public function getWidgetTheme() + public function getWidgetTheme($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/widget_theme'); + return $this->getValue(self::API_CONFIG_PATH . '/widget_theme', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getDebugEnabled() + public function getDebugEnabled($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/debug'); + return $this->getValue(self::API_CONFIG_PATH . '/debug', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function isHideOtherShippingMethods() + public function isHideOtherShippingMethods($store = null) { - return (bool)$this->getValue(self::API_CONFIG_PATH . '/hide_method_select'); + return (bool)$this->getValue(self::API_CONFIG_PATH . '/hide_method_select', $store); } /** + * @param null|Store|int|string $store + * * @return bool */ - public function isCarrierActive() + public function isCarrierActive($store = null) { - return $this->isEnabled() && - in_array($this->getValue('carriers/' . Paazlshipping::CODE . '/active'), [1, 'true']); + return $this->isEnabled($store) && + in_array($this->getValue('carriers/' . Paazlshipping::CODE . '/active', $store), [1, 'true']); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function isEnabled() + public function isEnabled($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/active'); + return $this->getValue(self::API_CONFIG_PATH . '/active', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function housenumberOnSecondStreet() + public function housenumberOnSecondStreet($store = null) { - return (bool)$this->getValue(self::API_CONFIG_PATH . '/housenumber_second_street'); + return (bool)$this->getValue(self::API_CONFIG_PATH . '/housenumber_second_street', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function housenumberExtensionOnThirdStreet() + public function housenumberExtensionOnThirdStreet($store = null) { - return (bool)$this->getValue(self::API_CONFIG_PATH . '/housenumber_extension_third_street'); + return (bool)$this->getValue(self::API_CONFIG_PATH . '/housenumber_extension_third_street', $store); } /** + * @param null|Store|int|string $store + * * @return mixed|null */ - public function getCustomDescription() + public function getCustomDescription($store = null) { - if (!$this->getValue(self::API_CONFIG_PATH . '/use_custom_description')) { + if (!$this->getValue(self::API_CONFIG_PATH . '/use_custom_description', $store)) { return null; } - return $this->getValue(self::API_CONFIG_PATH . '/custom_description'); + return $this->getValue(self::API_CONFIG_PATH . '/custom_description', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getProductAttributeWidth() + public function getProductAttributeWidth($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/width_attribute'); + return $this->getValue(self::API_CONFIG_PATH . '/width_attribute', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getProductAttributeLength() + public function getProductAttributeLength($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/length_attribute'); + return $this->getValue(self::API_CONFIG_PATH . '/length_attribute', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getProductAttributeHeight() + public function getProductAttributeHeight($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/height_attribute'); + return $this->getValue(self::API_CONFIG_PATH . '/height_attribute', $store); } /** + * @param null|Store|int|string $store + * * @return int|null */ - public function getProductAttributeNumberOfProcessingDays() + public function getProductAttributeNumberOfProcessingDays($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/number_of_processing_days_attribute'); + return $this->getValue(self::API_CONFIG_PATH . '/number_of_processing_days_attribute', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getProductAttributeCountyOfManufacture() + public function getProductAttributeCountyOfManufacture($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/country_of_manufacture_attribute'); + return $this->getValue(self::API_CONFIG_PATH . '/country_of_manufacture_attribute', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getProductStaticCountyOfManufacture() + public function getProductStaticCountyOfManufacture($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/country_of_manufacture_static'); + return $this->getValue(self::API_CONFIG_PATH . '/country_of_manufacture_static', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getProductAttributeHsTariffCode() + public function getProductAttributeHsTariffCode($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/hs_tariff_code_attribute'); + return $this->getValue(self::API_CONFIG_PATH . '/hs_tariff_code_attribute', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getProductStaticHsTariffCode() + public function getProductStaticHsTariffCode($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/hs_tariff_code_static'); + return $this->getValue(self::API_CONFIG_PATH . '/hs_tariff_code_static', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getGoogleMapKey() + public function getGoogleMapKey($store = null) { - if ($this->getValue(self::API_CONFIG_PATH . '/googlemaps')) { - return $this->getValue(self::API_CONFIG_PATH . '/googlemaps_key'); + if ($this->getValue(self::API_CONFIG_PATH . '/googlemaps', $store)) { + return $this->getValue(self::API_CONFIG_PATH . '/googlemaps_key', $store); } return null; } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getProductAttributeDeliveryMatrix() + public function getProductAttributeDeliveryMatrix($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/delivery_matrix_attribute'); + return $this->getValue(self::API_CONFIG_PATH . '/delivery_matrix_attribute', $store); } /** + * @param null|Store|int|string $store + * * @return mixed */ - public function getCarrierTitle() + public function getCarrierTitle($store = null) + { + return $this->getValue(self::API_CONFIG_PATH . '/title', $store); + } + + /** + * @param null|Store|int|string $store + * + * @return bool + */ + public function saveShippingInformationInstantly($store = null) { - return $this->getValue(self::API_CONFIG_PATH . '/title'); + return !!$this->getValue(self::API_CONFIG_PATH . '/onestep_checkout_used', $store); } } diff --git a/Model/Handler/Item.php b/Model/Handler/Item.php index 721f37c..ae70a9c 100755 --- a/Model/Handler/Item.php +++ b/Model/Handler/Item.php @@ -22,6 +22,11 @@ class Item */ private $generalHelper; + /** + * Item constructor. + * + * @param GeneralHelper $generalHelper + */ public function __construct(GeneralHelper $generalHelper) { $this->generalHelper = $generalHelper; @@ -31,8 +36,8 @@ public function __construct(GeneralHelper $generalHelper) * Gets formatted price from quote or order item * When price value = 0 method will return value equivalent 0.01 * - * @param $item - * @return string + * @param AbstractExtensibleModel $item + * @return float * @throws LocalizedException */ public function getPriceValue(AbstractExtensibleModel $item) diff --git a/Model/Order/OrderReference.php b/Model/Order/OrderReference.php index 07e0483..fe75995 100755 --- a/Model/Order/OrderReference.php +++ b/Model/Order/OrderReference.php @@ -85,4 +85,28 @@ public function isSent() { return (!empty($this->getExtSentAt())); } + + /** + * @inheritDoc + */ + public function canResend() + { + return $this->isSent(); + } + + /** + * @inheritDoc + */ + public function canRetry() + { + return (!$this->isSent()) && (!empty($this->getExtShippingInfo())); + } + + /** + * @inheritDoc + */ + public function canEdit() + { + return !$this->isSent(); + } } diff --git a/Model/Order/WidgetConfigProvider.php b/Model/Order/WidgetConfigProvider.php index e3415a3..bcdce7d 100644 --- a/Model/Order/WidgetConfigProvider.php +++ b/Model/Order/WidgetConfigProvider.php @@ -10,7 +10,6 @@ use Magento\Framework\Exception\LocalizedException; use Magento\Sales\Model\Order as OrderModel; use Paazl\CheckoutWidget\Helper\General as GeneralHelper; -use Paazl\CheckoutWidget\Model\Api\PaazlApiFactory; use Paazl\CheckoutWidget\Model\Checkout\LanguageProvider; use Paazl\CheckoutWidget\Model\Config; use Paazl\CheckoutWidget\Model\Handler\Item as ItemHandler; @@ -31,11 +30,6 @@ class WidgetConfigProvider implements ConfigProviderInterface */ private $order; - /** - * @var PaazlApiFactory - */ - private $paazlApi; - /** * @var GeneralHelper */ @@ -60,7 +54,6 @@ class WidgetConfigProvider implements ConfigProviderInterface * Widget constructor. * * @param Config $scopeConfig - * @param PaazlApiFactory $paazlApi * @param GeneralHelper $generalHelper * @param ItemHandler $itemHandler * @param TokenRetriever $tokenRetriever @@ -68,14 +61,12 @@ class WidgetConfigProvider implements ConfigProviderInterface */ public function __construct( Config $scopeConfig, - PaazlApiFactory $paazlApi, GeneralHelper $generalHelper, ItemHandler $itemHandler, TokenRetriever $tokenRetriever, LanguageProvider $languageProvider ) { $this->scopeConfig = $scopeConfig; - $this->paazlApi = $paazlApi; $this->generalHelper = $generalHelper; $this->itemHandler = $itemHandler; $this->tokenRetriever = $tokenRetriever; @@ -122,7 +113,7 @@ public function getConfig() 'numberOfGoods' => $this->getProductsCount(), 'goods' => $goods ], - 'currency' => 'EUR', + 'currency' => $this->getOrder()->getOrderCurrency(), 'sortingModel' => [ 'orderBy' => 'PRICE', 'sortOrder' => 'ASC' @@ -156,8 +147,8 @@ public function getDefaultPostcode() /** * Retrieves price in price format * - * @param $price - * @return double + * @param double|float $price + * @return string */ public function formatPrice($price) { diff --git a/Model/Quote/QuoteReference.php b/Model/Quote/QuoteReference.php index abf013b..125fd1e 100644 --- a/Model/Quote/QuoteReference.php +++ b/Model/Quote/QuoteReference.php @@ -7,6 +7,7 @@ namespace Paazl\CheckoutWidget\Model\Quote; use Magento\Framework\Model\AbstractModel; +use Magento\Framework\Stdlib\DateTime; use Paazl\CheckoutWidget\Api\Data\Quote\QuoteReferenceInterface; use Paazl\CheckoutWidget\Model\ResourceModel\Quote\QuoteReference as QuoteReferenceResource; @@ -98,4 +99,34 @@ public function getTokenExpiresAt() { return $this->getData(self::TOKEN_EXPIRES_AT); } + + /** + * @inheritDoc + */ + public function isTokenExpired(\DateTime $now = null) + { + $result = true; + $expiresAt = $this->getTokenExpiresAt(); + if (empty($expiresAt)) { + return $result; + } + + $expires = \DateTime::createFromFormat( + DateTime::DATETIME_PHP_FORMAT, + $expiresAt, + new \DateTimeZone('UTC') + ); + + try { + $now = $now ?: new \DateTime('now', new \DateTimeZone('UTC')); + // phpcs:ignore + } catch (\Exception $e) { + } + + if ($now && $expires && ($now < $expires)) { + $result = false; + } + + return $result; + } } diff --git a/Model/ShippingInfo.php b/Model/ShippingInfo.php index 6adf845..58ad8bc 100644 --- a/Model/ShippingInfo.php +++ b/Model/ShippingInfo.php @@ -148,7 +148,7 @@ public function setPickupAddress($value) } /** - * @return string|null + * @return array|null */ public function getPickupAddress() { @@ -156,7 +156,7 @@ public function getPickupAddress() } /** - * @param string $value + * @param float $value * @return $this */ public function setPrice($value) @@ -165,7 +165,7 @@ public function setPrice($value) } /** - * @return string|null + * @return float|null */ public function getPrice() { diff --git a/Model/System/Config/Source/ApiMode.php b/Model/System/Config/Source/ApiMode.php index b966d2c..ec8acae 100755 --- a/Model/System/Config/Source/ApiMode.php +++ b/Model/System/Config/Source/ApiMode.php @@ -9,12 +9,14 @@ use Magento\Framework\Option\ArrayInterface; /** - * Class Apimode + * Class ApiMode * * @package Paazl\CheckoutWidget\Model\System\Config\Source */ class ApiMode implements ArrayInterface { + const MODE_PRODUCTION = 1; + const MODE_STAGING = 0; /** * @var array diff --git a/Model/System/Config/Source/Attributes.php b/Model/System/Config/Source/Attributes.php index 70451f5..7fc87af 100755 --- a/Model/System/Config/Source/Attributes.php +++ b/Model/System/Config/Source/Attributes.php @@ -22,10 +22,12 @@ class Attributes implements ArrayInterface * @var array */ public $options; + /** * @var Repository */ private $attributeRepository; + /** * @var SearchCriteriaBuilder */ @@ -74,7 +76,7 @@ private function getAttributeCollection() } /** - * @param $attributeLabel + * @param string $attributeLabel * * @return string */ diff --git a/Model/System/Config/Source/AttributesWithStatic.php b/Model/System/Config/Source/AttributesWithStatic.php index ee2f044..a98266e 100755 --- a/Model/System/Config/Source/AttributesWithStatic.php +++ b/Model/System/Config/Source/AttributesWithStatic.php @@ -22,10 +22,12 @@ class AttributesWithStatic implements ArrayInterface * @var array */ public $options; + /** * @var Repository */ private $attributeRepository; + /** * @var SearchCriteriaBuilder */ @@ -75,7 +77,7 @@ private function getAttributeCollection() } /** - * @param $attributeLabel + * @param string $attributeLabel * * @return string */ diff --git a/Model/TokenRetriever.php b/Model/TokenRetriever.php index babfce4..c125e8e 100644 --- a/Model/TokenRetriever.php +++ b/Model/TokenRetriever.php @@ -116,26 +116,13 @@ public function retrieveByQuote(Quote $quote) if (!$this->token) { $reference = $this->getQuoteReference($quote); - if ($reference->getToken()) { - try { - $api = $this->apiFactory->create(); - // Check if token is expired - if (($token = $api->getApiToken($this->referenceBuilder->getQuoteReference($quote))) - && $token->getToken() !== $reference->getToken() - ) { - // ... and refresh it in QuoteReference - $this->refreshQuoteReferenceApiToken($reference, $token->getToken()); - } - } catch (\Exception $exception) { - throw new LocalizedException(__($exception->getMessage()), $exception); - } + if ($reference->getToken() && !$reference->isTokenExpired()) { $this->token = $reference->getToken(); - return $this->token; } try { - $api = $this->apiFactory->create(); + $api = $this->apiFactory->create($quote->getStoreId()); $token = $api->getApiToken($this->referenceBuilder->getQuoteReference($quote)); $gmtNow = $this->timezone->date(null, null, false); // @codingStandardsIgnoreLine @@ -163,7 +150,7 @@ public function retrieveByOrder(OrderInterface $order) { if (!$this->token) { try { - $api = $this->apiFactory->create(); + $api = $this->apiFactory->create($order->getStoreId()); $token = $api->getApiToken($this->referenceBuilder->getOrderReference($order)); $this->token = $token->getToken(); } catch (\Exception $exception) { @@ -178,7 +165,7 @@ public function retrieveByOrder(OrderInterface $order) * Refreshes API token in quote reference * * @param QuoteReferenceInterface $reference - * @param $token + * @param string $token * @throws LocalizedException */ protected function refreshQuoteReferenceApiToken(QuoteReferenceInterface $reference, $token) diff --git a/Observer/Admin/Order/Create/ProcessData.php b/Observer/Admin/Order/Create/ProcessData.php new file mode 100755 index 0000000..4d9dbe2 --- /dev/null +++ b/Observer/Admin/Order/Create/ProcessData.php @@ -0,0 +1,67 @@ +messageManager = $messageManager; + $this->checkoutInfoToQuote = $checkoutInfoToQuote; + $this->referenceBuilder = $referenceBuilder; + } + + /** + * {@inheritdoc} + */ + public function execute(Observer $observer) + { + /** @var OrderCreateModel $orderCreateModel */ + $orderCreateModel = $observer->getOrderCreateModel(); + $shippingMethod = $orderCreateModel->getShippingAddress()->getShippingMethod(); + if ($shippingMethod === Paazlshipping::CODE . '_' . Paazlshipping::CODE) { + /** @var Quote $quote */ + $quote = $orderCreateModel->getQuote(); + $this->checkoutInfoToQuote->process($quote); + $quote->getShippingAddress()->setCollectShippingRates(1); + } + } +} diff --git a/Plugin/Checkout/ShippingInformationManagementPlugin.php b/Plugin/Checkout/ShippingInformationManagementPlugin.php index d794fd8..3a40ce0 100755 --- a/Plugin/Checkout/ShippingInformationManagementPlugin.php +++ b/Plugin/Checkout/ShippingInformationManagementPlugin.php @@ -21,6 +21,7 @@ use Magento\Quote\Api\ShippingMethodManagementInterface; use Paazl\CheckoutWidget\Model\Api\Builder\Reference; use Paazl\CheckoutWidget\Model\Api\PaazlApi; +use Paazl\CheckoutWidget\Model\Api\PaazlApiFactory; use Paazl\CheckoutWidget\Model\Api\Processor\CheckoutInfoToQuote; use Paazl\CheckoutWidget\Model\Carrier\Paazlshipping; use Paazl\CheckoutWidget\Model\Api\ApiException; @@ -34,9 +35,9 @@ class ShippingInformationManagementPlugin { /** - * @var PaazlApi + * @var PaazlApiFactory */ - private $api; + private $paazlApiFactory; /** * @var Reference @@ -59,7 +60,7 @@ class ShippingInformationManagementPlugin private $shipmentEstimation; /** - * @var CartInterface + * @var CartInterface|null */ private $quote; @@ -81,7 +82,7 @@ class ShippingInformationManagementPlugin /** * ShippingInformationManagementPlugin constructor. * - * @param PaazlApi $api + * @param PaazlApiFactory $paazlApiFactory * @param Reference $referenceBuilder * @param CartRepositoryInterface $quoteRepository * @param CheckoutInfoToQuote $checkoutInfoToQuote @@ -91,7 +92,7 @@ class ShippingInformationManagementPlugin * @param ArrayManager $arrayManager */ public function __construct( - PaazlApi $api, + PaazlApiFactory $paazlApiFactory, Reference $referenceBuilder, CartRepositoryInterface $quoteRepository, CheckoutInfoToQuote $checkoutInfoToQuote, @@ -100,7 +101,7 @@ public function __construct( TotalsExtensionFactory $totalsExtensionFactory, ArrayManager $arrayManager ) { - $this->api = $api; + $this->paazlApiFactory = $paazlApiFactory; $this->referenceBuilder = $referenceBuilder; $this->quoteRepository = $quoteRepository; $this->checkoutInfoToQuote = $checkoutInfoToQuote; @@ -112,7 +113,7 @@ public function __construct( /** * @param ShippingInformationManagement $subject - * @param $cartId + * @param int $cartId * @param ShippingInformationInterface $addressInformation * * @return null @@ -129,7 +130,9 @@ public function beforeSaveAddressInformation( if ($addressInformation->getShippingCarrierCode() === Paazlshipping::CODE) { // Getting the checkout information from Paazl - $result = $this->api->fetchCheckoutData($this->referenceBuilder->getQuoteReference($quote)); + /** @var PaazlApi $paazlApi */ + $paazlApi = $this->paazlApiFactory->create($quote->getStoreId()); + $result = $paazlApi->fetchCheckoutData($this->referenceBuilder->getQuoteReference($quote)); // Checking pickupLocation if ($this->arrayManager->get('deliveryType', $result) === DeliveryType::PICKUP) { @@ -203,7 +206,7 @@ public function afterSaveAddressInformation( /** @var TotalsInterface $totals */ $totals = $paymentDetails->getTotals(); - /** @var TotalsExtensionInterface $extension */ + /** @var TotalsExtensionInterface|null $extension */ $extension = $totals->getExtensionAttributes(); if (!$extension) { $extension = $this->totalsExtensionFactory->create(); diff --git a/Plugin/ExcludeFromMinification.php b/Plugin/ExcludeFromMinification.php index d772aa4..7190c22 100755 --- a/Plugin/ExcludeFromMinification.php +++ b/Plugin/ExcludeFromMinification.php @@ -21,7 +21,7 @@ class ExcludeFromMinification * * @param Minification $subject * @param array $result - * @param $contentType + * @param string $contentType * * @return array */ diff --git a/Plugin/Quote/CartManagementPlugin.php b/Plugin/Quote/CartManagementPlugin.php new file mode 100644 index 0000000..33d1008 --- /dev/null +++ b/Plugin/Quote/CartManagementPlugin.php @@ -0,0 +1,80 @@ +quoteRepository = $quoteRepository; + $this->orderHelper = $orderHelper; + $this->infoHandler = $infoHandler; + } + + /** + * @param CartManagementInterface $subject + * @param int $cartId + * @param PaymentInterface|null $paymentMethod + * + * @return null + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws CouldNotSaveException + */ + public function beforePlaceOrder( + CartManagementInterface $subject, + $cartId, + PaymentInterface $paymentMethod = null + ) { + $quote = $this->quoteRepository->getActive($cartId); + if ($quote->getIsVirtual()) { + return null; + } + + $shippingMethod = $quote->getShippingAddress()->getShippingMethod(); + if (!$this->orderHelper->isPaazlShippingMethod($shippingMethod)) { + return null; + } + + $info = $this->infoHandler->getInfoFromQuote($quote); + if (!$info) { + throw new CouldNotSaveException(__('Shipping information not found')); + } + + return null; + } +} diff --git a/Plugin/Sales/OrderRepositoryPlugin.php b/Plugin/Sales/OrderRepositoryPlugin.php index f669136..4c35e08 100755 --- a/Plugin/Sales/OrderRepositoryPlugin.php +++ b/Plugin/Sales/OrderRepositoryPlugin.php @@ -122,7 +122,6 @@ public function afterSave( try { $this->orderReferenceRepository->save($orderReference); - $this->sendToService->process($order); } catch (\Exception $e) { $this->generalHelper->addTolog('exception', $e->getMessage()); } diff --git a/Plugin/Shipping/CarrierFactoryPlugin.php b/Plugin/Shipping/CarrierFactoryPlugin.php deleted file mode 100755 index 48a1081..0000000 --- a/Plugin/Shipping/CarrierFactoryPlugin.php +++ /dev/null @@ -1,96 +0,0 @@ -config = $config; - $this->checkout = $checkout; - $this->quoteReferenceRepository = $quoteReferenceRepository; - } - - /** - * @param CarrierFactory $subject - * @param \Closure $proceed - * @param $carrierCode - * @param null $storeId - * - * @return bool|AbstractCarrier - */ - public function aroundCreateIfActive( - CarrierFactory $subject, - \Closure $proceed, - $carrierCode, - $storeId = null - ) { - $paazlActive = $this->config->isCarrierActive(); - - try { - $reference = $this->quoteReferenceRepository->getByQuoteId($this->checkout->getQuoteId()); - $paazlActive = $paazlActive && !empty($reference->getToken()); - } catch (NoSuchEntityException $e) { - $paazlActive = false; - } - - $carrier = $proceed($carrierCode, $storeId); - if (!$carrier) { - return $carrier; - } - - if ($paazlActive && $this->config->isHideOtherShippingMethods() && ($carrierCode != Paazlshipping::CODE)) { - // This is not Paazl, but Paazl is active and hides other methods - deactivating this method - return false; - } - - if (!$paazlActive && ($carrierCode == Paazlshipping::CODE)) { - return false; - } - - return $carrier; - } -} diff --git a/Plugin/Shipping/RateCollectorPlugin.php b/Plugin/Shipping/RateCollectorPlugin.php new file mode 100644 index 0000000..f17dae5 --- /dev/null +++ b/Plugin/Shipping/RateCollectorPlugin.php @@ -0,0 +1,63 @@ +config = $config; + } + + public function afterCollectRates( + RateCollectorInterface $subject, + RateCollectorInterface $result + ) { + + /** @var \Magento\Shipping\Model\Rate\Result $ratesResult */ + $ratesResult = $result->getResult(); + + /* + * If Paazl is active + * and HideOtherCarriers exists - removing non-Paazl rates + */ + $hideOthers = $this->config->isCarrierActive() && $this->config->isHideOtherShippingMethods(); + if ($hideOthers && !empty($ratesResult->getRatesByCarrier(Paazlshipping::CODE))) { + // Removing other rates + $rates = $ratesResult->getAllRates(); + $errorExists = $ratesResult->getError(); + $ratesResult->reset(); + + /** @var \Magento\Quote\Model\Quote\Address\RateResult\AbstractResult $rate */ + foreach ($rates as $rateKey => $rate) { + if ($rate->getCarrier() !== Paazlshipping::CODE) { + unset($rates[$rateKey]); + } + } + + $ratesResult->setError($errorExists); + foreach ($rates as $rate) { + $ratesResult->append($rate); + } + } + + return $result; + } +} diff --git a/README.md b/README.md index 280371b..8d60da3 100755 --- a/README.md +++ b/README.md @@ -51,4 +51,4 @@ If Magento 2 is running in production modus, run compiltation and deploy static ``` php bin/magento setup:di:compile php bin/magento setup:static-content:deploy - ``` + ``` \ No newline at end of file diff --git a/Ui/Component/Order/View/PaazlModal/AvailableShippingMethods/Options.php b/Ui/Component/Order/View/PaazlModal/AvailableShippingMethods/Options.php index 000ed7d..5383bcc 100644 --- a/Ui/Component/Order/View/PaazlModal/AvailableShippingMethods/Options.php +++ b/Ui/Component/Order/View/PaazlModal/AvailableShippingMethods/Options.php @@ -13,9 +13,9 @@ use Magento\Framework\Exception\NoSuchEntityException; use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\OrderRepositoryInterface; -use Magento\Backend\Model\Session\Proxy as Session; +use Magento\Backend\Model\Session; +use Paazl\CheckoutWidget\Model\Api\PaazlApiFactory; use Paazl\CheckoutWidget\Model\Order\WidgetConfigProvider; -use Paazl\CheckoutWidget\Model\Api\PaazlApi; use Paazl\CheckoutWidget\Model\Api\ApiException; /** @@ -23,49 +23,63 @@ */ class Options implements OptionSourceInterface { - /** @var RequestInterface */ + /** + * @var RequestInterface + */ protected $request; - /** @var array */ + /** + * @var array + */ protected $options = null; - /** @var OrderRepositoryInterface */ + /** + * @var OrderRepositoryInterface + */ protected $orderRepository; - /** @var WidgetConfigProvider */ + /** + * @var WidgetConfigProvider + */ protected $widgetConfigProvider; - /** @var PaazlApi */ - protected $paazlApi; + /** + * @var PaazlApiFactory + */ + protected $paazlApiFactory; - /** @var SerializerInterface */ + /** + * @var SerializerInterface + */ protected $serializer; - /** @var Session */ + /** + * @var Session + */ private $session; /** * Constructor * - * @param RequestInterface $request + * @param RequestInterface $request * @param OrderRepositoryInterface $orderRepository - * @param WidgetConfigProvider $widgetConfigProvider - * @param PaazlApi $paazlApi - * @param SerializerInterface $serializer - * @param Session $session + * @param WidgetConfigProvider $widgetConfigProvider + * @param PaazlApiFactory $paazlApiFactory + * @param SerializerInterface $serializer + * @param Session $session */ public function __construct( RequestInterface $request, OrderRepositoryInterface $orderRepository, WidgetConfigProvider $widgetConfigProvider, - PaazlApi $paazlApi, + PaazlApiFactory $paazlApiFactory, SerializerInterface $serializer, Session $session ) { $this->request = $request; $this->orderRepository = $orderRepository; $this->widgetConfigProvider = $widgetConfigProvider; - $this->paazlApi = $paazlApi; + $this->paazlApiFactory = $paazlApiFactory; $this->serializer = $serializer; $this->session = $session; } @@ -92,7 +106,10 @@ protected function getShippingOptions() $orderData = $this->widgetConfigProvider ->setOrder($order) ->getConfig(); - $shippingOptions = $this->serializer->unserialize($this->paazlApi->getShippingOptions($orderData)); + $shippingOptions = $this->serializer->unserialize( + $this->paazlApiFactory->create($order->getStoreId()) + ->getShippingOptions($orderData) + ); $shippingOptions = $shippingOptions['shippingOptions']; $this->session->setPaazlShippingOptions($this->serializer->serialize($shippingOptions)); $options = []; diff --git a/Ui/DataProvider/Order/View/PaazlOrderDataDataProvider.php b/Ui/DataProvider/Order/View/PaazlOrderDataDataProvider.php index bf5d04e..b1621ea 100644 --- a/Ui/DataProvider/Order/View/PaazlOrderDataDataProvider.php +++ b/Ui/DataProvider/Order/View/PaazlOrderDataDataProvider.php @@ -79,13 +79,15 @@ public function getConfigData() return []; } + // phpcs:disable /** * {@inheritDoc} */ public function setConfigData($config) { - // TODO: Implement setConfigData() method. + } + // phpcs:enable /** * {@inheritDoc} @@ -143,43 +145,53 @@ public function getData() return []; } + // phpcs:disable /** * {@inheritDoc} */ public function addFilter(\Magento\Framework\Api\Filter $filter) { - // TODO: Implement addFilter() method. + } + // phpcs:enable + // phpcs:disable /** * {@inheritDoc} */ public function addOrder($field, $direction) { - // TODO: Implement addOrder() method. + } + // phpcs:enable + // phpcs:disable /** * {@inheritDoc} */ public function setLimit($offset, $size) { - // TODO: Implement setLimit() method. + } + // phpcs:enable + // phpcs:disable /** * {@inheritDoc} */ public function getSearchCriteria() { - // TODO: Implement getSearchCriteria() method. + } + // phpcs:enable + // phpcs:disable /** * {@inheritDoc} */ public function getSearchResult() { - // TODO: Implement getSearchResult() method. + } + // phpcs:enable } diff --git a/ViewModel/PaazlStatus/DeliveryDate.php b/ViewModel/PaazlStatus/DeliveryDate.php index f03d23d..7783a7b 100755 --- a/ViewModel/PaazlStatus/DeliveryDate.php +++ b/ViewModel/PaazlStatus/DeliveryDate.php @@ -7,11 +7,11 @@ namespace Paazl\CheckoutWidget\ViewModel\PaazlStatus; use Magento\Framework\View\Element\Block\ArgumentInterface; -use Magento\Backend\Block\Template\Context\Proxy as ProxyContext; +use Magento\Backend\Block\Template\Context; use Magento\Framework\Api\DataObjectHelper; -use Magento\Framework\Serialize\SerializerInterface; use Magento\Framework\Exception\LocalizedException; use Paazl\CheckoutWidget\Block\Adminhtml\Order\View\ShippingAndHandling\PaazlStatus as ParentBlock; +use Paazl\CheckoutWidget\Model\ExtInfoHandler; use Paazl\CheckoutWidget\Model\ShippingInfo; use Paazl\CheckoutWidget\Model\ShippingInfoFactory; use Paazl\CheckoutWidget\Model\Api\Field\DeliveryType; @@ -30,12 +30,7 @@ class DeliveryDate implements ArgumentInterface protected $dataObjectHelper; /** - * @var SerializerInterface - */ - private $serializer; - - /** - * @var ProxyContext + * @var Context */ private $context; @@ -59,24 +54,29 @@ class DeliveryDate implements ArgumentInterface */ private $extShippingInfo = null; + /** + * @var ExtInfoHandler + */ + private $extInfoHandler; + /** * ViewModel constructor * - * @param DataObjectHelper $dataObjectHelper - * @param SerializerInterface $serializer - * @param ProxyContext $context + * @param DataObjectHelper $dataObjectHelper + * @param ExtInfoHandler $extInfoHandler + * @param Context $context * @param ShippingInfoFactory $shippingInfoFactory */ public function __construct( DataObjectHelper $dataObjectHelper, - SerializerInterface $serializer, - ProxyContext $context, + ExtInfoHandler $extInfoHandler, + Context $context, ShippingInfoFactory $shippingInfoFactory ) { $this->dataObjectHelper = $dataObjectHelper; - $this->serializer = $serializer; $this->shippingInfoFactory = $shippingInfoFactory; $this->context = $context; + $this->extInfoHandler = $extInfoHandler; } /** @@ -122,14 +122,7 @@ public function getExtShippingInfo() } if (null === $this->extShippingInfo) { - $shippingInfo = $this->shippingInfoFactory->create(); - $shippingInfoData = $this->serializer->unserialize($this->getPaazlOrder()->getExtShippingInfo()); - $this->dataObjectHelper->populateWithArray( - $shippingInfo, - $shippingInfoData, - ShippingInfo::class - ); - $this->extShippingInfo = $shippingInfo; + $this->extShippingInfo = $this->extInfoHandler->getInfoFromOrderReference($this->getPaazlOrder()); } return $this->extShippingInfo; @@ -143,6 +136,6 @@ public function getExtShippingInfo() */ public function isTypeDelivery() { - return $this->getExtShippingInfo()->getType() === DeliveryType::DELIVERY; + return $this->getExtShippingInfo() && $this->getExtShippingInfo()->getType() === DeliveryType::DELIVERY; } } diff --git a/ViewModel/Pickup/Info.php b/ViewModel/Pickup/Info.php index aebad5d..ae61627 100755 --- a/ViewModel/Pickup/Info.php +++ b/ViewModel/Pickup/Info.php @@ -21,7 +21,6 @@ use Paazl\CheckoutWidget\Model\Api\Field\DeliveryType; use Paazl\CheckoutWidget\Model\ExtInfoHandler; use Paazl\CheckoutWidget\Model\Delivery\OrderPickupLocationFactory; -use Paazl\CheckoutWidget\Model\Api\PaazlApi; use Paazl\CheckoutWidget\Model\ShippingInfo; use Paazl\CheckoutWidget\Model\Location\OrderAddressFactory; @@ -30,37 +29,54 @@ */ class Info implements ArgumentInterface { - /** @var OrderInterface */ + /** + * @var OrderInterface + */ private $order = null; - /** @var ShippingInfo */ + /** + * @var ShippingInfo + */ protected $orderInfo = null; - /** @var RequestInterface */ + /** + * @var RequestInterface + */ protected $request; - /** @var OrderRepositoryInterface */ + /** + * @var OrderRepositoryInterface + */ protected $orderRepository; - /** @var OrderHelper */ + /** + * @var OrderHelper + */ protected $orderHelper; - /** @var OrderReferenceRepositoryInterface */ + /** + * @var OrderReferenceRepositoryInterface + */ private $orderReferenceRepository; - /** @var PaazlApi */ - private $api; - - /** @var ExtInfoHandler */ + /** + * @var ExtInfoHandler + */ protected $extInfoHandler; - /** @var OrderPickupLocationFactory $orderPickupLocationFactory */ + /** + * @var OrderPickupLocationFactory $orderPickupLocationFactory + */ protected $orderPickupLocationFactory; - /** @var OrderAddressFactory */ + /** + * @var OrderAddressFactory + */ private $orderAddressFactory; - /** @var AddressRenderer */ + /** + * @var AddressRenderer + */ private $addressRenderer; /** @@ -70,7 +86,6 @@ class Info implements ArgumentInterface * @param OrderRepositoryInterface $orderRepository * @param OrderHelper $orderHelper * @param OrderReferenceRepositoryInterface $orderReferenceRepository - * @param PaazlApi $api * @param ExtInfoHandler $extInfoHandler * @param OrderPickupLocationFactory $orderPickupLocationFactory * @param OrderAddressFactory $orderAddressFactory @@ -81,7 +96,6 @@ public function __construct( OrderRepositoryInterface $orderRepository, OrderHelper $orderHelper, OrderReferenceRepositoryInterface $orderReferenceRepository, - PaazlApi $api, ExtInfoHandler $extInfoHandler, OrderPickupLocationFactory $orderPickupLocationFactory, OrderAddressFactory $orderAddressFactory, @@ -91,7 +105,6 @@ public function __construct( $this->orderRepository = $orderRepository; $this->orderHelper = $orderHelper; $this->orderReferenceRepository = $orderReferenceRepository; - $this->api = $api; $this->extInfoHandler = $extInfoHandler; $this->orderPickupLocationFactory = $orderPickupLocationFactory; $this->orderAddressFactory = $orderAddressFactory; @@ -139,10 +152,10 @@ public function getPickupLocationAddressHtml() return ''; } - /** @var ShippingInfo $orderInfo */ + /** @var ShippingInfo|null $orderInfo */ $orderInfo = $this->getOrderInfo(); - if ($orderInfo->getType() !== DeliveryType::PICKUP) { + if (!$orderInfo || ($orderInfo->getType() !== DeliveryType::PICKUP)) { return ''; } diff --git a/composer.json b/composer.json index 1de9f6b..4715657 100755 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "paazl/magento2-checkout-widget", "description": "Paazl checkoutWidget for Magento 2", "type": "magento2-module", - "version": "1.1.4", + "version": "1.2.0", "keywords": [ "Paazl", "Magento 2", diff --git a/etc/adminhtml/di.xml b/etc/adminhtml/di.xml new file mode 100755 index 0000000..545d4df --- /dev/null +++ b/etc/adminhtml/di.xml @@ -0,0 +1,40 @@ + + + + + + + Paazl\CheckoutWidget\Model\Admin\Order\Create\PaazlConfigProvider + + + + + + + Magento\Backend\Model\Session\Proxy + + + + + + Magento\Backend\Model\Session\Proxy + + + + + + Magento\Backend\Model\Session\Proxy + + + + + + Magento\Backend\Block\Template\Context\Proxy + + + diff --git a/etc/adminhtml/events.xml b/etc/adminhtml/events.xml new file mode 100755 index 0000000..043c8dd --- /dev/null +++ b/etc/adminhtml/events.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 0b73d26..f44576c 100755 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -227,6 +227,11 @@ + + + Magento\Config\Model\Config\Source\Yesno + OneStepCheckout, Custom Checkout etc. + diff --git a/etc/di.xml b/etc/di.xml index 31a4368..550628f 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -49,6 +49,17 @@ + + + Magento\Sales\Api\OrderRepositoryInterface\Proxy + Paazl\CheckoutWidget\Model\Api\Processor\SendToService\Proxy + Magento\Framework\App\State\Proxy + + + @@ -78,4 +89,8 @@ + + + + diff --git a/etc/frontend/di.xml b/etc/frontend/di.xml index 9e68d64..db1231c 100755 --- a/etc/frontend/di.xml +++ b/etc/frontend/di.xml @@ -5,9 +5,8 @@ --> - - + + diff --git a/etc/module.xml b/etc/module.xml index 8d2c38a..6cedb6c 100755 --- a/etc/module.xml +++ b/etc/module.xml @@ -5,7 +5,7 @@ --> - + diff --git a/etc/webapi_rest/di.xml b/etc/webapi_rest/di.xml index 0d6b465..2844e29 100755 --- a/etc/webapi_rest/di.xml +++ b/etc/webapi_rest/di.xml @@ -5,10 +5,10 @@ --> - - + + + diff --git a/view/adminhtml/layout/sales_order_create_index.xml b/view/adminhtml/layout/sales_order_create_index.xml new file mode 100755 index 0000000..f52bed4 --- /dev/null +++ b/view/adminhtml/layout/sales_order_create_index.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + diff --git a/view/adminhtml/layout/sales_order_create_load_block_header.xml b/view/adminhtml/layout/sales_order_create_load_block_header.xml new file mode 100644 index 0000000..f07dab0 --- /dev/null +++ b/view/adminhtml/layout/sales_order_create_load_block_header.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/view/adminhtml/layout/sales_order_create_load_block_shipping_method.xml b/view/adminhtml/layout/sales_order_create_load_block_shipping_method.xml new file mode 100755 index 0000000..a0c8555 --- /dev/null +++ b/view/adminhtml/layout/sales_order_create_load_block_shipping_method.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/view/adminhtml/requirejs-config.js b/view/adminhtml/requirejs-config.js index 3726877..93d5309 100755 --- a/view/adminhtml/requirejs-config.js +++ b/view/adminhtml/requirejs-config.js @@ -4,6 +4,11 @@ */ var config = { + map: { + '*': { + paazlWidgetModal: 'Paazl_CheckoutWidget/js/admin/order/create/shipping/method/paazl/widget/modal' + } + }, config: { mixins: { 'mage/validation': { diff --git a/view/adminhtml/templates/order/create/paazl-js.phtml b/view/adminhtml/templates/order/create/paazl-js.phtml new file mode 100755 index 0000000..2dfa511 --- /dev/null +++ b/view/adminhtml/templates/order/create/paazl-js.phtml @@ -0,0 +1,43 @@ + + + diff --git a/view/adminhtml/templates/order/create/shipping/method/form.phtml b/view/adminhtml/templates/order/create/shipping/method/form.phtml new file mode 100755 index 0000000..6f5934a --- /dev/null +++ b/view/adminhtml/templates/order/create/shipping/method/form.phtml @@ -0,0 +1,107 @@ + + +getShippingRates(); ?> + + + getActiveMethodRate()): ?> +
+
+
+ escapeHtml($block->getCarrierName($_rate->getCarrier())) ?> +
+
+ escapeHtml($_rate->getMethodTitle() ? $_rate->getMethodTitle() : $_rate->getMethodDescription()) ?> - + + getShippingPrice($_rate->getPrice(), $this->helper('Magento\Tax\Helper\Data')->displayShippingPriceIncludingTax()); ?> + getShippingPrice($_rate->getPrice(), true); ?> + + + helper('Magento\Tax\Helper\Data')->displayShippingBothPrices() && $_incl != $_excl): ?> + ( ) + + +
+
+ + + +
+ + + +getIsRateRequest()): ?> +
+ +
+ +
+ + + + +
+ + + diff --git a/view/adminhtml/templates/order/create/shipping/method/paazl.phtml b/view/adminhtml/templates/order/create/shipping/method/paazl.phtml new file mode 100755 index 0000000..c30c6ae --- /dev/null +++ b/view/adminhtml/templates/order/create/shipping/method/paazl.phtml @@ -0,0 +1,14 @@ + +
+ getChildHtml('', false) ?> +
diff --git a/view/adminhtml/templates/order/create/shipping/method/paazl/widget/config.phtml b/view/adminhtml/templates/order/create/shipping/method/paazl/widget/config.phtml new file mode 100755 index 0000000..177afaf --- /dev/null +++ b/view/adminhtml/templates/order/create/shipping/method/paazl/widget/config.phtml @@ -0,0 +1,19 @@ + + diff --git a/view/adminhtml/templates/order/create/shipping/method/paazl/widget/modal.phtml b/view/adminhtml/templates/order/create/shipping/method/paazl/widget/modal.phtml new file mode 100755 index 0000000..489c35e --- /dev/null +++ b/view/adminhtml/templates/order/create/shipping/method/paazl/widget/modal.phtml @@ -0,0 +1,16 @@ + + +
+
+
diff --git a/view/adminhtml/templates/order/view/shipping-and-handling-info/paazl-status.phtml b/view/adminhtml/templates/order/view/shipping-and-handling-info/paazl-status.phtml index 67d1821..4327efd 100644 --- a/view/adminhtml/templates/order/view/shipping-and-handling-info/paazl-status.phtml +++ b/view/adminhtml/templates/order/view/shipping-and-handling-info/paazl-status.phtml @@ -54,4 +54,3 @@ use Paazl\CheckoutWidget\Ui\Component\Order\Listing\Column\Status\Options; - diff --git a/view/adminhtml/web/css/styles.css b/view/adminhtml/web/css/styles.css index 18ae739..32c0acb 100644 --- a/view/adminhtml/web/css/styles.css +++ b/view/adminhtml/web/css/styles.css @@ -168,3 +168,16 @@ aside.paazl_order_data_form_modal .page-actions.floating-header { .paazl-delivery-date .value { margin-left: 1rem; } + +aside.paazl-widget-modal .modal-inner-wrap { + width: calc(720px + 6rem); +} + +section.paazl.method-select { + padding-bottom: 0; +} + +section.paazl.method-select section.paazl__body.body form.options { + max-height: 400px; + overflow-y: auto; +} \ No newline at end of file diff --git a/view/adminhtml/web/js/admin/order/create/shipping/method/paazl/widget/config.js b/view/adminhtml/web/js/admin/order/create/shipping/method/paazl/widget/config.js new file mode 100755 index 0000000..27459e4 --- /dev/null +++ b/view/adminhtml/web/js/admin/order/create/shipping/method/paazl/widget/config.js @@ -0,0 +1,109 @@ +/** + * Copyright © 2019 Paazl. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'ko', + 'uiComponent', + 'jquery', + 'domReady' +], function (ko, Component, $, domReady) { + 'use strict'; + + var shippingConfig, + widgetConfig; + + domReady(function () { + /** + * Preventing propagation of click event in order to avoid send of Shipping form + */ + $(document).on('click', "#widget_paazlshipping_paazlshipping button", function (event) { + event.preventDefault(); + event.stopPropagation(); + return false; + }); + }); + + return Component.extend({ + configJson: ko.observable(), + customerAddressId: null, + state: { + postcode: null, + country: null, + token: null + }, + + initialize: function () { + this._super(); + this.initConfig(); + }, + + initConfig: function () { + shippingConfig = order.paazlshipping || {}; + widgetConfig = shippingConfig.widgetConfig || {}; + + this.setConfigJson(widgetConfig); + }, + + setConfigJson: function (data) { + this.configJson(data); + }, + + isHideOtherMethods: function () { + return shippingConfig.hideOtherMethods; + }, + + getCarrierCode: function () { + return shippingConfig.carrierCode; + }, + + getMethodCode: function () { + return shippingConfig.methodCode; + }, + + /** + * + * @return {string} + */ + getJsName: function () { + var name = 'checkoutjs'; + if (shippingConfig.mode === 'test') { + name += '_test'; + } else { + name += '_live'; + } + + return name; + }, + + loadWidget: function (postcode, country) { + this.initialize(); + + var data = this.configJson(), + self = this; + + if (!data) { + return; + } + var container = $('#' + data.mountElementId); + + if (!container.length) { + return; + } + + container.html(''); + + var infoUpdate = function (paazlCheckout) { + data.consigneePostalCode = postcode || data.consigneePostalCode; + data.consigneeCountryCode = country || data.consigneeCountryCode; + paazlCheckout.init(data); + self.state.postcode = data.consigneePostalCode; + self.state.country = data.consigneeCountryCode; + self.state.token = data.token; + }; + + require([this.getJsName()], infoUpdate); + } + }); +}); diff --git a/view/adminhtml/web/js/admin/order/create/shipping/method/paazl/widget/modal.js b/view/adminhtml/web/js/admin/order/create/shipping/method/paazl/widget/modal.js new file mode 100755 index 0000000..cb017f0 --- /dev/null +++ b/view/adminhtml/web/js/admin/order/create/shipping/method/paazl/widget/modal.js @@ -0,0 +1,77 @@ +/** + * Copyright © 2019 Paazl. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'jquery', + 'Paazl_CheckoutWidget/js/admin/order/create/shipping/method/paazl/widget/config', + 'jquery/ui', + 'Magento_Ui/js/modal/modal' +], function($, widgetConfig) { + "use strict"; + + $.widget('mage.paazlWidgetModal', $.mage.modal, { + options: { + modalForm: '#paazl-modal', + modalButton: '.paazl-modal-open' + }, + _create: function () { + Object.assign(this.options, this._prepareModal()); + this._super(); + }, + _prepareModal: function () { + return { + responsive: true, + clickableOverlay: false, + title: $.mage.__('Choose shipping method'), + modalClass: 'popup paazl-widget-modal', + buttons: [{ + text: $.mage.__('Continue'), + class: '', + click: function () { + this.saveShippingMethod(); + } + }] + }; + }, + openModal: function () { + this._super(); + + let addressContainer = order.shippingAsBilling ? + 'billingAddressContainer' : + 'shippingAddressContainer', + addressIndex = order.shippingAsBilling ? + 'billing_address' : + 'shipping_address', + data = order.serializeData(order[addressContainer]).toObject(), + postcode = data['order[' + addressIndex + '][postcode]'], + countryId = data['order[' + addressIndex + '][country_id]']; + + widgetConfig.prototype.loadWidget(postcode, countryId); + }, + closeModal: function (force = false) { + this._super(); + + if (force) { + this._super(); + return; + } + + if (!order.oldShippingMethod) { + order.resetShippingMethod(); + return; + } + + order.showModalFlag = false; + order.setShippingMethod(order.oldShippingMethod); + }, + saveShippingMethod: function () { + order.showModalFlag = false; + order.setShippingMethod('paazlshipping_paazlshipping'); + this.closeModal(true); + } + }); + + return $.mage.paazlWidgetModal; +}); \ No newline at end of file diff --git a/view/adminhtml/web/template/admin/order/create/shipping/method/paazl/widget/config.html b/view/adminhtml/web/template/admin/order/create/shipping/method/paazl/widget/config.html new file mode 100755 index 0000000..64dcaab --- /dev/null +++ b/view/adminhtml/web/template/admin/order/create/shipping/method/paazl/widget/config.html @@ -0,0 +1,3 @@ + + + diff --git a/view/base/requirejs-config.js b/view/base/requirejs-config.js new file mode 100755 index 0000000..3fe691b --- /dev/null +++ b/view/base/requirejs-config.js @@ -0,0 +1,25 @@ +/** + * Copyright © 2019 Paazl. All rights reserved. + * See COPYING.txt for license details. + */ + +var config = { + map: { + '*': { + paazlCheckout: 'Paazl_CheckoutWidget/js/checkout', + widgetConfig: 'Paazl_CheckoutWidget/js/checkout/view/widget-config', + paazlShippingModal: 'Paazl_CheckoutWidget/js/admin/order/create/paazl-shipping/modal', + customJs: 'Paazl_CheckoutWidget/js/custom', + checkoutjs_test: "https://widget-acc.paazl.com/v1/checkout.js", + checkoutjs_live: "https://widget.paazl.com/v1/checkout.js" + } + }, + paths: { + paazlCheckout: 'Paazl_CheckoutWidget/js/checkout' + }, + shim: { + 'Paazl_CheckoutWidget/js/checkout': { + deps: ['jquery'] + } + }, +}; diff --git a/view/frontend/templates/checkout/widget.phtml b/view/base/templates/checkout/widget.phtml old mode 100644 new mode 100755 similarity index 88% rename from view/frontend/templates/checkout/widget.phtml rename to view/base/templates/checkout/widget.phtml index a992ed6..2d987e7 --- a/view/frontend/templates/checkout/widget.phtml +++ b/view/base/templates/checkout/widget.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** @var \Paazl\CheckoutWidget\Block\Checkout\Widget $block */ +/** @var Paazl\CheckoutWidget\Block\Checkout\Widget $block */ ?> getApiBaseUrl()) : ?>