├── .gitignore ├── Api └── ApiCallbackInterface.php ├── Block ├── Adminhtml │ ├── Order │ │ ├── CheckShipment.php │ │ ├── Packaging.php │ │ ├── Packaging │ │ │ └── Grid.php │ │ └── PrintShippingList.php │ ├── System │ │ ├── Carrier │ │ │ └── DpdCustomerProductSettings.php │ │ └── Config │ │ │ ├── Header.php │ │ │ └── TestConnection.php │ ├── Tablerate │ │ └── Grid.php │ ├── TablerateExport.php │ └── TablerateImport.php ├── GoogleMaps.php └── ParcelshopInfo.php ├── Config └── Source │ └── Settings │ ├── ContentType.php │ ├── CustomsTerms.php │ ├── DaysInWeek.php │ ├── PrintFormat.php │ ├── ProductAttribute.php │ └── RateType.php ├── Controller ├── Adminhtml │ ├── Batch │ │ ├── Index.php │ │ └── Retry.php │ ├── BatchJob │ │ └── Index.php │ ├── Label │ │ ├── Download.php │ │ ├── Index.php │ │ └── MassDownload.php │ ├── Order │ │ ├── CheckShipment.php │ │ ├── CreateShipment.php │ │ ├── PrintReturnLabel.php │ │ ├── PrintShippingList.php │ │ └── Shipment │ │ │ ├── GetShippingItemsGrid.php │ │ │ └── Save.php │ ├── Search │ │ └── System │ │ │ └── Config │ │ │ └── TestConnection.php │ ├── Shipping │ │ ├── CreateShipment.php │ │ └── MassDownload.php │ └── Tablerate │ │ └── Export.php ├── Carrier │ └── Save.php └── Parcelshops │ ├── Index.php │ └── Save.php ├── DpdException.php ├── Helper ├── Constants.php ├── DPDClient.php ├── Data.php ├── DpdCache.php ├── DpdSettings.php ├── Services │ ├── OrderConvertService.php │ ├── OrderService.php │ └── ShipmentLabelService.php └── TrackingPopup.php ├── LICENSE ├── Model ├── ApiCallback.php ├── Attribute │ ├── Backend │ │ └── ShippingDescription.php │ └── Source │ │ ├── DefaultPackageTypeOptions.php │ │ └── ShippingType.php ├── Batch.php ├── BatchJob.php ├── Carrier │ ├── AbstractCarrier.php │ ├── Dpd.php │ ├── DpdClassic.php │ ├── DpdClassicSaturday.php │ ├── DpdExpress10.php │ ├── DpdExpress12.php │ ├── DpdGuarantee18.php │ ├── DpdSaturday.php │ ├── Dpdpickup.php │ └── Dpdpredict.php ├── CheckoutConfigProvider.php ├── Config │ ├── Backend │ │ └── CustomerProduct.php │ └── Tablerate.php ├── Mail │ └── Template │ │ └── TransportBuilder.php ├── ResourceModel │ ├── Batch.php │ ├── Batch │ │ └── Collection.php │ ├── BatchJob.php │ ├── BatchJob │ │ └── Collection.php │ ├── ShipmentLabel.php │ ├── ShipmentLabel │ │ └── Collection.php │ ├── Tablerate.php │ └── Tablerate │ │ ├── Collection.php │ │ ├── DataHashGenerator.php │ │ ├── Import.php │ │ └── RateQuery.php ├── ShipmentLabel.php └── Tablerate.php ├── Observer ├── SalesOrderAddressSaveBefore.php ├── SalesOrderSaveBefore.php └── SalesOrderShipmentSaveBefore.php ├── Plugin └── Api │ ├── Data │ └── OrderInterfacePlugin.php │ └── OrderRepositoryInterfacePlugin.php ├── README.md ├── Services ├── BatchManager.php ├── GoogleMaps.php └── ShipmentManager.php ├── Setup ├── UpgradeData.php └── UpgradeSchema.php ├── Ui └── Component │ ├── BatchJobProvider.php │ ├── BatchProvider.php │ ├── Listing │ └── Column │ │ └── ShipmentLabelActions.php │ ├── ShipmentLabelProvider.php │ └── Shipping │ └── CreateShipmentAction.php ├── ViewModel └── CheckShipment.php ├── composer.json ├── composer.lock ├── etc ├── adminhtml │ ├── acl.xml │ ├── menu.xml │ ├── routes.xml │ ├── system.xml │ └── system │ │ ├── carriers.xml │ │ ├── carriers │ │ ├── dpd.xml │ │ ├── dpd_classic.xml │ │ ├── dpd_classic_saturday.xml │ │ ├── dpd_express10.xml │ │ ├── dpd_express12.xml │ │ ├── dpd_guarantee18.xml │ │ ├── dpd_pickup.xml │ │ ├── dpd_predict.xml │ │ └── dpd_saturday.xml │ │ └── dpd │ │ ├── account_settings.xml │ │ ├── advanced.xml │ │ ├── api.xml │ │ ├── product_attribute.xml │ │ ├── shipping_origin.xml │ │ └── store_information.xml ├── config.xml ├── csp_whitelist.xml ├── di.xml ├── email_templates.xml ├── events.xml ├── extension_attributes.xml ├── frontend │ ├── di.xml │ └── routes.xml ├── module.xml └── webapi.xml ├── i18n ├── de_DE.csv ├── en_US.csv ├── es_ES.csv ├── fr_FR.csv ├── it_IT.csv ├── nl_NL.csv └── pl_PL.csv ├── registration.php └── view ├── adminhtml ├── email │ └── return_labels.html ├── layout │ ├── adminhtml_order_shipment_new.xml │ ├── adminhtml_order_shipment_view.xml │ ├── adminhtml_system_config_edit.xml │ ├── dpd_shipping_batch_index.xml │ ├── dpd_shipping_batchjob_index.xml │ ├── dpd_shipping_label_index.xml │ ├── dpd_shipping_order_checkshipment.xml │ ├── dpdshipping_order_printshippinglist.xml │ └── dpdshippingv2_index_index.xml ├── requirejs-config.js ├── templates │ ├── order │ │ ├── checkshipment.phtml │ │ └── packaging │ │ │ ├── grid.phtml │ │ │ ├── popup.phtml │ │ │ └── popup_content.phtml │ ├── printshippinglist.phtml │ └── system │ │ ├── carrier │ │ └── dpd-customer-product-settings.phtml │ │ └── config │ │ ├── header.phtml │ │ └── testconnection.phtml ├── ui_component │ ├── dpdconnect_shipping_shipment_batch_grid.xml │ ├── dpdconnect_shipping_shipment_batchjob_grid.xml │ ├── dpdconnect_shipping_shipment_label_grid.xml │ ├── sales_order_grid.xml │ └── sales_order_view_shipment_grid.xml └── web │ ├── css │ └── dpd_adminhtml.css │ ├── images │ ├── dpd-icon.png │ ├── dpd-logo-transparant.png │ └── external_link_32.png │ └── js │ └── testconnection.js └── frontend ├── layout ├── checkout_index_index.xml └── onestepcheckout_index_index.xml ├── requirejs-config.js ├── templates └── checkout │ └── shipping │ ├── googlemaps.phtml │ └── parcelshop-info.phtml └── web ├── css ├── parcelshop.css └── source │ └── _module.less ├── images ├── button_close.png ├── dpd_parcelshop_logo.png ├── icon_info.gif ├── icon_info.png ├── icon_parcelshop.png ├── icon_parcelshop_shadow.png └── icon_route.png ├── js ├── model │ ├── set-shipping-information-mixin.js │ ├── shipping-rates-validation-rules.js │ └── shipping-rates-validator.js └── view │ ├── ShippingInfo.js │ ├── aheadworks-onestepcheckout-shipping-method-mixin.js │ ├── checkout │ └── shipping │ │ ├── dpd.js │ │ └── parcelshop.js │ ├── mageplaza-osc-shipping-mixin.js │ ├── onestepcheckout │ └── shipping │ │ └── parcelshop.js │ └── shipping-rates-validation.js └── template ├── ShippingInfo.html └── checkout ├── onestepcheckout └── shipping-method.html └── shipping └── parcelshops.html /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea -------------------------------------------------------------------------------- /Api/ApiCallbackInterface.php: -------------------------------------------------------------------------------- 1 | _shipmentItemFactory = $shipmentItemFactory; 40 | $this->_coreRegistry = $registry; 41 | parent::__construct($context, $data); 42 | } 43 | 44 | /** 45 | * Return collection of shipment items 46 | * 47 | * @return array 48 | */ 49 | public function getCollection() 50 | { 51 | if ($this->getShipment()->getId()) { 52 | $collection = $this->_shipmentItemFactory->create()->getCollection()->setShipmentFilter( 53 | $this->getShipment()->getId() 54 | ); 55 | } else { 56 | $collection = $this->getShipment()->getAllItems(); 57 | } 58 | return $collection; 59 | } 60 | 61 | /** 62 | * Retrieve shipment model instance 63 | * 64 | * @return \Magento\Sales\Model\Order\Shipment 65 | */ 66 | public function getShipment() 67 | { 68 | return $this->_coreRegistry->registry('current_shipment'); 69 | } 70 | 71 | /** 72 | * Can display customs value 73 | * 74 | * @return bool 75 | */ 76 | public function displayCustomsValue() 77 | { 78 | $storeId = $this->getShipment()->getStoreId(); 79 | $order = $this->getShipment()->getOrder(); 80 | $address = $order->getShippingAddress(); 81 | $shipperAddressCountryCode = $this->_scopeConfig->getValue( 82 | \Magento\Sales\Model\Order\Shipment::XML_PATH_STORE_COUNTRY_ID, 83 | \Magento\Store\Model\ScopeInterface::SCOPE_STORE, 84 | $storeId 85 | ); 86 | $recipientAddressCountryCode = $address->getCountryId(); 87 | if ($shipperAddressCountryCode != $recipientAddressCountryCode) { 88 | return true; 89 | } 90 | return false; 91 | } 92 | 93 | /** 94 | * Format price 95 | * 96 | * @param float $value 97 | * @return string 98 | */ 99 | public function formatPrice($value) 100 | { 101 | return sprintf('%.2F', $value); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Block/Adminhtml/Order/PrintShippingList.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | 21 | namespace DpdConnect\Shipping\Block\Adminhtml\Order; 22 | 23 | use Magento\Framework\View\Element\Template; 24 | use Magento\Framework\View\Element\Template\Context; 25 | 26 | class PrintShippingList extends Template 27 | { 28 | public function __construct(Context $context) 29 | { 30 | parent::__construct($context); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Block/Adminhtml/System/Config/Header.php: -------------------------------------------------------------------------------- 1 | toHtml(); 21 | } 22 | 23 | /** 24 | * @return string 25 | */ 26 | public function getLogo() 27 | { 28 | return $this->getViewFileUrl('DpdConnect_Shipping::images/dpd-logo-transparant.png'); 29 | } 30 | 31 | /** 32 | * @return string 33 | */ 34 | public function getIcon() 35 | { 36 | return $this->getViewFileUrl('DpdConnect_Shipping::images/dpd-icon.png'); 37 | } 38 | 39 | /** 40 | * @return string 41 | */ 42 | public function getSupportUrl() 43 | { 44 | return 'https://klantenservice.dpd.nl/'; 45 | } 46 | 47 | /** 48 | * @return string 49 | */ 50 | public function getDocumentationUrl() 51 | { 52 | return 'https://github.com/dpdconnect/magento2-shipping'; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Block/Adminhtml/System/Config/TestConnection.php: -------------------------------------------------------------------------------- 1 | setTemplate('DpdConnect_Shipping::system/config/testconnection.phtml'); 27 | return $this; 28 | } 29 | 30 | /** 31 | * Unset some non-related element parameters 32 | * 33 | * @param AbstractElement $element 34 | * @return string 35 | * @since 100.1.0 36 | */ 37 | public function render(AbstractElement $element) 38 | { 39 | $element = clone $element; 40 | $element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue(); 41 | return parent::render($element); 42 | } 43 | 44 | /** 45 | * Get the button and scripts contents 46 | * 47 | * @param AbstractElement $element 48 | * @return string 49 | * @since 100.1.0 50 | */ 51 | protected function _getElementHtml(AbstractElement $element) 52 | { 53 | $originalData = $element->getOriginalData(); 54 | $this->addData( 55 | [ 56 | 'button_label' => __($originalData['button_label']), 57 | 'html_id' => $element->getHtmlId(), 58 | 'ajax_url' => $this->_urlBuilder->getUrl('dpd_shipping/search_system_config/testconnection'), 59 | 'field_mapping' => str_replace('"', '\\"', json_encode($this->_getFieldMapping())) 60 | ] 61 | ); 62 | 63 | return $this->_toHtml(); 64 | } 65 | 66 | /** 67 | * Returns configuration fields required to perform the ping request 68 | * 69 | * @return array 70 | * @since 100.1.0 71 | */ 72 | protected function _getFieldMapping() 73 | { 74 | return [ 75 | 'user' => 'dpdshipping_account_settings_username', 76 | 'password' => 'dpdshipping_account_settings_password', 77 | 'depot' => 'dpdshipping_account_settings_depot', 78 | ]; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Block/Adminhtml/TablerateExport.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Block\Adminhtml; 21 | 22 | class TablerateExport extends \Magento\Framework\Data\Form\Element\AbstractElement 23 | { 24 | /** 25 | * @var \Magento\Backend\Model\UrlInterface 26 | */ 27 | protected $_backendUrl; 28 | /** 29 | * @param \Magento\Framework\Data\Form\Element\Factory $factoryElement 30 | * @param \Magento\Framework\Data\Form\Element\CollectionFactory $factoryCollection 31 | * @param \Magento\Framework\Escaper $escaper 32 | * @param \Magento\Backend\Helper\Data $helper 33 | * @param array $data 34 | */ 35 | public function __construct( 36 | \Magento\Framework\Data\Form\Element\Factory $factoryElement, 37 | \Magento\Framework\Data\Form\Element\CollectionFactory $factoryCollection, 38 | \Magento\Framework\Escaper $escaper, 39 | \Magento\Backend\Model\UrlInterface $backendUrl, 40 | array $data = [] 41 | ) { 42 | parent::__construct($factoryElement, $factoryCollection, $escaper, $data); 43 | $this->_backendUrl = $backendUrl; 44 | } 45 | /** 46 | * @return string 47 | */ 48 | public function getElementHtml() 49 | { 50 | /** @var \Magento\Backend\Block\Widget\Button $buttonBlock */ 51 | $buttonBlock = $this->getForm()->getParent()->getLayout()->createBlock( 52 | \Magento\Backend\Block\Widget\Button::class 53 | ); 54 | 55 | // get the group name 56 | $groupId = $this->getContainer()['group']['id']; 57 | 58 | $params = []; 59 | $params['website'] = $buttonBlock->getRequest()->getParam('website'); 60 | $params['shipping_method'] = $groupId; 61 | $url = $this->_backendUrl->getUrl("dpd_shipping/tablerate/export", $params); 62 | $data = [ 63 | 'label' => __('Export CSV'), 64 | 'onclick' => "setLocation('" . 65 | $url . 66 | "conditionName/' + $('carriers_" . $groupId . "_condition_name').value + '/tablerates.csv' )", 67 | 'class' => '', 68 | ]; 69 | $html = $buttonBlock->setData($data)->toHtml(); 70 | return $html; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Block/Adminhtml/TablerateImport.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Block\Adminhtml; 21 | 22 | class TablerateImport extends \Magento\Framework\Data\Form\Element\AbstractElement 23 | { 24 | protected $shipconfig; 25 | 26 | /** 27 | * @return void 28 | */ 29 | protected function _construct() 30 | { 31 | parent::_construct(); 32 | $this->setType('file'); 33 | } 34 | /** 35 | * Enter description here... 36 | * 37 | * @return string 38 | */ 39 | public function getElementHtml() 40 | { 41 | 42 | // get the group name 43 | $groupId = $this->getContainer()['group']['id']; 44 | 45 | $html = ''; 46 | $html .= ''; 47 | $html .= << 49 | 50 | var groupId = '$groupId'; 51 | 52 | require(['prototype'], function(){ 53 | Event.observe($('carriers_' + groupId + '_condition_name'), 'change', checkConditionName.bind(this)); 54 | function checkConditionName(event) 55 | { 56 | var conditionNameElement = Event.element(event); 57 | if (conditionNameElement && conditionNameElement.id) { 58 | $('time_condition_' + groupId).value = '_' + conditionNameElement.value + '/' + Math.random(); 59 | } 60 | } 61 | }); 62 | 63 | EndHTML; 64 | $html .= parent::getElementHtml(); 65 | return $html; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Block/GoogleMaps.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Block; 21 | 22 | use DpdConnect\Sdk\Client; 23 | use DpdConnect\Shipping\Helper\DPDClient; 24 | use DpdConnect\Shipping\Helper\DpdSettings; 25 | use Magento\Framework\View\Element\Template\Context; 26 | 27 | class GoogleMaps extends \Magento\Framework\View\Element\Template 28 | { 29 | /** 30 | * @var DpdSettings 31 | */ 32 | private $dpdSettings; 33 | 34 | /** 35 | * GoogleMaps constructor. 36 | * 37 | * @param Context $context 38 | * @param DpdSettings $dpdSettings 39 | */ 40 | public function __construct( 41 | Context $context, 42 | DpdSettings $dpdSettings 43 | ) { 44 | parent::__construct($context); 45 | $this->dpdSettings = $dpdSettings; 46 | } 47 | 48 | /** 49 | * @return string 50 | */ 51 | public function getJsUrl() 52 | { 53 | $apiUrl = $this->dpdSettings->getValue(DpdSettings::API_ENDPOINT); 54 | if (null === $apiUrl || '' === trim($apiUrl)) { 55 | $apiUrl = Client::ENDPOINT; 56 | } 57 | 58 | return sprintf('%s/parcelshop/map/js', $apiUrl); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Block/ParcelshopInfo.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Block; 21 | 22 | class ParcelshopInfo extends \Magento\Framework\View\Element\Template 23 | { 24 | private $parcelshop; 25 | private $quote; 26 | private $countryFactory; 27 | 28 | public function __construct( 29 | \Magento\Framework\View\Element\Template\Context $context, 30 | \Magento\Directory\Model\CountryFactory $countryFactory 31 | ) { 32 | parent::__construct($context); 33 | $this->countryFactory = $countryFactory; 34 | } 35 | 36 | public function setParcelshop($parcelshop) 37 | { 38 | $this->parcelshop = $parcelshop; 39 | } 40 | 41 | public function getParcelshop() 42 | { 43 | return $this->parcelshop; 44 | } 45 | 46 | public function setQuote($quote) 47 | { 48 | $this->quote = $quote; 49 | } 50 | 51 | public function getQuote() 52 | { 53 | return $this->quote; 54 | } 55 | 56 | public function getCountry($countryCode) 57 | { 58 | $country = $this->countryFactory->create()->loadByCode($countryCode); 59 | return $country->getName(); 60 | } 61 | 62 | /** 63 | * Render the html for openinghours. (to keep template files clean from to much functional php) 64 | * 65 | * @return string 66 | */ 67 | public function getOpeningHoursHtml() 68 | { 69 | $html = ""; 70 | foreach ($this->parcelshop['openingHours'] as $openinghours) { 71 | $openingHoursMorning = $openinghours['openMorning'] . ' - ' . $openinghours['closeMorning']; 72 | $openingHoursAfternoon = $openinghours['openAfternoon'] . ' - ' . $openinghours['closeAfternoon']; 73 | 74 | if ($openingHoursMorning == '00:00 - 00:00') { 75 | $openingHoursMorning = __('Closed'); 76 | } 77 | 78 | if ($openingHoursAfternoon == '00:00 - 00:00') { 79 | $openingHoursAfternoon = __('Closed'); 80 | } 81 | 82 | $html .= ' 83 | 84 | 85 | ' . __(strtolower($openinghours['weekday'])) . ' 86 | ' . $openingHoursMorning . ' 87 | ' . $openingHoursAfternoon . ' 88 | '; 89 | } 90 | 91 | return $html; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Config/Source/Settings/ContentType.php: -------------------------------------------------------------------------------- 1 | __('Documents'), 'value' => self::CONTENT_TYPE_DOC], 19 | ['label' => __('Non documents'), 'value' => self::CONTENT_TYPE_NON_DOC] 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Config/Source/Settings/CustomsTerms.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Config\Source\Settings; 21 | 22 | use Magento\Framework\Option\ArrayInterface; 23 | 24 | class CustomsTerms implements ArrayInterface 25 | { 26 | /** 27 | * @return array 28 | */ 29 | public function toOptionArray() 30 | { 31 | return [ 32 | [ 33 | 'value' => 'DAPNP', 34 | 'label' => __('DAP NP - D&T paid by receiver'), 35 | ], 36 | [ 37 | 'value' => 'DAPDP', 38 | 'label' => __('DAP DP - D&T paid by sender'), 39 | ], 40 | ]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Config/Source/Settings/DaysInWeek.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Config\Source\Settings; 21 | 22 | use Magento\Framework\Option\ArrayInterface; 23 | 24 | class DaysInWeek implements ArrayInterface 25 | { 26 | /** 27 | * @return array 28 | */ 29 | public function toOptionArray() 30 | { 31 | $options = array( 32 | array( 33 | 'value' => '1', 34 | 'label' => __('monday'), 35 | ), 36 | array( 37 | 'value' => '2', 38 | 'label' => __('tuesday'), 39 | ), 40 | array( 41 | 'value' => '3', 42 | 'label' => __('wednesday'), 43 | ), 44 | array( 45 | 'value' => '4', 46 | 'label' => __('thursday'), 47 | ), 48 | array( 49 | 'value' => '5', 50 | 'label' => __('friday'), 51 | ), 52 | array( 53 | 'value' => '6', 54 | 'label' => __('saturday'), 55 | ), 56 | array( 57 | 'value' => '7', 58 | 'label' => __('sunday'), 59 | ), 60 | ); 61 | return $options; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Config/Source/Settings/PrintFormat.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Config\Source\Settings; 21 | 22 | use Magento\Framework\Option\ArrayInterface; 23 | 24 | class PrintFormat implements ArrayInterface 25 | { 26 | /** 27 | * Return mode option array 28 | * @return array 29 | */ 30 | public function toOptionArray() 31 | { 32 | // @codingStandardsIgnoreStart 33 | $options = [ 34 | ['value' => 'A4', 'label' => __('A4')], 35 | ['value' => 'A6', 'label' => __('A6')], 36 | ]; 37 | // @codingStandardsIgnoreEnd 38 | return $options; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Config/Source/Settings/ProductAttribute.php: -------------------------------------------------------------------------------- 1 | entityType = $entityType; 35 | $this->productAttributeCollection = $productAttributeCollection; 36 | } 37 | 38 | /** 39 | * Returns code => code pairs of attributes for all product attributes 40 | * 41 | * @return array 42 | */ 43 | public function toOptionArray() 44 | { 45 | $entityType = $this->entityType->loadByCode(ProductAttributeInterface::ENTITY_TYPE_CODE); 46 | 47 | $attributes = $this->productAttributeCollection->create(); 48 | 49 | $attributes = $attributes 50 | ->addFieldToSelect('attribute_code') 51 | ->setEntityTypeFilter($entityType->getId()) 52 | ->setOrder('attribute_code', 'ASC') 53 | ->getItems(); 54 | 55 | $attributeArray[] = [ 56 | 'label' => ' -- Please Select -- ', 57 | 'value' => '' 58 | ]; 59 | 60 | foreach ($attributes as $attribute) { 61 | $attributeArray[] = [ 62 | 'label' => $attribute->getAttributeCode(), 63 | 'value' => $attribute->getAttributeCode() 64 | ]; 65 | } 66 | 67 | return $attributeArray; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Config/Source/Settings/RateType.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Config\Source\Settings; 21 | 22 | use Magento\Framework\Option\ArrayInterface; 23 | 24 | class RateType implements ArrayInterface 25 | { 26 | /** 27 | * @return array 28 | */ 29 | public function toOptionArray() 30 | { 31 | $options = array( 32 | array( 33 | 'value' => 'flat', 34 | 'label' => __('Flat'), 35 | ), 36 | array( 37 | 'value' => 'table', 38 | 'label' => __('Table'), 39 | ), 40 | ); 41 | return $options; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Batch/Index.php: -------------------------------------------------------------------------------- 1 | resultPageFactory = $resultPageFactory; 27 | parent::__construct($context); 28 | } 29 | 30 | public function execute() 31 | { 32 | $resultPage = $this->resultPageFactory->create(); 33 | $resultPage->getConfig()->getTitle()->prepend(__('DPD - Shipment Batches')); 34 | return $resultPage; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Batch/Retry.php: -------------------------------------------------------------------------------- 1 | resultPageFactory = $resultPageFactory; 27 | parent::__construct($context); 28 | } 29 | 30 | public function execute() 31 | { 32 | $resultPage = $this->resultPageFactory->create(); 33 | $resultPage->getConfig()->getTitle()->prepend(__('DPD - Shipment Batch Jobs')); 34 | return $resultPage; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Label/Download.php: -------------------------------------------------------------------------------- 1 | shipmentLabelFactory = $shipmentLabelFactory; 44 | $this->fileFactory = $fileFactory; 45 | $this->filesystem = $filesystem; 46 | } 47 | 48 | /** 49 | * Execute action based on request and return result 50 | * 51 | * Note: Request will be added as operation argument in future 52 | * 53 | * @return ResultInterface|ResponseInterface|void 54 | */ 55 | public function execute() 56 | { 57 | $entityId = $this->getRequest()->getParam('entity_id'); 58 | $shipmentLabel = $this->shipmentLabelFactory->create(); 59 | $shipmentLabel->load($entityId); 60 | 61 | if ($shipmentLabel->getLabel() == '') { 62 | $content = $this->filesystem->read($shipmentLabel->getLabelPath()); 63 | } else { 64 | $content = $shipmentLabel->getLabel(); 65 | } 66 | 67 | $labelName = sprintf('DPD %s-%s.pdf', $shipmentLabel->getOrderIncrementId(), $shipmentLabel->getOrderId()); 68 | 69 | return $this->fileFactory->create( 70 | $labelName, 71 | $content, 72 | DirectoryList::VAR_DIR, 73 | 'application/pdf' 74 | ); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Label/Index.php: -------------------------------------------------------------------------------- 1 | resultPageFactory = $resultPageFactory; 22 | } 23 | 24 | /** 25 | * @return ResponseInterface|ResultInterface|void 26 | */ 27 | public function execute() 28 | { 29 | $resultPage = $this->resultPageFactory->create(); 30 | $resultPage->getConfig()->getTitle()->prepend(__('DPD - Shipment Labels')); 31 | return $resultPage; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Label/MassDownload.php: -------------------------------------------------------------------------------- 1 | shipmentLabelCollectionFactory = $shipmentLabelCollectionFactory; 59 | $this->filter = $filter; 60 | $this->fileFactory = $fileFactory; 61 | $this->dataHelper = $dataHelper; 62 | $this->filesystem = $filesystem; 63 | } 64 | 65 | /** 66 | * Execute action based on request and return result 67 | * 68 | * Note: Request will be added as operation argument in future 69 | * 70 | * @return ResultInterface|ResponseInterface|void 71 | */ 72 | public function execute() 73 | { 74 | $collection = $this->shipmentLabelCollectionFactory->create(); 75 | $collection = $this->filter->getCollection($collection); 76 | 77 | $labelPDFs = []; 78 | 79 | foreach ($collection as $shipmentLabel) { 80 | if ($shipmentLabel->getLabel() == '') { 81 | $content = $this->filesystem->read($shipmentLabel->getLabelPath()); 82 | } else { 83 | $content = $shipmentLabel->getLabel(); 84 | } 85 | 86 | $labelPDFs[] = $content; 87 | } 88 | 89 | $resultPDF = $this->dataHelper->combinePDFFiles($labelPDFs); 90 | 91 | return $this->fileFactory->create( 92 | 'DPD Shipping Labels.pdf', 93 | $resultPDF, 94 | DirectoryList::VAR_DIR, 95 | 'application/pdf' 96 | ); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Order/Shipment/GetShippingItemsGrid.php: -------------------------------------------------------------------------------- 1 | shipmentLoader = $shipmentLoader; 35 | parent::__construct($context); 36 | } 37 | 38 | /** 39 | * Return grid with shipping items for Ajax request 40 | * 41 | * @return ResponseInterface 42 | */ 43 | public function execute() 44 | { 45 | $this->shipmentLoader->setOrderId($this->getRequest()->getParam('order_id')); 46 | $this->shipmentLoader->setShipmentId($this->getRequest()->getParam('shipment_id')); 47 | $this->shipmentLoader->setShipment($this->getRequest()->getParam('shipment')); 48 | $this->shipmentLoader->setTracking($this->getRequest()->getParam('tracking')); 49 | $this->shipmentLoader->load(); 50 | return $this->getResponse()->setBody( 51 | $this->_view->getLayout()->createBlock( 52 | \DpdConnect\Shipping\Block\Adminhtml\Order\Packaging\Grid::class 53 | )->setIndex( 54 | $this->getRequest()->getParam('index') 55 | )->toHtml() 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Tablerate/Export.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Controller\Adminhtml\Tablerate; 21 | 22 | use Magento\Framework\App\ResponseInterface; 23 | use Magento\Config\Controller\Adminhtml\System\ConfigSectionChecker; 24 | use Magento\Framework\App\Filesystem\DirectoryList; 25 | 26 | class Export extends \Magento\Config\Controller\Adminhtml\System\AbstractConfig 27 | { 28 | /** 29 | * @var \Magento\Framework\App\Response\Http\FileFactory 30 | */ 31 | protected $_fileFactory; 32 | 33 | /** 34 | * @var \Magento\Store\Model\StoreManagerInterface 35 | */ 36 | protected $_storeManager; 37 | 38 | /** 39 | * @param \Magento\Backend\App\Action\Context $context 40 | * @param \Magento\Config\Model\Config\Structure $configStructure 41 | * @param \Magento\Config\Controller\Adminhtml\System\ConfigSectionChecker $sectionChecker 42 | * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory 43 | * @param \Magento\Store\Model\StoreManagerInterface $storeManager 44 | */ 45 | public function __construct( 46 | \Magento\Backend\App\Action\Context $context, 47 | \Magento\Config\Model\Config\Structure $configStructure, 48 | ConfigSectionChecker $sectionChecker, 49 | \Magento\Framework\App\Response\Http\FileFactory $fileFactory, 50 | \Magento\Store\Model\StoreManagerInterface $storeManager 51 | ) { 52 | $this->_storeManager = $storeManager; 53 | $this->_fileFactory = $fileFactory; 54 | parent::__construct($context, $configStructure, $sectionChecker); 55 | } 56 | 57 | /** 58 | * Export shipping table rates in csv format 59 | * 60 | * @return ResponseInterface 61 | */ 62 | public function execute() 63 | { 64 | $fileName = 'tablerates.csv'; 65 | /** @var $gridBlock \DpdConnect\Shipping\Block\Adminhtml\Tablerate\Grid */ 66 | $gridBlock = $this->_view->getLayout()->createBlock( 67 | 'DpdConnect\Shipping\Block\Adminhtml\Tablerate\Grid' 68 | ); 69 | $website = $this->_storeManager->getWebsite($this->getRequest()->getParam('website')); 70 | $shippingMethod = $this->getRequest()->getParam('shipping_method'); 71 | 72 | if ($this->getRequest()->getParam('conditionName')) { 73 | $conditionName = $this->getRequest()->getParam('conditionName'); 74 | } else { 75 | $conditionName = $website->getConfig('carriers/'.$shippingMethod.'/condition_name'); 76 | } 77 | $gridBlock->setWebsiteId($website->getId())->setConditionName($conditionName)->setShippingMethod($shippingMethod); 78 | $content = $gridBlock->getCsvFile(); 79 | 80 | return $this->_fileFactory->create($fileName, $content, DirectoryList::VAR_DIR); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Controller/Carrier/Save.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Controller\Carrier; 21 | 22 | use DpdConnect\Shipping\Helper\Data; 23 | use Magento\Framework\View\Asset\Repository; 24 | 25 | /** 26 | * Class Save 27 | * 28 | * @package DpdConnect\Shipping\Controller\Carrier 29 | */ 30 | class Save extends \Magento\Framework\App\Action\Action 31 | { 32 | /** 33 | * @var \Magento\Checkout\Model\Session 34 | */ 35 | protected $checkoutSession; 36 | /** 37 | * @var \Magento\Quote\Api\CartRepositoryInterface 38 | */ 39 | protected $quoteRepository; 40 | 41 | public function __construct( 42 | \Magento\Framework\App\Action\Context $context, 43 | \Magento\Checkout\Model\Session $checkoutSession, 44 | \Magento\Quote\Api\CartRepositoryInterface $quoteRepository 45 | ) { 46 | parent::__construct($context); 47 | $this->checkoutSession = $checkoutSession; 48 | $this->quoteRepository = $quoteRepository; 49 | } 50 | 51 | /** 52 | * Execute view action 53 | * 54 | * @return \Magento\Framework\Controller\ResultInterface 55 | */ 56 | public function execute() 57 | { 58 | $data = $this->getRequest()->getPostValue(); 59 | 60 | $quote = $this->checkoutSession->getQuote(); 61 | $quote->setData('dpd_shipping_product', $data['shippingProduct']); 62 | $this->quoteRepository->save($quote); 63 | 64 | $this->getResponse()->sendResponse(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Controller/Parcelshops/Save.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Controller\Parcelshops; 21 | 22 | use DpdConnect\Shipping\Helper\Data; 23 | use Magento\Framework\View\Asset\Repository; 24 | 25 | class Save extends \Magento\Framework\App\Action\Action 26 | { 27 | /** 28 | * @var \DpdConnect\Shipping\Helper\Data 29 | */ 30 | protected $data; 31 | 32 | /** 33 | * @var \Magento\Framework\Controller\Result\JsonFactory 34 | */ 35 | protected $resultPageFactory; 36 | 37 | /** 38 | * @var \Magento\Framework\View\Asset\Repository 39 | */ 40 | protected $assetRepo; 41 | 42 | /** 43 | * @var \Magento\Checkout\Model\Session 44 | */ 45 | protected $checkoutSession; 46 | /** 47 | * @var \Magento\Quote\Api\CartRepositoryInterface 48 | */ 49 | protected $quoteRepository; 50 | 51 | public function __construct( 52 | \Magento\Framework\App\Action\Context $context, 53 | Data $data, 54 | \Magento\Framework\View\Result\PageFactory $resultPageFactory, 55 | Repository $assetRepo, 56 | \Magento\Checkout\Model\Session $checkoutSession, 57 | \Magento\Quote\Api\CartRepositoryInterface $quoteRepository 58 | ) { 59 | parent::__construct($context); 60 | 61 | $this->data = $data; 62 | $this->resultPageFactory = $resultPageFactory; 63 | $this->assetRepo = $assetRepo; 64 | $this->checkoutSession = $checkoutSession; 65 | $this->quoteRepository = $quoteRepository; 66 | } 67 | 68 | /** 69 | * Execute view action 70 | * 71 | * @return \Magento\Framework\Controller\ResultInterface 72 | */ 73 | public function execute() 74 | { 75 | $parcelData = $this->getRequest()->getPostValue(); 76 | 77 | $resultPage = $this->resultPageFactory->create(); 78 | 79 | $quote = $this->checkoutSession->getQuote(); 80 | $quote->setData('dpd_parcelshop_id',$parcelData['parcelShopId']); 81 | $quote->setData('dpd_parcelshop_name',$parcelData['company']); 82 | $quote->setData('dpd_parcelshop_street', $parcelData['street']); 83 | $quote->setData('dpd_parcelshop_house_number', $parcelData['houseNo']); 84 | $quote->setData('dpd_parcelshop_zip_code',$parcelData['zipCode']); 85 | $quote->setData('dpd_parcelshop_city',$parcelData['city']); 86 | $quote->setData('dpd_parcelshop_country',$parcelData['isoAlpha2']); 87 | 88 | $this->quoteRepository->save($quote); 89 | 90 | $block = $resultPage->getLayout() 91 | ->createBlock('DpdConnect\Shipping\Block\ParcelshopInfo') 92 | ->setTemplate('DpdConnect_Shipping::checkout/shipping/parcelshop-info.phtml'); 93 | $block->setParcelshop($parcelData); 94 | $block->setQuote($quote); 95 | $blockHtml = $block->toHtml(); 96 | $this->getResponse()->setBody($blockHtml); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /DpdException.php: -------------------------------------------------------------------------------- 1 | getMessageString($message); 21 | // @codingStandardsIgnoreLine 22 | $this->exceptionMessage = __($message); 23 | if ($code !== 0) { 24 | $code = (string) $code; 25 | $this->code = $code; 26 | $message = '[' . $code . '] ' . $message; 27 | } 28 | if (is_string($message)) { 29 | // @codingStandardsIgnoreLine 30 | $message = __($message); 31 | } 32 | parent::__construct($message, $previous); 33 | } 34 | // @codingStandardsIgnoreEnd 35 | 36 | /** 37 | * @param $message 38 | * 39 | * @return string 40 | */ 41 | private function getMessageString($message) 42 | { 43 | if ($message instanceof Phrase) { 44 | return $message->render(); 45 | } 46 | 47 | return $message; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Helper/Constants.php: -------------------------------------------------------------------------------- 1 | magentoCache = $magentoCache; 19 | } 20 | 21 | public function setCache($key, $data, $expire) 22 | { 23 | $this->magentoCache->save(serialize($data), $key, [], $expire); 24 | } 25 | 26 | public function getCache($key) 27 | { 28 | $data = unserialize($this->magentoCache->load($key)); 29 | 30 | return $data; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Helper/TrackingPopup.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Helper; 21 | 22 | use Magento\Framework\App\Config\ScopeConfigInterface; 23 | use Magento\Framework\App\Helper\AbstractHelper; 24 | 25 | class TrackingPopup extends AbstractHelper 26 | { 27 | public function __construct(\Magento\Framework\App\Helper\Context $context) 28 | { 29 | parent::__construct($context); 30 | } 31 | 32 | public function getCarrierTitle() 33 | { 34 | $carrierCode = 'dpdpredict'; 35 | 36 | $carrierTitle = $this->scopeConfig->getValue( 37 | 'carriers/' . $carrierCode . '/title', 38 | \Magento\Store\Model\ScopeInterface::SCOPE_STORE 39 | ); 40 | 41 | return $carrierTitle; 42 | } 43 | 44 | public function getErrorMessage() 45 | { 46 | return __('Tracking not available'); 47 | } 48 | 49 | public function getProgressdetail() 50 | { 51 | return ''; 52 | } 53 | 54 | public function getTracking() 55 | { 56 | return ''; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Model/ApiCallback.php: -------------------------------------------------------------------------------- 1 | batchManager = $batchManager; 46 | $this->orderCollectionFactory = $orderCollectionFactory; 47 | $this->shipmentLabelService = $shipmentLabelService; 48 | $this->shipmentManager = $shipmentManager; 49 | } 50 | 51 | /** 52 | * @return mixed 53 | */ 54 | public function sendCallback() 55 | { 56 | $body = file_get_contents('php://input'); 57 | $data = json_decode($body, true); 58 | 59 | $orderId = $data['shipment']['orderId']; 60 | $jobId = $data['jobid']; 61 | $parcelNumber = $data['shipment']['trackingInfo']['parcelNumbers'][0]; 62 | $shipmentIdentifier = $data['shipment']['trackingInfo']['shipmentIdentifier']; 63 | $isReturn = $data['shipment']['product']['productCode'] === 'RETURN'; 64 | $errors = $data['error']; 65 | 66 | $orderCollection = $this->orderCollectionFactory->create(); 67 | /** @var Order $order */ 68 | $order = $orderCollection->addFieldToFilter('increment_id', $orderId)->getFirstItem(); 69 | $job = $this->batchManager->getJobById($jobId); 70 | $batch = $this->batchManager->getBatchById($job->getBatchId()); 71 | 72 | // Get the correct shipment 73 | $shipment = null; 74 | if (isset($data['shipment']['parcels'][0]['customerReferences'][3])) { 75 | $shipmentId = $data['shipment']['parcels'][0]['customerReferences'][3]; 76 | if (is_numeric($shipmentId)) { 77 | $shipment = $order->getShipmentsCollection()->getItemById($shipmentId); 78 | } 79 | } 80 | 81 | // Default to the first shipment 82 | if (null === $shipment) { 83 | $shipment = $order->getShipmentsCollection()->getFirstItem(); 84 | } 85 | 86 | $job->setOrderId($order->getEntityId()); 87 | $job->setOrderIncrementId($order->getIncrementId()); 88 | $job->setShipmentId($shipment->getEntityId()); 89 | $job->setShipmentIncrementId($shipment->getIncrementId()); 90 | 91 | if (count($errors) > 0) { 92 | $batch->setStatus(BatchManager::STATUS_FAILED); 93 | $job->setStatus(BatchManager::STATUS_FAILED); 94 | $batch->getResource()->save($batch); 95 | $job->getResource()->save($job); 96 | return; 97 | } 98 | 99 | $label = $this->shipmentLabelService->getLabel($parcelNumber); 100 | $this->shipmentLabelService->saveLabel($order, $shipment, $shipmentIdentifier, [$parcelNumber], $label, $isReturn); 101 | 102 | $this->shipmentManager->addTrackingNumbersToShipment($shipment, [$parcelNumber]); 103 | 104 | $job->setStatus(BatchManager::STATUS_SUCCESS); 105 | $batch->setStatus(BatchManager::STATUS_SUCCESS); 106 | $batch->getResource()->save($batch); 107 | $job->getResource()->save($job); 108 | return; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Model/Attribute/Backend/ShippingDescription.php: -------------------------------------------------------------------------------- 1 | getData('dpd_shipping_type'); 18 | if (true === in_array($selectedDpdShippingProduct, ['fresh', 'freeze'])) { 19 | $value = $object->getData($this->getAttribute()->getAttributeCode()); 20 | 21 | if ('' === $value || null === $value) { 22 | return false; 23 | } 24 | } 25 | 26 | return true; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Model/Attribute/Source/DefaultPackageTypeOptions.php: -------------------------------------------------------------------------------- 1 | _options) { 14 | $this->_options[] = [ 15 | 'label' => __('Small Parcel'), 16 | 'value' => '015010010' 17 | ]; 18 | 19 | $this->_options[] = [ 20 | 'label' => __('Normal Parcel'), 21 | 'value' => '100050050' 22 | ]; 23 | } 24 | 25 | return $this->_options; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Model/Attribute/Source/ShippingType.php: -------------------------------------------------------------------------------- 1 | client = $client; 19 | } 20 | 21 | /** 22 | * Get all options 23 | * @return array 24 | */ 25 | public function getAllOptions() 26 | { 27 | if (!$this->_options) { 28 | $availableProducts = $this->client->authenticate()->getProduct()->getList(); 29 | $availableCodes = array_map(function($product) { 30 | return $product['code']; 31 | }, $availableProducts); 32 | 33 | $this->_options = [ 34 | ['label' => __('Default'), 'value' => 'default'], 35 | ]; 36 | 37 | if (true === in_array('FRESH', $availableCodes)) { 38 | $this->_options[] = ['label' => __('Fresh'), 'value' => 'fresh']; 39 | } 40 | 41 | if (true === in_array('FREEZE', $availableCodes)) { 42 | $this->_options[] = ['label' => __('Freeze'), 'value' => 'freeze']; 43 | } 44 | } 45 | 46 | return $this->_options; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Model/Batch.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Model; 21 | 22 | use Magento\Framework\Model\AbstractModel; 23 | 24 | class Batch extends AbstractModel 25 | { 26 | protected function _construct() 27 | { 28 | $this->_init(\DpdConnect\Shipping\Model\ResourceModel\Batch::class); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Model/BatchJob.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Model; 21 | 22 | use Magento\Framework\Model\AbstractModel; 23 | 24 | class BatchJob extends AbstractModel 25 | { 26 | protected function _construct() 27 | { 28 | $this->_init(\DpdConnect\Shipping\Model\ResourceModel\BatchJob::class); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Model/Config/Backend/CustomerProduct.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Model\Config\Backend; 21 | 22 | use Magento\Config\Model\Config\Backend\Serialized\ArraySerialized; 23 | 24 | /** 25 | * Backend model for handling the customer products 26 | */ 27 | class CustomerProduct extends ArraySerialized 28 | { 29 | /** 30 | * @var \DpdConnect\Shipping\Model\ResourceModel\Carrier\TablerateFactory 31 | */ 32 | protected $_tablerateFactory; 33 | 34 | /** 35 | * @param \Magento\Framework\Model\Context $context 36 | * @param \Magento\Framework\Registry $registry 37 | * @param \Magento\Framework\App\Config\ScopeConfigInterface $config 38 | * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList 39 | * @param \DpdConnect\Shipping\Model\ResourceModel\TablerateFactory $tablerateFactory 40 | * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource 41 | * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection 42 | * @param array $data 43 | */ 44 | public function __construct( 45 | \Magento\Framework\Model\Context $context, 46 | \Magento\Framework\Registry $registry, 47 | \Magento\Framework\App\Config\ScopeConfigInterface $config, 48 | \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList, 49 | \DpdConnect\Shipping\Model\ResourceModel\TablerateFactory $tablerateFactory, 50 | \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, 51 | \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, 52 | array $data = [] 53 | ) { 54 | $this->_tablerateFactory = $tablerateFactory; 55 | parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data); 56 | } 57 | 58 | /** 59 | * @return CustomerProduct 60 | */ 61 | public function beforeSave() 62 | { 63 | // Remove the import field from the config 64 | $value = $this->getValue(); 65 | foreach ($value as $productCode => $data) { 66 | unset($value[$productCode]['import']); 67 | } 68 | 69 | $this->setValue($value); 70 | 71 | return parent::beforeSave(); 72 | } 73 | 74 | /** 75 | * @return $this 76 | */ 77 | public function afterSave() 78 | { 79 | if ($this->_registry->registry('dpd_import_processed')) { 80 | return parent::afterSave(); 81 | } 82 | 83 | $this->_registry->register('dpd_import_processed', true); 84 | /** @var \DpdConnect\Shipping\Model\ResourceModel\Tablerate $tableRate */ 85 | $tableRate = $this->_tablerateFactory->create(); 86 | $tableRate->uploadAndImport($this); 87 | 88 | return parent::afterSave(); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Model/Config/Tablerate.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Model\Config; 21 | 22 | use Magento\Framework\Model\AbstractModel; 23 | 24 | /** 25 | * Backend model for shipping table rates CSV importing 26 | * 27 | * @author Magento Core Team 28 | */ 29 | class Tablerate extends \Magento\Framework\App\Config\Value 30 | { 31 | /** 32 | * @var \DpdConnect\Shipping\Model\ResourceModel\Carrier\TablerateFactory 33 | */ 34 | protected $_tablerateFactory; 35 | /** 36 | * @param \Magento\Framework\Model\Context $context 37 | * @param \Magento\Framework\Registry $registry 38 | * @param \Magento\Framework\App\Config\ScopeConfigInterface $config 39 | * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList 40 | * @param \DpdConnect\Shipping\Model\ResourceModel\TablerateFactory $tablerateFactory 41 | * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource 42 | * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection 43 | * @param array $data 44 | */ 45 | public function __construct( 46 | \Magento\Framework\Model\Context $context, 47 | \Magento\Framework\Registry $registry, 48 | \Magento\Framework\App\Config\ScopeConfigInterface $config, 49 | \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList, 50 | \DpdConnect\Shipping\Model\ResourceModel\TablerateFactory $tablerateFactory, 51 | \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, 52 | \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, 53 | array $data = [] 54 | ) { 55 | $this->_tablerateFactory = $tablerateFactory; 56 | parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data); 57 | } 58 | /** 59 | * @return $this 60 | */ 61 | public function afterSave() 62 | { 63 | if ($this->_registry->registry('dpd_import_processed')) { 64 | return parent::afterSave(); 65 | } 66 | 67 | $this->_registry->register('dpd_import_processed', true); 68 | /** @var \DpdConnect\Shipping\Model\ResourceModel\Tablerate $tableRate */ 69 | $tableRate = $this->_tablerateFactory->create(); 70 | $tableRate->uploadAndImport($this); 71 | 72 | return parent::afterSave(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Model/ResourceModel/Batch.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Model\ResourceModel; 21 | 22 | use Magento\Framework\Model\ResourceModel\Db\AbstractDb; 23 | use Magento\Framework\Model\ResourceModel\Db\Context; 24 | 25 | class Batch extends AbstractDb 26 | { 27 | public function __construct(Context $context) 28 | { 29 | parent::__construct($context); 30 | } 31 | 32 | protected function _construct() 33 | { 34 | $this->_init('dpdconnect_shipping_batch', 'entity_id'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Model/ResourceModel/Batch/Collection.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Model\ResourceModel\Batch; 21 | 22 | use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection; 23 | 24 | class Collection extends AbstractCollection 25 | { 26 | protected $_idFieldName = 'entity_id'; 27 | protected $_eventPrefix = 'dpdconnect_shipping_batch_collection'; 28 | protected $_eventObject = 'dpd_batch_collection'; 29 | 30 | /** 31 | * Define resource model and item 32 | * 33 | * @return void 34 | */ 35 | protected function _construct() 36 | { 37 | $this->_init( 38 | \DpdConnect\Shipping\Model\Batch::class, 39 | \DpdConnect\Shipping\Model\ResourceModel\Batch::class 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Model/ResourceModel/BatchJob.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Model\ResourceModel; 21 | 22 | use Magento\Framework\Model\ResourceModel\Db\AbstractDb; 23 | use Magento\Framework\Model\ResourceModel\Db\Context; 24 | 25 | class BatchJob extends AbstractDb 26 | { 27 | public function __construct(Context $context) 28 | { 29 | parent::__construct($context); 30 | } 31 | 32 | protected function _construct() 33 | { 34 | $this->_init('dpdconnect_shipping_batch_job', 'entity_id'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Model/ResourceModel/BatchJob/Collection.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Model\ResourceModel\BatchJob; 21 | 22 | use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection; 23 | 24 | class Collection extends AbstractCollection 25 | { 26 | protected $_idFieldName = 'entity_id'; 27 | protected $_eventPrefix = 'dpdconnect_shipping_batch_job_collection'; 28 | protected $_eventObject = 'dpd_batch_job_collection'; 29 | 30 | /** 31 | * Define resource model and item 32 | * 33 | * @return void 34 | */ 35 | protected function _construct() 36 | { 37 | $this->_init( 38 | \DpdConnect\Shipping\Model\BatchJob::class, 39 | \DpdConnect\Shipping\Model\ResourceModel\BatchJob::class 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Model/ResourceModel/ShipmentLabel.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Model\ResourceModel; 21 | 22 | use Magento\Framework\Model\ResourceModel\Db\AbstractDb; 23 | use Magento\Framework\Model\ResourceModel\Db\Context; 24 | 25 | class ShipmentLabel extends AbstractDb 26 | { 27 | public function __construct(Context $context) 28 | { 29 | parent::__construct($context); 30 | } 31 | 32 | protected function _construct() 33 | { 34 | $this->_init('dpdconnect_shipping_label', 'entity_id'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Model/ResourceModel/ShipmentLabel/Collection.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Model\ResourceModel\ShipmentLabel; 21 | 22 | use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection; 23 | 24 | class Collection extends AbstractCollection 25 | { 26 | protected $_idFieldName = 'entity_id'; 27 | protected $_eventPrefix = 'dpdconnect_shipping_label_collection'; 28 | protected $_eventObject = 'dpd_shipment_collection'; 29 | 30 | /** 31 | * Define resource model and item 32 | * 33 | * @return void 34 | */ 35 | protected function _construct() 36 | { 37 | $this->_init( 38 | \DpdConnect\Shipping\Model\ShipmentLabel::class, 39 | \DpdConnect\Shipping\Model\ResourceModel\ShipmentLabel::class 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Model/ResourceModel/Tablerate/Collection.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Model\ResourceModel\Tablerate; 21 | 22 | class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection 23 | { 24 | /** 25 | * Directory/country table name 26 | * 27 | * @var string 28 | */ 29 | protected $_countryTable; 30 | 31 | /** 32 | * Directory/country_region table name 33 | * 34 | * @var string 35 | */ 36 | protected $_regionTable; 37 | 38 | /** 39 | * Define resource model and item 40 | * 41 | * @return void 42 | */ 43 | protected function _construct() 44 | { 45 | $this->_init( 46 | 'DpdConnect\Shipping\Model\Tablerate', 47 | 'DpdConnect\Shipping\Model\ResourceModel\Tablerate' 48 | ); 49 | $this->_countryTable = $this->getTable('directory_country'); 50 | $this->_regionTable = $this->getTable('directory_country_region'); 51 | } 52 | 53 | /** 54 | * Initialize select, add country iso3 code and region name 55 | * 56 | * @return void 57 | */ 58 | public function _initSelect() 59 | { 60 | parent::_initSelect(); 61 | 62 | $this->_select->joinLeft( 63 | ['country_table' => $this->_countryTable], 64 | 'country_table.country_id = main_table.dest_country_id', 65 | ['dest_country' => 'iso3_code'] 66 | )->joinLeft( 67 | ['region_table' => $this->_regionTable], 68 | 'region_table.region_id = main_table.dest_region_id', 69 | ['dest_region' => 'code'] 70 | ); 71 | 72 | $this->addOrder('dest_country', self::SORT_ORDER_ASC); 73 | $this->addOrder('dest_region', self::SORT_ORDER_ASC); 74 | $this->addOrder('dest_zip', self::SORT_ORDER_ASC); 75 | $this->addOrder('condition_value', self::SORT_ORDER_ASC); 76 | } 77 | 78 | /** 79 | * Add website filter to collection 80 | * 81 | * @param int $websiteId 82 | * @return \Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate\Collection 83 | */ 84 | public function setWebsiteFilter($websiteId) 85 | { 86 | return $this->addFieldToFilter('website_id', $websiteId); 87 | } 88 | 89 | /** 90 | * Add condition name (code) filter to collection 91 | * 92 | * @param string $conditionName 93 | * @return \Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate\Collection 94 | */ 95 | public function setConditionFilter($conditionName) 96 | { 97 | return $this->addFieldToFilter('condition_name', $conditionName); 98 | } 99 | 100 | /** 101 | * Add country filter to collection 102 | * 103 | * @param string $countryId 104 | * @return \Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate\Collection 105 | */ 106 | public function setCountryFilter($countryId) 107 | { 108 | return $this->addFieldToFilter('dest_country_id', $countryId); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Model/ResourceModel/Tablerate/DataHashGenerator.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Model; 21 | 22 | use Magento\Framework\Model\AbstractModel; 23 | 24 | class ShipmentLabel extends AbstractModel 25 | { 26 | protected function _construct() 27 | { 28 | $this->_init(\DpdConnect\Shipping\Model\ResourceModel\ShipmentLabel::class); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Model/Tablerate.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Model; 21 | 22 | class Tablerate extends \Magento\OfflineShipping\Model\Carrier\Tablerate 23 | { 24 | protected function _construct() 25 | { 26 | $this->_init('dpdconnect_shipping_tablerate', 'entity_id'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Observer/SalesOrderAddressSaveBefore.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Observer; 21 | 22 | use Magento\Framework\Event\ObserverInterface; 23 | use Magento\Sales\Model\Order; 24 | use Magento\Sales\Model\Order\Address; 25 | use Magento\Sales\Model\OrderRepository; 26 | 27 | class SalesOrderAddressSaveBefore implements ObserverInterface 28 | { 29 | /** 30 | * @var \Magento\Framework\App\State 31 | */ 32 | private $state; 33 | 34 | /** 35 | * @var \Magento\Framework\App\Config\ScopeConfigInterface 36 | */ 37 | protected $scopeConfig; 38 | 39 | public function __construct( 40 | \Magento\Framework\App\State $state, 41 | \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig 42 | ) 43 | { 44 | $this->state = $state; 45 | $this->scopeConfig = $scopeConfig; 46 | } 47 | 48 | public function execute(\Magento\Framework\Event\Observer $observer) 49 | { 50 | // Ignore adminhtml 51 | if ($this->state->getAreaCode() == \Magento\Framework\App\Area::AREA_ADMINHTML) { 52 | return; 53 | } 54 | 55 | $shippingAddress = $observer->getEvent()->getAddress(); 56 | /** @var Address $shippingAddress */ 57 | 58 | $order = $shippingAddress->getOrder(); 59 | /** @var Order $order */ 60 | 61 | // Ignore all orders that aren't dpd pickup 62 | if ($order->getShippingMethod() != 'dpdpickup_dpdpickup') { 63 | return; 64 | } 65 | 66 | // If the address isn't the shipping address 67 | if ($shippingAddress->getAddressType() != 'shipping') { 68 | return; 69 | } 70 | 71 | $shippingAddress->setFirstname('DPD ParcelShop:'); 72 | $shippingAddress->setLastname($order->getDpdParcelshopName()); 73 | $shippingAddress->setStreet($order->getDpdParcelshopStreet().' '.$order->getDpdParcelshopHouseNumber()); 74 | $shippingAddress->setCity($order->getDpdParcelshopCity()); 75 | $shippingAddress->setPostcode($order->getDpdParcelshopZipCode()); 76 | $shippingAddress->setCountryId($order->getDpdParcelshopCountry()); 77 | $shippingAddress->setCompany(''); 78 | 79 | if($this->scopeConfig->getValue('dpdshipping/advanced/picqer_mode')) { 80 | $shippingAddress->setFirstname($order->getBillingAddress()->getFirstname()); 81 | $shippingAddress->setLastname($order->getBillingAddress()->getLastname()); 82 | $shippingAddress->setCompany('DPD ParcelShop: ' . $order->getDpdParcelshopName()); 83 | } 84 | 85 | // empty this otherwise you'd get customer data and DPD parcelshop data mixed up 86 | $shippingAddress->setTelephone(''); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Observer/SalesOrderSaveBefore.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Observer; 21 | 22 | use Magento\Framework\Event\ObserverInterface; 23 | use Magento\Quote\Model\QuoteRepository; 24 | use Magento\Sales\Model\Order; 25 | use Magento\Sales\Model\OrderRepository; 26 | 27 | class SalesOrderSaveBefore implements ObserverInterface 28 | { 29 | /** 30 | * @var QuoteRepository 31 | */ 32 | private $quoteRepository; 33 | 34 | /** 35 | * @var \Magento\Framework\App\State 36 | */ 37 | private $state; 38 | 39 | public function __construct( 40 | QuoteRepository $quoteRepository, 41 | \Magento\Framework\App\State $state 42 | ) { 43 | $this->quoteRepository = $quoteRepository; 44 | $this->state = $state; 45 | } 46 | 47 | public function execute(\Magento\Framework\Event\Observer $observer) 48 | { 49 | // Ignore adminhtml 50 | if ($this->state->getAreaCode() == \Magento\Framework\App\Area::AREA_ADMINHTML) { 51 | $this->processAdminHtml($observer->getEvent()->getOrder()); 52 | return; 53 | } 54 | 55 | $this->processFrontend($observer->getEvent()->getOrder()); 56 | } 57 | 58 | /** 59 | * @param Order $order 60 | */ 61 | private function processAdminHtml(Order $order) 62 | { 63 | $shippingMethod = $order->getShippingMethod(); 64 | if (false === strpos($shippingMethod, 'dpd_')) { 65 | return; 66 | } 67 | 68 | if ('dpd_dpd' === $shippingMethod) { 69 | return; 70 | } 71 | 72 | $order->setShippingMethod('dpd_dpd'); 73 | 74 | $shippingMethodParts = explode('_', $shippingMethod); 75 | $order->setDpdShippingProduct($shippingMethodParts[1]); 76 | } 77 | 78 | /** 79 | * @param Order $order 80 | */ 81 | private function processFrontend(Order $order) 82 | { 83 | if (false === in_array($order->getShippingMethod(), ['dpd_dpd', 'dpdpickup_dpdpickup'])) { 84 | return; 85 | } 86 | 87 | $quoteId = $order->getQuoteId(); 88 | 89 | try { 90 | $quote = $this->quoteRepository->get($quoteId); 91 | } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { 92 | // Happens when the order has already been placed in which case this event has already 93 | // been called succesfully 94 | return; 95 | } 96 | 97 | if ('dpdpickup_dpdpickup' === $order->getShippingMethod()) { 98 | // Happens when editing old orders before 1.0.7 99 | if ($quote->getData('dpd_parcelshop_id') == '') { 100 | return; 101 | } 102 | 103 | $order->setDpdParcelshopId($quote->getData('dpd_parcelshop_id')); 104 | $order->setDpdParcelshopName($quote->getData('dpd_parcelshop_name')); 105 | $order->setDpdParcelshopStreet($quote->getData('dpd_parcelshop_street')); 106 | $order->setDpdParcelshopHouseNumber($quote->getData('dpd_parcelshop_house_number')); 107 | $order->setDpdParcelshopZipCode($quote->getData('dpd_parcelshop_zip_code')); 108 | $order->setDpdParcelshopCity($quote->getData('dpd_parcelshop_city')); 109 | $order->setDpdParcelshopCountry($quote->getData('dpd_parcelshop_country')); 110 | } 111 | 112 | if ('dpd_dpd' === $order->getShippingMethod()) { 113 | $order->setDpdShippingProduct($quote->getData('dpd_shipping_product')); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Observer/SalesOrderShipmentSaveBefore.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | namespace DpdConnect\Shipping\Observer; 21 | 22 | use DpdConnect\Shipping\Helper\Data; 23 | use Magento\Framework\Event\ObserverInterface; 24 | 25 | class SalesOrderShipmentSaveBefore implements ObserverInterface 26 | { 27 | /** 28 | * @var \Magento\Framework\App\State 29 | */ 30 | private $state; 31 | 32 | /** 33 | * @var Data 34 | */ 35 | private $dataHelper; 36 | 37 | /** 38 | * @param Data $dataHelper 39 | * @param \Magento\Framework\App\State $state 40 | */ 41 | public function __construct( 42 | Data $dataHelper, 43 | \Magento\Framework\App\State $state 44 | ) { 45 | $this->state = $state; 46 | $this->dataHelper = $dataHelper; 47 | } 48 | 49 | /** 50 | * @throws \Magento\Framework\Exception\LocalizedException 51 | * @throws \Exception 52 | */ 53 | public function execute(\Magento\Framework\Event\Observer $observer) 54 | { 55 | // Ignore frontend 56 | if ($this->state->getAreaCode() === \Magento\Framework\App\Area::AREA_FRONTEND) { 57 | return; 58 | } 59 | 60 | $shipment = $observer->getShipment(); 61 | if (false === $this->dataHelper->isDPDOrder($shipment->getOrder())) { 62 | return; 63 | } 64 | 65 | /** @var \Magento\Framework\UrlInterface $urlInterface */ 66 | $urlInterface = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Framework\UrlInterface'); 67 | if (false !== stripos($urlInterface->getCurrentUrl(), 'dpd_shipping')) { 68 | return; 69 | } 70 | 71 | if (true === $this->dataHelper->hasDpdFreshProducts($shipment->getOrder())) { 72 | throw new \Exception('This order has DPD Fresh/Freeze products, shipments can only be made through the order overview or the packages screen.'); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Plugin/Api/Data/OrderInterfacePlugin.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | declare(strict_types=1); 21 | 22 | namespace DpdConnect\Shipping\Plugin\Api\Data; 23 | 24 | use Magento\Sales\Api\Data\OrderExtensionFactory; 25 | use Magento\Sales\Api\Data\OrderExtensionInterface; 26 | use Magento\Sales\Api\Data\OrderInterface; 27 | 28 | class OrderInterfacePlugin 29 | { 30 | /** @var OrderExtensionFactory $extensionFactory */ 31 | private $extensionFactory; 32 | 33 | /** 34 | * @param OrderExtensionFactory $extensionFactory 35 | */ 36 | public function __construct(OrderExtensionFactory $extensionFactory) 37 | { 38 | $this->extensionFactory = $extensionFactory; 39 | } 40 | 41 | /** 42 | * @param OrderInterface $entity 43 | * @param OrderExtensionInterface|null $extensionAttributes 44 | * 45 | * @return OrderExtensionInterface 46 | */ 47 | public function afterGetExtensionAttributes( 48 | OrderInterface $entity, 49 | OrderExtensionInterface $extensionAttributes = null 50 | ): OrderExtensionInterface { 51 | if ($extensionAttributes === null) { 52 | $extensionAttributes = $this->extensionFactory->create(); 53 | $entity->setExtensionAttributes($extensionAttributes); 54 | } 55 | 56 | return $extensionAttributes; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Plugin/Api/OrderRepositoryInterfacePlugin.php: -------------------------------------------------------------------------------- 1 | . 19 | */ 20 | declare(strict_types=1); 21 | 22 | namespace DpdConnect\Shipping\Plugin\Api; 23 | 24 | use Magento\Sales\Api\Data\OrderInterface; 25 | use Magento\Sales\Api\OrderRepositoryInterface; 26 | use Magento\Sales\Model\ResourceModel\Order\Collection; 27 | 28 | class OrderRepositoryInterfacePlugin 29 | { 30 | /** 31 | * @param OrderRepositoryInterface $orderRepository 32 | * @param Collection $collection 33 | * 34 | * @return Collection 35 | */ 36 | public function afterGetList(OrderRepositoryInterface $orderRepository, Collection $collection): Collection 37 | { 38 | foreach ($collection->getItems() as $order) { 39 | /** @var OrderInterface $order */ 40 | 41 | $this->afterGet($orderRepository, $order); 42 | } 43 | 44 | return $collection; 45 | } 46 | 47 | /** 48 | * @param OrderRepositoryInterface $orderRepository 49 | * @param OrderInterface $entity 50 | * 51 | * @return OrderInterface 52 | */ 53 | public function afterGet(OrderRepositoryInterface $orderRepository, OrderInterface $entity): OrderInterface 54 | { 55 | $extensionAttributes = $entity->getExtensionAttributes(); 56 | $extensionAttributes->setDpdParcelshopId($entity->getData('dpd_parcelshop_id')); 57 | $entity->setExtensionAttributes($extensionAttributes); 58 | 59 | return $entity; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Installation 2 | ------------ 3 | 4 | ```bash 5 | composer require dpdconnect/magento2-shipping 6 | ``` 7 | 8 | Upgrade 9 | ------- 10 | 11 | ```bash 12 | composer update dpdconnect/magento2-shipping 13 | ``` 14 | 15 | After upgrade or install 16 | ------------------------ 17 | 18 | ```bash 19 | php bin/magento module:enable DpdConnect_Shipping 20 | ``` 21 | ```bash 22 | php bin/magento setup:upgrade 23 | ``` 24 | ```bash 25 | php bin/magento setup:di:compile 26 | ``` 27 | ```bash 28 | php bin/magento setup:static-content:deploy 29 | ``` 30 | 31 | Magento 2 Shipping module by DPDC 32 | 33 | 34 | FAQ 35 | -- 36 | 37 | * I get a "Bad credentials" error when printing a label 38 | > If you use the env.php to specify the username and password make sure to use `bin/magento config:sensitive:set` to specify the password. 39 | > The password has be encrypted in the env.php as well. -------------------------------------------------------------------------------- /Services/GoogleMaps.php: -------------------------------------------------------------------------------- 1 | data = $data; 25 | $this->logger = $logger; 26 | } 27 | 28 | /** 29 | * @param string $postcode 30 | * @param string $countryId 31 | * @return array|null 32 | */ 33 | public function getGoogleMapsCenter($postcode, $countryId) 34 | { 35 | try { 36 | $addressToInsert = 'country:' . $countryId . '|postal_code:' . $postcode; 37 | $result = $this->doGeocodeRequest([ 38 | 'components' => $addressToInsert, 39 | 'sensor' => 'false' 40 | ]); 41 | $latitude = $result->results[0]->geometry->location->lat; 42 | $longitude = $result->results[0]->geometry->location->lng; 43 | 44 | return [$latitude, $longitude]; 45 | 46 | } catch (\Exception $ex) { 47 | $this->logger->log('[DpdConnect_Shipping::GoogleMaps::getGoogleMapsCenterByQuery] ' . $ex->getMessage()); 48 | return null; 49 | } 50 | } 51 | 52 | /** 53 | * @param string $query 54 | * @return array|null 55 | */ 56 | public function getGoogleMapsCenterByQuery($query) 57 | { 58 | try { 59 | $result = $this->doGeocodeRequest([ 60 | 'address' => $query, 61 | 'sensor' => 'false' 62 | ]); 63 | 64 | $latitude = $result->results[0]->geometry->location->lat; 65 | $longitude = $result->results[0]->geometry->location->lng; 66 | 67 | return [$latitude, $longitude]; 68 | 69 | } catch (\Exception $ex) { 70 | $this->logger->log('[DpdConnect_Shipping::GoogleMaps::getGoogleMapsCenterByQuery] ' . $ex->getMessage()); 71 | return null; 72 | } 73 | } 74 | 75 | /** 76 | * @param array $fields 77 | * @return mixed 78 | */ 79 | protected function doGeocodeRequest($fields) 80 | { 81 | $apiKey = $this->data->getGoogleServerApiKey(); 82 | $url = static::GOOGLE_MAPS_API_BASE . 'geocode/json?key=' . $apiKey . '&' . http_build_query($fields); 83 | 84 | $ch = curl_init($url); 85 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 86 | $response = curl_exec($ch); 87 | curl_close($ch); 88 | 89 | return json_decode($response); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Ui/Component/BatchJobProvider.php: -------------------------------------------------------------------------------- 1 | request = $request; 27 | $this->collection = $collectionFactory->create(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Ui/Component/BatchProvider.php: -------------------------------------------------------------------------------- 1 | collection = $collectionFactory->create(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Ui/Component/Listing/Column/ShipmentLabelActions.php: -------------------------------------------------------------------------------- 1 | urlBuilder = $urlBuilder; 26 | $this->storeManager = $storeManager; 27 | parent::__construct($context, $uiComponentFactory, $components, $data); 28 | } 29 | 30 | public function prepareDataSource(array $dataSource) 31 | { 32 | if (isset($dataSource['data']['items'])) { 33 | foreach ($dataSource['data']['items'] as & $item) { 34 | $download = $this->urlBuilder->getUrl( 35 | 'dpd_shipping/label/download', 36 | [ 37 | 'entity_id' => $item['entity_id'], 38 | ] 39 | ); 40 | 41 | $item[$this->getData('name')] = [ 42 | 'view' => [ 43 | 'href' => $download, 44 | 'label' => __('Download') 45 | ] 46 | ]; 47 | } 48 | } 49 | 50 | return $dataSource; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Ui/Component/ShipmentLabelProvider.php: -------------------------------------------------------------------------------- 1 | collection = $collectionFactory->create(); 17 | } 18 | 19 | public function getData() 20 | { 21 | $data = parent::getData(); 22 | 23 | 24 | if (isset($data['items'])) { 25 | foreach ($data['items'] as &$item) { 26 | 27 | // Empty it because magento can't handle blob's in grids, it's not shown anyway 28 | $item['label'] = ''; 29 | 30 | if ($item['is_return']) { 31 | $item['is_return'] = __('Yes'); 32 | } else { 33 | $item['is_return'] = __('No'); 34 | } 35 | } 36 | } 37 | return $data; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Ui/Component/Shipping/CreateShipmentAction.php: -------------------------------------------------------------------------------- 1 | getConfiguration(); 11 | $context = $this->getContext(); 12 | 13 | $config['url'] = $context->getUrl( 14 | $config['createShipmentAction'], 15 | ['order_id' => $context->getRequestParam('order_id')] 16 | ); 17 | $this->setData('config', (array)$config); 18 | parent::prepare(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dpdconnect/magento2-shipping", 3 | "description": "DPD Connect - Magento2 Shipping", 4 | "require": { 5 | "php": ">=7.2", 6 | "magento/framework": ">=103.0.6", 7 | "dpdconnect/php-sdk": "^1.1" 8 | }, 9 | "type": "magento2-module", 10 | "license": "GPL-3.0-or-later", 11 | "authors": [ 12 | { 13 | "name": "DPD", 14 | "email": "pluginsupport@dpd.nl", 15 | "homepage": "http://www.dpd.nl" 16 | } 17 | ], 18 | "support": { 19 | "email": "pluginsupport@dpd.nl", 20 | "issues": "http://www.dpd.nl/" 21 | }, 22 | "homepage": "https://www.dpd.com/nl/business_customers/hulp_en_tools/e_commerce/magento", 23 | "keywords": ["dpd", "dpd parcelservice", "Magento2"], 24 | "minimum-stability": "stable", 25 | "autoload": { 26 | "files": [ 27 | "registration.php" 28 | ], 29 | "psr-4": { 30 | "DpdConnect\\Shipping\\": "" 31 | } 32 | }, 33 | "require-dev": { 34 | "magento/marketplace-eqp": "^2.0", 35 | "overtrue/phplint": "^1.1" 36 | }, 37 | "repositories": { 38 | "magento": { 39 | "type": "composer", 40 | "url": "https://repo.magento.com/" 41 | } 42 | }, 43 | "config": { 44 | "allow-plugins": { 45 | "dealerdirect/phpcodesniffer-composer-installer": true, 46 | "magento/composer-dependency-version-audit-plugin": false 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /etc/adminhtml/acl.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /etc/adminhtml/menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /etc/adminhtml/routes.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /etc/adminhtml/system.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 |
24 | 25 | sales 26 | Sales_DPDShipping::configuration 27 | dpd-shipping 28 | 29 | 30 | 31 | DpdConnect\Shipping\Block\Adminhtml\System\Config\Header 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 |
41 |
42 | -------------------------------------------------------------------------------- /etc/adminhtml/system/carriers.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 |
33 | -------------------------------------------------------------------------------- /etc/adminhtml/system/carriers/dpd.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 22 | 23 | 24 | 25 | 26 | Magento\Config\Model\Config\Source\Yesno 27 | 28 | 30 | 31 | 32 | 34 | 35 | 36 | 38 | 39 | 40 | 41 | 42 | DpdConnect\Shipping\Block\Adminhtml\System\Carrier\DpdCustomerProductSettings 43 | DpdConnect\Shipping\Model\Config\Backend\CustomerProduct 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /etc/adminhtml/system/dpd/account_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 22 | 24 | 25 | 26 | 27 | required-entry 28 | 29 | 30 | 31 | Magento\Config\Model\Config\Backend\Encrypted 32 | required-entry 33 | 34 | 35 | 36 | required-entry 37 | 38 | 40 | 44 | 45 | 46 | DpdConnect\Shipping\Config\Source\Settings\PrintFormat 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /etc/adminhtml/system/dpd/api.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 22 | 24 | 25 | 26 | 27 | 28 | Magento\Config\Model\Config\Source\Yesno 29 | 30 | 31 | 32 | 33 | Mass generation of labels above this number will be done Async 34 | 35 | 1 36 | 37 | 38 | 39 | 40 | 41 | The DPD Connect endpoint to use (useful for development) 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /etc/adminhtml/system/dpd/product_attribute.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 22 | 24 | 25 | 26 | 27 | DpdConnect\Shipping\Config\Source\Settings\ProductAttribute 28 | The product Harmonized System code 29 | 30 | 31 | 32 | 33 | DpdConnect\Shipping\Config\Source\Settings\ProductAttribute 34 | The product length attribute 35 | 36 | 37 | 38 | 39 | DpdConnect\Shipping\Config\Source\Settings\ProductAttribute 40 | The product width attribute 41 | 42 | 43 | 44 | 45 | DpdConnect\Shipping\Config\Source\Settings\ProductAttribute 46 | The product height attribute 47 | 48 | 49 | 50 | 51 | DpdConnect\Shipping\Config\Source\Settings\ProductAttribute 52 | The product depth attribute 53 | 54 | 55 | -------------------------------------------------------------------------------- /etc/adminhtml/system/dpd/shipping_origin.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 22 | 24 | 25 | These settings are used as Sender on shipping labels 26 | 27 | 29 | 30 | 31 | 32 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | 44 | 45 | 46 | 47 | 49 | 50 | 51 | 53 | 54 | Magento\Directory\Model\Config\Source\Country 55 | 56 | 57 | -------------------------------------------------------------------------------- /etc/csp_whitelist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | https://*.dpdconnect.nl 7 | 8 | 9 | 10 | 11 | https://*.dpdconnect.nl 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /etc/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 1 36 | 1 37 | 38 | 1 39 | 1 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /etc/email_templates.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |