Skip to content

Commit

Permalink
Merge pull request #16 from pimruiter/master
Browse files Browse the repository at this point in the history
Remove product from website if required attribute value is missing
  • Loading branch information
rbnmulder authored Apr 25, 2022
2 parents 26dc136 + e08a6ba commit bdf52e1
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 49 deletions.
129 changes: 129 additions & 0 deletions Plugin/CheckWebsiteAssociation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php

namespace JustBetter\AkeneoBundle\Plugin;

use Akeneo\Pim\ApiClient\Search\SearchBuilderFactory;
use Magento\Framework\DB\Select;
use Magento\Framework\DB\Statement\Pdo\Mysql;
use Magento\Framework\Serialize\SerializerInterface;
use Zend_Db_Expr as expression;
use Akeneo\Connector\Job\Product;
use Magento\Store\Model\ScopeInterface as scope;
use Akeneo\Connector\Helper\Store as StoreHelper;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Akeneo\Connector\Helper\Import\Product as ProductImportHelper;
use Akeneo\Connector\Helper\Config as ConfigHelper;
use Akeneo\Connector\Helper\Authenticator;

class CheckWebsiteAssociation
{
protected $entitiesHelper;
protected $storeHelper;
protected $config;
protected $serializer;

/**
* construct function
* @param ProductImportHelper $entitiesHelper
*/
public function __construct(
ProductImportHelper $entitiesHelper,
StoreHelper $storeHelper,
ScopeConfigInterface $config,
ConfigHelper $configHelper,
Authenticator $authenticator,
SearchBuilderFactory $searchBuilderFactory,
SerializerInterface $serializer
) {
$this->entitiesHelper = $entitiesHelper;
$this->storeHelper = $storeHelper;
$this->config = $config;
$this->configHelper = $configHelper;
$this->authenticator = $authenticator;
$this->searchBuilderFactory = $searchBuilderFactory;
$this->serializer = $serializer;
}

public function beforeSetWebsites(product $subject)
{
$connection = $this->entitiesHelper->getConnection();
/** @var string $tmpTable */
$tmpTable = $this->entitiesHelper->getTableName($subject->getCode());
$websiteAttribute = $this->configHelper->getWebsiteAttribute();
$websites = $this->storeHelper->getStores('website_code');
$websiteAssociation = $this->config->getValue('akeneo_connector/product/website_attribute');

$requiredAttributes = $this->getRequiredAttributes();

if ($connection->tableColumnExists($tmpTable, $websiteAttribute)) {
/** @var Select $select */
$select = $connection->select()->from(
$tmpTable
);
/** @var Mysql $query */
$query = $connection->query($select);
/** @var array $row */
while (($row = $query->fetch())) {

$mapping = $this->getMappedWebsiteChannels();

$websites = explode(',', $row[$websiteAssociation]);

foreach ($websites as $key => $website) {
$channel = $mapping[$website] ?? '';
if (empty($channel)) {
continue;
}

$locales = $this->storeHelper->getChannelStoreLangs($channel);
foreach ($requiredAttributes as $attribute) {
if (isset($attribute['localizable']) && $attribute['localizable'] === true) {
foreach ($locales as $locale) {
if (empty($row[$attribute['akeneo_attribute'] . '-' . $locale . '-' . $channel])) {
unset($websites[$key]);
break(2);
}
}
} else {
if (empty($row[$attribute])) {
unset($websites[$key]);
break(2);
}
}
}
}

$connection->update(
$tmpTable,
[
$websiteAssociation => implode(',', $websites),
],
['identifier = ?' => $row['identifier']]
);
}
}
return [$subject];
}

public function getMappedWebsiteChannels()
{
/** @var mixed[] $mapping */
$mapping = $this->configHelper->getWebsiteMapping();
/** @var string[] $channels */
$channels = array_column($mapping, 'channel', 'website');

return $channels;
}

public function getRequiredAttributes()
{
$requiredAttributes = $this->serializer->unserialize($this->config->getValue('akeneo_connector/product/required_attribute_mapping'));

foreach ($requiredAttributes as $key => &$requiredAttribute) {
$akeneoAttribute = $this->authenticator->getAkeneoApiClient()->getAttributeApi()->get($requiredAttribute['akeneo_attribute']);
$requiredAttribute['localizable'] = $akeneoAttribute['localizable'];
}

return $requiredAttributes;
}
}
137 changes: 91 additions & 46 deletions Plugin/SetTaxClassId.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,68 +4,53 @@

use Akeneo\Connector\Job\Product;
use Akeneo\Connector\Helper\Config;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Eav\Model\Config as EavConfig;
use Magento\Store\Model\ScopeInterface as scope;
use Akeneo\Connector\Helper\Authenticator;
use Akeneo\Connector\Helper\Store as StoreHelper;
use Akeneo\Connector\Helper\Config as ConfigHelper;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Akeneo\Connector\Helper\Import\Product as ProductImportHelper;
use Magento\Store\Model\ScopeInterface as scope;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Eav\Model\Config as EavConfig;

class SetTaxClassId
{
/**
* This variable contains a ProductImportHelper
*
* @var ProductImportHelper $entitiesHelper
*/
protected $entitiesHelper;

/**
* This variable contains a ConfigHelper
*
* @var ConfigHelper $configHelper
*/
protected $configHelper;

/**
* @var \Magento\Framework\App\Config\ScopeConfigInterface
*/
protected $scopeConfig;

/**
* column name of tax_id.
* @var string
*/
protected $tax_id_column;

/**
* @var Json
*/
protected $tax_id_columns;
protected $storeHelper;
protected $serializer;

/**
* @param ProductImportHelper $entitiesHelper
* @param Json $serializer
* @param ConfigHelper $configHelper
* @param ProductImportHelper $entitiesHelper
* @param StoreHelper $storeHelper
* @param Json $serializer
* @param ConfigHelper $configHelper
* @param Authenticator $authenticator
* @param ScopeConfigInterface $scopeConfig
* @param EavConfig $eavConfig
* @param EavConfig $eavConfig
*/
public function __construct(
ProductImportHelper $entitiesHelper,
StoreHelper $storeHelper,
Json $serializer,
ConfigHelper $configHelper,
Authenticator $authenticator,
ScopeConfigInterface $scopeConfig,
EavConfig $eavConfig
) {
$this->entitiesHelper = $entitiesHelper;
$this->storeHelper = $storeHelper;
$this->serializer = $serializer;
$this->configHelper = $configHelper;
$this->authenticator = $authenticator;
$this->scopeConfig = $scopeConfig;
$this->serializer = $serializer;
$this->eavConfig = $eavConfig;
}

/**
* Overwrite tax id with the one imported from Akeneo.
* Overwrite Magento Tax Class with the one from Akeneo.
*
* @param Product $context
*/
Expand All @@ -79,26 +64,41 @@ public function afterAddRequiredData(Product $context)
$attributes = $this->serializer->unserialize(
$this->scopeConfig->getValue(ConfigHelper::ATTRIBUTE_TYPES)
);

$mappings = $this->serializer->unserialize(
$this->scopeConfig->getValue('akeneo_connector/product/tax_id_mapping')
);

foreach ($attributes as $attribute) {
if ($attribute['magento_type'] === "tax") {
$this->tax_id_column = $attribute['pim_type'];
break;
$this->tax_id_columns[] = $attribute['pim_type'];
}
}

if (!$this->tax_id_column || !count($mappings)) {
if (!$this->tax_id_columns || !count($mappings)) {
return;
}

/** @var AdapterInterface $connection */
$connection = $this->entitiesHelper->getConnection();

/** @var string $tmpTable */
$tmpTable = $this->entitiesHelper->getTableName($context->getCode());
$connection->query($this->createQuery($this->tax_id_column, $tmpTable));

$this->tax_id_columns = $this->checkTaxColumnsExist($this->tax_id_columns, $tmpTable);

if (empty($this->tax_id_columns)) {
return;
}

foreach ($this->tax_id_columns as $tax_id_column) {
$taxQuery = $this->createQuery($tax_id_column, $tmpTable);
if (!$taxQuery) {
return;
}

$connection->query($taxQuery);
}
}

/**
Expand All @@ -110,7 +110,7 @@ public function afterAddRequiredData(Product $context)
*/
public function afterUpdateOption(Product $context)
{
if (!$this->tax_id_column) {
if (!$this->tax_id_columns) {
return;
}

Expand All @@ -119,7 +119,9 @@ public function afterUpdateOption(Product $context)
/** @var string $tmpTable */
$tmpTable = $this->entitiesHelper->getTableName($context->getCode());

$connection->query('UPDATE ' . $tmpTable . ' SET `' . $this->tax_id_column . '` = `_tax_class_id`;');
foreach ($this->tax_id_columns as $tax_id_column) {
$connection->query('UPDATE ' . $tmpTable . ' SET `' . $tax_id_column . '` = `_tax_class_id`;');
}
}

/**
Expand All @@ -139,7 +141,7 @@ public function createQuery($tax_id_column, $tableName)

$query = $this->addCase($query, $tax_id_column);

return $query;
return $query;
}

/**
Expand All @@ -152,12 +154,17 @@ public function createQuery($tax_id_column, $tableName)
*/
public function addCase($query, $tax_id_column)
{
$query .= "CASE
";

$mappings = $this->serializer->unserialize(
$this->scopeConfig->getValue('akeneo_connector/product/tax_id_mapping')
);

if (!count($mappings)) {
return $query;
}

$query .= "CASE
";

foreach ($mappings as $mapping) {
$query .= "WHEN `" . $tax_id_column . "` = '" . $mapping['akeneo'] . "' then '" . $mapping['magento'] . "'
";
Expand All @@ -166,7 +173,45 @@ public function addCase($query, $tax_id_column)
$query .= 'ELSE `_tax_class_id`
END';


return $query;
}

/**
* Check If the Tax Class is localizable and exist
*
* @param $mappings
* @param $tmpTable
* @return array
*/
public function checkTaxColumnsExist($mappings, $tmpTable)
{
$newMappings = [];

/** @var AdapterInterface $connection */
$connection = $this->entitiesHelper->getConnection();

foreach ($mappings as $key => $mapping) {

$akeneoAttribute = $this->authenticator->getAkeneoApiClient()->getAttributeApi()->get($mapping);

if($akeneoAttribute['localizable'] === false) {
if ($connection->tableColumnExists($tmpTable, $mapping)) {
$newMappings[] = $mapping;
}
}

if (isset($akeneoAttribute['localizable'])) {
$mappedChannels = $this->configHelper->getMappedChannels();
foreach ($mappedChannels as $key => $channel) {
foreach ($this->storeHelper->getChannelStoreLangs($channel) as $locale) {
if ($connection->tableColumnExists($tmpTable, $mapping . '-' . $locale . '-' . $channel)) {
$newMappings[] = $mapping . '-' . $locale . '-' . $channel;
}
}
}
}
}

return $newMappings;
}
}
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The following features are included in the JustBetter Akeneo Bundle extension:
| InsertNewProducts | Adds the possibility to disable insertion of new products from akeneo. |
| SetProductsActive | Adds the possibility to enable all products from akeneo. |
| EnableManageStock | Adds the possibility to enable manage stock for products from akeneo. |
| CheckWebsiteAssocation | Adds the possibility to unset the product website when one of the attributes is empty. For example when the Name attribute in Akeneo is empty for the associated website. |
| CategoryExist | Adds the possibility to skip inserting url paths when the category already exist. |
| SlackNotificationCommand | Adds the possibility to receive slack notifications about akeneo imports. |
| MailNotificationCommand | Adds the possibility to receive e-mail notifications about akeneo imports. |
Expand Down Expand Up @@ -40,7 +41,7 @@ akeneo_connector_import_finish_option
akeneo_connector_import_finish_product
```

These events are fired before the `cleanCache` function which only runs at the end of the job.
These events are fired before the `cleanCache` function which only runs at the end of the job.
That way the cache will still me flushed after your hook.

## Metric Units
Expand Down
Loading

0 comments on commit bdf52e1

Please sign in to comment.