diff --git a/events.xml b/events.xml index 27fb7a41526293b19d0ef0a472b84fc0bfc0f12f..bae7bfa1cf5a8324f550f69c59049c47b8d80a08 100644 --- a/events.xml +++ b/events.xml @@ -29,6 +29,9 @@ <event on="onQuiqqerOrderShippingOnEmpty" fire="\QUI\ERP\Shipping\EventHandler::onQuiqqerOrderShippingOnEmpty" /> + <event on="onQuiqqerOrderInit" + fire="\QUI\ERP\Shipping\EventHandler::onQuiqqerOrderInit" + /> <event on="onUserSaveBegin" fire="\QUI\ERP\Shipping\EventHandler::onUserSaveBegin" /> diff --git a/locale.xml b/locale.xml index 0287a871d484f07b1ebf5922b9a723b45a182689..bb80e612370bfe2fe99e58a26769abb34ac8d680 100644 --- a/locale.xml +++ b/locale.xml @@ -298,13 +298,13 @@ <de><![CDATA[Standard Versand]]></de> <en><![CDATA[Default shipping]]></en> </locale> - <locale name="shipping.defaultShipping.settings.defaultShipping"> - <de><![CDATA[Standard Versand]]></de> - <en><![CDATA[Default shipping]]></en> + <locale name="shipping.defaultShipping.settings.defaultShippingPrice"> + <de><![CDATA[Standardversand Preis]]></de> + <en><![CDATA[Default shipping price]]></en> </locale> - <locale name="shipping.defaultShipping.settings.defaultShipping.desc"> - <de><![CDATA[Lege fest welcher Versand als Standard Versand verwendet werden soll.]]></de> - <en><![CDATA[Specify which shipping should be used as default shipping.]]></en> + <locale name="shipping.defaultShipping.settings.defaultShippingPrice.desc"> + <de><![CDATA[Lege fest welcher Preis als Standardversand verwendet werden soll.]]></de> + <en><![CDATA[Specify which price should be used as default shipping.]]></en> </locale> <locale name="shipping.defaultShipping.settings.addDefaultShipping"> <de><![CDATA[Standard Versand automatisch hinzufügen]]></de> @@ -312,16 +312,27 @@ </locale> <locale name="shipping.defaultShipping.settings.addDefaultShipping.desc"> <de><![CDATA[ - Der Standard Versand wird einer Bestellung hinzugefügt falls diese Bestellung noch keinen Versand hat. - Diese Einstellung hat nur Auswirkung im Backend und nicht auf Frontend Aktionen. - Wenn ein Nutzer eine Bestellung ausführt, wird dieser Versand nicht beachtet. + Der Standard Versand wird einer Artikelliste hinzugefügt, wenn diese noch keinen Versand zugeordnet hat. + Diese Einstellung hat nur Auswirkung in der Verwaltung und nicht im Frontend des Shops. ]]></de> <en><![CDATA[ - The default shipping will be added to an order if this order has no shipping yet. - This setting has effect only in backend and not on frontend actions. - When a user executes an order, this shipping is ignored. + The default shipping is added to an item list if it does not have a shipping assigned yet. + This setting has effect only in the administration and not in the frontend of the store. ]]></en> </locale> + <locale name="shipping.defaultShipping.settings.defaultShippingTitle"> + <de><![CDATA[Titel des Standard Versand]]></de> + <en><![CDATA[Title of standard shipping]]></en> + </locale> + <locale name="shipping.defaultShipping.settings.defaultShippingTitle.desc"> + <de><![CDATA[Dieser Text wird als Titel des Versands in der Artikelliste verwendet.]]></de> + <en><![CDATA[This text will be used as the title of the shipment in the item list.]]></en> + </locale> + <locale name="shipping.default.pricefactor"> + <de><![CDATA[Versand]]></de> + <en><![CDATA[Shipping]]></en> + </locale> + </groups> <groups name="quiqqer/shipping" datatype="php"> diff --git a/settings.xml b/settings.xml index aa87a05c6908a2c0ea58bb8670c547319db8b138..b99f7a87046f29433a6d5d30e189f310777b9e83 100644 --- a/settings.xml +++ b/settings.xml @@ -25,13 +25,13 @@ <defaultvalue>0</defaultvalue> </conf> - <conf name="defaultShipping"> - <type><![CDATA[integer]]></type> - </conf> <conf name="addDefaultShipping"> <type><![CDATA[bool]]></type> <defaultvalue>0</defaultvalue> </conf> + <conf name="defaultShippingPrice"> + <type><![CDATA[string]]></type> + </conf> </section> <section name="no_rules"> @@ -157,29 +157,40 @@ <locale group="quiqqer/shipping" var="shipping.defaultShipping.settings.title"/> </title> - <input conf="shipping.defaultShipping" - data-qui="package/quiqqer/shipping/bin/backend/controls/ShippingSelect" - data-qui-options-multiple="0" - data-qui-options-max="1" - > + <input conf="shipping.addDefaultShipping" type="checkbox"> <text> <locale group="quiqqer/shipping" - var="shipping.defaultShipping.settings.defaultShipping"/> + var="shipping.defaultShipping.settings.addDefaultShipping"/> </text> <description> <locale group="quiqqer/shipping" - var="shipping.defaultShipping.settings.defaultShipping.desc"/> + var="shipping.defaultShipping.settings.addDefaultShipping.desc"/> </description> </input> - - <input conf="shipping.addDefaultShipping" type="checkbox"> + + <input conf="shipping.defaultShippingPrice"> <text> <locale group="quiqqer/shipping" - var="shipping.defaultShipping.settings.addDefaultShipping"/> + var="shipping.defaultShipping.settings.defaultShippingPrice"/> </text> <description> <locale group="quiqqer/shipping" - var="shipping.defaultShipping.settings.addDefaultShipping.desc"/> + var="shipping.defaultShipping.settings.defaultShippingPrice.desc"/> + </description> + </input> + + <input type="hidden" + data-qui="package/quiqqer/translator/bin/controls/Update" + data-qui-options-group="quiqqer/shipping" + data-qui-options-var="shipping.default.pricefactor" + > + <text> + <locale group="quiqqer/shipping" + var="shipping.defaultShipping.settings.defaultShippingTitle"/> + </text> + <description> + <locale group="quiqqer/shipping" + var="shipping.defaultShipping.settings.defaultShippingTitle.desc"/> </description> </input> </settings> diff --git a/src/QUI/ERP/Shipping/EventHandler.php b/src/QUI/ERP/Shipping/EventHandler.php index fd0a3d252b25ae7ab8052d088ea17a5700c7970b..bb8ffc5aa9e9ca28cc51ae762149a520990cb437 100644 --- a/src/QUI/ERP/Shipping/EventHandler.php +++ b/src/QUI/ERP/Shipping/EventHandler.php @@ -15,6 +15,7 @@ use function explode; use function json_decode; use function method_exists; +use function strpos; /** * Class EventHandler @@ -513,18 +514,44 @@ public static function onQuiqqerOrderShippingOnEmpty(QUI\ERP\Order\AbstractOrder return; } - $Config = QUI::getPackage('quiqqer/shipping')->getConfig(); - $default = $Config->getValue('shipping', 'defaultShipping'); - $add = $Config->getValue('shipping', 'addDefaultShipping'); + $Config = QUI::getPackage('quiqqer/shipping')->getConfig(); + $add = $Config->getValue('shipping', 'addDefaultShipping'); if (empty($add)) { return; } try { - $Shipping = Shipping::getInstance()->getShippingEntry($default); - $Order->setShipping($Shipping); + $Articles = $Order->getArticles(); + $PriceFactors = $Articles->getPriceFactors(); + + // check if shipping factor exist + $shippingFactor = null; + $factors = $PriceFactors->toArray(); + + foreach ($factors as $factor) { + if (strpos($factor['identifier'], 'shipping-pricefactor-default') !== false) { + $shippingFactor = $factor; + break; + } + } + + if (!$shippingFactor) { + $PriceFactor = Shipping::getInstance()->getDefaultPriceFactor(); + $Articles->addPriceFactor($PriceFactor); + } } catch (QUI\Exception $Exception) { } } + + /** + * @param \QUI\ERP\Order\AbstractOrder $Order + * + * @return void + * @throws \QUI\Exception + */ + public static function onQuiqqerOrderInit(QUI\ERP\Order\AbstractOrder $Order) + { + self::onQuiqqerOrderShippingOnEmpty($Order); + } } diff --git a/src/QUI/ERP/Shipping/Rules/ShippingRule.php b/src/QUI/ERP/Shipping/Rules/ShippingRule.php index 64ee7cee0e5b24307c667207696a4e14eadbedd6..fcf225c4e63b9f7eff55a05d3040c818f71df2ad 100644 --- a/src/QUI/ERP/Shipping/Rules/ShippingRule.php +++ b/src/QUI/ERP/Shipping/Rules/ShippingRule.php @@ -23,6 +23,7 @@ use function array_map; use function array_merge; use function array_unique; +use function count; use function explode; use function floatval; use function is_array; @@ -31,6 +32,7 @@ use function json_decode; use function json_encode; use function round; +use function strpos; use function strtotime; use function time; use function trim; @@ -484,7 +486,7 @@ public function canUsedInOrder($Order) } } - if ($articleFound && $articleOnly && \count($articleList) !== 1) { + if ($articleFound && $articleOnly && count($articleList) !== 1) { QUI\ERP\Shipping\Debug::addLog( "{$this->getTitle()} :: is not a single article" ); @@ -653,7 +655,7 @@ public function canUsedInOrder($Order) /* @var $Factor QUI\ERP\Products\Interfaces\PriceFactorInterface */ foreach ($PriceFactors as $Factor) { - if ($Factor->getIdentifier() === 'shipping-pricefactor') { + if (strpos($Factor->getIdentifier(), 'shipping-pricefactor') !== false) { $ShippingFactor = $Factor; break; } diff --git a/src/QUI/ERP/Shipping/Shipping.php b/src/QUI/ERP/Shipping/Shipping.php index d7e9824021ffe9aec300f83e6d731f60a4ec1fbc..d903686b19a19b5d04a2c1e1980fc89f85b6b01d 100644 --- a/src/QUI/ERP/Shipping/Shipping.php +++ b/src/QUI/ERP/Shipping/Shipping.php @@ -8,8 +8,14 @@ use QUI; use QUI\ERP\Order\AbstractOrder; -use QUI\ERP\Shipping\Types\Factory; use QUI\ERP\Shipping\Api\AbstractShippingProvider; +use QUI\ERP\Shipping\Types\Factory; + +use function array_keys; +use function count; +use function key; +use function max; +use function strpos; /** * Shipping @@ -291,7 +297,7 @@ public function getShippingPriceFactorByOrder(AbstractOrder $Order) foreach ($PriceFactors as $PriceFactor) { /* @var $PriceFactor QUI\ERP\Products\Utils\PriceFactor */ - if ($PriceFactor->getIdentifier() === 'shipping-pricefactor') { + if (strpos($PriceFactor->getIdentifier(), 'shipping-pricefactor') !== false) { return $PriceFactor; } } @@ -414,6 +420,88 @@ public function getShippingByOrderId($orderId) return $this->getShippingByObject($Order); } + /** + * @return \QUI\ERP\Products\Utils\PriceFactor + * @throws \QUI\Exception + */ + public function getDefaultPriceFactor(): QUI\ERP\Products\Utils\PriceFactor + { + $price = QUI::getPackage('quiqqer/shipping') + ->getConfig() + ->getValue('shipping', 'defaultShippingPrice'); + + $price = QUI\ERP\Money\Price::validatePrice($price); + + $PriceFactor = new QUI\ERP\Products\Utils\PriceFactor([ + 'identifier' => 'shipping-pricefactor-default', + 'title' => QUI::getLocale()->get('quiqqer/shipping', 'shipping.default.pricefactor'), + 'description' => '', + 'calculation' => QUI\ERP\Accounting\Calc::CALCULATION_COMPLEMENT, + 'basis' => QUI\ERP\Accounting\Calc::CALCULATION_BASIS_CURRENTPRICE, + 'value' => $price, + 'visible' => true, + 'currency' => QUI\ERP\Defaults::getCurrency()->getCode() + ]); + + //$PriceFactor->setSum($price); + $PriceFactor->setNettoSum($price); + + return $PriceFactor; + } + + /** + * Returns the var of an order + * + * @param $Order + * @return float|int|mixed|string|null + * @throws \QUI\Exception + */ + public function getOrderVat($Order) + { + /* @var $Article QUI\ERP\Accounting\Article */ + + $Articles = $Order->getArticles(); + $vats = []; + + foreach ($Articles as $Article) { + $vat = $Article->getVat(); + $price = $Article->getPrice()->getValue(); + + if (!isset($vats[(string)$vat])) { + $vats[(string)$vat] = 0; + } + + $vats[(string)$vat] = $vats[(string)$vat] + $price; + } + + // @todo implement VAT setting for shipping + // look at vat, which vat should be used + if (!count($vats) && !$Order->getCustomer()) { + // use default vat + $Area = QUI\ERP\Defaults::getArea(); + $TaxType = QUI\ERP\Tax\Utils::getTaxTypeByArea($Area); + $TaxEntry = QUI\ERP\Tax\Utils::getTaxEntry($TaxType, $Area); + + return $TaxEntry->getValue(); + } + + if (!count($vats) && $Order->getCustomer()) { + $Tax = QUI\ERP\Tax\Utils::getTaxByUser($Order->getCustomer()); + return $Tax->getValue(); + } + + if (count($vats) === 1) { + // use article vat + return key($vats); + } + + if (count($vats)) { + // get max, use the max VAT if multiple exists + return max(array_keys($vats)); + } + + return 0; + } /** * Notify customer about an Order status change (via e-mail) @@ -435,8 +523,8 @@ public function sendStatusChangeNotification( if (empty($customerEmail)) { QUI\System\Log::addWarning( - 'Status change notification for order #'.$Order->getPrefixedId().' cannot be sent' - .' because customer #'.$Customer->getId().' has no e-mail address.' + 'Status change notification for order #' . $Order->getPrefixedId() . ' cannot be sent' + . ' because customer #' . $Customer->getId() . ' has no e-mail address.' ); return; diff --git a/src/QUI/ERP/Shipping/Types/ShippingEntry.php b/src/QUI/ERP/Shipping/Types/ShippingEntry.php index 147a1c002122d8b9007938142a9031f55256a42c..08378c54009e7745572bc0c30b182dc7b08c5145 100644 --- a/src/QUI/ERP/Shipping/Types/ShippingEntry.php +++ b/src/QUI/ERP/Shipping/Types/ShippingEntry.php @@ -15,11 +15,7 @@ use QUI\Permissions\Permission; use QUI\Translator; -use function array_keys; -use function count; use function json_encode; -use function key; -use function max; use function method_exists; use function round; @@ -760,7 +756,7 @@ public function toPriceFactor( } $PriceFactor = new QUI\ERP\Products\Utils\PriceFactor([ - 'identifier' => 'shipping-pricefactor', + 'identifier' => 'shipping-pricefactor-' . $this->getId(), 'title' => QUI::getLocale()->get('quiqqer/shipping', 'shipping.order.title', [ 'shipping' => $this->getTitle($Locale) ]), @@ -781,31 +777,9 @@ public function toPriceFactor( return $PriceFactor; } - /* @var $Article QUI\ERP\Accounting\Article */ - - $Articles = $Order->getArticles(); - $vats = []; - - foreach ($Articles as $Article) { - $vat = $Article->getVat(); - $price = $Article->getPrice()->getValue(); - - if (!isset($vats[(string)$vat])) { - $vats[(string)$vat] = 0; - } - - $vats[(string)$vat] = $vats[(string)$vat] + $price; - } - - // look at vat, which vat should be used - if (count($vats) === 1) { - $PriceFactor->setVat(key($vats)); - } else { - // get max, use the max VAT if multiple exists - // @todo implement VAT setting for shipping - $maxVat = max(array_keys($vats)); - $PriceFactor->setVat($maxVat); - } + $PriceFactor->setVat( + QUI\ERP\Shipping\Shipping::getInstance()->getOrderVat($Order) + ); return $PriceFactor; }