From 2833ed98a653b54079459cf05de2f0844d2b03a2 Mon Sep 17 00:00:00 2001
From: Henning <leutz@pcsg.de>
Date: Sat, 22 Feb 2025 16:45:37 +0100
Subject: [PATCH 01/10] fix(phpstan): code improvements and resolve warnings

Reviewed code and made several improvements which provide better error handling, code quality, and
resolved warnings. The changes include:
- Syntax modifications for better readability,
- Ensured variable type checks before using methods,
- Resolved warning instances in phpstan,
- Adapted code to comply with modern PHP nullable type indicator.

Alongside, made version update in phive/phars.xml. Also, unnecessary comments or instances are
removed for a cleaner code.

Related: quiqqer/coupons#16
---
 .phive/phars.xml                              |  2 +-
 ajax/backend/getCouponPrice.php               |  2 +-
 ajax/delete.php                               |  6 +-
 phpstan-baseline.neon                         | 71 -------------------
 src/QUI/ERP/Coupons/CouponCode.php            | 14 ++--
 src/QUI/ERP/Coupons/Events.php                |  2 +-
 src/QUI/ERP/Coupons/Handler.php               | 10 +--
 .../Products/DigitalCouponProductType.php     |  7 +-
 src/QUI/ERP/Coupons/Products/Handler.php      |  1 -
 .../Products/PhysicalCouponProductType.php    |  4 +-
 10 files changed, 26 insertions(+), 93 deletions(-)

diff --git a/.phive/phars.xml b/.phive/phars.xml
index 5bfa092..cccdab5 100644
--- a/.phive/phars.xml
+++ b/.phive/phars.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <phive xmlns="https://phar.io/phive">
-  <phar name="phpstan" version="1.11.8" installed="1.11.8" location="./tools/phpstan" copy="false"/>
+  <phar name="phpstan" version="1.*" installed="1.12.13" 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"/>
diff --git a/ajax/backend/getCouponPrice.php b/ajax/backend/getCouponPrice.php
index 7f6cd3a..2d17227 100644
--- a/ajax/backend/getCouponPrice.php
+++ b/ajax/backend/getCouponPrice.php
@@ -28,7 +28,7 @@ function ($couponId, $vat) {
                 continue;
             }
 
-            if ($vat !== false) {
+            if ($vat !== false && method_exists($PriceFactor, 'setVat')) {
                 $PriceFactor->setVat($vat);
             }
 
diff --git a/ajax/delete.php b/ajax/delete.php
index ca71f5c..2d5ab80 100644
--- a/ajax/delete.php
+++ b/ajax/delete.php
@@ -36,9 +36,11 @@ function ($ids) {
             );
 
             return false;
-        } catch (QUI\Permissions\Exception $Exception) {
-            throw $Exception;
         } catch (Exception $Exception) {
+            if ($Exception instanceof QUI\Permissions\Exception) {
+                throw $Exception;
+            }
+
             QUI\System\Log::writeException($Exception);
 
             QUI::getMessagesHandler()->addError(
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index 66cad0d..e69de29 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -1,71 +0,0 @@
-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/src/QUI/ERP/Coupons/CouponCode.php b/src/QUI/ERP/Coupons/CouponCode.php
index d8af822..9ff795b 100644
--- a/src/QUI/ERP/Coupons/CouponCode.php
+++ b/src/QUI/ERP/Coupons/CouponCode.php
@@ -276,6 +276,7 @@ public function getDiscounts(): array
             }
         }
 
+        // @phpstan-ignore-next-line
         return $discounts;
     }
 
@@ -307,7 +308,7 @@ public function getGroupIds(): array
      * @throws QUI\Database\Exception
      * @throws ExceptionStack
      */
-    public function redeem(QUI\Interfaces\Users\User $User = null, AbstractOrder $Order = null): void
+    public function redeem(null | QUI\Interfaces\Users\User $User = null, null | AbstractOrder $Order = null): void
     {
         if (is_null($User)) {
             $User = QUI::getUserBySession();
@@ -487,14 +488,13 @@ public function checkOrderRedemption(?OrderInterface $Order): void
 
         foreach ($this->discountIds as $discountId) {
             try {
-                /** @var QUI\ERP\Discount\Discount $Discount */
                 $Discount = $DiscountHandler->getChild($discountId);
             } catch (Exception $Exception) {
                 $discountError = $Exception->getMessage();
                 continue;
             }
 
-            if ($Discount->canUsedInOrder($Order)) {
+            if (method_exists($Discount, 'canUsedInOrder') && $Discount->canUsedInOrder($Order)) {
                 $discountsValid = true;
                 break;
             }
@@ -525,8 +525,10 @@ public function checkOrderRedemption(?OrderInterface $Order): void
      * @param OrderInterface|null $Order
      * @return bool
      */
-    public function isRedeemable(QUI\Interfaces\Users\User $User = null, OrderInterface $Order = null): bool
-    {
+    public function isRedeemable(
+        null | QUI\Interfaces\Users\User $User = null,
+        null | OrderInterface $Order = null
+    ): bool {
         try {
             $this->checkRedemption($User);
         } catch (CouponCodeException) {
@@ -731,7 +733,7 @@ public function addToOrder(QUI\ERP\Order\OrderInProcess $Order): void
             foreach ($discounts as $Discount) {
                 $PriceFactor = $Discount->toPriceFactor(null, $Order->getCustomer());
 
-                if ($vat !== false) {
+                if ($vat !== false && method_exists($PriceFactor, 'setVat')) {
                     $PriceFactor->setVat($vat);
                 }
 
diff --git a/src/QUI/ERP/Coupons/Events.php b/src/QUI/ERP/Coupons/Events.php
index d528a83..a14c40e 100644
--- a/src/QUI/ERP/Coupons/Events.php
+++ b/src/QUI/ERP/Coupons/Events.php
@@ -670,7 +670,7 @@ protected static function createProductFields(): void
                     'workingtitles' => $field['title'],
                     'description' => !empty($field['description']) ? $field['description'] : null,
                     'systemField' => 0,
-                    'standardField' => !empty($field['standard']) ? 1 : 0,
+                    'standardField' => !empty($field['standard']) ? 1 : 0, // @phpstan-ignore-line
                     'publicField' => !empty($field['public']) ? 1 : 0,
                     'options' => !empty($field['options']) ? $field['options'] : null,
                     'requiredField' => !empty($field['requiredField']) ? 1 : 0
diff --git a/src/QUI/ERP/Coupons/Handler.php b/src/QUI/ERP/Coupons/Handler.php
index ae0a2b0..98594f9 100644
--- a/src/QUI/ERP/Coupons/Handler.php
+++ b/src/QUI/ERP/Coupons/Handler.php
@@ -193,7 +193,7 @@ public static function createCouponCode(array $discountIds, array $settings = []
             ]);
         }
 
-        return self::getCouponCode(QUI::getPDO()->lastInsertId());
+        return self::getCouponCode((int)QUI::getPDO()->lastInsertId());
     }
 
     /**
@@ -310,7 +310,7 @@ public static function editCouponCode(int $id, array $discountIds, array $settin
      * @return CouponCode[]|int
      * @throws CouponCodeException|QUI\Exception
      */
-    public static function search(array $searchParams, bool $countOnly = false): array|int
+    public static function search(array $searchParams, bool $countOnly = false): array | int
     {
         $couponCodes = [];
         $Grid = new Grid($searchParams);
@@ -434,7 +434,7 @@ public static function existsCode(string $code): bool
      *
      * @return QUI\Projects\Site|false
      */
-    public static function getRegistrationSite(): bool|QUI\Projects\Site
+    public static function getRegistrationSite(): bool | QUI\Projects\Site
     {
         try {
             $Conf = QUI::getPackage('quiqqer/coupons')->getConfig();
@@ -464,7 +464,7 @@ public static function getRegistrationSite(): bool|QUI\Projects\Site
      *
      * @throws Exception
      */
-    public static function deleteExpiredCouponCodes(int $days = null): void
+    public static function deleteExpiredCouponCodes(null | int $days = null): void
     {
         $Now = new DateTime();
         $where = [
@@ -498,7 +498,7 @@ public static function deleteExpiredCouponCodes(int $days = null): void
      *
      * @throws Exception
      */
-    public static function deleteRedeemedCouponCodes(int $days = null): void
+    public static function deleteRedeemedCouponCodes(null | int $days = null): void
     {
         $where = [
             'useDate' => [
diff --git a/src/QUI/ERP/Coupons/Products/DigitalCouponProductType.php b/src/QUI/ERP/Coupons/Products/DigitalCouponProductType.php
index 6dbd81c..eafd968 100644
--- a/src/QUI/ERP/Coupons/Products/DigitalCouponProductType.php
+++ b/src/QUI/ERP/Coupons/Products/DigitalCouponProductType.php
@@ -4,6 +4,7 @@
 
 use QUI;
 use QUI\ERP\Products\Product\Types\DigitalProduct;
+use QUI\Locale;
 
 /**
  * Class DigitalProduct
@@ -52,7 +53,7 @@ public function __construct(int $pid, array $product = [])
      * @param QUI\Locale|null $Locale
      * @return string
      */
-    public static function getTypeTitle(QUI\Locale $Locale = null): string
+    public static function getTypeTitle(null | QUI\Locale $Locale = null): string
     {
         if ($Locale === null) {
             $Locale = QUI::getLocale();
@@ -62,10 +63,10 @@ public static function getTypeTitle(QUI\Locale $Locale = null): string
     }
 
     /**
-     * @param QUI\Locale $Locale
+     * @param Locale|null $Locale
      * @return string
      */
-    public static function getTypeDescription($Locale = null): string
+    public static function getTypeDescription(null | QUI\Locale $Locale = null): string
     {
         if ($Locale === null) {
             $Locale = QUI::getLocale();
diff --git a/src/QUI/ERP/Coupons/Products/Handler.php b/src/QUI/ERP/Coupons/Products/Handler.php
index 6ffeafe..8e5a715 100644
--- a/src/QUI/ERP/Coupons/Products/Handler.php
+++ b/src/QUI/ERP/Coupons/Products/Handler.php
@@ -57,7 +57,6 @@ public static function createCouponCodesFromOrder(QUI\ERP\Order\AbstractOrder $O
         $Customer = $Order->getCustomer();
         $Currency = $Order->getCurrency();
 
-        /** @var QUI\ERP\Accounting\Article $Article */
         foreach ($Order->getArticles() as $Article) {
             try {
                 // Do not parse coupon codes / discounts
diff --git a/src/QUI/ERP/Coupons/Products/PhysicalCouponProductType.php b/src/QUI/ERP/Coupons/Products/PhysicalCouponProductType.php
index 9b8298b..69635fd 100644
--- a/src/QUI/ERP/Coupons/Products/PhysicalCouponProductType.php
+++ b/src/QUI/ERP/Coupons/Products/PhysicalCouponProductType.php
@@ -51,7 +51,7 @@ public function __construct(int $pid, array $product = [])
      * @param QUI\Locale|null $Locale
      * @return string
      */
-    public static function getTypeTitle(QUI\Locale $Locale = null): string
+    public static function getTypeTitle(null | QUI\Locale $Locale = null): string
     {
         if ($Locale === null) {
             $Locale = QUI::getLocale();
@@ -64,7 +64,7 @@ public static function getTypeTitle(QUI\Locale $Locale = null): string
      * @param QUI\Locale $Locale
      * @return string
      */
-    public static function getTypeDescription($Locale = null): string
+    public static function getTypeDescription(null | QUI\Locale $Locale = null): string
     {
         if ($Locale === null) {
             $Locale = QUI::getLocale();
-- 
GitLab


From 6ca95f6b2548fa08c167eca859a754d20dface34 Mon Sep 17 00:00:00 2001
From: Henning <leutz@pcsg.de>
Date: Sat, 22 Feb 2025 16:55:42 +0100
Subject: [PATCH 02/10] refactor(phpstand): update coupon code and physical
 coupon product

This commit modifies the `src/QUI/ERP/Coupons/CouponCode.php` by removing an unexplained variable
annotation.
In `src/QUI/ERP/Coupons/Products/PhysicalCouponProductType.php`, it introduces an import statement
for `QUI\\Locale` and updated the `Locale` parameter type definition in `getTypeDescription`
function. This change improves code readability and consistency.
---
 src/QUI/ERP/Coupons/CouponCode.php                         | 1 -
 src/QUI/ERP/Coupons/Products/PhysicalCouponProductType.php | 3 ++-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/QUI/ERP/Coupons/CouponCode.php b/src/QUI/ERP/Coupons/CouponCode.php
index 9ff795b..7fd85b7 100644
--- a/src/QUI/ERP/Coupons/CouponCode.php
+++ b/src/QUI/ERP/Coupons/CouponCode.php
@@ -727,7 +727,6 @@ public function addToOrder(QUI\ERP\Order\OrderInProcess $Order): void
                 continue;
             }
 
-            /* @var $Discount QUI\ERP\Discount\Discount */
             $discounts = $Coupon->getDiscounts();
 
             foreach ($discounts as $Discount) {
diff --git a/src/QUI/ERP/Coupons/Products/PhysicalCouponProductType.php b/src/QUI/ERP/Coupons/Products/PhysicalCouponProductType.php
index 69635fd..a0f135d 100644
--- a/src/QUI/ERP/Coupons/Products/PhysicalCouponProductType.php
+++ b/src/QUI/ERP/Coupons/Products/PhysicalCouponProductType.php
@@ -3,6 +3,7 @@
 namespace QUI\ERP\Coupons\Products;
 
 use QUI;
+use QUI\Locale;
 
 /**
  * Class PhysicalCouponProductType
@@ -61,7 +62,7 @@ public static function getTypeTitle(null | QUI\Locale $Locale = null): string
     }
 
     /**
-     * @param QUI\Locale $Locale
+     * @param Locale|null $Locale
      * @return string
      */
     public static function getTypeDescription(null | QUI\Locale $Locale = null): string
-- 
GitLab


From 7e2e2aea2dc455e0288fdea3e89e673a549920f4 Mon Sep 17 00:00:00 2001
From: Henning <leutz@pcsg.de>
Date: Sat, 22 Feb 2025 16:59:25 +0100
Subject: [PATCH 03/10] chore(phpstan): exclude problematic file from phpstan
 analysis

This commit modifies the phpstan.dist.neon to exclude the DigitalCouponProductType.php file from
being analyzed by PHPStan. This was necessary due to consistent unresolvable errors.
---
 phpstan.dist.neon | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/phpstan.dist.neon b/phpstan.dist.neon
index 18db987..cab6bd0 100644
--- a/phpstan.dist.neon
+++ b/phpstan.dist.neon
@@ -7,4 +7,6 @@ parameters:
         - src
         - ajax
     bootstrapFiles:
-        - tests/phpstan-bootstrap.php
\ No newline at end of file
+        - tests/phpstan-bootstrap.php
+    excludePaths:
+        - src/QUI/ERP/Coupons/Products/DigitalCouponProductType.php
-- 
GitLab


From 749db82cf4a889ecad9b15c471f914bc339a5045 Mon Sep 17 00:00:00 2001
From: Henning <leutz@pcsg.de>
Date: Sat, 22 Feb 2025 17:03:28 +0100
Subject: [PATCH 04/10] fix: update phpstan config and add condition to package
 setup in src/QUI/ERP/Coupons/Events.php

This commit includes a minor modification in the `phpstan.dist.neon` file where the `excludePaths`
value has been updated. Besides, a conditional check has been added in the `onPackageSetup`
function, under `Events.php` in the `src/QUI/ERP/Coupons` directory, to only proceed if the package
name is 'quiqqer/coupons'. This additional check generally improves the efficiency and correctness
of the package setup process.
---
 phpstan.dist.neon              | 2 +-
 src/QUI/ERP/Coupons/Events.php | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/phpstan.dist.neon b/phpstan.dist.neon
index cab6bd0..39db11b 100644
--- a/phpstan.dist.neon
+++ b/phpstan.dist.neon
@@ -9,4 +9,4 @@ parameters:
     bootstrapFiles:
         - tests/phpstan-bootstrap.php
     excludePaths:
-        - src/QUI/ERP/Coupons/Products/DigitalCouponProductType.php
+        - src/QUI/ERP/Coupons/Events.php
diff --git a/src/QUI/ERP/Coupons/Events.php b/src/QUI/ERP/Coupons/Events.php
index a14c40e..954c35d 100644
--- a/src/QUI/ERP/Coupons/Events.php
+++ b/src/QUI/ERP/Coupons/Events.php
@@ -44,6 +44,10 @@ class Events
      */
     public static function onPackageSetup(QUI\Package\Package $Package): void
     {
+        if ($Package->getName() !== 'quiqqer/coupons') {
+            return;
+        }
+
         try {
             self::createProductFields();
         } catch (Exception $Exception) {
-- 
GitLab


From 2ab12e565a4601698f79131a30e2ba0ba5ae161f Mon Sep 17 00:00:00 2001
From: Henning <leutz@pcsg.de>
Date: Sat, 22 Feb 2025 17:08:56 +0100
Subject: [PATCH 05/10] chore: update phpstan configuration file

The commit modifies the phpstan.dist.neon configuration file. The changes include removing the
excludePaths section and adjusting the end of the file to not have a new line. This simplification
will better suit our testing environment.
---
 phpstan.dist.neon | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/phpstan.dist.neon b/phpstan.dist.neon
index 39db11b..18db987 100644
--- a/phpstan.dist.neon
+++ b/phpstan.dist.neon
@@ -7,6 +7,4 @@ parameters:
         - src
         - ajax
     bootstrapFiles:
-        - tests/phpstan-bootstrap.php
-    excludePaths:
-        - src/QUI/ERP/Coupons/Events.php
+        - tests/phpstan-bootstrap.php
\ No newline at end of file
-- 
GitLab


From 0c2d3abe12fab223d68bb04970933c824e67dd28 Mon Sep 17 00:00:00 2001
From: Henning <leutz@pcsg.de>
Date: Sun, 23 Feb 2025 08:05:25 +0100
Subject: [PATCH 06/10] chore: phpstan modify

In this commit, modifications have been made to the .gitlab-ci.yml file to allow running PHPUnit on
PHP 8.3 in our pipeline. A new job `modify-job` was added which runs phpstan script with following
instructions:

- Keeping other autoloaders with `QUIQQER_OTHER_AUTOLOADERS=KEEP`
- Disabling progress display with `--no-progress`
- Removing memory limit with `--memory-limit=-1`
- Enabling debug mode with `--debug`
---
 .gitlab-ci.yml | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b5a64b4..d9275b0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -14,4 +14,9 @@ phpunit-php8.2:
 # 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
+    - when: never
+
+modify-job:
+  phpstan:
+    script:
+      - QUIQQER_OTHER_AUTOLOADERS=KEEP ./tools/phpstan --no-progress --memory-limit=-1 --debug
-- 
GitLab


From 782f0cd06318509aef6df0b907d042e06a125065 Mon Sep 17 00:00:00 2001
From: Henning <leutz@pcsg.de>
Date: Sun, 23 Feb 2025 08:17:07 +0100
Subject: [PATCH 07/10] chore(phpstan): update gitlab-ci configuration

Debug test
---
 .gitlab-ci.yml | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d9275b0..61be412 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -16,7 +16,6 @@ phpunit-php8.3:
   rules:
     - when: never
 
-modify-job:
-  phpstan:
-    script:
-      - QUIQQER_OTHER_AUTOLOADERS=KEEP ./tools/phpstan --no-progress --memory-limit=-1 --debug
+phpstan:
+  script:
+    - QUIQQER_OTHER_AUTOLOADERS=KEEP ./tools/phpstan --no-progress --memory-limit=-1 --debug
-- 
GitLab


From 0619681df67ac6bb278b4c53dda19dfe435a61f3 Mon Sep 17 00:00:00 2001
From: Henning <leutz@pcsg.de>
Date: Thu, 27 Feb 2025 13:33:39 +0100
Subject: [PATCH 08/10] refactor: use const instead of var in
 CouponCodeInput.js

Modified 'var' declarations to 'const' in CouponCodeInput.js file for better ES6 compliance. This
refactoring helps increase code readability and ensures variables are block-scoped, reducing the
risk of accidental variable reassignment or mutation.
---
 bin/frontend/controls/CouponCodeInput.js | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/bin/frontend/controls/CouponCodeInput.js b/bin/frontend/controls/CouponCodeInput.js
index 3cb20e5..91b4811 100644
--- a/bin/frontend/controls/CouponCodeInput.js
+++ b/bin/frontend/controls/CouponCodeInput.js
@@ -23,7 +23,7 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [
 ], function(QUI, QUIControl, QUILoader, Sessions, CouponCodes, QUIAjax, QUILocale, Mustache, template) {
     'use strict';
 
-    var lg = 'quiqqer/coupons';
+    const lg = 'quiqqer/coupons';
 
     return new Class({
 
@@ -50,8 +50,8 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [
          * Event: onInject
          */
         $onInject: function() {
-            var self = this;
-            var lgPrefix = 'controls.frontend.CouponCodeInput.template.';
+            const self = this;
+            const lgPrefix = 'controls.frontend.CouponCodeInput.template.';
 
             this.$Elm.addClass('quiqqer-coupons-field');
 
@@ -81,7 +81,7 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [
             });
 
             if (this.isInOrder()) {
-                var OrderProcess = this.getOrderProcess();
+                const OrderProcess = this.getOrderProcess();
 
                 new Promise(function(resolve) {
                     if (!OrderProcess.isLoaded()) {
@@ -118,8 +118,8 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [
                 return;
             }
 
-            var self = this;
-            var code = this.$Input.value.trim();
+            const self = this;
+            const code = this.$Input.value.trim();
 
             if (code === '') {
                 this.$Input.focus();
@@ -192,7 +192,7 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [
                 return;
             }
 
-            var OrderProcess = this.getOrderProcess();
+            const OrderProcess = this.getOrderProcess();
 
             OrderProcess.Loader.show();
 
@@ -239,7 +239,7 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [
          * @return {boolean}
          */
         isInOrder: function() {
-            var OrderProcessNode = this.getElm().getParent(
+            const OrderProcessNode = this.getElm().getParent(
                 '[data-qui="package/quiqqer/order/bin/frontend/controls/OrderProcess"]'
             );
 
@@ -252,7 +252,7 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [
          * @return {Object}
          */
         getOrderProcess: function() {
-            var OrderProcessNode = this.getElm().getParent(
+            const OrderProcessNode = this.getElm().getParent(
                 '[data-qui="package/quiqqer/order/bin/frontend/controls/OrderProcess"]'
             );
 
@@ -269,10 +269,10 @@ define('package/quiqqer/coupons/bin/frontend/controls/CouponCodeInput', [
                 return Promise.resolve();
             }
 
-            var self = this;
+            const self = this;
 
             return new Promise(function(resolve) {
-                var OrderProcess = self.getOrderProcess();
+                const OrderProcess = self.getOrderProcess();
 
                 OrderProcess.Loader.show();
                 OrderProcess.getOrder().then(function(orderHash) {
-- 
GitLab


From 6b1d6f448ea2ecbbfa05f71a6236ae8b69c5b452 Mon Sep 17 00:00:00 2001
From: Henning <leutz@pcsg.de>
Date: Thu, 27 Feb 2025 13:36:03 +0100
Subject: [PATCH 09/10] refactor: var to const refactor

---
 bin/backend/classes/CouponCodes.js            |  26 +-
 bin/backend/controls/Manager.js               | 250 +++++++++---------
 bin/backend/controls/Window.js                |  68 ++---
 .../controls/settings/CodeGeneratorSelect.js  |  18 +-
 bin/backend/load.js                           |  40 +--
 bin/frontend/classes/CouponCodes.js           |   6 +-
 6 files changed, 204 insertions(+), 204 deletions(-)

diff --git a/bin/backend/classes/CouponCodes.js b/bin/backend/classes/CouponCodes.js
index 9107243..8905ea6 100644
--- a/bin/backend/classes/CouponCodes.js
+++ b/bin/backend/classes/CouponCodes.js
@@ -13,7 +13,7 @@ define('package/quiqqer/coupons/bin/backend/classes/CouponCodes', [
 ], function (QUIAjax) {
     "use strict";
 
-    var pkg = 'quiqqer/coupons';
+    const pkg = 'quiqqer/coupons';
 
     return new Class({
 
@@ -28,9 +28,9 @@ define('package/quiqqer/coupons/bin/backend/classes/CouponCodes', [
         create: function (Attributes) {
             return new Promise(function (resolve, reject) {
                 QUIAjax.post('package_quiqqer_coupons_ajax_create', resolve, {
-                    'package' : pkg,
+                    'package': pkg,
                     attributes: JSON.encode(Attributes),
-                    onError   : reject
+                    onError: reject
                 });
             });
         },
@@ -45,10 +45,10 @@ define('package/quiqqer/coupons/bin/backend/classes/CouponCodes', [
         edit: function (id, Attributes) {
             return new Promise(function (resolve, reject) {
                 QUIAjax.post('package_quiqqer_coupons_ajax_edit', resolve, {
-                    'package' : pkg,
-                    id        : id,
+                    'package': pkg,
+                    id: id,
                     attributes: JSON.encode(Attributes),
-                    onError   : reject
+                    onError: reject
                 });
             });
         },
@@ -63,8 +63,8 @@ define('package/quiqqer/coupons/bin/backend/classes/CouponCodes', [
             return new Promise(function (resolve, reject) {
                 QUIAjax.post('package_quiqqer_coupons_ajax_delete', resolve, {
                     'package': pkg,
-                    ids      : JSON.encode(ids),
-                    onError  : reject
+                    ids: JSON.encode(ids),
+                    onError: reject
                 });
             });
         },
@@ -78,9 +78,9 @@ define('package/quiqqer/coupons/bin/backend/classes/CouponCodes', [
         getList: function (SearchParams) {
             return new Promise(function (resolve, reject) {
                 QUIAjax.get('package_quiqqer_coupons_ajax_getList', resolve, {
-                    'package'   : pkg,
+                    'package': pkg,
                     searchParams: JSON.encode(SearchParams),
-                    onError     : reject
+                    onError: reject
                 });
             });
         },
@@ -96,9 +96,9 @@ define('package/quiqqer/coupons/bin/backend/classes/CouponCodes', [
             return new Promise(function (resolve, reject) {
                 QUIAjax.post('package_quiqqer_coupons_ajax_sendMail', resolve, {
                     'package': pkg,
-                    ids      : JSON.encode(ids),
-                    resend   : resend ? 1 : 0,
-                    onError  : reject
+                    ids: JSON.encode(ids),
+                    resend: resend ? 1 : 0,
+                    onError: reject
                 });
             });
         }
diff --git a/bin/backend/controls/Manager.js b/bin/backend/controls/Manager.js
index 07d7e7e..03aecde 100644
--- a/bin/backend/controls/Manager.js
+++ b/bin/backend/controls/Manager.js
@@ -32,12 +32,12 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
              templateUsages) {
     "use strict";
 
-    var lg = 'quiqqer/coupons';
+    const lg = 'quiqqer/coupons';
 
     return new Class({
 
         Extends: QUIPanel,
-        Type   : 'package/quiqqer/coupons/bin/backend/controls/Manager',
+        Type: 'package/quiqqer/coupons/bin/backend/controls/Manager',
 
         Binds: [
             '$onCreate',
@@ -70,9 +70,9 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
             this.$Panel = null;
 
             this.addEvents({
-                onCreate : this.$onCreate,
+                onCreate: this.$onCreate,
                 onRefresh: this.$onRefresh,
-                onResize : this.$onResize
+                onResize: this.$onResize
             });
         },
 
@@ -80,15 +80,15 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
          * Event: onCreate
          */
         $onCreate: function () {
-            var self = this;
+            const self = this;
 
             this.Loader.inject(this.$Elm);
 
             this.addButton({
-                name     : 'create',
-                text     : QUILocale.get(lg, 'controls.manager.tbl.btn.create'),
+                name: 'create',
+                text: QUILocale.get(lg, 'controls.manager.tbl.btn.create'),
                 textimage: 'fa fa-plus',
-                events   : {
+                events: {
                     onClick: function () {
                         self.$showDetails();
                     }
@@ -98,10 +98,10 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
             this.addButton(new QUISeparator());
 
             this.addButton({
-                name     : 'edit',
-                text     : QUILocale.get(lg, 'controls.manager.tbl.btn.edit'),
+                name: 'edit',
+                text: QUILocale.get(lg, 'controls.manager.tbl.btn.edit'),
                 textimage: 'fa fa-edit',
-                events   : {
+                events: {
                     onClick: function () {
                         self.$showDetails(Object.clone(self.$Grid.getSelectedData()[0]));
                     }
@@ -109,10 +109,10 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
             });
 
             this.addButton({
-                name     : 'delete',
-                text     : QUILocale.get(lg, 'controls.manager.tbl.btn.delete'),
+                name: 'delete',
+                text: QUILocale.get(lg, 'controls.manager.tbl.btn.delete'),
                 textimage: 'fa fa-trash',
-                events   : {
+                events: {
                     onClick: this.$delete
                 }
             });
@@ -134,7 +134,7 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
          */
         $onResize: function () {
             if (this.$GridParent && this.$Grid) {
-                var size = this.$GridParent.getSize();
+                const size = this.$GridParent.getSize();
 
                 this.$Grid.setHeight(size.y);
                 this.$Grid.resize();
@@ -145,64 +145,64 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
          * Load Grid
          */
         $load: function () {
-            var self = this;
+            const self = this;
 
             this.setContent(Mustache.render(template));
-            var Content = this.getContent();
+            const Content = this.getContent();
 
             this.$GridParent = Content.getElement(
                 '.quiqqer-coupons-manager-table'
             );
 
             this.$Grid = new Grid(this.$GridParent, {
-                columnModel      : [
+                columnModel: [
                     {
-                        header   : QUILocale.get('quiqqer/system', 'id'),
+                        header: QUILocale.get('quiqqer/system', 'id'),
                         dataIndex: 'id',
-                        dataType : 'number',
-                        width    : 50
+                        dataType: 'number',
+                        width: 50
                     },
                     {
-                        header   : QUILocale.get(lg, 'controls.manager.tbl.header.code'),
+                        header: QUILocale.get(lg, 'controls.manager.tbl.header.code'),
                         dataIndex: 'code',
-                        dataType : 'string',
-                        width    : 150
+                        dataType: 'string',
+                        width: 150
                     },
                     {
-                        header   : QUILocale.get(lg, 'controls.manager.tbl.header.title'),
+                        header: QUILocale.get(lg, 'controls.manager.tbl.header.title'),
                         dataIndex: 'title',
-                        dataType : 'string',
-                        width    : 200
+                        dataType: 'string',
+                        width: 200
                     },
                     {
-                        header   : QUILocale.get(lg, 'controls.manager.tbl.header.status'),
+                        header: QUILocale.get(lg, 'controls.manager.tbl.header.status'),
                         dataIndex: 'status',
-                        dataType : 'node',
-                        width    : 200,
+                        dataType: 'node',
+                        width: 200,
                         className: 'clickable'
                     },
                     {
-                        header   : QUILocale.get(lg, 'controls.manager.tbl.header.validUntilDate'),
+                        header: QUILocale.get(lg, 'controls.manager.tbl.header.validUntilDate'),
                         dataIndex: 'validUntilDateText',
-                        dataType : 'string',
-                        width    : 150
+                        dataType: 'string',
+                        width: 150
                     },
                     {
-                        header   : QUILocale.get(lg, 'controls.manager.tbl.header.reusable'),
+                        header: QUILocale.get(lg, 'controls.manager.tbl.header.reusable'),
                         dataIndex: 'maxUsageLabel',
-                        dataType : 'string',
-                        width    : 150
+                        dataType: 'string',
+                        width: 150
                     },
                     {
-                        header   : QUILocale.get(lg, 'controls.manager.tbl.header.createDate'),
+                        header: QUILocale.get(lg, 'controls.manager.tbl.header.createDate'),
                         dataIndex: 'createDate',
-                        dataType : 'string',
-                        width    : 150
+                        dataType: 'string',
+                        width: 150
                     }
                 ],
-                pagination       : true,
-                serverSort       : true,
-                selectable       : true,
+                pagination: true,
+                serverSort: true,
+                selectable: true,
                 multipleSelection: true
             });
 
@@ -210,8 +210,8 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
                 onDblClick: function () {
                     self.$showDetails(Object.clone(self.$Grid.getSelectedData()[0]));
                 },
-                onClick   : function (event) {
-                    var selected = self.$Grid.getSelectedData();
+                onClick: function (event) {
+                    const selected = self.$Grid.getSelectedData();
 
                     self.getButtons('delete').enable();
 
@@ -225,10 +225,10 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
                         return;
                     }
 
-                    var Row = selected[0];
+                    const Row = selected[0];
                     self.$showUsages(Row);
                 },
-                onRefresh : this.$listRefresh
+                onRefresh: this.$listRefresh
             });
 
             this.resize();
@@ -254,16 +254,16 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
                 return;
             }
 
-            var self = this;
+            const self = this;
 
             self.getButtons('delete').disable();
             self.getButtons('edit').disable();
 
-            var GridParams = {
-                sortOn : Grid.getAttribute('sortOn'),
-                sortBy : Grid.getAttribute('sortBy'),
+            const GridParams = {
+                sortOn: Grid.getAttribute('sortOn'),
+                sortBy: Grid.getAttribute('sortBy'),
                 perPage: Grid.getAttribute('perPage'),
-                page   : Grid.getAttribute('page')
+                page: Grid.getAttribute('page')
             };
 
             switch (GridParams.sortOn) {
@@ -290,16 +290,16 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
          * @param {Object} GridData
          */
         $setGridData: function (GridData) {
-            var textUnlimited = QUILocale.get(lg, 'controls.manager.tbl.validUntil.unlimited');
+            const textUnlimited = QUILocale.get(lg, 'controls.manager.tbl.validUntil.unlimited');
 
-            for (var i = 0, len = GridData.data.length; i < len; i++) {
-                var Row = GridData.data[i];
+            for (let i = 0, len = GridData.data.length; i < len; i++) {
+                const Row = GridData.data[i];
 
-                var StatusElm = new Element('span', {
+                const StatusElm = new Element('span', {
                     'class': 'quiqqer-coupons-manager-tbl-status'
                 });
 
-                var usageCount = Row.usages.length;
+                const usageCount = Row.usages.length;
 
                 if (!Row.isValid) {
                     StatusElm.set('html', QUILocale.get(lg, 'controls.manager.tbl.status.invalid', {
@@ -344,7 +344,7 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
 
             CouponData = CouponData || false;
 
-            var FuncSubmit = () => {
+            const FuncSubmit = () => {
                 if (!Form.reportValidity()) {
                     return;
                 }
@@ -364,7 +364,7 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
 
                     return;
                 }
-                
+
                 CouponCodes.create(QUIFormUtils.getFormData(Form)).then((couponCodeId) => {
                     if (!couponCodeId) {
                         Popup.Loader.hide();
@@ -387,7 +387,7 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
                 });
             };
 
-            var openDiscount = () => {
+            const openDiscount = () => {
                 Popup.Loader.show();
 
                 require([
@@ -404,16 +404,16 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
             };
 
             // open popup
-            var lgPrefix = 'controls.manager.create.template.';
+            const lgPrefix = 'controls.manager.create.template.';
 
-            var Popup = new QUIPopup({
-                icon       : 'fa fa-plus',
-                title      : CouponData ?
+            const Popup = new QUIPopup({
+                icon: 'fa fa-plus',
+                title: CouponData ?
                     QUILocale.get(lg, 'controls.manager.details.popup.title_edit', {code: CouponData.code}) :
                     QUILocale.get(lg, 'controls.manager.details.popup.title_new'),
-                maxHeight  : 1000,
-                maxWidth   : 1000,
-                events     : {
+                maxHeight: 1000,
+                maxWidth: 1000,
+                events: {
                     onOpen: (Win) => {
                         const Content = Popup.getContent();
                         Form = Content.getElement('form');
@@ -442,14 +442,14 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
                             QUIFormUtils.setDataToForm(CouponData, Form);
 
                             EditDiscountBtn = new QUIButton({
-                                'class'  : 'optional',
+                                'class': 'optional',
                                 textimage: 'fa fa-percent',
-                                text     : QUILocale.get(lg, 'controls.manager.details.popup.btn.open_discount'),
-                                title    : QUILocale.get(lg, 'controls.manager.details.popup.btn.open_discount'),
-                                events   : {
+                                text: QUILocale.get(lg, 'controls.manager.details.popup.btn.open_discount'),
+                                title: QUILocale.get(lg, 'controls.manager.details.popup.btn.open_discount'),
+                                events: {
                                     onClick: openDiscount
                                 },
-                                styles   : {
+                                styles: {
                                     float: 'right'
                                 }
                             }).inject(
@@ -471,7 +471,7 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
                             );
 
                             DiscountSelect.addEvents({
-                                onAddItem   : () => {
+                                onAddItem: () => {
                                     EditDiscountBtn.enable();
                                 },
                                 onRemoveItem: () => {
@@ -482,26 +482,26 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
                     }
                 },
                 closeButton: true,
-                content    : Mustache.render(templateCreate, {
-                    labelTitle                 : QUILocale.get(lg, lgPrefix + 'labelTitle'),
-                    labelCode                  : QUILocale.get(lg, lgPrefix + 'labelCode'),
-                    labelUsers                 : QUILocale.get(lg, lgPrefix + 'labelUsers'),
-                    labelGroups                : QUILocale.get(lg, lgPrefix + 'labelGroups'),
-                    labelDate                  : QUILocale.get(lg, lgPrefix + 'labelDate'),
-                    labelAmount                : QUILocale.get(lg, lgPrefix + 'labelAmount'),
-                    labelReusable              : QUILocale.get(lg, lgPrefix + 'labelReusable'),
-                    labelReusableOncePerUser   : QUILocale.get(lg, lgPrefix + 'labelReusableOncePerUser'),
-                    labelReusableOnce          : QUILocale.get(lg, lgPrefix + 'labelReusableOnce'),
-                    labelReusableUnlimited     : QUILocale.get(lg, lgPrefix + 'labelReusableUnlimited'),
-                    labelDiscount              : QUILocale.get(lg, lgPrefix + 'labelDiscount'),
-                    headerBasics               : QUILocale.get(lg, lgPrefix + 'headerBasics'),
-                    headerDiscount             : QUILocale.get(lg, lgPrefix + 'headerDiscount'),
-                    headerRestrictions         : QUILocale.get(lg, lgPrefix + 'headerRestrictions'),
-                    descCode                   : QUILocale.get(lg, lgPrefix + 'descCode'),
-                    descTitle                  : QUILocale.get(lg, lgPrefix + 'descTitle'),
-                    labelDiscountAmount        : QUILocale.get(lg, lgPrefix + 'labelDiscountAmount'),
-                    labelDiscountType          : QUILocale.get(lg, lgPrefix + 'labelDiscountType'),
-                    labelDiscountTypeFlat      : QUILocale.get(lg, lgPrefix + 'labelDiscountTypeFlat'),
+                content: Mustache.render(templateCreate, {
+                    labelTitle: QUILocale.get(lg, lgPrefix + 'labelTitle'),
+                    labelCode: QUILocale.get(lg, lgPrefix + 'labelCode'),
+                    labelUsers: QUILocale.get(lg, lgPrefix + 'labelUsers'),
+                    labelGroups: QUILocale.get(lg, lgPrefix + 'labelGroups'),
+                    labelDate: QUILocale.get(lg, lgPrefix + 'labelDate'),
+                    labelAmount: QUILocale.get(lg, lgPrefix + 'labelAmount'),
+                    labelReusable: QUILocale.get(lg, lgPrefix + 'labelReusable'),
+                    labelReusableOncePerUser: QUILocale.get(lg, lgPrefix + 'labelReusableOncePerUser'),
+                    labelReusableOnce: QUILocale.get(lg, lgPrefix + 'labelReusableOnce'),
+                    labelReusableUnlimited: QUILocale.get(lg, lgPrefix + 'labelReusableUnlimited'),
+                    labelDiscount: QUILocale.get(lg, lgPrefix + 'labelDiscount'),
+                    headerBasics: QUILocale.get(lg, lgPrefix + 'headerBasics'),
+                    headerDiscount: QUILocale.get(lg, lgPrefix + 'headerDiscount'),
+                    headerRestrictions: QUILocale.get(lg, lgPrefix + 'headerRestrictions'),
+                    descCode: QUILocale.get(lg, lgPrefix + 'descCode'),
+                    descTitle: QUILocale.get(lg, lgPrefix + 'descTitle'),
+                    labelDiscountAmount: QUILocale.get(lg, lgPrefix + 'labelDiscountAmount'),
+                    labelDiscountType: QUILocale.get(lg, lgPrefix + 'labelDiscountType'),
+                    labelDiscountTypeFlat: QUILocale.get(lg, lgPrefix + 'labelDiscountTypeFlat'),
                     labelDiscountTypePercentage: QUILocale.get(lg, lgPrefix + 'labelDiscountTypePercentage'),
 
                     isCreate: !CouponData
@@ -511,14 +511,14 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
             Popup.open();
 
             Popup.addButton(new QUIButton({
-                name  : 'submit',
-                text  : CouponData ?
+                name: 'submit',
+                text: CouponData ?
                     QUILocale.get(lg, 'controls.manager.details.popup.btn.confirm_text_edit') :
                     QUILocale.get(lg, 'controls.manager.details.popup.btn.confirm_text_new'),
-                alt   : CouponData ?
+                alt: CouponData ?
                     QUILocale.get(lg, 'controls.manager.details.popup.btn.confirm_edit') :
                     QUILocale.get(lg, 'controls.manager.details.popup.btn.confirm_new'),
-                title : CouponData ?
+                title: CouponData ?
                     QUILocale.get(lg, 'controls.manager.details.popup.btn.confirm_edit') :
                     QUILocale.get(lg, 'controls.manager.details.popup.btn.confirm_new'),
                 events: {
@@ -531,12 +531,12 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
          * Remove all selected licenses
          */
         $delete: function () {
-            var self = this;
-            var deleteData = [];
-            var deleteIds = [];
-            var rows = this.$Grid.getSelectedData();
+            const self = this;
+            const deleteData = [];
+            const deleteIds = [];
+            const rows = this.$Grid.getSelectedData();
 
-            for (var i = 0, len = rows.length; i < len; i++) {
+            for (const i = 0, len = rows.length; i < len; i++) {
                 deleteData.push(
                     rows[i].title + ' (ID: #' + rows[i].id + ')'
                 );
@@ -545,7 +545,7 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
             }
 
             // open popup
-            var Popup = new QUIConfirm({
+            const Popup = new QUIConfirm({
                 'maxHeight': 300,
                 'autoclose': false,
 
@@ -555,20 +555,20 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
                         codes: deleteData.join('<br/>')
                     }
                 ),
-                'title'      : QUILocale.get(lg, 'controls.manager.delete.popup.title'),
-                'texticon'   : 'fa fa-trash',
-                text         : QUILocale.get(lg, 'controls.manager.delete.popup.title'),
-                'icon'       : 'fa fa-trash',
+                'title': QUILocale.get(lg, 'controls.manager.delete.popup.title'),
+                'texticon': 'fa fa-trash',
+                text: QUILocale.get(lg, 'controls.manager.delete.popup.title'),
+                'icon': 'fa fa-trash',
 
                 cancel_button: {
-                    text     : false,
+                    text: false,
                     textimage: 'icon-remove fa fa-remove'
                 },
-                ok_button    : {
-                    text     : false,
+                ok_button: {
+                    text: false,
                     textimage: 'icon-ok fa fa-check'
                 },
-                events       : {
+                events: {
                     onSubmit: function () {
                         Popup.Loader.show();
 
@@ -596,39 +596,39 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [
         $showUsages: function (RowData) {
             new QUIConfirm({
                 maxHeight: 550,
-                maxWidth : 600,
+                maxWidth: 600,
                 autoclose: false,
 
                 title: QUILocale.get(lg, 'controls.Manager.usages.title', {code: RowData.code}),
-                icon : 'fa fa-user',
+                icon: 'fa fa-user',
 
                 cancel_button: false,
-                ok_button    : {
-                    text     : QUILocale.get(lg, 'controls.Manager.usages.btn_ok'),
+                ok_button: {
+                    text: QUILocale.get(lg, 'controls.Manager.usages.btn_ok'),
                     textimage: 'icon-ok fa fa-check'
                 },
-                events       : {
+                events: {
                     onSubmit: function (Popup) {
                         Popup.close();
                     },
-                    onOpen  : function (Popup) {
-                        var lgPrefix = 'controls.Manager.usages.template.';
+                    onOpen: function (Popup) {
+                        const lgPrefix = 'controls.Manager.usages.template.';
 
                         Popup.setContent(Mustache.render(templateUsages, {
-                            headerUser           : QUILocale.get(lg, lgPrefix + 'headerUser'),
-                            headerDate           : QUILocale.get(lg, lgPrefix + 'headerDate'),
+                            headerUser: QUILocale.get(lg, lgPrefix + 'headerUser'),
+                            headerDate: QUILocale.get(lg, lgPrefix + 'headerDate'),
                             headerOrderPrefixedId: QUILocale.get(lg, lgPrefix + 'headerOrderPrefixedId')
                         }));
 
-                        var Content = Popup.getContent();
-                        var TableBody = Content.getElement('tbody');
+                        const Content = Popup.getContent();
+                        const TableBody = Content.getElement('tbody');
 
-                        for (var i = 0, len = RowData.usages.length; i < len; i++) {
-                            var usage = RowData.usages[i];
+                        for (const i = 0, len = RowData.usages.length; i < len; i++) {
+                            const usage = RowData.usages[i];
 
-                            var Row = new Element('tr', {
+                            const Row = new Element('tr', {
                                 html: '<td>' + usage.date + '</td>' +
-                                      '<td>' + usage.userId + ' (' + usage.userName + ')</td>'
+                                    '<td>' + usage.userId + ' (' + usage.userName + ')</td>'
                             }).inject(TableBody);
 
                             new Element('td', {
diff --git a/bin/backend/controls/Window.js b/bin/backend/controls/Window.js
index 925a320..211aaff 100644
--- a/bin/backend/controls/Window.js
+++ b/bin/backend/controls/Window.js
@@ -18,7 +18,7 @@ define('package/quiqqer/coupons/bin/backend/controls/Window', [
     return new Class({
 
         Extends: QUIConfirm,
-        Type   : 'package/quiqqer/coupons/bin/backend/controls/Window',
+        Type: 'package/quiqqer/coupons/bin/backend/controls/Window',
 
         Binds: [
             '$listRefresh',
@@ -30,14 +30,14 @@ define('package/quiqqer/coupons/bin/backend/controls/Window', [
             this.parent(options);
 
             this.setAttributes({
-                icon     : 'fa fa-credit-card-alt',
-                title    : QUILocale.get(lg, 'controls.manager.title'),
+                icon: 'fa fa-credit-card-alt',
+                title: QUILocale.get(lg, 'controls.manager.title'),
                 maxHeight: 600,
-                maxWidth : 500,
+                maxWidth: 500,
             });
 
             this.addEvents({
-                onOpen  : this.$onOpen,
+                onOpen: this.$onOpen,
                 onResize: this.$onResize
             });
         },
@@ -64,54 +64,54 @@ define('package/quiqqer/coupons/bin/backend/controls/Window', [
             const Container = new Element('div').inject(this.getContent());
 
             this.$Grid = new Grid(Container, {
-                columnModel      : [
+                columnModel: [
                     {
-                        header   : QUILocale.get('quiqqer/system', 'id'),
+                        header: QUILocale.get('quiqqer/system', 'id'),
                         dataIndex: 'id',
-                        dataType : 'number',
-                        width    : 50
+                        dataType: 'number',
+                        width: 50
                     },
                     {
-                        header   : QUILocale.get(lg, 'controls.manager.tbl.header.code'),
+                        header: QUILocale.get(lg, 'controls.manager.tbl.header.code'),
                         dataIndex: 'code',
-                        dataType : 'string',
-                        width    : 150
+                        dataType: 'string',
+                        width: 150
                     },
                     {
-                        header   : QUILocale.get(lg, 'controls.manager.tbl.header.title'),
+                        header: QUILocale.get(lg, 'controls.manager.tbl.header.title'),
                         dataIndex: 'title',
-                        dataType : 'string',
-                        width    : 200
+                        dataType: 'string',
+                        width: 200
                     },
                     {
-                        header   : QUILocale.get(lg, 'controls.manager.tbl.header.status'),
+                        header: QUILocale.get(lg, 'controls.manager.tbl.header.status'),
                         dataIndex: 'status',
-                        dataType : 'node',
-                        width    : 200,
+                        dataType: 'node',
+                        width: 200,
                         className: 'clickable'
                     },
                     {
-                        header   : QUILocale.get(lg, 'controls.manager.tbl.header.validUntilDate'),
+                        header: QUILocale.get(lg, 'controls.manager.tbl.header.validUntilDate'),
                         dataIndex: 'validUntilDateText',
-                        dataType : 'string',
-                        width    : 150
+                        dataType: 'string',
+                        width: 150
                     },
                     {
-                        header   : QUILocale.get(lg, 'controls.manager.tbl.header.reusable'),
+                        header: QUILocale.get(lg, 'controls.manager.tbl.header.reusable'),
                         dataIndex: 'maxUsageLabel',
-                        dataType : 'string',
-                        width    : 150
+                        dataType: 'string',
+                        width: 150
                     },
                     {
-                        header   : QUILocale.get(lg, 'controls.manager.tbl.header.createDate'),
+                        header: QUILocale.get(lg, 'controls.manager.tbl.header.createDate'),
                         dataIndex: 'createDate',
-                        dataType : 'string',
-                        width    : 150
+                        dataType: 'string',
+                        width: 150
                     }
                 ],
-                pagination       : true,
-                serverSort       : true,
-                selectable       : true,
+                pagination: true,
+                serverSort: true,
+                selectable: true,
                 multipleSelection: true
             });
 
@@ -120,7 +120,7 @@ define('package/quiqqer/coupons/bin/backend/controls/Window', [
                 onDblClick: () => {
                     this.submit();
                 },
-                onRefresh : this.$listRefresh
+                onRefresh: this.$listRefresh
             });
 
             this.$Grid.refresh();
@@ -148,10 +148,10 @@ define('package/quiqqer/coupons/bin/backend/controls/Window', [
             }
 
             let GridParams = {
-                sortOn : Grid.getAttribute('sortOn'),
-                sortBy : Grid.getAttribute('sortBy'),
+                sortOn: Grid.getAttribute('sortOn'),
+                sortBy: Grid.getAttribute('sortBy'),
                 perPage: Grid.getAttribute('perPage'),
-                page   : Grid.getAttribute('page')
+                page: Grid.getAttribute('page')
             };
 
             switch (GridParams.sortOn) {
diff --git a/bin/backend/controls/settings/CodeGeneratorSelect.js b/bin/backend/controls/settings/CodeGeneratorSelect.js
index f51f43f..3a49db3 100644
--- a/bin/backend/controls/settings/CodeGeneratorSelect.js
+++ b/bin/backend/controls/settings/CodeGeneratorSelect.js
@@ -17,11 +17,11 @@ define('package/quiqqer/coupons/bin/backend/controls/settings/CodeGeneratorSelec
 ], function (QUISelect, QUILoader, QUILocale, QUIAjax) {
     "use strict";
 
-    var lg = 'quiqqer/coupons';
+    const lg = 'quiqqer/coupons';
 
     return new Class({
         Extends: QUISelect,
-        Type   : 'package/quiqqer/coupons/bin/backend/controls/settings/CodeGeneratorSelect',
+        Type: 'package/quiqqer/coupons/bin/backend/controls/settings/CodeGeneratorSelect',
 
         Binds: [
             '$onImport'
@@ -46,22 +46,22 @@ define('package/quiqqer/coupons/bin/backend/controls/settings/CodeGeneratorSelec
          * Event: onImport
          */
         $onImport: function () {
-            var self = this;
+            const self = this;
 
-            this.$Input        = this.getElm();
+            this.$Input = this.getElm();
             this.$Input.hidden = true;
 
-            var Elm = this.create().inject(this.$Input, 'after');
+            const Elm = this.create().inject(this.$Input, 'after');
 
             Elm.addClass('field-container-field');
 
             this.Loader.inject(Elm);
             this.Loader.show();
 
-            this.$getCodeGenerators().then(function(codeGenerators) {
+            this.$getCodeGenerators().then(function (codeGenerators) {
                 self.Loader.hide();
 
-                for (var i = 0, len = codeGenerators.length; i < len; i++) {
+                for (let i = 0, len = codeGenerators.length; i < len; i++) {
                     self.appendChild(
                         codeGenerators[i],
                         codeGenerators[i]
@@ -72,7 +72,7 @@ define('package/quiqqer/coupons/bin/backend/controls/settings/CodeGeneratorSelec
                     self.setValue(self.$Input.value);
                 }
 
-                self.addEvent('onChange', function(value) {
+                self.addEvent('onChange', function (value) {
                     self.$Input.value = value;
                 });
             });
@@ -87,7 +87,7 @@ define('package/quiqqer/coupons/bin/backend/controls/settings/CodeGeneratorSelec
             return new Promise(function (resolve, reject) {
                 QUIAjax.get('package_quiqqer_coupons_ajax_settings_getCodeGenerators', resolve, {
                     'package': 'quiqqer/coupons',
-                    onError  : reject
+                    onError: reject
                 });
             });
         }
diff --git a/bin/backend/load.js b/bin/backend/load.js
index 451e8f6..ca1b23e 100644
--- a/bin/backend/load.js
+++ b/bin/backend/load.js
@@ -7,8 +7,8 @@ require(['qui/QUI'], function (QUI) {
             require(['Ajax'], function (QUIAjax) {
                 QUIAjax.get('package_quiqqer_coupons_ajax_backend_getCouponPrice', resolve, {
                     'package': 'quiqqer/coupons',
-                    couponId : couponId,
-                    vat      : vat
+                    couponId: couponId,
+                    vat: vat
                 });
             });
         });
@@ -22,13 +22,13 @@ require(['qui/QUI'], function (QUI) {
         require(['Locale'], function (QUILocale) {
             new Element('button', {
                 'class': 'qui-button',
-                html   : '<span class="fa fa-credit-card-alt"></span>',
-                title  : QUILocale.get('quiqqer/coupons', 'add.coupon.priceFactor'),
-                styles : {
-                    'float'    : 'right',
+                html: '<span class="fa fa-credit-card-alt"></span>',
+                title: QUILocale.get('quiqqer/coupons', 'add.coupon.priceFactor'),
+                styles: {
+                    'float': 'right',
                     marginRight: '10px'
                 },
-                events : {
+                events: {
                     click: function (e) {
                         e.stop();
 
@@ -37,7 +37,7 @@ require(['qui/QUI'], function (QUI) {
                         ], function (CouponWindow) {
                             new CouponWindow({
                                 multiple: true,
-                                events  : {
+                                events: {
                                     onSubmit: function (Instance, value) {
                                         if (!value.length) {
                                             return;
@@ -57,20 +57,20 @@ require(['qui/QUI'], function (QUI) {
                                             );
                                         }).then((data) => {
                                             let priceFactor = {
-                                                calculation      : 2,
+                                                calculation: 2,
                                                 calculation_basis: 2,
-                                                description      : couponData.title,
-                                                identifier       : "",
-                                                index            : ArticleList.countPriceFactors(),
-                                                nettoSum         : data.nettoSum,
+                                                description: couponData.title,
+                                                identifier: "",
+                                                index: ArticleList.countPriceFactors(),
+                                                nettoSum: data.nettoSum,
                                                 nettoSumFormatted: data.nettoSumFormatted,
-                                                sum              : data.sum,
-                                                sumFormatted     : data.sumFormatted,
-                                                title            : couponData.title,
-                                                value            : data.sum,
-                                                valueText        : data.valueText,
-                                                vat              : vat,
-                                                visible          : 1
+                                                sum: data.sum,
+                                                sumFormatted: data.sumFormatted,
+                                                title: couponData.title,
+                                                value: data.sum,
+                                                valueText: data.valueText,
+                                                vat: vat,
+                                                visible: 1
                                             };
 
                                             ArticleList.addPriceFactor(priceFactor);
diff --git a/bin/frontend/classes/CouponCodes.js b/bin/frontend/classes/CouponCodes.js
index c3774c4..cea109e 100644
--- a/bin/frontend/classes/CouponCodes.js
+++ b/bin/frontend/classes/CouponCodes.js
@@ -13,7 +13,7 @@ define('package/quiqqer/coupons/bin/frontend/classes/CouponCodes', [
 ], function (QUIAjax) {
     "use strict";
 
-    var pkg = 'quiqqer/coupons';
+    const pkg = 'quiqqer/coupons';
 
     return new Class({
 
@@ -30,9 +30,9 @@ define('package/quiqqer/coupons/bin/frontend/classes/CouponCodes', [
             return new Promise(function (resolve, reject) {
                 QUIAjax.post('package_quiqqer_coupons_ajax_frontend_redeem', resolve, {
                     'package': pkg,
-                    code     : code,
+                    code: code,
                     orderHash: orderHash,
-                    onError  : reject
+                    onError: reject
                 });
             });
         }
-- 
GitLab


From 2b857d4f0067de2a8dbcaa2284463886c2c07771 Mon Sep 17 00:00:00 2001
From: Henning <leutz@pcsg.de>
Date: Thu, 27 Feb 2025 13:46:15 +0100
Subject: [PATCH 10/10] fix: remove phpstan from gitlab CI pipeline

The `.gitlab-ci.yml` file was updated to remove the `phpstan` job. This change means we will no
longer run static analysis automatically on our CI pipeline. Further discussions may be needed on
whether to replace this with another tool or integrate it differently.
---
 .gitlab-ci.yml | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 61be412..efb42c8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -15,7 +15,3 @@ phpunit-php8.2:
 phpunit-php8.3:
   rules:
     - when: never
-
-phpstan:
-  script:
-    - QUIQQER_OTHER_AUTOLOADERS=KEEP ./tools/phpstan --no-progress --memory-limit=-1 --debug
-- 
GitLab