1

I am trying to get the last quantity of the current product from the product view page bought by the logged in customer and display it with a button to add the same amount into the cart. It should only display it if the customer had bought it before and it is still in stock.

0

I created a small extension to do this. The only thing I didn't do was create the button. Instead, I exposed the SKU and Qty from the most recent order inside of the template that you create your button inside of. And that's all you need to create the button. And as a follow up to our convo on the other question, there are no class overrides. Actually, I didn't have to do any plugins, observers, or argument replacements. This is an example of just working within the main framework without anything to crazy.

Additionally:

  • If the last order contained more than one row of the same item, it sums them up so you get the true quantity
  • It checks to make sure customer is logged in
  • It checks to make sure the item is salable

Create these files exactly as you see below, just copy and paste and then of course ENABLE the module. You won't see anything until you have logged in and navigate to a product which you previous ordered with the logged in customer.

app/code/MageModule/Reorder/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="MageModule_Reorder" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Catalog"/>
            <module name="Magento_Customer"/>
        </sequence>
    </module>
</config>

app/code/MageModule/Reorder/composer.json

{
    "name": "magemodule/module-reorder",
    "type": "magento2-module",
    "description": "",
    "version": "1.0.0",
    "license": [
        "Commercial"
    ],
    "autoload": {
        "files": [
            "registration.php"
        ],
        "psr-4": {
            "MageModule\\Reorder\\": ""
        }
    }
}

app/code/MageModule/Reorder/registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'MageModule_Reorder',
    __DIR__
);

app/code/MageModule/Reorder/Block/Catalog/Product/View/Reorder.php

<?php

namespace MageModule\Reorder\Block\Catalog\Product\View;

class Reorder extends \Magento\Framework\View\Element\Template
{
    /**
     * @var \Magento\Customer\Model\Session
     */
    private $session;

    /**
     * @var \Magento\Framework\Registry
     */
    private $registry;

    /**
     * @var \MageModule\Reorder\Model\Customer\Product\LastOrder
     */
    private $lastOrder;

    /**
     * @var int|null
     */
    private $lastOrderQty;

    /**
     * Reorder constructor.
     *
     * @param \MageModule\Reorder\Model\Customer\Product\LastOrder $lastOrder
     * @param \Magento\Customer\Model\Session                      $session
     * @param \Magento\Framework\Registry                          $registry
     * @param \Magento\Framework\View\Element\Template\Context     $context
     * @param array                                                $data
     */
    public function __construct(
        \MageModule\Reorder\Model\Customer\Product\LastOrder $lastOrder,
        \Magento\Customer\Model\Session $session,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\View\Element\Template\Context $context,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->lastOrder = $lastOrder;
        $this->session = $session;
        $this->registry = $registry;
    }

    /**
     * @return bool
     */
    public function isLoggedIn()
    {
        return $this->session->isLoggedIn();
    }

    /**
     * @return \Magento\Customer\Model\Customer
     */
    public function getCustomer()
    {
        return $this->session->getCustomer();
    }

    /**
     * @return bool|null|\Magento\Catalog\Api\Data\ProductInterface|\Magento\Catalog\Model\Product
     */
    public function getProduct()
    {
        return $this->registry->registry('current_product');
    }

    /**
     * @return bool
     */
    public function isAvailable()
    {
        if ($this->getProduct() instanceof \Magento\Catalog\Model\Product) {
            return $this->getProduct()->isAvailable();
        }

        return false;
    }

    /**
     * @return float|int|null
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getQtyFromLastOrder()
    {
        if ($this->lastOrderQty === null) {
            $this->lastOrderQty = $this->lastOrder->getQty(
                $this->getCustomer()->getDataModel(),
                $this->getProduct()
            );
        }

        return $this->lastOrderQty;
    }
}

app/code/MageModule/Reorder/Model/Customer/Product/LastOrder.php

<?php

namespace MageModule\Reorder\Model\Customer\Product;

use Magento\Sales\Api\Data\OrderInterface;
use Magento\Sales\Api\Data\OrderItemInterface;

class LastOrder
{
    /**
     * @var \Magento\Sales\Model\ResourceModel\Order\CollectionFactory
     */
    private $collectionFactory;

    /**
     * @var \Magento\Sales\Model\ResourceModel\Order\Item
     */
    private $itemResource;

    /**
     * @var \Zend_Db_ExprFactory
     */
    private $zendDbExprFactory;

    /**
     * LastOrder constructor.
     *
     * @param \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $collectionFactory
     * @param \Magento\Sales\Model\ResourceModel\Order\Item              $itemResource
     * @param \Zend_Db_ExprFactory                                       $zendDbExprFactory
     */
    public function __construct(
        \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $collectionFactory,
        \Magento\Sales\Model\ResourceModel\Order\Item $itemResource,
        \Zend_Db_ExprFactory $zendDbExprFactory
    ) {
        $this->collectionFactory = $collectionFactory;
        $this->itemResource      = $itemResource;
        $this->zendDbExprFactory = $zendDbExprFactory;
    }

    /**
     * @param \Magento\Customer\Api\Data\CustomerInterface $customer
     * @param \Magento\Catalog\Api\Data\ProductInterface   $product
     *
     * @return int|float
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getQty(
        \Magento\Customer\Api\Data\CustomerInterface $customer,
        \Magento\Catalog\Api\Data\ProductInterface $product
    ) {
        /** @var \Magento\Sales\Model\ResourceModel\Order\Collection $collection */
        $collection = $this->collectionFactory->create($customer->getId());
        $collection->setOrder(OrderInterface::CREATED_AT, $collection::SORT_ORDER_DESC);
        $collection->join(
            ['item_table' => $this->itemResource->getMainTable()],
            'item_table.' . OrderItemInterface::ORDER_ID . ' = main_table.' . OrderInterface::ENTITY_ID,
            OrderItemInterface::QTY_ORDERED
        );
        $collection->addFieldToFilter('item_table.' . OrderItemInterface::SKU, $product->getSku());
        $collection->addFieldToFilter('item_table.' . OrderItemInterface::PARENT_ITEM_ID, ['null' => true]);
        $collection->getSelect()->columns(
            [
                'qty' => $this->zendDbExprFactory->create(
                    ['expression' => 'SUM(item_table.' . OrderItemInterface::QTY_ORDERED . ')']
                )
            ]
        );
        $collection->getSelect()->group('main_table.' . OrderInterface::ENTITY_ID);
        $collection->setPageSize(1);
        $order = $collection->fetchItem();

        if ($order instanceof OrderInterface) {
            return (float)$order->getData('qty');
        }

        return 0;
    }
}

app/code/MageModule/Reorder/view/frontend/layout/catalog_product_view.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <!-- You can place this block ANYWHERE on the page. I just chose alert.urls at random -->
        <referenceBlock name="alert.urls">
            <block class="MageModule\Reorder\Block\Catalog\Product\View\Reorder" name="reorder.addtocart" template="MageModule_Reorder::catalog/product/view/reorder/button.phtml" />
        </referenceBlock>
    </body>
</page>

app/code/MageModule/Reorder/view/frontend/templates/catalog/product/view/reorder/button.phtml

<?php /** @var \MageModule\Reorder\Block\Catalog\Product\View\Reorder $block */ ?>
<?php if ($block->isLoggedIn() && $block->isAvailable()) : ?>
    <?php $product = $block->getProduct(); ?>
    <?php $qty = $block->getQtyFromLastOrder(); ?>
    <?php
    /**
     *  Create your button here. With product and qty you have everything you need.
     */
    ?>
    <h3><?php echo 'Last Ordered SKU: ' .$product->getSku(); ?></h3>
    <h3><?php echo 'Last Ordered Qty: ' . $qty; ?></h3>
<?php endif; ?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.