From 056bc4994c60256e13d7446d751205434ee0a32a Mon Sep 17 00:00:00 2001 From: Jean-Michel Batty Date: Wed, 14 Aug 2024 16:22:03 -0500 Subject: [PATCH] Allow tracking of Parent Order when purchasing from a Lead Token where to see the changes - consume a lead token and add the warranty to the cart. - in the minicart/cart you will see the details of the warranty now include "Parent Order" and the increment ID of the parent order - in the database, you now have an extra column in sales_order_item called "extend_parent_order_id" that will have the order ID (not the increment ID) of the parent order from where the lead Token originates --- Helper/Api/Magento/Data.php | 2 + Model/Orders.php | 2 +- Model/Product/Type.php | 38 ++++++++++++++++++- Observer/CreateOrder.php | 24 +++++++++++- .../Configuration/GetCustomOptionsPlugin.php | 31 +++++++++++++++ ViewModel/Warranty.php | 23 ++++++++++- etc/db_schema.xml | 1 + etc/extension_attributes.xml | 3 +- .../templates/items/column/name.phtml | 11 +++++- 9 files changed, 127 insertions(+), 8 deletions(-) diff --git a/Helper/Api/Magento/Data.php b/Helper/Api/Magento/Data.php index a216b3f1..6aa1c26d 100644 --- a/Helper/Api/Magento/Data.php +++ b/Helper/Api/Magento/Data.php @@ -15,6 +15,7 @@ use Magento\Framework\App\Helper\Context; use Magento\Framework\Serialize\Serializer\Json; use Magento\Sales\Api\Data\OrderItemExtensionFactory; +use Magento\Sales\Api\Data\OrderItemExtensionInterface; use Magento\Sales\Api\Data\OrderItemInterface; use Magento\Sales\Model\Order\Item; @@ -36,6 +37,7 @@ class Data extends AbstractHelper public const WARRANTY_TERM = 'warranty_term'; public const LEAD_TOKEN = 'lead_token'; public const PLAN_TYPE = 'plan_type'; + public const PARENT_ORDER_ID = 'parent_order_id'; /** * Order Extension Attributes Factory diff --git a/Model/Orders.php b/Model/Orders.php index 9892b4ca..a677d618 100644 --- a/Model/Orders.php +++ b/Model/Orders.php @@ -290,7 +290,7 @@ public function cancel($order) $extendOrder = false; } - + if ($extendOrder){ $this->getOrderRequest($order->getStoreId()) ->cancel($extendOrder->getExtendOrderId()); diff --git a/Model/Product/Type.php b/Model/Product/Type.php index cb8cb6f8..f5142261 100644 --- a/Model/Product/Type.php +++ b/Model/Product/Type.php @@ -16,6 +16,7 @@ use Extend\Warranty\Helper\Data; use Magento\Framework\Exception\LocalizedException; use \Magento\Framework\Exception\NoSuchEntityException; +use \Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory as OrderItemCollectionFactory; /** * Class Type @@ -40,14 +41,16 @@ class Type extends AbstractType public const LEAD_TOKEN = 'lead_token'; public const BUY_REQUEST = 'info_buyRequest'; public const SECONDARY_SKU = 'secondary_sku'; + public const ASSOCIATED_PARENT_ORDER_ID = 'parent_order_id'; /** * Custom option labels */ public const ASSOCIATED_PRODUCT_LABEL = 'SKU'; - public const ASSOCIATED_PRODUCT_NAME_LABEL = 'Name'; public const TERM_LABEL = 'Term'; + public const PARENT_ORDER_LABEL = 'Parent Order'; + /** * Warranty Helper @@ -57,9 +60,16 @@ class Type extends AbstractType protected $helper; /** - * Type constructor. + * OrderItemCollectionFactory * + * @var Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory + */ + protected $orderItemCollectionFactory; + + /** + * Type constructor. * @param Product\Option $catalogProductOption + * @param \Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory $orderItemCollectionFactory * @param \Magento\Eav\Model\Config $eavConfig * @param Product\Type $catalogProductType * @param \Magento\Framework\Event\ManagerInterface $eventManager @@ -72,7 +82,9 @@ class Type extends AbstractType * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer */ public function __construct( + \Magento\Catalog\Model\Product\Option $catalogProductOption, + \Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory $orderItemCollectionFactory, \Magento\Eav\Model\Config $eavConfig, \Magento\Catalog\Model\Product\Type $catalogProductType, \Magento\Framework\Event\ManagerInterface $eventManager, @@ -86,6 +98,7 @@ public function __construct( ) { $this->helper = $helper; + $this->orderItemCollectionFactory = $orderItemCollectionFactory; parent::__construct( $catalogProductOption, $eavConfig, @@ -170,6 +183,23 @@ protected function _prepareProduct(\Magento\Framework\DataObject $buyRequest, $p if ($buyRequest->hasData('leadToken')) { $product->addCustomOption(self::LEAD_TOKEN, $buyRequest->getData('leadToken')); + + // Add parent order only if type = warranty and leadToken is set + // Find an existing sales_order_item record with lead_token matching and type is not warranty + + $orderItemCollection = $this->orderItemCollectionFactory->create(); + $orderItemCollection->addFieldToFilter('product_type', ['neq' => 'warranty']); + $orderItemCollection->addFieldToFilter('lead_token', ['like' =>'%'.$buyRequest->getData('leadToken').'%'] ); + $existingOrderItem = $orderItemCollection->getFirstItem(); + if ($existingOrderItem && $existingOrderItem->getId()) { + $parentOrderId = $existingOrderItem->getOrderId(); + } else { + $parentOrderId = null; + } + + if ($parentOrderId){ + $product->addCustomOption(self::ASSOCIATED_PARENT_ORDER_ID, $parentOrderId); + } } if ($this->_isStrictProcessMode($processMode)) { @@ -214,6 +244,10 @@ public function getOrderOptions($product) $options[self::LEAD_TOKEN] = $leadToken->getValue(); } + if ($parentOrder = $product->getCustomOption(self::ASSOCIATED_PARENT_ORDER_ID)) { + $options[self::ASSOCIATED_PARENT_ORDER_ID] = $parentOrder->getValue(); + } + return $options; } } diff --git a/Observer/CreateOrder.php b/Observer/CreateOrder.php index 2d7dad9e..7e38b0f4 100644 --- a/Observer/CreateOrder.php +++ b/Observer/CreateOrder.php @@ -24,6 +24,7 @@ use Magento\Sales\Api\Data\OrderItemInterface; use Exception; use Extend\Warranty\Model\CreateContract as WarrantyContractCreate; +use \Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory as OrderItemCollectionFactory; /** * Class CreateLead @@ -67,6 +68,13 @@ class CreateOrder implements ObserverInterface */ private $warrantyContractCreate; + /** + * OrderItemCollectionFactory + * + * @var Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory + */ + protected $orderItemCollectionFactory; + /** * CreateLead constructor * @@ -74,13 +82,15 @@ class CreateOrder implements ObserverInterface * @param ExtendOrder $extendOrder * @param DataHelper $dataHelper * @param LoggerInterface $logger + * @param \Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory $orderItemCollectionFactory */ public function __construct( OrderItemRepositoryInterface $orderItemRepository, ExtendOrder $extendOrder, DataHelper $dataHelper, LoggerInterface $logger, - WarrantyContractCreate $warrantyContractCreate + WarrantyContractCreate $warrantyContractCreate, + \Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory $orderItemCollectionFactory ) { $this->orderItemRepository = $orderItemRepository; @@ -88,6 +98,8 @@ public function __construct( $this->dataHelper = $dataHelper; $this->logger = $logger; $this->warrantyContractCreate = $warrantyContractCreate; + $this->orderItemCollectionFactory = $orderItemCollectionFactory; + } /** @@ -157,6 +169,16 @@ private function processBuyRequestLeadToken(OrderItemInterface $warrantyItem) $leadToken[] = $warrantyItem->getProductOptionByCode('info_buyRequest')['leadToken']; if (!empty($leadToken)) { $warrantyItem->setLeadToken(json_encode($leadToken)); + + // Set parent order id by finding an existing sales_order_item record with same lead_token and type not warranty + $orderItemCollectionCreateOrder = $this->orderItemCollectionFactory->create(); + $orderItemCollectionCreateOrder->addFieldToFilter('product_type', ['neq' => 'warranty']); + $orderItemCollectionCreateOrder->addFieldToFilter('lead_token', ['like' => '%'.str_replace('"', "", $leadToken[0]).'%' ] ); + $existingOrderItem = $orderItemCollectionCreateOrder->getFirstItem(); + if ($existingOrderItem && $existingOrderItem->getId()) { + $parentOrderId = $existingOrderItem->getOrderId(); + $warrantyItem->setExtendParentOrderId($parentOrderId); + } } } } catch (Exception $exception) { diff --git a/Plugin/Catalog/Helper/Product/Configuration/GetCustomOptionsPlugin.php b/Plugin/Catalog/Helper/Product/Configuration/GetCustomOptionsPlugin.php index dc8e8b76..4830b58a 100644 --- a/Plugin/Catalog/Helper/Product/Configuration/GetCustomOptionsPlugin.php +++ b/Plugin/Catalog/Helper/Product/Configuration/GetCustomOptionsPlugin.php @@ -13,6 +13,7 @@ use Magento\Catalog\Helper\Product\Configuration; use Magento\Catalog\Model\Product\Configuration\Item\ItemInterface; use Extend\Warranty\Model\Product\Type; +use Magento\Sales\Api\OrderRepositoryInterface; /** * Class GetCustomOptionsPlugin @@ -29,6 +30,23 @@ class GetCustomOptionsPlugin * @param ItemInterface $item * @return array */ + + /** + * @var OrderRepositoryInterface + */ + protected $orderRepository; + + /** + * Constructor + * + * @param OrderRepositoryInterface $orderRepository + */ + public function __construct(OrderRepositoryInterface $orderRepository) + { + $this->orderRepository = $orderRepository; + } + + public function afterGetCustomOptions(Configuration $subject, array $result, ItemInterface $item): array { $product = $item->getProduct(); @@ -64,6 +82,19 @@ public function afterGetCustomOptions(Configuration $subject, array $result, Ite ]; } + //Custom option parent order ID (this is displayed in the cart, so use Increment ID) + $parentOrderIdOption = $product->getCustomOption(Type::ASSOCIATED_PARENT_ORDER_ID); + if ($parentOrderIdOption && $parentOrderIdOption->getValue()) { + $parentOrderId = (int) $parentOrderIdOption->getValue(); + $order = $this->orderRepository->get($parentOrderId); + $incrementId = $order->getIncrementId(); + $parentOrderLabel = Type::PARENT_ORDER_LABEL; + $customOptions[] = [ + 'label' => __($parentOrderLabel), + 'value' => $incrementId, + ]; + } + $result = array_merge($result, $customOptions); } diff --git a/ViewModel/Warranty.php b/ViewModel/Warranty.php index a6486a34..9e0866aa 100644 --- a/ViewModel/Warranty.php +++ b/ViewModel/Warranty.php @@ -38,6 +38,7 @@ use Magento\Sales\Model\Order\Item; use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; +use Magento\Sales\Api\OrderRepositoryInterface; /** * Class Warranty @@ -128,6 +129,11 @@ class Warranty implements ArgumentInterface protected $helper; + /** + * @var OrderRepositoryInterface + */ + protected $orderRepository; + /** * Warranty constructor * @@ -144,6 +150,7 @@ class Warranty implements ArgumentInterface * @param AdminSession $adminSession * @param LeadInfo $leadInfo * @param WarrantyRelation $warrantyRelation + * @param OrderRepositoryInterface $orderRepository */ public function __construct( DataHelper $dataHelper, @@ -159,7 +166,8 @@ public function __construct( AdminSession $adminSession, LeadInfo $leadInfo, WarrantyRelation $warrantyRelation, - ExtendHelper $helper + ExtendHelper $helper, + OrderRepositoryInterface $orderRepository ) { $this->dataHelper = $dataHelper; @@ -176,6 +184,7 @@ public function __construct( $this->adminSession = $adminSession; $this->leadInfo = $leadInfo; $this->warrantyRelation = $warrantyRelation; + $this->orderRepository = $orderRepository; } /** @@ -399,7 +408,7 @@ public function itemHasLeadWarrantyInQuote($orderItem): bool $relationSku = $this->warrantyRelation->getOfferOrderItemSku($orderItem); return !empty($this->warrantyRelation->getWarrantyByRelationSku($relationSku)); } - + /** * Check does quote have warranty item for the item * Kept for backwards compatibility with Hyva module @@ -656,4 +665,14 @@ public function getProductInfo($product) : \Extend\Warranty\Model\Api\Request\ProductDataBuilder::NO_CATEGORY_DEFAULT_VALUE ]; } + + public function getOrderIncrementId($orderId = null){ + if ($orderId){ + $order = $this->orderRepository->get($orderId); + $incrementId = $order->getIncrementId(); + if ($incrementId){ + return $incrementId; + } + } + } } diff --git a/etc/db_schema.xml b/etc/db_schema.xml index 7b6c8d2d..d2041ca9 100644 --- a/etc/db_schema.xml +++ b/etc/db_schema.xml @@ -4,6 +4,7 @@ +
diff --git a/etc/extension_attributes.xml b/etc/extension_attributes.xml index 07d4c8f3..5ddfd02b 100644 --- a/etc/extension_attributes.xml +++ b/etc/extension_attributes.xml @@ -3,7 +3,7 @@ /** * Extend Warranty * - * @author Extend Magento Team + * @author Extend Magento Team * @category Extend * @package Warranty * @copyright Copyright (c) 2021 Extend Inc. (https://www.extend.com/) @@ -21,6 +21,7 @@ + diff --git a/view/adminhtml/templates/items/column/name.phtml b/view/adminhtml/templates/items/column/name.phtml index b89f9f13..df998396 100644 --- a/view/adminhtml/templates/items/column/name.phtml +++ b/view/adminhtml/templates/items/column/name.phtml @@ -37,7 +37,11 @@ use Magento\Framework\View\Helper\SecureHtmlRenderer; $_refunded = (isset($_productOptions["refund"]) && true == $_productOptions["refund"]) ? "-- All refunded --" : ''; - ; + + //retrieve Parent Order ID if present + $currentOrderId = $_item->getOrderId(); + $parentOrderId = isset($_productOptions["parent_order_id"]) ? $_productOptions["parent_order_id"] : null; + $incrementId = $parentOrderId ? $viewModel->getOrderIncrementId($parentOrderId) : null; ?>

@@ -48,6 +52,11 @@ use Magento\Framework\View\Helper\SecureHtmlRenderer; escapeHtml($_refunded); ?>
escapeHtml(__('Plan ID'))?>: + + + $currentOrderId) && $incrementId) :?> +

escapeHtml(__('Parent Order ID'))?>: +