From 4ca679f1f6abb55e46b7d40f1b29441d6c1e8e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maksymilian=20Szyd=C5=82o?= Date: Sat, 24 Mar 2018 16:48:52 +0100 Subject: [PATCH] Add ability to set custom product option with negative price Modify option value validator to accept negative prices that don't exceed product's special/regular price --- .../Adminhtml/Product/Initialization/Helper.php | 1 + .../Option/Validator/DefaultValidator.php | 11 ++++++++++- .../Model/Product/Option/Validator/Select.php | 16 +++++++++++++--- .../Product/Form/Modifier/CustomOptions.php | 2 +- .../Catalog/view/base/web/js/price-options.js | 4 +++- 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index beb6f2b13bcfe..98f475b5932d7 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -461,6 +461,7 @@ private function fillProductOptions(Product $product, array $productOptions) } $customOption = $this->customOptionFactory->create(['data' => $customOptionData]); + $customOption->setProduct($product); $customOption->setProductSku($product->getSku()); $customOptions[] = $customOption; } diff --git a/app/code/Magento/Catalog/Model/Product/Option/Validator/DefaultValidator.php b/app/code/Magento/Catalog/Model/Product/Option/Validator/DefaultValidator.php index 1e5c7f76d829b..a6e57fea33976 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Validator/DefaultValidator.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Validator/DefaultValidator.php @@ -6,6 +6,7 @@ namespace Magento\Catalog\Model\Product\Option\Validator; +use Magento\Catalog\Model\Config\Source\ProductPriceOptionsInterface; use Magento\Catalog\Model\Product\Option; use Zend_Validate_Exception; @@ -132,7 +133,15 @@ protected function validateOptionType(Option $option) */ protected function validateOptionValue(Option $option) { - return $this->isInRange($option->getPriceType(), $this->priceTypes) && !$this->isNegative($option->getPrice()); + $productPrice = 0.0; + if ($option->getPriceType() === ProductPriceOptionsInterface::VALUE_PERCENT) { + $productPrice = 100.0; + } elseif ($option->getProduct()) { + $productPrice = $option->getProduct()->getSpecialPrice() ?: $option->getProduct()->getPrice(); + } + + return $this->isInRange($option->getPriceType(), $this->priceTypes) + && !$this->isNegative($productPrice + $option->getPrice()); } /** diff --git a/app/code/Magento/Catalog/Model/Product/Option/Validator/Select.php b/app/code/Magento/Catalog/Model/Product/Option/Validator/Select.php index f04ab497e1d4f..f99fbf91b58f9 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Validator/Select.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Validator/Select.php @@ -6,6 +6,7 @@ namespace Magento\Catalog\Model\Product\Option\Validator; +use Magento\Catalog\Model\Config\Source\ProductPriceOptionsInterface; use Magento\Catalog\Model\Product\Option; class Select extends DefaultValidator @@ -47,16 +48,25 @@ protected function validateOptionValue(Option $option) } $storeId = \Magento\Store\Model\Store::DEFAULT_STORE_ID; + $productPrice = 0.0; if ($option->getProduct()) { $storeId = $option->getProduct()->getStoreId(); + $productPrice = $option->getProduct()->getSpecialPrice() ?: $option->getProduct()->getPrice(); } foreach ($values as $value) { if (isset($value['is_delete']) && (bool)$value['is_delete']) { continue; } - $type = isset($value['price_type']) ? $value['price_type'] : null; - $price = isset($value['price']) ? $value['price'] : null; - $title = isset($value['title']) ? $value['title'] : null; + $type = $value['price_type'] ?? null; + $price = $value['price'] ?? 0.0; + $title = $value['title'] ?? null; + + if ($type === ProductPriceOptionsInterface::VALUE_PERCENT) { + $price += 100.0; + } else { + $price += $productPrice; + } + if (!$this->isValidOptionPrice($type, $price, $storeId) || !$this->isValidOptionTitle($title, $storeId) ) { diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php index 7196a721f1d02..e557c8a377681 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php @@ -923,7 +923,7 @@ protected function getPriceFieldConfig($sortOrder) 'addbeforePool' => $this->productOptionsPrice->prefixesToOptionArray(), 'sortOrder' => $sortOrder, 'validation' => [ - 'validate-zero-or-greater' => true + 'validate-number' => true ], ], ], diff --git a/app/code/Magento/Catalog/view/base/web/js/price-options.js b/app/code/Magento/Catalog/view/base/web/js/price-options.js index ceeea4c878622..e86f48c93aca8 100644 --- a/app/code/Magento/Catalog/view/base/web/js/price-options.js +++ b/app/code/Magento/Catalog/view/base/web/js/price-options.js @@ -20,8 +20,10 @@ define([ optionConfig: {}, optionHandlers: {}, optionTemplate: '<%= data.label %>' + - '<% if (data.finalPrice.value) { %>' + + '<% if (data.finalPrice.value > 0) { %>' + ' +<%- data.finalPrice.formatted %>' + + '<% } else if (data.finalPrice.value) { %>' + + ' <%- data.finalPrice.formatted %>' + '<% } %>', controlContainer: 'dd' };