From 4f4a1d816ea7c12a8adb8abcdedd37bef040de29 Mon Sep 17 00:00:00 2001
From: Henning Leutz <leutz@pcsg.de>
Date: Fri, 8 Sep 2023 10:10:49 +0200
Subject: [PATCH] fix: quiqqer/shipping#50

---
 ajax/backend/update.php                       |   6 +-
 .../controls/shippingRules/CreateRule.html    |  14 +-
 .../controls/shippingRules/CreateRule.js      | 144 +++++++++---------
 src/QUI/ERP/Shipping/Rules/Factory.php        |  36 +++--
 4 files changed, 110 insertions(+), 90 deletions(-)

diff --git a/ajax/backend/update.php b/ajax/backend/update.php
index eb5f371..d47f2ab 100644
--- a/ajax/backend/update.php
+++ b/ajax/backend/update.php
@@ -18,7 +18,7 @@ function ($shippingId, $data) {
         $Factory = new Factory();
         $ShippingEntry = $Factory->getChild($shippingId);
 
-        $data = \json_decode($data, true);
+        $data = json_decode($data, true);
 
         $ShippingEntry->setAttributes($data);
 
@@ -42,9 +42,9 @@ function ($shippingId, $data) {
         }
 
         if (isset($data['shipping_rules'])) {
-            $shipping = \json_decode($data['shipping_rules'], true);
+            $shipping = json_decode($data['shipping_rules'], true);
 
-            if (!\is_array($shipping)) {
+            if (!is_array($shipping)) {
                 $shipping = [];
             }
 
diff --git a/bin/backend/controls/shippingRules/CreateRule.html b/bin/backend/controls/shippingRules/CreateRule.html
index b79da15..99945a9 100644
--- a/bin/backend/controls/shippingRules/CreateRule.html
+++ b/bin/backend/controls/shippingRules/CreateRule.html
@@ -46,7 +46,7 @@
                     </span>
                     <span class="field-container-field field-container-field-no-padding">
                         <select name="discount_type" class="field-container-field"
-                                style="width: 40%"
+                                style="width: 100%"
                         >
                             <option value="ABS">
                                 {{discountAbsolute}}
@@ -58,11 +58,13 @@
                                 {{discountPercentageOrder}}
                             </option>
                         </select>
-                        <input type="number"
-                               name="discount"
-                               class="field-container-field"
-                               style="width: 59%"
-                        />
+                        <span style="border-top: 1px solid rgba(147, 128, 108, 0.25)">
+                            <input type="number"
+                                   step="0.01"
+                                   name="discount"
+                                   data-qui="package/quiqqer/erp/bin/backend/controls/elements/PriceCalcInput"
+                            />
+                        </span>
                     </span>
                 </label>
             </td>
diff --git a/bin/backend/controls/shippingRules/CreateRule.js b/bin/backend/controls/shippingRules/CreateRule.js
index fb771fc..9660b6a 100644
--- a/bin/backend/controls/shippingRules/CreateRule.js
+++ b/bin/backend/controls/shippingRules/CreateRule.js
@@ -19,25 +19,26 @@ define('package/quiqqer/shipping/bin/backend/controls/shippingRules/CreateRule',
     'text!package/quiqqer/shipping/bin/backend/controls/shippingRules/RuleUnit.html',
     'css!package/quiqqer/shipping/bin/backend/controls/shippingRules/Rule.css'
 
-], function (QUI, QUIControl, Translator, TranslateUpdater, InputMultiLang, Fields,
-             ShippingRules, FormUtils, QUILocale, Mustache, template, templateUnit) {
-    "use strict";
+], function(QUI, QUIControl, Translator, TranslateUpdater, InputMultiLang, Fields,
+    ShippingRules, FormUtils, QUILocale, Mustache, template, templateUnit
+) {
+    'use strict';
 
-    var lg = 'quiqqer/shipping';
+    const lg = 'quiqqer/shipping';
 
     return new Class({
 
         Extends: QUIControl,
-        Type   : 'package/quiqqer/shipping/bin/backend/controls/shippingRules/CreateRule',
+        Type: 'package/quiqqer/shipping/bin/backend/controls/shippingRules/CreateRule',
 
         Binds: [
             '$onInject'
         ],
 
-        initialize: function (options) {
+        initialize: function(options) {
             this.parent(options);
 
-            this.$DataTitle        = null;
+            this.$DataTitle = null;
             this.$DataWorkingTitle = null;
 
             this.addEvents({
@@ -50,65 +51,72 @@ define('package/quiqqer/shipping/bin/backend/controls/shippingRules/CreateRule',
          *
          * @return {HTMLDivElement}
          */
-        create: function () {
+        create: function() {
             this.$Elm = this.parent();
             this.$Elm.addClass('quiqqer-shipping-rule-create');
 
             this.$Elm.set('html', Mustache.render(template, {
-                generalHeader           : QUILocale.get(lg, 'shipping.edit.template.general'),
-                title                   : QUILocale.get(lg, 'shipping.edit.template.title'),
-                workingTitle            : QUILocale.get('quiqqer/system', 'workingtitle'),
-                calculationPriority     : QUILocale.get(lg, 'shipping.edit.template.calculationPriority'),
-                discountTitle           : QUILocale.get(lg, 'shipping.edit.template.discount'),
-                discountDescription     : QUILocale.get(lg, 'shipping.edit.template.discount.description'),
-                discountAbsolute        : QUILocale.get(lg, 'shipping.edit.template.discount.absolute'),
-                discountPercentage      : QUILocale.get(lg, 'shipping.edit.template.discount.percentage'),
-                discountPercentageOrder : QUILocale.get(lg, 'shipping.edit.template.discount.percentageOrder'),
-                statusTitle             : QUILocale.get(lg, 'shipping.edit.template.status'),
-                statusDescription       : QUILocale.get(lg, 'shipping.edit.template.status.description'),
-                noRulesTitle            : QUILocale.get(lg, 'shipping.edit.template.noRules'),
-                noRulesText             : QUILocale.get(lg, 'shipping.edit.template.noRules.text'),
-                unitTitle               : QUILocale.get(lg, 'shipping.edit.template.unit'),
-                unitHeader              : QUILocale.get(lg, 'shipping.edit.template.unitTitle'),
-                usageHeader             : QUILocale.get(lg, 'shipping.edit.template.usage'),
-                usageFrom               : QUILocale.get(lg, 'shipping.edit.template.usage.from'),
-                usageTo                 : QUILocale.get(lg, 'shipping.edit.template.usage.to'),
-                usageAmountOf           : QUILocale.get(lg, 'shipping.edit.template.shopping.amount.of'),
-                usageAmountTo           : QUILocale.get(lg, 'shipping.edit.template.shopping.amount.to'),
-                usageValueOf            : QUILocale.get(lg, 'shipping.edit.template.purchase.value.of'),
-                usageValueTo            : QUILocale.get(lg, 'shipping.edit.template.purchase.value.to'),
-                usageAssignmentUser     : QUILocale.get(lg, 'shipping.edit.template.assignment.user'),
-                usageAssignmentProduct  : QUILocale.get(lg, 'shipping.edit.template.assignment.product'),
-                usageAssignmentCategory : QUILocale.get(lg, 'shipping.edit.template.assignment.category'),
-                usageAssignmentArea     : QUILocale.get(lg, 'shipping.edit.template.assignment.areas'),
-
-                productHeader                 : QUILocale.get(lg, 'shipping.edit.template.assignment.product.header'),
-                usageAssignmentProductOnly    : QUILocale.get(lg, 'shipping.edit.template.assignment.product.only'),
-                usageAssignmentProductOnlyText: QUILocale.get(lg, 'shipping.edit.template.assignment.product.only.text'),
+                generalHeader: QUILocale.get(lg, 'shipping.edit.template.general'),
+                title: QUILocale.get(lg, 'shipping.edit.template.title'),
+                workingTitle: QUILocale.get('quiqqer/system', 'workingtitle'),
+                calculationPriority: QUILocale.get(lg, 'shipping.edit.template.calculationPriority'),
+                discountTitle: QUILocale.get(lg, 'shipping.edit.template.discount'),
+                discountDescription: QUILocale.get(lg, 'shipping.edit.template.discount.description'),
+                discountAbsolute: QUILocale.get(lg, 'shipping.edit.template.discount.absolute'),
+                discountPercentage: QUILocale.get(lg, 'shipping.edit.template.discount.percentage'),
+                discountPercentageOrder: QUILocale.get(lg, 'shipping.edit.template.discount.percentageOrder'),
+                statusTitle: QUILocale.get(lg, 'shipping.edit.template.status'),
+                statusDescription: QUILocale.get(lg, 'shipping.edit.template.status.description'),
+                noRulesTitle: QUILocale.get(lg, 'shipping.edit.template.noRules'),
+                noRulesText: QUILocale.get(lg, 'shipping.edit.template.noRules.text'),
+                unitTitle: QUILocale.get(lg, 'shipping.edit.template.unit'),
+                unitHeader: QUILocale.get(lg, 'shipping.edit.template.unitTitle'),
+                usageHeader: QUILocale.get(lg, 'shipping.edit.template.usage'),
+                usageFrom: QUILocale.get(lg, 'shipping.edit.template.usage.from'),
+                usageTo: QUILocale.get(lg, 'shipping.edit.template.usage.to'),
+                usageAmountOf: QUILocale.get(lg, 'shipping.edit.template.shopping.amount.of'),
+                usageAmountTo: QUILocale.get(lg, 'shipping.edit.template.shopping.amount.to'),
+                usageValueOf: QUILocale.get(lg, 'shipping.edit.template.purchase.value.of'),
+                usageValueTo: QUILocale.get(lg, 'shipping.edit.template.purchase.value.to'),
+                usageAssignmentUser: QUILocale.get(lg, 'shipping.edit.template.assignment.user'),
+                usageAssignmentProduct: QUILocale.get(lg, 'shipping.edit.template.assignment.product'),
+                usageAssignmentCategory: QUILocale.get(lg, 'shipping.edit.template.assignment.category'),
+                usageAssignmentArea: QUILocale.get(lg, 'shipping.edit.template.assignment.areas'),
+
+                productHeader: QUILocale.get(lg, 'shipping.edit.template.assignment.product.header'),
+                usageAssignmentProductOnly: QUILocale.get(lg, 'shipping.edit.template.assignment.product.only'),
+                usageAssignmentProductOnlyText: QUILocale.get(
+                    lg,
+                    'shipping.edit.template.assignment.product.only.text'
+                ),
                 usageAssignmentProductOnlyDesc: QUILocale.get(lg, 'shipping.edit.template.assignment.product.only.desc')
             }));
 
+            this.$Elm.getElement('form').addEvent('submit', (e) => {
+                e.stop();
+            });
+
             return this.$Elm;
         },
 
         /**
          * event: on inject
          */
-        $onInject: function () {
-            var self    = this,
+        $onInject: function() {
+            const self = this,
                 current = QUILocale.getCurrent();
 
-            var getOptions = function (field) {
-                var entries = field.options.entries,
-                    result  = [];
+            const getOptions = function(field) {
+                const entries = field.options.entries,
+                    result = [];
 
-                for (var i in entries) {
+                for (const i in entries) {
                     if (!entries.hasOwnProperty(i)) {
                         continue;
                     }
 
                     result.push({
-                        key  : i,
+                        key: i,
                         title: entries[i].title[current]
                     });
                 }
@@ -116,21 +124,21 @@ define('package/quiqqer/shipping/bin/backend/controls/shippingRules/CreateRule',
                 return result;
             };
 
-            ShippingRules.getShippingRuleUnitFields().then(function (unitFields) {
-                var i, len, html, field;
+            ShippingRules.getShippingRuleUnitFields().then(function(unitFields) {
+                let i, len, html, field;
 
-                var Table = self.getElm().getElement('.unit-table'),
+                const Table = self.getElm().getElement('.unit-table'),
                     Tbody = Table.getElement('tbody');
 
                 Tbody.set('html', '');
 
                 for (i = 0, len = unitFields.length; i < len; i++) {
                     field = unitFields[i];
-                    html  = Mustache.render(templateUnit, {
+                    html = Mustache.render(templateUnit, {
                         andText: QUILocale.get(lg, 'shipping.edit.template.and'),
                         options: getOptions(field),
-                        id     : field.id,
-                        title  : field.title
+                        id: field.id,
+                        title: field.title
                     });
 
                     new Element('tr', {
@@ -140,11 +148,11 @@ define('package/quiqqer/shipping/bin/backend/controls/shippingRules/CreateRule',
 
                 Tbody.getElements('select').set('disabled', false);
                 Tbody.getElements('input').set('disabled', false);
-            }).then(function () {
+            }).then(function() {
                 return QUI.parse(self.getElm());
-            }).then(function () {
+            }).then(function() {
                 // locale for title and working title
-                self.$DataTitle        = new InputMultiLang().replaces(self.$Elm.getElement('.shipping-title'));
+                self.$DataTitle = new InputMultiLang().replaces(self.$Elm.getElement('.shipping-title'));
                 self.$DataWorkingTitle = new InputMultiLang().replaces(self.$Elm.getElement('.shipping-workingTitle'));
 
                 this.fireEvent('load', [this]);
@@ -156,37 +164,37 @@ define('package/quiqqer/shipping/bin/backend/controls/shippingRules/CreateRule',
          *
          * @return {Promise}
          */
-        submit: function () {
+        submit: function() {
             if (!this.$DataTitle || !this.$DataWorkingTitle) {
                 return Promise.reject('Missing DOMNode Elements');
             }
 
-            var formData = FormUtils.getFormData(this.getElm().getElement('form'));
+            const formData = FormUtils.getFormData(this.getElm().getElement('form'));
 
-            formData.title        = this.$DataTitle.getData();
+            formData.title = this.$DataTitle.getData();
             formData.workingTitle = this.$DataWorkingTitle.getData();
 
-            var i, len, Unit, Term, Term2, Value, Value2, Label;
+            let i, len, Unit, Term, Term2, Value, Value2, Label;
 
-            var unitData = [];
-            var UnitRows = this.getElm().getElements('.unit-table td');
+            const unitData = [];
+            const UnitRows = this.getElm().getElements('.unit-table td');
 
             for (i = 0, len = UnitRows.length; i < len; i++) {
-                Unit  = UnitRows[i].getElement('[name="unit"]');
-                Term  = UnitRows[i].getElement('[name="term"]');
+                Unit = UnitRows[i].getElement('[name="unit"]');
+                Term = UnitRows[i].getElement('[name="term"]');
                 Value = UnitRows[i].getElement('[name="value"]');
                 Label = UnitRows[i].getElement('label');
 
-                Term2  = UnitRows[i].getElement('[name="term"]');
+                Term2 = UnitRows[i].getElement('[name="term"]');
                 Value2 = UnitRows[i].getElement('[name="value"]');
 
                 unitData.push({
-                    id    : parseInt(Label.get('data-id')),
-                    value : Value.value,
+                    id: parseInt(Label.get('data-id')),
+                    value: Value.value,
                     value2: Value2.value,
-                    term  : Term.value,
-                    term2 : Term2.value,
-                    unit  : Unit.value
+                    term: Term.value,
+                    term2: Term2.value,
+                    unit: Unit.value
                 });
             }
 
diff --git a/src/QUI/ERP/Shipping/Rules/Factory.php b/src/QUI/ERP/Shipping/Rules/Factory.php
index 86dc7ad..151c8b3 100644
--- a/src/QUI/ERP/Shipping/Rules/Factory.php
+++ b/src/QUI/ERP/Shipping/Rules/Factory.php
@@ -10,6 +10,14 @@
 use QUI\ERP\Shipping\Rules\Factory as RuleFactory;
 use QUI\Permissions\Permission;
 
+use function array_filter;
+use function array_flip;
+use function is_array;
+use function is_numeric;
+use function json_encode;
+
+use const ARRAY_FILTER_USE_KEY;
+
 /**
  * Class Factory
  *
@@ -61,7 +69,7 @@ public function __construct()
     public function createChild($data = [])
     {
         // filter
-        $allowed = \array_flip([
+        $allowed = array_flip([
             'title',
             'workingTitle',
             'date_from',
@@ -81,9 +89,9 @@ public function createChild($data = [])
             'no_rule_after'
         ]);
 
-        $data = \array_filter($data, function ($k) use ($allowed) {
+        $data = array_filter($data, function ($k) use ($allowed) {
             return isset($allowed[$k]);
-        }, \ARRAY_FILTER_USE_KEY);
+        }, ARRAY_FILTER_USE_KEY);
 
 
         if (!isset($data['active']) || !\is_integer($data['active'])) {
@@ -98,38 +106,40 @@ public function createChild($data = [])
             $data['purchase_quantity_until'] = 0;
         }
 
-        if (!isset($data['priority']) || !\is_numeric($data['priority'])) {
+        if (!isset($data['priority']) || !is_numeric($data['priority'])) {
             $data['priority'] = 0;
-        } elseif (isset($data['priority']) && !\is_int($data['priority'])) {
+        } elseif (!\is_int($data['priority'])) {
             $data['priority'] = (int)$data['priority'];
         }
 
-        if (!isset($data['discount']) || empty($data['discount'])) {
+        if (empty($data['discount'])) {
             $data['discount'] = 0;
+        } else {
+            $data['discount'] = QUI\ERP\Money\Price::validatePrice($data['discount']);
         }
 
-        if (isset($data['unit_terms']) && \is_array($data['unit_terms'])) {
-            $data['unit_terms'] = \json_encode($data['unit_terms']);
+        if (isset($data['unit_terms']) && is_array($data['unit_terms'])) {
+            $data['unit_terms'] = json_encode($data['unit_terms']);
         }
 
         if (!isset($data['unit_terms'])) {
             $data['unit_terms'] = '';
         }
 
-        if (!isset($data['articles_only']) || empty($data['articles_only'])) {
+        if (empty($data['articles_only'])) {
             $data['articles_only'] = 0;
         } else {
             $data['articles_only'] = (int)$data['articles_only'];
         }
 
-        if (!isset($data['no_rule_after']) || empty($data['no_rule_after'])) {
+        if (empty($data['no_rule_after'])) {
             $data['no_rule_after'] = 0;
         } else {
             $data['no_rule_after'] = (int)$data['no_rule_after'];
         }
 
         // discount
-        if (\is_numeric($data['discount_type'])) {
+        if (is_numeric($data['discount_type'])) {
             $data['discount_type'] = (int)$data['discount_type'];
         }
 
@@ -178,7 +188,7 @@ public function createChild($data = [])
         );
 
         // set translations
-        if (isset($data['title']) && !empty($data['title']) && \is_array($data['title'])) {
+        if (isset($data['title']) && !empty($data['title']) && is_array($data['title'])) {
             $title = [];
 
             foreach ($data['title'] as $lang => $v) {
@@ -195,7 +205,7 @@ public function createChild($data = [])
             );
         }
 
-        if (isset($data['workingTitle']) && !empty($data['workingTitle']) && \is_array($data['workingTitle'])) {
+        if (isset($data['workingTitle']) && !empty($data['workingTitle']) && is_array($data['workingTitle'])) {
             $title = [];
 
             foreach ($data['workingTitle'] as $lang => $v) {
-- 
GitLab