diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..9ab59b180fb670006ac910a2bc4524a1376dcea0 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,15 @@ + +# Ignore developer files when exporting +.gitattributes export-ignore +.gitignore export-ignore +.gitlab-ci.yml export-ignore +.phive export-ignore +captainhook.json export-ignore +phpcs.xml.dist export-ignore +phpstan-baseline.neon export-ignore +phpstan.dist.neon export-ignore +phpunit.dist.xml export-ignore +tests export-ignore + +# Explicitly set file type and line endings for PHP files, improves git diff output +*.php text eol=lf diff=php \ No newline at end of file diff --git a/.gitignore b/.gitignore index f4da20891502a3992abf2981d8f6c46e33868ab6..e25391c1f85364060ac958b37e8e35c6c51beafe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,11 @@ tools/ phpstan.neon .phpunit.result.cache -phpunit.xml \ No newline at end of file +phpunit.xml +tools/ + +phpstan.neon + +.phpunit.result.cache + +phpunit.xml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b8d20acb6c365ad8036a7b36d47dabd876d08efa..b5a64b401e554341447c74d7cf93a89ac95a3fdb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,3 +1,17 @@ include: - - project: 'quiqqer/stabilization/semantic-release' - file: '/ci-templates/.gitlab-ci.yml' + - component: dev.quiqqer.com/quiqqer/stabilization/ci-cd-components/quiqqer-package-bundle/quiqqer-package-bundle@main + +# Remove the entire phpunit-php8.1 block, to allow PHPUnit to run on PHP 8.1 in your pipeline +phpunit-php8.1: + rules: + - when: never + +# Remove the entire phpunit-php8.2 block, to allow PHPUnit to run on PHP 8.2 in your pipeline +phpunit-php8.2: + rules: + - when: never + +# Remove the entire phpunit-php8.3 block, to allow PHPUnit to run on PHP 8.3 in your pipeline +phpunit-php8.3: + rules: + - when: never \ No newline at end of file diff --git a/.phive/phars.xml b/.phive/phars.xml index a1315a09b4adad780a9c5e52f74835c708c5c7d5..5bfa092bfad10dad9d23240281a5a2041acb815b 100644 --- a/.phive/phars.xml +++ b/.phive/phars.xml @@ -1,4 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <phive xmlns="https://phar.io/phive"> - <phar name="phpstan" version="^1.10.67" installed="1.10.67" location="./tools/phpstan" copy="false"/> + <phar name="phpstan" version="1.11.8" installed="1.11.8" location="./tools/phpstan" copy="false"/> + <phar name="phpunit" version="^10.5.20" installed="10.5.20" location="./tools/phpunit" copy="false"/> + <phar name="phpcs" version="^3.10.1" installed="3.10.1" location="./tools/phpcs" copy="false"/> + <phar name="phpcbf" version="^3.10.1" installed="3.10.1" location="./tools/phpcbf" copy="false"/> + <phar name="captainhook" version="^5.23.3" installed="5.23.3" location="./tools/captainhook" copy="false"/> </phive> diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..4a69a59b440e5beec561eca1e341509bd5a18688 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,3 @@ +# Contributing + +This package follows the [QUIQQER contribution guidelines](https://dev.quiqqer.com/quiqqer/stabilization/documentation/-/wikis/home). \ No newline at end of file diff --git a/bin/frontend/controls/CouponCodeInput.css b/bin/frontend/controls/CouponCodeInput.css index f88583bf327d4ea95860ec1f8d75685875c44635..cf95da74bce32e5ee81a6bcd8f46648d4cec707c 100644 --- a/bin/frontend/controls/CouponCodeInput.css +++ b/bin/frontend/controls/CouponCodeInput.css @@ -29,3 +29,26 @@ div + .quiqqer-coupons-field { .quiqqer-coupons-remove .fa { margin-right: 0; } + +/** + * Simple Checkout + */ + +.quiqqer-coupons-field-simpleCheckout { + margin-top: 20px; + margin-left: 0 !important; +} + +.quiqqer-coupons-field-simpleCheckout .quiqqer-coupons-couponcodeinput { + background: var(--_sectionBgColor); + display: flex; + padding: var(--_sectionPadding); +} + +.quiqqer-coupons-field-simpleCheckout .quiqqer-coupons-couponcodeinput label { + flex-grow: 1; +} + +.quiqqer-coupons-field-simpleCheckout .quiqqer-coupons-couponcodeinput-input { + width: calc(100% - 1rem); +} \ No newline at end of file diff --git a/bin/frontend/controls/CouponCodeInput.js b/bin/frontend/controls/CouponCodeInput.js index 7bd7b9b5bc358b327e17d32807a5e658cbdf1e11..d24f612bc509cd9148015d714acce8a3d3f6c53f 100644 --- a/bin/frontend/controls/CouponCodeInput.js +++ b/bin/frontend/controls/CouponCodeInput.js @@ -20,25 +20,25 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [ 'text!package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput.html', 'css!package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput.css' -], function (QUI, QUIControl, QUILoader, Sessions, CouponCodes, QUIAjax, QUILocale, Mustache, template) { - "use strict"; +], function(QUI, QUIControl, QUILoader, Sessions, CouponCodes, QUIAjax, QUILocale, Mustache, template) { + 'use strict'; var lg = 'quiqqer/coupons'; return new Class({ Extends: QUIControl, - Type : 'package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', + Type: 'package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', Binds: [ '$submit' ], - initialize: function (options) { + initialize: function(options) { this.parent(options); - this.$Input = null; - this.Loader = new QUILoader(); + this.$Input = null; + this.Loader = new QUILoader(); this.$running = false; this.addEvents({ @@ -49,23 +49,27 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [ /** * Event: onInject */ - $onInject: function () { - var self = this; + $onInject: function() { + var self = this; var lgPrefix = 'controls.frontend.CouponCodeInput.template.'; this.$Elm.addClass('quiqqer-coupons-field'); + if (this.$Elm.getParent('[data-name="quiqqer-simple-checkout"]')) { + this.$Elm.addClass('quiqqer-coupons-field-simpleCheckout'); + } + this.$Elm.set('html', Mustache.render(template, { - labelInput : QUILocale.get(lg, lgPrefix + 'labelInput'), + labelInput: QUILocale.get(lg, lgPrefix + 'labelInput'), labelInputPlaceholder: QUILocale.get(lg, lgPrefix + 'labelInputPlaceholder'), - submitBtnText : QUILocale.get(lg, lgPrefix + 'submitBtnText') + submitBtnText: QUILocale.get(lg, lgPrefix + 'submitBtnText') })); this.Loader.inject(this.$Elm); this.$Input = this.$Elm.getElement('input[name="code"]'); - this.$Input.addEvent('keyup', function (event) { + this.$Input.addEvent('keyup', function(event) { if (event.code === 13) { self.$submit(); } @@ -73,7 +77,7 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [ this.$Elm.getElement( 'button.quiqqer-coupons-couponcodeinput-btn' - ).addEvent('click', function (event) { + ).addEvent('click', function(event) { event.stop(); self.$submit(); }); @@ -81,23 +85,23 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [ if (this.isInOrder()) { var OrderProcess = this.getOrderProcess(); - new Promise(function (resolve) { + new Promise(function(resolve) { if (!OrderProcess.isLoaded()) { return OrderProcess.addEvent('onLoad', resolve); } resolve(); - }).then(function () { + }).then(function() { if (OrderProcess.getAttribute('basketEditable') === false) { // remove coupon codes button new Element('button', { 'class': 'quiqqer-coupons-remove', - 'html' : '<span class="fa fa-close"></span>', - title : QUILocale.get(lg, 'remove.coupons.button'), - events : { - click: function (e) { + 'html': '<span class="fa fa-close"></span>', + title: QUILocale.get(lg, 'remove.coupons.button'), + events: { + click: function(e) { e.stop(); - self.removeCouponsFromOrder().catch(function (e) { + self.removeCouponsFromOrder().catch(function(e) { console.error(e); }); } @@ -111,7 +115,7 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [ /** * Submit a CouponCode */ - $submit: function () { + $submit: function() { if (this.$running) { return; } @@ -127,18 +131,56 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [ this.$running = true; this.Loader.show(); + // simple order + const SimpleCheckoutNode = this.getElm().getParent('[data-name="quiqqer-simple-checkout"]'); + + if (SimpleCheckoutNode) { + const SimpleCheckout = QUI.Controls.getById(SimpleCheckoutNode.get('data-quiid')); + let orderHash = window.location.hash.substring(1); + + if (!orderHash || orderHash === '') { + orderHash = SimpleCheckout.getAttribute('orderHash'); + } + + QUIAjax.get('package_quiqqer_order-simple-checkout_ajax_frontend_getOrder', (response) => { + CouponCodes.addCouponCodeToBasket(code, response.order.uuid).then(() => { + if (SimpleCheckout) { + SimpleCheckout.$refreshBasket().then(() => { + this.$running = false; + this.Loader.hide(); + }); + + return; + } + + this.$running = false; + this.Loader.hide(); + }).catch((err) => { + console.error(err); + + this.$running = false; + this.Loader.hide(); + }); + }, { + 'package': 'quiqqer/order-simple-checkout', + orderHash: orderHash + }); + + return; + } + // get order process if (!this.isInOrder()) { - QUIAjax.get('package_quiqqer_order_ajax_frontend_basket_getLastOrder', function (order) { - CouponCodes.addCouponCodeToBasket(code, order.hash).then(function (redeemed) { + QUIAjax.get('package_quiqqer_order_ajax_frontend_basket_getLastOrder', function(order) { + CouponCodes.addCouponCodeToBasket(code, order.hash).then(function(redeemed) { if (!redeemed) { self.$running = false; self.Loader.hide(); return; } - self.$addCouponCodeToSession(code).then(function () { - QUIAjax.get('package_quiqqer_order_ajax_frontend_basket_getOrderProcessUrl', function (url) { + self.$addCouponCodeToSession(code).then(function() { + QUIAjax.get('package_quiqqer_order_ajax_frontend_basket_getOrderProcessUrl', function(url) { window.location = url + '?coupon=' + code; }, { 'package': 'quiqqer/order' @@ -156,9 +198,9 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [ OrderProcess.Loader.show(); - OrderProcess.getOrder().then(function (orderHash) { + OrderProcess.getOrder().then(function(orderHash) { return CouponCodes.addCouponCodeToBasket(code, orderHash); - }).then(function (redeemed) { + }).then(function(redeemed) { self.$running = false; if (redeemed === false) { @@ -167,7 +209,7 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [ return; } - self.$addCouponCodeToSession(code).then(function () { + self.$addCouponCodeToSession(code).then(function() { OrderProcess.reload(); }); }); @@ -178,15 +220,15 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [ * @param code * @return {Promise} */ - $addCouponCodeToSession: function (code) { - return Sessions.get('quiqqer-coupons').then(function (coupons) { + $addCouponCodeToSession: function(code) { + return Sessions.get('quiqqer-coupons').then(function(coupons) { if (!coupons || typeOf(coupons) !== 'array') { coupons = []; } coupons.push(code); - coupons = coupons.filter(function (value, index, self) { + coupons = coupons.filter(function(value, index, self) { return self.indexOf(value) === index; }); @@ -198,7 +240,7 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [ * Is the coupon in the order process? * @return {boolean} */ - isInOrder: function () { + isInOrder: function() { var OrderProcessNode = this.getElm().getParent( '[data-qui="package/quiqqer/order/bin/frontend/controls/OrderProcess"]' ); @@ -211,7 +253,7 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [ * * @return {Object} */ - getOrderProcess: function () { + getOrderProcess: function() { var OrderProcessNode = this.getElm().getParent( '[data-qui="package/quiqqer/order/bin/frontend/controls/OrderProcess"]' ); @@ -224,19 +266,19 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [ * * @return {Promise} */ - removeCouponsFromOrder: function () { + removeCouponsFromOrder: function() { if (!this.isInOrder()) { return Promise.resolve(); } var self = this; - return new Promise(function (resolve) { + return new Promise(function(resolve) { var OrderProcess = self.getOrderProcess(); OrderProcess.Loader.show(); - OrderProcess.getOrder().then(function (orderHash) { - QUIAjax.get('package_quiqqer_coupons_ajax_frontend_removeCoupons', function () { + OrderProcess.getOrder().then(function(orderHash) { + QUIAjax.get('package_quiqqer_coupons_ajax_frontend_removeCoupons', function() { resolve(); OrderProcess.reload(); }, { diff --git a/captainhook.json b/captainhook.json new file mode 100644 index 0000000000000000000000000000000000000000..3702e1a358868bedd5ff4c7eae40bb1abb589267 --- /dev/null +++ b/captainhook.json @@ -0,0 +1,13 @@ +{ + "pre-commit": { + "enabled": true, + "actions": [ + { + "action": "\\CaptainHook\\App\\Hook\\PHP\\Action\\Linting" + }, + { + "action": "composer test" + } + ] + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index 925f04f4c931c09ab0cb5065bdd4a8b41f196386..fb16364f45b47345262479388fc608f9a84068e2 100644 --- a/composer.json +++ b/composer.json @@ -1,28 +1,71 @@ { - "name": "quiqqer/coupons", - "type": "quiqqer-module", - "description": "Coupons for QUIQQER", - "license": "GPL-3.0+", - "authors": [ - { - "name": "Patrick M\u00fcller", - "email": "support@pcsg.de", - "homepage": "https://www.pcsg.de", - "role": "Developer" + "name": "quiqqer/coupons", + "type": "quiqqer-module", + "description": "Coupons for QUIQQER", + "license": "GPL-3.0+", + "authors": [ + { + "name": "Patrick Müller", + "email": "support@pcsg.de", + "homepage": "https://www.pcsg.de", + "role": "Developer" + } + ], + "support": { + "email": "support@pcsg.de" + }, + "require": { + "quiqqer/core": "^2", + "quiqqer/erp": "^3.2", + "quiqqer/discount": "^2", + "quiqqer/products": "^2", + "quiqqer/order": "^2" + }, + "autoload": { + "psr-4": { + "QUI\\ERP\\Coupons\\": "src/QUI/ERP/Coupons" + } + }, + "scripts": { + "test": [ + "@dev:lint", + "@dev:phpunit" + ], + "dev:phpunit": "./tools/phpunit", + "dev:lint": [ + "@dev:lint:phpstan", + "@dev:lint:style" + ], + "dev:lint:phpstan": "./tools/phpstan", + "dev:lint:style": "./tools/phpcs", + "dev:lint:style:fix": "./tools/phpcbf", + "dev:init": [ + "@dev:init:check-requirements", + "@dev:init:tools", + "@dev:init:git-hooks" + ], + "dev:init:check-requirements": [ + "which composer > /dev/null || (echo 'Error: composer has to be globally installed'; exit 1)", + "which phive > /dev/null || (echo 'Error: PHIVE has to be globally installed'; exit 1)" + ], + "dev:init:tools": "phive install --temporary", + "dev:init:git-hooks": "./tools/captainhook install --only-enabled --force" + }, + "scripts-aliases": { + "test": [ + "dev:test" + ] + }, + "scripts-descriptions": { + "test": "Runs linting, static analysis, and unit tests.", + "dev:phpunit": "Run PHPUnit test suites", + "dev:lint": "Run PHPStan and code style check", + "dev:lint:phpstan": "Run PHPStan", + "dev:lint:style": "Run code style check (PHP_CodeSniffer)", + "dev:lint:style:fix": "Try to fix code style errors automatically", + "dev:init": "Initialize the developer tooling (tools and git hooks)", + "dev:init:check-requirements": "Check if the necessary requirements are met", + "dev:init:tools": "Install all developer tools (requires PHIVE)", + "dev:init:git-hooks": "Install all git hooks (may require tools to be installed)" } - ], - "support": { - "email": "support@pcsg.de" - }, - "require": { - "quiqqer/core": "^2", - "quiqqer/erp": "^3.2", - "quiqqer/discount": "^2", - "quiqqer/products": "^2" - }, - "autoload": { - "psr-4": { - "QUI\\ERP\\Coupons\\": "src/QUI/ERP/Coupons" - } - } -} +} \ No newline at end of file diff --git a/events.xml b/events.xml index f267a3e3c895402b6d0115c714f6a578f9faf23f..ba9ec1f86adc1f0bab8b186757181b1e0e78fb08 100644 --- a/events.xml +++ b/events.xml @@ -42,4 +42,7 @@ <event on="onQuiqqerOrderSuccessful" fire="\QUI\ERP\Coupons\Events::removeCouponsFromSession"/> <event on="onQuiqqer::order::orderProcessFinish" fire="\QUI\ERP\Coupons\Events::removeCouponsFromSession"/> <event on="onQuiqqerMigrationV2" fire="\QUI\ERP\Coupons\Events::onQuiqqerMigrationV2"/> + + <!-- simple order compatibility --> + <event on="onQuiqqer::simple::order::basket::middle" fire="\QUI\ERP\Coupons\Events::templateOrderSimpleOrder"/> </events> diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000000000000000000000000000000000000..d48084fbdc86a2dbfb78dd89ab2e0b0ff2322ba7 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<ruleset> + <!-- Use PSR-12 ruleset --> + <rule ref="PSR12"/> + + <!-- Only scan *.php files --> + <arg name="extensions" value="php"/> + + <!-- Ignore warnings --> + <arg name="warning-severity" value="0"/> + + <!-- Process 64 (or number of CPU cores) files in parallel --> + <arg name="parallel" value="64"/> + + <!-- Output relative file paths, by setting the current folder as the basepath --> + <arg name="basepath" value="."/> + + <!-- Show colored output --> + <arg name="colors"/> + + <!-- Scan everything in the current folder --> + <file>.</file> +</ruleset> diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..66cad0d6e45338268da2661f09f15a75d969595d 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -0,0 +1,71 @@ +parameters: + ignoreErrors: + - + message: "#^Call to an undefined method QUI\\\\ERP\\\\Products\\\\Interfaces\\\\PriceFactorInterface\\:\\:setVat\\(\\)\\.$#" + count: 1 + path: ajax/backend/getCouponPrice.php + + - + message: "#^Dead catch \\- Exception is never thrown in the try block\\.$#" + count: 1 + path: ajax/delete.php + + - + message: "#^Call to an undefined method QUI\\\\ERP\\\\Products\\\\Interfaces\\\\PriceFactorInterface\\:\\:setVat\\(\\)\\.$#" + count: 1 + path: src/QUI/ERP/Coupons/CouponCode.php + + - + message: "#^Method QUI\\\\ERP\\\\Coupons\\\\CouponCode\\:\\:getDiscounts\\(\\) should return array\\<QUI\\\\ERP\\\\Discount\\\\Discount\\> but returns array\\<int\\<0, max\\>, QUI\\\\CRUD\\\\Child\\>\\.$#" + count: 1 + path: src/QUI/ERP/Coupons/CouponCode.php + + - + message: "#^Offset 'standard' on array\\{title\\: array\\{de\\: 'Gutschein \\- Versand', en\\: 'Coupon delivery'\\}, type\\: 'ProductAttributeList', public\\: true, standard\\: false, requiredField\\: true, options\\: array\\{entries\\: array\\{array\\{title\\: array\\{de\\: 'per E \\- Mail', en\\: 'via email'\\}, sum\\: 0, type\\: 2, selected\\: true, userinput\\: false\\}, array\\{title\\: array\\{de\\: 'per Post', en\\: 'via mail'\\}, sum\\: 0, type\\: 2, selected\\: false, userinput\\: false\\}\\}\\}\\}\\|array\\{title\\: array\\{de\\: 'Gutschein Wert', en\\: 'Coupon amount'\\}, type\\: 'FloatType', public\\: false, standard\\: false, requiredField\\: true\\}\\|array\\{title\\: array\\{de\\: 'Gutschein\\-Code als…', en\\: 'Provide coupon code…'\\}, description\\: array\\{de\\: 'Der Gutschein wird…', en\\: 'The coupon is also…'\\}, type\\: 'BoolType', public\\: false, standard\\: false, requiredField\\: false\\}\\|array\\{title\\: array\\{de\\: 'Gutschein\\-Code ist…', en\\: 'Coupon code is…'\\}, description\\: array\\{de\\: 'Übertragbare…', en\\: 'Transferable…'\\}, type\\: 'BoolType', public\\: false, standard\\: false, requiredField\\: false\\}\\|array\\{title\\: array\\{de\\: 'Gutschein\\-Code per…', en\\: 'Send coupon code…'\\}, description\\: array\\{de\\: 'Der Gutschein\\-Code…', en\\: 'The coupon code is…'\\}, type\\: 'BoolType', public\\: false, standard\\: false, requiredField\\: false\\}\\|array\\{title\\: array\\{de\\: 'Gutschein\\-Code…', en\\: 'Coupon code…'\\}, type\\: 'IntType', public\\: false, standard\\: false, requiredField\\: true\\}\\|array\\{title\\: array\\{de\\: 'Gutschein…', en\\: 'Coupon description'\\}, description\\: array\\{de\\: 'Diese Beschreibung…', en\\: 'This description…'\\}, type\\: 'InputMultiLang', public\\: false, standard\\: false, requiredField\\: false\\}\\|array\\{title\\: array\\{de\\: 'Ist Einzweck…', en\\: 'Is single purpose…'\\}, description\\: array\\{de\\: 'Einzweck\\-Gutscheine…', en\\: 'Single\\-purpose…'\\}, type\\: 'BoolType', public\\: false, standard\\: false, requiredField\\: false\\}\\|array\\{title\\: array\\{de\\: 'Kunde darf…', en\\: 'Customer can choose…'\\}, description\\: array\\{de\\: 'Ist diese Funktion…', en\\: 'if this option is…'\\}, type\\: 'BoolType', public\\: false, standard\\: false, requiredField\\: false\\} in empty\\(\\) always exists and is always falsy\\.$#" + count: 1 + path: src/QUI/ERP/Coupons/Events.php + + - + message: "#^Parameter \\#1 \\$id of static method QUI\\\\ERP\\\\Coupons\\\\Handler\\:\\:getCouponCode\\(\\) expects int, string\\|false given\\.$#" + count: 1 + path: src/QUI/ERP/Coupons/Handler.php + + - + message: "#^Call to method createPDF\\(\\) on an unknown class QUI\\\\HtmlToPdf\\\\Document\\.$#" + count: 1 + path: src/QUI/ERP/Coupons/Products/Handler.php + + - + message: "#^Call to method setAttribute\\(\\) on an unknown class QUI\\\\HtmlToPdf\\\\Document\\.$#" + count: 7 + path: src/QUI/ERP/Coupons/Products/Handler.php + + - + message: "#^Call to method setContentHTML\\(\\) on an unknown class QUI\\\\HtmlToPdf\\\\Document\\.$#" + count: 1 + path: src/QUI/ERP/Coupons/Products/Handler.php + + - + message: "#^Call to method setFooterHTML\\(\\) on an unknown class QUI\\\\HtmlToPdf\\\\Document\\.$#" + count: 1 + path: src/QUI/ERP/Coupons/Products/Handler.php + + - + message: "#^Call to method setHeaderHTML\\(\\) on an unknown class QUI\\\\HtmlToPdf\\\\Document\\.$#" + count: 1 + path: src/QUI/ERP/Coupons/Products/Handler.php + + - + message: "#^Instantiated class QUI\\\\HtmlToPdf\\\\Document not found\\.$#" + count: 1 + path: src/QUI/ERP/Coupons/Products/Handler.php + + - + message: "#^Negated boolean expression is always false\\.$#" + count: 1 + path: src/QUI/ERP/Coupons/Products/Handler.php + + - + message: "#^Parameter \\#1 \\$key of method QUI\\\\ERP\\\\Accounting\\\\Article\\:\\:getCustomField\\(\\) expects string, int given\\.$#" + count: 1 + path: src/QUI/ERP/Coupons/Products/Handler.php diff --git a/phpstan.dist.neon b/phpstan.dist.neon index a545a041a3c5b0c758d99bf8c1c49b2a83252eaa..18db987295f4cd08f7b698474102b19b6ecf75da 100644 --- a/phpstan.dist.neon +++ b/phpstan.dist.neon @@ -2,7 +2,7 @@ includes: - phpstan-baseline.neon parameters: - level: 1 + level: 5 paths: - src - ajax diff --git a/phpunit.dist.xml b/phpunit.dist.xml new file mode 100644 index 0000000000000000000000000000000000000000..f6c7becf0c12757beb871a9333e2d81e02aa7cae --- /dev/null +++ b/phpunit.dist.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<phpunit bootstrap="tests/phpunit-bootstrap.php"> + <testsuites> + <testsuite name="Tests"> + <directory>tests/</directory> + </testsuite> + </testsuites> +</phpunit> diff --git a/src/QUI/ERP/Coupons/Events.php b/src/QUI/ERP/Coupons/Events.php index c2e5774aecfb16769c9acf304b9e26b087bc3f15..d528a8367b4157c14ca0c2b597140814616363a0 100644 --- a/src/QUI/ERP/Coupons/Events.php +++ b/src/QUI/ERP/Coupons/Events.php @@ -27,6 +27,7 @@ use function is_string; use function json_decode; use function json_encode; +use function method_exists; /** * Class Events @@ -63,12 +64,12 @@ public static function onAdminLoadFooter(): void * * @param Collector $Collector * @param mixed $Basket - * @param AbstractOrder|null $Order + * @param mixed $Order */ public static function templateOrderProcessBasketEnd( Collector $Collector, mixed $Basket, - AbstractOrder $Order = null + mixed $Order = null ): void { if ( !($Basket instanceof Basket) @@ -96,6 +97,26 @@ public static function templateOrderProcessBasketEnd( ); } + public static function templateOrderSimpleOrder( + Collector $Collector, + AbstractOrder $Order + ): void { + if ($Order instanceof QUI\ERP\Order\OrderInProcess && isset($_GET['coupon'])) { + try { + $code = Handler::sanitizeCode($_GET['coupon']); + + $CouponCode = Handler::getCouponCodeByCode($code); + $CouponCode->checkRedemption(QUI::getUserBySession()); + $CouponCode->addToOrder($Order); + } catch (Exception) { + } + } + + $Collector->append( + '<div data-qui="package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput"></div>' + ); + } + /** * @param QUI\ERP\Order\OrderProcess $OrderProcess * @throws QUI\ERP\Order\Exception @@ -193,7 +214,9 @@ public static function onQuiqqerOrderBasketRemovePos( $Order->setData('quiqqer-coupons', $orderCoupons); try { - $Order->save(); + if (method_exists($Order, 'save')) { + $Order->save(); + } } catch (QUI\Exception) { } } diff --git a/tests/phpunit-bootstrap.php b/tests/phpunit-bootstrap.php new file mode 100644 index 0000000000000000000000000000000000000000..eca92fd67bed8ae4ec424ed82d300119d792f042 --- /dev/null +++ b/tests/phpunit-bootstrap.php @@ -0,0 +1,11 @@ +<?php + +if (!defined('QUIQQER_SYSTEM')) { + define('QUIQQER_SYSTEM', true); +} + +if (!defined('QUIQQER_AJAX')) { + define('QUIQQER_AJAX', true); +} + +require_once __DIR__ . '/../../../../bootstrap.php';