diff --git a/Plugin/Directory/PriceCurrency.php b/Plugin/Directory/PriceCurrency.php new file mode 100644 index 0000000..3863645 --- /dev/null +++ b/Plugin/Directory/PriceCurrency.php @@ -0,0 +1,92 @@ +_storeManager->getStore()->getBaseCurrency()->getCode(); + $code = $this->getCurrencyCode(); + if ($baseCurrencyCode && isset($result['currencyCode']) && $result['currencyCode'] === $baseCurrencyCode) { + $code = $baseCurrencyCode; + } + + $config = $this->getFormatByCurrency($code); + + return (int) $config['decimal_number']; + } + + /** + * @param DirectoryPriceCurrency $subject + * @param callable $proceed + * @param float $price + * + * @return float + * @throws NoSuchEntityException + * @throws Zend_Currency_Exception + */ + public function aroundRound(DirectoryPriceCurrency $subject, callable $proceed, float $price): float + { + if (!$this->_helperData->isEnabled()) { + return $proceed($price); + } + + return round($price, $this->getPrecision()); + } + + /** + * @param DirectoryPriceCurrency $subject + * @param callable $proceed + * @param float $price + * @param int $precision + * + * @return float + * @throws NoSuchEntityException + * @throws Zend_Currency_Exception + */ + public function aroundRoundPrice( + DirectoryPriceCurrency $subject, + callable $proceed, + float $price, + int $precision + ): float { + if (!$this->_helperData->isEnabled()) { + return $proceed($price, $precision); + } + + return round($price, $this->getPrecision()); + } +} diff --git a/Ui/DataProvider/Product/Form/Modifier/Eav.php b/Ui/DataProvider/Product/Form/Modifier/Eav.php new file mode 100644 index 0000000..c278ea2 --- /dev/null +++ b/Ui/DataProvider/Product/Form/Modifier/Eav.php @@ -0,0 +1,484 @@ +locator = $locator; + $this->request = $request; + $this->storeManager = $storeManager; + $this->attributeGroupRepository = $attributeGroupRepository; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->attributeRepository = $attributeRepository; + $this->sortOrderBuilder = $sortOrderBuilder; + $this->scopeOverriddenValue = $scopeOverriddenValue; + $this->dataPersistor = $dataPersistor; + $this->data = $data; + $this->_localeCurrency = $_localeCurrency; + $this->attributeCollectionFactory = $attributeCollectionFactory + ?: ObjectManager::getInstance()->get(AttributeCollectionFactory::class); + } + + /** + * @param array $data + * @return array + * @throws NoSuchEntityException + * @throws \Zend_Currency_Exception + */ + public function modifyData(array $data) + { + if (!$this->locator->getProduct()->getId() && $this->dataPersistor->get('catalog_product')) { + return $this->resolvePersistentData($data); + } + + $productId = $this->locator->getProduct()->getId(); + + /** @var string $groupCode */ + foreach (array_keys($this->getGroups()) as $groupCode) { + /** @var ProductAttributeInterface[] $attributes */ + $attributes = !empty($this->getAttributes()[$groupCode]) ? $this->getAttributes()[$groupCode] : []; + + foreach ($attributes as $attribute) { + if (null !== ($attributeValue = $this->setupAttributeData($attribute))) { + if ($this->isPriceAttribute($attribute, $attributeValue)) { + $attributeValue = $this->formatPrice($attributeValue); + } + $data[$productId][self::DATA_SOURCE_DEFAULT][$attribute->getAttributeCode()] = $attributeValue; + } + } + } + + return $data; + } + + /** + * @param $value + * @return mixed + * @throws NoSuchEntityException + * @throws \Zend_Currency_Exception + */ + protected function formatPrice($value) + { + $currency = $this->storeManager->getStore()->getCurrentCurrency()->getCode(); + $config = $this->getFormatByCurrency($currency, $this->getStoreId()); + $decimal = (int) $config['decimal_number']; + + $options['precision'] = $decimal; + $options['display'] = Zend_Currency::NO_SYMBOL; + $firstResult = $this->_localeCurrency->getCurrency($currency)->toCurrency($value, $options); + + return $firstResult; + } + + /** + * @param string $currencyCode + * @param null $storeId + * + * @return mixed + * @throws NoSuchEntityException + */ + public function getFormatByCurrency($currencyCode, $storeId = null) + { + $storeId = ($storeId === null) ? $this->getStoreId() : $storeId; + + return $this->data->getCurrencyConfig($currencyCode, $storeId); + } + + /** + * @return int + * @throws NoSuchEntityException + */ + public function getStoreId() + { + return $this->storeManager->getStore()->getId(); + } + + /** + * @param ProductAttributeInterface $attribute + * @param $attributeValue + * @return bool + */ + private function isPriceAttribute(ProductAttributeInterface $attribute, $attributeValue) + { + return $attribute->getFrontendInput() === 'price' + && is_scalar($attributeValue) + && !$this->isBundleSpecialPrice($attribute); + } + + /** + * @param ProductAttributeInterface $attribute + * @return bool + */ + private function isBundleSpecialPrice(ProductAttributeInterface $attribute) + { + return $this->locator->getProduct()->getTypeId() === ProductType::TYPE_BUNDLE + && $attribute->getAttributeCode() === ProductAttributeInterface::CODE_SPECIAL_PRICE; + } + + /** + * @param ProductAttributeInterface $attribute + * @return mixed|null + */ + public function setupAttributeData(ProductAttributeInterface $attribute) + { + $product = $this->locator->getProduct(); + $productId = $product->getId(); + $prevSetId = $this->getPreviousSetId(); + $notUsed = !$prevSetId + || ($prevSetId && !in_array($attribute->getAttributeCode(), $this->getPreviousSetAttributes())); + + if ($productId && $notUsed) { + return $this->getValue($attribute); + } + + return null; + } + + /** + * @param ProductAttributeInterface $attribute + * @return mixed|null + */ + private function getValue(ProductAttributeInterface $attribute) + { + /** @var Product $product */ + $product = $this->locator->getProduct(); + + return $product->getData($attribute->getAttributeCode()); + } + + /** + * @return array + */ + private function getPreviousSetAttributes() + { + if ($this->prevSetAttributes === null) { + $searchCriteria = $this->searchCriteriaBuilder + ->addFilter('attribute_set_id', $this->getPreviousSetId()) + ->create(); + $attributes = $this->attributeRepository->getList($searchCriteria)->getItems(); + $this->prevSetAttributes = []; + foreach ($attributes as $attribute) { + $this->prevSetAttributes[] = $attribute->getAttributeCode(); + } + } + + return $this->prevSetAttributes; + } + + /** + * @return int + */ + private function getPreviousSetId() + { + return (int)$this->request->getParam('prev_set_id', 0); + } + + /** + * @param array $data + * @return array + */ + private function resolvePersistentData(array $data) + { + $persistentData = (array)$this->dataPersistor->get('catalog_product'); + $this->dataPersistor->clear('catalog_product'); + $productId = $this->locator->getProduct()->getId(); + + if (empty($data[$productId][self::DATA_SOURCE_DEFAULT])) { + $data[$productId][self::DATA_SOURCE_DEFAULT] = []; + } + + $data[$productId] = array_replace_recursive( + $data[$productId][self::DATA_SOURCE_DEFAULT], + $persistentData + ); + + return $data; + } + + /** + * @return AttributeGroupInterface[] + * @throws NoSuchEntityException + */ + private function getGroups() + { + if (!$this->attributeGroups) { + $searchCriteria = $this->prepareGroupSearchCriteria()->create(); + $attributeGroupSearchResult = $this->attributeGroupRepository->getList($searchCriteria); + foreach ($attributeGroupSearchResult->getItems() as $group) { + $this->attributeGroups[$this->calculateGroupCode($group)] = $group; + } + } + + return $this->attributeGroups; + } + + /** + * @return SearchCriteriaBuilder + */ + private function prepareGroupSearchCriteria() + { + return $this->searchCriteriaBuilder->addFilter( + AttributeGroupInterface::ATTRIBUTE_SET_ID, + $this->getAttributeSetId() + ); + } + + /** + * Return current attribute set id + * + * @return int|null + */ + private function getAttributeSetId() + { + return $this->locator->getProduct()->getAttributeSetId(); + } + + /** + * @param AttributeGroupInterface $group + * @return string + */ + private function calculateGroupCode(AttributeGroupInterface $group) + { + $attributeGroupCode = $group->getAttributeGroupCode(); + + if ($attributeGroupCode === 'images') { + $attributeGroupCode = 'image-management'; + } + + return $attributeGroupCode; + } + + /** + * @return ProductAttributeInterface[]|EavAttribute[] + * @throws NoSuchEntityException + */ + private function getAttributes() + { + if (!$this->attributes) { + $this->attributes = $this->loadAttributesForGroups($this->getGroups()); + } + + return $this->attributes; + } + + /** + * @param array $groups + * @return array + */ + private function loadAttributesForGroups(array $groups) + { + $attributes = []; + $groupIds = []; + + foreach ($groups as $group) { + $groupIds[$group->getAttributeGroupId()] = $this->calculateGroupCode($group); + $attributes[$this->calculateGroupCode($group)] = []; + } + + $collection = $this->attributeCollectionFactory->create(); + $collection->setAttributeGroupFilter(array_keys($groupIds)); + + $mapAttributeToGroup = []; + + foreach ($collection->getItems() as $attribute) { + $mapAttributeToGroup[$attribute->getAttributeId()] = $attribute->getAttributeGroupId(); + } + + $sortOrder = $this->sortOrderBuilder + ->setField('sort_order') + ->setAscendingDirection() + ->create(); + + $searchCriteria = $this->searchCriteriaBuilder + ->addFilter(AttributeGroupInterface::GROUP_ID, array_keys($groupIds), 'in') + ->addFilter(ProductAttributeInterface::IS_VISIBLE, 1) + ->addSortOrder($sortOrder) + ->create(); + + $groupAttributes = $this->attributeRepository->getList($searchCriteria)->getItems(); + + $productType = $this->getProductType(); + + foreach ($groupAttributes as $attribute) { + $applyTo = $attribute->getApplyTo(); + $isRelated = !$applyTo || in_array($productType, $applyTo); + if ($isRelated) { + $attributeGroupId = $mapAttributeToGroup[$attribute->getAttributeId()]; + $attributeGroupCode = $groupIds[$attributeGroupId]; + $attributes[$attributeGroupCode][] = $attribute; + } + } + + return $attributes; + } + + /** + * Get product type + * + * @return null|string + */ + private function getProductType() + { + return (string)$this->request->getParam('type', $this->locator->getProduct()->getTypeId()); + } + + /** + * @param array $meta + * @return array + */ + public function modifyMeta(array $meta) + { + return $meta; + } +} diff --git a/composer.json b/composer.json index 559fbf8..7e06e3b 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "mageplaza/module-core": "^1.4.4" }, "type": "magento2-module", - "version": "1.0.4", + "version": "1.0.5", "license": "proprietary", "authors": [ { diff --git a/etc/adminhtml/di.xml b/etc/adminhtml/di.xml new file mode 100644 index 0000000..be2f48b --- /dev/null +++ b/etc/adminhtml/di.xml @@ -0,0 +1,34 @@ + + + + + + + + Mageplaza\CurrencyFormatter\Ui\DataProvider\Product\Form\Modifier\Eav + 11 + + + + + diff --git a/etc/di.xml b/etc/di.xml index eed47f1..f80b1b5 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -27,6 +27,9 @@ + + +