Using Negative Values for the Product Quantity in Magento 2
Magento 2 includes this functionality. We can turn on the support for Qty field values which are less than 0 in Inventory Management Configuration. But there is one small catch. If the product quantity in Magento 2 is less than zero, the online shop administrator can’t edit and re-save this product. The following error will appear in the Qty field:
“Please enter a valid number in this field.”
You can find the description of this issue and the possible solution to it on GitHub. But you should know that it doesn’t work on the latest Magento versions (checked on Magento 2.1.7). We’ll cover the reason for this issues and the solution to it below.
The product editing form is implemented with UI-component. It is useful in case we need to perform customization with different modules. For example, the form is claimed in the Catalog module. However, Cataloginventory module handles the quantity management.
“Please enter a valid number in this field.”
You can find the description of this issue and the possible solution to it on GitHub. But you should know that it doesn’t work on the latest Magento versions (checked on Magento 2.1.7). We’ll cover the reason for this issues and the solution to it below.
The product editing form is implemented with UI-component. It is useful in case we need to perform customization with different modules. For example, the form is claimed in the Catalog module. However, Cataloginventory module handles the quantity management.
Cataloginventory Module for Product Quantity in Magento 2
It’s possible to implement customization with classes-modifiers. They fit into Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool virtual type with di.xml.If we take the Cataloginventory module, this modifier is claimed in the following way there:
<virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> <item name="advancedInventory" xsi:type="array"> <item name="class" xsi:type="string">Magento\CatalogInventory\Ui\DataProvider\Product\Form\Modifier\AdvancedInventory</item> <item name="sortOrder" xsi:type="number">20</item> </item> </argument> </arguments> </virtualType>
The modifier class should implement \Magento\Ui\DataProvider\Modifier\ModifierInterface which must create two methods: modifyData($data) and modifyMeta($meta).The component configuration is implemented in modifyMeta($meta) method, including its frontend part (javascript). In the solution from GitHub, the developer recommended turning off the digital validation with a custom modifier. We can implement it in the following way:
<virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> <item name="hf_quantity" xsi:type="array"> <item name="class" xsi:type="string">Web4pro\Defaultproduct\Ui\DataProvider\Product\Modifier\Quantity</item> <item name="sortOrder" xsi:type="number">10000000</item> </item> </argument> </arguments> </virtualType>class Quantity implements \Magento\Ui\DataProvider\Modifier\ModifierInterface { protected $arrayManager; public function __construct(\Magento\Framework\Stdlib\ArrayManager $arrayManager){ $this->arrayManager =$arrayManager; } public function modifyMeta(array $meta) { if ($path = $this->arrayManager->findPath('quantity_and_stock_status_qty', $meta, null, 'children')) { $this->arrayManager->remove( $path . '/children/qty/arguments/data/config/validation/validate-digits', $meta ); } if ($path = $this->arrayManager->findPath('advanced_inventory_modal', $meta)) { $meta = $this->arrayManager->merge( $path . '/children/stock_data/children/qty/arguments/data/config', $meta, ['validation' => ['validate-digits' => false]] ); } return $meta; } public function modifyData(array $data){ return $data; } }In the latest Magento versions (Magento 2.1.7) this code will not work. The reason is the following. Magento has the implementation of support for integers and fractions. For example, the fractions work in case of product drop-shipping by weight.
Solution for Product Quantity in Magento 2
Magento_CatalogInventory/js/components/qty-validator-changer component was implemented for the quantity validation. This is its code:define([ 'Magento_Ui/js/form/element/abstract' ], function (Abstract) { 'use strict'; return Abstract.extend({ defaults: { valueUpdate: 'input' }, /** * Change validator */ handleChanges: function (value) { var isDigits = value !== 1; this.validation['validate-number'] = !isDigits; this.validation['validate-digits'] = isDigits; this.validation['less-than-equals-to'] = isDigits ? 99999999 : 99999999.9999; this.validate(); } }); });
handleChanges method checks the configuration value transmitted to the component. If the integers are used for the quantity, we should apply validate-digits validator. If we deal with fractions, we should apply validate-number. So, it’s not enough to turn off the validate-digits validator. Wsoftpro also should set the needed value of handleChanges function’s parameter. It allows us to avoid choosing this validator by the other function.We describe this function’s parameter in Magento\CatalogInventory\Ui\DataProvider\Product\Form\Modifier\AdvancedInventory modifier in the following way:
... 'imports' => [ 'handleChanges' => '${$.provider}:data.product.stock_data.is_qty_decimal', ], …. As we can see, we can get its values in both cases, whether we use integers or fractions for quantity. We set that in the configuration. So, let’s implement modifyMeta($meta) method in our modifier: public function modifyMeta(array $meta) { if ($path = $this->arrayManager->findPath('quantity_and_stock_status_qty', $meta, null, 'children')) { $this->arrayManager->remove( $path . '/children/qty/arguments/data/config/validation/validate-digits', $meta ); $this->arrayManager->merge($path . '/children/qty/arguments/data/config/imports',$meta, array('handleChanges'=>"1")); } if ($path = $this->arrayManager->findPath('advanced_inventory_modal', $meta)) { $meta = $this->arrayManager->merge( $path . '/children/stock_data/children/qty/arguments/data/config', $meta, ['validation' => ['validate-digits' => false],'imports'=>['handleChanges'=>'1']] ); } return $meta; }
Finally, we have the next results:- we turned off the validate-digits validator;
- we set ‘handleChanges’ equal to 1.
As a result, the online store administrator will be able to save the products of which quantity is less than zero without any problems.
This case is new for Magento 2. We do everything possible to make your journey with Magento 2 easier. We are happy save your time. If you have any questions, or you need some help with Magento 2, contact us. We’ll take care of your project.
Give us some claps, if this story is useful for you, and, of course, don’t forget to share it with your friends :)
Nhận xét
Đăng nhận xét