diff --git a/app/code/Magento/InventorySalesAlert/Api/ProductIsSalableInterface.php b/app/code/Magento/InventorySalesAlert/Api/ProductIsSalableInterface.php
new file mode 100644
index 000000000000..db07a9d785c9
--- /dev/null
+++ b/app/code/Magento/InventorySalesAlert/Api/ProductIsSalableInterface.php
@@ -0,0 +1,34 @@
+stockItem = $stockItem ?: ObjectManager::getInstance()->get(IsProductInStock::class);
+ $this->stockResolver = $stockResolver ?: ObjectManager::getInstance()->get(StockResolver::class);
+ }
+
+
+ /**
+ * @param ProductInterface $product
+ *
+ * @return bool
+ */
+ public function isSalable(
+ ProductInterface $product,
+ string $websiteCode,
+ string $salesChannel = SalesChannelInterface::TYPE_WEBSITE
+ ): bool
+ {
+ $stock = $this->stockResolver->get($salesChannel, $websiteCode);
+ if ($stock->getId()) {
+ return $this->stockItem->execute($product->getSku(), (int) $stock->getStockId());
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/app/code/Magento/InventorySalesAlert/composer.json b/app/code/Magento/InventorySalesAlert/composer.json
new file mode 100644
index 000000000000..e870c3bac327
--- /dev/null
+++ b/app/code/Magento/InventorySalesAlert/composer.json
@@ -0,0 +1,42 @@
+{
+ "name": "magento/module-inventory-sales-alert",
+ "description": "",
+ "require": {
+ "php": "7.0.2|7.0.4|~7.0.6|~7.1.0",
+ "magento/framework": "100.3.*",
+ "magento/module-backend": "100.0.*",
+ "magento/module-catalog": "100.0.*",
+ "magento/module-catalog-inventory": "100.0.*",
+ "magento/module-inventory": "100.0.*",
+ "magento/module-inventory-api": "100.0.*",
+ "magento/module-inventory-catalog": "100.0.*",
+ "magento/module-inventory-sales-api": "100.0.*",
+ "magento/module-store": "100.3.*",
+ "magento/module-ui": "100.3.*",
+ "magento/magento-composer-installer": "*"
+ },
+ "suggest": {
+
+ },
+ "type": "magento2-module",
+ "version": "0.1.0",
+ "license": [
+
+ ],
+ "autoload": {
+ "files": [
+ "registration.php"
+ ],
+ "psr-4": {
+ "Magento\\InventorySalesAlert\\": ""
+ }
+ },
+ "extra": {
+ "map": [
+ [
+ "*",
+ "Magento/InventorySalesAlert"
+ ]
+ ]
+ }
+}
\ No newline at end of file
diff --git a/app/code/Magento/InventorySalesAlert/etc/di.xml b/app/code/Magento/InventorySalesAlert/etc/di.xml
new file mode 100644
index 000000000000..cc18447618d2
--- /dev/null
+++ b/app/code/Magento/InventorySalesAlert/etc/di.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/app/code/Magento/InventorySalesAlert/etc/module.xml b/app/code/Magento/InventorySalesAlert/etc/module.xml
new file mode 100644
index 000000000000..871eec000cd3
--- /dev/null
+++ b/app/code/Magento/InventorySalesAlert/etc/module.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/InventorySalesAlert/registration.php b/app/code/Magento/InventorySalesAlert/registration.php
new file mode 100644
index 000000000000..1868109415e4
--- /dev/null
+++ b/app/code/Magento/InventorySalesAlert/registration.php
@@ -0,0 +1,7 @@
+_catalogData = $catalogData;
- $this->_scopeConfig = $scopeConfig;
- $this->_storeManager = $storeManager;
- $this->_priceColFactory = $priceColFactory;
+ $this->catalogData = $catalogData;
+ $this->scopeConfig = $scopeConfig;
+ $this->storeManager = $storeManager;
+ $this->priceColFactory = $priceColFactory;
$this->customerRepository = $customerRepository;
- $this->productRepository = $productRepository;
- $this->_dateFactory = $dateFactory;
- $this->_stockColFactory = $stockColFactory;
- $this->_transportBuilder = $transportBuilder;
- $this->_emailFactory = $emailFactory;
- $this->inlineTranslation = $inlineTranslation;
+ $this->productRepository = $productRepository;
+ $this->dateFactory = $dateFactory;
+ $this->stockColFactory = $stockColFactory;
+ $this->transportBuilder = $transportBuilder;
+ $this->emailFactory = $emailFactory;
+ $this->inlineTranslation = $inlineTranslation;
+ $this->productIsSalable = $productIsSalable;
}
/**
@@ -161,27 +189,29 @@ public function __construct(
*/
protected function _getWebsites()
{
- if ($this->_websites === null) {
+ if ($this->websites === null) {
try {
- $this->_websites = $this->_storeManager->getWebsites();
+ $this->websites = $this->storeManager->getWebsites();
} catch (\Exception $e) {
- $this->_errors[] = $e->getMessage();
+ $this->errors[] = $e->getMessage();
throw $e;
}
}
- return $this->_websites;
+
+ return $this->websites;
}
/**
* Process price emails
*
* @param \Magento\ProductAlert\Model\Email $email
+ *
* @return $this
* @throws \Exception
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
- protected function _processPrice(\Magento\ProductAlert\Model\Email $email)
+ protected function _processPrice(Email $email): Observer
{
$email->setType('price');
foreach ($this->_getWebsites() as $website) {
@@ -189,20 +219,20 @@ protected function _processPrice(\Magento\ProductAlert\Model\Email $email)
if (!$website->getDefaultGroup() || !$website->getDefaultGroup()->getDefaultStore()) {
continue;
}
- if (!$this->_scopeConfig->getValue(
+ if (!$this->scopeConfig->getValue(
self::XML_PATH_PRICE_ALLOW,
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+ ScopeInterface::SCOPE_STORE,
$website->getDefaultGroup()->getDefaultStore()->getId()
)
) {
continue;
}
try {
- $collection = $this->_priceColFactory->create()->addWebsiteFilter(
+ $collection = $this->priceColFactory->create()->addWebsiteFilter(
$website->getId()
)->setCustomerOrder();
} catch (\Exception $e) {
- $this->_errors[] = $e->getMessage();
+ $this->errors[] = $e->getMessage();
throw $e;
}
@@ -234,18 +264,18 @@ protected function _processPrice(\Magento\ProductAlert\Model\Email $email)
$product->setCustomerGroupId($customer->getGroupId());
if ($alert->getPrice() > $product->getFinalPrice()) {
$productPrice = $product->getFinalPrice();
- $product->setFinalPrice($this->_catalogData->getTaxPrice($product, $productPrice));
- $product->setPrice($this->_catalogData->getTaxPrice($product, $product->getPrice()));
+ $product->setFinalPrice($this->catalogData->getTaxPrice($product, $productPrice));
+ $product->setPrice($this->catalogData->getTaxPrice($product, $product->getPrice()));
$email->addPriceProduct($product);
$alert->setPrice($productPrice);
- $alert->setLastSendDate($this->_dateFactory->create()->gmtDate());
+ $alert->setLastSendDate($this->dateFactory->create()->gmtDate());
$alert->setSendCount($alert->getSendCount() + 1);
$alert->setStatus(1);
$alert->save();
}
} catch (\Exception $e) {
- $this->_errors[] = $e->getMessage();
+ $this->errors[] = $e->getMessage();
throw $e;
}
}
@@ -253,11 +283,12 @@ protected function _processPrice(\Magento\ProductAlert\Model\Email $email)
try {
$email->send();
} catch (\Exception $e) {
- $this->_errors[] = $e->getMessage();
+ $this->errors[] = $e->getMessage();
throw $e;
}
}
}
+
return $this;
}
@@ -265,12 +296,13 @@ protected function _processPrice(\Magento\ProductAlert\Model\Email $email)
* Process stock emails
*
* @param \Magento\ProductAlert\Model\Email $email
+ *
* @return $this
* @throws \Exception
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
- protected function _processStock(\Magento\ProductAlert\Model\Email $email)
+ protected function _processStock(Email $email): Observer
{
$email->setType('stock');
@@ -280,22 +312,22 @@ protected function _processStock(\Magento\ProductAlert\Model\Email $email)
if (!$website->getDefaultGroup() || !$website->getDefaultGroup()->getDefaultStore()) {
continue;
}
- if (!$this->_scopeConfig->getValue(
+ if (!$this->scopeConfig->getValue(
self::XML_PATH_STOCK_ALLOW,
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+ ScopeInterface::SCOPE_STORE,
$website->getDefaultGroup()->getDefaultStore()->getId()
)
) {
continue;
}
try {
- $collection = $this->_stockColFactory->create()->addWebsiteFilter(
+ $collection = $this->stockColFactory->create()->addWebsiteFilter(
$website->getId()
)->addStatusFilter(
0
)->setCustomerOrder();
} catch (\Exception $e) {
- $this->_errors[] = $e->getMessage();
+ $this->errors[] = $e->getMessage();
throw $e;
}
@@ -326,16 +358,16 @@ protected function _processStock(\Magento\ProductAlert\Model\Email $email)
$product->setCustomerGroupId($customer->getGroupId());
- if ($product->isSalable()) {
+ if ($this->productIsSalable->isSalable($product, $website->getCode())) {
$email->addStockProduct($product);
- $alert->setSendDate($this->_dateFactory->create()->gmtDate());
+ $alert->setSendDate($this->dateFactory->create()->gmtDate());
$alert->setSendCount($alert->getSendCount() + 1);
$alert->setStatus(1);
$alert->save();
}
} catch (\Exception $e) {
- $this->_errors[] = $e->getMessage();
+ $this->errors[] = $e->getMessage();
throw $e;
}
}
@@ -344,7 +376,7 @@ protected function _processStock(\Magento\ProductAlert\Model\Email $email)
try {
$email->send();
} catch (\Exception $e) {
- $this->_errors[] = $e->getMessage();
+ $this->errors[] = $e->getMessage();
throw $e;
}
}
@@ -357,13 +389,14 @@ protected function _processStock(\Magento\ProductAlert\Model\Email $email)
* Send email to administrator if error
*
* @return $this
+ * @throws \Magento\Framework\Exception\MailException
*/
- protected function _sendErrorEmail()
+ protected function _sendErrorEmail(): Observer
{
- if (count($this->_errors)) {
- if (!$this->_scopeConfig->getValue(
+ if (count($this->errors)) {
+ if (!$this->scopeConfig->getValue(
self::XML_PATH_ERROR_TEMPLATE,
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+ ScopeInterface::SCOPE_STORE
)
) {
return $this;
@@ -371,35 +404,36 @@ protected function _sendErrorEmail()
$this->inlineTranslation->suspend();
- $transport = $this->_transportBuilder->setTemplateIdentifier(
- $this->_scopeConfig->getValue(
+ $transport = $this->transportBuilder->setTemplateIdentifier(
+ $this->scopeConfig->getValue(
self::XML_PATH_ERROR_TEMPLATE,
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+ ScopeInterface::SCOPE_STORE
)
)->setTemplateOptions(
[
- 'area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE,
- 'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
+ 'area' => FrontNameResolver::AREA_CODE,
+ 'store' => Store::DEFAULT_STORE_ID,
]
)->setTemplateVars(
- ['warnings' => join("\n", $this->_errors)]
+ ['warnings' => join("\n", $this->errors)]
)->setFrom(
- $this->_scopeConfig->getValue(
+ $this->scopeConfig->getValue(
self::XML_PATH_ERROR_IDENTITY,
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+ ScopeInterface::SCOPE_STORE
)
)->addTo(
- $this->_scopeConfig->getValue(
+ $this->scopeConfig->getValue(
self::XML_PATH_ERROR_RECIPIENT,
- \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+ ScopeInterface::SCOPE_STORE
)
)->getTransport();
$transport->sendMessage();
$this->inlineTranslation->resume();
- $this->_errors[] = [];
+ $this->errors[] = [];
}
+
return $this;
}
@@ -407,11 +441,13 @@ protected function _sendErrorEmail()
* Run process send product alerts
*
* @return $this
+ * @throws \Exception
+ * @throws \Magento\Framework\Exception\MailException
*/
public function process()
{
- /* @var $email \Magento\ProductAlert\Model\Email */
- $email = $this->_emailFactory->create();
+ /* @var $email Email */
+ $email = $this->emailFactory->create();
$this->_processPrice($email);
$this->_processStock($email);
$this->_sendErrorEmail();