From c71b02e0fb63835eba706519fb9c743e58c4ef24 Mon Sep 17 00:00:00 2001 From: Henning Leutz <leutz@pcsg.de> Date: Fri, 16 Sep 2022 10:34:24 +0200 Subject: [PATCH] feat: quiqqer/erp#78 --- .../articleList/getShippingPriceFactor.php | 27 +++ bin/backend/controls/Shipping.js | 180 ++++++++------- bin/backend/controls/ShippingWindow.js | 209 ++++++++++++++++++ bin/backend/load.js | 85 +++++++ events.xml | 2 + locale.xml | 9 + src/QUI/ERP/Shipping/EventHandler.php | 8 + src/QUI/ERP/Shipping/Types/ShippingEntry.php | 10 +- 8 files changed, 444 insertions(+), 86 deletions(-) create mode 100644 ajax/backend/articleList/getShippingPriceFactor.php create mode 100644 bin/backend/controls/ShippingWindow.js create mode 100644 bin/backend/load.js diff --git a/ajax/backend/articleList/getShippingPriceFactor.php b/ajax/backend/articleList/getShippingPriceFactor.php new file mode 100644 index 0000000..8b42ca8 --- /dev/null +++ b/ajax/backend/articleList/getShippingPriceFactor.php @@ -0,0 +1,27 @@ +<?php + +/** + * This file contains package_quiqqer_shipping_ajax_backend_articleList_getShippingPriceFactor + */ + +use QUI\ERP\Shipping\Shipping; + +/** + * Return the shipping price for a article list + * - all shipping rules are summarized + * + * @return array + */ +QUI::$Ajax->registerFunction( + 'package_quiqqer_shipping_ajax_backend_articleList_getShippingPriceFactor', + function ($shippingId) { + $Shipping = Shipping::getInstance()->getShippingEntry($shippingId); + + return [ + 'title' => $Shipping->getTitle(), + 'price' => $Shipping->getPrice() + ]; + }, + ['shippingId'], + 'Permission::checkAdminUser' +); diff --git a/bin/backend/controls/Shipping.js b/bin/backend/controls/Shipping.js index 67e891c..ec646fd 100644 --- a/bin/backend/controls/Shipping.js +++ b/bin/backend/controls/Shipping.js @@ -19,8 +19,8 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ ], function (QUI, QUIPanel, QUIConfirm, QUIButton, Shipping, Grid, Mustache, QUILocale) { "use strict"; - var lg = 'quiqqer/shipping'; - var current = QUILocale.getCurrent(); + const lg = 'quiqqer/shipping'; + const current = QUILocale.getCurrent(); return new Class({ @@ -76,7 +76,7 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ this.Loader.show(); - var self = this; + const self = this; this.$Grid.getButtons().filter(function (Btn) { return Btn.getAttribute('name') === 'edit'; @@ -88,12 +88,11 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ Shipping.getShippingList().then(function (result) { - var toggle = function (Btn) { - var data = Btn.getAttribute('data'), + const toggle = function (Btn) { + let data = Btn.getAttribute('data'), shippingId = data.id, status = parseInt(data.active); - Btn.setAttribute('icon', 'fa fa-spinner fa-spin'); if (status) { @@ -104,7 +103,7 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ Shipping.activateShipping(shippingId); }; - for (var i = 0, len = result.length; i < len; i++) { + for (let i = 0, len = result.length; i < len; i++) { if (parseInt(result[i].active)) { result[i].status = { icon : 'fa fa-check', @@ -133,8 +132,13 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ result[i].shippingType_display = ''; - result[i].title = result[i].title[current]; - result[i].workingTitle = result[i].workingTitle[current]; + if (typeOf(result[i].title) !== 'string') { + result[i].title = result[i].title[current]; + } + + if (typeOf(result[i].workingTitle) !== 'string') { + result[i].workingTitle = result[i].workingTitle[current]; + } if ("shippingType" in result[i] && result[i].shippingType) { result[i].shippingType_display = result[i].shippingType.title; @@ -153,7 +157,7 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ * event: on create */ $onCreate: function () { - var Container = new Element('div', { + const Container = new Element('div', { styles: { minHeight: 300, width : '100%' @@ -161,63 +165,75 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ }).inject(this.getContent()); this.$Grid = new Grid(Container, { - buttons : [{ - name : 'add', - text : QUILocale.get('quiqqer/quiqqer', 'add'), - textimage: 'fa fa-plus', - events : { - onClick: this.$openCreateDialog - } - }, { - type: 'separator' - }, { - name : 'edit', - text : QUILocale.get('quiqqer/quiqqer', 'edit'), - textimage: 'fa fa-edit', - disabled : true, - events : { - onClick: this.$onEditClick + buttons : [ + { + name : 'add', + text : QUILocale.get('quiqqer/quiqqer', 'add'), + textimage: 'fa fa-plus', + events : { + onClick: this.$openCreateDialog + } + }, + { + type: 'separator' + }, + { + name : 'edit', + text : QUILocale.get('quiqqer/quiqqer', 'edit'), + textimage: 'fa fa-edit', + disabled : true, + events : { + onClick: this.$onEditClick + } + }, + { + name : 'delete', + text : QUILocale.get('quiqqer/system', 'delete'), + textimage: 'fa fa-trash', + disabled : true, + events : { + onClick: this.$openDeleteDialog + } } - }, { - name : 'delete', - text : QUILocale.get('quiqqer/system', 'delete'), - textimage: 'fa fa-trash', - disabled : true, - events : { - onClick: this.$openDeleteDialog + ], + columnModel: [ + { + header : QUILocale.get('quiqqer/system', 'priority'), + dataIndex: 'priority', + dataType : 'number', + width : 50 + }, + { + header : QUILocale.get('quiqqer/system', 'status'), + dataIndex: 'status', + dataType : 'button', + width : 60 + }, + { + header : QUILocale.get('quiqqer/system', 'title'), + dataIndex: 'title', + dataType : 'string', + width : 200 + }, + { + header : QUILocale.get('quiqqer/system', 'workingtitle'), + dataIndex: 'workingTitle', + dataType : 'string', + width : 200 + }, + { + header : QUILocale.get('quiqqer/system', 'id'), + dataIndex: 'id', + dataType : 'number', + width : 30 + }, + { + header : QUILocale.get(lg, 'shipping.type'), + dataIndex: 'shippingType_display', + dataType : 'string', + width : 200 } - }], - columnModel: [{ - header : QUILocale.get('quiqqer/system', 'priority'), - dataIndex: 'priority', - dataType : 'number', - width : 50 - }, { - header : QUILocale.get('quiqqer/system', 'status'), - dataIndex: 'status', - dataType : 'button', - width : 60 - }, { - header : QUILocale.get('quiqqer/system', 'title'), - dataIndex: 'title', - dataType : 'string', - width : 200 - }, { - header : QUILocale.get('quiqqer/system', 'workingtitle'), - dataIndex: 'workingTitle', - dataType : 'string', - width : 200 - }, { - header : QUILocale.get('quiqqer/system', 'id'), - dataIndex: 'id', - dataType : 'number', - width : 30 - }, { - header : QUILocale.get(lg, 'shipping.type'), - dataIndex: 'shippingType_display', - dataType : 'string', - width : 200 - }] + ] }); this.$Grid.addEvents({ @@ -255,13 +271,13 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ return; } - var Body = this.getContent(); + const Body = this.getContent(); if (!Body) { return; } - var size = Body.getSize(); + const size = Body.getSize(); this.$Grid.setHeight(size.y - 40); this.$Grid.setWidth(size.x - 40); }, @@ -294,7 +310,7 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ * event: on edit */ $onEditClick: function () { - var data = this.$Grid.getSelectedData(); + const data = this.$Grid.getSelectedData(); if (data.length) { this.openShipping(data[0].id); @@ -305,7 +321,7 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ * open the add dialog */ $openCreateDialog: function () { - var self = this; + const self = this; new QUIConfirm({ icon : 'fa fa-plus', @@ -318,12 +334,12 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ maxWidth : 600, events : { onOpen : function (Win) { - var Content = Win.getContent(), - Body = Content.getElement('.textbody'); + const Content = Win.getContent(), + Body = Content.getElement('.textbody'); Win.Loader.show(); - var Container = new Element('div', { + const Container = new Element('div', { html : QUILocale.get(lg, 'window.create.shippingType'), styles: { clear : 'both', @@ -334,7 +350,7 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ } }).inject(Body, 'after'); - var Select = new Element('select', { + const Select = new Element('select', { styles: { marginTop: 10, maxWidth : '100%', @@ -343,7 +359,7 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ }).inject(Container); Shipping.getShippingTypes().then(function (result) { - for (var i in result) { + for (let i in result) { if (!result.hasOwnProperty(i)) { continue; } @@ -362,7 +378,7 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ onSubmit: function (Win) { Win.Loader.show(); - var Select = Win.getContent().getElement('select'); + const Select = Win.getContent().getElement('select'); Shipping.createShipping(Select.value).then(function (newId) { Win.close(); @@ -380,14 +396,14 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ * open the add dialog */ $openDeleteDialog: function () { - var selected = this.$Grid.getSelectedData(); + const selected = this.$Grid.getSelectedData(); if (!selected.length) { return; } - var self = this, - shipping = selected[0].title, + const self = this; + let shipping = selected[0].title, shippingId = selected[0].id; if (shipping === '') { @@ -429,14 +445,14 @@ define('package/quiqqer/shipping/bin/backend/controls/Shipping', [ * looks at the grid */ $refreshButtonStatus: function () { - var selected = this.$Grid.getSelectedIndices(), - buttons = this.$Grid.getButtons(); + const selected = this.$Grid.getSelectedIndices(), + buttons = this.$Grid.getButtons(); - var Edit = buttons.filter(function (Btn) { + const Edit = buttons.filter(function (Btn) { return Btn.getAttribute('name') === 'edit'; })[0]; - var Delete = buttons.filter(function (Btn) { + const Delete = buttons.filter(function (Btn) { return Btn.getAttribute('name') === 'delete'; })[0]; diff --git a/bin/backend/controls/ShippingWindow.js b/bin/backend/controls/ShippingWindow.js new file mode 100644 index 0000000..9212e22 --- /dev/null +++ b/bin/backend/controls/ShippingWindow.js @@ -0,0 +1,209 @@ +/** + * @module package/quiqqer/shipping/bin/backend/controls/ShippingWindow + * @author www.pcsg.de + */ +define('package/quiqqer/shipping/bin/backend/controls/ShippingWindow', [ + + 'qui/QUI', + 'qui/controls/windows/Confirm', + 'package/quiqqer/shipping/bin/backend/Shipping', + 'controls/grid/Grid', + 'Locale' + +], function (QUI, QUIConfirm, Shipping, Grid, QUILocale) { + "use strict"; + + const lg = 'quiqqer/shipping'; + const current = QUILocale.getCurrent(); + + return new Class({ + + Extends: QUIConfirm, + Type : 'package/quiqqer/shipping/bin/backend/controls/ShippingWindow', + + Binds: [ + '$onOpen', + '$onDblClick', + 'refresh' + ], + + options: { + Order: null + }, + + initialize: function (options) { + this.parent(options); + + this.setAttributes({ + title : QUILocale.get(lg, 'shipping.window.title'), + icon : 'fa fa-truck', + maxHeight: 560, + maxWidth : 500, + }); + + this.$Grid = null; + + this.addEvents({ + onOpen: this.$onOpen + }); + }, + + refresh: function () { + if (!this.$Elm) { + return; + } + + this.Loader.show(); + + Shipping.getShippingList().then((result) => { + const toggle = function (Btn) { + let data = Btn.getAttribute('data'), + shippingId = data.id, + status = parseInt(data.active); + + Btn.setAttribute('icon', 'fa fa-spinner fa-spin'); + + if (status) { + Shipping.deactivateShipping(shippingId); + return; + } + + Shipping.activateShipping(shippingId); + }; + + for (let i = 0, len = result.length; i < len; i++) { + if (parseInt(result[i].active)) { + result[i].status = { + icon : 'fa fa-check', + styles: { + lineHeight: 20, + padding : 0, + width : 20 + }, + events: { + onClick: toggle + } + }; + } else { + result[i].status = { + icon : 'fa fa-remove', + styles: { + lineHeight: 20, + padding : 0, + width : 20 + }, + events: { + onClick: toggle + } + }; + } + + result[i].shippingType_display = ''; + + if (typeOf(result[i].title) !== 'string') { + result[i].title = result[i].title[current]; + } + + if (typeOf(result[i].workingTitle) !== 'string') { + result[i].workingTitle = result[i].workingTitle[current]; + } + + if ("shippingType" in result[i] && result[i].shippingType) { + result[i].shippingType_display = result[i].shippingType.title; + } + } + + this.$Grid.setData({ + data: result + }); + + this.$Grid.setHeight( + this.getContent().getSize().y - 40 + ).then(() => { + this.Loader.hide(); + }); + }); + }, + + $onOpen: function () { + this.Loader.show(); + this.getContent().set('html', ''); + + const Container = new Element('div', { + styles: { + height: '100%', + width : '100%' + } + }).inject(this.getContent()); + + this.$Grid = new Grid(Container, { + columnModel: [ + { + header : QUILocale.get('quiqqer/system', 'priority'), + dataIndex: 'priority', + dataType : 'number', + width : 50 + }, + { + header : QUILocale.get('quiqqer/system', 'status'), + dataIndex: 'status', + dataType : 'button', + width : 60 + }, + { + header : QUILocale.get('quiqqer/system', 'title'), + dataIndex: 'title', + dataType : 'string', + width : 200 + }, + { + header : QUILocale.get('quiqqer/system', 'workingtitle'), + dataIndex: 'workingTitle', + dataType : 'string', + width : 200 + }, + { + header : QUILocale.get('quiqqer/system', 'id'), + dataIndex: 'id', + dataType : 'number', + width : 30 + }, + { + header : QUILocale.get(lg, 'shipping.type'), + dataIndex: 'shippingType_display', + dataType : 'string', + width : 200 + } + ] + }); + + this.$Grid.addEvents({ + onRefresh : this.refresh, + onDblClick: this.$onDblClick + }); + + this.refresh(); + }, + + $onDblClick: function () { + this.submit(); + }, + + submit: function () { + const data = this.$Grid.getSelectedData(); + + if (!data.length) { + return; + } + + this.fireEvent('submit', [ + this, + data + ]); + + if (this.getAttribute('autoclose')) { + this.close(); + } + } + }); +}); \ No newline at end of file diff --git a/bin/backend/load.js b/bin/backend/load.js new file mode 100644 index 0000000..c9bdba6 --- /dev/null +++ b/bin/backend/load.js @@ -0,0 +1,85 @@ +console.log('load shipping'); + +require(['qui/QUI'], function (QUI) { + "use strict"; + + function getShippingPrice(shippingId) { + return new Promise(function (resolve) { + require(['Ajax'], function (QUIAjax) { + QUIAjax.get('package_quiqqer_shipping_ajax_backend_articleList_getShippingPriceFactor', resolve, { + 'package' : 'quiqqer/shipping', + shippingId: shippingId + }); + }); + }); + } + + QUI.addEvent('quiqqerErpPriceFactorWindow', function (PriceFactorWindow) { + const Content = PriceFactorWindow.getContent(); + const Buttons = Content.getElement('.quiqqer-erp-priceFactors-button'); + const ArticleList = PriceFactorWindow.getArticleList(); + + require(['Locale'], function (QUILocale) { + new Element('button', { + 'class': 'qui-button', + html : '<span class="fa fa-truck"></span>', + title : QUILocale.get('quiqqer/shipping', 'add.shipping.priceFactor'), + styles : { + 'float' : 'right', + marginRight: '10px' + }, + events : { + click: function (e) { + e.stop(); + + require([ + 'package/quiqqer/shipping/bin/backend/controls/ShippingWindow' + ], function (ShippingWindow) { + new ShippingWindow({ + events: { + onSubmit: function (Instance, value) { + PriceFactorWindow.Loader.show(); + + const currency = ArticleList.getAttribute('currency'); + const vat = 19; + let shippingData; + + getShippingPrice(value[0].id).then(function (result) { + shippingData = result; + + return PriceFactorWindow.getPriceFactorData( + result.price, + vat, + currency + ); + }).then((data) => { + let priceFactor = { + calculation : 2, + calculation_basis: 2, + description : shippingData.title, + identifier : "", + index : ArticleList.countPriceFactors(), + nettoSum : data.nettoSum, + nettoSumFormatted: data.nettoSumFormatted, + sum : data.sum, + sumFormatted : data.sumFormatted, + title : shippingData.title, + value : data.sum, + valueText : data.valueText, + vat : vat, + visible : 1 + }; + + ArticleList.addPriceFactor(priceFactor); + PriceFactorWindow.refresh(); + }); + } + } + }).open(); + }); + } + } + }).inject(Buttons); + }); + }); +}); diff --git a/events.xml b/events.xml index 5685af1..3dcb21e 100644 --- a/events.xml +++ b/events.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <events> + <event on="onAdminLoadFooter" fire="\QUI\ERP\Shipping\EventHandler::onAdminLoadFooter"/> + <event on="onQuiqqerOrderBasketToOrderEnd" fire="\QUI\ERP\Shipping\EventHandler::onQuiqqerOrderBasketToOrderEnd" /> diff --git a/locale.xml b/locale.xml index 2588f7c..29fcb90 100644 --- a/locale.xml +++ b/locale.xml @@ -918,6 +918,15 @@ to send a notification.]]></en> </locale> + <locale name="add.shipping.priceFactor"> + <de><![CDATA[Versandart hinzufügen]]></de> + <en><![CDATA[Add shipping type]]></en> + </locale> + <locale name="shipping.window.title"> + <de><![CDATA[Versandarten]]></de> + <en><![CDATA[Shipping type]]></en> + </locale> + </groups> <groups name="quiqqer/order"> diff --git a/src/QUI/ERP/Shipping/EventHandler.php b/src/QUI/ERP/Shipping/EventHandler.php index 6f31d85..f97654e 100644 --- a/src/QUI/ERP/Shipping/EventHandler.php +++ b/src/QUI/ERP/Shipping/EventHandler.php @@ -104,6 +104,14 @@ public static function onPackageSetup(QUI\Package\Package $Package) self::createProductFields(); } + /** + * event : on admin load footer + */ + public static function onAdminLoadFooter() + { + echo '<script src="' . URL_OPT_DIR . 'quiqqer/shipping/bin/backend/load.js"></script>'; + } + /** * event - on price factor init * diff --git a/src/QUI/ERP/Shipping/Types/ShippingEntry.php b/src/QUI/ERP/Shipping/Types/ShippingEntry.php index 82acb68..147a1c0 100644 --- a/src/QUI/ERP/Shipping/Types/ShippingEntry.php +++ b/src/QUI/ERP/Shipping/Types/ShippingEntry.php @@ -20,6 +20,8 @@ use function json_encode; use function key; use function max; +use function method_exists; +use function round; /** * Class ShippingEntry @@ -245,7 +247,7 @@ public function getPrice() continue; } - $pc = \round($nettoSum * ($discount / 100)); + $pc = round($nettoSum * ($discount / 100)); $price = $price + $pc; continue; @@ -254,7 +256,7 @@ public function getPrice() } } - $pc = \round($price * ($discount / 100)); + $pc = round($price * ($discount / 100)); $price = $price + $pc; } @@ -284,7 +286,7 @@ public function canUsedBy( try { $ShippingType = $this->getShippingType(); - if (\method_exists($ShippingType, 'canUsedBy')) { + if (method_exists($ShippingType, 'canUsedBy')) { return $ShippingType->canUsedBy($User, $this, $Order); } } catch (QUI\Exception $Exception) { @@ -312,7 +314,7 @@ public function canUsedInOrder(QUI\ERP\Order\OrderInterface $Order) try { $ShippingType = $this->getShippingType(); - if (\method_exists($ShippingType, 'canUsedInOrder')) { + if (method_exists($ShippingType, 'canUsedInOrder')) { return $ShippingType->canUsedInOrder($Order, $this); } } catch (QUI\Exception $Exception) { -- GitLab