diff --git a/.phive/phars.xml b/.phive/phars.xml
index 63a030f34ebaa167a4ac0c278a66d42d6f1d11e6..ebb5988ac5456a0286d35a530df2673a49c57c2b 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.1" installed="1.11.1" 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"/>
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6bcbec17459f7da641035e4098754c5bb0a0ffe0 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -0,0 +1,316 @@
+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 static method getInstance\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\Handler\\.$#"
+			count: 1
+			path: ajax/frontend/redeem.php
+
+		-
+			message: "#^Class QUI\\\\ERP\\\\Order\\\\OrderInProcess not found\\.$#"
+			count: 1
+			path: ajax/frontend/redeem.php
+
+		-
+			message: "#^Call to static method getInstance\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\Handler\\.$#"
+			count: 1
+			path: ajax/frontend/removeCoupons.php
+
+		-
+			message: "#^Call to an undefined method QUI\\\\ERP\\\\Products\\\\Interfaces\\\\PriceFactorInterface\\:\\:setVat\\(\\)\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Call to method addArticle\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\OrderInProcess\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Call to method addFrontendMessage\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\OrderInterface\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Call to method addPriceFactors\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\OrderInProcess\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Call to method getArticles\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\OrderInProcess\\.$#"
+			count: 2
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Call to method getCustomer\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\OrderInProcess\\.$#"
+			count: 2
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Call to method getDataEntry\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\OrderInProcess\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Call to method getPrefixedNumber\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Call to method getPrefixedNumber\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\Order\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Call to method update\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\OrderInProcess\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Class QUI\\\\ERP\\\\Order\\\\Order not found\\.$#"
+			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: "#^Parameter \\#2 \\$Order of method QUI\\\\ERP\\\\Coupons\\\\CouponCode\\:\\:isRedeemable\\(\\) expects QUI\\\\ERP\\\\Order\\\\OrderInterface\\|null, QUI\\\\ERP\\\\Order\\\\OrderInProcess given\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Parameter \\$Order of method QUI\\\\ERP\\\\Coupons\\\\CouponCode\\:\\:addToOrder\\(\\) has invalid type QUI\\\\ERP\\\\Order\\\\OrderInProcess\\.$#"
+			count: 2
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Parameter \\$Order of method QUI\\\\ERP\\\\Coupons\\\\CouponCode\\:\\:checkOrderRedemption\\(\\) has invalid type QUI\\\\ERP\\\\Order\\\\OrderInterface\\.$#"
+			count: 2
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Parameter \\$Order of method QUI\\\\ERP\\\\Coupons\\\\CouponCode\\:\\:isRedeemable\\(\\) has invalid type QUI\\\\ERP\\\\Order\\\\OrderInterface\\.$#"
+			count: 2
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Parameter \\$Order of method QUI\\\\ERP\\\\Coupons\\\\CouponCode\\:\\:redeem\\(\\) has invalid type QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 2
+			path: src/QUI/ERP/Coupons/CouponCode.php
+
+		-
+			message: "#^Call to method getAttribute\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 2
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Call to method getAttribute\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\OrderInProcess\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Call to method getCurrentStep\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\OrderProcess\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Call to method getCustomer\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 3
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Call to method getDataEntry\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 2
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Call to method getDataEntry\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\OrderInProcess\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Call to method getOrder\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\Basket\\\\Basket\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Call to method getOrder\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\OrderProcess\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Call to method isSuccessful\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Call to method setData\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\OrderInProcess\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Call to method update\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\OrderInProcess\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Call to static method getInstance\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\Handler\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Class QUI\\\\ERP\\\\Order\\\\Basket\\\\Basket not found\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Class QUI\\\\ERP\\\\Order\\\\Basket\\\\BasketOrder not found\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Class QUI\\\\ERP\\\\Order\\\\Controls\\\\OrderProcess\\\\Basket not found\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Class QUI\\\\ERP\\\\Order\\\\OrderInProcess not found\\.$#"
+			count: 3
+			path: src/QUI/ERP/Coupons/Events.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: "#^PHPDoc tag @throws with type QUI\\\\ERP\\\\Order\\\\Exception\\|QUI\\\\Exception is not subtype of Throwable$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Parameter \\#1 \\$Order of method QUI\\\\ERP\\\\Coupons\\\\CouponCode\\:\\:checkOrderRedemption\\(\\) expects QUI\\\\ERP\\\\Order\\\\OrderInterface\\|null, QUI\\\\ERP\\\\Order\\\\OrderInProcess given\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Parameter \\$Basket of method QUI\\\\ERP\\\\Coupons\\\\Events\\:\\:onQuiqqerOrderBasketRemovePos\\(\\) has invalid type QUI\\\\ERP\\\\Order\\\\Basket\\\\Basket\\.$#"
+			count: 2
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Parameter \\$Order of method QUI\\\\ERP\\\\Coupons\\\\Events\\:\\:onQuiqqerOrderBasketToOrder\\(\\) has invalid type QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 2
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Parameter \\$Order of method QUI\\\\ERP\\\\Coupons\\\\Events\\:\\:onQuiqqerOrderCreated\\(\\) has invalid type QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 2
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Parameter \\$Order of method QUI\\\\ERP\\\\Coupons\\\\Events\\:\\:onQuiqqerOrderSuccessful\\(\\) has invalid type QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 2
+			path: src/QUI/ERP/Coupons/Events.php
+
+		-
+			message: "#^Parameter \\$OrderProcess of method QUI\\\\ERP\\\\Coupons\\\\Events\\:\\:onOrderProcess\\(\\) has invalid type QUI\\\\ERP\\\\Order\\\\OrderProcess\\.$#"
+			count: 2
+			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 addHistory\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 2
+			path: src/QUI/ERP/Coupons/Products/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 getArticles\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Products/Handler.php
+
+		-
+			message: "#^Call to method getCurrency\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Products/Handler.php
+
+		-
+			message: "#^Call to method getCustomer\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Products/Handler.php
+
+		-
+			message: "#^Call to method getPrefixedNumber\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 1
+			path: src/QUI/ERP/Coupons/Products/Handler.php
+
+		-
+			message: "#^Call to method getUUID\\(\\) on an unknown class QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			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
+
+		-
+			message: "#^Parameter \\$Order of method QUI\\\\ERP\\\\Coupons\\\\Products\\\\Handler\\:\\:createCouponCodeFromProduct\\(\\) has invalid type QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 2
+			path: src/QUI/ERP/Coupons/Products/Handler.php
+
+		-
+			message: "#^Parameter \\$Order of method QUI\\\\ERP\\\\Coupons\\\\Products\\\\Handler\\:\\:createCouponCodesFromOrder\\(\\) has invalid type QUI\\\\ERP\\\\Order\\\\AbstractOrder\\.$#"
+			count: 2
+			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