diff --git a/Adapter/DeliveryOptionsFromOrderAdapter.php b/Adapter/DeliveryOptionsFromOrderAdapter.php index a8d5a798..c6c89d7d 100644 --- a/Adapter/DeliveryOptionsFromOrderAdapter.php +++ b/Adapter/DeliveryOptionsFromOrderAdapter.php @@ -4,7 +4,7 @@ namespace MyParcelNL\Magento\Adapter; -use MyParcelNL\Sdk\src\Adapter\DeliveryOptions\AbstractDeliveryOptionsAdapter; +use MyParcelNL\Sdk\Adapter\DeliveryOptions\AbstractDeliveryOptionsAdapter; class DeliveryOptionsFromOrderAdapter extends AbstractDeliveryOptionsAdapter { diff --git a/Adapter/OrderLineOptionsFromOrderAdapter.php b/Adapter/OrderLineOptionsFromOrderAdapter.php index 6a9a9b8b..311a9de3 100644 --- a/Adapter/OrderLineOptionsFromOrderAdapter.php +++ b/Adapter/OrderLineOptionsFromOrderAdapter.php @@ -4,7 +4,7 @@ namespace MyParcelNL\Magento\Adapter; -use MyParcelNL\Sdk\src\Model\Fulfilment\OrderLine; +use MyParcelNL\Sdk\Model\Fulfilment\OrderLine; class OrderLineOptionsFromOrderAdapter extends OrderLine { diff --git a/Adapter/ShipmentOptionsFromAdapter.php b/Adapter/ShipmentOptionsFromAdapter.php index 956fd35f..c3dd3cc6 100644 --- a/Adapter/ShipmentOptionsFromAdapter.php +++ b/Adapter/ShipmentOptionsFromAdapter.php @@ -4,8 +4,9 @@ namespace MyParcelNL\Magento\Adapter; -use MyParcelNL\Sdk\src\Adapter\DeliveryOptions\AbstractDeliveryOptionsAdapter; -use MyParcelNL\Sdk\src\Adapter\DeliveryOptions\AbstractShipmentOptionsAdapter; +use MyParcelNL\Magento\Helper\ShipmentOptions; +use MyParcelNL\Sdk\Adapter\DeliveryOptions\AbstractDeliveryOptionsAdapter; +use MyParcelNL\Sdk\Adapter\DeliveryOptions\AbstractShipmentOptionsAdapter; class ShipmentOptionsFromAdapter extends AbstractShipmentOptionsAdapter { @@ -17,11 +18,13 @@ class ShipmentOptionsFromAdapter extends AbstractShipmentOptionsAdapter public function __construct(array $inputData) { $options = $inputData ?? []; - $this->signature = (bool) ($options['signature'] ?? false); - $this->only_recipient = (bool) ($options['only_recipient'] ?? false); - $this->large_format = (bool) ($options['large_format'] ?? false); - $this->age_check = (bool) ($options['age_check'] ?? false); - $this->return = (bool) ($options['return'] ?? false); - $this->insurance = (int) ($options['insurance'] ?? self::DEFAULT_INSURANCE); + $this->signature = (bool) ($options[ShipmentOptions::SIGNATURE] ?? false); + $this->collect = (bool) ($options[ShipmentOptions::COLLECT] ?? false); + $this->receipt_code = (bool) ($options[ShipmentOptions::RECEIPT_CODE] ?? false); + $this->only_recipient = (bool) ($options[ShipmentOptions::ONLY_RECIPIENT] ?? false); + $this->large_format = (bool) ($options[ShipmentOptions::LARGE_FORMAT] ?? false); + $this->age_check = (bool) ($options[ShipmentOptions::AGE_CHECK] ?? false); + $this->return = (bool) ($options[ShipmentOptions::RETURN] ?? false); + $this->insurance = (int) ($options[ShipmentOptions::INSURANCE] ?? self::DEFAULT_INSURANCE); } } diff --git a/Block/DataProviders/Email/Shipment/TrackingUrl.php b/Block/DataProviders/Email/Shipment/TrackingUrl.php index 38aa047f..9eea321d 100644 --- a/Block/DataProviders/Email/Shipment/TrackingUrl.php +++ b/Block/DataProviders/Email/Shipment/TrackingUrl.php @@ -5,7 +5,7 @@ use Magento\Framework\App\ObjectManager; use Magento\Sales\Model\Order; use Magento\Sales\Model\Order\Shipment\Track; -use MyParcelNL\Sdk\src\Helper\TrackTraceUrl; +use MyParcelNL\Sdk\Helper\TrackTraceUrl; // For Magento version < 2.3.2 the TrackingUrl is not exist. Therefore, it must be checked if the class exists and so that the class can be extended. if (class_exists('\Magento\Sales\Block\DataProviders\Email\Shipment\TrackingUrl')) { diff --git a/Block/Sales/NewShipment.php b/Block/Sales/NewShipment.php index ba1f7cda..5d9575a7 100755 --- a/Block/Sales/NewShipment.php +++ b/Block/Sales/NewShipment.php @@ -14,116 +14,85 @@ namespace MyParcelNL\Magento\Block\Sales; +use Exception; use Magento\Backend\Block\Template\Context; use Magento\CatalogInventory\Api\StockConfigurationInterface; use Magento\CatalogInventory\Api\StockRegistryInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Registry; use Magento\Sales\Block\Adminhtml\Items\AbstractItems; -use MyParcelNL\Magento\Helper\Checkout; use MyParcelNL\Magento\Model\Sales\MagentoOrderCollection; use MyParcelNL\Magento\Model\Source\DefaultOptions; -use MyParcelNL\Magento\Helper\Data; -use MyParcelNL\Magento\Model\Sales\TrackTraceHolder; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Magento\Service\Weight; +use MyParcelNL\Sdk\Model\Carrier\CarrierPostNL; +use MyParcelNL\Sdk\Model\Carrier\CarrierUPS; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; class NewShipment extends AbstractItems { - /** - * @var \MyParcelNL\Magento\Helper\Data - */ - private $dataHelper; - /** * @var \Magento\Sales\Model\Order */ private $order; - /** - * @var \Magento\Framework\ObjectManagerInterface - */ - private $objectManager; - /** * @var \MyParcelNL\Magento\Model\Source\DefaultOptions */ - private $defaultOptions; + private DefaultOptions $defaultOptions; /** * @var \MyParcelNL\Magento\Block\Sales\NewShipmentForm */ - private $form; + private NewShipmentForm $form; /** * @var \MyParcelNL\Magento\Model\Sales\MagentoOrderCollection */ - private $orderCollection; - - /** - * @var mixed - */ - private $request; + private MagentoOrderCollection $orderCollection; /** - * @param \Magento\Backend\Block\Template\Context $context - * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry - * @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration - * @param \Magento\Framework\Registry $registry - * @param \Magento\Framework\ObjectManagerInterface $objectManager + * @param Context $context + * @param StockRegistryInterface $stockRegistry + * @param StockConfigurationInterface $stockConfiguration + * @param Registry $registry */ public function __construct( - Context $context, - Data $helper, - StockRegistryInterface $stockRegistry, + Context $context, + StockRegistryInterface $stockRegistry, StockConfigurationInterface $stockConfiguration, - Registry $registry, - ObjectManagerInterface $objectManager - ) { - // Set order + Registry $registry, + ObjectManagerInterface $objectManager + ) + { $this->order = $registry->registry('current_shipment')->getOrder(); - $this->dataHelper = $helper; - $this->objectManager = $objectManager; + $this->weightService = $objectManager->get(Weight::class); + $this->configService = $objectManager->get(Config::class); $this->form = new NewShipmentForm(); - $this->defaultOptions = new DefaultOptions( - $this->order, - $this->objectManager->get(Data::class) - ); + $this->defaultOptions = new DefaultOptions($this->order); - $this->request = $this->objectManager->get('Magento\Framework\App\RequestInterface'); - $this->orderCollection = new MagentoOrderCollection($this->objectManager, $this->request); + $request = $objectManager->get('Magento\Framework\App\RequestInterface'); + $this->orderCollection = new MagentoOrderCollection($objectManager, $request); parent::__construct($context, $stockRegistry, $stockConfiguration, $registry); } /** - * @param string $option 'signature', 'only_recipient' - * @param string $carrier + * @param string $option 'signature', 'only_recipient' + * @param string $carrier * * @return bool */ public function hasDefaultOption(string $option, string $carrier): bool { - return $this->defaultOptions->hasDefault($option, $carrier); - } - - /** - * Get default value of age check - * - * @param string $carrier - * @param string $option - * - * @return bool - */ - public function hasDefaultOptionsWithoutPrice(string $carrier, string $option): bool - { - return $this->defaultOptions->hasDefaultOptionsWithoutPrice($carrier, $option); + return $this->defaultOptions->hasOptionSet($option, $carrier); } /** * Get default value of insurance based on order grand total * - * @param string $carrier + * @param string $carrier * * @return int */ @@ -138,7 +107,7 @@ public function getDefaultInsurance(string $carrier): int */ public function getDigitalStampWeight(): int { - $weight = $this->dataHelper->convertToGrams($this->order->getWeight() ?? 0.0); + $weight = $this->weightService->convertToGrams($this->order->getWeight() ?? 0.0); if (0 === $weight) { $weight = $this->defaultOptions->getDigitalStampDefaultWeight(); @@ -160,7 +129,7 @@ public function getPackageType() */ public function getCarrier(): string { - return $this->defaultOptions->getCarrier(); + return $this->defaultOptions->getCarrierName(); } /** @@ -171,9 +140,49 @@ public function getCountry() return $this->order->getShippingAddress()->getCountryId(); } + public function getDeliveryType(): int + { + try { + $deliveryTypeName = json_decode($this->order->getData(Config::FIELD_DELIVERY_OPTIONS), true)['deliveryType']; + $deliveryType = AbstractConsignment::DELIVERY_TYPES_NAMES_IDS_MAP[$deliveryTypeName]; + } catch (Exception $e) { + $deliveryType = AbstractConsignment::DEFAULT_DELIVERY_TYPE; + } + + return $deliveryType; + } + public function consignmentHasShipmentOption(AbstractConsignment $consignment, string $shipmentOption): bool { - return $this->dataHelper->consignmentHasShipmentOption($consignment, $shipmentOption); + /** + * Business logic determining what shipment options to show, if any. + */ + if (AbstractConsignment::SHIPMENT_OPTION_RECEIPT_CODE === $shipmentOption + && AbstractConsignment::DELIVERY_TYPE_STANDARD !== $this->getDeliveryType() + ) { + return false; // receipt code is only available for standard delivery + } + + if (AbstractConsignment::CC_NL === $consignment->getCountry()) { + return $consignment->canHaveShipmentOption($shipmentOption); + } + + // For PostNL in Belgium - recipient-only, signature and receipt-code are available + if (AbstractConsignment::CC_BE === $consignment->getCountry() && CarrierPostNL::NAME === $consignment->getCarrierName()) { + return in_array($shipmentOption, [ + AbstractConsignment::SHIPMENT_OPTION_ONLY_RECIPIENT, + AbstractConsignment::SHIPMENT_OPTION_SIGNATURE, + AbstractConsignment::SHIPMENT_OPTION_RECEIPT_CODE, + ], true); + } + + // For UPS shipment options are available for all countries in the EU + if (CarrierUPS::NAME === $consignment->getCarrierName()) { + return true; + } + + // No shipment options available in any other cases + return false; } /** @@ -189,6 +198,6 @@ public function getNewShipmentForm(): NewShipmentForm */ public function isOrderManagementEnabled(): bool { - return TrackTraceHolder::EXPORT_MODE_PPS === $this->orderCollection->getExportMode(); + return Config::EXPORT_MODE_PPS === $this->configService->getExportMode(); } } diff --git a/Block/Sales/NewShipmentForm.php b/Block/Sales/NewShipmentForm.php index ec361cbd..0a7367de 100644 --- a/Block/Sales/NewShipmentForm.php +++ b/Block/Sales/NewShipmentForm.php @@ -2,15 +2,16 @@ namespace MyParcelNL\Magento\Block\Sales; -use MyParcelNL\Sdk\src\Factory\ConsignmentFactory; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierDHLEuroplus; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierDHLForYou; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierDHLParcelConnect; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierDPD; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierFactory; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierPostNL; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierUPS; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; +use Exception; +use MyParcelNL\Sdk\Factory\ConsignmentFactory; +use MyParcelNL\Sdk\Model\Carrier\CarrierDHLEuroplus; +use MyParcelNL\Sdk\Model\Carrier\CarrierDHLForYou; +use MyParcelNL\Sdk\Model\Carrier\CarrierDHLParcelConnect; +use MyParcelNL\Sdk\Model\Carrier\CarrierDPD; +use MyParcelNL\Sdk\Model\Carrier\CarrierFactory; +use MyParcelNL\Sdk\Model\Carrier\CarrierPostNL; +use MyParcelNL\Sdk\Model\Carrier\CarrierUPS; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; class NewShipmentForm { @@ -34,13 +35,20 @@ class NewShipmentForm /** * @var array */ - private $shipmentOptionsHumanMap; + private array $shipmentOptionsHumanMap; + + /** + * @var array + */ + private array $shipmentOptionsExplanation; public function __construct() { $this->shipmentOptionsHumanMap = [ AbstractConsignment::SHIPMENT_OPTION_SIGNATURE => __('Signature on receipt'), + AbstractConsignment::SHIPMENT_OPTION_RECEIPT_CODE => __('Receiving code'), + AbstractConsignment::SHIPMENT_OPTION_COLLECT => __('Collect package'), AbstractConsignment::SHIPMENT_OPTION_ONLY_RECIPIENT => __('Home address only'), AbstractConsignment::SHIPMENT_OPTION_AGE_CHECK => __('Age check 18+'), AbstractConsignment::SHIPMENT_OPTION_HIDE_SENDER => __('Hide sender'), @@ -48,10 +56,15 @@ public function __construct() AbstractConsignment::SHIPMENT_OPTION_RETURN => __('Return if no answer'), AbstractConsignment::SHIPMENT_OPTION_SAME_DAY_DELIVERY => __('Same day delivery'), ]; + + $this->shipmentOptionsExplanation = [ + AbstractConsignment::SHIPMENT_OPTION_RECEIPT_CODE => __('Insurance is mandatory and will be set. Other shipment options will be removed.'), + ]; } + /** * @return AbstractConsignment[] - * @throws \Exception + * @throws Exception */ public function getCarrierSpecificAbstractConsignments(): array { @@ -71,4 +84,12 @@ public function getShipmentOptionsHumanMap(): array { return $this->shipmentOptionsHumanMap; } + + /** + * @return array + */ + public function getShipmentOptionsExplanationMap(): array + { + return $this->shipmentOptionsExplanation; + } } diff --git a/Block/Sales/OrderAction.php b/Block/Sales/OrderAction.php index 7d5f8f2c..3343b6c4 100755 --- a/Block/Sales/OrderAction.php +++ b/Block/Sales/OrderAction.php @@ -15,7 +15,7 @@ namespace MyParcelNL\Magento\Block\Sales; use Magento\Backend\Block\Template\Context; -use MyParcelNL\Sdk\src\Model\Consignment\BaseConsignment; +use MyParcelNL\Sdk\Model\Consignment\BaseConsignment; use \Magento\Framework\Registry; class OrderAction extends OrdersAction @@ -25,14 +25,14 @@ class OrderAction extends OrdersAction */ private $order; /** - * @var \MyParcelNL\Sdk\src\Model\Consignment\BaseConsignment + * @var \MyParcelNL\Sdk\Model\Consignment\BaseConsignment */ private $consignment; /** * @param Context $context * @param \Magento\Framework\Registry $registry - * @param \MyParcelNL\Sdk\src\Model\Consignment\BaseConsignment $consignment + * @param \MyParcelNL\Sdk\Model\Consignment\BaseConsignment $consignment * @param array $data */ public function __construct( diff --git a/Block/Sales/OrdersAction.php b/Block/Sales/OrdersAction.php index a3bc4f9c..9eec28fd 100755 --- a/Block/Sales/OrdersAction.php +++ b/Block/Sales/OrdersAction.php @@ -17,30 +17,23 @@ use Magento\Backend\Block\Template; use Magento\Backend\Block\Template\Context; use Magento\Framework\App\ObjectManager; -use MyParcelNL\Magento\Helper\Data; +use MyParcelNL\Magento\Service\Config; class OrdersAction extends Template { - /** - * @var \Magento\Framework\ObjectManagerInterface - */ - private $objectManager; - - /** - * @var \MyParcelNL\Magento\Helper\Data - */ - private $helper; + private Config $configService; /** * @param Context $context - * @param array $data + * @param array $data */ public function __construct( Context $context, - array $data = [] - ) { - $this->objectManager = ObjectManager::getInstance(); - $this->helper = $this->objectManager->get(Data::class); + array $data = [] + ) + { + $objectManager = ObjectManager::getInstance(); + $this->configService = $objectManager->get(Config::class); parent::__construct($context, $data); } @@ -51,7 +44,7 @@ public function __construct( */ public function hasApiKey(): bool { - return $this->helper->hasApiKey(); + return $this->configService->hasApiKey(); } /** @@ -91,7 +84,7 @@ public function getAjaxUrlSendReturnMail(): string */ public function getPrintSettings() { - $settings = $this->helper->getGeneralConfig('print'); + $settings = $this->configService->getGeneralConfig('print'); return json_encode($settings); } diff --git a/Block/Sales/ShipmentAction.php b/Block/Sales/ShipmentAction.php index ac99a45b..b698994c 100755 --- a/Block/Sales/ShipmentAction.php +++ b/Block/Sales/ShipmentAction.php @@ -17,7 +17,7 @@ use Magento\Backend\Block\Template\Context; use Magento\Framework\Registry; use Magento\Sales\Model\Order\Shipment; -use MyParcelNL\Sdk\src\Model\Consignment\BaseConsignment; +use MyParcelNL\Sdk\Model\Consignment\BaseConsignment; class ShipmentAction extends OrdersAction { @@ -30,7 +30,7 @@ class ShipmentAction extends OrdersAction */ private $shipment; /** - * @var \MyParcelNL\Sdk\src\Model\Consignment\BaseConsignment + * @var \MyParcelNL\Sdk\Model\Consignment\BaseConsignment */ private $consignment; @@ -38,7 +38,7 @@ class ShipmentAction extends OrdersAction * @param Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Sales\Model\Order\Shipment $shipment - * @param \MyParcelNL\Sdk\src\Model\Consignment\BaseConsignment $consignment + * @param \MyParcelNL\Sdk\Model\Consignment\BaseConsignment $consignment * @param array $data */ public function __construct( diff --git a/Block/Sales/ShipmentsAction.php b/Block/Sales/ShipmentsAction.php index c169a8f6..cb51d0a5 100755 --- a/Block/Sales/ShipmentsAction.php +++ b/Block/Sales/ShipmentsAction.php @@ -17,14 +17,11 @@ use Magento\Backend\Block\Template; use Magento\Backend\Block\Template\Context; use Magento\Framework\App\ObjectManager; -use MyParcelNL\Magento\Helper\Data; +use MyParcelNL\Magento\Service\Config; class ShipmentsAction extends Template { - /** - * @var \MyParcelNL\Magento\Helper\Data - */ - private $helper; + private Config $Config; /** * @param Context $context @@ -34,8 +31,7 @@ public function __construct( Context $context, array $data = [] ) { - $objectManager = ObjectManager::getInstance(); - $this->helper = $objectManager->get(Data::class); + $this->Config = (ObjectManager::getInstance())->get(Config::class); parent::__construct($context, $data); } @@ -46,7 +42,7 @@ public function __construct( */ public function hasApiKey(): bool { - return $this->helper->hasApiKey(); + return $this->Config->hasApiKey(); } /** @@ -86,7 +82,7 @@ public function getAjaxUrlSendReturnMail(): string */ public function getPrintSettings(): string { - $settings = $this->helper->getGeneralConfig('print'); + $settings = $this->Config->getGeneralConfig('print'); return json_encode($settings); } diff --git a/Block/Sales/View.php b/Block/Sales/View.php index a0a523c3..668718b6 100755 --- a/Block/Sales/View.php +++ b/Block/Sales/View.php @@ -19,11 +19,14 @@ namespace MyParcelNL\Magento\Block\Sales; use DateTime; -use Magento\Framework\App\ObjectManager; +use Exception; +use Magento\Framework\Exception\LocalizedException; use Magento\Sales\Block\Adminhtml\Order\AbstractOrder; -use MyParcelNL\Magento\Helper\Checkout as CheckoutHelper; -use MyParcelNL\Sdk\src\Adapter\DeliveryOptions\AbstractDeliveryOptionsAdapter; -use MyParcelNL\Sdk\src\Factory\DeliveryOptionsAdapterFactory; +use MyParcelNL\Magento\Facade\Logger; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Sdk\Adapter\DeliveryOptions\AbstractDeliveryOptionsAdapter; +use MyParcelNL\Sdk\Factory\DeliveryOptionsAdapterFactory; +use Throwable; class View extends AbstractOrder { @@ -31,17 +34,17 @@ class View extends AbstractOrder * Collect options selected at checkout and calculate type consignment * * @return string - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Exception + * @throws LocalizedException + * @throws Exception */ public function getCheckoutOptionsHtml(): string { $order = $this->getOrder(); /** @var object $data Data from checkout */ - $data = $order->getData(CheckoutHelper::FIELD_DELIVERY_OPTIONS) !== null ? json_decode($order->getData(CheckoutHelper::FIELD_DELIVERY_OPTIONS), true) : null; + $data = json_decode($order->getData(Config::FIELD_DELIVERY_OPTIONS) ?? null, true); - if (! is_array($data)) { + if (!is_array($data)) { return ''; } @@ -56,8 +59,8 @@ public function getCheckoutOptionsHtml(): string if ($deliveryOptions->getDate()) { $returnString = htmlentities($this->getCheckoutOptionsDeliveryHtml($deliveryOptions)); } - } catch (\Throwable $e) { - ObjectManager::getInstance()->get(CheckoutHelper::class)->log($e->getMessage()); + } catch (Throwable $e) { + Logger::critical($e->getMessage()); $returnString = __('MyParcel options data not found'); } @@ -68,7 +71,8 @@ public function getCheckoutOptionsHtml(): string * @param AbstractDeliveryOptionsAdapter $deliveryOptions * @return string */ - private function getCheckoutOptionsPickupHtml(AbstractDeliveryOptionsAdapter $deliveryOptions): string { + private function getCheckoutOptionsPickupHtml(AbstractDeliveryOptionsAdapter $deliveryOptions): string + { ob_start(); echo __("{$deliveryOptions->getCarrier()} location:"), ' '; @@ -90,9 +94,10 @@ private function getCheckoutOptionsPickupHtml(AbstractDeliveryOptionsAdapter $de /** * @param AbstractDeliveryOptionsAdapter $deliveryOptions * @return string - * @throws \Exception + * @throws Exception */ - private function getCheckoutOptionsDeliveryHtml(AbstractDeliveryOptionsAdapter $deliveryOptions): string { + private function getCheckoutOptionsDeliveryHtml(AbstractDeliveryOptionsAdapter $deliveryOptions): string + { ob_start(); if ($deliveryOptions->getPackageType()) { diff --git a/Block/System/Config/Form/AbstractDefaultDropOffPoint.php b/Block/System/Config/Form/AbstractDefaultDropOffPoint.php index e1b8627a..91d5d49b 100644 --- a/Block/System/Config/Form/AbstractDefaultDropOffPoint.php +++ b/Block/System/Config/Form/AbstractDefaultDropOffPoint.php @@ -9,8 +9,9 @@ use Magento\Config\Block\System\Config\Form\Field; use Magento\Framework\App\ObjectManager; use Magento\Framework\Data\Form\Element\AbstractElement; -use MyParcelNL\Magento\Helper\Data; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierFactory; +use MyParcelNL\Magento\Model\Settings\AccountSettings; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Sdk\Model\Carrier\CarrierFactory; abstract class AbstractDefaultDropOffPoint extends Field { @@ -22,7 +23,7 @@ abstract class AbstractDefaultDropOffPoint extends Field protected $_template = 'MyParcelNL_Magento::default_drop_off_point.phtml'; /** - * @var \MyParcelNL\Sdk\src\Model\Consignment\DropOffPoint + * @var \MyParcelNL\Sdk\Model\Consignment\DropOffPoint */ private $dropOffPoint; @@ -31,9 +32,7 @@ abstract class AbstractDefaultDropOffPoint extends Field */ public function __construct(Context $context, array $data = []) { - $objectManager = ObjectManager::getInstance(); - $helper = $objectManager->get(Data::class); - $dropOffPoint = $helper->getDropOffPoint(CarrierFactory::createFromId($this->getCarrierId())); + $dropOffPoint = AccountSettings::getInstance()->getDropOffPoint(CarrierFactory::createFromId($this->getCarrierId())); $this->dropOffPoint = $dropOffPoint; parent::__construct($context, $data); } @@ -46,7 +45,7 @@ abstract public function getCarrierId(): int; /** * Retrieve HTML markup for given form element * - * @param \Magento\Framework\Data\Form\Element\AbstractElement $element + * @param \Magento\Framework\Data\Form\Element\AbstractElement $element * * @return string */ @@ -61,7 +60,7 @@ public function render(AbstractElement $element): string /** * Retrieve element HTML markup * - * @param \Magento\Framework\Data\Form\Element\AbstractElement $element + * @param \Magento\Framework\Data\Form\Element\AbstractElement $element * * @return string */ @@ -75,14 +74,20 @@ protected function _getElementHtml(AbstractElement $element): string */ public function getDropOffPointDetails(): ?array { - return $this->dropOffPoint ? [ - 'location_name' => $this->dropOffPoint->getLocationName(), - 'city' => $this->dropOffPoint->getCity(), - 'street' => $this->dropOffPoint->getStreet(), - 'number' => $this->dropOffPoint->getNumber(), - 'number_suffix' => $this->dropOffPoint->getNumberSuffix(), - 'postal_code' => $this->dropOffPoint->getPostalCode(), - ] : null; + if (!$this->dropOffPoint) { + return null; + } + + $dropOffPoint = $this->dropOffPoint; + + return [ + 'location_name' => $dropOffPoint->getLocationName(), + 'city' => $dropOffPoint->getCity(), + 'street' => $dropOffPoint->getStreet(), + 'number' => $dropOffPoint->getNumber(), + 'number_suffix' => $dropOffPoint->getNumberSuffix(), + 'postal_code' => $dropOffPoint->getPostalCode(), + ]; } /** @@ -106,7 +111,7 @@ public function getButtonHtml(): string $button = $this->getLayout() ->createBlock(Button::class) ->setData([ - 'id' => 'settings-button', + 'id' => 'settings-button', 'label' => __('Import'), ]); return $button->toHtml(); diff --git a/Block/System/Config/Form/DefaultDropOffPointPostNL.php b/Block/System/Config/Form/DefaultDropOffPointPostNL.php index 958e3408..482de1a9 100644 --- a/Block/System/Config/Form/DefaultDropOffPointPostNL.php +++ b/Block/System/Config/Form/DefaultDropOffPointPostNL.php @@ -4,7 +4,7 @@ namespace MyParcelNL\Magento\Block\System\Config\Form; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierPostNL; +use MyParcelNL\Sdk\Model\Carrier\CarrierPostNL; class DefaultDropOffPointPostNL extends AbstractDefaultDropOffPoint { diff --git a/Block/System/Config/Form/DeliveryCostsMatrix.php b/Block/System/Config/Form/DeliveryCostsMatrix.php new file mode 100644 index 00000000..d7fcfd18 --- /dev/null +++ b/Block/System/Config/Form/DeliveryCostsMatrix.php @@ -0,0 +1,57 @@ +getName()] = $carrier->getHuman(); + } + return $carriers; + } + + public function getPackageTypes(): array + { + return NewShipmentForm::PACKAGE_TYPE_HUMAN_MAP; // TODO move constant from NewShipmentForm + } + + public function getCountryCodes(): array + { + return CountryCodes::ALL; + } + + public function getCountryParts(): array + { + return [CountryCodes::ZONE_EU, CountryCodes::ZONE_ROW]; + } + + /** + * Retrieve element HTML markup, called from Magento + * + * @param \Magento\Framework\Data\Form\Element\AbstractElement $element + * + * @return string + */ + protected function _getElementHtml(AbstractElement $element): string + { + return $this->_toHtml(); + } +} \ No newline at end of file diff --git a/Block/System/Config/Form/SupportTabRepository.php b/Block/System/Config/Form/SupportTabRepository.php index e1e582fe..e10a67ad 100755 --- a/Block/System/Config/Form/SupportTabRepository.php +++ b/Block/System/Config/Form/SupportTabRepository.php @@ -18,17 +18,11 @@ namespace MyParcelNL\Magento\Block\System\Config\Form; -use MyParcelNL\Magento\Helper\Data; - class SupportTabRepository extends \Magento\Sales\Block\Adminhtml\Order\AbstractOrder {/** * @var \Magento\Framework\Module\ModuleListInterface */ protected $moduleList; - /** - * @var \MyParcelNL\Magento\Helper\Data - */ - private $helper; /** * MyParcelSupportTab constructor diff --git a/Controller/Adminhtml/Order/CreateAndPrintMyParcelTrack.php b/Controller/Adminhtml/Order/CreateAndPrintMyParcelTrack.php index fa124595..2bbb56b0 100755 --- a/Controller/Adminhtml/Order/CreateAndPrintMyParcelTrack.php +++ b/Controller/Adminhtml/Order/CreateAndPrintMyParcelTrack.php @@ -11,12 +11,13 @@ use MyParcelNL\Magento\Model\Sales\MagentoCollection; use MyParcelNL\Magento\Model\Sales\MagentoOrderCollection; use MyParcelNL\Magento\Model\Sales\TrackTraceHolder; +use MyParcelNL\Magento\Service\Config; use MyParcelNL\Magento\Ui\Component\Listing\Column\TrackAndTrace; -use MyParcelNL\Sdk\src\Exception\ApiException; -use MyParcelNL\Sdk\src\Exception\MissingFieldException; -use MyParcelNL\Sdk\src\Helper\ValidatePostalCode; -use MyParcelNL\Sdk\src\Helper\ValidateStreet; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; +use MyParcelNL\Sdk\Exception\ApiException; +use MyParcelNL\Sdk\Exception\MissingFieldException; +use MyParcelNL\Sdk\Helper\ValidatePostalCode; +use MyParcelNL\Sdk\Helper\ValidateStreet; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; use Magento\Sales\Model\Order; /** @@ -36,15 +37,9 @@ class CreateAndPrintMyParcelTrack extends \Magento\Framework\App\Action\Action const PATH_MODEL_ORDER = 'Magento\Sales\Model\Order'; const PATH_URI_ORDER_INDEX = 'sales/order/index'; - /** - * @var \Magento\Backend\App\Action\Context - */ - private $context; - /** - * @var MagentoOrderCollection - */ - private $orderCollection; + private MagentoOrderCollection $orderCollection; + private Config $configService; /** * CreateAndPrintMyParcelTrack constructor. @@ -53,12 +48,13 @@ class CreateAndPrintMyParcelTrack extends \Magento\Framework\App\Action\Action */ public function __construct(Context $context) { - $this->context = $context; - parent::__construct($this->context); + // TODO joeri don’t use deprecated action + parent::__construct($context); - $this->resultRedirectFactory = $this->context->getResultRedirectFactory(); + $this->configService = $this->_objectManager->get(Config::class); + $this->resultRedirectFactory = $context->getResultRedirectFactory(); $this->orderCollection = new MagentoOrderCollection( - $context->getObjectManager(), + $this->_objectManager, $this->getRequest(), null ); @@ -76,6 +72,7 @@ public function execute() $this->massAction(); } catch (ApiException | MissingFieldException $e) { $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e); + $this->messageManager->addErrorMessage($e->getMessage()); } return $this->resultRedirectFactory->create()->setPath(self::PATH_URI_ORDER_INDEX); @@ -86,13 +83,13 @@ public function execute() * * @return $this * @throws \Magento\Framework\Exception\LocalizedException - * @throws \MyParcelNL\Sdk\src\Exception\ApiException - * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException + * @throws \MyParcelNL\Sdk\Exception\ApiException + * @throws \MyParcelNL\Sdk\Exception\MissingFieldException * @throws \Exception */ private function massAction() { - if (! $this->orderCollection->apiKeyIsCorrect()) { + if (! $this->configService->apiKeyIsCorrect()) { $message = 'You not have entered the correct API key. To get your personal API credentials you should contact MyParcel.'; $this->messageManager->addErrorMessage(__($message)); $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($message); @@ -115,7 +112,7 @@ private function massAction() $orderIds = $this->filterCorrectAddress($orderIds); $this->addOrdersToCollection($orderIds); - if (TrackTraceHolder::EXPORT_MODE_PPS === $this->orderCollection->getExportMode()) { + if (Config::EXPORT_MODE_PPS === $this->configService->getExportMode()) { $this->orderCollection->setFulfilment(); return $this; @@ -128,10 +125,6 @@ private function massAction() if (! $this->orderCollection->hasShipment()) { $this->messageManager->addErrorMessage(__(MagentoCollection::ERROR_ORDER_HAS_NO_SHIPMENT)); - } - - if ($this->messageManager->getMessages()->getErrors()) { - $this->messageManager->getMessages(); return $this; } @@ -163,7 +156,7 @@ private function addOrdersToCollection($orderIds) /** * @var \Magento\Sales\Model\ResourceModel\Order\Collection $collection */ - $collection = $this->_objectManager->get(MagentoOrderCollection::PATH_MODEL_ORDER); + $collection = $this->_objectManager->get(MagentoOrderCollection::PATH_MODEL_ORDER_COLLECTION); $collection->addAttributeToFilter('entity_id', ['in' => $orderIds]); $this->orderCollection->setOrderCollection($collection); } @@ -175,8 +168,7 @@ private function addOrdersToCollection($orderIds) */ private function filterCorrectAddress(array $orderIds): array { - $objectManager = ObjectManager::getInstance(); - $order = $objectManager->get(Order::class); + $order = $this->_objectManager->get(Order::class); // Go through the selected orders and check if the address details are correct foreach ($orderIds as $orderId) { $order->load($orderId); diff --git a/Controller/Adminhtml/Order/SendMyParcelReturnMail.php b/Controller/Adminhtml/Order/SendMyParcelReturnMail.php index 5bfabb5e..1450c90f 100755 --- a/Controller/Adminhtml/Order/SendMyParcelReturnMail.php +++ b/Controller/Adminhtml/Order/SendMyParcelReturnMail.php @@ -6,6 +6,7 @@ use Magento\Backend\App\Action\Context; use Magento\Framework\Exception\LocalizedException; use MyParcelNL\Magento\Model\Sales\MagentoOrderCollection; +use MyParcelNL\Magento\Service\Config; /** * Action to send mails with a return label @@ -21,13 +22,10 @@ */ class SendMyParcelReturnMail extends \Magento\Framework\App\Action\Action { - const PATH_MODEL_ORDER = 'Magento\Sales\Model\Order'; const PATH_URI_ORDER_INDEX = 'sales/order/index'; - /** - * @var MagentoOrderCollection - */ - private $orderCollection; + private MagentoOrderCollection $orderCollection; + private Config $configService; /** * CreateAndPrintMyParcelTrack constructor. @@ -38,6 +36,7 @@ public function __construct(Context $context) { parent::__construct($context); + $this->configService = $context->getObjectManager()->get(Config::class); $this->resultRedirectFactory = $context->getResultRedirectFactory(); $this->orderCollection = new MagentoOrderCollection( $context->getObjectManager(), @@ -69,7 +68,7 @@ private function sendReturnMail() { error_reporting(E_ALL); ini_set('display_errors', 1); - if ($this->orderCollection->apiKeyIsCorrect() !== true) { + if ($this->configService->apiKeyIsCorrect() !== true) { $message = 'You not have entered the correct API key. Go to the general settings in the back office of MyParcel to generate the API Key.'; $this->messageManager->addErrorMessage(__($message)); $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($message); @@ -123,7 +122,7 @@ private function addOrdersToCollection($orderIds) /** * @var \Magento\Sales\Model\ResourceModel\Order\Collection $collection */ - $collection = $this->_objectManager->get(MagentoOrderCollection::PATH_MODEL_ORDER); + $collection = $this->_objectManager->get(MagentoOrderCollection::PATH_MODEL_ORDER_COLLECTION); $collection->addAttributeToFilter('entity_id', ['in' => $orderIds]); $this->orderCollection->setOrderCollection($collection); } diff --git a/Controller/Adminhtml/Settings/CarrierConfigurationImport.php b/Controller/Adminhtml/Settings/CarrierConfigurationImport.php index 64408dd1..8ab32882 100644 --- a/Controller/Adminhtml/Settings/CarrierConfigurationImport.php +++ b/Controller/Adminhtml/Settings/CarrierConfigurationImport.php @@ -4,7 +4,7 @@ namespace MyParcelNL\Magento\Controller\Adminhtml\Settings; -use Magento\Config\Model\ResourceModel\Config; +use Magento\Config\Model\ResourceModel\Config as resourceConfig; use Magento\Backend\App\Action; use Magento\Backend\App\Action\Context; use Magento\Framework\App\Cache\Frontend\Pool; @@ -12,29 +12,20 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\ObjectManager; use Magento\Framework\Controller\Result\JsonFactory; -use Magento\Framework\Message\ManagerInterface; -use Magento\Framework\Message\MessageInterface; use Magento\Framework\Model\ResourceModel\Db\Context as DbContext; -use MyParcelNL\Magento\Helper\Data; -use MyParcelNL\Magento\Model\Sales\MagentoOrderCollection; -use MyParcelNL\Sdk\src\Model\Account\CarrierConfiguration; -use MyParcelNL\Sdk\src\Model\Account\CarrierOptions; -use MyParcelNL\Sdk\src\Support\Collection; -use MyParcelNL\Sdk\src\Services\Web\AccountWebService; -use MyParcelNL\Sdk\src\Services\Web\CarrierConfigurationWebService; -use MyParcelNL\Sdk\src\Services\Web\CarrierOptionsWebService; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Sdk\Model\Account\CarrierConfiguration; +use MyParcelNL\Sdk\Model\Account\CarrierOptions; +use MyParcelNL\Sdk\Support\Collection; +use MyParcelNL\Sdk\Services\Web\AccountWebService; +use MyParcelNL\Sdk\Services\Web\CarrierConfigurationWebService; +use MyParcelNL\Sdk\Services\Web\CarrierOptionsWebService; class CarrierConfigurationImport extends Action { - /** - * @var string - */ - private $apiKey; - - /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface - */ - private $config; + private string $apiKey; + private ScopeConfigInterface $config; + private Pool $pool; /** * @var mixed @@ -46,11 +37,6 @@ class CarrierConfigurationImport extends Action */ private $typeListInterface; - /** - * @var Pool - */ - private $pool; - /** * @param \Magento\Framework\Controller\Result\JsonFactory $resultFactory * @param \Magento\Backend\App\Action\Context $context @@ -69,22 +55,21 @@ public function __construct( ) { parent::__construct($context); $this->resultFactory = $resultFactory; - $this->config = $config; - $this->apiKey = $this->config->getValue(Data::XML_PATH_GENERAL . 'api/key'); + $this->apiKey = $config->getValue(Config::XML_PATH_GENERAL . 'api/key'); $this->context = $dbContext; $this->typeListInterface = $typeListInterface; $this->pool = $pool; } /** - * @throws \MyParcelNL\Sdk\src\Exception\ApiException - * @throws \MyParcelNL\Sdk\src\Exception\AccountNotActiveException - * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException + * @throws \MyParcelNL\Sdk\Exception\ApiException + * @throws \MyParcelNL\Sdk\Exception\AccountNotActiveException + * @throws \MyParcelNL\Sdk\Exception\MissingFieldException */ public function execute() { - $config = new Config($this->context); - $path = Data::XML_PATH_GENERAL . 'account_settings'; + $config = new ResourceConfig($this->context); + $path = Config::XML_PATH_GENERAL . 'account_settings'; $configuration = $this->fetchConfigurations(); $config->saveConfig($path, json_encode($this->createArray($configuration))); @@ -100,10 +85,10 @@ public function execute() } /** - * @return \MyParcelNL\Sdk\src\Support\Collection - * @throws \MyParcelNL\Sdk\src\Exception\AccountNotActiveException - * @throws \MyParcelNL\Sdk\src\Exception\ApiException - * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException + * @return \MyParcelNL\Sdk\Support\Collection + * @throws \MyParcelNL\Sdk\Exception\AccountNotActiveException + * @throws \MyParcelNL\Sdk\Exception\ApiException + * @throws \MyParcelNL\Sdk\Exception\MissingFieldException */ public function fetchConfigurations(): Collection { @@ -127,14 +112,14 @@ public function fetchConfigurations(): Collection } /** - * @return \MyParcelNL\Sdk\src\Support\Collection|null + * @return \MyParcelNL\Sdk\Support\Collection|null * @throws \Exception */ public static function getAccountSettings(): ?Collection { $objectManager = ObjectManager::getInstance(); $accountSettings = $objectManager->get(ScopeConfigInterface::class) - ->getValue(Data::XML_PATH_GENERAL . 'account_settings'); + ->getValue(Config::XML_PATH_GENERAL . 'account_settings'); if (! $accountSettings) { return null; @@ -155,20 +140,20 @@ private function clearCache(): void } /** - * @param \MyParcelNL\Sdk\src\Support\Collection $settings + * @param \MyParcelNL\Sdk\Support\Collection $settings * * @return array * @TODO sdk#326 remove this entire function and replace with toArray */ private function createArray(Collection $settings): array { - /** @var \MyParcelNL\Sdk\src\Model\Account\Shop $shop */ + /** @var \MyParcelNL\Sdk\Model\Account\Shop $shop */ $shop = $settings->get('shop'); - /** @var \MyParcelNL\Sdk\src\Model\Account\Account $account */ + /** @var \MyParcelNL\Sdk\Model\Account\Account $account */ $account = $settings->get('account'); - /** @var \MyParcelNL\Sdk\src\Model\Account\CarrierOptions[]|Collection $carrierOptions */ + /** @var \MyParcelNL\Sdk\Model\Account\CarrierOptions[]|Collection $carrierOptions */ $carrierOptions = $settings->get('carrier_options'); - /** @var \MyParcelNL\Sdk\src\Model\Account\CarrierConfiguration[]|Collection $carrierConfigurations */ + /** @var \MyParcelNL\Sdk\Model\Account\CarrierConfiguration[]|Collection $carrierConfigurations */ $carrierConfigurations = $settings->get('carrier_configurations'); return [ diff --git a/Controller/Adminhtml/Shipment/CreateAndPrintMyParcelTrack.php b/Controller/Adminhtml/Shipment/CreateAndPrintMyParcelTrack.php index b6f99838..50eef84c 100755 --- a/Controller/Adminhtml/Shipment/CreateAndPrintMyParcelTrack.php +++ b/Controller/Adminhtml/Shipment/CreateAndPrintMyParcelTrack.php @@ -6,7 +6,9 @@ use Magento\Framework\App\ResponseInterface; use Magento\Framework\Controller\ResultInterface; use Magento\Framework\Exception\LocalizedException; +use MyParcelNL\Magento\Model\Sales\MagentoCollection; use MyParcelNL\Magento\Model\Sales\MagentoShipmentCollection; +use MyParcelNL\Magento\Service\Config; /** * Action to create and print MyParcel Track @@ -22,13 +24,13 @@ */ class CreateAndPrintMyParcelTrack extends \Magento\Framework\App\Action\Action { - const PATH_MODEL_ORDER = 'Magento\Sales\Model\Order'; const PATH_URI_SHIPMENT_INDEX = 'sales/shipment/index'; /** * @var MagentoShipmentCollection */ - private $shipmentCollection; + private $shipmentCollection; + private Config $configService; /** * CreateAndPrintMyParcelTrack constructor. @@ -39,6 +41,7 @@ public function __construct(Context $context) { parent::__construct($context); + $this->configService = $context->getObjectManager()->get(Config::class); $this->resultRedirectFactory = $context->getResultRedirectFactory(); $this->shipmentCollection = new MagentoShipmentCollection( $context->getObjectManager(), @@ -52,8 +55,8 @@ public function __construct(Context $context) * * @return ResultInterface|ResponseInterface * @throws LocalizedException - * @throws \MyParcelNL\Sdk\src\Exception\ApiException - * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException + * @throws \MyParcelNL\Sdk\Exception\ApiException + * @throws \MyParcelNL\Sdk\Exception\MissingFieldException */ public function execute() { @@ -67,13 +70,13 @@ public function execute() * * @return $this * @throws LocalizedException - * @throws \MyParcelNL\Sdk\src\Exception\ApiException - * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException + * @throws \MyParcelNL\Sdk\Exception\ApiException + * @throws \MyParcelNL\Sdk\Exception\MissingFieldException * @throws \Exception */ private function massAction() { - if (! $this->shipmentCollection->apiKeyIsCorrect()) { + if (! $this->configService->apiKeyIsCorrect()) { $message = 'You not have entered the correct API key. Go to the general settings in the back office of MyParcel to generate the API Key.'; $this->messageManager->addErrorMessage(__($message)); $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($message); @@ -126,7 +129,7 @@ private function addShipmentsToCollection($shipmentIds) /** * @var \Magento\Sales\Model\ResourceModel\Order\Shipment\Collection $collection */ - $collection = $this->_objectManager->get(MagentoShipmentCollection::PATH_MODEL_SHIPMENT); + $collection = $this->_objectManager->get(MagentoCollection::PATH_MODEL_SHIPMENT_COLLECTION); $collection->addAttributeToFilter('entity_id', ['in' => $shipmentIds]); $this->shipmentCollection->setShipmentCollection($collection); } diff --git a/Cron/UpdateStatus.php b/Cron/UpdateStatus.php index e0b18e21..2022ae63 100755 --- a/Cron/UpdateStatus.php +++ b/Cron/UpdateStatus.php @@ -21,60 +21,56 @@ namespace MyParcelNL\Magento\Cron; +use DateTime; +use Exception; +use Magento\Framework\App\AreaList; use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\AlreadyExistsException; +use Magento\Framework\Exception\LocalizedException; use Magento\Sales\Api\Data\ShipmentTrackInterface; use Magento\Sales\Model\Order; +use Magento\Sales\Model\ResourceModel\Order\Shipment\Track\Collection; use MyParcelNL\Magento\Api\ShipmentStatus; +use MyParcelNL\Magento\Facade\Logger; +use MyParcelNL\Magento\Model\Carrier\Carrier; +use MyParcelNL\Magento\Model\Sales\MagentoCollection; use MyParcelNL\Magento\Model\Sales\MagentoOrderCollection; -use MyParcelNL\Magento\Model\Sales\TrackTraceHolder; +use MyParcelNL\Magento\Service\Config; use MyParcelNL\Magento\Ui\Component\Listing\Column\TrackAndTrace; -use MyParcelNL\Sdk\src\Collection\Fulfilment\OrderCollection; -use Magento\Sales\Model\ResourceModel\Order\Shipment\Track\Collection; +use MyParcelNL\Sdk\Collection\Fulfilment\OrderCollection; +use MyParcelNL\Sdk\Exception\AccountNotActiveException; +use MyParcelNL\Sdk\Exception\ApiException; +use MyParcelNL\Sdk\Exception\MissingFieldException; +use Psr\Log\LoggerInterface; class UpdateStatus { - public const ORDER_ID_NOT_TO_PROCESS = '000000000'; - public const ORDER_STATUS_EXPORTED = 'Exported'; - public const PATH_MODEL_ORDER_TRACK = Collection::class; - public const PATH_MODEL_ORDER = \Magento\Sales\Model\ResourceModel\Order\Collection::class; - - /** - * @var \Psr\Log\LoggerInterface - */ - private $logger; - - /** - * @var ObjectManager - */ - private $objectManager; + public const ORDER_ID_NOT_TO_PROCESS = '000000000'; + public const ORDER_STATUS_EXPORTED = 'Exported'; + public const PATH_MODEL_ORDER_TRACK = Collection::class; - /** - * @var \Magento\Sales\Model\ResourceModel\Order - */ - private $orderResource; - /** - * @var \MyParcelNL\Magento\Model\Sales\MagentoOrderCollection - */ - private $orderCollection; + private ObjectManager $objectManager; + private \Magento\Sales\Model\ResourceModel\Order $orderResource; + private MagentoOrderCollection $orderCollection; + private Config $configService; /** * UpdateStatus constructor. * - * @param \Magento\Framework\App\AreaList $areaList - * @param \Psr\Log\LoggerInterface $logger + * @param AreaList $areaList * @param \Magento\Sales\Model\ResourceModel\Order $orderResource * * @todo; Adjust if there is a solution to the following problem: https://github.com/magento/magento2/pull/8413 */ public function __construct( - \Magento\Framework\App\AreaList $areaList, - \Psr\Log\LoggerInterface $logger, + AreaList $areaList, \Magento\Sales\Model\ResourceModel\Order $orderResource - ) { - $this->objectManager = ObjectManager::getInstance(); + ) + { + $this->objectManager = $objectManager = ObjectManager::getInstance(); + $this->configService = $objectManager->get(Config::class); $this->orderCollection = new MagentoOrderCollection($this->objectManager, null, $areaList); - $this->logger = $logger; $this->orderResource = $orderResource; } @@ -82,19 +78,19 @@ public function __construct( * Run the cron job * * @return $this - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Exception + * @throws LocalizedException + * @throws Exception */ public function execute(): self { - if (TrackTraceHolder::EXPORT_MODE_PPS === $this->orderCollection->getExportMode()) { - return $this->updateStatusOrderbeheer(); + if (Config::EXPORT_MODE_PPS === $this->configService->getExportMode()) { + return $this->updateStatusPPS(); } return $this->updateStatusShipments(); } /** - * Handles orders exported using Orderbeheer setting. + * Handles orders exported using Orderbeheer (PPS) setting. * Gets (max 300) orders from Magento that are eligible, gets the most recently updated orders from the api. * When the api order is one of the eligible Magento orders and it is shipped, adds the shipment in Magento. * @@ -107,18 +103,18 @@ public function execute(): self * this means only on the following run the track_number is updated because the order cannot be shipped anymore. * * @return $this - * @throws \Magento\Framework\Exception\AlreadyExistsException - * @throws \MyParcelNL\Sdk\src\Exception\AccountNotActiveException - * @throws \MyParcelNL\Sdk\src\Exception\ApiException - * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException - * @throws \Exception + * @throws AlreadyExistsException + * @throws AccountNotActiveException + * @throws ApiException + * @throws MissingFieldException + * @throws Exception */ - private function updateStatusOrderbeheer(): self + private function updateStatusPPS(): self { /** * @var \Magento\Sales\Model\ResourceModel\Order\Collection $magentoOrders */ - $magentoOrders = $this->objectManager->get(self::PATH_MODEL_ORDER); + $magentoOrders = $this->objectManager->get(MagentoCollection::PATH_MODEL_ORDER_COLLECTION); $magentoOrders ->addFieldToSelect('increment_id') ->addFieldToSelect('entity_id') @@ -128,40 +124,40 @@ private function updateStatusOrderbeheer(): self ->setOrder('increment_id', 'DESC'); $orderIdsToCheck = array_unique(array_column($magentoOrders->getData(), 'increment_id')); - $apiOrders = OrderCollection::query($this->orderCollection->getApiKey()); + $apiOrders = OrderCollection::query($this->configService->getApiKey()); $orderIdsDone = []; foreach ($apiOrders->getIterator() as $apiOrder) { $incrementId = $apiOrder->getExternalIdentifier(); $shipment = $apiOrder->getOrderShipments()[0]['shipment'] ?? null; - if (! $incrementId - || ! $shipment + if (!$incrementId + || !$shipment || isset($orderIdsDone[$incrementId]) - || ! array_contains($orderIdsToCheck, $incrementId)) { + || !array_contains($orderIdsToCheck, $incrementId)) { continue; } $orderIdsDone[$incrementId] = $incrementId; $barcode = $shipment['external_identifier'] ?? TrackAndTrace::VALUE_PRINTED; - if (! $this->apiShipmentIsShipped($shipment)) { + if (!$this->apiShipmentIsShipped($shipment)) { continue; } $magentoOrder = $this->objectManager->create('Magento\Sales\Model\Order') - ->loadByIncrementId($incrementId); + ->loadByIncrementId($incrementId); - if (! $magentoOrder->canShip()) { + if (!$magentoOrder->canShip()) { $orderIdsDone[$incrementId] = self::ORDER_ID_NOT_TO_PROCESS; - $this->logger->notice('Order is shipped from backoffice but Magento will not create a shipment.'); + Logger::notice('Order is shipped from backoffice but Magento will not create a shipment.'); $this->setShippedWithoutShipment($magentoOrder, $barcode); } } - if (! $orderIdsDone) { - $this->logger->notice('Orderbeheer: no orders updated'); + if (!$orderIdsDone) { + Logger::notice('PPS: no orders updated'); return $this; } @@ -175,24 +171,24 @@ private function updateStatusOrderbeheer(): self $arrayWithIdsArray = $magentoOrders->getData(); foreach ($arrayWithIdsArray as $arrayWithIds) { - if (! in_array($arrayWithIds['increment_id'], $orderIncrementIds)) { + if (!in_array($arrayWithIds['increment_id'], $orderIncrementIds)) { continue; } $orderEntityIds[] = $arrayWithIds['entity_id']; } - if (! $orderEntityIds) { + if (!$orderEntityIds) { return $this; } - $this->logger->notice(sprintf('Orderbeheer: update orders %s', implode(', ', $orderIncrementIds ?? []))); + Logger::notice(sprintf('PPS: update orders %s', implode(', ', $orderIncrementIds ?? []))); $this->addOrdersToCollection($orderEntityIds); $this->orderCollection->setNewMagentoShipment(false) - ->setMagentoTrack() - ->setNewMyParcelTracks() - ->setLatestData() - ->updateMagentoTrack(); + ->setMagentoTrack() + ->setNewMyParcelTracks() + ->setLatestData() + ->updateMagentoTrack(); return $this; } @@ -200,8 +196,8 @@ private function updateStatusOrderbeheer(): self /** * Handles orders that have regular shipments, first removes any lingering orders in $this->orderCollection * - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Exception + * @throws LocalizedException + * @throws Exception */ private function updateStatusShipments(): self { @@ -216,11 +212,11 @@ private function updateStatusShipments(): self } /** - * @throws \Magento\Framework\Exception\AlreadyExistsException + * @throws AlreadyExistsException */ private function setShippedWithoutShipment(Order $magentoOrder, string $barcode): void { - $this->logger->notice( + Logger::notice( sprintf( 'Order %s set to shipped without shipment', $magentoOrder->getIncrementId() @@ -241,13 +237,13 @@ private function apiShipmentIsShipped(array $shipment): bool $status = $shipment['status'] ?? null; return $status >= ShipmentStatus::PRINTED_MINIMUM - && (! in_array($status, [ShipmentStatus::CREDITED, ShipmentStatus::CANCELLED])); + && (!in_array($status, [ShipmentStatus::CREDITED, ShipmentStatus::CANCELLED], true)); } /** * Get all order to update the data * - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ private function setOrdersToUpdate() { @@ -266,15 +262,15 @@ private function setOrdersToUpdate() private function getOrderIdFromTrackToUpdate() { /** - * @var $magentoTrack Order\Shipment\Track - * @var \Magento\Sales\Model\ResourceModel\Order\Shipment\Track\Collection $trackCollection + * @var Order\Shipment\Track $magentoTrack + * @var Collection $trackCollection */ $trackCollection = $this->objectManager->get(self::PATH_MODEL_ORDER_TRACK); $trackCollection ->addFieldToSelect('order_id') ->addAttributeToFilter('myparcel_status', [1, 2, 3, 4, 5, 6, 8]) ->addAttributeToFilter('myparcel_consignment_id', ['notnull' => true]) - ->addAttributeToFilter(ShipmentTrackInterface::CARRIER_CODE, TrackTraceHolder::MYPARCEL_CARRIER_CODE) + ->addAttributeToFilter(ShipmentTrackInterface::CARRIER_CODE, Carrier::CODE) ->setPageSize(300) ->setOrder('order_id', 'DESC'); @@ -291,8 +287,8 @@ private function addOrdersToCollection(array $orderIds): void /** * @var \Magento\Sales\Model\ResourceModel\Order\Collection $collection */ - $now = new \DateTime('now -14 day'); - $collection = $this->objectManager->get(MagentoOrderCollection::PATH_MODEL_ORDER); + $now = new DateTime('now -14 day'); + $collection = $this->objectManager->get(MagentoCollection::PATH_MODEL_ORDER_COLLECTION); $collection ->addAttributeToFilter('entity_id', ['in' => $orderIds]) ->addFieldToFilter('created_at', ['gteq' => $now->format('Y-m-d H:i:s')]); diff --git a/Facade/Facade.php b/Facade/Facade.php new file mode 100644 index 00000000..d14d77c2 --- /dev/null +++ b/Facade/Facade.php @@ -0,0 +1,25 @@ +$method( + ...$args + ); + } + + protected static function getFacadeRoot() + { + return ObjectManager::getInstance()->get(static::getFacadeAccessor()); + } + + abstract public static function getFacadeAccessor(); +} diff --git a/Facade/Logger.php b/Facade/Logger.php new file mode 100644 index 00000000..f97241f9 --- /dev/null +++ b/Facade/Logger.php @@ -0,0 +1,27 @@ + - * @copyright 2010-2016 MyParcel - * @license http://creativecommons.org/licenses/by-nc-nd/3.0/nl/deed.en_US CC BY-NC-ND 3.0 NL - * @link https://github.com/myparcelnl/magento - * @since File available since Release v0.1.0 - */ - -namespace MyParcelNL\Magento\Helper; - -use Magento\Checkout\Model\Session; -use Magento\Framework\App\Helper\Context; -use Magento\Framework\Module\ModuleListInterface; -use Magento\Quote\Api\Data\EstimateAddressInterfaceFactory; -use Magento\Quote\Model\Cart\ShippingMethod; -use Magento\Quote\Model\ShippingMethodManagement; -use MyParcelNL\Magento\Model\Rate\Result; -use MyParcelNL\Magento\Model\Source\PriceDeliveryOptionsView; -use MyParcelNL\Sdk\src\Services\CheckApiKeyService; - -class Checkout extends Data -{ - public const FIELD_DROP_OFF_DAY = 'drop_off_day'; - public const FIELD_MYPARCEL_CARRIER = 'myparcel_carrier'; - public const FIELD_DELIVERY_OPTIONS = 'myparcel_delivery_options'; - public const FIELD_TRACK_STATUS = 'track_status'; - public const DEFAULT_COUNTRY_CODE = 'NL'; - - /** - * @var int - */ - private $base_price = 0; - - /** - * @var ShippingMethodManagement - */ - private $shippingMethodManagement; - /** - * @var EstimateAddressInterfaceFactory - */ - private $estimatedAddressFactory; - - /** - * @var \Magento\Quote\Model\Quote - */ - private $quote; - - /** - * @param Context $context - * @param ModuleListInterface $moduleList - * @param EstimateAddressInterfaceFactory $estimatedAddressFactory - * @param ShippingMethodManagement $shippingMethodManagement - * @param CheckApiKeyService $checkApiKeyService - * @param Session $session - * - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ - public function __construct( - Context $context, - ModuleListInterface $moduleList, - EstimateAddressInterfaceFactory $estimatedAddressFactory, - ShippingMethodManagement $shippingMethodManagement, - CheckApiKeyService $checkApiKeyService, - Session $session - ) { - parent::__construct($context, $moduleList, $checkApiKeyService); - $this->shippingMethodManagement = $shippingMethodManagement; - $this->estimatedAddressFactory = $estimatedAddressFactory; - $this->quote = $session->getQuote(); - } - - /** - * @return float - */ - public function getBasePrice() - { - return $this->base_price; - } - - /** - * @param string $message - * - * @return void - */ - public function log(string $message): void - { - $this->_logger->critical($message); - } - - /** - * @param float $base_price - */ - public function setBasePrice($base_price) - { - $this->base_price = $base_price; - } - - /** - * Set shipping base price - * - * @param int $quoteId - * @param array $forAddress - * @return Checkout - */ - public function setBasePriceFromQuote(int $quoteId, array $forAddress = []): Checkout - { - $method = $this->getParentRateFromQuote($quoteId, $forAddress); - $price = ($method) ? $method->getPriceInclTax() : 0; - - $this->setBasePrice((double) $price); - - return $this; - } - - /** - * @param int $quoteId - * @param array $forAddress - * @return ShippingMethod|null - */ - public function getParentRateFromQuote(int $quoteId, array $forAddress = []) - { - $parentCarriers = explode(',', $this->getGeneralConfig('shipping_methods/methods') ?? ''); - - /** - * @var \Magento\Quote\Api\Data\EstimateAddressInterface $estimatedAddress - * @var \Magento\Quote\Model\Cart\ShippingMethod[] $methods - */ - $estimatedAddress = $this->getEstimatedAddress($forAddress, $this->quote->getShippingAddress()); - $magentoMethods = $this->shippingMethodManagement->estimateByAddress($quoteId, $estimatedAddress); - $myParcelMethods = array_keys(Result::getMethods()); - - foreach ($magentoMethods as $method) { - $methodCode = explode('/', $method->getMethodCode() ?? ''); - $latestMethodCode = array_pop($methodCode); - - if ( - ! in_array($latestMethodCode, $myParcelMethods, true) - && in_array($method->getCarrierCode(), $parentCarriers, true) - ) { - return $method; - } - } - - return null; - } - - /** - * @param array $fromClient - * @param \Magento\Quote\Model\Quote\Address $fromQuote - * - * @return \Magento\Quote\Api\Data\EstimateAddressInterface - */ - private function getEstimatedAddress( - array $fromClient, - \Magento\Quote\Model\Quote\Address $fromQuote - ): \Magento\Quote\Api\Data\EstimateAddressInterface - { - $address = $this->estimatedAddressFactory->create(); - - if (isset($fromClient['countryId'])) { - $address->setCountryId($fromClient['countryId']); - $address->setPostcode($fromClient['postcode'] ?? ''); - $address->setRegion($fromClient['region'] ?? ''); - } else { - $address->setCountryId($fromQuote->getCountryId() ?? self::DEFAULT_COUNTRY_CODE); - $address->setPostcode($fromQuote->getPostcode() ?? ''); - $address->setRegion($fromQuote->getRegion() ?? ''); - $address->setRegionId($fromQuote->getRegionId() ?? 0); - } - - return $address; - } - - /** - * Get MyParcel method/option price. - * Check if total shipping price is not below 0 euro - * - * @param string $carrier - * @param string $key - * @param bool $addBasePrice - * - * @return float - */ - public function getMethodPrice(string $carrier, string $key, bool $addBasePrice = true): float - { - $value = (float) $this->getCarrierConfig($key, $carrier); - $showTotalPrice = $this->getCarrierConfig('shipping_methods/delivery_options_prices', Data::XML_PATH_GENERAL) === PriceDeliveryOptionsView::TOTAL; - - if ($showTotalPrice && $addBasePrice) { - // Calculate value - $value = (float) $this->getBasePrice() + $value; - } - - return $value; - } - - /** - * Get shipping price - * - * @param $price - * @param $flag - * - * @return mixed - */ - /*private function getShippingPrice($price, $flag = false) - { - $flag = $flag ? true : Mage::helper('tax')->displayShippingPriceIncludingTax(); - return (float)Mage::helper('tax')->getShippingPrice($price, $flag, $quoteId->getShippingAddress()); - }*/ - - /** - * Get checkout setting - * - * @param string $carrier - * @param string $code - * - * @return mixed - */ - public function getCarrierConfig(string $code, string $carrier) - { - $value = $this->getConfigValue($carrier . $code); - if (null === $value) { - $this->_logger->critical('Can\'t get setting with path:' . $carrier . $code); - return 0; - } - - return $value; - } - - /** - * Get bool of setting - * - * @param string $carrier - * @param string $key - * - * @return bool - */ - public function getBoolConfig(string $carrier, string $key): bool - { - return '1' === $this->getCarrierConfig($key, $carrier); - } - - /** - * Get time for delivery endpoint - * - * @param string $carrier - * @param string $key - * - * @return string - */ - public function getTimeConfig(string $carrier, string $key): string - { - $timeAsString = str_replace(',', ':', (string) $this->getCarrierConfig($key, $carrier)); - $timeComponents = explode(':', $timeAsString ?? ''); - if (count($timeComponents) >= 3) { - [$hours, $minutes] = $timeComponents; - $timeAsString = $hours . ':' . $minutes; - } - - return $timeAsString; - } - - /** - * Get array for delivery endpoint - * - * @param string $carrier - * @param string $key - * - * @return array - */ - public function getArrayConfig(string $carrier, string $key): array - { - return array_map(static function($val) { - return is_numeric($val) ? (int) $val : $val; - }, explode(',', (string) ($this->getCarrierConfig($key, $carrier) ?? ''))); - } - - /** - * Get array for delivery endpoint - * - * @param string $carrier - * @param string $key - * - * @return float - */ - public function getIntegerConfig($carrier, $key) - { - return (float) $this->getCarrierConfig($key, $carrier); - } -} diff --git a/Helper/CustomsDeclarationFromOrder.php b/Helper/CustomsDeclarationFromOrder.php index 4d14fcd3..fb8f66aa 100644 --- a/Helper/CustomsDeclarationFromOrder.php +++ b/Helper/CustomsDeclarationFromOrder.php @@ -2,16 +2,18 @@ namespace MyParcelNL\Magento\Helper; +use Exception; +use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product; -use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\App\ObjectManager; use Magento\Sales\Model\Order; -use MyParcelNL\Magento\Model\Sales\TrackTraceHolder; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; -use MyParcelNL\Sdk\src\Model\CustomsDeclaration; -use MyParcelNL\Sdk\src\Model\MyParcelCustomsItem; -use Magento\Catalog\Api\ProductRepositoryInterface; -use MyParcelNL\Sdk\src\Support\Str; -use MyParcelNL\Magento\Helper\Data; +use MyParcelNL\Magento\Service\DeliveryCosts; +use MyParcelNL\Magento\Service\Weight; +use MyParcelNL\Sdk\Exception\MissingFieldException; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; +use MyParcelNL\Sdk\Model\CustomsDeclaration; +use MyParcelNL\Sdk\Model\MyParcelCustomsItem; +use MyParcelNL\Sdk\Support\Str; class CustomsDeclarationFromOrder { @@ -23,30 +25,35 @@ class CustomsDeclarationFromOrder private $helper; /** - * @var \Magento\Framework\App\ObjectManager + * @var ObjectManager */ private $objectManager; /** - * @var \Magento\Sales\Model\Order + * @var Order */ private $order; /** - * @param \Magento\Sales\Model\Order $order - * @param \Magento\Framework\ObjectManagerInterface $objectManager + * @var Weight + */ + private $weightService; + + /** + * @param Order $order */ - public function __construct(Order $order, ObjectManagerInterface $objectManager) + public function __construct(Order $order) { + $objectManager = ObjectManager::getInstance(); $this->order = $order; $this->objectManager = $objectManager; - $this->helper = $this->objectManager->get(Data::class); + $this->weightService = $objectManager->get(Weight::class); } /** - * @return \MyParcelNL\Sdk\src\Model\CustomsDeclaration - * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException - * @throws \Exception + * @return CustomsDeclaration + * @throws MissingFieldException + * @throws Exception */ public function createCustomsDeclaration(): CustomsDeclaration { @@ -56,22 +63,22 @@ public function createCustomsDeclaration(): CustomsDeclaration foreach ($this->order->getItems() as $item) { $product = $item->getProduct(); - if (! $product) { + if (!$product) { continue; } - $amount = (float) $item->getQtyShipped() ? $item->getQtyShipped() : $item->getQtyOrdered(); - $totalWeight += $this->helper->convertToGrams($product->getWeight() * $amount); - $description = Str::limit($product->getName(), AbstractConsignment::DESCRIPTION_MAX_LENGTH); + $amount = (float)$item->getQtyShipped() ? $item->getQtyShipped() : $item->getQtyOrdered(); + $totalWeight += $this->weightService->convertToGrams($product->getWeight() * $amount); + $description = Str::limit($product->getName(), AbstractConsignment::CUSTOMS_DECLARATION_DESCRIPTION_MAX_LENGTH); $customsItem = (new MyParcelCustomsItem()) ->setDescription($description) ->setAmount($amount) - ->setWeight($this->helper->convertToGrams($product->getWeight())) + ->setWeight($this->weightService->convertToGrams($product->getWeight())) ->setItemValueArray([ - 'amount' => TrackTraceHolder::getCentsByPrice($product->getPrice()), - 'currency' => $this->order->getOrderCurrency()->getCode() ?? self::CURRENCY_EURO, - ]) + 'amount' => DeliveryCosts::getPriceInCents($product->getPrice()), + 'currency' => $this->order->getOrderCurrency()->getCode() ?? self::CURRENCY_EURO, + ]) ->setCountry($this->getCountryOfOrigin($product)) ->setClassification($this->getHsCode($product)); @@ -87,7 +94,7 @@ public function createCustomsDeclaration(): CustomsDeclaration } /** - * @param \Magento\Catalog\Model\Product $product + * @param Product $product * * @return string */ @@ -102,7 +109,7 @@ private function getCountryOfOrigin(Product $product): string } /** - * @param \Magento\Catalog\Model\Product $product + * @param Product $product * * @return int */ diff --git a/Helper/Data.php b/Helper/Data.php index 3e50b30a..085550c7 100755 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -8,16 +8,16 @@ use Magento\Framework\Module\ModuleListInterface; use Magento\Store\Model\ScopeInterface; use MyParcelNL\Magento\Model\Settings\AccountSettings; -use MyParcelNL\Sdk\src\Model\Carrier\AbstractCarrier; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierDHLEuroplus; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierDHLForYou; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierDHLParcelConnect; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierDPD; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierPostNL; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierUPS; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; -use MyParcelNL\Sdk\src\Model\Consignment\DropOffPoint; -use MyParcelNL\Sdk\src\Services\CheckApiKeyService; +use MyParcelNL\Sdk\Model\Carrier\AbstractCarrier; +use MyParcelNL\Sdk\Model\Carrier\CarrierDHLEuroplus; +use MyParcelNL\Sdk\Model\Carrier\CarrierDHLForYou; +use MyParcelNL\Sdk\Model\Carrier\CarrierDHLParcelConnect; +use MyParcelNL\Sdk\Model\Carrier\CarrierDPD; +use MyParcelNL\Sdk\Model\Carrier\CarrierPostNL; +use MyParcelNL\Sdk\Model\Carrier\CarrierUPS; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; +use MyParcelNL\Sdk\Model\Consignment\DropOffPoint; +use MyParcelNL\Sdk\Services\CheckApiKeyService; class Data extends AbstractHelper { @@ -30,7 +30,6 @@ class Data extends AbstractHelper public const XML_PATH_UPS_SETTINGS = 'myparcelnl_magento_ups_settings/'; public const XML_PATH_DPD_SETTINGS = 'myparcelnl_magento_dpd_settings/'; public const XML_PATH_LOCALE_WEIGHT_UNIT = 'general/locale/weight_unit'; - public const DEFAULT_WEIGHT = 1000; public const CARRIERS_XML_PATH_MAP = [ CarrierPostNL::NAME => self::XML_PATH_POSTNL_SETTINGS, CarrierDHLForYou::NAME => self::XML_PATH_DHLFORYOU_SETTINGS, @@ -62,9 +61,11 @@ public function __construct( ModuleListInterface $moduleList, CheckApiKeyService $checkApiKeyService ) { + throw new \Exception('Do not use Helper/Data.php'); parent::__construct($context); $this->moduleList = $moduleList; $this->checkApiKeyService = $checkApiKeyService; + throw new \Exception('do not use Data.php'); } /** @@ -123,36 +124,11 @@ public function getDropOffPoint(AbstractCarrier $carrier): ?DropOffPoint * * @return mixed */ - public function getStandardConfig(string $carrier, string $code = '', $storeId = null) + public function getCarrierConfig(string $carrier, string $code = '', $storeId = null) { return $this->getConfigValue(self::CARRIERS_XML_PATH_MAP[$carrier] . $code, $storeId); } - /** - * Get carrier setting - * - * @param string $code - * @param string $carrier - * - * @return mixed - */ - public function getCarrierConfig(string $code, string $carrier) - { - $settings = $this->getConfigValue($carrier . $code); - - if (null === $settings) { - $value = $this->getConfigValue($carrier . $code); - - if (null === $value) { - $this->_logger->critical('Can\'t get setting with path:' . $carrier . $code); - } - - return $value; - } - - return $settings; - } - /** * Get the version number of the installed module * @@ -267,33 +243,13 @@ public function consignmentHasShipmentOption(AbstractConsignment $consignment, s AbstractConsignment::SHIPMENT_OPTION_SIGNATURE], true); } - // No shipment options available in any other cases - return false; - } - - /** - * Get the correct weight type - * - * @param null|float $weight - * - * @return int - */ - public function convertToGrams(?float $weight): int - { - $weightType = $this->getGeneralConfig('print/weight_indication'); - - if ('kilo' === $weightType) { - return (int) ($weight * 1000); + // For UPS shipment options are available for all countries in the EU + if (CarrierUPS::NAME === $consignment->getCarrierName()) { + return true; } - return (int) $weight ?: self::DEFAULT_WEIGHT; + // No shipment options available in any other cases + return false; } - /** - * @return string|null - */ - public function getExportMode(): ?string - { - return $this->getGeneralConfig('print/export_mode'); - } } diff --git a/Helper/ShipmentOptions.php b/Helper/ShipmentOptions.php index 27ebf134..5ad754f6 100644 --- a/Helper/ShipmentOptions.php +++ b/Helper/ShipmentOptions.php @@ -4,20 +4,26 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\ObjectManagerInterface; +use Magento\Sales\Model\Order; use MyParcelNL\Magento\Model\Source\DefaultOptions; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Magento\Service\Dating; +use MyParcelNL\Sdk\Model\Carrier\CarrierPostNL; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; use Magento\Framework\App\ResourceConnection; class ShipmentOptions { - private const INSURANCE = 'insurance'; - private const ONLY_RECIPIENT = 'only_recipient'; - private const SAME_DAY_DELIVERY = 'same_day_delivery'; - private const SIGNATURE = 'signature'; - private const RETURN = 'return'; - private const AGE_CHECK = 'age_check'; - private const LARGE_FORMAT = 'large_format'; - private const HIDE_SENDER = 'hide_sender'; + public const INSURANCE = AbstractConsignment::SHIPMENT_OPTION_INSURANCE; + public const ONLY_RECIPIENT = AbstractConsignment::SHIPMENT_OPTION_ONLY_RECIPIENT; + private const SAME_DAY_DELIVERY = AbstractConsignment::SHIPMENT_OPTION_SAME_DAY_DELIVERY; + public const SIGNATURE = AbstractConsignment::SHIPMENT_OPTION_SIGNATURE; + public const COLLECT = AbstractConsignment::SHIPMENT_OPTION_COLLECT; + public const RECEIPT_CODE = AbstractConsignment::SHIPMENT_OPTION_RECEIPT_CODE; + public const RETURN = AbstractConsignment::SHIPMENT_OPTION_RETURN; + public const AGE_CHECK = AbstractConsignment::SHIPMENT_OPTION_AGE_CHECK; + public const LARGE_FORMAT = AbstractConsignment::SHIPMENT_OPTION_LARGE_FORMAT; + private const HIDE_SENDER = AbstractConsignment::SHIPMENT_OPTION_HIDE_SENDER; private const LABEL_DESCRIPTION = 'label_description'; private const ORDER_NUMBER = '%order_nr%'; private const DELIVERY_DATE = '%delivery_date%'; @@ -31,12 +37,12 @@ class ShipmentOptions private $carrier; /** - * @var \MyParcelNL\Magento\Model\Source\DefaultOptions + * @var DefaultOptions */ - private static $defaultOptions; + private $defaultOptions; /** - * @var \Magento\Framework\ObjectManagerInterface + * @var ObjectManagerInterface */ private $objectManager; @@ -46,38 +52,37 @@ class ShipmentOptions private $options; /** - * @var \MyParcelNL\Magento\Helper\Data + * @var Data */ - private $helper; + private $configService; /** - * @var \Magento\Sales\Model\Order + * @var Order */ private $order; /** * @var string|null */ - private $cc; + private ?string $cc; /** - * @param \MyParcelNL\Magento\Model\Source\DefaultOptions $defaultOptions - * @param \MyParcelNL\Magento\Helper\Data $helper - * @param \Magento\Sales\Model\Order $order - * @param \Magento\Framework\ObjectManagerInterface $objectManager - * @param string $carrier - * @param array $options + * @param DefaultOptions $defaultOptions + * @param Order $order + * @param ObjectManagerInterface $objectManager + * @param string $carrier + * @param array $options */ public function __construct( - DefaultOptions $defaultOptions, - Data $helper, - \Magento\Sales\Model\Order $order, - ObjectManagerInterface $objectManager, - string $carrier, - array $options = [] - ) { - self::$defaultOptions = $defaultOptions; - $this->helper = $helper; + DefaultOptions $defaultOptions, + Order $order, + ObjectManagerInterface $objectManager, + string $carrier, + array $options = [] + ) + { + $this->defaultOptions = $defaultOptions; + $this->configService = $objectManager->get(Config::class); $this->order = $order; $this->objectManager = $objectManager; $this->carrier = $carrier; @@ -90,7 +95,7 @@ public function __construct( */ public function getInsurance(): int { - return $this->options['insurance'] ?? self::$defaultOptions->getDefaultInsurance($this->carrier); + return $this->options['insurance'] ?? $this->defaultOptions->getDefaultInsurance($this->carrier); } /** @@ -107,6 +112,28 @@ public function hasSignature(): bool return $signatureFromOptions ?? $this->optionIsEnabled(self::SIGNATURE); } + public function hasCollect(): bool + { + $collectFromOptions = self::getValueOfOptionWhenSet(self::COLLECT, $this->options); + + return $collectFromOptions ?? $this->optionIsEnabled(self::COLLECT); + } + + public function hasReceiptCode(): bool + { + $deliveryOptions = $this->order->getData(Config::FIELD_DELIVERY_OPTIONS) ?? []; + $deliveryType = $deliveryOptions['deliveryType'] ?? AbstractConsignment::DEFAULT_DELIVERY_TYPE; + + if (AbstractConsignment::CC_NL !== $this->cc + || CarrierPostNL::NAME !== $this->carrier + || AbstractConsignment::DELIVERY_TYPE_STANDARD !== $deliveryType + ) { + return false; + } + + return self::getValueOfOptionWhenSet(self::RECEIPT_CODE, $this->options) ?? $this->optionIsEnabled(self::RECEIPT_CODE); + } + /** * @return bool */ @@ -148,7 +175,7 @@ public function hasAgeCheck(): bool $ageCheckFromOptions = self::getValueOfOptionWhenSet(self::AGE_CHECK, $this->options); $ageCheckOfProduct = self::getAgeCheckFromProduct($this->order->getItems()); - $ageCheckFromSettings = self::$defaultOptions->hasDefaultOptionsWithoutPrice($this->carrier, self::AGE_CHECK); + $ageCheckFromSettings = $this->defaultOptions->hasDefaultOption($this->carrier, self::AGE_CHECK); return $ageCheckFromOptions ?? $ageCheckOfProduct ?? $ageCheckFromSettings; } @@ -173,7 +200,7 @@ public static function getAgeCheckFromProduct($products): ?bool $productAgeCheck = self::getAttributeValue( 'catalog_product_entity_varchar', $product['product_id'], - 'age_check' + self::AGE_CHECK ); if (! isset($productAgeCheck) || '' === $productAgeCheck) { @@ -187,9 +214,9 @@ public static function getAgeCheckFromProduct($products): ?bool } /** - * @param string $tableName - * @param string $entityId - * @param string $column + * @param string $tableName + * @param string $entityId + * @param string $column * * @return null|string */ @@ -214,8 +241,8 @@ public static function getAttributeValue(string $tableName, string $entityId, st /** * @param $connection - * @param string $tableName - * @param string $databaseColumn + * @param string $tableName + * @param string $databaseColumn * * @return mixed */ @@ -230,10 +257,10 @@ public static function getAttributeId($connection, string $tableName, string $da } /** - * @param object $connection - * @param string $tableName - * @param string $attributeId - * @param string $entityId + * @param object $connection + * @param string $tableName + * @param string $attributeId + * @param string $entityId * * @return string|null */ @@ -242,7 +269,8 @@ public static function getValueFromAttribute( string $tableName, string $attributeId, string $entityId - ): ?string { + ): ?string + { $sql = $connection ->select() ->from($tableName, ['value']) @@ -253,8 +281,8 @@ public static function getValueFromAttribute( } /** - * @param string $key - * @param array $options + * @param string $key + * @param array $options * * @return bool|null boolean value of the option named $key, or null when not set in $options */ @@ -277,7 +305,7 @@ public function hasLargeFormat(): bool } $largeFormatFromOptions = self::getValueOfOptionWhenSet(self::LARGE_FORMAT, $this->options); - $largeFormatFromSettings = self::$defaultOptions->hasDefault(self::LARGE_FORMAT, $this->carrier); + $largeFormatFromSettings = $this->defaultOptions->hasOptionSet(self::LARGE_FORMAT, $this->carrier); return $largeFormatFromOptions ?? $largeFormatFromSettings; } @@ -287,8 +315,7 @@ public function hasLargeFormat(): bool */ public function getLabelDescription(): string { - $checkoutData = $this->order->getData('myparcel_delivery_options'); - $labelDescription = $this->helper->getGeneralConfig( + $labelDescription = $this->configService->getGeneralConfig( 'print/label_description', $this->order->getStoreId() ); @@ -297,8 +324,9 @@ public function getLabelDescription(): string return ''; } + $deliveryOptions = $this->order->getData(Config::FIELD_DELIVERY_OPTIONS); + $checkoutDate = json_decode($deliveryOptions, true)['date'] ?? null; $productInfo = $this->getItemsCollectionByShipmentId($this->order->getId()); - $deliveryDate = $checkoutData ? date('d-m-Y', strtotime($this->helper->convertDeliveryDate($checkoutData))) : null; $labelDescription = str_replace( [ self::ORDER_NUMBER, @@ -309,7 +337,7 @@ public function getLabelDescription(): string ], [ $this->order->getIncrementId(), - $this->helper->convertDeliveryDate($checkoutData) ? $deliveryDate : '', + Dating::convertDeliveryDate($checkoutDate, 'd-m-Y') ?: '', $this->getProductInfo($productInfo, 'product_id'), $this->getProductInfo($productInfo, 'name'), $productInfo ? round($this->getProductInfo($productInfo, 'qty')) : null, @@ -321,8 +349,8 @@ public function getLabelDescription(): string } /** - * @param array $productInfo - * @param string $field + * @param array $productInfo + * @param string $field * * @return string|null */ @@ -342,14 +370,14 @@ private function getProductInfo(array $productInfo, string $field): ?string */ public function getItemsCollectionByShipmentId($shipmentId): array { - /** @var \Magento\Framework\App\ResourceConnection $connection */ + /** @var ResourceConnection $connection */ $connection = $this->objectManager->create(ResourceConnection::class); $conn = $connection->getConnection(); $select = $conn->select() - ->from( - ['main_table' => $connection->getTableName('sales_shipment_item')] - ) - ->where('main_table.parent_id=?', $shipmentId); + ->from( + ['main_table' => $connection->getTableName('sales_shipment_item')] + ) + ->where('main_table.parent_id=?', $shipmentId); return $conn->fetchAll($select); } @@ -364,7 +392,7 @@ public function getItemsCollectionByShipmentId($shipmentId): array private function optionIsEnabled($optionKey): bool { if (! isset($this->options[$optionKey])) { - return self::$defaultOptions->hasDefault($optionKey, $this->carrier); + return $this->defaultOptions->hasOptionSet($optionKey, $this->carrier); } return (bool) $this->options[$optionKey]; @@ -380,6 +408,8 @@ public function getShipmentOptions(): array self::RETURN => $this->hasReturn(), self::ONLY_RECIPIENT => $this->hasOnlyRecipient(), self::SIGNATURE => $this->hasSignature(), + self::COLLECT => $this->hasCollect(), + self::RECEIPT_CODE => $this->hasReceiptCode(), self::AGE_CHECK => $this->hasAgeCheck(), self::LARGE_FORMAT => $this->hasLargeFormat(), self::LABEL_DESCRIPTION => $this->getLabelDescription(), @@ -388,4 +418,3 @@ public function getShipmentOptions(): array ]; } } - diff --git a/Model/Carrier/Carrier.php b/Model/Carrier/Carrier.php new file mode 100644 index 00000000..c1c07c71 --- /dev/null +++ b/Model/Carrier/Carrier.php @@ -0,0 +1,214 @@ + + * @copyright 2010-2019 MyParcel + * @license http://creativecommons.org/licenses/by-nc-nd/3.0/nl/deed.en_US CC BY-NC-ND 3.0 NL + * @link https://github.com/myparcelnl/magento + * @since File available since Release 0.1.0 + */ + +namespace MyParcelNL\Magento\Model\Carrier; + +use Exception; +use InvalidArgumentException; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\DataObject; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\Quote\Address\RateRequest; +use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory; +use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory; +use Magento\Shipping\Model\Carrier\AbstractCarrier; +use Magento\Shipping\Model\Carrier\CarrierInterface; +use Magento\Shipping\Model\Rate\ResultFactory; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Magento\Service\DeliveryCosts; +use MyParcelNL\Magento\Service\NeedsQuoteProps; +use MyParcelNL\Magento\Service\Tax; +use MyParcelNL\Sdk\Adapter\DeliveryOptions\ShipmentOptionsV3Adapter; +use MyParcelNL\Sdk\Model\Carrier\CarrierFactory; +use Psr\Log\LoggerInterface; + +class Carrier extends AbstractCarrier implements CarrierInterface +{ + use NeedsQuoteProps; + + public const CODE = 'myparcel'; // same as in /etc/config.xml and the carrier group in system.xml + + protected $_code = self::CODE; // $_code is a mandatory property for a Magento carrier + protected $_name; + protected $_title; + + /** + * Carrier constructor. + * + * @param ScopeConfigInterface $scopeConfig + * @param ErrorFactory $rateErrorFactory + * @param LoggerInterface $logger + * @param Tax $tax + * @param Config $config + * @param DeliveryCosts $deliveryCosts + * @param ResultFactory $rateFactory + * @param MethodFactory $rateMethodFactory + * @param array $data + * + */ + public function __construct( + ScopeConfigInterface $scopeConfig, + ErrorFactory $rateErrorFactory, + LoggerInterface $logger, + Tax $tax, + Config $config, + DeliveryCosts $deliveryCosts, + ResultFactory $rateFactory, + MethodFactory $rateMethodFactory, + array $data = [] + ) + { + parent::__construct( + $scopeConfig, + $rateErrorFactory, + $logger, + $data, + ); + + $this->_name = $config->getMagentoCarrierConfig('name') ?: self::CODE; + $this->_title = $config->getMagentoCarrierConfig('title') ?: self::CODE; + + $this->tax = $tax; + $this->config = $config; + $this->rateResultFactory = $rateFactory; + $this->rateMethodFactory = $rateMethodFactory; + $this->deliveryCosts = $deliveryCosts; + } + + public function collectRates(RateRequest $request) + { + if (!$this->getConfigFlag('active')) { + return false; + } + + $quote = $this->getQuoteFromRateRequest($request); + + if (null === $quote) { + throw new InvalidArgumentException('No quote found in request'); + } + + $result = $this->rateResultFactory->create(); + $method = $this->rateMethodFactory->create(); + + $method->setCarrier($this->_code); + $method->setCarrierTitle($this->_title); + $method->setMethod($this->_name); + $method->setMethodTitle($this->getMethodTitle($quote)); + $method->setPrice((string) $this->getMethodAmount($quote)); + + $result->append($method); + + return $result; + } + + public function getMethodForFrontend(Quote $quote): array + { + $amount = $this->getMethodAmount($quote); + + //todo joeri where is this specific structure / array coming from? Not method->toArray unfortunately + return [ + 'amount' => $amount, + 'available' => true, + 'base_amount' => $amount, + 'carrier_code' => $this->_code, + 'carrier_title' => $this->_title, + 'error_message' => '', + 'method_code' => $this->_name, + 'method_title' => $this->getMethodTitle($quote), + //todo JOERI where is excl / incl vat ever used? Some custom checkout maybe? + 'price_excl_tax' => $this->tax->excludingVat($amount, $quote), + 'price_incl_tax' => $this->tax->includingVat($amount, $quote), + ]; + } + + private function getMethodAmount(Quote $quote): float + { + $deliveryOptions = $this->getDeliveryOptionsFromQuote($quote); + $configPath = Config::CARRIERS_XML_PATH_MAP[$deliveryOptions->getCarrier()] ?? ''; + $shipmentOptions = $deliveryOptions->getShipmentOptions() ?? new ShipmentOptionsV3Adapter([]); + $shipmentFees = [ + "{$deliveryOptions->getDeliveryType()}/fee" => true, + //"{$deliveryOptions->getPackageType()}/fee" => true, + 'delivery/only_recipient_fee' => $shipmentOptions->hasOnlyRecipient(), + 'delivery/signature_fee' => $shipmentOptions->hasSignature(), + 'delivery/receipt_code_fee' => $shipmentOptions->hasReceiptCode(), + ]; + + $amount = $this->deliveryCosts->getBasePrice($quote); + + foreach ($shipmentFees as $key => $value) { + if (!$value) { + continue; + } + $amount += (float) $this->config->getConfigValue("$configPath$key"); + } + + // the method should never give a discount on the order, so we return 0 if the amount is negative + return max(0, $amount); + } + + private function getMethodTitle(Quote $quote): string + { + $deliveryOptions = $this->getDeliveryOptionsFromQuote($quote); + $shipmentOptions = $deliveryOptions->getShipmentOptions() ?? new ShipmentOptionsV3Adapter([]); + $carrierName = $deliveryOptions->getCarrier(); + + if (null === $carrierName) { + return $this->_title; + } + + try { + $carrierHuman = CarrierFactory::createFromName($carrierName)->getHuman(); + } catch (Exception $e) { + $carrierHuman = $carrierName; + } + + ob_start(); + echo $carrierHuman, ' ', __("{$deliveryOptions->getDeliveryType()}_title"), ', ', __("{$deliveryOptions->getPackageType()}_title"); + + + foreach ($shipmentOptions->toArray() as $key => $value) { + if ($value) { + echo ', ', trim(__("{$key}_title")); + } + } + + return trim(ob_get_clean()); + } + + public function processAdditionalValidation(DataObject $request): bool + { + return true; + } + + /** + * Get allowed shipping methods + * + * @return array + */ + public function getAllowedMethods(): array + { + return [$this->_name]; + } + + public function isTrackingAvailable(): bool + { + // TODO: Implement isTrackingAvailable() method. + return true; + } +} diff --git a/Model/Checkout/Carrier.php b/Model/Checkout/Carrier.php deleted file mode 100644 index 0c9a8949..00000000 --- a/Model/Checkout/Carrier.php +++ /dev/null @@ -1,257 +0,0 @@ - - * @copyright 2010-2019 MyParcel - * @license http://creativecommons.org/licenses/by-nc-nd/3.0/nl/deed.en_US CC BY-NC-ND 3.0 NL - * @link https://github.com/myparcelnl/magento - * @since File available since Release 0.1.0 - */ - -namespace MyParcelNL\Magento\Model\Checkout; - -use Magento\CatalogInventory\Api\StockRegistryInterface; -use Magento\Checkout\Model\Session; -use Magento\Directory\Model\CountryFactory; -use Magento\Directory\Model\CurrencyFactory; -use Magento\Directory\Model\RegionFactory; -use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\DataObject; -use Magento\Framework\Xml\Security; -use Magento\Quote\Model\Quote\Address\RateRequest; -use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory; -use Magento\Shipping\Model\Carrier\AbstractCarrierOnline; -use Magento\Shipping\Model\Carrier\CarrierInterface; -use Magento\Shipping\Model\Simplexml\ElementFactory; -use Magento\Shipping\Model\Tracking\Result\ErrorFactory; -use Magento\Shipping\Model\Tracking\Result\StatusFactory; -use Magento\Shipping\Model\Tracking\ResultFactory; -use MyParcelNL\Magento\Helper\Checkout; -use MyParcelNL\Magento\Helper\Data; -use MyParcelNL\Magento\Model\Sales\Repository\PackageRepository; -use Psr\Log\LoggerInterface; - -class Carrier extends AbstractCarrierOnline implements CarrierInterface -{ - const CODE = 'mypa'; - protected $_code = self::CODE; - protected $_localeFormat; - - /** - * @var \Magento\Quote\Model\Quote - */ - private $quote; - - /** - * @var Checkout - */ - private $myParcelHelper; - - /** - * @var PackageRepository - */ - private $package; - - /** - * Carrier constructor. - * - * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory - * @param \Psr\Log\LoggerInterface $logger - * @param Security $xmlSecurity - * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory - * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory - * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory - * @param \Magento\Shipping\Model\Tracking\ResultFactory $trackFactory - * @param \Magento\Shipping\Model\Tracking\Result\ErrorFactory $trackErrorFactory - * @param \Magento\Shipping\Model\Tracking\Result\StatusFactory $trackStatusFactory - * @param \Magento\Directory\Model\RegionFactory $regionFactory - * @param \Magento\Directory\Model\CountryFactory $countryFactory - * @param \Magento\Directory\Model\CurrencyFactory $currencyFactory - * @param \Magento\Directory\Helper\Data $directoryData - * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry - * @param \Magento\Checkout\Model\Session $session - * @param Checkout $myParcelHelper - * @param PackageRepository $package - * @param array $data - * - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ - public function __construct( - ScopeConfigInterface $scopeConfig, - \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory, - LoggerInterface $logger, - Security $xmlSecurity, - ElementFactory $xmlElFactory, - \Magento\Shipping\Model\Rate\ResultFactory $rateFactory, - MethodFactory $rateMethodFactory, - ResultFactory $trackFactory, - ErrorFactory $trackErrorFactory, - StatusFactory $trackStatusFactory, - RegionFactory $regionFactory, - CountryFactory $countryFactory, - CurrencyFactory $currencyFactory, - \Magento\Directory\Helper\Data $directoryData, - StockRegistryInterface $stockRegistry, - Session $session, - Checkout $myParcelHelper, - PackageRepository $package, - array $data = [] - ) { - parent::__construct( - $scopeConfig, - $rateErrorFactory, - $logger, - $xmlSecurity, - $xmlElFactory, - $rateFactory, - $rateMethodFactory, - $trackFactory, - $trackErrorFactory, - $trackStatusFactory, - $regionFactory, - $countryFactory, - $currencyFactory, - $directoryData, - $stockRegistry, - $data - ); - $this->quote = $session->getQuote(); - $this->myParcelHelper = $myParcelHelper; - $this->package = $package; - } - - protected function _doShipmentRequest(DataObject $request) - { - } - - public function collectRates(RateRequest $request) - { - /** @var \Magento\Quote\Model\Quote\Address\RateRequest $result */ - $result = $this->_rateFactory->create(); - $result = $this->addShippingMethods($result); - - return $result; - } - - public function proccessAdditionalValidation(DataObject $request) - { - return true; - } - - /** - * Get allowed shipping methods - * - * @return array - */ - public static function getMethods() - { - $methods = [ - 'signature_only_recip' => 'delivery/signature_and_only_recipient_', - 'morning' => 'morning/', - 'morning_signature' => 'morning_signature/', - 'evening' => 'evening/', - 'evening_signature' => 'evening_signature/', - 'pickup' => 'pickup/', - 'mailbox' => 'mailbox/', - 'digital_stamp' => 'digital_stamp/', - ]; - - return $methods; - } - - /** - * Get allowed shipping methods - * - * @return array - */ - public function getAllowedMethods() - { - return self::getMethods(); - } - - /** - * @param \Magento\Quote\Model\Quote\Address\RateRequest $result - * @return mixed - */ - private function addShippingMethods($result) - { - $this->package->setDigitalStampSettings(); - $this->package->setMailboxSettings(); - - foreach ($this->getAllowedMethods() as $alias => $settingPath) { - $active = $this->myParcelHelper->getConfigValue(Data::XML_PATH_POSTNL_SETTINGS . $settingPath . 'active') === '1'; - if ($active) { - $method = $this->getShippingMethod($alias, $settingPath); - $result->append($method); - } - } - - return $result; - } - - /** - * @param $alias - * @param string $settingPath - * - * @return \Magento\Quote\Model\Quote\Address\RateResult\Method - */ - private function getShippingMethod($alias, string $settingPath) - { - $title = $this->createTitle($settingPath); - $price = $this->createPrice($alias, $settingPath); - - $method = $this->_rateMethodFactory->create(); - $method->setCarrier($this->_code); - $method->setCarrierTitle($alias); - $method->setMethod($alias); - $method->setMethodTitle($title); - $method->setPrice($price); - - return $method; - } - - /** - * Create title for method - * If no title isset in config, get title from translation - * - * @param $settingPath - * @return \Magento\Framework\Phrase|mixed - */ - private function createTitle($settingPath) - { - $title = $this->myParcelHelper->getConfigValue(Data::XML_PATH_POSTNL_SETTINGS . $settingPath . 'title'); - - if ($title === null) { - $title = __($settingPath . 'title'); - } - - return $title; - } - - /** - * Create price - * Calculate price if multiple options are chosen - * - * @param $alias - * @param $settingPath - * @return float - */ - private function createPrice($alias, $settingPath) - { - $price = 0; - - $price += $this->myParcelHelper->getMethodPrice($settingPath . 'fee', $alias); - - return $price; - } -} diff --git a/Model/Checkout/DeliveryOptionsToShippingMethods.php b/Model/Checkout/DeliveryOptionsToShippingMethods.php index a198b451..2812622e 100755 --- a/Model/Checkout/DeliveryOptionsToShippingMethods.php +++ b/Model/Checkout/DeliveryOptionsToShippingMethods.php @@ -5,13 +5,13 @@ namespace MyParcelNL\Magento\Model\Checkout; use Exception; -use MyParcelNL\Magento\Helper\Data; -use MyParcelNL\Sdk\src\Factory\DeliveryOptionsAdapterFactory; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Sdk\Factory\DeliveryOptionsAdapterFactory; class DeliveryOptionsToShippingMethods { /** - * @var \MyParcelNL\Sdk\src\Adapter\DeliveryOptions\AbstractDeliveryOptionsAdapter + * @var \MyParcelNL\Sdk\Adapter\DeliveryOptions\AbstractDeliveryOptionsAdapter */ private $deliveryOptions; @@ -31,6 +31,8 @@ public function __construct(array $deliveryOptions) { $this->deliveryOptions = DeliveryOptionsAdapterFactory::create($deliveryOptions); $this->createShippingMethod(); + file_put_contents('/Applications/MAMP/htdocs/magento246/var/log/joeri.log', "DeliveryOptionsToShippingMethods is called / constructed and probably not working\n", FILE_APPEND); + throw new \Exception('DeliveryOptionsToShippingMethods is called, this is not working probably'); } /** @@ -57,8 +59,8 @@ private function getCarrierXmlPath(): string { $carrier = $this->deliveryOptions->getCarrier(); - if (array_key_exists($carrier, Data::CARRIERS_XML_PATH_MAP)) { - return Data::CARRIERS_XML_PATH_MAP[$carrier]; + if (array_key_exists($carrier, Config::CARRIERS_XML_PATH_MAP)) { + return Config::CARRIERS_XML_PATH_MAP[$carrier]; } throw new Exception("No XML path found for carrier '{$carrier}'."); diff --git a/Model/Checkout/LayoutProcessorPlugin.php b/Model/Checkout/LayoutProcessorPlugin.php index 34f28c04..40aaefad 100755 --- a/Model/Checkout/LayoutProcessorPlugin.php +++ b/Model/Checkout/LayoutProcessorPlugin.php @@ -19,8 +19,8 @@ namespace MyParcelNL\Magento\Model\Checkout; use Magento\Checkout\Block\Checkout\LayoutProcessor; -use MyParcelNL\Magento\Helper\Checkout as CheckoutHelper; use MyParcelNL\Magento\Model\Quote\Checkout; +use MyParcelNL\Magento\Service\Config; class LayoutProcessorPlugin { @@ -49,7 +49,7 @@ public function afterProcess(LayoutProcessor $subject, array $jsLayout) { $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step'] ['children']['shippingAddress']['children']['before-shipping-method-form']['children'], [ - CheckoutHelper::FIELD_DELIVERY_OPTIONS => [ + Config::FIELD_DELIVERY_OPTIONS => [ 'component' => 'Magento_Ui/js/form/element/abstract', 'config' => [ 'customScope' => 'shippingAddress', @@ -58,7 +58,7 @@ public function afterProcess(LayoutProcessor $subject, array $jsLayout) { 'options' => [], 'id' => 'myparcel-delivery-options', ], - 'dataScope' => 'shippingAddress.' . CheckoutHelper::FIELD_DELIVERY_OPTIONS, + 'dataScope' => 'shippingAddress.' . Config::FIELD_DELIVERY_OPTIONS, 'label' => 'Delivery Options', 'provider' => 'checkoutProvider', 'visible' => false, diff --git a/Model/Checkout/ShippingMethods.php b/Model/Checkout/ShippingMethods.php index f07ecdf5..0517c7de 100755 --- a/Model/Checkout/ShippingMethods.php +++ b/Model/Checkout/ShippingMethods.php @@ -4,30 +4,36 @@ use Exception; use Magento\Checkout\Model\Session; +use Magento\Framework\App\ObjectManager; +use Magento\Quote\Model\QuoteRepository\SaveHandler; use MyParcelNL\Magento\Api\ShippingMethodsInterface; -use MyParcelNL\Sdk\src\Factory\DeliveryOptionsAdapterFactory; +use MyParcelNL\Magento\Model\Carrier\Carrier; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Sdk\Factory\DeliveryOptionsAdapterFactory; /** * @since 3.0.0 */ class ShippingMethods implements ShippingMethodsInterface { - /** - * @var \Magento\Checkout\Model\Session - */ - private $session; + private Session $session; + private Carrier $carrier; /** * ShippingMethods constructor. * - * @param \Magento\Checkout\Model\Session $session + * @param Session $session + * @param Carrier $carrier */ - public function __construct(Session $session) + public function __construct(Session $session, Carrier $carrier) { $this->session = $session; + $this->carrier = $carrier; } /** + * Defined in etc/webapi.xml + * * @param mixed $deliveryOptions indexed array holding 1 deliveryOptions object * * @return array[] @@ -35,47 +41,18 @@ public function __construct(Session $session) */ public function getFromDeliveryOptions($deliveryOptions): array { - if (! $deliveryOptions[0]) { + if (! isset($deliveryOptions[0]) || ! $deliveryOptions[0]) { return []; } - try { - $shipping = new DeliveryOptionsToShippingMethods($deliveryOptions[0]); - - $response = [ - 'root' => [ - 'element_id' => $shipping->getShippingMethod(), - ], - ]; - } catch (Exception $e) { - $response = [ - 'code' => '422', - 'message' => $e->getMessage(), - ]; - } - - $response[] = $this->persistDeliveryOptions($deliveryOptions[0]); - - return $response; - } - - /** - * @param array $deliveryOptions - * - * @return array - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ - public function persistDeliveryOptions(array $deliveryOptions): array - { + // save the delivery options in the quote + $adapted = DeliveryOptionsAdapterFactory::create($deliveryOptions[0]); $quote = $this->session->getQuote(); - $adapted = DeliveryOptionsAdapterFactory::create($deliveryOptions); - $quote->addData(['myparcel_delivery_options' => json_encode($adapted->toArray())]); - $quote->save(); + $quote->addData([Config::FIELD_DELIVERY_OPTIONS => json_encode($adapted->toArray(), JSON_THROW_ON_ERROR)]); + $saver = ObjectManager::getInstance()->get(SaveHandler::class); + $saver->save($quote); - return [ - 'delivery_options' => $deliveryOptions, - 'message' => "Delivery options persisted in quote {$quote->getId()}", - ]; + // return a fresh method from the carrier + return ['root' => $this->carrier->getMethodForFrontend($quote)]; } } diff --git a/Model/Quote/Checkout.php b/Model/Quote/Checkout.php index 7f184cde..d8967f9b 100644 --- a/Model/Quote/Checkout.php +++ b/Model/Quote/Checkout.php @@ -2,72 +2,60 @@ namespace MyParcelNL\Magento\Model\Quote; -use Magento\Checkout\Model\Cart; -use Magento\Checkout\Model\Session; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Quote\Model\Quote; use Magento\Store\Model\StoreManagerInterface; -use MyParcelNL\Magento\Helper\Data; +use MyParcelNL\Magento\Facade\Logger; +use MyParcelNL\Magento\Model\Carrier\Carrier; use MyParcelNL\Magento\Model\Sales\Repository\PackageRepository; use MyParcelNL\Magento\Model\Source\PriceDeliveryOptionsView; -use MyParcelNL\Sdk\src\Factory\ConsignmentFactory; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Magento\Service\DeliveryCosts; +use MyParcelNL\Magento\Service\NeedsQuoteProps; +use MyParcelNL\Magento\Service\Tax; +use MyParcelNL\Sdk\Factory\ConsignmentFactory; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; +use Throwable; class Checkout { - private const PLATFORM = 'myparcel'; - private const PACKAGE_TYPE_MAILBOX = 'mailbox'; + use NeedsQuoteProps; - /** - * @var \MyParcelNL\Magento\Helper\Checkout - */ - private $helper; - - /** - * @var \Magento\Quote\Model\Quote - */ - private $quoteId; - - /** - * @var PackageRepository - */ - private $package; + private Tax $tax; + private Config $config; + private DeliveryCosts $deliveryCosts; + private PackageRepository $package; + private Quote $quote; + private StoreManagerInterface $currency; /** - * @var \Magento\Eav\Model\Entity\Collection\AbstractCollection[] + * @var string */ - private $cart; - - /** - * @var \Magento\Store\Model\StoreManagerInterface - */ - private $currency; - - /** - * @var mixed - */ - private $country; + private string $country; /** * Checkout constructor. * - * @param \Magento\Checkout\Model\Session $session - * @param \Magento\Checkout\Model\Cart $cart - * @param \MyParcelNL\Magento\Helper\Checkout $helper - * @param PackageRepository $package - * @param \Magento\Store\Model\StoreManagerInterface $currency - * + * @param Config $config + * @param DeliveryCosts $deliveryCosts + * @param PackageRepository $package + * @param StoreManagerInterface $currency */ public function __construct( - Session $session, - Cart $cart, - \MyParcelNL\Magento\Helper\Checkout $helper, - PackageRepository $package, + Tax $tax, + Config $config, + DeliveryCosts $deliveryCosts, + PackageRepository $package, // TODO DEPRECATE / IMPROVE StoreManagerInterface $currency - ) { - $this->helper = $helper; - $this->quoteId = $session->getQuoteId(); - $this->cart = $cart->getQuote(); - $this->package = $package; - $this->currency = $currency; + ) + { + $this->tax = $tax; + $this->config = $config; + $this->deliveryCosts = $deliveryCosts; + $this->package = $package; + $this->currency = $currency; + $this->quote = $this->getQuoteFromCurrentSession(); } /** @@ -76,35 +64,32 @@ public function __construct( * @param array $forAddress associative array holding the latest address from the client * * @return array - * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws NoSuchEntityException|LocalizedException */ public function getDeliveryOptions(array $forAddress = []): array { - $this->helper->setBasePriceFromQuote((int) $this->quoteId, $forAddress); $this->hideDeliveryOptionsForProduct(); + $packageType = $this->getPackageType(); if (isset($forAddress['countryId'])) { $this->country = $forAddress['countryId']; } - $packageType = $this->getPackageType(); - $data = [ - /* the 'method' string here is actually the carrier_code of the method */ - 'methods' => explode(',', $this->helper->getGeneralConfig('shipping_methods/methods') ?? ''), - 'config' => array_merge( + 'carrierCode' => Carrier::CODE, + 'config' => array_merge( $this->getGeneralData(), $this->getDeliveryData($packageType), ['packageType' => $packageType] ), - 'strings' => $this->getDeliveryOptionsStrings(), - 'forAddress' => $forAddress, + 'strings' => $this->getDeliveryOptionsStrings(), + 'forAddress' => $forAddress, ]; return [ 'root' => [ - 'version' => (string) $this->helper->getVersion(), - 'data' => (array) $data, + 'version' => $this->config->getVersion(), + 'data' => $data, ], ]; } @@ -112,22 +97,22 @@ public function getDeliveryOptions(array $forAddress = []): array /** * Get general data * - * @return array) - * @throws \Magento\Framework\Exception\NoSuchEntityException + * @return array + * @throws NoSuchEntityException|LocalizedException */ private function getGeneralData() { return [ 'allowRetry' => true, - 'platform' => self::PLATFORM, + 'platform' => Config::PLATFORM, 'carriers' => $this->getActiveCarriers(), 'currency' => $this->currency->getStore()->getCurrentCurrency()->getCode(), - 'allowShowDeliveryDate' => $this->helper->getBoolConfig(Data::XML_PATH_GENERAL, 'date_settings/allow_show_delivery_date'), - 'deliveryDaysWindow' => $this->helper->getIntegerConfig(Data::XML_PATH_GENERAL, 'date_settings/deliverydays_window'), - 'dropOffDelay' => $this->getDropOffDelay(Data::XML_PATH_GENERAL, 'date_settings/dropoff_delay'), - 'pickupLocationsDefaultView' => $this->helper->getCarrierConfig('shipping_methods/pickup_locations_view', Data::XML_PATH_GENERAL), - 'showPriceSurcharge' => $this->helper->getCarrierConfig('shipping_methods/delivery_options_prices', Data::XML_PATH_GENERAL) === PriceDeliveryOptionsView::SURCHARGE, - 'basePrice' => $this->helper->getBasePrice(), + 'allowShowDeliveryDate' => $this->config->getBoolConfig(Config::XML_PATH_GENERAL, 'date_settings/allow_show_delivery_date'), + 'deliveryDaysWindow' => $this->config->getIntegerConfig(Config::XML_PATH_GENERAL, 'date_settings/deliverydays_window'), + 'dropOffDelay' => $this->getDropOffDelay(Config::XML_PATH_GENERAL, 'date_settings/dropoff_delay'), + 'pickupLocationsDefaultView' => $this->config->getConfigValue(Config::XML_PATH_GENERAL . 'shipping_methods/pickup_locations_view'), + 'showPriceSurcharge' => $this->config->getConfigValue(Config::XML_PATH_GENERAL . 'shipping_methods/delivery_options_prices') === PriceDeliveryOptionsView::SURCHARGE, + 'basePrice' => $this->deliveryCosts->getBasePriceForClient($this->quote), ]; } @@ -161,101 +146,111 @@ private function getPackageType(): string /** * Get delivery data * - * @param string|null $packageType + * @param string $packageType * @return array */ - private function getDeliveryData(?string $packageType = null): array + private function getDeliveryData(string $packageType): array { $myParcelConfig = []; $activeCarriers = $this->getActiveCarriers(); - $carrierPaths = Data::CARRIERS_XML_PATH_MAP; - $showTotalPrice = $this->helper->getCarrierConfig('shipping_methods/delivery_options_prices', Data::XML_PATH_GENERAL) === PriceDeliveryOptionsView::TOTAL; + $carrierPaths = Config::CARRIERS_XML_PATH_MAP; + $showTotalPrice = $this->config->getConfigValue(Config::XML_PATH_GENERAL . 'shipping_methods/delivery_options_prices') === PriceDeliveryOptionsView::TOTAL; - foreach ($activeCarriers as $carrier) { - $carrierPath = $carrierPaths[$carrier]; + $quote = $this->quote; + + foreach ($activeCarriers as $carrierName) { + $carrierPath = $carrierPaths[$carrierName]; + $basePrice = $this->deliveryCosts->getBasePriceForClient($quote, $carrierName, $packageType, $this->country); try { - $consignment = ConsignmentFactory::createByCarrierName($carrier); + $consignment = ConsignmentFactory::createByCarrierName($carrierName); $consignment->setPackageType(AbstractConsignment::PACKAGE_TYPE_PACKAGE); - } catch (\Throwable $ex) { - $this->helper->log(sprintf('getDeliveryData: Could not create default consignment for %s', $carrier)); + } catch (Throwable $ex) { + Logger::info(sprintf('getDeliveryData: Could not create default consignment for %s', $carrierName)); continue; } - $canHaveDigitalStamp = $consignment->canHavePackageType(AbstractConsignment::PACKAGE_TYPE_DIGITAL_STAMP_NAME); - $canHaveMailbox = $consignment->canHavePackageType(AbstractConsignment::PACKAGE_TYPE_MAILBOX_NAME); - $canHavePackageSmall = $consignment->canHavePackageType(AbstractConsignment::PACKAGE_TYPE_PACKAGE_SMALL_NAME); +// $canHaveDigitalStamp = $consignment->canHavePackageType(AbstractConsignment::PACKAGE_TYPE_DIGITAL_STAMP_NAME); +// $canHaveMailbox = $consignment->canHavePackageType(AbstractConsignment::PACKAGE_TYPE_MAILBOX_NAME); +// $canHavePackageSmall = $consignment->canHavePackageType(AbstractConsignment::PACKAGE_TYPE_PACKAGE_SMALL_NAME); $canHaveSameDay = $consignment->canHaveExtraOption(AbstractConsignment::SHIPMENT_OPTION_SAME_DAY_DELIVERY); $canHaveMonday = $consignment->canHaveExtraOption(AbstractConsignment::EXTRA_OPTION_DELIVERY_MONDAY); $canHaveMorning = $consignment->canHaveDeliveryType(AbstractConsignment::DELIVERY_TYPE_MORNING_NAME); $canHaveEvening = $consignment->canHaveDeliveryType(AbstractConsignment::DELIVERY_TYPE_EVENING_NAME); + $canHaveExpress = $consignment->canHaveDeliveryType(AbstractConsignment::DELIVERY_TYPE_EXPRESS_NAME); + $canHavePickup = $consignment->canHaveDeliveryType(AbstractConsignment::DELIVERY_TYPE_PICKUP_NAME); $canHaveSignature = $consignment->canHaveShipmentOption(AbstractConsignment::SHIPMENT_OPTION_SIGNATURE); + $canHaveCollect = $consignment->canHaveShipmentOption(AbstractConsignment::SHIPMENT_OPTION_COLLECT); + $canHaveReceiptCode = $consignment->canHaveShipmentOption(AbstractConsignment::SHIPMENT_OPTION_RECEIPT_CODE); $canHaveOnlyRecipient = $consignment->canHaveShipmentOption(AbstractConsignment::SHIPMENT_OPTION_ONLY_RECIPIENT); $canHaveAgeCheck = $consignment->canHaveShipmentOption(AbstractConsignment::SHIPMENT_OPTION_AGE_CHECK); - $canHavePickup = $consignment->canHaveDeliveryType(AbstractConsignment::DELIVERY_TYPE_PICKUP_NAME); - - $mailboxFee = 0; - if ($canHaveMailbox) { - $cc = $this->country ?? $this->cart->getShippingAddress()->getCountryId() ?? AbstractConsignment::CC_NL; - if (AbstractConsignment::CC_NL === $cc) { - $mailboxFee = $this->helper->getMethodPrice($carrierPath, 'mailbox/fee', false); - } else { - $mailboxFee = $this->helper->getMethodPrice($carrierPath, 'mailbox/international_fee', false); - } - } - $basePrice = $this->helper->getBasePrice(); - $mondayFee = $canHaveMonday ? $this->helper->getMethodPrice($carrierPath, 'delivery/monday_fee') : 0; - $morningFee = $canHaveMorning ? $this->helper->getMethodPrice($carrierPath, 'morning/fee') : 0; - $eveningFee = $canHaveEvening ? $this->helper->getMethodPrice($carrierPath, 'evening/fee') : 0; - $sameDayFee = $canHaveSameDay ? (int) $this->helper->getMethodPrice($carrierPath, 'delivery/same_day_delivery_fee') : 0; - $signatureFee = $canHaveSignature ? $this->helper->getMethodPrice($carrierPath, 'delivery/signature_fee', false) : 0; - $onlyRecipientFee = $canHaveOnlyRecipient ? $this->helper->getMethodPrice($carrierPath, 'delivery/only_recipient_fee', false) : 0; + $addBasePrice = ($showTotalPrice) ? $basePrice : 0; + $mondayFee = $canHaveMonday ? $this->tax->shippingPrice($this->config->getFloatConfig($carrierPath, 'delivery/monday_fee'), $quote) + $addBasePrice : 0; + $morningFee = $canHaveMorning ? $this->tax->shippingPrice($this->config->getFloatConfig($carrierPath, 'morning/fee'), $quote) + $addBasePrice : 0; + $eveningFee = $canHaveEvening ? $this->tax->shippingPrice($this->config->getFloatConfig($carrierPath, 'evening/fee'), $quote) + $addBasePrice : 0; + $sameDayFee = $canHaveSameDay ? $this->tax->shippingPrice($this->config->getFloatConfig($carrierPath, 'delivery/same_day_delivery_fee'), $quote) + $addBasePrice : 0; + $signatureFee = $canHaveSignature ? $this->tax->shippingPrice($this->config->getFloatConfig($carrierPath, 'delivery/signature_fee'), $quote) : 0; + $collectFee = $canHaveCollect ? $this->tax->shippingPrice($this->config->getFloatConfig($carrierPath, 'delivery/collect_fee'), $quote) : 0; + $receiptCodeFee = $canHaveReceiptCode ? $this->tax->shippingPrice($this->config->getFloatConfig($carrierPath, 'delivery/receipt_code_fee'), $quote) : 0; + $onlyRecipientFee = $canHaveOnlyRecipient ? $this->tax->shippingPrice($this->config->getFloatConfig($carrierPath, 'delivery/only_recipient_fee'), $quote) : 0; $isAgeCheckActive = $canHaveAgeCheck && $this->isAgeCheckActive($carrierPath); - $allowPickup = $this->helper->getBoolConfig($carrierPath, 'pickup/active'); - $allowStandardDelivery = $this->helper->getBoolConfig($carrierPath, 'delivery/active'); - $allowMorningDelivery = ! $isAgeCheckActive && $canHaveMorning && $this->helper->getBoolConfig($carrierPath, 'morning/active'); - $allowEveningDelivery = ! $isAgeCheckActive && $canHaveEvening && $this->helper->getBoolConfig($carrierPath, 'evening/active'); - $allowDeliveryOptions = ! $this->package->deliveryOptionsDisabled - && ($allowPickup || $allowStandardDelivery || $allowMorningDelivery || $allowEveningDelivery); + $allowPickup = $this->config->getBoolConfig($carrierPath, 'pickup/active'); + $allowStandardDelivery = $this->config->getBoolConfig($carrierPath, 'delivery/active'); + $allowMorningDelivery = !$isAgeCheckActive && $canHaveMorning && $this->config->getBoolConfig($carrierPath, 'morning/active'); + $allowEveningDelivery = !$isAgeCheckActive && $canHaveEvening && $this->config->getBoolConfig($carrierPath, 'evening/active'); + $allowExpressDelivery = $canHaveExpress && $this->config->getBoolConfig($carrierPath, 'express/active'); + $allowDeliveryOptions = !$this->package->deliveryOptionsDisabled + && ($allowPickup || $allowStandardDelivery || $allowMorningDelivery || $allowEveningDelivery); if ($allowDeliveryOptions && $packageType === AbstractConsignment::PACKAGE_TYPE_MAILBOX_NAME) { $this->package->setMailboxSettings($carrierPath); - $allowDeliveryOptions = $this->helper->getBoolConfig($carrierPath, 'mailbox/active') - && $this->package->getMaxMailboxWeight() >= $this->package->getWeight(); + $allowDeliveryOptions = $this->config->getBoolConfig($carrierPath, 'mailbox/active') + && $this->package->getMaxMailboxWeight() >= $this->package->getWeight(); } - $myParcelConfig['carrierSettings'][$carrier] = [ + $myParcelConfig['carrierSettings'][$carrierName] = [ 'allowDeliveryOptions' => $allowDeliveryOptions, 'allowStandardDelivery' => $allowStandardDelivery, - 'allowSignature' => $canHaveSignature && $this->helper->getBoolConfig($carrierPath, 'delivery/signature_active'), - 'allowOnlyRecipient' => $canHaveOnlyRecipient && $this->helper->getBoolConfig($carrierPath, 'delivery/only_recipient_active'), + 'allowSignature' => $canHaveSignature && $this->config->getBoolConfig($carrierPath, 'delivery/signature_active'), + 'allowCollect' => $canHaveCollect && $this->config->getBoolConfig($carrierPath, 'delivery/collect_active'), + 'allowReceiptCode' => $canHaveReceiptCode && $this->config->getBoolConfig($carrierPath, 'delivery/receipt_code_active'), + 'allowOnlyRecipient' => $canHaveOnlyRecipient && $this->config->getBoolConfig($carrierPath, 'delivery/only_recipient_active'), 'allowMorningDelivery' => $allowMorningDelivery, 'allowEveningDelivery' => $allowEveningDelivery, 'allowPickupLocations' => $canHavePickup && $this->isPickupAllowed($carrierPath), - 'allowMondayDelivery' => $canHaveMonday && $this->helper->getBoolConfig($carrierPath, 'delivery/monday_active'), - 'allowSameDayDelivery' => $canHaveSameDay && $this->helper->getBoolConfig($carrierPath, 'delivery/same_day_delivery_active'), + 'allowMondayDelivery' => $canHaveMonday && $this->config->getBoolConfig($carrierPath, 'delivery/monday_active'), + 'allowSameDayDelivery' => $canHaveSameDay && $this->config->getBoolConfig($carrierPath, 'delivery/same_day_delivery_active'), + 'allowExpressDelivery' => $allowExpressDelivery, - 'dropOffDays' => $this->getDropOffDays($carrierPath), + 'dropOffDays' => $this->getDropOffDays($carrierPath), 'priceSignature' => $signatureFee, + 'priceCollect' => $collectFee, + 'priceReceiptCode' => $receiptCodeFee, 'priceOnlyRecipient' => $onlyRecipientFee, - 'priceStandardDelivery' => $showTotalPrice ? $basePrice : 0, + 'priceStandardDelivery' => $addBasePrice, 'priceMondayDelivery' => $mondayFee, 'priceMorningDelivery' => $morningFee, 'priceEveningDelivery' => $eveningFee, 'priceSameDayDelivery' => $sameDayFee, + 'priceExpressdelivery' => $allowExpressDelivery ? $this->config->getFloatConfig($carrierPath, 'express/fee') : 0, 'priceSameDayDeliveryAndOnlyRecipient' => $sameDayFee + $onlyRecipientFee, 'priceMorningSignature' => ($morningFee + $signatureFee), 'priceEveningSignature' => ($eveningFee + $signatureFee), 'priceSignatureAndOnlyRecipient' => ($basePrice + $signatureFee + $onlyRecipientFee), - 'pricePickup' => $canHavePickup ? $this->helper->getMethodPrice($carrierPath, 'pickup/fee') : 0, - 'pricePackageTypeMailbox' => $mailboxFee, - 'pricePackageTypeDigitalStamp' => $canHaveDigitalStamp ? $this->helper->getMethodPrice($carrierPath, 'digital_stamp/fee', false) : 0, - 'pricePackageTypePackageSmall' => $canHavePackageSmall ? $this->helper->getMethodPrice($carrierPath, 'package_small/fee', false) : 0, + 'pricePickup' => max(0, $canHavePickup ? $this->config->getFloatConfig($carrierPath, 'pickup/fee') + $basePrice : 0), + // because of how the delivery options work, we need to put the correctly calculated price in separate keys: + 'pricePackageTypeMailbox' => $basePrice, + 'pricePackageTypeDigitalStamp' => $basePrice, + 'pricePackageTypePackageSmall' => $basePrice, + // if you want separate package type prices, get them with this: $this->deliveryCosts->getBasePrice($this->quote, $carrierName, $packageType, $this->country); + // 'pricePackageTypeMailbox' => $mailboxFee, + // 'pricePackageTypeDigitalStamp' => $canHaveDigitalStamp ? $this->config->getFloatConfig($carrierPath, 'digital_stamp/fee') : 0, + // 'pricePackageTypePackageSmall' => $canHavePackageSmall ? $this->config->getFloatConfig($carrierPath, 'package_small/fee') : 0, ]; } @@ -270,9 +265,9 @@ private function getDeliveryData(?string $packageType = null): array public function getActiveCarriers(): array { $carriers = []; - foreach (Data::CARRIERS_XML_PATH_MAP as $carrier => $path) { - if ($this->helper->getBoolConfig($path, 'delivery/active') || - $this->helper->getBoolConfig($path, 'pickup/active') + foreach (Config::CARRIERS_XML_PATH_MAP as $carrier => $path) { + if ($this->config->getBoolConfig($path, 'delivery/active') || + $this->config->getBoolConfig($path, 'pickup/active') ) { $carriers[] = $carrier; } @@ -281,16 +276,20 @@ public function getActiveCarriers(): array return $carriers; } - private function getDropOffDays(string $carrierPath): array { + private function getDropOffDays(string $carrierPath): array + { $dropOffDays = []; for ($weekday = 0; $weekday < 7; $weekday++) { - $cutoffTimeSameDay = $this->helper->getTimeConfig($carrierPath, "drop_off_days/cutoff_time_same_day_$weekday"); - $sameDayTimeEntry = $cutoffTimeSameDay ? ['cutoffTimeSameDay' => $cutoffTimeSameDay] : []; - if ($this->helper->getBoolConfig($carrierPath, "drop_off_days/day_{$weekday}_active")) { - $dropOffDays[] = (object) array_merge([ - 'weekday' => $weekday, - 'cutoffTime' => $this->helper->getTimeConfig($carrierPath, "drop_off_days/cutoff_time_$weekday"), - ], $sameDayTimeEntry); + $cutoffTimeSameDay = $this->config->getTimeConfig($carrierPath, "drop_off_days/cutoff_time_same_day_$weekday"); + $sameDayTimeEntry = $cutoffTimeSameDay ? ['cutoffTimeSameDay' => $cutoffTimeSameDay] : []; + if ($this->config->getBoolConfig($carrierPath, "drop_off_days/day_{$weekday}_active")) { + $dropOffDays[] = (object) array_merge( + [ + 'weekday' => $weekday, + 'cutoffTime' => $this->config->getTimeConfig($carrierPath, "drop_off_days/cutoff_time_$weekday"), + ], + $sameDayTimeEntry + ); } } @@ -305,22 +304,22 @@ private function getDropOffDays(string $carrierPath): array { private function getDeliveryOptionsStrings(): array { return [ - 'deliveryTitle' => $this->helper->getGeneralConfig('delivery_titles/delivery_title') ?: __('delivery_title'), - 'deliveryStandardTitle' => $this->helper->getGeneralConfig('delivery_titles/standard_delivery_title') ?: __('standard_delivery'), - 'deliveryMorningTitle' => $this->helper->getGeneralConfig('delivery_titles/morning_title') ?: __('morning_title'), - 'deliveryEveningTitle' => $this->helper->getGeneralConfig('delivery_titles/evening_title') ?: __('evening_title'), - 'deliveryPickupTitle' => $this->helper->getGeneralConfig('delivery_titles/pickup_title') ?: __('pickup_title'), - 'pickupTitle' => $this->helper->getGeneralConfig('delivery_titles/pickup_title') ?: __('pickup_title'), - 'deliverySameDayTitle' => $this->helper->getGeneralConfig('delivery_titles/same_day_title') ?: __('same_day_title'), - 'hideSenderTitle' => $this->helper->getGeneralConfig('delivery_titles/hide_sender_title') ?: __('hide_sender_title'), - 'list' => $this->helper->getGeneralConfig('delivery_titles/pickup_list_button_title') ?: __('list_title'), - 'map' => $this->helper->getGeneralConfig('delivery_titles/pickup_map_button_title') ?: __('map_title'), - 'packageTypeMailbox' => $this->helper->getGeneralConfig('delivery_titles/mailbox_title') ?: __('mailbox_title'), - 'packageTypeDigitalStamp' => $this->helper->getGeneralConfig('delivery_titles/digital_stamp_title') ?: __('digital_stamp_title'), - 'packageTypePackageSmall' => $this->helper->getGeneralConfig('delivery_titles/package_small_title') ?: __('packet_title'), - 'signatureTitle' => $this->helper->getGeneralConfig('delivery_titles/signature_title') ?: __('signature_title'), - 'onlyRecipientTitle' => $this->helper->getGeneralConfig('delivery_titles/only_recipient_title') ?: __('only_recipient_title'), - 'saturdayDeliveryTitle' => $this->helper->getGeneralConfig('delivery_titles/saturday_title') ?: __('saturday_delivery_title'), + 'deliveryTitle' => $this->config->getGeneralConfig('delivery_titles/delivery_title') ?: __('delivery_title'), + 'deliveryStandardTitle' => $this->config->getGeneralConfig('delivery_titles/standard_delivery_title') ?: __('standard_delivery'), + 'deliveryMorningTitle' => $this->config->getGeneralConfig('delivery_titles/morning_title') ?: __('morning_title'), + 'deliveryEveningTitle' => $this->config->getGeneralConfig('delivery_titles/evening_title') ?: __('evening_title'), + 'deliveryPickupTitle' => $this->config->getGeneralConfig('delivery_titles/pickup_title') ?: __('pickup_title'), + 'pickupTitle' => $this->config->getGeneralConfig('delivery_titles/pickup_title') ?: __('pickup_title'), + 'deliverySameDayTitle' => $this->config->getGeneralConfig('delivery_titles/same_day_title') ?: __('same_day_title'), + 'hideSenderTitle' => $this->config->getGeneralConfig('delivery_titles/hide_sender_title') ?: __('hide_sender_title'), + 'list' => $this->config->getGeneralConfig('delivery_titles/pickup_list_button_title') ?: __('list_title'), + 'map' => $this->config->getGeneralConfig('delivery_titles/pickup_map_button_title') ?: __('map_title'), + 'packageTypeMailbox' => $this->config->getGeneralConfig('delivery_titles/mailbox_title') ?: __('mailbox_title'), + 'packageTypeDigitalStamp' => $this->config->getGeneralConfig('delivery_titles/digital_stamp_title') ?: __('digital_stamp_title'), + 'packageTypePackageSmall' => $this->config->getGeneralConfig('delivery_titles/package_small_title') ?: __('packet_title'), + 'signatureTitle' => $this->config->getGeneralConfig('delivery_titles/signature_title') ?: __('signature_title'), + 'onlyRecipientTitle' => $this->config->getGeneralConfig('delivery_titles/only_recipient_title') ?: __('only_recipient_title'), + 'saturdayDeliveryTitle' => $this->config->getGeneralConfig('delivery_titles/saturday_title') ?: __('saturday_delivery_title'), 'wrongPostalCodeCity' => __('Postcode/city combination unknown'), 'addressNotFound' => __('Address details are not entered'), @@ -336,17 +335,17 @@ private function getDeliveryOptionsStrings(): array 'showMoreHours' => __('Show more opening hours'), 'showMoreLocations' => __('Show more locations'), - 'error3212' => __('{field} is required.'), - 'error3501' => __('Address not found.'), - 'error3505' => __('Postal code is invalid for the current country.'), - - 'cityText' => __('City'), - 'city' => __('City'), - 'cc' => __('Country'), - 'houseNumber' => __('House number'), - 'numberText' => __('House number'), - 'postalCode' => __('Postal code'), - 'street' => __('Street'), + 'error3212' => __('{field} is required.'), + 'error3501' => __('Address not found.'), + 'error3505' => __('Postal code is invalid for the current country.'), + + 'cityText' => __('City'), + 'city' => __('City'), + 'cc' => __('Country'), + 'houseNumber' => __('House number'), + 'numberText' => __('House number'), + 'postalCode' => __('Postal code'), + 'street' => __('Street'), ]; } @@ -360,15 +359,15 @@ public function checkPackageType(string $carrier, ?string $country = null): stri { try { $consignment = ConsignmentFactory::createByCarrierName($carrier); - } catch (\Throwable $e) { - $this->helper->log(sprintf('checkPackageType: Could not create default consignment for %s', $carrier)); + } catch (Throwable $e) { + Logger::critical(sprintf('checkPackageType: Could not create default consignment for %s', $carrier)); return AbstractConsignment::DEFAULT_PACKAGE_TYPE_NAME; } - $carrierPath = Data::CARRIERS_XML_PATH_MAP[$carrier]; - $products = $this->cart->getAllItems(); - $country = $country ?? $this->country ?? $this->cart->getShippingAddress()->getCountryId(); + $carrierPath = Config::CARRIERS_XML_PATH_MAP[$carrier]; + $products = $this->quote->getAllItems(); + $country = $country ?? $this->country ?? $this->quote->getShippingAddress()->getCountryId(); $canHaveDigitalStamp = $consignment->canHavePackageType(AbstractConsignment::PACKAGE_TYPE_DIGITAL_STAMP_NAME); $canHaveMailbox = $consignment->canHavePackageType(AbstractConsignment::PACKAGE_TYPE_MAILBOX_NAME); $canHavePackageSmall = $consignment->canHavePackageType(AbstractConsignment::PACKAGE_TYPE_PACKAGE_SMALL_NAME); @@ -379,17 +378,17 @@ public function checkPackageType(string $carrier, ?string $country = null): stri if ($canHaveMailbox) { if (AbstractConsignment::CC_NL === $country) { - $this->package->setMailboxActive($this->helper->getBoolConfig($carrierPath, 'mailbox/active')); + $this->package->setMailboxActive($this->config->getBoolConfig($carrierPath, 'mailbox/active')); } else { - $this->package->setMailboxActive($this->helper->getBoolConfig($carrierPath, 'mailbox/international_active')); + $this->package->setMailboxActive($this->config->getBoolConfig($carrierPath, 'mailbox/international_active')); } } else { $this->package->setMailboxActive(false); } $this->package->setCurrentCountry($country); - $this->package->setDigitalStampActive($canHaveDigitalStamp && $this->helper->getBoolConfig($carrierPath, 'digital_stamp/active')); - $this->package->setPackageSmallActive($canHavePackageSmall && $this->helper->getBoolConfig($carrierPath, 'package_small/active')); + $this->package->setDigitalStampActive($canHaveDigitalStamp && $this->config->getBoolConfig($carrierPath, 'digital_stamp/active')); + $this->package->setPackageSmallActive($canHavePackageSmall && $this->config->getBoolConfig($carrierPath, 'package_small/active')); return $this->package->selectPackageType($products, $carrierPath); } @@ -401,7 +400,7 @@ public function checkPackageType(string $carrier, ?string $country = null): stri */ public function isAgeCheckActive(string $carrierPath): bool { - $products = $this->cart->getAllItems(); + $products = $this->quote->getAllItems(); return $this->package->getAgeCheck($products, $carrierPath); } @@ -414,39 +413,34 @@ public function isAgeCheckActive(string $carrierPath): bool */ public function getDropOffDelay(string $carrierPath, string $key): int { - $products = $this->cart->getAllItems(); - $productDelay = $this->package->getProductDropOffDelay($products); - - if (! $productDelay) { - $productDelay = $this->helper->getIntegerConfig($carrierPath, $key); - } + $products = $this->quote->getAllItems(); + $productDelay = (int) $this->package->getProductDropOffDelay($products); + $configDelay = $this->config->getIntegerConfig($carrierPath, $key); - return (int) $productDelay; + return max($productDelay, $configDelay); } /** - * @return $this + * @return self */ public function hideDeliveryOptionsForProduct() { - $products = $this->cart->getAllItems(); + $products = $this->quote->getAllItems(); $this->package->productWithoutDeliveryOptions($products); return $this; } /** - * @param string $carrier + * @param string $carrier * * @return bool */ private function isPickupAllowed(string $carrier): bool { - $isMailboxPackage = self::PACKAGE_TYPE_MAILBOX === $this->getPackageType(); - $pickupEnabled = $this->helper->getBoolConfig($carrier, 'pickup/active'); - $showPickupForMailbox = $this->helper->getBoolConfig($carrier, 'mailbox/pickup_mailbox'); - $showPickup = ! $isMailboxPackage || $showPickupForMailbox; + $pickupEnabled = AbstractConsignment::PACKAGE_TYPE_PACKAGE_NAME === $this->getPackageType() + && $this->config->getBoolConfig($carrier, 'pickup/active'); - return ! $this->package->deliveryOptionsDisabled && $pickupEnabled && $showPickup; + return !$this->package->deliveryOptionsDisabled && $pickupEnabled; } } diff --git a/Model/Quote/SaveOrderBeforeSalesModelQuoteObserver.php b/Model/Quote/SaveOrderBeforeSalesModelQuoteObserver.php index 57403d17..a0ba0135 100644 --- a/Model/Quote/SaveOrderBeforeSalesModelQuoteObserver.php +++ b/Model/Quote/SaveOrderBeforeSalesModelQuoteObserver.php @@ -24,12 +24,13 @@ use Magento\Framework\Event\ObserverInterface; use Magento\Quote\Model\Quote; use Magento\Sales\Model\Order; -use MyParcelNL\Magento\Helper\Checkout; -use MyParcelNL\Magento\Model\Checkout\Carrier; +use MyParcelNL\Magento\Model\Carrier\Carrier; use MyParcelNL\Magento\Model\Sales\Repository\DeliveryRepository; -use MyParcelNL\Sdk\src\Helper\ValidatePostalCode; -use MyParcelNL\Sdk\src\Helper\ValidateStreet; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Sdk\Helper\ValidatePostalCode; +use MyParcelNL\Sdk\Helper\ValidateStreet; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; +use MyParcelNL\Sdk\Support\Str; class SaveOrderBeforeSalesModelQuoteObserver implements ObserverInterface { @@ -46,15 +47,16 @@ class SaveOrderBeforeSalesModelQuoteObserver implements ObserverInterface /** * SaveOrderBeforeSalesModelQuoteObserver constructor. * - * @param DeliveryRepository $delivery - * @param Checkout $checkoutHelper + * @param DeliveryRepository $delivery + * @param Config $configService */ public function __construct( DeliveryRepository $delivery, - Checkout $checkoutHelper - ) { + Config $configService + ) + { $this->delivery = $delivery; - $this->parentMethods = explode(',', $checkoutHelper->getGeneralConfig('shipping_methods/methods') ?? ''); + $this->parentMethods = explode(',', $configService->getGeneralConfig('shipping_methods/methods') ?? ''); } /** @@ -79,66 +81,43 @@ public function execute(Observer $observer) $postcode = $order->getShippingAddress()->getPostcode(); $destinationCountry = $order->getShippingAddress()->getCountryId(); - if (! ValidateStreet::validate($fullStreet, AbstractConsignment::CC_NL, $destinationCountry)) { - $order->setData(Checkout::FIELD_TRACK_STATUS, __('⚠️  Please check street')); + if (!ValidateStreet::validate($fullStreet, AbstractConsignment::CC_NL, $destinationCountry)) { + $order->setData(Config::FIELD_TRACK_STATUS, __('⚠️  Please check street')); } - if (! ValidatePostalCode::validate($postcode, $destinationCountry)) { - $order->setData(Checkout::FIELD_TRACK_STATUS, __('⚠️  Please check postal code')); + if (!ValidatePostalCode::validate($postcode, $destinationCountry)) { + $order->setData(Config::FIELD_TRACK_STATUS, __('⚠️  Please check postal code')); } - if ($quote->hasData(Checkout::FIELD_DELIVERY_OPTIONS) && $this->hasMyParcelDeliveryOptions($quote)) { - $jsonDeliveryOptions = $quote->getData(Checkout::FIELD_DELIVERY_OPTIONS) ?? ''; + if ($quote->hasData(Config::FIELD_DELIVERY_OPTIONS) && $this->hasMyParcelDeliveryOptions($quote)) { + $jsonDeliveryOptions = $quote->getData(Config::FIELD_DELIVERY_OPTIONS) ?? ''; $deliveryOptions = json_decode($jsonDeliveryOptions, true) ?? []; - $order->setData(Checkout::FIELD_DELIVERY_OPTIONS, $jsonDeliveryOptions); + $order->setData(Config::FIELD_DELIVERY_OPTIONS, $jsonDeliveryOptions); $dropOffDay = $this->delivery->getDropOffDayFromDeliveryOptions($deliveryOptions); - $order->setData(Checkout::FIELD_DROP_OFF_DAY, $dropOffDay); + $order->setData(Config::FIELD_DROP_OFF_DAY, $dropOffDay); $selectedCarrier = $this->delivery->getCarrierFromDeliveryOptions($deliveryOptions); - $order->setData(Checkout::FIELD_MYPARCEL_CARRIER, $selectedCarrier); + $order->setData(Config::FIELD_MYPARCEL_CARRIER, $selectedCarrier); } return $this; } /** - * @param Quote $quote + * @param Quote $quote * * @return bool */ private function hasMyParcelDeliveryOptions(Quote $quote): bool { - $myParcelMethods = array_keys(Carrier::getMethods()); - $shippingMethod = $quote->getShippingAddress()->getShippingMethod(); - - if ($this->isMyParcelRelated($shippingMethod, $myParcelMethods)) { - return true; - } + $shippingMethod = $quote->getShippingAddress()->getShippingMethod(); - if ($this->isMyParcelRelated($shippingMethod, $this->parentMethods)) { + if (Str::startswith($shippingMethod, Carrier::CODE)) { return true; } - return array_key_exists('myparcel_delivery_options', $quote->getData()); - } - - /** - * @param string $input - * @param array $data - * - * @return bool - */ - private function isMyParcelRelated(string $input, array $data): bool - { - $result = array_filter( - $data, - static function ($item) use ($input) { - return stripos($input, $item) !== false; - } - ); - - return count($result) > 0; + return array_key_exists(Config::FIELD_DELIVERY_OPTIONS, $quote->getData()); } } diff --git a/Model/Rate/Result.php b/Model/Rate/Result.php deleted file mode 100755 index 12562455..00000000 --- a/Model/Rate/Result.php +++ /dev/null @@ -1,435 +0,0 @@ - - * @license http://creativecommons.org/licenses/by-nc-nd/3.0/nl/deed.en_US CC BY-NC-ND 3.0 NL - * @link https://github.com/myparcelnl/magento - * @copyright 2010-2019 MyParcel - * @since File available since Release 2.0.0 - */ - -namespace MyParcelNL\Magento\Model\Rate; - -use Countable; -use Magento\Checkout\Model\Session; -use Magento\Quote\Model\Quote\Address\RateResult\Method; -use MyParcelNL\Magento\Helper\Checkout; -use MyParcelNL\Magento\Helper\Data; -use MyParcelNL\Magento\Model\Sales\Repository\PackageRepository; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierDHLForYou; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierDPD; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierPostNL; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; - -class Result extends \Magento\Shipping\Model\Rate\Result -{ - private const FIRST_PART = 0; - private const SECOND_PART = 1; - private const THIRD_PART = 2; - private const FOURTH_PART = 3; - private const CARRIERS_WITH_MAILBOX = [ - CarrierPostNL::NAME, - CarrierDHLForYou::NAME, - CarrierDPD::NAME, - ]; - public const CARRIERS_WITH_DIGITAL_STAMP = [ - CarrierPostNL::NAME, - ]; - - /** - * @var Checkout - */ - private $myParcelHelper; - - /** - * @var \MyParcelNL\Magento\Model\Sales\Repository\PackageRepository - */ - private $package; - - /** - * @var array - */ - private $parentMethods; - - /** - * @var Session - */ - private $session; - - /** - * @var \Magento\Backend\Model\Session\Quote - */ - private $quote; - - /** - * Result constructor. - * - * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Backend\Model\Session\Quote $quote - * @param Session $session - * @param Checkout $myParcelHelper - * @param PackageRepository $package - * - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Magento\Framework\Exception\NoSuchEntityException - * @internal param \Magento\Checkout\Model\Session $session - */ - public function __construct( - \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Backend\Model\Session\Quote $quote, - Session $session, - Checkout $myParcelHelper, - PackageRepository $package - ) { - parent::__construct($storeManager); - - $this->myParcelHelper = $myParcelHelper; - $this->session = $session; - $this->quote = $quote; - $this->parentMethods = explode(',', $this->myParcelHelper->getGeneralConfig('shipping_methods/methods') ?? ''); - $package->setCurrentCountry( - $this->getQuoteFromCartOrSession() - ->getShippingAddress() - ->getCountryId() - ); - $this->package = $package; - } - - /** - * Add a rate to the result - * - * @param \Magento\Quote\Model\Quote\Address\RateResult\AbstractResult|\Magento\Shipping\Model\Rate\Result $result - * - * @return $this - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ - public function append($result) - { - if ($result instanceof \Magento\Quote\Model\Quote\Address\RateResult\Error) { - $this->setError(true); - } - if ($result instanceof \Magento\Quote\Model\Quote\Address\RateResult\Method) { - $this->_rates[] = $result; - $this->addMyParcelRates($result); - } elseif ($result instanceof \Magento\Quote\Model\Quote\Address\RateResult\AbstractResult) { - $this->_rates[] = $result; - } elseif ($result instanceof \Magento\Shipping\Model\Rate\Result) { - $rates = $result->getAllRates(); - foreach ($rates as $rate) { - $this->append($rate); - $this->addMyParcelRates($rate); - } - } - - return $this; - } - - /** - * Get allowed shipping methods - * - * @return array - */ - public static function getMethods(): array - { - return [ - 'pickup' => 'pickup', - 'standard' => 'delivery', - 'standard_signature' => 'delivery/signature', - 'standard_only_recipient' => 'delivery/only_recipient', - 'standard_only_recipient_signature' => 'delivery/only_recipient/signature', - 'morning' => 'morning', - 'morning_only_recipient' => 'morning/only_recipient', - 'morning_only_recipient_signature' => 'morning/only_recipient/signature', - 'evening' => 'evening', - 'evening_only_recipient' => 'evening/only_recipient', - 'evening_only_recipient_signature' => 'evening/only_recipient/signature', - 'mailbox' => 'mailbox', - 'digital_stamp' => 'digital_stamp', - 'same_day_delivery' => 'delivery/same_day_delivery', - 'same_day_delivery_only_recipient' => 'delivery/only_recipient/same_day_delivery', - ]; - } - - /** - * Add MyParcel shipping rates - * - * @param \Magento\Quote\Model\Quote\Address\RateResult\Method $parentRate - * - * @return void - * @throws \Magento\Framework\Exception\NoSuchEntityException - * @throws \Magento\Framework\Exception\LocalizedException - */ - private function addMyParcelRates(Method $parentRate): void - { - $parentShippingMethod = $parentRate->getData('carrier'); - if (! in_array($parentShippingMethod, $this->parentMethods, true)) { - return; - } - - foreach (Data::CARRIERS_XML_PATH_MAP as $carrier => $carrierPath) { - if (! $this->myParcelHelper->getConfigValue("{$carrierPath}delivery/active")) { - continue; - } - - if (in_array($carrier, self::CARRIERS_WITH_MAILBOX)) { - $this->package->setMailboxSettings($carrierPath); - } - - if (in_array($carrier, self::CARRIERS_WITH_DIGITAL_STAMP)) { - $this->package->setDigitalStampSettings($carrierPath); - } - - $packageType = $this->package->selectPackageType( - $this->getQuoteFromCartOrSession()->getAllItems(), - $carrierPath - ); - - foreach (self::getMethods() as $settingPath) { - $fullPath = $this->getFullSettingPath($carrierPath, $settingPath); - $separator = $this->isBaseSetting($settingPath) ? '/' : '_'; - $pathParts = explode('/', $settingPath ?? ''); - - if (! $fullPath - || ! $this->isRelevantOption($packageType, $pathParts[0]) - || ! $this->isSettingActive($carrierPath, $settingPath, $separator) - ) { - continue; - } - - $this->_rates[] = $this->getShippingMethod( - $fullPath, - $parentRate - ); - } - } - } - - /** - * @param string $packageType - * @param string $fromOptionPath - * - * @return bool - */ - private function isRelevantOption(string $packageType, string $fromOptionPath): bool - { - switch ($packageType) { - - case AbstractConsignment::PACKAGE_TYPE_LETTER_NAME: - return false; - - case AbstractConsignment::PACKAGE_TYPE_DIGITAL_STAMP_NAME: - return AbstractConsignment::PACKAGE_TYPE_DIGITAL_STAMP_NAME === $fromOptionPath; - - case AbstractConsignment::PACKAGE_TYPE_MAILBOX_NAME: - if (AbstractConsignment::DELIVERY_TYPE_PICKUP_NAME === $fromOptionPath) { - return $this->package->isPickupMailboxActive(); - } - return AbstractConsignment::PACKAGE_TYPE_MAILBOX_NAME === $fromOptionPath; - - default: - return ! in_array($fromOptionPath, - [ - AbstractConsignment::PACKAGE_TYPE_MAILBOX_NAME, - AbstractConsignment::PACKAGE_TYPE_DIGITAL_STAMP_NAME, - ] - ); - } - } - - /** - * Check if a given map/setting combination is active. If the setting is not a top level setting its parent group - * will be checked for an "active" setting. If this is disabled this will return false; - * - * @param string $map - * @param string $settingPath - * @param string $separator - * - * @return bool - */ - private function isSettingActive(string $map, string $settingPath, string $separator): bool - { - $settingPathParts = explode("/", $settingPath ?? ''); - $baseSetting = $settingPathParts[0]; - - if (! $this->myParcelHelper->getConfigValue("{$map}{$baseSetting}/active")) { - return false; - } - - foreach ($settingPathParts as $index => $option) { - if (0 === $index) { - continue; - } - $fullPath = "{$map}delivery/{$option}{$separator}active"; - if (! $this->myParcelHelper->getConfigValue($fullPath)) { - return false; - } - } - - return true; - } - - /** - * @param string $map - * @param string $settingPath - * - * @return string|null - */ - private function getFullSettingPath(string $map, string $settingPath): ?string - { - $separator = $this->isBaseSetting($settingPath) ? '/' : '_'; - $settingActive = $this->isSettingActive($map, $settingPath, $separator); - - if ($settingActive) { - return $map . $settingPath . $separator; - } - - return null; - } - - /** - * @param string $settingPath - * - * @return bool - */ - private function isBaseSetting(string $settingPath): bool - { - return strpos($settingPath, '/') === false; - } - - /** - * @param string|null $settingPath - * @param Method|null $parentRate - * - * @return Method - */ - private function getShippingMethod(string $settingPath, Method $parentRate): Method - { - $method = clone $parentRate; - $this->myParcelHelper->setBasePrice($parentRate->getData('price')); - - $title = $this->createTitle($settingPath); - $price = $this->getPrice($settingPath); - - $method->setData('cost', 0); - // Trim the separator off the end of the settings path - $method->setData('method', substr($settingPath, 0, -1)); - $method->setData('method_title', $title); - $method->setPrice($price); - - return $method; - } - - /** - * Create title for method - * If no title isset in config, get title from translation - * - * @param $settingPath - * - * @return \Magento\Framework\Phrase|mixed - */ - private function createTitle($settingPath) - { - return __(substr($settingPath, 0, -1)); - } - - /** - * Create price - * Calculate price if multiple options are chosen - * - * @param $settingPath - * - * @return float - * @todo: Several improvements are possible within this method - */ - private function getPrice($settingPath): float - { - $basePrice = $this->myParcelHelper->getBasePrice(); - $settingFee = 0; - - // Explode settingPath like: myparcelnl_magento_postnl_settings/delivery/only_recipient/signature - $settingPath = explode('/', $settingPath ?? ''); - - // Check if the selected delivery options are delivery, only_recipient and signature - // delivery/only_recipient/signature - if (isset($settingPath[self::THIRD_PART], $settingPath[self::FOURTH_PART]) && 'delivery' === $settingPath[self::SECOND_PART]) { - $settingFee += (float) $this->myParcelHelper->getConfigValue( - sprintf( - "%s/%s/%s_fee", - $settingPath[self::FIRST_PART], - $settingPath[self::SECOND_PART], - $settingPath[self::THIRD_PART] - ) - ); - $settingFee += (float) $this->myParcelHelper->getConfigValue( - sprintf( - "%s/%s/%sfee", - $settingPath[self::FIRST_PART], - $settingPath[self::SECOND_PART], - $settingPath[self::FOURTH_PART] - ) - ); - } - - // Check if the selected delivery is morning or evening and select the fee - if (AbstractConsignment::DELIVERY_TYPE_MORNING_NAME === $settingPath[self::SECOND_PART] || AbstractConsignment::DELIVERY_TYPE_EVENING_NAME === $settingPath[self::SECOND_PART]) { - $settingFee = (float) $this->myParcelHelper->getConfigValue( - sprintf("%s/%s/fee", $settingPath[self::FIRST_PART], $settingPath[self::SECOND_PART]) - ); - - // change delivery type if there is a signature selected - if (isset($settingPath[self::FOURTH_PART])) { - $settingPath[self::SECOND_PART] = 'delivery'; - } - // Unset only_recipient to select the correct price - unset($settingPath[self::THIRD_PART]); - } - - $settingFee += (float) $this->myParcelHelper->getConfigValue(implode('/', $settingPath ?? []) . 'fee'); - - // For mailbox and digital stamp the base price should not be calculated - if (AbstractConsignment::PACKAGE_TYPE_MAILBOX_NAME === $settingPath[self::SECOND_PART]) { - // for international mailbox, we have a different price :-) - $cc = $this->session->getQuote()->getShippingAddress()->getCountryId(); - if ($cc !== 'NL') { - $settingFee = (float) $this->myParcelHelper->getConfigValue( - sprintf("%s/%s/international_fee", $settingPath[self::FIRST_PART], $settingPath[self::SECOND_PART]) - ); - } - return min($settingFee, $basePrice); - } - if (AbstractConsignment::PACKAGE_TYPE_DIGITAL_STAMP_NAME === $settingPath[self::SECOND_PART]){ - return min($settingFee, $basePrice); - } - - return $basePrice + $settingFee; - } - - /** - * Can't get quote from session\Magento\Checkout\Model\Session::getQuote() - * To fix a conflict with buckeroo, use \Magento\Checkout\Model\Cart::getQuote() like the following - * - * @return \Magento\Quote\Model\Quote - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ - private function getQuoteFromCartOrSession() - { - if ($this->quote->getQuoteId() != null && $this->quote->getQuote() - && $this->quote->getQuote() instanceof Countable - && count($this->quote->getQuote()) - ) { - return $this->quote->getQuote(); - } - - return $this->session->getQuote(); - } -} diff --git a/Model/Sales/Delivery.php b/Model/Sales/Delivery.php deleted file mode 100755 index 79e8de85..00000000 --- a/Model/Sales/Delivery.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright 2010-2019 MyParcel - * @license http://creativecommons.org/licenses/by-nc-nd/3.0/nl/deed.en_US CC BY-NC-ND 3.0 NL - * @link https://github.com/myparcelnl/magento - * @since File available since Release 2.0.0 - */ - -namespace MyParcelNL\Magento\Model\Sales; - - -use Magento\Framework\Module\ModuleListInterface; -use MyParcelNL\Magento\Helper\Data; -use Magento\Framework\App\Helper\Context; -use Psr\Log\LoggerInterface; - -class Delivery extends Data implements DeliveryInterface -{ - /** - * @var int - */ - private $deliveryDateTime; - - /** - * @return int - */ - public function getDeliveryDateTime() - { - return $this->deliveryDateTime; - } - - /** - * @param int $deliveryDateTime - * @return int - */ - public function setDeliveryDateTime($deliveryDateTime) - { - $this->deliveryDateTime = $deliveryDateTime; - } -} diff --git a/Model/Sales/MagentoCollection.php b/Model/Sales/MagentoCollection.php index eca7b02f..ed9b8d45 100755 --- a/Model/Sales/MagentoCollection.php +++ b/Model/Sales/MagentoCollection.php @@ -14,19 +14,36 @@ namespace MyParcelNL\Magento\Model\Sales; +use Exception; +use Magento\Framework\App\Area; +use Magento\Framework\App\AreaList; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Message\ManagerInterface; use Magento\Framework\Module\Manager; use Magento\Framework\ObjectManagerInterface; use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Shipment\Track; +use Magento\Sales\Model\ResourceModel\Order\Collection as OrderCollection; +use Magento\Sales\Model\ResourceModel\Order\Shipment; +use Magento\Sales\Model\ResourceModel\Order\Shipment\Collection as ShipmentCollection; +use Magento\Sales\Model\ResourceModel\Order\Shipment\Track\Collection; +use MyParcelNL\Magento\Model\Carrier\Carrier; use MyParcelNL\Magento\Model\Order\Email\Sender\TrackSender; use MyParcelNL\Magento\Model\Source\ReturnInTheBox; use MyParcelNL\Magento\Model\Source\SourceItem; use MyParcelNL\Magento\Observer\NewShipment; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Magento\Service\Weight; use MyParcelNL\Magento\Ui\Component\Listing\Column\TrackAndTrace; -use MyParcelNL\Sdk\src\Helper\MyParcelCollection; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierPostNL; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; -use MyParcelNL\Sdk\src\Model\Consignment\BaseConsignment; -use Magento\Framework\App\ResourceConnection; +use MyParcelNL\Sdk\Exception\AccountNotActiveException; +use MyParcelNL\Sdk\Exception\ApiException; +use MyParcelNL\Sdk\Exception\MissingFieldException; +use MyParcelNL\Sdk\Helper\MyParcelCollection; +use MyParcelNL\Sdk\Model\Carrier\CarrierPostNL; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; +use MyParcelNL\Sdk\Model\Consignment\BaseConsignment; /** * Class MagentoOrderCollection @@ -35,87 +52,55 @@ */ abstract class MagentoCollection implements MagentoCollectionInterface { - public const PATH_HELPER_DATA = '\MyParcelNL\Magento\Helper\Data'; - public const PATH_MODEL_ORDER = '\Magento\Sales\Model\ResourceModel\Order\Collection'; - public const PATH_MODEL_SHIPMENT = '\Magento\Sales\Model\ResourceModel\Order\Shipment\Collection'; - public const ERROR_ORDER_HAS_NO_SHIPMENT = 'No shipment can be made with this order. Shipments can not be created if the status is On Hold or if the product is digital.'; - public const ERROR_ORDER_HAS_NO_SOURCE = 'Creating shipments via bulk actions is not possible for orders without a source. Go to the details of the order and process the shipment manually.'; - public const DEFAULT_ERROR_ORDER_HAS_NO_SOURCE = 'Source item not found by source code'; + public const PATH_MODEL_ORDER_COLLECTION = OrderCollection::class; + public const PATH_MODEL_SHIPMENT_COLLECTION = ShipmentCollection::class; + public const ERROR_ORDER_HAS_NO_SHIPMENT = 'No shipment can be made with this order. Shipments can not be created if the status is On Hold or if the product is digital.'; + public const ERROR_ORDER_HAS_NO_SOURCE = 'Creating shipments via bulk actions is not possible for orders without a source. Go to the details of the order and process the shipment manually.'; + public const DEFAULT_ERROR_ORDER_HAS_NO_SOURCE = 'Source item not found by source code'; private const PATH_ORDER_TRACK = '\Magento\Sales\Model\Order\Shipment\Track'; private const PATH_MANAGER_INTERFACE = '\Magento\Framework\Message\ManagerInterface'; private const PATH_ORDER_TRACK_COLLECTION = '\Magento\Sales\Model\ResourceModel\Order\Shipment\Track\Collection'; - /** - * @var MyParcelCollection - */ - public $myParcelCollection; - - /** - * @var \Magento\Framework\Module\Manager - */ - protected $moduleManager; - - /** - * @var \MyParcelNL\Magento\Model\Source\SourceItem - */ - protected $sourceItem; - - /** - * @var \Magento\Framework\App\RequestInterface - */ - public $request = null; - - /** - * @var TrackSender - */ - protected $trackSender; - - /** - * @var ObjectManagerInterface - */ - protected $objectManager; - - /** - * @var Order\Shipment\Track - */ - protected $modelTrack; - - /** - * @var \Magento\Framework\App\AreaList - */ - protected $areaList; - - /** - * @var \Magento\Framework\Message\ManagerInterface $messageManager - */ - protected $messageManager; - /** - * @var \MyParcelNL\Magento\Helper\Data - */ - protected $helper; + public MyParcelCollection $myParcelCollection; + public ?RequestInterface $request = null; + protected Manager $moduleManager; + protected SourceItem $sourceItem; + protected TrackSender $trackSender; + protected ObjectManagerInterface $objectManager; + protected Track $modelTrack; + protected AreaList $areaList; + protected ManagerInterface $messageManager; + protected Config $configService; /** * @var array */ - protected $options = [ - 'create_track_if_one_already_exist' => true, - 'request_type' => 'download', - 'package_type' => 'default', - 'carrier' => 'postnl', - 'positions' => null, - 'signature' => null, - 'only_recipient' => null, - 'return' => null, - 'large_format' => null, - 'age_check' => null, - 'insurance' => null, - 'label_amount' => NewShipment::DEFAULT_LABEL_AMOUNT, - 'digital_stamp_weight' => null, - 'return_in_the_box' => false, - 'same_day_delivery' => false, - ]; + protected $options + = [ + 'create_track_if_one_already_exist' => true, + 'request_type' => 'download', + 'package_type' => 'default', + 'carrier' => 'postnl', + 'positions' => null, + 'signature' => null, + 'collect' => null, + 'receipt_code' => null, + 'only_recipient' => null, + 'return' => null, + 'large_format' => null, + 'age_check' => null, + 'insurance' => null, + 'label_amount' => NewShipment::DEFAULT_LABEL_AMOUNT, + 'digital_stamp_weight' => null, + 'return_in_the_box' => false, + 'same_day_delivery' => false, + ]; + /** + * @var mixed + */ + private $weightService; /** * @param ObjectManagerInterface $objectManager @@ -126,7 +111,8 @@ public function __construct( ObjectManagerInterface $objectManager, $request = null, $areaList = null - ) { + ) + { // @todo; Adjust if there is a solution to the following problem: https://github.com/magento/magento2/pull/8413 if ($areaList) { $this->areaList = $areaList; @@ -135,14 +121,13 @@ public function __construct( $this->objectManager = $objectManager; $this->moduleManager = $objectManager->get(Manager::class); $this->request = $request; - $this->trackSender = $this->objectManager->get( - 'MyParcelNL\Magento\Model\Order\Email\Sender\TrackSender' - ); - $this->helper = $objectManager->create(self::PATH_HELPER_DATA); + $this->trackSender = $this->objectManager->get(TrackSender::class); + $this->configService = $objectManager->get(Config::class); + $this->weightService = $objectManager->get(Weight::class); $this->modelTrack = $objectManager->create(self::PATH_ORDER_TRACK); $this->messageManager = $objectManager->create(self::PATH_MANAGER_INTERFACE); $this->myParcelCollection = (new MyParcelCollection())->setUserAgents( - ['Magento2' => $this->helper->getVersion()] + ['Magento2' => $this->configService->getVersion()] ); $this->setSourceItemWhenInventoryApiEnabled(); @@ -151,7 +136,7 @@ public function __construct( /** * Set options from POST or GET variables * - * @return $this + * @return self */ public function setOptionsFromParameters() { @@ -189,7 +174,7 @@ public function setOptionsFromParameters() $this->options['create_track_if_one_already_exist'] = false; } - $returnInTheBox = $this->helper->getGeneralConfig('print/return_in_the_box'); + $returnInTheBox = $this->configService->getGeneralConfig('print/return_in_the_box'); if (ReturnInTheBox::NO_OPTIONS === $returnInTheBox || ReturnInTheBox::EQUAL_TO_SHIPMENT === $returnInTheBox) { $this->options['return_in_the_box'] = $returnInTheBox; } @@ -224,8 +209,8 @@ public function getOption($option) * * @param $consignment BaseConsignment * - * @return $this - * @throws \Exception + * @return self + * @throws Exception */ public function addConsignment(BaseConsignment $consignment) { @@ -234,30 +219,6 @@ public function addConsignment(BaseConsignment $consignment) return $this; } - /** - * @return string - */ - public function getApiKey(): string - { - return $this->helper->getApiKey(); - } - - /** - * @return string|null - */ - public function getExportMode(): ?string - { - return $this->helper->getExportMode(); - } - - /** - * @return bool - */ - public function apiKeyIsCorrect(): bool - { - return $this->helper->apiKeyIsCorrect(); - } - /** * Update sales_order table * @@ -272,15 +233,15 @@ public function getHtmlForGridColumns($orderId) */ // Temporarily fix to translate in cronjob if (! empty($this->areaList)) { - $areaObject = $this->areaList->getArea(\Magento\Framework\App\Area::AREA_ADMINHTML); - $areaObject->load(\Magento\Framework\App\Area::PART_TRANSLATE); + $areaObject = $this->areaList->getArea(Area::AREA_ADMINHTML); + $areaObject->load(Area::PART_TRANSLATE); } return $this->getHtmlForGridColumnsByTracks($this->getTracksCollectionByOrderId($orderId)); } /** - * @param Order\Shipment\Track[]|\Magento\Sales\Model\ResourceModel\Order\Shipment\Track\Collection $tracks + * @param Track[]|Collection $tracks * * @return string[] */ @@ -313,7 +274,7 @@ public function getHtmlForGridColumnsByTracks($tracks): array /** * Check if track already exists * - * @param \Magento\Sales\Model\ResourceModel\Order\Shipment $shipment + * @param Shipment $shipment * * @return bool */ @@ -327,18 +288,18 @@ protected function shipmentHasTrack($shipment) * * @param Order\Shipment $shipment * - * @return \Magento\Sales\Model\Order\Shipment\Track - * @throws \Exception + * @return Track + * @throws Exception */ protected function setNewMagentoTrack($shipment) { - /** @var \Magento\Sales\Model\Order\Shipment\Track $track */ - $track = $this->objectManager->create('Magento\Sales\Model\Order\Shipment\Track'); + /** @var Track $track */ + $track = $this->objectManager->create(Track::class); $track ->setOrderId($shipment->getOrderId()) ->setShipment($shipment) - ->setCarrierCode(TrackTraceHolder::MYPARCEL_CARRIER_CODE) - ->setTitle(TrackTraceHolder::MYPARCEL_TRACK_TITLE) + ->setCarrierCode(Carrier::CODE) + ->setTitle(Config::MYPARCEL_TRACK_TITLE) ->setQty($shipment->getTotalQty()) ->setTrackNumber(TrackAndTrace::VALUE_EMPTY) ->save(); @@ -349,13 +310,13 @@ protected function setNewMagentoTrack($shipment) /** * Get all tracks * - * @param \Magento\Sales\Model\ResourceModel\Order\Shipment $shipment + * @param Shipment $shipment * - * @return \Magento\Sales\Model\ResourceModel\Order\Shipment\Track\Collection + * @return Collection */ protected function getTrackByShipment($shipment) { - /* @var \Magento\Sales\Model\ResourceModel\Order\Shipment\Track\Collection $collection */ + /* @var Collection $collection */ $collection = $this->objectManager->create(self::PATH_ORDER_TRACK_COLLECTION); $collection ->addAttributeToFilter('parent_id', $shipment->getId()); @@ -366,16 +327,15 @@ protected function getTrackByShipment($shipment) /** * Get MyParcel Track from Magento Track * - * @param Order\Shipment\Track $magentoTrack + * @param Track $magentoTrack * * @return TrackTraceHolder $myParcelTrack - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ protected function createConsignmentAndGetTrackTraceHolder($magentoTrack): TrackTraceHolder { $trackTraceHolder = new TrackTraceHolder( $this->objectManager, - $this->helper, $magentoTrack->getShipment()->getOrder() ); $trackTraceHolder->convertDataFromMagentoToApi($magentoTrack, $this->options); @@ -384,7 +344,7 @@ protected function createConsignmentAndGetTrackTraceHolder($magentoTrack): Track } /** - * @return $this + * @return self */ public function syncMagentoToMyparcel(): self { @@ -393,9 +353,9 @@ public function syncMagentoToMyparcel(): self try { $this->myParcelCollection->addConsignmentByConsignmentIds( $consignmentIds, - $this->getApiKey() + $this->configService->getApiKey() ); - } catch (\Exception $e) { + } catch (Exception $e) { $this->messageManager->addErrorMessage($e->getMessage()); } @@ -403,10 +363,10 @@ public function syncMagentoToMyparcel(): self } /** - * @return $this - * @throws \MyParcelNL\Sdk\src\Exception\ApiException - * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException - * @throws \Exception + * @return self + * @throws ApiException + * @throws MissingFieldException + * @throws Exception */ public function createMyParcelConcepts(): self { @@ -417,7 +377,7 @@ public function createMyParcelConcepts(): self try { $this->myParcelCollection->createConcepts(); - } catch (\Exception $e) { + } catch (Exception $e) { $this->messageManager->addErrorMessage($e->getMessage()); return $this; } @@ -430,8 +390,8 @@ public function createMyParcelConcepts(): self /** * Add MyParcel Track from Magento Track * - * @return $this - * @throws \Exception + * @return self + * @throws Exception */ public function setNewMyParcelTracks(): self { @@ -439,15 +399,15 @@ public function setNewMyParcelTracks(): self $multiColloConsignments = []; /** - * @var Order\Shipment $shipment - * @var Order\Shipment\Track $magentoTrack + * @var Order\Shipment $shipment + * @var Track $magentoTrack */ foreach ($shipments as $shipment) { $magentoTracks = $this->getTrackByShipment($shipment)->getItems(); foreach ($magentoTracks as $magentoTrack) { if ($magentoTrack->getData('myparcel_consignment_id') - || TrackTraceHolder::MYPARCEL_CARRIER_CODE !== $magentoTrack->getCarrierCode()) { + || Carrier::CODE !== $magentoTrack->getCarrierCode()) { continue; } @@ -473,7 +433,7 @@ public function setNewMyParcelTracks(): self /** * @param array $multiColloConsignments * - * @return $this + * @return self */ protected function addGroupedConsignments(array $multiColloConsignments): self { @@ -493,10 +453,10 @@ protected function addGroupedConsignments(array $multiColloConsignments): self } /** - * @param \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment $consignment - * @param int $quantity + * @param AbstractConsignment $consignment + * @param int $quantity * - * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException + * @throws MissingFieldException */ protected function addConsignmentMultipleTimes(AbstractConsignment $consignment, int $quantity): void { @@ -505,7 +465,7 @@ protected function addConsignmentMultipleTimes(AbstractConsignment $consignment, while ($i < $quantity) { try { $this->myParcelCollection->addConsignment($consignment); - } catch (\Exception $e) { + } catch (Exception $e) { return; } @@ -514,9 +474,9 @@ protected function addConsignmentMultipleTimes(AbstractConsignment $consignment, } /** - * @throws \MyParcelNL\Sdk\src\Exception\AccountNotActiveException - * @throws \MyParcelNL\Sdk\src\Exception\ApiException - * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException + * @throws AccountNotActiveException + * @throws ApiException + * @throws MissingFieldException */ public function addReturnInTheBox(string $returnOptions): void { @@ -548,8 +508,8 @@ function ( } /** - * @return $this - * @throws \Exception + * @return self + * @throws Exception */ public function updateMagentoTrack(): self { @@ -592,10 +552,10 @@ public function updateMagentoTrack(): self } /** - * @return $this - * @throws \MyParcelNL\Sdk\src\Exception\AccountNotActiveException - * @throws \MyParcelNL\Sdk\src\Exception\ApiException - * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException + * @return self + * @throws AccountNotActiveException + * @throws ApiException + * @throws MissingFieldException */ public function addReturnShipments(): self { @@ -609,7 +569,7 @@ public function addReturnShipments(): self } /** - * @return $this + * @return self */ protected function updateOrderGrid(): self { @@ -639,7 +599,7 @@ protected function updateOrderGrid(): self return $this; } - abstract protected function getShipmentsCollection(): \Magento\Sales\Model\ResourceModel\Order\Shipment\Collection; + abstract protected function getShipmentsCollection(): ShipmentCollection; /** * @param $orderId @@ -648,7 +608,7 @@ abstract protected function getShipmentsCollection(): \Magento\Sales\Model\Resou */ private function getTracksCollectionByOrderId($orderId): array { - /** @var \Magento\Framework\App\ResourceConnection $connection */ + /** @var ResourceConnection $connection */ $connection = $this->objectManager->create(ResourceConnection::class); $conn = $connection->getConnection(); $select = $conn->select() @@ -681,7 +641,7 @@ protected function getMyparcelConsignmentIdsForShipments(): array } /** - * @param \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment $consignment + * @param AbstractConsignment $consignment * * @return bool whether $consignment properties allow for multicollo shipments */ diff --git a/Model/Sales/MagentoOrderCollection.php b/Model/Sales/MagentoOrderCollection.php index 376df205..1b114520 100755 --- a/Model/Sales/MagentoOrderCollection.php +++ b/Model/Sales/MagentoOrderCollection.php @@ -4,9 +4,16 @@ namespace MyParcelNL\Magento\Model\Sales; +use BadMethodCallException; +use DateTime; +use DateTimeZone; +use Exception; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\AlreadyExistsException; use Magento\Framework\Exception\LocalizedException; use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Shipment; use Magento\Sales\Model\ResourceModel\Order as OrderResource; use Magento\Sales\Model\ResourceModel\Order\Shipment as ShipmentResource; use Magento\Store\Model\ScopeInterface; @@ -15,21 +22,26 @@ use MyParcelNL\Magento\Helper\CustomsDeclarationFromOrder; use MyParcelNL\Magento\Helper\ShipmentOptions; use MyParcelNL\Magento\Model\Source\DefaultOptions; -use MyParcelNL\Magento\Services\Normalizer\ConsignmentNormalizer; -use MyParcelNL\Sdk\src\Collection\Fulfilment\OrderCollection; -use MyParcelNL\Sdk\src\Collection\Fulfilment\OrderNotesCollection; -use MyParcelNL\Sdk\src\Factory\ConsignmentFactory; -use MyParcelNL\Sdk\src\Factory\DeliveryOptionsAdapterFactory; -use MyParcelNL\Sdk\src\Helper\SplitStreet; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierFactory; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierPostNL; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; -use MyParcelNL\Sdk\src\Model\Fulfilment\Order as FulfilmentOrder; -use MyParcelNL\Sdk\src\Model\Fulfilment\OrderNote; -use MyParcelNL\Sdk\src\Model\PickupLocation; -use MyParcelNL\Sdk\src\Model\Recipient; -use MyParcelNL\Sdk\src\Support\Collection; -use MyParcelNL\Sdk\src\Support\Str; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Magento\Service\Normalizer\ConsignmentNormalizer; +use MyParcelNL\Sdk\Collection\Fulfilment\OrderCollection; +use MyParcelNL\Sdk\Collection\Fulfilment\OrderNotesCollection; +use MyParcelNL\Sdk\Exception\AccountNotActiveException; +use MyParcelNL\Sdk\Exception\ApiException; +use MyParcelNL\Sdk\Exception\MissingFieldException; +use MyParcelNL\Sdk\Factory\ConsignmentFactory; +use MyParcelNL\Sdk\Factory\DeliveryOptionsAdapterFactory; +use MyParcelNL\Sdk\Helper\SplitStreet; +use MyParcelNL\Sdk\Model\Carrier\CarrierFactory; +use MyParcelNL\Sdk\Model\Carrier\CarrierPostNL; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; +use MyParcelNL\Sdk\Model\Consignment\PostNLConsignment; +use MyParcelNL\Sdk\Model\Fulfilment\Order as FulfilmentOrder; +use MyParcelNL\Sdk\Model\Fulfilment\OrderNote; +use MyParcelNL\Sdk\Model\PickupLocation; +use MyParcelNL\Sdk\Model\Recipient; +use MyParcelNL\Sdk\Support\Collection; +use MyParcelNL\Sdk\Support\Str; /** * Class MagentoOrderCollection @@ -39,29 +51,29 @@ class MagentoOrderCollection extends MagentoCollection { /** - * @var \Magento\Sales\Model\ResourceModel\Order\Collection + * @var OrderResource\Collection */ private $orders = null; /** - * @var \Magento\Sales\Model\Order + * @var Order */ private $order; /** - * @var \MyParcelNL\Sdk\src\Model\Recipient + * @var Recipient */ private $billingRecipient; /** - * @var \MyParcelNL\Sdk\src\Model\Recipient + * @var Recipient */ private $shippingRecipient; /** * Get all Magento orders * - * @return \Magento\Sales\Model\ResourceModel\Order\Collection + * @return OrderResource\Collection */ public function getOrders() { @@ -71,7 +83,7 @@ public function getOrders() /** * Set Magento collection * - * @param \Magento\Sales\Model\ResourceModel\Order\Collection|Order[] $orderCollection + * @param OrderResource\Collection|Order[] $orderCollection * * @return $this */ @@ -93,7 +105,7 @@ public function reload(): self $orders = []; foreach ($ids as $orderId) { - $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); + $objectManager = ObjectManager::getInstance(); $orders[] = $objectManager->create(Order::class)->load($orderId); } @@ -105,13 +117,13 @@ public function reload(): self /** * Set existing or create new Magento Track and set API consignment to collection * - * @throws \Exception + * @throws Exception * @throws LocalizedException */ public function setNewMagentoShipment(bool $notifyClientsByEmail = true): MagentoOrderCollection { /** @var Order $order */ - /** @var Order\Shipment $shipment */ + /** @var Shipment $shipment */ foreach ($this->getOrders() as $order) { if ($order->canShip()) { $this->createMagentoShipment($order, $notifyClientsByEmail); @@ -127,13 +139,13 @@ public function setNewMagentoShipment(bool $notifyClientsByEmail = true): Magent * Create new Magento Track and save order * * @return $this - * @throws \Exception + * @throws Exception */ public function setMagentoTrack(): MagentoOrderCollection { /** - * @var Order $order - * @var Order\Shipment $shipment + * @var Order $order + * @var Shipment $shipment */ foreach ($this->getShipmentsCollection() as $shipment) { $i = 1; @@ -156,23 +168,22 @@ public function setMagentoTrack(): MagentoOrderCollection /** * @return $this - * @throws \Exception + * @throws Exception * */ public function setFulfilment(): self { - $apiKey = $this->getApiKey(); + $apiKey = $this->configService->getApiKey(); $orderCollection = (new OrderCollection())->setApiKey($apiKey); $orderLines = new Collection(); foreach ($this->getOrders() as $magentoOrder) { - $defaultOptions = new DefaultOptions($magentoOrder, $this->helper); - $myparcelDeliveryOptions = $magentoOrder['myparcel_delivery_options'] ?? ''; + $defaultOptions = new DefaultOptions($magentoOrder); + $myparcelDeliveryOptions = $magentoOrder[Config::FIELD_DELIVERY_OPTIONS] ?? ''; $deliveryOptions = json_decode($myparcelDeliveryOptions, true); $selectedCarrier = $deliveryOptions['carrier'] ?? $this->options['carrier'] ?? CarrierPostNL::NAME; $shipmentOptionsHelper = new ShipmentOptions( $defaultOptions, - $this->helper, $magentoOrder, $this->objectManager, $selectedCarrier, @@ -184,16 +195,16 @@ public function setFulfilment(): self } $deliveryOptions['shipmentOptions'] = $shipmentOptionsHelper->getShipmentOptions(); + $deliveryOptions['carrier'] = $selectedCarrier; try { // create new instance from known json - $deliveryOptions['carrier'] = $selectedCarrier; - $deliveryOptionsAdapter = DeliveryOptionsAdapterFactory::create((array) $deliveryOptions); - } catch (\BadMethodCallException $e) { + $deliveryOptionsAdapter = DeliveryOptionsAdapterFactory::create((array)$deliveryOptions); + } catch (BadMethodCallException $e) { // create new instance from unknown json data - $deliveryOptions = (new ConsignmentNormalizer((array) $deliveryOptions))->normalize(); - $deliveryOptions['packageType'] = $deliveryOptions['packageType'] ?? AbstractConsignment::PACKAGE_TYPE_PACKAGE_NAME; - $deliveryOptionsAdapter = DeliveryOptionsAdapterFactory::create($deliveryOptions); + $deliveryOptions['packageType'] = $deliveryOptions['packageType'] ?? AbstractConsignment::PACKAGE_TYPE_PACKAGE_NAME; + $deliveryOptions['deliveryType'] = $deliveryOptions['deliveryType'] ?? AbstractConsignment::DELIVERY_TYPE_STANDARD_NAME; + $deliveryOptionsAdapter = DeliveryOptionsAdapterFactory::create($deliveryOptions); } $this->order = $magentoOrder; @@ -208,7 +219,7 @@ public function setFulfilment(): self ->setOrderDate($this->getLocalCreatedAtDate()) ->setExternalIdentifier($this->order->getIncrementId()) ->setDropOffPoint( - $this->helper->getDropOffPoint( + $this->configService->getDropOffPoint( CarrierFactory::createFromName($deliveryOptionsAdapter->getCarrier()) ) ); @@ -216,15 +227,15 @@ public function setFulfilment(): self if ($deliveryOptionsAdapter->isPickup()) { $pickupData = $deliveryOptionsAdapter->getPickupLocation(); $pickupLocation = new PickupLocation([ - 'cc' => $pickupData->getCountry(), - 'city' => $pickupData->getCity(), - 'postal_code' => $pickupData->getPostalCode(), - 'street' => $pickupData->getStreet(), - 'number' => $pickupData->getNumber(), - 'location_name' => $pickupData->getLocationName(), - 'location_code' => $pickupData->getLocationCode(), - 'retail_network_id' => $pickupData->getRetailNetworkId(), - ]); + 'cc' => $pickupData->getCountry(), + 'city' => $pickupData->getCity(), + 'postal_code' => $pickupData->getPostalCode(), + 'street' => $pickupData->getStreet(), + 'number' => $pickupData->getNumber(), + 'location_name' => $pickupData->getLocationName(), + 'location_code' => $pickupData->getLocationCode(), + 'retail_network_id' => $pickupData->getRetailNetworkId(), + ]); $order->setPickupLocation($pickupLocation); } @@ -236,8 +247,8 @@ public function setFulfilment(): self $order->setOrderLines($orderLines); - if (! in_array($this->shippingRecipient->getCc(), AbstractConsignment::EURO_COUNTRIES, true)) { - $customsDeclarationAdapter = new CustomsDeclarationFromOrder($this->order, $this->objectManager); + if (!in_array($this->shippingRecipient->getCc(), AbstractConsignment::EURO_COUNTRIES, true)) { + $customsDeclarationAdapter = new CustomsDeclarationFromOrder($this->order); $customsDeclaration = $customsDeclarationAdapter->createCustomsDeclaration(); $order->setCustomsDeclaration($customsDeclaration); } @@ -249,13 +260,13 @@ public function setFulfilment(): self try { $this->myParcelCollection = $orderCollection->save(); $this->setMagentoOrdersAsExported(); - } catch (\Exception $e) { + } catch (Exception $e) { $this->messageManager->addErrorMessage($e->getMessage()); } try { $this->saveOrderNotes(); - } catch(\Exception $e) { + } catch (Exception $e) { $this->messageManager->addErrorMessage($e->getMessage()); } @@ -263,21 +274,21 @@ public function setFulfilment(): self } /** - * @throws \MyParcelNL\Sdk\src\Exception\AccountNotActiveException - * @throws \MyParcelNL\Sdk\src\Exception\ApiException - * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException + * @throws AccountNotActiveException + * @throws ApiException + * @throws MissingFieldException */ private function saveOrderNotes(): void { - $notes = (new OrderNotesCollection())->setApiKey($this->getApiKey()); + $notes = (new OrderNotesCollection())->setApiKey($this->configService->getApiKey()); - $this->myParcelCollection->each(function(FulfilmentOrder $order) use ($notes) { + $this->myParcelCollection->each(function (FulfilmentOrder $order) use ($notes) { - $this->getAllNotesForOrder($order)->each(function(OrderNote $note) use ($notes) { + $this->getAllNotesForOrder($order)->each(function (OrderNote $note) use ($notes) { try { $note->validate(); $notes->push($note); - } catch (\Exception $e) { + } catch (Exception $e) { $this->messageManager->addWarningMessage( sprintf( 'Note `%s` not exported. %s', @@ -297,19 +308,19 @@ private function getAllNotesForOrder(FulfilmentOrder $fulfilmentOrder): OrderNot $notes = new OrderNotesCollection(); $orderUuid = $fulfilmentOrder->getUuid(); $magentoOrder = $this->objectManager->create(Order::class) - ->loadByIncrementId($fulfilmentOrder->getExternalIdentifier()); + ->loadByIncrementId($fulfilmentOrder->getExternalIdentifier()); foreach ($magentoOrder->getStatusHistoryCollection() as $status) { - if (! $status->getComment()) { + if (!$status->getComment()) { continue; } $notes->push( new OrderNote([ - 'orderUuid' => $orderUuid, - 'note' => $status->getComment(), - 'author' => 'webshop', - ]) + 'orderUuid' => $orderUuid, + 'note' => $status->getComment(), + 'author' => 'webshop', + ]) ); } @@ -321,7 +332,7 @@ private function setMagentoOrdersAsExported(): void foreach ($this->getOrders() as $magentoOrder) { $magentoOrder->setData('track_status', UpdateStatus::ORDER_STATUS_EXPORTED); - $fulfilmentOrder = $this->myParcelCollection->first(function(FulfilmentOrder $order) use ($magentoOrder){ + $fulfilmentOrder = $this->myParcelCollection->first(function (FulfilmentOrder $order) use ($magentoOrder) { return $order->getExternalIdentifier() === $magentoOrder->getIncrementId(); }); @@ -344,25 +355,25 @@ private function getTotalWeight(): int foreach ($this->order->getItems() as $item) { $product = $item->getProduct(); - if (! $product) { + if (!$product) { continue; } $totalWeight += $product->getWeight() * $item->getQtyOrdered(); } - return $this->helper->convertToGrams($totalWeight); + return $this->configService->convertToGrams($totalWeight); } /** - * @param string $format + * @param string $format * * @return string */ public function getLocalCreatedAtDate(string $format = 'Y-m-d H:i:s'): string { $scopeConfig = $this->objectManager->create(ScopeConfigInterface::class); - $datetime = \DateTime::createFromFormat('Y-m-d H:i:s', $this->order->getCreatedAt()); + $datetime = DateTime::createFromFormat('Y-m-d H:i:s', $this->order->getCreatedAt()); $timezone = $scopeConfig->getValue( 'general/locale/timezone', ScopeInterface::SCOPE_STORE, @@ -370,7 +381,7 @@ public function getLocalCreatedAtDate(string $format = 'Y-m-d H:i:s'): string ); if ($timezone) { - $storeTime = new \DateTimeZone($timezone); + $storeTime = new DateTimeZone($timezone); $datetime->setTimezone($storeTime); } @@ -396,7 +407,7 @@ public function setBillingRecipient(): self } /** - * @return \MyParcelNL\Sdk\src\Model\Recipient|null + * @return Recipient|null */ public function getBillingRecipient(): ?Recipient { @@ -405,15 +416,15 @@ public function getBillingRecipient(): ?Recipient /** * @return self - * @throws \Exception + * @throws Exception */ public function setShippingRecipient(): self { - $carrier = ConsignmentFactory::createByCarrierName(CarrierPostNL::NAME); - $street = implode( + $carrier = ConsignmentFactory::createByCarrierName(CarrierPostNL::NAME); + $street = implode( ' ', $this->order->getShippingAddress() - ->getStreet() ?? [] + ->getStreet() ?? [] ); $country = $this->order->getShippingAddress()->getCountryId(); @@ -427,16 +438,16 @@ public function setShippingRecipient(): self ->setPerson($this->getFullCustomerName()) ->setPostalCode($this->order->getShippingAddress()->getPostcode()) ->setStreet($streetParts->getStreet()) - ->setNumber((string) $streetParts->getNumber()) - ->setNumberSuffix((string) $streetParts->getNumberSuffix()) - ->setBoxNumber((string) $streetParts->getBoxNumber()) + ->setNumber((string)$streetParts->getNumber()) + ->setNumberSuffix((string)$streetParts->getNumberSuffix()) + ->setBoxNumber((string)$streetParts->getBoxNumber()) ->setPhone($this->order->getShippingAddress()->getTelephone()); return $this; } /** - * @return \MyParcelNL\Sdk\src\Model\Recipient|null + * @return Recipient|null */ public function getShippingRecipient(): ?Recipient { @@ -459,7 +470,7 @@ public function getFullCustomerName(): string * Set PDF content and convert status 'Concept' to 'Registered' * * @return $this - * @throws \Exception + * @throws Exception */ public function setPdfOfLabels(): self { @@ -472,7 +483,7 @@ public function setPdfOfLabels(): self * Download PDF directly * * @return $this - * @throws \Exception + * @throws Exception */ public function downloadPdfOfLabels(): self { @@ -486,7 +497,7 @@ public function downloadPdfOfLabels(): self * Update MyParcel collection * * @return $this - * @throws \Exception + * @throws Exception */ public function setLatestData(): self { @@ -501,8 +512,8 @@ public function setLatestData(): self /** * @return $this - * @throws \MyParcelNL\Sdk\src\Exception\ApiException - * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException|\MyParcelNL\Sdk\src\Exception\AccountNotActiveException + * @throws ApiException + * @throws MissingFieldException|AccountNotActiveException */ public function sendReturnLabelMails() { @@ -542,16 +553,16 @@ public function hasShipment(): bool } /** - * @return \Magento\Sales\Model\ResourceModel\Order\Shipment\Collection + * @return ShipmentResource\Collection */ - protected function getShipmentsCollection(): \Magento\Sales\Model\ResourceModel\Order\Shipment\Collection + protected function getShipmentsCollection(): ShipmentResource\Collection { $orderIds = []; foreach ($this->getOrders() as $order) { $orderIds[] = $order->getEntityId(); } - $shipmentsCollection = $this->objectManager->get(MagentoShipmentCollection::PATH_MODEL_SHIPMENT); + $shipmentsCollection = $this->objectManager->get(MagentoShipmentCollection::PATH_MODEL_SHIPMENT_COLLECTION); $shipmentsCollection->addAttributeToFilter('order_id', ['in' => $orderIds]); return $shipmentsCollection; @@ -570,14 +581,14 @@ private function save(): void /** * Send shipment email with Track and trace variable * - * @param \Magento\Sales\Model\Order $order + * @param Order $order * * @return $this */ private function sendTrackEmailFromOrder(Order $order): self { /** - * @var \Magento\Sales\Model\Order\Shipment $shipment + * @var Shipment $shipment */ if ($this->trackSender->isEnabled() == false) { return $this; @@ -593,7 +604,7 @@ private function sendTrackEmailFromOrder(Order $order): self } /** - * @throws \Magento\Framework\Exception\AlreadyExistsException + * @throws AlreadyExistsException */ public function createMagentoShipment(Order $order, bool $notifyClientByEmail = true): void { @@ -608,11 +619,11 @@ public function createMagentoShipment(Order $order, bool $notifyClientByEmail = } foreach ($order->getAllItems() as $orderItem) { - if (! $orderItem->getQtyToShip() || $orderItem->getIsVirtual()) { + if (!$orderItem->getQtyToShip() || $orderItem->getIsVirtual()) { continue; } - $qtyShipped = $orderItem->getQtyToShip(); + $qtyShipped = $orderItem->getQtyToShip(); $shipmentItem = $convertOrder->itemToShipmentItem($orderItem)->setQty($qtyShipped); $shipment->addItem($shipmentItem); } @@ -623,7 +634,7 @@ public function createMagentoShipment(Order $order, bool $notifyClientByEmail = try { $this->objectManager->get(ShipmentResource::class)->save($shipment); $this->objectManager->get(OrderResource::class)->save($shipment->getOrder()); - } catch (\Exception $e) { + } catch (Exception $e) { if (preg_match('/' . MagentoOrderCollection::DEFAULT_ERROR_ORDER_HAS_NO_SOURCE . '/', $e->getMessage())) { $this->messageManager->addErrorMessage(__(MagentoOrderCollection::ERROR_ORDER_HAS_NO_SOURCE)); } else { @@ -635,7 +646,7 @@ public function createMagentoShipment(Order $order, bool $notifyClientByEmail = if ($notifyClientByEmail) { $this->objectManager->create('Magento\Shipping\Model\ShipmentNotifier') - ->notify($shipment); + ->notify($shipment); } } } diff --git a/Model/Sales/Package.php b/Model/Sales/Package.php index 32d0fa2a..cd5f85ac 100755 --- a/Model/Sales/Package.php +++ b/Model/Sales/Package.php @@ -18,15 +18,10 @@ namespace MyParcelNL\Magento\Model\Sales; -use MyParcelNL\Magento\Helper\Data; +use MyParcelNL\Magento\Service\Config; -class Package extends Data implements PackageInterface +class Package extends Config implements PackageInterface //used to extend MyParcelNL\Magento\Helper\Data; { - const PACKAGE_TYPE_NORMAL = 1; - const PACKAGE_TYPE_MAILBOX = 2; - const PACKAGE_TYPE_LETTER = 3; - const PACKAGE_TYPE_DIGITAL_STAMP = 4; - /** * @var int */ @@ -244,17 +239,6 @@ protected function setMaxPackageSmallWeight(float $maxWeight): void $this->maxPackageSmallWeight = $maxWeight; } - /** - * @param bool $allProductsFit - * @deprecated fit in what? use PackageRepository->selectPackageType() to get the relevant package type - */ - public function setAllProductsFit(bool $allProductsFit): void - { - if ($allProductsFit === false) { - $this->allProductsFit = $allProductsFit; - } - } - /** * @return int */ @@ -263,6 +247,7 @@ public function getPackageType(): int if (! isset($this->packageType)) { throw new \RuntimeException('Use setPackageType() before you can getPackageType()'); } + throw new \Exception('Please remove Package.php and PackageRepository.php and use a service'); return $this->packageType; } diff --git a/Model/Sales/PackageInterface.php b/Model/Sales/PackageInterface.php index c987060d..bd1879f4 100755 --- a/Model/Sales/PackageInterface.php +++ b/Model/Sales/PackageInterface.php @@ -34,11 +34,6 @@ public function setWeight(float $weight); */ public function addWeight(float $weight); - /** - * @param bool $all_products_fit - */ - public function setAllProductsFit(bool $all_products_fit); - /** * package = 1 * diff --git a/Model/Sales/Repository/DeliveryRepository.php b/Model/Sales/Repository/DeliveryRepository.php index 4c089c7e..ffbfdfc4 100755 --- a/Model/Sales/Repository/DeliveryRepository.php +++ b/Model/Sales/Repository/DeliveryRepository.php @@ -18,10 +18,33 @@ namespace MyParcelNL\Magento\Model\Sales\Repository; -use MyParcelNL\Magento\Model\Sales\Delivery; +use MyParcelNL\Magento\Model\Sales\DeliveryInterface; +use MyParcelNL\Magento\Service\Config; -class DeliveryRepository extends Delivery +class DeliveryRepository extends Config implements DeliveryInterface // used to extend MyParcelNL\Magento\Helper\Data; { + /** + * @var int + */ + private int $deliveryDateTime; + + /** + * @return int + */ + public function getDeliveryDateTime() + { + return $this->deliveryDateTime; + } + + /** + * @param int $deliveryDateTime + * @return int + */ + public function setDeliveryDateTime($deliveryDateTime) + { + $this->deliveryDateTime = $deliveryDateTime; + } + /** * Get drop off day with chosen options from checkout * diff --git a/Model/Sales/Repository/PackageRepository.php b/Model/Sales/Repository/PackageRepository.php index ee2e0a53..6502077e 100755 --- a/Model/Sales/Repository/PackageRepository.php +++ b/Model/Sales/Repository/PackageRepository.php @@ -20,17 +20,17 @@ use MyParcelNL\Magento\Model\Sales\Package; use MyParcelNL\Magento\Model\Settings\AccountSettings; -use MyParcelNL\Sdk\src\Model\Carrier\AbstractCarrier; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierFactory; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierPostNL; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; +use MyParcelNL\Magento\Service\Weight; +use MyParcelNL\Sdk\Model\Carrier\AbstractCarrier; +use MyParcelNL\Sdk\Model\Carrier\CarrierFactory; +use MyParcelNL\Sdk\Model\Carrier\CarrierPostNL; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; class PackageRepository extends Package { public const DEFAULT_MAXIMUM_MAILBOX_WEIGHT = 2000; public const MAXIMUM_DIGITAL_STAMP_WEIGHT = 2000; public const MAXIMUM_PACKAGE_SMALL_WEIGHT = 2000; - public const DEFAULT_LARGE_FORMAT_WEIGHT = 23000; public const CARRIER_TYPE_CUSTOM = 'custom'; /** @@ -150,7 +150,8 @@ static function ($carrierOptions) { */ public function fitInDigitalStamp(): bool { - $orderWeight = $this->convertToGrams($this->getWeight()); + // TODO temporary weight calculation since PackageRepository will be removed alltogether + $orderWeight = (new Weight($this))->convertToGrams($this->getWeight()); $maximumDigitalStampWeight = $this->getMaxDigitalStampWeight(); return $this->getCurrentCountry() === AbstractConsignment::CC_NL @@ -171,8 +172,6 @@ public function setMailboxSettings(string $carrierPath = self::XML_PATH_POSTNL_S $settings = $this->getConfigValue("{$carrierPath}mailbox"); if (null === $settings || ! array_key_exists('active', $settings)) { - $this->_logger->critical("Can't set settings with path: {$carrierPath}mailbox"); - return $this; } @@ -267,8 +266,6 @@ public function setDigitalStampSettings(string $carrierPath = self::XML_PATH_POS $settings = $this->getConfigValue("{$carrierPath}digital_stamp"); if (null === $settings || ! array_key_exists('active', $settings)) { - $this->_logger->critical("Can't set settings with path: {$carrierPath}digital_stamp"); - return $this; } @@ -293,8 +290,6 @@ public function setPackageSmallSettings(string $carrierPath = self::XML_PATH_POS $settings = $this->getConfigValue("{$carrierPath}package_small"); if (null === $settings || ! array_key_exists('active', $settings)) { - $this->_logger->critical("Can't set settings with path: {$carrierPath}package_small"); - return $this; } diff --git a/Model/Sales/TrackTraceHolder.php b/Model/Sales/TrackTraceHolder.php index 3e2d7498..073eb933 100755 --- a/Model/Sales/TrackTraceHolder.php +++ b/Model/Sales/TrackTraceHolder.php @@ -18,22 +18,27 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\App\ResourceConnection; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Message\ManagerInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Sales\Model\Order; use Magento\Sales\Model\Order\Shipment; use Magento\Sales\Model\Order\Shipment\Track; use MyParcelNL\Magento\Adapter\DeliveryOptionsFromOrderAdapter; -use MyParcelNL\Magento\Helper\Data; use MyParcelNL\Magento\Helper\ShipmentOptions; +use MyParcelNL\Magento\Model\Carrier\Carrier; +use MyParcelNL\Magento\Model\Settings\AccountSettings; use MyParcelNL\Magento\Model\Source\DefaultOptions; -use MyParcelNL\Magento\Services\Normalizer\ConsignmentNormalizer; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Magento\Service\DeliveryCosts; +use MyParcelNL\Magento\Service\Dating; +use MyParcelNL\Magento\Service\Weight; use MyParcelNL\Magento\Ui\Component\Listing\Column\TrackAndTrace; -use MyParcelNL\Sdk\src\Exception\MissingFieldException; -use MyParcelNL\Sdk\src\Factory\ConsignmentFactory; -use MyParcelNL\Sdk\src\Factory\DeliveryOptionsAdapterFactory; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierFactory; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; -use MyParcelNL\Sdk\src\Model\MyParcelCustomsItem; +use MyParcelNL\Sdk\Exception\MissingFieldException; +use MyParcelNL\Sdk\Factory\ConsignmentFactory; +use MyParcelNL\Sdk\Factory\DeliveryOptionsAdapterFactory; +use MyParcelNL\Sdk\Model\Carrier\CarrierFactory; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; +use MyParcelNL\Sdk\Model\MyParcelCustomsItem; use RuntimeException; /** @@ -44,20 +49,12 @@ class TrackTraceHolder { /** - * Track title showing in Magento + * @var DefaultOptions */ - public const MYPARCEL_TRACK_TITLE = 'MyParcel'; - public const MYPARCEL_CARRIER_CODE = 'myparcel'; - public const EXPORT_MODE_PPS = 'pps'; - public const EXPORT_MODE_SHIPMENTS = 'shipments'; + private $defaultOptions; /** - * @var \MyParcelNL\Magento\Model\Source\DefaultOptions - */ - private static $defaultOptions; - - /** - * @var \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment|null + * @var AbstractConsignment|null */ public $consignment; @@ -67,7 +64,7 @@ class TrackTraceHolder public $mageTrack; /** - * @var \Magento\Framework\Message\ManagerInterface + * @var ManagerInterface */ protected $messageManager; @@ -76,10 +73,7 @@ class TrackTraceHolder */ private $carrier; - /** - * @var \MyParcelNL\Magento\Helper\Data - */ - private $dataHelper; + private Config $configService; /** * @var ObjectManagerInterface @@ -87,77 +81,61 @@ class TrackTraceHolder private $objectManager; /** - * @var \MyParcelNL\Magento\Helper\ShipmentOptions + * @var ShipmentOptions */ - private $shipmentOptionsHelper; + private $shipmentOptionsHelper; + private Weight $weight; /** * TrackTraceHolder constructor. * - * @param ObjectManagerInterface $objectManager - * @param Data $helper - * @param \Magento\Sales\Model\Order $order + * @param ObjectManagerInterface $objectManager + * @param Order $order */ public function __construct( ObjectManagerInterface $objectManager, - Data $helper, Order $order - ) { + ) + { $this->objectManager = $objectManager; - $this->dataHelper = $helper; + $this->configService = $objectManager->get(Config::class); + $this->weight = $objectManager->get(Weight::class); $this->messageManager = $this->objectManager->create('Magento\Framework\Message\ManagerInterface'); - self::$defaultOptions = new DefaultOptions( - $order, - $this->dataHelper - ); - } - - /** - * @param float $price - * - * @return int - */ - public static function getCentsByPrice(float $price): int - { - return (int) $price * 100; + $this->defaultOptions = new DefaultOptions($order); } /** * Set all data to MyParcel object * - * @param Order\Shipment\Track $magentoTrack - * @param array $options + * @param Order\Shipment\Track $magentoTrack + * @param array $options * - * @return $this - * @throws \Exception + * @return self + * @throws Exception * @throws LocalizedException */ public function convertDataFromMagentoToApi(Track $magentoTrack, array $options): self { - $shipment = $magentoTrack->getShipment(); - $address = $shipment->getShippingAddress(); - $order = $shipment->getOrder(); - $checkoutData = $order->getData('myparcel_delivery_options') ?? ''; - $deliveryOptions = json_decode($checkoutData, true) ?? []; - $deliveryOptions['carrier'] = $this->getCarrierFromOptions($options) - ?? $deliveryOptions['carrier'] - ?? DefaultOptions::getDefaultCarrier() - ->getName(); + $shipment = $magentoTrack->getShipment(); + $address = $shipment->getShippingAddress(); + $order = $shipment->getOrder(); + $checkoutData = $order->getData('myparcel_delivery_options') ?? ''; + $deliveryOptions = json_decode($checkoutData, true) ?? []; + $deliveryOptions['carrier'] = $this->defaultOptions->getCarrierName(); $totalWeight = $options['digital_stamp_weight'] !== null ? (int) $options['digital_stamp_weight'] - : (int) self::$defaultOptions->getDigitalStampDefaultWeight(); + : (int) $this->defaultOptions->getDigitalStampDefaultWeight(); try { // create new instance from known json $deliveryOptionsAdapter = DeliveryOptionsAdapterFactory::create((array) $deliveryOptions); } catch (BadMethodCallException $e) { // create new instance from unknown json data - $deliveryOptions = (new ConsignmentNormalizer((array) $deliveryOptions + $options))->normalize(); - $deliveryOptionsAdapter = new DeliveryOptionsFromOrderAdapter($deliveryOptions); + $deliveryOptionsAdapter = new DeliveryOptionsFromOrderAdapter((array) $deliveryOptions + $options); } $pickupLocationAdapter = $deliveryOptionsAdapter->getPickupLocation(); - $apiKey = $this->dataHelper->getGeneralConfig( + $apiKey = $this->configService->getGeneralConfig( 'api/key', $order->getStoreId() ); @@ -165,8 +143,7 @@ public function convertDataFromMagentoToApi(Track $magentoTrack, array $options) $this->validateApiKey($apiKey); $this->carrier = $deliveryOptionsAdapter->getCarrier(); $this->shipmentOptionsHelper = new ShipmentOptions( - self::$defaultOptions, - $this->dataHelper, + $this->defaultOptions, $order, $this->objectManager, $this->carrier, @@ -178,7 +155,7 @@ public function convertDataFromMagentoToApi(Track $magentoTrack, array $options) ->setReferenceIdentifier($shipment->getEntityId()) ->setConsignmentId($magentoTrack->getData('myparcel_consignment_id')) ->setCountry($address->getCountryId()) - ->setCompany(self::$defaultOptions->getMaxCompanyName($address->getCompany())) + ->setCompany($address->getCompany()) ->setPerson($address->getName()); try { @@ -186,28 +163,32 @@ public function convertDataFromMagentoToApi(Track $magentoTrack, array $options) ->setFullStreet($address->getData('street')) ->setPostalCode(preg_replace('/\s+/', '', $address->getPostcode())); } catch (Exception $e) { - $errorHuman = - sprintf( - 'An error has occurred while validating order number %s. Check address.', - $order->getIncrementId() - ); + $errorHuman + = sprintf( + 'An error has occurred while validating order number %s. Check address.', + $order->getIncrementId() + ); $this->messageManager->addErrorMessage($errorHuman . ' View log file for more information.'); $this->objectManager->get('Psr\Log\LoggerInterface') - ->critical($errorHuman . '-' . $e); + ->critical($errorHuman . '-' . $e); - $this->dataHelper->setOrderStatus($magentoTrack->getOrderId(), Order::STATE_NEW); + $this->setOrderStatus($magentoTrack->getOrderId(), Order::STATE_NEW); } if (isset($deliveryOptions['packageType'])) { $options['package_type'] = $deliveryOptions['packageType']; } $packageType = $this->getPackageType($options, $magentoTrack, $address); - $dropOffPoint = $this->dataHelper->getDropOffPoint( + $deliveryDate = ( + AbstractConsignment::PACKAGE_TYPE_PACKAGE_SMALL === $packageType + && 'NL' !== $address->getCountryId() + ) ? null : Dating::convertDeliveryDate($deliveryOptionsAdapter->getDate()); + $dropOffPoint = AccountSettings::getInstance()->getDropOffPoint( CarrierFactory::createFromName($deliveryOptionsAdapter->getCarrier()) ); $regionCode = $address->getRegionCode(); - $state = $regionCode && strlen($regionCode) === 2 ? $regionCode : null; + $state = $regionCode && strlen($regionCode) === 2 ? $regionCode : null; $this->consignment ->setCity($address->getCity()) @@ -215,12 +196,14 @@ public function convertDataFromMagentoToApi(Track $magentoTrack, array $options) ->setPhone($address->getTelephone()) ->setEmail($address->getEmail()) ->setLabelDescription($this->shipmentOptionsHelper->getLabelDescription()) - ->setDeliveryDate($this->dataHelper->convertDeliveryDate($deliveryOptionsAdapter->getDate())) - ->setDeliveryType($this->dataHelper->checkDeliveryType($deliveryOptionsAdapter->getDeliveryTypeId())) + ->setDeliveryType($deliveryOptionsAdapter->getDeliveryTypeId() ?? AbstractConsignment::DELIVERY_TYPE_STANDARD) + ->setDeliveryDate($deliveryDate) ->setPackageType($packageType) ->setDropOffPoint($dropOffPoint) ->setOnlyRecipient($this->shipmentOptionsHelper->hasOnlyRecipient()) ->setSignature($this->shipmentOptionsHelper->hasSignature()) + ->setCollect($this->shipmentOptionsHelper->hasCollect()) + ->setReceiptCode($this->shipmentOptionsHelper->hasReceiptCode()) ->setReturn($this->shipmentOptionsHelper->hasReturn()) ->setSameDayDelivery($this->shipmentOptionsHelper->hasSameDayDelivery()) ->setLargeFormat($this->shipmentOptionsHelper->hasLargeFormat()) @@ -233,7 +216,7 @@ public function convertDataFromMagentoToApi(Track $magentoTrack, array $options) ) ->setSaveRecipientAddress(false); - if ($deliveryOptionsAdapter->isPickup() && $pickupLocationAdapter) { + if ($pickupLocationAdapter && $deliveryOptionsAdapter->isPickup()) { $this->consignment ->setPickupPostalCode($pickupLocationAdapter->getPostalCode()) ->setPickupStreet($pickupLocationAdapter->getStreet()) @@ -242,7 +225,6 @@ public function convertDataFromMagentoToApi(Track $magentoTrack, array $options) ->setPickupCountry($pickupLocationAdapter->getCountry()) ->setPickupLocationName($pickupLocationAdapter->getLocationName()) ->setPickupLocationCode($pickupLocationAdapter->getLocationCode()) - ->setPickupNetworkId($pickupLocationAdapter->getPickupNetworkId()) ->setReturn(false); if ($pickupLocationAdapter->getRetailNetworkId()) { @@ -252,7 +234,7 @@ public function convertDataFromMagentoToApi(Track $magentoTrack, array $options) try { $this->convertDataForCdCountry($magentoTrack) - ->calculateTotalWeight($magentoTrack, $totalWeight); + ->calculateTotalWeight($magentoTrack, $totalWeight); } catch (Exception $e) { $this->messageManager->addErrorMessage($e->getMessage()); return $this; @@ -264,9 +246,9 @@ public function convertDataFromMagentoToApi(Track $magentoTrack, array $options) /** * Create Magento Track from Magento shipment * - * @param \Magento\Sales\Model\Order\Shipment $shipment + * @param Shipment $shipment * - * @return $this + * @return self */ public function createTrackTraceFromShipment(Shipment $shipment) { @@ -274,42 +256,56 @@ public function createTrackTraceFromShipment(Shipment $shipment) $this->mageTrack ->setOrderId($shipment->getOrderId()) ->setShipment($shipment) - ->setCarrierCode(self::MYPARCEL_CARRIER_CODE) - ->setTitle(self::MYPARCEL_TRACK_TITLE) + ->setCarrierCode(Carrier::CODE) + ->setTitle(Config::MYPARCEL_TRACK_TITLE) ->setQty($shipment->getTotalQty()) ->setTrackNumber(TrackAndTrace::VALUE_EMPTY); return $this; } + /** + * @param int $orderId + * @param string $status + */ + private function setOrderStatus(int $orderId, string $status): void + { + $order = ObjectManager::getInstance() + ->create('\Magento\Sales\Model\Order') + ->load($orderId); + $order->setState($status) + ->setStatus($status); + $order->save(); + } + /** * Get country of origin from product settings or, if they are not found, from the MyParcel settings. * - * @param $product_id + * @param int $product_id * * @return string */ public function getCountryOfOrigin(int $product_id): string { - $product = - $this->objectManager->get('Magento\Catalog\Api\ProductRepositoryInterface') - ->getById($product_id); + $product = $this->objectManager->get('Magento\Catalog\Api\ProductRepositoryInterface') + ->getById($product_id); + $productCountryOfManufacture = $product->getCountryOfManufacture(); if ($productCountryOfManufacture) { return $productCountryOfManufacture; } - return $this->dataHelper->getGeneralConfig('print/country_of_origin'); + return $this->configService->getGeneralConfig('print/country_of_origin'); } /** * Override to check if key isset * - * @param null|string $apiKey + * @param null|string $apiKey * - * @return $this - * @throws \Magento\Framework\Exception\LocalizedException + * @return self + * @throws LocalizedException */ public function validateApiKey(?string $apiKey): self { @@ -325,12 +321,12 @@ public function validateApiKey(?string $apiKey): self } /** - * @param Order\Shipment\Track $magentoTrack - * @param int $totalWeight + * @param Order\Shipment\Track $magentoTrack + * @param int $totalWeight * * @return TrackTraceHolder * @throws LocalizedException - * @throws \Exception + * @throws Exception */ private function calculateTotalWeight(Track $magentoTrack, int $totalWeight = 0): self { @@ -344,30 +340,30 @@ private function calculateTotalWeight(Track $magentoTrack, int $totalWeight = 0) return $this; } - $weightFromSettings = (int) self::$defaultOptions->getDigitalStampDefaultWeight(); + $weightFromSettings = (int) $this->defaultOptions->getDigitalStampDefaultWeight(); if ($weightFromSettings) { $this->consignment->setPhysicalProperties(["weight" => $weightFromSettings]); return $this; } - $shipmentItems = - $magentoTrack->getShipment() - ->getItems(); + $shipmentItems + = $magentoTrack->getShipment() + ->getItems(); foreach ($shipmentItems as $shipmentItem) { $totalWeight += $shipmentItem['weight'] * $shipmentItem['qty']; } - $totalWeight = $this->dataHelper->convertToGrams($totalWeight); + $totalWeight = $this->weight->convertToGrams($totalWeight); if (0 === $totalWeight) { throw new RuntimeException( sprintf( 'Order %s can not be exported as digital stamp, no weights have been entered.', $magentoTrack->getShipment() - ->getOrder() - ->getIncrementId() + ->getOrder() + ->getIncrementId() ) ); } @@ -380,12 +376,12 @@ private function calculateTotalWeight(Track $magentoTrack, int $totalWeight = 0) } /** - * @param Order\Shipment\Track $magentoTrack + * @param Order\Shipment\Track $magentoTrack * - * @return $this + * @return self * @throws LocalizedException * @throws MissingFieldException - * @throws \Exception + * @throws Exception */ private function convertDataForCdCountry(Track $magentoTrack) { @@ -393,15 +389,15 @@ private function convertDataForCdCountry(Track $magentoTrack) return $this; } - if ($products = - $magentoTrack->getShipment() - ->getData('items')) { + if ($products + = $magentoTrack->getShipment() + ->getData('items')) { foreach ($products as $product) { $myParcelProduct = (new MyParcelCustomsItem()) ->setDescription($product->getName()) ->setAmount($product->getQty()) - ->setWeight($this->dataHelper->convertToGrams($product->getWeight()) ?: 1) - ->setItemValue($this->getCentsByPrice($product->getPrice())) + ->setWeight($this->weight->convertToGrams($product->getWeight()) ?: 1) + ->setItemValue(DeliveryCosts::getPriceInCents($product->getPrice())) ->setClassification( (int) $this->getAttributeValue( 'catalog_product_entity_int', @@ -415,11 +411,11 @@ private function convertDataForCdCountry(Track $magentoTrack) } foreach ($magentoTrack->getShipment() - ->getItems() as $item) { + ->getItems() as $item) { $myParcelProduct = (new MyParcelCustomsItem()) ->setDescription($item->getName()) ->setAmount($item->getQty()) - ->setWeight($this->dataHelper->convertToGrams($item->getWeight() * $item->getQty())) + ->setWeight($this->weight->convertToGrams($item->getWeight() * $item->getQty())) ->setItemValue($item->getPrice() * 100) ->setClassification( (int) $this->getAttributeValue( @@ -437,12 +433,12 @@ private function convertDataForCdCountry(Track $magentoTrack) } /** - * @param Order\Shipment\Track $magentoTrack - * @param object $address - * @param array $options + * @param Order\Shipment\Track $magentoTrack + * @param object $address + * @param array $options * * @return bool - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ private function getAgeCheck(Track $magentoTrack, $address, array $options = []): bool { @@ -450,17 +446,17 @@ private function getAgeCheck(Track $magentoTrack, $address, array $options = []) return false; } - $ageCheckFromOptions = ShipmentOptions::getValueOfOptionWhenSet('age_check', $options); + $ageCheckFromOptions = ShipmentOptions::getValueOfOptionWhenSet(ShipmentOptions::AGE_CHECK, $options); $ageCheckOfProduct = ShipmentOptions::getAgeCheckFromProduct($magentoTrack); - $ageCheckFromSettings = self::$defaultOptions->hasDefaultOptionsWithoutPrice($this->carrier, 'age_check'); + $ageCheckFromSettings = $this->defaultOptions->hasDefaultOption($this->carrier, ShipmentOptions::AGE_CHECK); return $ageCheckFromOptions ?? $ageCheckOfProduct ?? $ageCheckFromSettings; } /** - * @param string $tableName - * @param string $entityId - * @param string $column + * @param string $tableName + * @param string $entityId + * @param string $column * * @return string|null */ @@ -484,7 +480,7 @@ private function getAttributeValue(string $tableName, string $entityId, string $ } /** - * @param array $options + * @param array $options * * @return null|string */ @@ -493,22 +489,22 @@ private function getCarrierFromOptions(array $options): ?string $carrier = null; if (array_key_exists('carrier', $options) && $options['carrier']) { - $carrier = - DefaultOptions::DEFAULT_OPTION_VALUE === $options['carrier'] ? self::$defaultOptions->getCarrier() - : $options['carrier']; + $carrier + = DefaultOptions::DEFAULT_OPTION_VALUE === $options['carrier'] ? $this->defaultOptions->getCarrierName() + : $options['carrier']; } return $carrier; } /** - * @param array $options - * @param string $packageType - * @param Order\Shipment\Track $magentoTrack - * @param object $address + * @param array $options + * @param string $packageType + * @param Order\Shipment\Track $magentoTrack + * @param object $address * * @return int - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ private function getPackageType(array $options, Track $magentoTrack, $address): int { @@ -519,11 +515,11 @@ private function getPackageType(array $options, Track $magentoTrack, $address): // get package type from selected radio buttons and check if package type is set $packageType = $options['package_type'] ?? 'default'; if ('default' === $packageType) { - $packageType = self::$defaultOptions->getPackageType(); + $packageType = $this->defaultOptions->getPackageType(); } if (! is_numeric($packageType)) { - $packageType = AbstractConsignment::PACKAGE_TYPES_NAMES_IDS_MAP[$packageType] ?? self::$defaultOptions->getPackageType(); + $packageType = AbstractConsignment::PACKAGE_TYPES_NAMES_IDS_MAP[$packageType] ?? $this->defaultOptions->getPackageType(); } return $packageType; diff --git a/Model/Settings/AccountSettings.php b/Model/Settings/AccountSettings.php index 4ebba166..100883eb 100644 --- a/Model/Settings/AccountSettings.php +++ b/Model/Settings/AccountSettings.php @@ -4,55 +4,40 @@ namespace MyParcelNL\Magento\Model\Settings; +use Exception; use MyParcelNL\Magento\Controller\Adminhtml\Settings\CarrierConfigurationImport; -use MyParcelNL\Sdk\src\Factory\Account\CarrierConfigurationFactory; -use MyParcelNL\Sdk\src\Model\Account\Account; -use MyParcelNL\Sdk\src\Model\Account\CarrierConfiguration; -use MyParcelNL\Sdk\src\Model\Account\CarrierOptions; -use MyParcelNL\Sdk\src\Model\Account\Shop; -use MyParcelNL\Sdk\src\Model\BaseModel; -use MyParcelNL\Sdk\src\Model\Carrier\AbstractCarrier; -use MyParcelNL\Sdk\src\Support\Collection; +use MyParcelNL\Sdk\Exception\AccountNotActiveException; +use MyParcelNL\Sdk\Exception\ApiException; +use MyParcelNL\Sdk\Exception\MissingFieldException; +use MyParcelNL\Sdk\Factory\Account\CarrierConfigurationFactory; +use MyParcelNL\Sdk\Model\Account\Account; +use MyParcelNL\Sdk\Model\Account\CarrierConfiguration; +use MyParcelNL\Sdk\Model\Account\CarrierOptions; +use MyParcelNL\Sdk\Model\Account\Shop; +use MyParcelNL\Sdk\Model\BaseModel; +use MyParcelNL\Sdk\Model\Carrier\AbstractCarrier; +use MyParcelNL\Sdk\Model\Consignment\DropOffPoint; +use MyParcelNL\Sdk\Support\Collection; class AccountSettings extends BaseModel { + protected Shop $shop; + protected Account $account; + protected Collection $carrierOptions; + protected Collection $carrierConfigurations; + private static self $instance; /** - * @var - */ - protected $shop; - - /** - * @var - */ - protected $account; - - /** - * @var - */ - protected $carrier_options; - - /** - * @var - */ - protected $carrier_configurations; - - /** - * @var self - */ - private static $instance; - - /** - * @throws \MyParcelNL\Sdk\src\Exception\ApiException - * @throws \MyParcelNL\Sdk\src\Exception\AccountNotActiveException - * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException - * @throws \Exception + * @throws ApiException + * @throws AccountNotActiveException + * @throws MissingFieldException + * @throws Exception */ public function __construct() { $settings = CarrierConfigurationImport::getAccountSettings(); - if (! $settings) { + if (!$settings) { return; } @@ -60,7 +45,7 @@ public function __construct() } /** - * @return null|\MyParcelNL\Sdk\src\Model\Account\Account + * @return null|Account */ public function getAccount(): ?Account { @@ -68,9 +53,9 @@ public function getAccount(): ?Account } /** - * @param \MyParcelNL\Sdk\src\Model\Carrier\AbstractCarrier $carrier + * @param AbstractCarrier $carrier * - * @return null|\MyParcelNL\Sdk\src\Model\Account\CarrierConfiguration + * @return null|CarrierConfiguration */ public function getCarrierConfigurationByCarrier(AbstractCarrier $carrier): ?CarrierConfiguration { @@ -79,34 +64,33 @@ public function getCarrierConfigurationByCarrier(AbstractCarrier $carrier): ?Car return $carrierConfigurations ->filter( static function (CarrierConfiguration $carrierConfiguration) use ($carrier) { - return $carrier->getId() === $carrierConfiguration->getCarrier() - ->getId(); + return $carrier->getId() === $carrierConfiguration->getCarrier()->getId(); } ) ->first(); } /** - * @return \MyParcelNL\Sdk\src\Model\Account\CarrierConfiguration[]|\MyParcelNL\Sdk\src\Support\Collection + * @return CarrierConfiguration[]|Collection */ public function getCarrierConfigurations(): Collection { - return $this->carrier_configurations ?? new Collection(); + return $this->carrierConfigurations ?? new Collection(); } /** c * - * @return \MyParcelNL\Sdk\src\Model\Account\CarrierOptions[]|\MyParcelNL\Sdk\src\Support\Collection + * @return CarrierOptions[]|Collection */ public function getCarrierOptions(): Collection { - return $this->carrier_options ?? new Collection(); + return $this->carrierOptions ?? new Collection(); } /** - * @param \MyParcelNL\Sdk\src\Model\Carrier\AbstractCarrier $carrier + * @param AbstractCarrier $carrier * - * @return null|\MyParcelNL\Sdk\src\Model\Account\CarrierOptions + * @return null|CarrierOptions */ public function getCarrierOptionsByCarrier(AbstractCarrier $carrier): ?CarrierOptions { @@ -115,15 +99,14 @@ public function getCarrierOptionsByCarrier(AbstractCarrier $carrier): ?CarrierOp return $carrierOptions ->filter( static function (CarrierOptions $carrierOptions) use ($carrier) { - return $carrier->getId() === $carrierOptions->getCarrier() - ->getId(); + return $carrier->getId() === $carrierOptions->getCarrier()->getId(); } ) ->first(); } /** - * @return null|\MyParcelNL\Sdk\src\Model\Account\Shop + * @return null|Shop */ public function getShop(): ?Shop { @@ -131,21 +114,41 @@ public function getShop(): ?Shop } /** - * @param \MyParcelNL\Sdk\src\Support\Collection $settings + * @throws Exception + */ + public function getDropOffPoint(AbstractCarrier $carrier): ?DropOffPoint + { + $carrierConfiguration = $this->getCarrierConfigurationByCarrier($carrier); + + if (!$carrierConfiguration) { + return null; + } + + $dropOffPoint = $carrierConfiguration->getDefaultDropOffPoint(); + + if ($dropOffPoint && null === $dropOffPoint->getNumberSuffix()) { + $dropOffPoint->setNumberSuffix(''); + } + + return $dropOffPoint; + } + + /** + * @param Collection $settings * * @return void */ private function fillProperties(Collection $settings): void { - $shop = $settings->get('shop'); - $account = $settings->get('account'); - $carrierOptions = $settings->get('carrier_options'); - $carrierConfigurations = $settings->get('carrier_configurations'); - $this->shop = new Shop($shop); - $account['shops'] = [$shop]; - $this->account = new Account($account); - $this->carrier_options = (new Collection($carrierOptions))->mapInto(CarrierOptions::class); - $this->carrier_configurations = (new Collection($carrierConfigurations))->map(function (array $data) { + $shop = $settings->get('shop'); + $account = $settings->get('account'); + $carrierOptions = $settings->get('carrier_options'); + $carrierConfigurations = $settings->get('carrier_configurations'); + $this->shop = new Shop($shop); + $account['shops'] = [$shop]; + $this->account = new Account($account); + $this->carrierOptions = (new Collection($carrierOptions))->mapInto(CarrierOptions::class); + $this->carrierConfigurations = (new Collection($carrierConfigurations))->map(function (array $data) { return CarrierConfigurationFactory::create($data); }); } @@ -153,11 +156,11 @@ private function fillProperties(Collection $settings): void /** * Get the one instance of this class that is loaded or can be loaded. * - * @return \MyParcelNL\Magento\Model\Settings\AccountSettings + * @return AccountSettings */ public static function getInstance(): self { - if (null === static::$instance) { + if (!isset(static::$instance)) { static::$instance = new static(); } diff --git a/Model/Source/AgeCheckNo.php b/Model/Source/AgeCheckNo.php index 77ab06a8..aa917aa7 100755 --- a/Model/Source/AgeCheckNo.php +++ b/Model/Source/AgeCheckNo.php @@ -16,9 +16,8 @@ namespace MyParcelNL\Magento\Model\Source; use Magento\Framework\Data\OptionSourceInterface; -use Magento\Sales\Model\Order; -use MyParcelNL\Magento\Helper\Data; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierPostNL; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Sdk\Model\Carrier\CarrierPostNL; /** * @api @@ -26,20 +25,14 @@ */ class AgeCheckNo implements OptionSourceInterface { - /** - * @var Data - */ - static private $helper; + static private Config $configService; /** - * Insurance constructor. - * - * @param $order Order - * @param $helper Data + * @param Config $configService */ - public function __construct(Data $helper) + public function __construct(Config $configService) { - self::$helper = $helper; + self::$configService = $configService; } /** @@ -49,7 +42,8 @@ public function __construct(Data $helper) */ public function getDefault($option) { - $settings = self::$helper->getStandardConfig(CarrierPostNL::NAME, 'default_options'); + //throw new \Exception('this is not really a default'); + $settings = self::$configService->getCarrierConfig(CarrierPostNL::NAME, 'default_options'); return (bool) $settings[$option . '_active']; } diff --git a/Model/Source/AgeCheckYes.php b/Model/Source/AgeCheckYes.php index 064c47a0..f62debd5 100755 --- a/Model/Source/AgeCheckYes.php +++ b/Model/Source/AgeCheckYes.php @@ -17,8 +17,8 @@ use Magento\Framework\Data\OptionSourceInterface; use Magento\Sales\Model\Order; -use MyParcelNL\Magento\Helper\Data; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierPostNL; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Sdk\Model\Carrier\CarrierPostNL; /** * @api @@ -26,10 +26,7 @@ */ class AgeCheckYes implements OptionSourceInterface { - /** - * @var Data - */ - static private $helper; + static private Config $configService; /** * Insurance constructor. @@ -37,9 +34,9 @@ class AgeCheckYes implements OptionSourceInterface * @param $order Order * @param $helper Data */ - public function __construct(Data $helper) + public function __construct(Config $configService) { - self::$helper = $helper; + self::$configService = $configService; } /** @@ -49,7 +46,8 @@ public function __construct(Data $helper) */ public function hasDefault($option): bool { - $settings = self::$helper->getStandardConfig(CarrierPostNL::NAME, 'default_options'); + throw new \Exception('this is not really a default option'); + $settings = self::$configService->getCarrierConfig(CarrierPostNL::NAME, 'default_options'); return (bool) $settings[$option . '_active']; } diff --git a/Model/Source/CarrierInsurancePossibilities.php b/Model/Source/CarrierInsurancePossibilities.php index 11b4e0a2..eb57ac15 100755 --- a/Model/Source/CarrierInsurancePossibilities.php +++ b/Model/Source/CarrierInsurancePossibilities.php @@ -6,9 +6,9 @@ use Exception; use Magento\Framework\Data\OptionSourceInterface; -use MyParcelNL\Sdk\src\Factory\ConsignmentFactory; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; -use MyParcelNL\Sdk\src\Services\CountryCodes; +use MyParcelNL\Sdk\Factory\ConsignmentFactory; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; +use MyParcelNL\Sdk\Services\CountryCodes; class CarrierInsurancePossibilities implements OptionSourceInterface { diff --git a/Model/Source/DefaultOptions.php b/Model/Source/DefaultOptions.php index 71349428..42e8bc8c 100755 --- a/Model/Source/DefaultOptions.php +++ b/Model/Source/DefaultOptions.php @@ -13,164 +13,122 @@ namespace MyParcelNL\Magento\Model\Source; -use BadMethodCallException; use Exception; +use Magento\Framework\App\ObjectManager; +use Magento\Quote\Model\Quote; use Magento\Sales\Model\Order; -use MyParcelNL\Magento\Helper\Checkout; -use MyParcelNL\Magento\Helper\Data; +use MyParcelNL\Magento\Facade\Logger; use MyParcelNL\Magento\Model\Sales\Repository\PackageRepository; -use MyParcelNL\Sdk\src\Factory\ConsignmentFactory; -use MyParcelNL\Sdk\src\Factory\DeliveryOptionsAdapterFactory; -use MyParcelNL\Sdk\src\Model\Carrier\AbstractCarrier; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierFactory; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierPostNL; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Magento\Service\Weight; +use MyParcelNL\Sdk\Factory\ConsignmentFactory; +use MyParcelNL\Sdk\Factory\DeliveryOptionsAdapterFactory; +use MyParcelNL\Sdk\Model\Carrier\AbstractCarrier; +use MyParcelNL\Sdk\Model\Carrier\CarrierFactory; +use MyParcelNL\Sdk\Model\Carrier\CarrierPostNL; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; +use MyParcelNL\Sdk\Support\Str; class DefaultOptions { - // Maximum characters length of company name. - private const COMPANY_NAME_MAX_LENGTH = 50; - /** @deprecated */ - private const INSURANCE_BELGIUM = 'insurance_belgium_custom'; - /** @deprecated */ - private const INSURANCE_EU_AMOUNT_50 = 'insurance_eu_50'; - /** @deprecated */ - private const INSURANCE_EU_AMOUNT_500 = 'insurance_eu_500'; - /** @deprecated */ - private const INSURANCE_AMOUNT_100 = 'insurance_100'; - /** @deprecated */ - private const INSURANCE_AMOUNT_250 = 'insurance_250'; - /** @deprecated */ - private const INSURANCE_AMOUNT_500 = 'insurance_500'; - /** @deprecated */ - private const INSURANCE_AMOUNT_CUSTOM = 'insurance_custom'; - - private const INSURANCE_FROM_PRICE = 'insurance_from_price'; - private const INSURANCE_LOCAL_AMOUNT = 'insurance_local_amount'; - private const INSURANCE_BELGIUM_AMOUNT = 'insurance_belgium_amount'; - private const INSURANCE_EU_AMOUNT = 'insurance_eu_amount'; - private const INSURANCE_ROW_AMOUNT = 'insurance_row_amount'; - private const INSURANCE_PERCENTAGE = 'insurance_percentage'; - public const DEFAULT_OPTION_VALUE = 'default'; + private const INSURANCE_FROM_PRICE = 'insurance_from_price'; + private const INSURANCE_LOCAL_AMOUNT = 'insurance_local_amount'; + private const INSURANCE_BELGIUM_AMOUNT = 'insurance_belgium_amount'; + private const INSURANCE_EU_AMOUNT = 'insurance_eu_amount'; + private const INSURANCE_ROW_AMOUNT = 'insurance_row_amount'; + private const INSURANCE_PERCENTAGE = 'insurance_percentage'; + public const DEFAULT_OPTION_VALUE = 'default'; + + private Config $configService; + private $quote; + private array $chosenOptions; + private Weight $weightService; /** - * @var Data - */ - private static $helper; - - /** - * @var Order - */ - private static $order; - - /** - * @var array - */ - private static $chosenOptions; - - /** - * Insurance constructor. + * In Magento both Order and Quote have getData() and getShippingAddress() methods. + * However, they do not share an interface (?!), so we cannot type hint for both. + * As long as this class only needs to getData and getShippingAddress, we can use either. * - * @param Order $order - * @param Data $helper + * @param Order|Quote $quote */ - public function __construct(Order $order, Data $helper) + public function __construct($quote) { - self::$helper = $helper; - self::$order = $order; + $objectManager = ObjectManager::getInstance(); + $this->configService = $objectManager->get(Config::class); + $this->weightService = $objectManager->get(Weight::class); + $this->quote = $quote; try { - self::$chosenOptions = DeliveryOptionsAdapterFactory::create( - (array) json_decode($order->getData(Checkout::FIELD_DELIVERY_OPTIONS), true) + $this->chosenOptions = DeliveryOptionsAdapterFactory::create( + (array) json_decode($quote->getData(Config::FIELD_DELIVERY_OPTIONS), true, 4, JSON_THROW_ON_ERROR) )->toArray(); } catch (Exception $e) { - self::$chosenOptions = []; + $this->chosenOptions = []; } } /** * Get default of the option * - * @param string $option 'only_recipient'|'signature'|'return'|'large_format' - * @param string $carrier + * @param string $option 'only_recipient'|'signature'|'collect'|'receipt_code'|'return'|'large_format' + * @param string $carrier * * @return bool */ - public function hasDefault(string $option, string $carrier): bool + public function hasOptionSet(string $option, string $carrier): bool { if (AbstractConsignment::SHIPMENT_OPTION_LARGE_FORMAT === $option) { return $this->hasDefaultLargeFormat($carrier, $option); } // Check that the customer has already chosen this option in the checkout - if (is_array(self::$chosenOptions) && - array_key_exists('shipmentOptions', self::$chosenOptions) && - array_key_exists($option, self::$chosenOptions['shipmentOptions']) && - self::$chosenOptions['shipmentOptions'][$option] + if (array_key_exists('shipmentOptions', $this->chosenOptions) && + array_key_exists($option, $this->chosenOptions['shipmentOptions']) && + $this->chosenOptions['shipmentOptions'][$option] ) { return true; } - return false; - } - - /** - * @param string|null $company - * - * @return string|null - */ - public function getMaxCompanyName(?string $company): ?string - { - if ($company !== null && (strlen($company) >= self::COMPANY_NAME_MAX_LENGTH)) { - $company = substr($company, 0, 47) . '...'; - } - - return $company; + return $this->hasDefaultOption($carrier, $option); } /** * Get default value of options without price check * - * @param string $carrier - * @param string $option + * @param string $carrier + * @param string $option * * @return bool */ public function hasDefaultLargeFormat(string $carrier, string $option): bool { - $price = self::$order->getGrandTotal(); - $weight = self::$helper->convertToGrams(self::$order->getWeight()); + $price = $this->quote->getGrandTotal(); - $settings = self::$helper->getStandardConfig($carrier, 'default_options'); + $settings = $this->configService->getCarrierConfig($carrier, 'default_options'); $activeKey = "{$option}_active"; - if (isset($settings[$activeKey]) && - 'weight' === $settings[$activeKey] && - $weight >= PackageRepository::DEFAULT_LARGE_FORMAT_WEIGHT - ) { - return true; - } - - if (isset($settings[$activeKey]) && - 'price' === $settings[$activeKey] && - $price >= $settings["{$option}_from_price"] - ) { - return true; - } - - return false; + return isset($settings[$activeKey]) && + 'price' === $settings[$activeKey] && + $price >= $settings["{$option}_from_price"]; } /** - * @param string $carrier - * @param string $option + * @param string $carrier + * @param string $option * * @return bool */ - public function hasDefaultOptionsWithoutPrice(string $carrier, string $option): bool + public function hasDefaultOption(string $carrier, string $option): bool { - $settings = self::$helper->getStandardConfig($carrier, 'default_options'); + $settings = $this->configService->getCarrierConfig($carrier, 'default_options'); - return '1' === ($settings[$option . '_active'] ?? null); + if ('1' !== ($settings["{$option}_active"] ?? null)) { + return false; + } + + $fromPrice = $settings["{$option}_from_price"] ?? 0; + $orderAmount = $this->quote->getGrandTotal() ?? 0.0; + + return $fromPrice <= $orderAmount; } /** @@ -183,7 +141,7 @@ public function hasDefaultOptionsWithoutPrice(string $carrier, string $option): */ public function getDefaultInsurance(string $carrier): int { - $shippingAddress = self::$order->getShippingAddress(); + $shippingAddress = $this->quote->getShippingAddress(); $shippingCountry = $shippingAddress ? $shippingAddress->getCountryId() : AbstractConsignment::CC_NL; if (AbstractConsignment::CC_NL === $shippingCountry) { @@ -206,17 +164,17 @@ public function getDefaultInsurance(string $carrier): int */ private function getInsurance(string $carrierName, string $priceKey, string $shippingCountry): int { - $total = self::$order->getGrandTotal(); - $settings = self::$helper->getStandardConfig($carrierName, 'default_options'); + $total = $this->quote->getGrandTotal(); + $settings = $this->configService->getCarrierConfig($carrierName, 'default_options'); $totalAfterPercentage = $total * (($settings[self::INSURANCE_PERCENTAGE] ?? 0) / 100); - if (! isset($settings[$priceKey]) - || $settings[$priceKey] === 0 - || $totalAfterPercentage < $settings[self::INSURANCE_FROM_PRICE]) { + if (!isset($settings[$priceKey]) + || (int) $settings[$priceKey] === 0 + || $totalAfterPercentage < (int) $settings[self::INSURANCE_FROM_PRICE]) { return 0; } - $carrier = ConsignmentFactory::createByCarrierName($carrierName); + $carrier = ConsignmentFactory::createByCarrierName($carrierName); $insuranceTiers = $carrier->getInsurancePossibilities($shippingCountry); sort($insuranceTiers); @@ -241,7 +199,7 @@ private function getInsurance(string $carrierName, string $priceKey, string $shi */ public function getDigitalStampDefaultWeight(): string { - return self::$helper->getCarrierConfig('digital_stamp/default_weight', 'myparcelnl_magento_postnl_settings/'); + return $this->configService->getConfigValue('myparcelnl_magento_postnl_settings/digital_stamp/default_weight'); } /** @@ -251,11 +209,11 @@ public function getDigitalStampDefaultWeight(): string */ public function getPackageType(): int { - if (self::$chosenOptions) { - $keyIsPresent = array_key_exists('packageType', self::$chosenOptions); + if ($this->chosenOptions) { + $keyIsPresent = array_key_exists('packageType', $this->chosenOptions); if ($keyIsPresent) { - $packageType = self::$chosenOptions['packageType']; + $packageType = $this->chosenOptions['packageType']; return AbstractConsignment::PACKAGE_TYPES_NAMES_IDS_MAP[$packageType]; } @@ -267,38 +225,16 @@ public function getPackageType(): int /** * @return string */ - public function getCarrier(): string + public function getCarrierName(): string { - if (self::$chosenOptions) { - $keyIsPresent = array_key_exists('carrier', self::$chosenOptions); + if ($this->chosenOptions) { + $keyIsPresent = array_key_exists('carrier', $this->chosenOptions); if ($keyIsPresent) { - return self::$chosenOptions['carrier']; + return $this->chosenOptions['carrier']; } } - return CarrierPostNL::NAME; - } - - /** - * Get package type name as a string by default - * - * @return string - */ - public function getPackageTypeName(): string - { - $packageTypesMap = array_flip(AbstractConsignment::PACKAGE_TYPES_NAMES_IDS_MAP); - return $packageTypesMap[$this->getPackageType()]; - } - - /** - * TODO: In the future, when multiple carriers will be available for Rest of World shipments, replace PostNL with a setting for default carrier - * - * @return \MyParcelNL\Sdk\src\Model\Carrier\AbstractCarrier - * @throws \Exception - */ - public static function getDefaultCarrier(): AbstractCarrier - { - return CarrierFactory::createFromClass(CarrierPostNL::class); + return $this->configService->getDefaultCarrierName($this->quote->getShippingAddress()); } } diff --git a/Model/Source/DigitalStampWeightOptions.php b/Model/Source/DigitalStampWeightOptions.php index 50d648e3..a5803d4e 100755 --- a/Model/Source/DigitalStampWeightOptions.php +++ b/Model/Source/DigitalStampWeightOptions.php @@ -16,9 +16,8 @@ namespace MyParcelNL\Magento\Model\Source; use Magento\Framework\Data\OptionSourceInterface; -use Magento\Sales\Model\Order; -use MyParcelNL\Magento\Helper\Data; -use MyParcelNL\Sdk\src\Model\Carrier\CarrierPostNL; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Sdk\Model\Carrier\CarrierPostNL; /** * @api @@ -26,20 +25,14 @@ */ class DigitalStampWeightOptions implements OptionSourceInterface { - /** - * @var Data - */ - static private $helper; + static private $configService; /** - * Insurance constructor. - * - * @param $order Order - * @param $helper Data + * @param $configService Config */ - public function __construct(Data $helper) + public function __construct(Config $configService) { - self::$helper = $helper; + self::$configService = $configService; } /** @@ -49,7 +42,8 @@ public function __construct(Data $helper) */ public function getDefault($option): bool { - $settings = self::$helper->getStandardConfig(CarrierPostNL::NAME, 'options'); + throw new \Exception('again, not really a default'); + $settings = self::$configService->getCarrierConfig(CarrierPostNL::NAME, 'options'); return (bool) $settings[$option . '_active']; } @@ -61,14 +55,12 @@ public function getDefault($option): bool */ public function toOptionArray() { - $digitalStampOptions = [ + return [ ['value' => 0, 'label' => __('No standard weight')], ['value' => 20, 'label' => __('0 - 20 gram')], ['value' => 50, 'label' => __('20 - 50 gram')], ['value' => 200, 'label' => __('50 - 350 gram')], ['value' => 2000, 'label' => __('350 - 2000 gram')] ]; - - return $digitalStampOptions; } } diff --git a/Model/Source/ExportMode.php b/Model/Source/ExportMode.php index e7578374..c4c69923 100755 --- a/Model/Source/ExportMode.php +++ b/Model/Source/ExportMode.php @@ -6,6 +6,7 @@ use Magento\Framework\Data\OptionSourceInterface; use MyParcelNL\Magento\Model\Sales\TrackTraceHolder; +use MyParcelNL\Magento\Service\Config; class ExportMode implements OptionSourceInterface { @@ -16,11 +17,11 @@ public function toOptionArray(): array { return [ [ - 'value' => TrackTraceHolder::EXPORT_MODE_SHIPMENTS, + 'value' => Config::EXPORT_MODE_SHIPMENTS, 'label' => __('Export shipping details only') ], [ - 'value' => TrackTraceHolder::EXPORT_MODE_PPS, + 'value' => Config::EXPORT_MODE_PPS, 'label' => __('Export entire order') ] ]; @@ -32,8 +33,8 @@ public function toOptionArray(): array public function toArray(): array { return [ - 'shipments' => __(TrackTraceHolder::EXPORT_MODE_SHIPMENTS), - 'pps' => __(TrackTraceHolder::EXPORT_MODE_PPS) + 'shipments' => __(Config::EXPORT_MODE_SHIPMENTS), + 'pps' => __(Config::EXPORT_MODE_PPS) ]; } } diff --git a/Model/Source/LargeFormatOptions.php b/Model/Source/LargeFormatOptions.php index 65a6d235..deec92e7 100755 --- a/Model/Source/LargeFormatOptions.php +++ b/Model/Source/LargeFormatOptions.php @@ -5,25 +5,18 @@ namespace MyParcelNL\Magento\Model\Source; use Magento\Framework\Data\OptionSourceInterface; -use Magento\Sales\Model\Order; -use MyParcelNL\Magento\Helper\Data; +use MyParcelNL\Magento\Service\Config; class LargeFormatOptions implements OptionSourceInterface { - /** - * @var Data - */ - static private $helper; + static private Config $configService; /** - * Insurance constructor. - * - * @param $order Order - * @param $helper Data + * @param $configService Config */ - public function __construct(Data $helper) + public function __construct(Config $configService) { - self::$helper = $helper; + self::$configService = $configService; } /** @@ -35,7 +28,6 @@ public function toOptionArray() { return [ ['value' => 'price', 'label' => __('Price')], - ['value' => 'weight', 'label' => __('Weight')], ['value' => '0', 'label' => __('No')] ]; } @@ -49,7 +41,6 @@ public function toArray() { return [ 'price' => __('Price'), - 'weight' => __('Weight'), '0' => __('No') ]; } diff --git a/Model/Source/ShippingMethods.php b/Model/Source/ShippingMethods.php deleted file mode 100755 index 3dda3b46..00000000 --- a/Model/Source/ShippingMethods.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright 2010-2019 MyParcel - * @license http://creativecommons.org/licenses/by-nc-nd/3.0/nl/deed.en_US CC BY-NC-ND 3.0 NL - * @link https://github.com/myparcelnl/magento - * @since File available since Release 0.1.0 - */ - -namespace MyParcelNL\Magento\Model\Source; - -use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Shipping\Model\Config; - -class ShippingMethods implements \Magento\Framework\Option\ArrayInterface -{ - /** - * @var ScopeConfigInterface - */ - private $scopeConfig; - /** - * @var Config - */ - private $deliveryModelConfig; - - /** - * @param ScopeConfigInterface $scopeConfig - * @param Config $deliveryModelConfig - */ - public function __construct( - ScopeConfigInterface $scopeConfig, - Config $deliveryModelConfig - ) { - $this->scopeConfig = $scopeConfig; - $this->deliveryModelConfig = $deliveryModelConfig; - } - - /** - * Get all Drop off days - * - * @return array - */ - public function toOptionArray() - { - $methods = $this->deliveryModelConfig->getAllCarriers(); - - $aMethods = []; - - /** @var \Magento\OfflineShipping\Model\Carrier\Flatrate $method */ - foreach ($methods as $code => $method) { - $aMethods[] = ['value' => $code, 'label' => $code]; - } - - return $aMethods; - } -} diff --git a/Observer/CreateConceptAfterInvoice.php b/Observer/CreateConceptAfterInvoice.php index 8327ecaf..591742a5 100644 --- a/Observer/CreateConceptAfterInvoice.php +++ b/Observer/CreateConceptAfterInvoice.php @@ -23,17 +23,15 @@ use Magento\Framework\Model\AbstractModel; use Magento\Sales\Model\Order\Shipment\Track; use Magento\Sales\Model\ResourceModel\Order\Collection; -use MyParcelNL\Magento\Helper\Data; +use MyParcelNL\Magento\Model\Sales\MagentoCollection; use MyParcelNL\Magento\Model\Sales\MagentoOrderCollection; use MyParcelNL\Magento\Model\Sales\MagentoShipmentCollection; -use MyParcelNL\Magento\Model\Sales\TrackTraceHolder; -use MyParcelNL\Sdk\src\Exception\ApiException; -use MyParcelNL\Sdk\src\Exception\MissingFieldException; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Sdk\Exception\ApiException; +use MyParcelNL\Sdk\Exception\MissingFieldException; class CreateConceptAfterInvoice implements ObserverInterface { - const DEFAULT_LABEL_AMOUNT = 1; - protected $orderFactory; /** @@ -56,10 +54,7 @@ class CreateConceptAfterInvoice implements ObserverInterface */ private $orderCollection; - /** - * @var Data - */ - private $helper; + private Config $configService; /** * @var MagentoShipmentCollection @@ -78,12 +73,12 @@ class CreateConceptAfterInvoice implements ObserverInterface */ public function __construct(MagentoOrderCollection $orderCollection = null) { - $this->objectManager = ObjectManager::getInstance(); - $this->request = $this->objectManager->get('Magento\Framework\App\RequestInterface'); + $objectManager = ObjectManager::getInstance(); + //$this->request = $objectManager->get('Magento\Framework\App\RequestInterface'); $this->orderCollection = $orderCollection ?? new MagentoOrderCollection($this->objectManager, $this->request); - $this->helper = $this->objectManager->get('MyParcelNL\Magento\Helper\Data'); - $this->modelTrack = $this->objectManager->create('Magento\Sales\Model\Order\Shipment\Track'); - $this->orderFactory = $this->objectManager->get('\Magento\Sales\Model\Order'); + $this->configService = $objectManager->get(Config::class); + //$this->modelTrack = $objectManager->create('Magento\Sales\Model\Order\Shipment\Track'); + //$this->orderFactory = $objectManager->get('\Magento\Sales\Model\Order'); } /** @@ -96,7 +91,7 @@ public function __construct(MagentoOrderCollection $orderCollection = null) */ public function execute(Observer $observer): self { - if ($this->helper->getGeneralConfig('print/create_concept_after_invoice')) { + if ($this->configService->getGeneralConfig('print/create_concept_after_invoice')) { $order = $observer ->getEvent() ->getInvoice() @@ -133,7 +128,7 @@ private function exportAccordingToMode($orderIds) ->setOptionsFromParameters() ->setNewMagentoShipment(); - if (TrackTraceHolder::EXPORT_MODE_PPS === $this->orderCollection->getExportMode()) { + if (Config::EXPORT_MODE_PPS === $this->configService->getExportMode()) { $this->orderCollection->setFulfilment(); return $this; @@ -151,12 +146,12 @@ private function exportAccordingToMode($orderIds) /** * @param $orderIds int[] */ - private function addOrdersToCollection($orderIds) + private function addOrdersToCollection($orderIds): void { /** * @var Collection $collection */ - $collection = $this->objectManager->get(MagentoOrderCollection::PATH_MODEL_ORDER); + $collection = $this->objectManager->get(MagentoCollection::PATH_MODEL_ORDER_COLLECTION); $collection->addAttributeToFilter('entity_id', ['in' => $orderIds]); $this->orderCollection->setOrderCollection($collection); } diff --git a/Observer/NewShipment.php b/Observer/NewShipment.php index 351eb09e..8d9aa73d 100755 --- a/Observer/NewShipment.php +++ b/Observer/NewShipment.php @@ -15,11 +15,15 @@ namespace MyParcelNL\Magento\Observer; use Magento\Framework\App\ObjectManager; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Controller\Result\RedirectFactory; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; +use Magento\Framework\Message\Manager; use Magento\Sales\Model\Order\Shipment; use MyParcelNL\Magento\Model\Sales\MagentoOrderCollection; use MyParcelNL\Magento\Model\Sales\TrackTraceHolder; +use MyParcelNL\Magento\Service\Config; class NewShipment implements ObserverInterface { @@ -45,11 +49,6 @@ class NewShipment implements ObserverInterface */ private $request; - /** - * @var \Magento\Sales\Model\Order\Shipment\Track - */ - private $modelTrack; - /** * @var MagentoOrderCollection */ @@ -58,7 +57,7 @@ class NewShipment implements ObserverInterface /** * @var \MyParcelNL\Magento\Helper\Data */ - private $helper; + private $configService; /** * NewShipment constructor. @@ -68,12 +67,11 @@ class NewShipment implements ObserverInterface public function __construct(MagentoOrderCollection $orderCollection = null) { $this->objectManager = ObjectManager::getInstance(); - $this->request = $this->objectManager->get('Magento\Framework\App\RequestInterface'); - $this->redirectFactory = $this->objectManager->get('Magento\Framework\Controller\Result\RedirectFactory'); - $this->messageManager = $this->objectManager->get('Magento\Framework\Message\Manager'); + $this->request = $this->objectManager->get(RequestInterface::class); + $this->redirectFactory = $this->objectManager->get(RedirectFactory::class); + $this->messageManager = $this->objectManager->get(Manager::class); $this->orderCollection = $orderCollection ?? new MagentoOrderCollection($this->objectManager, $this->request); - $this->helper = $this->objectManager->get('MyParcelNL\Magento\Helper\Data'); - $this->modelTrack = $this->objectManager->create('Magento\Sales\Model\Order\Shipment\Track'); + $this->configService = $this->objectManager->get(Config::class); } /** @@ -112,7 +110,7 @@ public function execute(Observer $observer) private function setMagentoAndMyParcelTrack(Shipment $shipment): void { $options = $this->orderCollection->setOptionsFromParameters() - ->getOptions(); + ->getOptions(); if (isset($options['carrier']) && false === $options['carrier']) { unset($options['carrier']); @@ -127,7 +125,7 @@ private function setMagentoAndMyParcelTrack(Shipment $shipment): void while ($i <= $amount) { // Set MyParcel options - $trackTraceHolder = (new TrackTraceHolder($this->objectManager, $this->helper, $shipment->getOrder())) + $trackTraceHolder = (new TrackTraceHolder($this->objectManager, $shipment->getOrder())) ->createTrackTraceFromShipment($shipment); $trackTraceHolder->convertDataFromMagentoToApi($trackTraceHolder->mageTrack, $options); @@ -151,7 +149,7 @@ private function setMagentoAndMyParcelTrack(Shipment $shipment): void ); } - if (TrackTraceHolder::EXPORT_MODE_PPS === $this->orderCollection->getExportMode()) { + if (Config::EXPORT_MODE_PPS === $this->configService->getExportMode()) { $this->exportEntireOrder($shipment); $this->updateTrackGrid($shipment, true); @@ -186,7 +184,7 @@ private function exportEntireOrder($shipment): void /** * @var \Magento\Sales\Model\ResourceModel\Order\Collection $collection */ - $collection = $this->objectManager->get(MagentoOrderCollection::PATH_MODEL_ORDER); + $collection = $this->objectManager->get(MagentoOrderCollection::PATH_MODEL_ORDER_COLLECTION); $collection->addAttributeToFilter('entity_id', ['in' => $orderId]); $this->orderCollection->setOrderCollection($collection); $this->orderCollection->setFulfilment(); @@ -210,8 +208,8 @@ private function updateTrackGrid($shipment, $entireOrder): void } $shipment->getOrder() - ->setData('track_status', $aHtml['track_status']) - ->setData('track_number', $aHtml['track_number']) - ->save(); + ->setData('track_status', $aHtml['track_status']) + ->setData('track_number', $aHtml['track_number']) + ->save(); } } diff --git a/Observer/SalesOrderStatusHistoryObserver.php b/Observer/SalesOrderStatusHistoryObserver.php index d879e961..a1429506 100644 --- a/Observer/SalesOrderStatusHistoryObserver.php +++ b/Observer/SalesOrderStatusHistoryObserver.php @@ -9,25 +9,18 @@ use Magento\Framework\Event\ObserverInterface; use Magento\Sales\Model\Order; use Magento\Sales\Model\Order\Status\History; -use MyParcelNL\Sdk\src\Collection\Fulfilment\OrderNotesCollection; -use MyParcelNL\Sdk\src\Model\Fulfilment\OrderNote; -use MyParcelNL\Magento\Helper\Data; +use MyParcelNL\Magento\Service\Config; +use MyParcelNL\Sdk\Collection\Fulfilment\OrderNotesCollection; +use MyParcelNL\Sdk\Model\Fulfilment\OrderNote; class SalesOrderStatusHistoryObserver implements ObserverInterface { - /** - * @var \MyParcelNL\Magento\Helper\Data - */ - private $helper; - - /** - * @var \Magento\Framework\App\ObjectManager - */ - private $objectManager; + private Config $configService; + private ObjectManager $objectManager; public function __construct() { - $this->objectManager = ObjectManager::getInstance(); - $this->helper = $this->objectManager->get(Data::class); + $this->objectManager = ObjectManager::getInstance(); + $this->configService = $this->objectManager->get(Config::class); } /** @@ -57,7 +50,7 @@ public function execute(Observer $observer): self return $this; } - (new OrderNotesCollection())->setApiKey($this->helper->getApiKey()) + (new OrderNotesCollection())->setApiKey($this->configService->getApiKey()) ->push( new OrderNote([ 'orderUuid' => $uuid, diff --git a/Plugin/Magento/Sales/Api/Data/OrderExtension.php b/Plugin/Magento/Sales/Api/Data/OrderExtension.php index 3ffa733e..ed298fee 100644 --- a/Plugin/Magento/Sales/Api/Data/OrderExtension.php +++ b/Plugin/Magento/Sales/Api/Data/OrderExtension.php @@ -13,7 +13,7 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\HTTP\PhpEnvironment\Request; -use MyParcelNL\Sdk\src\Support\Arr; +use MyParcelNL\Sdk\Support\Arr; class OrderExtension { diff --git a/Service/Config.php b/Service/Config.php new file mode 100644 index 00000000..02c72adc --- /dev/null +++ b/Service/Config.php @@ -0,0 +1,231 @@ + self::XML_PATH_POSTNL_SETTINGS, + CarrierDHLForYou::NAME => self::XML_PATH_DHLFORYOU_SETTINGS, + CarrierDHLEuroplus::NAME => self::XML_PATH_DHLEUROPLUS_SETTINGS, + CarrierDHLParcelConnect::NAME => self::XML_PATH_DHLPARCELCONNECT_SETTINGS, + CarrierUPS::NAME => self::XML_PATH_UPS_SETTINGS, + CarrierDPD::NAME => self::XML_PATH_DPD_SETTINGS, + ]; + + /** + * @var ModuleListInterface + */ + private $moduleList; + /** + * @var CheckApiKeyWebService + */ + private $checkApiKeyWebService; + + /** + * @param Context $context + * @param ModuleListInterface $moduleList + * @param CheckApiKeyWebService $checkApiKeyWebService + */ + public function __construct( + Context $context, + ModuleListInterface $moduleList, + CheckApiKeyWebService $checkApiKeyWebService + ) + { + parent::__construct($context); + $this->moduleList = $moduleList; + $this->checkApiKeyWebService = $checkApiKeyWebService; + } + + /** + * Get settings by field + * + * @param $field + * @param null $storeId + * + * @return mixed + */ + public function getConfigValue($field, $storeId = null) + { + return $this->scopeConfig->getValue($field, ScopeInterface::SCOPE_STORE, $storeId); + } + + /** + * @param string $path + * @param string $key + * @return bool + */ + public function getBoolConfig(string $path, string $key): bool + { + return '1' === $this->getConfigValue("$path$key"); + } + + public function getFloatConfig($path, $key): float + { + return (float) $this->getConfigValue("$path$key"); + } + + public function getTimeConfig(string $carrier, string $key): string + { + $timeAsString = str_replace(',', ':', (string) $this->getConfigValue("$carrier$key")); + $timeComponents = explode(':', $timeAsString ?? ''); + if (count($timeComponents) >= 3) { + [$hours, $minutes] = $timeComponents; + $timeAsString = $hours . ':' . $minutes; + } + + return $timeAsString; + } + + /** + * @param $path + * @param $key + * @return int + */ + public function getIntegerConfig($path, $key): int + { + return (int) $this->getConfigValue("$path$key"); + } + + /** + * Get setting for carrier + * + * @param string $carrier + * @param string $code + * @param null $storeId + * + * @return mixed + */ + public function getCarrierConfig(string $carrier, string $code = '', $storeId = null) + { + $path = self::CARRIERS_XML_PATH_MAP[$carrier] ?? null; + + if (null === $path) { + return null; + } + + return $this->getConfigValue("$path$code", $storeId); + } + + + /** + * Get general settings + * + * @param string $code + * @param null|int $storeId + * + * @return mixed + */ + public function getGeneralConfig(string $code = '', int $storeId = null) + { + return $this->getConfigValue(self::XML_PATH_GENERAL . $code, $storeId); + } + + public function getMagentoCarrierConfig(string $code = '', int $storeId = null) + { + return $this->getConfigValue(self::XML_PATH_MAGENTO_CARRIER . $code, $storeId); + } + + /** + * @return string|null + */ + public function getExportMode(): ?string + { + return $this->getGeneralConfig('print/export_mode'); + } + + /** + * @param Address|null $address + * @return string the carrier name configured for this address + */ + public function getDefaultCarrierName(?Address $address): string + { + return 'postnl'; + // todo make config value that allows carriers per country / region / etc, select it here based on address. + return $this->getConfigValue(self::XML_PATH_GENERAL . "default_carrier/$country"); + } + + // TODO everything below here must be refactored out + + /** + * Get the version number of the installed module + * + * @return string + */ + public function getVersion(): string + { + $moduleCode = self::MODULE_NAME; + $moduleInfo = $this->moduleList->getOne($moduleCode); + + return (string) $moduleInfo['setup_version']; + } + + /** + * Check if api key is correct + */ + public function apiKeyIsCorrect(): bool + { + $apiKey = $this->getApiKey(); + + return $this->checkApiKeyWebService->setApiKey($apiKey) + ->apiKeyIsCorrect() + ; + } + + /** + * @return null|string + */ + public function getApiKey(): ?string + { + return $this->getGeneralConfig('api/key'); + } + + /** + * Check if global API Key isset + * + * @return bool + */ + public function hasApiKey(): bool + { + $apiKey = $this->getApiKey(); + + return isset($apiKey); + } +} diff --git a/Service/Dating.php b/Service/Dating.php new file mode 100644 index 00000000..e59570ca --- /dev/null +++ b/Service/Dating.php @@ -0,0 +1,39 @@ +format('Y-m-d')); + } catch (Exception $e) { + return null; + } + + $currentDate = strtotime(date('Y-m-d')); + + if ($deliveryDate <= $currentDate) { + return date($format, strtotime('now +1 day')); + } + + return date($format, $deliveryDate); + } +} diff --git a/Service/DeliveryCosts.php b/Service/DeliveryCosts.php new file mode 100644 index 00000000..a132595e --- /dev/null +++ b/Service/DeliveryCosts.php @@ -0,0 +1,199 @@ + 32, + 'country_part_of' => 16, + 'package_type' => 8, + 'carrier_name' => 4, + 'maximum_weight' => 2, + 'unspecified' => 1, // when a condition is not specified, it should be considered met, but least specific + ]; + + public function __construct(Weight $weight, Config $config, Tax $tax) + { + $this->weight = $weight; + $this->config = $config; + $this->tax = $tax; + } + + /** + * Returns the base price with Magento tax settings applied, for displaying to the client. + * + * @param Quote $quote to get the weight and default carrier, package type and country, and calculate tax + * @param string|null $carrierName override carrier from quote if you want + * @param string|null $packageTypeName override package type from quote if you want + * @param string|null $countryCode override country from quote->shippingAddress if you want + * @return float + * @uses DeliveryCosts::getBasePrice() + */ + public function getBasePriceForClient(Quote $quote, ?string $carrierName = null, ?string $packageTypeName = null, ?string $countryCode = null): float + { + $price = $this->getBasePrice($quote, $carrierName, $packageTypeName, $countryCode); + + return $this->tax->shippingPrice($price, $quote); + } + + /** + * Returns the base price bare, without any tax settings applied, used inside Magento (it will apply tax settings later). + * + * @param Quote $quote to get the weight and default carrier, package type and country, and calculate tax + * @param string|null $carrierName override carrier from quote if you want + * @param string|null $packageTypeName override package type from quote if you want + * @param string|null $countryCode override country from quote->shippingAddress if you want + * @return float + */ + public function getBasePrice(Quote $quote, ?string $carrierName = null, ?string $packageTypeName = null, ?string $countryCode = null): float + { + if ($this->isFreeShippingAvailable($quote)) { + return 0.0; + } + $defaultOptions = new DefaultOptions($quote); + + $carrierName = $carrierName ?? $defaultOptions->getCarrierName(); + $packageType = AbstractConsignment::PACKAGE_TYPES_NAMES_IDS_MAP[$packageTypeName] ?? $defaultOptions->getPackageType(); + $countryCode = $countryCode ?? $quote->getShippingAddress()->getCountryId() ?? AbstractConsignment::CC_NL; + $weight = $this->weight->getEmptyPackageWeightInGrams($packageType) + + $this->weight->getQuoteWeightInGrams($quote); + + return $this->calculate([ + 'carrier_name' => $carrierName, + 'package_type' => $packageType, + 'country' => $countryCode, + 'weight' => $weight, + ]); + } + + /** + * Calculates the actual price based on the conditions, using self::CONDITIONS to determine the hierarchy. + * If no conditions are met, the default shipping cost from the Magento carrier settings will be used. + * + * @param array $conditions + * @return float + */ + private function calculate(array $conditions): float + { + if (!isset($conditions['carrier_name'], $conditions['package_type'], $conditions['country'], $conditions['weight'])) { + throw new \InvalidArgumentException('Missing required conditions'); + } + + $json = $this->config->getGeneralConfig('matrix/delivery_costs'); + if (null === $json) { + return (float) $this->config->getMagentoCarrierConfig('shipping_cost'); + } + + $matrix = json_decode($json, true, 8) ?? []; + $return = []; + + foreach ($matrix as $definition) { + if (!isset($definition['conditions']) || !is_array(($definedConditions = $definition['conditions']))) { + continue; + } + + // calculate relative weight of this option (definition) using hierarchy points by walking through the conditions + $totalPoints = 0; + foreach (self::CONDITIONS as $condition => $points) { + if ('unspecified' === $condition) { + continue; + } + // consider unspecified conditions as valid + if (!isset($definedConditions[$condition])) { + $totalPoints += self::CONDITIONS['unspecified']; + continue; + } + switch ($condition) { + case 'maximum_weight': + if ((float) $conditions['weight'] <= (float) $definedConditions[$condition]) { + $totalPoints += $points; + continue 2; + } + break; + case 'country_part_of': + if (self::isCountryPartOf($conditions['country'], $definedConditions[$condition])) { + $totalPoints += $points; + continue 2; + } + break; + default: + if ($conditions[$condition] === $definedConditions[$condition]) { + $totalPoints += $points; + continue 2; + } + } + // when condition is not met, don’t count it + continue 2; + } + + $return[] = [ + 'definition' => $definition, + 'points' => $totalPoints, + ]; + } + + if (0 === count($return)) { + // when nothing matched, act as a flat rate using the provided shipping cost + return (float) $this->config->getMagentoCarrierConfig('shipping_cost'); + } + + // sort by points, highest first, then return the price from the first result + usort($return, static function ($a, $b) { + return $b['points'] <=> $a['points']; + }); + + //file_put_contents('/Applications/MAMP/htdocs/magento246/var/log/joeri.log', "--conditions--\n" . var_export($conditions, true) . "\n" . "--WEIGHTED--\n" . var_export($return, true) . "\n", FILE_APPEND); + + return (float) $return[0]['definition']['price']; + } + + /** + * @param string $needle the country code (2-letter ISO) + * @param string|array $haystackDefinition string denoting an existing array or array of countries (2-letter ISO) + * @return bool whether the country is part of the haystack + */ + public static function isCountryPartOf(string $needle, $haystackDefinition): bool + { + switch ($haystackDefinition) { + case is_array($haystackDefinition):// TODO make country_part_of an array, possibly? + return in_array($needle, $haystackDefinition, true); + case CountryCodes::ZONE_EU: + return in_array($needle, CountryCodes::EU_COUNTRIES); + case CountryCodes::ZONE_ROW: + return !in_array($needle, CountryCodes::EU_COUNTRIES); + default: + return $needle === $haystackDefinition; + } + } + + + /** + * @param float $price in Euros + * + * @return int price in cents + */ + public static function getPriceInCents(float $price): int + { + return (int) ($price * 100); + } +} diff --git a/Service/NeedsQuoteProps.php b/Service/NeedsQuoteProps.php new file mode 100644 index 00000000..c183a1b9 --- /dev/null +++ b/Service/NeedsQuoteProps.php @@ -0,0 +1,158 @@ +getAllItems(); + if (!$items) { + return null; + } + + /** @var \Magento\Quote\Model\Quote\Item $firstItem */ + $firstItem = reset($items); + if (!$firstItem) { + return null; + } + + $quote = $firstItem->getQuote(); + if (!($quote instanceof Quote)) { + return null; + } + + return $quote; + } + + protected function getQuoteFromCurrentSession(): ?Quote + { + $session = ObjectManager::getInstance()->get(Session::class); + $quote = $session->getQuote(); + + if (!($quote instanceof Quote)) { + return null; + } + + /** + * The available shipping methods can be found in the quote from the session, so force re-checking + * of the availability of free shipping now, by unsetting the session variable. + */ + $session->unsMyParcelFreeShippingIsAvailable(); + + return $quote; + } + + protected function getDeliveryOptionsFromQuote(Quote $quote): AbstractDeliveryOptionsAdapter + { + if (isset($this->deliveryOptions)) { + return $this->deliveryOptions; + } + + $deliveryOptions = $quote->getData(Config::FIELD_DELIVERY_OPTIONS); + + if (is_string($deliveryOptions)) { + try { + $this->deliveryOptions = DeliveryOptionsAdapterFactory::create(json_decode($deliveryOptions, true, 512, JSON_THROW_ON_ERROR)); + } catch (\Throwable $e) { + Logger::log('warning', "Failed to retrieve delivery options from quote {$quote->getId()}", (array) $deliveryOptions); + $this->deliveryOptions = new DeliveryOptionsV3Adapter(); + } + } else { + $this->deliveryOptions = new DeliveryOptionsV3Adapter(); + } + + return $this->deliveryOptions; + } + + /** + * @param Quote $quote + * @return array indexed array of ShippingMethodInterface objects + * @throws LocalizedException + */ + protected function getShippingMethodsFromQuote(Quote $quote): array + { + $quoteId = $quote->getId(); + + try { + $shippingMethodManagement = ObjectManager::getInstance()->get(ShippingMethodManagementInterface::class); + $shippingMethods = $shippingMethodManagement->getList($quoteId); + + $methods = []; + foreach ($shippingMethods as $method) { + /** @var ShippingMethodInterface $method */ + $methods[] = $method; + } + } catch (\Exception $exception) { + throw new LocalizedException(__($exception->getMessage())); + } + + return $methods; + } + + /** + * If free shipping is available for this quote, will return true. + * + * @param Quote $quote + * @return bool + */ + public function isFreeShippingAvailable(Quote $quote): bool + { + $session = ObjectManager::getInstance()->get(Session::class); + + // NULL when not set, boolean value when set + $freeShippingIsAvailable = $session->getMyParcelFreeShippingIsAvailable(); + + if (null !== $freeShippingIsAvailable) { + return $freeShippingIsAvailable; + } + + $freeShippingIsAvailable = false; + + try { + $shippingMethods = $this->getShippingMethodsFromQuote($quote); + + foreach ($shippingMethods as $method) { + /** @var ShippingMethodInterface $method */ + if ('freeshipping' === $method->getCarrierCode()) { + $freeShippingIsAvailable = true; + break; + } + } + } catch (LocalizedException $e) { + Logger::critical($e->getMessage()); + } + + $session->setMyParcelFreeShippingIsAvailable($freeShippingIsAvailable); + + return $freeShippingIsAvailable; + } +} diff --git a/Service/Tax.php b/Service/Tax.php new file mode 100644 index 00000000..d6111ef3 --- /dev/null +++ b/Service/Tax.php @@ -0,0 +1,108 @@ +taxCalculation = $taxCalculation; + + // Tax -> Tax Classes -> Tax Class for Shipping + $this->shippingTaxClass = (int) $config->getConfigValue('tax/classes/shipping_tax_class'); + // Tax -> Calculation Settings -> Shipping Prices: are prices entered as tax-inclusive or exclusive? Defaults to inclusive + $this->priceIncludesTax = '0' !== $config->getConfigValue('tax/calculation/shipping_includes_tax'); + // Tax -> Shopping Cart Display Settings -> Display Shipping Amount, default to display including tax + $this->displayIncluding = self::DISPLAY_EXCLUDING_TAX !== $config->getConfigValue('tax/cart_display/shipping'); + } + + + /** + * Get shipping tax options from Magento and apply them to the price. + * Prices display including tax unless specifically set to excluding tax in Magento admin. + * Optionally supply boolean to force excluding (false) or including (true) vat + * + * @param float $price the shipping price you want altered for tax settings + * @param Quote $quote + * @param bool|null $vat + * @return float + */ + public function shippingPrice(float $price, Quote $quote, ?bool $vat = null): float + { + $shippingTaxRate = $this->getShippingTaxRate($quote); + $including = $vat ?? $this->displayIncluding; + +// Debugging +// $dump = $this->taxRates + [ +// 'shippingTaxClass' => $this->shippingTaxClass, +// 'priceIncludesTax' => $this->priceIncludesTax, +// 'displayIncluding' => $this->displayIncluding, +// 'price' => $price, +// ]; +// file_put_contents('/Applications/MAMP/htdocs/magento246/var/log/joeri.log', 'SHIPPING TAX RATE (JOERIDEBUG): ' . var_export($dump, true) . "\n", FILE_APPEND); + + if ($this->priceIncludesTax === $including) { + return $price; + } + + $taxAmount = $this->taxCalculation->calcTaxAmount($price, $shippingTaxRate, $this->priceIncludesTax, false); + + if ($this->priceIncludesTax && !$including) { + return $price - $taxAmount; + } + + // !$pricesIncludeTax && $including + return $price + $taxAmount; + } + + private function getShippingTaxRate(Quote $quote) + { + // if the quote has changed, we need to recalculate the tax rates + if (!isset($this->quote) || $this->quote->getId() !== $quote->getId()) { + $this->quote = $quote; + // getTaxRates(...) ultimately returns an array of available rates holding (int) ‘tax class id’ => (float) ‘rate as percentage’ + $this->taxRates = $this->taxCalculation->getTaxRates($quote->getBillingAddress()->toArray(), $quote->getShippingAddress()->toArray(), $quote->getCustomerTaxClassId()); + } + + return $this->taxRates[$this->shippingTaxClass] ?? 0.0; + } + + /** + * @param float $price + * @param Quote $quote + * @return float the price excluding VAT, accounting for settings in Magento admin + */ + public function excludingVat(float $price, Quote $quote): float + { + return $this->shippingPrice($price, $quote, false); + } + + public function includingVat(float $price, Quote $quote): float + { + return $this->shippingPrice($price, $quote, true); + } + + public function addVatToExVatPrice(float $price, Quote $quote): float + { + $shippingTaxRate = $this->getShippingTaxRate($quote); + $taxAmount = $this->taxCalculation->calcTaxAmount($price, $shippingTaxRate, false, false); + + return $price + $taxAmount; + } +} diff --git a/Service/Weight.php b/Service/Weight.php new file mode 100644 index 00000000..608eaf00 --- /dev/null +++ b/Service/Weight.php @@ -0,0 +1,80 @@ +config = $config; + } + + /** + * Returns weight in grams based on configured weight indication, defaults to self::DEFAULT_WEIGHT + * + * @param null|float $weight + * + * @return int + */ + public function convertToGrams(?float $weight): int + { + $weightType = $this->config->getGeneralConfig('print/weight_indication'); + + if ('kilo' === $weightType) { + return (int) ($weight * 1000) ?: self::DEFAULT_WEIGHT; + } + + return (int) $weight ?: self::DEFAULT_WEIGHT; + } + + /** + * Returns configured empty weight in grams, defaults to 0 when not found or not set + * + * @param string $packageType + * @return int + */ + public function getEmptyPackageWeightInGrams(int $packageType): int + { + if (!in_array($packageType, AbstractConsignment::PACKAGE_TYPES_IDS, true)) { + return 0; + } + // todo if this array_flip is used in multiple places, consider making a method or something else + $packageTypeName = array_flip(AbstractConsignment::PACKAGE_TYPES_NAMES_IDS_MAP)[$packageType]; + + return (int) $this->config->getGeneralConfig("empty_package_weight/$packageTypeName"); + } + + /** + * Returns weight of products in Quote in grams, skips products with quantity < 1 or weight <= 0 + * + * @param Quote $quote + * @return int + */ + public function getQuoteWeightInGrams(Quote $quote): int + { + $products = $quote->getAllItems(); + $weight = 0; + + foreach ($products as $product) { + $productQty = (float) $product->getQty(); + $productWeight = (float) $product->getWeight(); + if ($productQty < 1 || $productWeight <= 0) { + continue; + } + + $weight += $productWeight * $productQty; + } + + return $this->convertToGrams($weight); + } +} diff --git a/Services/Normalizer/ConsignmentNormalizer.php b/Services/Normalizer/ConsignmentNormalizer.php deleted file mode 100644 index 215768a9..00000000 --- a/Services/Normalizer/ConsignmentNormalizer.php +++ /dev/null @@ -1,31 +0,0 @@ -data = $data; - } - - public function normalize(): array - { - $data = $this->data; - $data['carrier'] = $data['carrier'] ?? PostNLConsignment::CARRIER_NAME; - $data['deliveryType'] = $data['deliveryType'] ?? AbstractConsignment::DELIVERY_TYPE_STANDARD_NAME; - $data['package_type'] = $data['package_type'] ?? AbstractConsignment::PACKAGE_TYPE_PACKAGE_NAME; - - return $data; - } -} diff --git a/Setup/UpgradeData.php b/Setup/UpgradeData.php index 326d0990..2e3de2f7 100644 --- a/Setup/UpgradeData.php +++ b/Setup/UpgradeData.php @@ -26,14 +26,14 @@ use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\UpgradeDataInterface; -use MyParcelNL\Magento\Helper\Data; +use MyParcelNL\Magento\Service\Config; use MyParcelNL\Magento\Setup\Migrations\ReplaceDpzRange; use MyParcelNL\Magento\Setup\Migrations\ReplaceFitInMailbox; use MyParcelNL\Magento\Setup\Migrations\ReplaceDisableCheckout; use MyParcelNL\Magento\Model\Source\FitInMailboxOptions; use Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend; -use MyParcelNL\Sdk\src\Factory\ConsignmentFactory; -use MyParcelNL\Sdk\src\Services\CountryCodes; +use MyParcelNL\Sdk\Factory\ConsignmentFactory; +use MyParcelNL\Sdk\Services\CountryCodes; /** * Upgrade Data script @@ -777,7 +777,7 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface continue; } - foreach (Data::CARRIERS_XML_PATH_MAP as $carrierName => $carrierPath) { + foreach (Config::CARRIERS_XML_PATH_MAP as $carrierName => $carrierPath) { echo "\nMigrating $carrierName for scope $scope ($scopeId)"; /** * update the carrier specific date settings to a single setting for later diff --git a/Ui/Component/Listing/Column/TrackActions.php b/Ui/Component/Listing/Column/TrackActions.php index 5a6b1920..087cf874 100755 --- a/Ui/Component/Listing/Column/TrackActions.php +++ b/Ui/Component/Listing/Column/TrackActions.php @@ -8,44 +8,33 @@ use Magento\Framework\View\Element\UiComponent\ContextInterface; use Magento\Framework\View\Element\UiComponentFactory; use Magento\Ui\Component\Listing\Columns\Column; -use MyParcelNL\Magento\Helper\Data; -use MyParcelNL\Magento\Model\Sales\TrackTraceHolder; +use MyParcelNL\Magento\Service\Config; -/** - * Class DepartmentActions - */ class TrackActions extends Column { - const NAME = 'track_actions'; + public const NAME = 'track_actions'; - /** - * @var \MyParcelNL\Magento\Helper\Data - */ - private $helper; + private Config $configService; + private UrlInterface $urlBuilder; /** - * @var UrlInterface - */ - private $urlBuilder; - - /** - * @param ContextInterface $context - * @param UiComponentFactory $uiComponentFactory - * @param UrlInterface $urlBuilder - * @param \MyParcelNL\Magento\Helper\Data $helper - * @param array $components - * @param array $data + * @param ContextInterface $context + * @param UiComponentFactory $uiComponentFactory + * @param UrlInterface $urlBuilder + * @param array $components + * @param array $data */ public function __construct( - ContextInterface $context, + ContextInterface $context, UiComponentFactory $uiComponentFactory, - UrlInterface $urlBuilder, - array $components = [], - array $data = [] - ) { - $this->urlBuilder = $urlBuilder; - $objectManager = ObjectManager::getInstance(); - $this->helper = $objectManager->create(Data::class); + UrlInterface $urlBuilder, + array $components = [], + array $data = [] + ) + { + $this->urlBuilder = $urlBuilder; + $objectManager = ObjectManager::getInstance(); + $this->configService = $objectManager->get(Config::class); parent::__construct($context, $uiComponentFactory, $components, $data); } @@ -59,14 +48,14 @@ public function __construct( */ public function prepareDataSource(array $dataSource) { - if (! isset($dataSource['data']['items'])) { + if (!isset($dataSource['data']['items'])) { return $dataSource; } - $orderManagementActivated = TrackTraceHolder::EXPORT_MODE_PPS === $this->helper->getExportMode(); + $orderManagementActivated = Config::EXPORT_MODE_PPS === $this->configService->getExportMode(); foreach ($dataSource['data']['items'] as &$item) { - if (! key_exists(ShippingStatus::NAME, $item)) { + if (!array_key_exists(ShippingStatus::NAME, $item)) { throw new LocalizedException( __( 'Note that the installation of the extension was not successful. Some columns have not been added to the database. The installation should be reversed. Use the following command to reinstall the module: DELETE FROM `setup_module` WHERE `setup_module`.`module` = \'MyParcelNL_Magento\'' @@ -75,8 +64,8 @@ public function prepareDataSource(array $dataSource) continue; } - if (! isset($item[ShippingStatus::NAME])) { - if (TrackTraceHolder::EXPORT_MODE_PPS === $this->helper->getExportMode()) { + if (!isset($item[ShippingStatus::NAME])) { + if (Config::EXPORT_MODE_PPS === $this->configService->getExportMode()) { $item[$this->getData('name')]['action-create_concept'] = [ 'href' => $this->urlBuilder->getUrl( 'myparcel/order/CreateAndPrintMyParcelTrack', @@ -86,10 +75,10 @@ public function prepareDataSource(array $dataSource) ] ), 'label' => __('Export to MyParcel'), - 'hidden' => ! $orderManagementActivated, + 'hidden' => !$orderManagementActivated, ]; } else { - $item[$this->getData('name')]['action-download_package_label'] = [ + $item[$this->getData('name')]['action-download_package_label'] = [ 'href' => $this->urlBuilder->getUrl( 'myparcel/order/CreateAndPrintMyParcelTrack', [ @@ -125,7 +114,7 @@ public function prepareDataSource(array $dataSource) 'label' => __('Download digital stamp label'), 'hidden' => $orderManagementActivated, ]; - $item[$this->getData('name')]['action-download_mailbox_label'] = [ + $item[$this->getData('name')]['action-download_mailbox_label'] = [ 'href' => $this->urlBuilder->getUrl( 'myparcel/order/CreateAndPrintMyParcelTrack', [ @@ -137,7 +126,7 @@ public function prepareDataSource(array $dataSource) 'label' => __('Download mailbox label'), 'hidden' => $orderManagementActivated, ]; - $item[$this->getData('name')]['action-download_letter_label'] = [ + $item[$this->getData('name')]['action-download_letter_label'] = [ 'href' => $this->urlBuilder->getUrl( 'myparcel/order/CreateAndPrintMyParcelTrack', [ @@ -149,7 +138,7 @@ public function prepareDataSource(array $dataSource) 'label' => __('Download letter label'), 'hidden' => $orderManagementActivated, ]; - $item[$this->getData('name')]['action-create_concept'] = [ + $item[$this->getData('name')]['action-create_concept'] = [ 'href' => $this->urlBuilder->getUrl( 'myparcel/order/CreateAndPrintMyParcelTrack', [ @@ -160,7 +149,7 @@ public function prepareDataSource(array $dataSource) 'label' => __('Create new concept'), 'hidden' => $orderManagementActivated, ]; - $item[$this->getData('name')]['action-ship_direct'] = [ + $item[$this->getData('name')]['action-ship_direct'] = [ 'href' => $this->urlBuilder->getUrl( 'adminhtml/order_shipment/start', [ @@ -174,7 +163,7 @@ public function prepareDataSource(array $dataSource) } if (isset($item[ShippingStatus::NAME])) { - $item[$this->getData('name')]['action-create_concept'] = [ + $item[$this->getData('name')]['action-create_concept'] = [ 'href' => $this->urlBuilder->getUrl( 'myparcel/order/CreateAndPrintMyParcelTrack', [ @@ -183,9 +172,9 @@ public function prepareDataSource(array $dataSource) ] ), 'label' => __('Already exported'), - 'hidden' => ! $orderManagementActivated, + 'hidden' => !$orderManagementActivated, ]; - $item[$this->getData('name')]['action-download_package_label'] = [ + $item[$this->getData('name')]['action-download_package_label'] = [ 'href' => $this->urlBuilder->getUrl( 'myparcel/order/CreateAndPrintMyParcelTrack', [ diff --git a/Ui/Component/Listing/Column/TrackAndTrace.php b/Ui/Component/Listing/Column/TrackAndTrace.php index 771302e5..305d2dd3 100755 --- a/Ui/Component/Listing/Column/TrackAndTrace.php +++ b/Ui/Component/Listing/Column/TrackAndTrace.php @@ -7,8 +7,8 @@ use Magento\Framework\App\ObjectManager; use Magento\Sales\Model\Order; use Magento\Ui\Component\Listing\Columns\Column; -use MyParcelNL\Sdk\src\Helper\TrackTraceUrl; -use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment; +use MyParcelNL\Sdk\Helper\TrackTraceUrl; +use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment; class TrackAndTrace extends Column { diff --git a/composer.json b/composer.json index 21ca0c84..6d1620c5 100755 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "myparcelnl/magento", - "version": "4.16.1", + "version": "5.0.0", "description": "A Magento 2 module that creates MyParcel labels", "keywords": [ "myparcel", @@ -30,7 +30,7 @@ "type": "magento2-module", "require": { "php": "^7.1 || ^8.0", - "myparcelnl/sdk": "~v7.15.3", + "myparcelnl/sdk": "~v7.18", "magento/framework": ">=101.0.8 <102 || >=102.0.1" }, "require-dev": { diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 433d09f4..6111192f 100755 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -29,6 +29,16 @@ MyParcelNL\Magento\Block\System\Config\Form\SettingsButton + + \MyParcelNL\Magento\Block\System\Config\Form\DeliveryCostsMatrix + + + + + + If you leave this empty or invalid, this shipping method will act as Flat rate using the Shipping cost defined under Sales->Delivery Methods->MyParcel + + @@ -89,14 +99,23 @@ - - - - - MyParcelNL\Magento\Model\Source\ShippingMethods - The extra myparcel options are added to this shipping method - 1 + + + + + + + + + + + + + + + + MyParcelNL\Magento\Model\Source\PickupLocationsView @@ -121,44 +140,46 @@ - The times will be visible when nothing is filled in - + + + + - + The times will be visible when nothing is filled in - + The times will be visible when nothing is filled in - + The times will be visible when nothing is filled in - + - + - + - + - + - + - + @@ -196,7 +217,7 @@ 1 - + This will be added to the regular shipping price @@ -204,6 +225,21 @@ 1 + + + Magento\Config\Model\Config\Source\Yesno + + 1 + + + + + This will be added to the regular shipping price + + 1 + 1 + + Magento\Config\Model\Config\Source\Yesno @@ -323,6 +359,17 @@ 1 + + + Magento\Config\Model\Config\Source\Yesno + + + + validate-number validate-zero-or-greater + + 1 + + Magento\Config\Model\Config\Source\Yesno @@ -410,13 +457,6 @@ 1 - - - Enter a basic price for a digital stamp. The regular price will not affect this price. - - 1 - - @@ -432,13 +472,6 @@ 1 - - - Enter a basic price for a mailbox. The regular price will not affect this price. - - 1 - - Only available for certain contracts. If this is not in your contract, the setting has no effect. @@ -447,14 +480,6 @@ 1 - - - Enter a basic price for a mailbox. The regular price will not affect this price. - - 1 - 1 - - @@ -470,13 +495,6 @@ 1 - - - Enter a basic price for a mailbox. The regular price will not affect this price. - - 1 - - @@ -731,13 +749,6 @@ 1 - - - Enter a basic price for a mailbox. The regular price will not affect this price. - - 1 - - @@ -1158,14 +1169,6 @@ 1 - - - Enter a basic price for a mailbox. The regular price will not affect this price. - - 1 - -
@@ -1178,6 +1181,40 @@ Magento\Config\Model\Config\Source\Yesno + + + Magento\Config\Model\Config\Source\Yesno + + 1 + + + + + This will be added to the regular shipping price + + 1 + 1 + + + + + Magento\Config\Model\Config\Source\Yesno + + 1 + + + + + This will be added to the regular shipping price + + 1 + 1 + + @@ -1267,6 +1304,98 @@ For orders before this time, the drop-off is considered done on this day. + + + Fill in your preferences for a shipment. These settings will only apply for the mass actions in + the order grid. When creating a single shipment, these settings can be changed manually. These + settings will activate based on the order total amount. + + + + Magento\Config\Model\Config\Source\Yesno + + + + validate-number validate-zero-or-greater + 'Signature on receipt' operates above a certain order total amount + + 1 + + + + + Magento\Config\Model\Config\Source\Yesno + + + + validate-number validate-zero-or-greater + + 1 + + + + + Magento\Config\Model\Config\Source\Yesno + + + + validate-number validate-zero-or-greater + 'Home address only' operates above a certain order total amount + + 1 + + + + + Magento\Config\Model\Config\Source\Yesno + + + + validate-number validate-zero-or-greater + The minimum amount from when insurance is active. + + + + MyParcelNL\Magento\Model\Source\CarrierInsurancePossibilities\UPS\Local + + + + validate-number validate-number-range number-range-0-100 + Use percentage of total order amount for insurance. After the calculation, the next + available price scale is selected. + + + + + + + + Magento\Config\Model\Config\Source\Yesno + UPS guarantees delivery within one day with this option active. + + + + This will be added to the regular shipping price + + 1 + + +
@@ -1292,5 +1421,42 @@
+
+ + + + + Magento\Config\Model\Config\Source\Yesno + + + + + + + + + + validate-number validate-zero-or-greater + + + + shipping-applicable-country + Magento\Shipping\Model\Config\Source\Allspecificcountries + + + + Magento\Directory\Model\Config\Source\Country + 1 + + + + Magento\Config\Model\Config\Source\Yesno + shipping-skip-hide + + + + + +
diff --git a/etc/config.xml b/etc/config.xml index fdcaf32d..043762dd 100755 --- a/etc/config.xml +++ b/etc/config.xml @@ -5,7 +5,8 @@ * See COPYING.txt for license details. */ --> - + @@ -244,5 +245,18 @@ bcc + + + + 1 + MyParcel + MyParcel + 10 + 0 + 15 + MyParcelNL\Magento\Model\Carrier\Carrier + + + diff --git a/etc/di.xml b/etc/di.xml index 90ce5dfa..f28b272b 100755 --- a/etc/di.xml +++ b/etc/di.xml @@ -40,8 +40,6 @@ - - @@ -72,6 +70,13 @@ + + + ups + local + + + diff --git a/etc/module.xml b/etc/module.xml index 32dd093d..9c95f2d4 100755 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,5 +1,5 @@ - + diff --git a/i18n/en_US.csv b/i18n/en_US.csv index 08ddd101..b88ed027 100755 --- a/i18n/en_US.csv +++ b/i18n/en_US.csv @@ -58,8 +58,8 @@ location_page, location manager package_small, Small package show_total_price, Show total price show_surcharge_price, Show surcharge -Automate 'Large format',Automate 'Larger than 100 x 70 x 58 cm or heavier than 23 kg' -Large package,Larger than 100 x 70 x 58 cm or heavier than 23 kg +Automate 'Large format',Automate 'Larger than 100 x 70 x 58 cm' +Large package,Larger than 100 x 70 x 58 cm delivery_title, Delivery Options standard_title, Standard Delivery @@ -73,7 +73,9 @@ map_title, Map mailbox_title, Mailbox digital_stamp_title, Digital Stamp packet_title, Packet +package_title, Package signature_title, Signature +receipt_code_title, Receiving code only_recipient_title, Only Recipient saturday_delivery, Saturday Delivery diff --git a/i18n/fr_FR.csv b/i18n/fr_FR.csv index 88a64165..005914f9 100644 --- a/i18n/fr_FR.csv +++ b/i18n/fr_FR.csv @@ -75,6 +75,8 @@ Select a standard orientation for printing labels.,Sélectionnez une orientation Default shipping options,Options d'expédition standards "Fill in your preferences for a shipment. These settings will only apply for the mass actions in the order grid. When creating a single shipment, these settings can be changed manually. These settings will activate based on the order total amount.","Indiquez ici vos préférences standards quant aux options d'expédition. S'ils sont d'application, ces paramètres seront utilisés par défaut pour tous vos envois. Ces options peuvent bien sûr toujours être modifiées lors du traitement." Automate 'Signature on receipt',Automatisation de la 'Signature pour réception' +Automate 'Collect package',Automatisation de 'Livré en 1 jour' +Automate 'Receipt code',Automatisation de la 'Code de réception' Signature on receipt' operates above a certain order total amount,La 'Signature pour réception' est activée lorsque le montant total dépasse le montant indiqué ci-dessus Automate 'Insurance € 500',Automatisation de l''Assurance jusqu'à € 500' "Insurance € 500' operates above a certain order total amount.","L''Assurance jusqu'à € 500' est activée lorsque le montant total dépasse le montant ci-dessus." @@ -85,6 +87,9 @@ Track action,Action de suivi MyParcel options,Options MyParcel Package,Colis Signature on receipt,Signature pour réception +Collect package,Faire récupérer le colis +Receipt code,Code de réception +Receipt code fee,Frais de code de réception Home address only,Livraison à domicile uniquement Hide sender title,Titre de masquer l'expéditeur Insured up to:,Assuré jusqu'à : @@ -136,6 +141,9 @@ Cut-off time,Heure limite de commande "If a request is made for the delivery options between Friday after, and Monday before, cut-off time then Tuesday will be shown as the next possible delivery date.","Lorsqu'une commande est passée après la dernière heure de commande le vendredi et avant celle-ci le lundi, c'est donc le mardi qui sera affiché comme premier jour de livraison." Drop-off days,Jours de dépôt Monday delivery,Livraison le lundi +Express delivery,Livré en un jour +Express delivery fee,Livré en un jour - prix +Express delivery active,Livré en un jour actif Same day delivery,Livraison le jour même Same day title,Titre le jour même "Delivery on monday may require special conditions compared to other (week)days including but not limited to fee and cutoff time.","La livraison le lundi peut nécessiter des conditions spéciales par rapport aux autres jours de la semaine, y compris mais sans s'y limiter, des frais et heure limite de commande." @@ -201,8 +209,11 @@ Thursday,Jeudi Friday,Vendredi Saturday,Samedi Sunday,Dimanche -Automate 'Large format',Automatiser "Plus grand que 100 x 70 x 58 cm ou plus lourd que 23 kg" -Large package,Plus grand que 100 x 70 x 58 cm ou plus lourd que 23 kg +Automate 'Large format',Automatiser "Plus grand que 100 x 70 x 58 cm" +Large package,Plus grand que 100 x 70 x 58 cm +Mailbox,Colis boîte aux lettres +Digital stamp,Timbre numérique +Small package,Colis petit format {field} is required.,{field} est requis. Address not found.,Adresse introuvable. @@ -219,7 +230,9 @@ list_title, Liste map_title, Carte mailbox_title, Colis boîte aux lettres digital_stamp_title, Timbre digital -packet_title, Colis +packet_title,Petit colis +package_title,Colis signature_title, Signature à réception +receipt_code_title, Code de réception only_recipient_title, Adresse de résidence uniquement saturday_delivery, Livraison le samedi diff --git a/i18n/nl_NL.csv b/i18n/nl_NL.csv index 220368ce..16f90040 100755 --- a/i18n/nl_NL.csv +++ b/i18n/nl_NL.csv @@ -89,10 +89,12 @@ Show map first,Toon kaart eerst Default shipping options,Standaard verzendinstellingen "Fill in your preferences for a shipment. These settings will only apply for the mass actions in the order grid. When creating a single shipment, these settings can be changed manually. These settings will activate based on the order total amount.","Vul hier uw standaard voorkeuren in voor uw verzendopties. Deze instellingen worden als default op al uw zendingen toegepast, indien van toepassing. Deze opties zijn later, per zending, uiteraard nog wel aan te passen tijdens het verwerken." Automate 'Signature on receipt',Automatiseer 'Handtekening voor ontvangst' +Automate 'Collect package',Automatiseer 'Pakket laten ophalen' +Automate 'Receipt code',Automatiseer 'Ontvangstcode' Automate 'Home address only',Automatiseer 'Alleen huisadres' Automate 'Return if no answer',Automatiseer 'Retour bij geen gehoor' -Automate 'Large format',Automatiseer 'Groter dan 100 x 70 x 58 cm of zwaarder dan 23 kg' -Large package,Groter dan 100 x 70 x 58 cm of zwaarder dan 23 kg +Automate 'Large format',Automatiseer 'Groter dan 100 x 70 x 58 cm' +Large package,Groter dan 100 x 70 x 58 cm Automate 'Age check 18+',Automatiseer 'Leeftijdscontrole 18+' Automate 'Insurance € 100',Automatiseer 'Verzekerd tot €100' Automate 'Insurance € 250',Automatiseer 'Verzekerd tot €250' @@ -114,6 +116,9 @@ Enter a basic price for a mailbox. The regular price will not affect this price. Morning delivery,Ochtendlevering Evening delivery,Avondlevering Evening delivery fee,Avondlevering kosten +Express delivery,Binnen 1 dag bezorgd +Express delivery fee,Binnen 1 dag bezorgd kosten +Express delivery active,Binnen 1 dag bezorgd ingeschakeld Same day delivery,Zelfde dag bezorgd Same day title,Zelfde dag titel Morning delivery active,Ochtendlevering ingeschakeld @@ -125,6 +130,9 @@ Monday delivery,Maandag levering "Delivery on monday may require special conditions compared to other (week)days including but not limited to fee and cutoff time.","Levering op maandag kan speciale voorwaarden vereisen in vergelijking met andere (week)dagen, waaronder maar niet beperkt tot kosten en laatste bestelmoment." Number of days,Aantal dagen Delivery enabled,Bezorging ingeschakeld +Receipt code,Ontvangstcode +Receipt code fee,Ontvangstcode kosten +Collect package,Pakket laten ophalen Home address only,Alleen huisadres Home address only fee,Alleen huisadres kosten Digital stamp settings,Digitalepostzegel instellingen @@ -280,6 +288,7 @@ Sunday,Zondag Enable create label concept, when invoice is printed., Maak concept labels aan, wanneer je een factuur afdrukt. Mailbox,Brievenbuspakje Digital stamp,Digitale postzegel +Small package,Klein pakket Print return label directly,Print het retour label direct I use the following weight type,Ik gebruik de volgende eenheid voor gewicht This is the type of weight that I use with my products.,Dit is de eenheid die je gebruikt voor het gewicht van je producten. @@ -300,18 +309,20 @@ Export to MyParcel, Exporteer naar MyParcel Already exported, Reeds geëxporteerd "Enabling this setting automatically creates a related return shipment for any shipment you export. When downloading the shipment labels the corresponding return shipment labels will be included.","Na het activeren van deze instelling wordt er bij het exporteren van elke zending automatisch een retour zending aangemaakt. Als je het label print wordt ook meteen het retour label geprint." -delivery_title, Bezorgopties -standard_title, Standaard bezorging -morning_title, Maandag levering -evening_title, Avond levering -pickup_title, Afhaal locaties -same_day_title, Zelfde dag levering -hide_sender_title, Afzender verbergen -list_title, Lijst -map_title, Kaart -mailbox_title, Brievenbuspakje -digital_stamp_title, Digitale postzegel -packet_title, Pakket -signature_title, Handtekening voor ontvangst -only_recipient_title, Alleen huisadres -saturday_delivery, Zaterdag levering +delivery_title,Bezorgopties +standard_title,Standaard bezorging +morning_title,Ochtend levering +evening_title,Avond levering +pickup_title,Afhaal locaties +same_day_title,Zelfde dag levering +hide_sender_title,Afzender verbergen +list_title,Lijst +map_title,Kaart +mailbox_title,Brievenbuspakje +digital_stamp_title,Digitale postzegel +packet_title,Klein pakket +package_title,Pakket +signature_title,Handtekening voor ontvangst +receipt_code_title,Ontvangstcode +only_recipient_title,Alleen huisadres +saturday_delivery,Zaterdag levering diff --git a/view/adminhtml/templates/delivery_costs_matrix.phtml b/view/adminhtml/templates/delivery_costs_matrix.phtml new file mode 100644 index 00000000..f4e6729a --- /dev/null +++ b/view/adminhtml/templates/delivery_costs_matrix.phtml @@ -0,0 +1,19 @@ + + diff --git a/view/adminhtml/templates/new_shipment.phtml b/view/adminhtml/templates/new_shipment.phtml index 9698d673..6217fd25 100755 --- a/view/adminhtml/templates/new_shipment.phtml +++ b/view/adminhtml/templates/new_shipment.phtml @@ -1,8 +1,8 @@ @@ -170,6 +170,11 @@ foreach ($form->getCarrierSpecificAbstractConsignments() as $abstractConsignment class="admin__field-label" for="mypa___"> getShipmentOptionsHumanMap()[$shipmentOption] ?? $shipmentOption ?> + getShipmentOptionsExplanationMap()[$shipmentOption] ?? '')) { + echo '
', htmlentities($explanation), '
'; + } ?>
diff --git a/view/adminhtml/web/js/delivery-costs-matrix.js b/view/adminhtml/web/js/delivery-costs-matrix.js new file mode 100644 index 00000000..cbc853c3 --- /dev/null +++ b/view/adminhtml/web/js/delivery-costs-matrix.js @@ -0,0 +1,12 @@ +define( + function() { + 'use strict'; + + return function Matrix(options) { + console.warn('Matrix loaded', options); + console.log(JSON.parse(options.carriers)); + console.log(JSON.parse(options.packageTypes)); + console.log(JSON.parse(options.countryParts)); + }; + } +); diff --git a/view/frontend/web/js/model/checkout.js b/view/frontend/web/js/model/checkout.js index 0921fc2f..a4bc8807 100644 --- a/view/frontend/web/js/model/checkout.js +++ b/view/frontend/web/js/model/checkout.js @@ -44,7 +44,7 @@ function( ) { 'use strict'; - var Model = { + const Model = { configuration: ko.observable(null), /** @@ -71,24 +71,30 @@ function( * Best package type. */ bestPackageType: null, + carrierCode: 'myparcel', // default, may be overridden by carrierCode in configuration /** * Initialize by requesting the MyParcel settings configuration from Magento. */ initialize: function() { + console.error(' Joeri debugging 2 '); Model.compute = ko.computed(function() { - var configuration = Model.configuration(); - var rates = Model.rates(); + const configuration = Model.configuration(); + const rates = Model.rates(); if (!configuration || !rates.length) { return false; } + // necessary vor updateAllowedShippingMethods() + if (configuration.carrierCode) Model.carrierCode = configuration.carrierCode; + + // the object with information that we need return {configuration: configuration, rates: rates}; }); - Model.compute.subscribe(function(a) { - if (!a) { + Model.compute.subscribe(function(objectWithInformation) { + if (!objectWithInformation) { return; } @@ -102,7 +108,7 @@ function( doRequest(Model.getDeliveryOptionsConfig, {onSuccess: Model.onInitializeSuccess}); function reloadConfig() { - var shippingAddress = quote.shippingAddress(); + const shippingAddress = quote.shippingAddress(); if (shippingAddress.countryId !== Model.countryId()) { doRequest(Model.getDeliveryOptionsConfig, {onSuccess: Model.onReFetchDeliveryOptionsConfig}); @@ -115,7 +121,7 @@ function( }, onReFetchDeliveryOptionsConfig: function(response) { - var configuration = response[0].data; + const configuration = response[0].data; Model.bestPackageType = configuration.config.packageType; Model.setDeliveryOptionsConfig(configuration); }, @@ -130,19 +136,6 @@ function( Model.hideShippingMethods(); }, - /** - * Search the rates for the given method code. - * - * @param {string} methodCode - Method code to search for. - * - * @returns {Object} - The found rate, if any. - */ - findRateByMethodCode: function(methodCode) { - return Model.rates().find(function(rate) { - return rate.method_code === methodCode; - }); - }, - /** * Search the rates for the given carrier code. * @@ -152,9 +145,7 @@ function( */ findOriginalRateByCarrierCode: function(carrierCode) { return Model.rates().find(function(rate) { - if (-1 === rate.method_code.indexOf('myparcel')) { - return rate.carrier_code === carrierCode; - } + return rate.carrier_code === carrierCode; }); }, @@ -162,32 +153,22 @@ function( * Hide the shipping methods the delivery options should replace. */ hideShippingMethods: function() { - var rowsToHide = []; + const row = Model.rowElement(); - Model.rates().forEach(function(rate) { - const hasDeliveryOptions = Model.hasDeliveryOptions(); - const myParcelMethods = hasDeliveryOptions ? Model.configuration().methods || [] : []; - const cell = document.getElementById('label_method_' + rate.method_code + '_' + rate.carrier_code) || null; - - if (!rate.available || !cell) { - return; - } + if (row && Model.hasDeliveryOptions) { + row.style.display = 'none'; + } + }, - const row = cell.parentElement; + rowElement: function() { + const rate = Model.findOriginalRateByCarrierCode(Model.carrierCode) || {}, + cell = document.getElementById(`label_method_${rate.method_code}_${rate.carrier_code}`); - /** - * Hide MyParcel-specific methods, and the parent methods delivery options are bound to - */ - if (rate.method_code.indexOf('myparcel') !== -1) { - rowsToHide.push(row); - } else if (myParcelMethods.includes(rate.carrier_code)) { - rowsToHide.push(row); - } - }); + if (!cell) { + return null; + } - rowsToHide.forEach(function(row) { - row.style.display = 'none'; - }); + return cell.parentElement; // or cell.closest('tr');? who knows how this is structured in different checkouts? }, /** @@ -211,11 +192,11 @@ function( * @returns {XMLHttpRequest} */ calculatePackageType: function(carrier) { - var list = document.querySelector('[name="country_id"]'); function isVisible(el) { return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length); } - var countryId = (list && isVisible(list)) ? list.options[list.selectedIndex].value : Model.countryId(); + const list = document.querySelector('[name="country_id"]'), + countryId = (list && isVisible(list)) ? list.options[list.selectedIndex].value : Model.countryId(); return sendRequest( 'rest/V1/package_type', 'GET', @@ -275,14 +256,13 @@ function( * Filter the allowed shipping methods by checking if they are actually present in the checkout. If not they will * be left out. */ - Model.allowedShippingMethods(Model.configuration().methods.filter(function(carrierCode) { - return !!Model.findOriginalRateByCarrierCode(carrierCode); - })); + const row = Model.rowElement(); + if (!row) setTimeout(updateAllowedShippingMethods, 151); + Model.allowedShippingMethods([Model.carrierCode]); } function updateHasDeliveryOptions() { let isAllowed = false; - const shippingCountry = quote.shippingAddress().countryId; Model.allowedShippingMethods().forEach(function(carrierCode) { const rate = Model.findOriginalRateByCarrierCode(carrierCode); @@ -290,7 +270,6 @@ function( isAllowed = true; } }); - Model.hasDeliveryOptions(isAllowed); Model.hideShippingMethods(); } @@ -319,7 +298,7 @@ function( }; request().onload = function() { - var response = JSON.parse(this.response); + const response = JSON.parse(this.response); if (this.status >= STATUS_SUCCESS && this.status < STATUS_ERROR) { handlers.doHandler('onSuccess', response); @@ -341,15 +320,15 @@ function( * @returns {XMLHttpRequest} */ function sendRequest(endpoint, method, options) { - var url = mageUrl.build(endpoint); - var request = new XMLHttpRequest(); - var query = []; + let url = mageUrl.build(endpoint); + const query = [], + request = new XMLHttpRequest(); method = method || 'GET'; options = options || {}; if (method === 'GET') { - for (var key in options) { + for (const key in options) { query.push(key + '=' + encodeURIComponent(options[key])); } } diff --git a/view/frontend/web/js/model/shipping-save-processor-default.js b/view/frontend/web/js/model/shipping-save-processor-default.js old mode 100755 new mode 100644 diff --git a/view/frontend/web/js/view/delivery-options.js b/view/frontend/web/js/view/delivery-options.js index 82366ffd..efbc7397 100644 --- a/view/frontend/web/js/view/delivery-options.js +++ b/view/frontend/web/js/view/delivery-options.js @@ -27,9 +27,7 @@ define( ) { 'use strict'; - var deliveryOptions; - - deliveryOptions = { + const deliveryOptions = { rendered: ko.observable(false), splitStreetRegex: /(.*?)\s?(\d{1,5})[/\s-]{0,2}([A-z]\d{1,3}|-\d{1,4}|\d{2}\w{1,2}|[A-z][A-z\s]{0,3})?$/, @@ -57,48 +55,6 @@ define( */ hiddenDataInput: '[name="myparcel_delivery_options"]', - methodCodeStandardDelivery: 'myparcelnl_magento_postnl_settings/delivery', - - /** - * Maps shipping method codes to prices in the delivery options config. - */ - methodCodeDeliveryOptionsConfigMap: { - 'myparcelnl_magento_postnl_settings/delivery': 'config.carrierSettings.postnl.priceStandardDelivery', - 'myparcelnl_magento_postnl_settings/mailbox': 'config.carrierSettings.postnl.pricePackageTypeMailbox', - 'myparcelnl_magento_postnl_settings/package_small': 'config.carrierSettings.postnl.pricePackageTypePackageSmall', - 'myparcelnl_magento_postnl_settings/digital_stamp': 'config.carrierSettings.postnl.pricePackageTypeDigitalStamp', - 'myparcelnl_magento_postnl_settings/morning': 'config.carrierSettings.postnl.priceMorningDelivery', - 'myparcelnl_magento_postnl_settings/evening': 'config.carrierSettings.postnl.priceEveningDelivery', - 'myparcelnl_magento_postnl_settings/morning/only_recipient': 'config.carrierSettings.postnl.priceMorningDelivery', - 'myparcelnl_magento_postnl_settings/evening/only_recipient': 'config.carrierSettings.postnl.priceEveningDelivery', - 'myparcelnl_magento_postnl_settings/pickup': 'config.carrierSettings.postnl.pricePickup', - 'myparcelnl_magento_postnl_settings/morning/only_recipient/signature': 'config.carrierSettings.postnl.priceMorningSignature', - 'myparcelnl_magento_postnl_settings/evening/only_recipient/signature': 'config.carrierSettings.postnl.priceEveningSignature', - 'myparcelnl_magento_postnl_settings/delivery/only_recipient/signature': 'config.carrierSettings.postnl.priceSignatureAndOnlyRecipient', - 'myparcelnl_magento_dhlforyou_settings/delivery': 'config.carrierSettings.dhlforyou.priceStandardDelivery', - 'myparcelnl_magento_dhlforyou_settings/mailbox': 'config.carrierSettings.dhlforyou.pricePackageTypeMailbox', - 'myparcelnl_magento_dhlforyou_settings/pickup': 'config.carrierSettings.dhlforyou.pricePickup', - 'myparcelnl_magento_dhlforyou_settings/delivery/same_day_delivery': 'config.carrierSettings.dhlforyou.priceSameDayDelivery', - 'myparcelnl_magento_dhlforyou_settings/delivery/only_recipient/same_day_delivery': 'config.carrierSettings.dhlforyou.priceSameDayDeliveryAndOnlyRecipient', - 'myparcelnl_magento_dhleuroplus_settings/delivery': 'config.carrierSettings.dhleuroplus.priceStandardDelivery', - 'myparcelnl_magento_dhlparcelconnect_settings/delivery': 'config.carrierSettings.dhlparcelconnect.priceStandardDelivery', - 'myparcelnl_magento_ups_settings/delivery': 'config.carrierSettings.ups.priceStandardDelivery', - 'myparcelnl_magento_dpd_settings/delivery': 'config.carrierSettings.dpd.priceStandardDelivery', - 'myparcelnl_magento_dpd_settings/pickup': 'config.carrierSettings.dpd.pricePickup', - 'myparcelnl_magento_dpd_settings/mailbox': 'config.carrierSettings.dpd.pricePackageTypeMailbox', - }, - - /** - * Maps shipping method codes to prices in the delivery options config. - */ - methodCodeShipmentOptionsConfigMap: { - 'myparcelnl_magento_postnl_settings/delivery/signature': 'config.carrierSettings.postnl.priceSignature', - 'myparcelnl_magento_postnl_settings/delivery/only_recipient': 'config.carrierSettings.postnl.priceOnlyRecipient', - 'myparcelnl_magento_dhlforyou_settings/delivery/only_recipient': 'config.carrierSettings.dhlforyou.priceOnlyRecipient', - 'myparcelnl_magento_dhlforyou_settings/delivery/same_day_delivery': 'config.carrierSettings.dhlforyou.priceSameDayDelivery', - 'myparcelnl_magento_dhlforyou_settings/delivery/only_recipient/same_day_delivery': 'config.carrierSettings.dhlforyou.priceSameDayDeliveryAndOnlyRecipient', - }, - /** * Initialize the script. Render the delivery options div, request the plugin settings, then initialize listeners. */ @@ -115,14 +71,14 @@ define( }, setToRenderWhenVisible: function() { - var shippingMethodDiv = document.getElementById('checkout-shipping-method-load'); + const shippingMethodDiv = document.getElementById('checkout-shipping-method-load'); /** - * Sometimes the shipping method div doesn't exist yet. Retry in 100ms if it happens. + * Sometimes the shipping method div doesn't exist yet. Retry in 151ms if it happens. */ if (!shippingMethodDiv) { setTimeout(function() { deliveryOptions.setToRenderWhenVisible(); - }, 100); + }, 151); return; } @@ -155,24 +111,21 @@ define( deliveryOptions.triggerEvent(deliveryOptions.hideDeliveryOptionsEvent); }, - /** - * Create the div the delivery options will be rendered in, if it doesn't exist yet. - */ render: function() { - var hasUnrenderedDiv = document.querySelector('#myparcel-delivery-options'); - var hasRenderedDeliveryOptions = document.querySelector('.myparcel-delivery-options__table'); - var shippingMethodDiv = document.getElementById('checkout-shipping-method-load'); - var deliveryOptionsDiv = document.createElement('div'); - + const deliveryOptionsDiv = document.getElementById('myparcel-delivery-options'), + shippingMethodDiv = document.getElementById('checkout-shipping-method-load'); checkout.hideShippingMethods(); deliveryOptions.rendered(false); - if (hasUnrenderedDiv || hasRenderedDeliveryOptions) { + if (deliveryOptionsDiv) { deliveryOptions.triggerEvent(deliveryOptions.updateDeliveryOptionsEvent); - } else if (!hasUnrenderedDiv) { - deliveryOptionsDiv.setAttribute('id', 'myparcel-delivery-options'); - shippingMethodDiv.insertBefore(deliveryOptionsDiv, shippingMethodDiv.firstChild); - deliveryOptions.triggerEvent(deliveryOptions.renderDeliveryOptionsEvent); + } else { + const newDeliveryOptionsDiv = document.createElement('div'); + newDeliveryOptionsDiv.setAttribute('id', 'myparcel-delivery-options'); + shippingMethodDiv.insertAdjacentElement('afterbegin', newDeliveryOptionsDiv); + requestAnimationFrame(function() { // wait for the element to actually be added to the DOM + deliveryOptions.triggerEvent(deliveryOptions.renderDeliveryOptionsEvent) + }); } deliveryOptions.rendered(true); @@ -200,8 +153,8 @@ define( * @returns {integer|null} - The house number, if found. Otherwise null. */ getHouseNumber: function(address) { - var result = deliveryOptions.splitStreetRegex.exec(address); - var numberIndex = 2; + const result = deliveryOptions.splitStreetRegex.exec(address), + numberIndex = 2; return result ? parseInt(result[numberIndex]) : null; }, @@ -211,9 +164,7 @@ define( * @param {string} identifier - Name of the event. */ triggerEvent: function(identifier) { - var event = document.createEvent('HTMLEvents'); - event.initEvent(identifier, true, false); - document.querySelector('body').dispatchEvent(event); + document.body.dispatchEvent(new Event(identifier, { bubbles: true, cancelable: false })); }, /** @@ -260,8 +211,8 @@ define( * @param {CustomEvent} event - The event that was sent. */ onUpdatedDeliveryOptions: function(event) { - var element = document.getElementsByClassName('checkout-shipping-method').item(0); - var displayStyle = window.getComputedStyle(element, null).display; + const element = document.querySelector('.checkout-shipping-method'), + displayStyle = window.getComputedStyle(element, null).display; if ('none' === displayStyle) { return; @@ -295,21 +246,7 @@ define( if (!response.length) { return; } - - /** - * For the cart summary to display the correct shipping method name on the - * second page of the standard checkout, we need to update the storage. - */ - var cacheObject = JSON.parse(localStorage.getItem('mage-cache-storage')); - if (cacheObject.hasOwnProperty('checkout-data')) { - cacheObject['checkout-data']['selectedShippingRate'] = response[0].element_id; - localStorage.setItem('mage-cache-storage', JSON.stringify(cacheObject)); - } - /** - * Set the method to null first, for the price of options to update in the cart summary. - */ - selectShippingMethodAction(null); - selectShippingMethodAction(deliveryOptions.getNewShippingMethod(response[0].element_id)); + selectShippingMethodAction(response[0]); }, }); }, @@ -319,8 +256,8 @@ define( * Until there's a built in solution, there's the following workaround. */ disabledDeliveryPickupRadio: function() { - var delivery = document.getElementById(deliveryOptions.disableDelivery); - var pickup = document.getElementById(deliveryOptions.disablePickup); + const pickup = document.getElementById(deliveryOptions.disablePickup), + delivery = document.getElementById(deliveryOptions.disableDelivery); if (delivery) { delivery.disabled = false; @@ -337,17 +274,17 @@ define( * @param {Object} selectedShippingMethod - The shipping method that was selected. */ onShippingMethodUpdate: function(selectedShippingMethod) { - var newShippingMethod = selectedShippingMethod || {}; - var available = newShippingMethod.available || false; - var isMyParcelMethod = deliveryOptions.isMyParcelShippingMethod(newShippingMethod); - + const newShippingMethod = selectedShippingMethod || {}, + available = newShippingMethod.available || false, + carrierCode = newShippingMethod.carrier_code || '', + myparcelCarrierCode = checkout.carrierCode; checkout.hideShippingMethods(); if (!checkout.hasDeliveryOptions() || !available) { return; } - if (!isMyParcelMethod) { + if (carrierCode !== myparcelCarrierCode) { deliveryOptions.triggerEvent(deliveryOptions.disableDeliveryOptionsEvent); deliveryOptions.isUsingMyParcelMethod = false; return; @@ -357,44 +294,6 @@ define( deliveryOptions.isUsingMyParcelMethod = true; }, - /** - * Get the new shipping method that should be saved. - * - * @param {string} methodCode - Method code to use to find a method. - * - * @returns {Object} - */ - getNewShippingMethod: function(methodCode) { - var newShippingMethod = []; - var matchingShippingMethod = checkout.findRateByMethodCode(methodCode); - - if (matchingShippingMethod) { - return matchingShippingMethod; - } else { - /** - * If the method doesn't exist, loop through the allowed shipping methods and return the first one that - * matches. - */ - checkout.allowedShippingMethods().forEach(function(carrierCode) { - var foundRate = checkout.findOriginalRateByCarrierCode(carrierCode); - - if (foundRate) { - newShippingMethod.push(foundRate); - } - }); - - return newShippingMethod.length ? newShippingMethod[0] : null; - } - }, - - /** - * @param {Object} shippingMethod - * @returns {boolean} - */ - isMyParcelShippingMethod: function(shippingMethod) { - return shippingMethod.available && shippingMethod.method_code.indexOf('myparcel') !== -1; - }, - /** * For use when magic decimals appear... * @@ -405,8 +304,7 @@ define( * @see https://stackoverflow.com/a/10474209 */ roundNumber: function(number, decimals) { - var newNumber = Number(String(number)).toFixed(decimals); - return parseFloat(newNumber); + return parseFloat(Number(String(number)).toFixed(decimals)); }, updateConfig: function() { diff --git a/view/frontend/web/js/view/shipping.js b/view/frontend/web/js/view/shipping.js index bde6fe5b..7d61ca50 100644 --- a/view/frontend/web/js/view/shipping.js +++ b/view/frontend/web/js/view/shipping.js @@ -34,7 +34,6 @@ define([ */ checkout.hasDeliveryOptions.subscribe(function(enabled) { checkout.hideShippingMethods(); - if (enabled) { deliveryOptions.initialize(); } else {