Skip to content

Commit

Permalink
Add "Ready for Pickup" button on the Order page in Admin Panel which …
Browse files Browse the repository at this point in the history
…notifies Customer that Order could be picked up #2034.

Implemented synchronous email sending with custom email template for storepickup.
Added even more TODOs
  • Loading branch information
novikor committed Apr 1, 2019
1 parent 5fc0018 commit b695a48
Show file tree
Hide file tree
Showing 11 changed files with 363 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,58 @@ class NotifyOrderIsReadyAndShip implements NotifyOrderIsReadyAndShipInterface
*/
private $shipOrder;

/**
* @var \Magento\InventoryInStorePickup\Model\Order\Email\ReadyForPickupNotifier
*/
private $emailNotifier;

/**
* @var \Magento\Sales\Api\OrderRepositoryInterface
*/
private $orderRepository;

/**
* NotifyOrderIsReadyAndShip constructor.
*
* @param \Magento\InventoryInStorePickupApi\Api\IsOrderReadyForPickupInterface $isOrderReadyForPickup
* @param \Magento\Sales\Api\ShipOrderInterface $shipOrder
* @param \Magento\InventoryInStorePickupApi\Api\IsOrderReadyForPickupInterface $isOrderReadyForPickup
* @param \Magento\Sales\Api\ShipOrderInterface $shipOrder
* @param \Magento\InventoryInStorePickup\Model\Order\Email\ReadyForPickupNotifier $emailNotifier
* @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
*/
public function __construct(
IsOrderReadyForPickupInterface $isOrderReadyForPickup,
\Magento\Sales\Api\ShipOrderInterface $shipOrder
\Magento\Sales\Api\ShipOrderInterface $shipOrder,
Order\Email\ReadyForPickupNotifier $emailNotifier,
\Magento\Sales\Api\OrderRepositoryInterface $orderRepository
) {
$this->isOrderReadyForPickup = $isOrderReadyForPickup;
$this->shipOrder = $shipOrder;
$this->emailNotifier = $emailNotifier;
$this->orderRepository = $orderRepository;
}

/**
* {@inheritdoc}
*/
public function execute(int $orderId):int
public function execute(int $orderId):?int
{
if (!$this->isOrderReadyForPickup->execute($orderId)) {
throw new OrderIsNotReadyForPickupException();
}

/* TODO: send email */
$this->emailNotifier->notify($this->getOrder($orderId));
/* TODO: add order comment? */

return $this->shipOrder->execute($orderId);
return (int)$this->shipOrder->execute($orderId);
}

/**
* @param int $orderId
*
* @return \Magento\Sales\Api\Data\OrderInterface|\Magento\Sales\Model\Order
*/
private function getOrder(int $orderId)
{
return $this->orderRepository->get($orderId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\InventoryInStorePickup\Model\Order\Email\Container;

use Magento\Sales\Model\Order\Email\Container\Container;
use Magento\Sales\Model\Order\Email\Container\IdentityInterface;

class ReadyForPickupIdentity extends Container implements IdentityInterface
{
/**
* Configuration paths
*/
const XML_PATH_EMAIL_COPY_METHOD = 'storepickup_email/order_ready_for_pickup/copy_method';
const XML_PATH_EMAIL_COPY_TO = 'storepickup_email/order_ready_for_pickup/copy_to';
const XML_PATH_EMAIL_IDENTITY = 'storepickup_email/order_ready_for_pickup/identity';
const XML_PATH_EMAIL_GUEST_TEMPLATE = 'storepickup_email/order_ready_for_pickup/guest_template';
const XML_PATH_EMAIL_TEMPLATE = 'storepickup_email/order_ready_for_pickup/template';
const XML_PATH_EMAIL_ENABLED = 'storepickup_email/order_ready_for_pickup/enabled';

/**
* @return bool
*/
public function isEnabled()
{
return $this->scopeConfig->isSetFlag(
self::XML_PATH_EMAIL_ENABLED,
\Magento\Store\Model\ScopeInterface::SCOPE_STORE,
$this->getStore()->getStoreId()
);
}

/**
* Return email copy_to list
*
* @return array|bool
*/
public function getEmailCopyTo()
{
$data = $this->getConfigValue(self::XML_PATH_EMAIL_COPY_TO, $this->getStore()->getStoreId());
if (!empty($data)) {
return explode(',', $data);
}

return false;
}

/**
* Return copy method
*
* @return mixed
*/
public function getCopyMethod()
{
return $this->getConfigValue(self::XML_PATH_EMAIL_COPY_METHOD, $this->getStore()->getStoreId());
}

/**
* Return guest template id
*
* @return mixed
*/
public function getGuestTemplateId()
{
return $this->getConfigValue(self::XML_PATH_EMAIL_GUEST_TEMPLATE, $this->getStore()->getStoreId());
}

/**
* Return template id
*
* @return mixed
*/
public function getTemplateId()
{
return $this->getConfigValue(self::XML_PATH_EMAIL_TEMPLATE, $this->getStore()->getStoreId());
}

/**
* Return email identity
*
* @return mixed
*/
public function getEmailIdentity()
{
return $this->getConfigValue(self::XML_PATH_EMAIL_IDENTITY, $this->getStore()->getStoreId());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\InventoryInStorePickup\Model\Order\Email;

use Magento\Sales\Model\Order\Email\Sender\OrderSender;
use Magento\Sales\Model\ResourceModel\Order\Status\History\CollectionFactory;
use Psr\Log\LoggerInterface as Logger;

/**
* Class ReadyForPickupNotifier
*
* @package Magento\InventoryInStorePickup\Model\Order\Email
* TODO: probaly remove this class
*/
class ReadyForPickupNotifier extends \Magento\Sales\Model\AbstractNotifier
{
/**
* @var CollectionFactory
*/
protected $historyCollectionFactory;

/**
* @var \Psr\Log\LoggerInterface
*/
protected $logger;

/**
* @var OrderSender
*/
protected $sender;

/**
* @param CollectionFactory $historyCollectionFactory
* @param Logger $logger
* @param \Magento\InventoryInStorePickup\Model\Order\Email\ReadyForPickupSender $sender
*/
public function __construct(
CollectionFactory $historyCollectionFactory,
Logger $logger,
ReadyForPickupSender $sender
) {
$this->historyCollectionFactory = $historyCollectionFactory;
$this->logger = $logger;
$this->sender = $sender;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\InventoryInStorePickup\Model\Order\Email;

use Magento\Framework\DataObject;

/**
* Class ReadyForPickupSender
*
* @package Magento\InventoryInStorePickup\Model\Order\Email
* TODO: refactor
* TODO: Implement asynchronous email sending
*/
class ReadyForPickupSender extends \Magento\Sales\Model\Order\Email\Sender
{
/**
* @var \Magento\Framework\Event\ManagerInterface
*/
private $eventManager;

/**
* ReadyForPickupSender constructor.
*
* @param \Magento\Sales\Model\Order\Email\Container\Template $templateContainer
* @param \Magento\Sales\Model\Order\Email\Container\IdentityInterface $identityContainer
* @param \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory
* @param \Psr\Log\LoggerInterface $logger
* @param \Magento\Sales\Model\Order\Address\Renderer $addressRenderer
* @param \Magento\Framework\Event\ManagerInterface $eventManager
*/
public function __construct(
\Magento\Sales\Model\Order\Email\Container\Template $templateContainer,
\Magento\Sales\Model\Order\Email\Container\IdentityInterface $identityContainer,
\Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory,
\Psr\Log\LoggerInterface $logger,
\Magento\Sales\Model\Order\Address\Renderer $addressRenderer,
\Magento\Framework\Event\ManagerInterface $eventManager
) {
parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger, $addressRenderer);

$this->eventManager = $eventManager;
}

/**
* @param \Magento\Sales\Model\Order $order
*
* @return bool
*/
public function send(\Magento\Sales\Model\Order $order):bool
{
return $this->checkAndSend($order);
}

/**
* Prepare email template with variables
*
* @param \Magento\Sales\Model\ $order
*
* @return void
*/
protected function prepareTemplate(\Magento\Sales\Model\Order $order)
{
$transport = [
'order' => $order,
'store' => $order->getStore(),
'formattedShippingAddress' => $this->getFormattedShippingAddress($order),
];
$transportObject = new DataObject($transport);

/**
* Event argument `transport` is @deprecated. Use `transportObject` instead.
*/
$this->eventManager->dispatch(
'email_ready_for_pickup_set_template_vars_before',
['sender' => $this, 'transport' => $transportObject, 'transportObject' => $transportObject]
);

$this->templateContainer->setTemplateVars($transportObject->getData());

parent::prepareTemplate($order);
}

}
3 changes: 2 additions & 1 deletion app/code/Magento/InventoryInStorePickup/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"magento/framework": "*",
"magento/module-inventory-in-store-pickup-api": "*",
"magento/module-inventory-api": "*",
"magento/module-sales": "*"
"magento/module-sales": "*",
"magento/module-store": "*"
},
"type": "magento2-module",
"license": [
Expand Down
26 changes: 26 additions & 0 deletions app/code/Magento/InventoryInStorePickup/etc/config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<storepickup_email>
<order_ready_for_pickup>
<enabled>1</enabled>
<template>inventory_instorepickup_order_ready_for_pickup_template</template>
<guest_template>inventory_instorepickup_order_ready_for_pickup_template</guest_template>
<identity>storepickup</identity>
<copy_method>bcc</copy_method>
</order_ready_for_pickup>
</storepickup_email>
<trans_email>
<ident_storepickup>
<email>sales@example.com</email>
<name>Store pickup</name>
</ident_storepickup>
</trans_email>
</default>
</config>
6 changes: 5 additions & 1 deletion app/code/Magento/InventoryInStorePickup/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,9 @@
type="\Magento\InventoryInStorePickup\Model\NotifyOrderIsReadyAndShip"/>
<preference for="\Magento\InventoryInStorePickupApi\Api\IsOrderReadyForPickupInterface"
type="\Magento\InventoryInStorePickup\Model\IsOrderReadyForPickup"/>

<type name="\Magento\InventoryInStorePickup\Model\Order\Email\ReadyForPickupSender">
<arguments>
<argument name="identityContainer" xsi:type="object">\Magento\InventoryInStorePickup\Model\Order\Email\Container\ReadyForPickupIdentity</argument>
</arguments>
</type>
</config>
12 changes: 12 additions & 0 deletions app/code/Magento/InventoryInStorePickup/etc/email_templates.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Email:etc/email_templates.xsd">
<template id="inventory_instorepickup_order_ready_for_pickup_template" label="Order is Ready for Pickup"
file="order_ready_for_pickup.html" type="html" module="Magento_InventoryInStorePickup" area="frontend"
/>
</config>
1 change: 1 addition & 0 deletions app/code/Magento/InventoryInStorePickup/etc/module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<module name="Magento_Inventory"/>
<module name="Magento_InventoryInStorePickupApi"/>
<module name="Magento_Sales" />
<module name="Magento_Store" />
</sequence>
</module>
</config>
Loading

0 comments on commit b695a48

Please sign in to comment.