From 802f402ec74c015bb1c35cdbbc521cf5a950b4ea Mon Sep 17 00:00:00 2001 From: Henning Leutz <leutz@pcsg.de> Date: Mon, 19 Sep 2022 08:20:57 +0200 Subject: [PATCH] refactor: price factor stuff --- ajax/calcPriceFactor.php | 41 +++ .../controls/articles/BruttoCalcButton.js | 62 ++++ .../articles/windows/PriceFactors.Add.html | 37 +++ .../articles/windows/PriceFactors.css | 5 + .../articles/windows/PriceFactors.html | 68 ++++ .../controls/articles/windows/PriceFactors.js | 301 ++++++++++++++++++ 6 files changed, 514 insertions(+) create mode 100644 ajax/calcPriceFactor.php create mode 100644 bin/backend/controls/articles/BruttoCalcButton.js create mode 100644 bin/backend/controls/articles/windows/PriceFactors.Add.html create mode 100644 bin/backend/controls/articles/windows/PriceFactors.css create mode 100644 bin/backend/controls/articles/windows/PriceFactors.html create mode 100644 bin/backend/controls/articles/windows/PriceFactors.js diff --git a/ajax/calcPriceFactor.php b/ajax/calcPriceFactor.php new file mode 100644 index 0000000..0f08849 --- /dev/null +++ b/ajax/calcPriceFactor.php @@ -0,0 +1,41 @@ +<?php + +/** + * This file contains package_quiqqer_erp_ajax_calculatePriceFactor + */ + +/** + * + */ + +use QUI\ERP\Currency\Handler as CurrencyHandler; +use QUI\ERP\Money\Price; + +QUI::$Ajax->registerFunction( + 'package_quiqqer_erp_ajax_calcPriceFactor', + function ($price, $vat, $currency) { + $Currency = CurrencyHandler::getCurrency($currency); + $price = Price::validatePrice($price); + + $nettoSum = $price; + $nettoSumFormatted = $Currency->format($price); + $sum = $price * (($vat + 100) / 100); + $sumFormatted = $Currency->format($sum); + + $valueText = $sumFormatted; + + if (strpos($valueText, '+') === false && strpos($valueText, '-') === false) { + $valueText = '+' . $valueText; + } + + return [ + 'nettoSum' => $nettoSum, + 'nettoSumFormatted' => $nettoSumFormatted, + 'sum' => $sum, + 'sumFormatted' => $sumFormatted, + 'valueText' => $valueText + ]; + }, + ['price', 'vat', 'currency'], + 'Permission::checkAdminUser' +); diff --git a/bin/backend/controls/articles/BruttoCalcButton.js b/bin/backend/controls/articles/BruttoCalcButton.js new file mode 100644 index 0000000..32179bf --- /dev/null +++ b/bin/backend/controls/articles/BruttoCalcButton.js @@ -0,0 +1,62 @@ +/** + * @module package/quiqqer/erp/bin/backend/controls/articles/BruttoCalcButton + * @author www.pcsgde (Henning Leutz) + */ +define('package/quiqqer/erp/bin/backend/controls/articles/BruttoCalcButton', [ + + 'qui/QUI', + 'qui/controls/Control', + 'package/quiqqer/products/bin/controls/fields/windows/PriceBrutto', + +], function (QUI, QUIButton, PriceBruttoWindow) { + "use strict"; + + return new Class({ + + Type : 'package/quiqqer/erp/bin/backend/controls/articles/BruttoCalcButton', + Extends: QUIButton, + + Binds: [ + 'openBruttoWindow' + ], + + options: { + Price: null + }, + + initialize: function (options) { + this.parent(options); + }, + + create: function () { + this.$Elm = new Element('button'); + this.$Elm.set('data-quiid', this.getId()); + this.$Elm.set('data-qui', 'package/quiqqer/erp/bin/backend/controls/articles/BruttoCalcButton'); + this.$Elm.set('html', '<span class="fa fa-calculator"></span>'); + + this.$Elm.addClass('qui-button'); + this.$Elm.addEvent('click', (e) => { + e.stop(); + this.openBruttoWindow(); + }); + + return this.$Elm; + }, + + openBruttoWindow: function () { + const Price = this.getAttribute('Price'); + + new PriceBruttoWindow({ + events: { + onOpen: function (Win) { + Win.getContent().set('html', ''); + }, + + onSubmit: (Win, value) => { + Price.value = value; + } + } + }).open(); + } + }); +}); \ No newline at end of file diff --git a/bin/backend/controls/articles/windows/PriceFactors.Add.html b/bin/backend/controls/articles/windows/PriceFactors.Add.html new file mode 100644 index 0000000..b9d76b7 --- /dev/null +++ b/bin/backend/controls/articles/windows/PriceFactors.Add.html @@ -0,0 +1,37 @@ +<form name="price-factor-add"> + <table class="data-table data-table-flexbox"> + <tr> + <td> + <label class="field-container"> + <span class="field-container-item">{{titlePrice}}</span> + <input name="price" class="field-container-field"/> + </label> + </td> + </tr> + <tr> + <td> + <label class="field-container"> + <span class="field-container-item">{{titleTitle}}</span> + <input name="title" class="field-container-field"/> + </label> + </td> + </tr> + <tr> + <td> + <label class="field-container"> + <span class="field-container-item">{{titlePriority}}</span> + <input name="priority" type="number" class="field-container-field"/> + </label> + </td> + </tr> + <tr> + <td> + <label class="field-container"> + <span class="field-container-item">{{titleVat}}</span> + <select name="vat" class="field-container-field"> + </select> + </label> + </td> + </tr> + </table> +</form> \ No newline at end of file diff --git a/bin/backend/controls/articles/windows/PriceFactors.css b/bin/backend/controls/articles/windows/PriceFactors.css new file mode 100644 index 0000000..333e743 --- /dev/null +++ b/bin/backend/controls/articles/windows/PriceFactors.css @@ -0,0 +1,5 @@ +.quiqqer-erp-priceFactors .pricefactor-index { + font-weight: bold; + font-size: 10px; + margin-right: 5px; +} \ No newline at end of file diff --git a/bin/backend/controls/articles/windows/PriceFactors.html b/bin/backend/controls/articles/windows/PriceFactors.html new file mode 100644 index 0000000..7e4b869 --- /dev/null +++ b/bin/backend/controls/articles/windows/PriceFactors.html @@ -0,0 +1,68 @@ +<table class="data-table data-table-flexbox quiqqer-erp-priceFactors"> + <thead> + <tr> + <th class="quiqqer-erp-priceFactors-button"> + <button name="add-pricefactor" disabled class="qui-button" style="float: right"> + <span class="fa fa plus"></span> + <span>{{textAddButton}}</span> + </button> + </th> + </tr> + </thead> + <tbody> + {{#priceFactors}} + <tr data-index="{{index}}"> + <td> + <div class="field-container"> + <label style="width: 100%; display: flex;"> + <span class="field-container-item"> + <span class="pricefactor-index">#{{priority}}</span> + {{title}} + </span> + <span class="field-container-field">{{valueText}}</span> + </label> + <button class="qui-button delete" style="width: 50px; cursor: pointer;"> + <span class="fa fa-close"></span> + </button> + </div> + </td> + </tr> + {{/priceFactors}} + {{^priceFactors}} + <tr> + <td>{{textNoFactors}}</td> + </tr> + {{/priceFactors}} + </tbody> +</table> + +<table class="data-table data-table-flexbox quiqqer-erp-backend-temporaryErp-summaryWin-total"> + <tbody> + {{#vatArray}} + <tr> + <td> + <label class="field-container"> + <span class="field-container-item vat-title">{{text}}</span> + <span class="field-container-field vat-value">{{sum}}</span> + </label> + </td> + </tr> + {{/vatArray}} + <tr> + <td> + <label class="field-container"> + <span class="field-container-item netto-title">{{textNetto}}</span> + <span class="field-container-field netto-value"></span> + </label> + </td> + </tr> + <tr> + <td> + <label class="field-container"> + <span class="field-container-item brutto-title">{{textBrutto}}</span> + <span class="field-container-field brutto-value"></span> + </label> + </td> + </tr> + </tbody> +</table> diff --git a/bin/backend/controls/articles/windows/PriceFactors.js b/bin/backend/controls/articles/windows/PriceFactors.js new file mode 100644 index 0000000..05a3858 --- /dev/null +++ b/bin/backend/controls/articles/windows/PriceFactors.js @@ -0,0 +1,301 @@ +/** + * @module package/quiqqer/erp/bin/backend/controls/articles/windows/PriceFactors + * @author www.pcsg.de (Henning Leutz) + */ +define('package/quiqqer/erp/bin/backend/controls/articles/windows/PriceFactors', [ + + 'qui/QUI', + 'qui/controls/windows/Popup', + 'qui/controls/windows/Confirm', + 'package/quiqqer/currency/bin/Currency', + 'Ajax', + 'Locale', + 'Mustache', + + "text!package/quiqqer/erp/bin/backend/controls/articles/windows/PriceFactors.html", + "text!package/quiqqer/erp/bin/backend/controls/articles/windows/PriceFactors.Add.html", + "css!package/quiqqer/erp/bin/backend/controls/articles/windows/PriceFactors.css" + +], function (QUI, QUIWindow, QUIConfirm, Currency, QUIAjax, QUILocale, Mustache, template, templateAdd) { + "use strict"; + + const lg = 'quiqqer/erp'; + + return new Class({ + + Extends: QUIWindow, + Type : 'package/quiqqer/erp/bin/backend/controls/articles/windows/PriceFactors', + + Binds: [ + '$onOpen' + ], + + options: { + ArticleList: null + }, + + initialize: function (option) { + this.setAttributes({ + title : QUILocale.get(lg, 'pricefactors.summary.window.title'), + buttons : false, + maxHeight: 600, + maxWidth : 600, + }); + + this.parent(option); + + this.$Formatter = null; + + this.addEvents({ + onOpen: this.$onOpen + }); + }, + + $onOpen: function () { + this.refresh(); + }, + + /** + * Return the article list + * + * @returns {*} + */ + getArticleList: function () { + return this.getAttribute('ArticleList'); + }, + + refresh: function () { + if (!this.getAttribute('ArticleList')) { + this.close(); + return; + } + + this.Loader.show(); + + const ArticleList = this.getAttribute('ArticleList'); + const Content = this.getContent(); + + let priceFactors = ArticleList.getPriceFactors(); + let calculations = ArticleList.getCalculation(); + + if (typeof calculations.vatArray === 'undefined') { + calculations.vatArray = {}; + } + + for (let i = 0, len = priceFactors.length; i < len; i++) { + priceFactors[i].index = i; + priceFactors[i].priority = i + 1; + } + + Content.set({ + html: Mustache.render(template, { + textAddButton: QUILocale.get(lg, 'add.pricefactor.button'), + textNoFactors: QUILocale.get(lg, 'message.pricefactor.empty'), + textNetto : QUILocale.get(lg, 'article.summary.tpl.labelNet'), + textBrutto : QUILocale.get(lg, 'article.summary.tpl.labelGross'), + priceFactors : priceFactors, + vatArray : Object.values(calculations.vatArray) + }) + }); + + const PriceFactorButton = Content.getElement('[name="add-pricefactor"]'); + + this.getCurrencyFormatter().then((Formatter) => { + const Total = Content.getElement('.quiqqer-erp-backend-temporaryErp-summaryWin-total'); + let calc = calculations.calculations; + + if (!calc) { + calc = { + nettoSum: 0, + sum : 0 + }; + } + + Total.getElement('.netto-value').set('html', Formatter.format(calc.nettoSum)); + Total.getElement('.brutto-value').set('html', Formatter.format(calc.sum)); + + Content.getElements('.delete').addEvent('click', (e) => { + e.stop(); + let index = e.target.getParent('tr').get('data-index'); + + ArticleList.removePriceFactor(index); + this.refresh(); + }); + + PriceFactorButton.addEvent('click', (e) => { + e.stop(); + this.addPriceFactor(); + }); + + PriceFactorButton.disabled = false; + + this.fireEvent('quiqqerErpPriceFactorWindow', [this]); + QUI.fireEvent('quiqqerErpPriceFactorWindow', [this]); + + this.Loader.hide(); + }); + }, + + /** + * opens the add price factor window + */ + addPriceFactor: function () { + const ArticleList = this.getAttribute('ArticleList'); + let calculations = ArticleList.getCalculation(); + + if (typeof calculations.vatArray === 'undefined') { + calculations.vatArray = {}; + } + + new QUIConfirm({ + icon : 'fa fa-plus', + title : QUILocale.get(lg, 'pricefactors.summary.window.title'), + maxHeight: 400, + maxWidth : 580, + autoclose: false, + events : { + onOpen: (Win) => { + Win.Loader.show(); + + Win.getContent().set({ + html: Mustache.render(templateAdd, { + titlePrice : QUILocale.get(lg, 'title.price'), + titleTitle : QUILocale.get(lg, 'title.title'), + titlePriority: QUILocale.get(lg, 'title.priority'), + titleVat : QUILocale.get(lg, 'title.vat'), + + calculationBasis : QUILocale.get(lg, 'calculationBasis'), + calculationBasisNetto : QUILocale.get(lg, 'calculationBasis.netto'), + calculationBasisCalcPrice : QUILocale.get(lg, 'calculationBasis.calculationBasisCalcPrice'), + calculationBasisCalcBrutto: QUILocale.get(lg, 'calculationBasis.calculationBasisCalcBrutto'), + }) + }); + + require([ + 'package/quiqqer/erp/bin/backend/controls/articles/BruttoCalcButton' + ], (Calc) => { + new Calc({ + Price: Win.getContent().getElement('[name="price"]') + }).inject( + Win.getContent().getElement('[name="price"]'), + 'after' + ); + + Win.getContent() + .getElement('[name="priority"]') + .set('value', ArticleList.countPriceFactors() + 1); + + // vat + const VatSelect = Win.getContent().getElement('[name="vat"]'); + + for (let vat in calculations.calculations.vatArray) { + new Element('option', { + html : vat + '%', + value: vat + }).inject(VatSelect); + } + + + Win.Loader.hide(); + }); + }, + + onSubmit: (Win) => { + const Form = Win.getContent().getElement('form'); + const price = Form.elements.price.value; + const currency = ArticleList.getAttribute('currency'); + + if (!price || price === '') { + return; + } + + Win.Loader.show(); + + this.getPriceFactorData( + price, + Form.elements.vat.value, + currency + ).then((data) => { + let priority = Form.elements.priority.value; + + if (priority === '') { + priority = 1; + } + + let priceFactor = { + calculation : 2, + calculation_basis: 2, + description : Form.elements.title.value, + identifier : "", + index : priority - 1, + nettoSum : data.nettoSum, + nettoSumFormatted: data.nettoSumFormatted, + sum : data.sum, + sumFormatted : data.sumFormatted, + title : Form.elements.title.value, + value : data.sum, + valueText : data.valueText, + vat : Form.elements.vat.value, + visible : 1 + }; + + ArticleList.addPriceFactor(priceFactor); + Win.close(); + this.refresh(); + }); + } + } + }).open(); + }, + + /** + * returns the current currency formatter of the article list + * + * @returns {*} + */ + getCurrencyFormatter: function () { + if (this.$Formatter) { + return Promise.resolve(this.$Formatter); + } + + // admin format + return new Promise((resolve) => { + let currency = null; + + if (this.getAttribute('currency')) { + currency = this.getAttribute('currency'); + } + + Currency.getCurrency(currency).then((currency) => { + this.$Formatter = QUILocale.getNumberFormatter({ + style : 'currency', + currency : currency.code, + minimumFractionDigits: currency.precision, + maximumFractionDigits: currency.precision + }); + + resolve(this.$Formatter); + }); + }); + }, + + /** + * Return the data for the price factor + * + * @param price + * @param vat + * @param currency + * @returns {*} + */ + getPriceFactorData: function (price, vat, currency) { + return new Promise(function (resolve) { + QUIAjax.get('package_quiqqer_erp_ajax_calcPriceFactor', resolve, { + 'package': 'quiqqer/erp', + price : price, + vat : vat, + currency : currency + }); + }); + } + }); +}); -- GitLab