diff --git a/Model/Carrier/Customshipping.php b/Model/Carrier/Customshipping.php index c90a8ec98afeeccd34e2f53f3adb27fd8c687d77..519cd0315a308529fbece14e162fc2c3a96e94e6 100644 --- a/Model/Carrier/Customshipping.php +++ b/Model/Carrier/Customshipping.php @@ -5,6 +5,7 @@ namespace uafrica\Customshipping\Model\Carrier; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; use Magento\CatalogInventory\Api\StockRegistryInterface; +use Magento\Checkout\Api\Data\ShippingInformationInterface; use Magento\Directory\Helper\Data; use Magento\Directory\Model\CountryFactory; use Magento\Directory\Model\CurrencyFactory; @@ -31,7 +32,7 @@ use Psr\Log\LoggerInterface; /** * uAfrica shipping implementation - * @category uafrica + * @category bob * @package uafrica_Customshipping * @author info@bob.co.za * @website https://www.bob.co.za @@ -48,10 +49,7 @@ class Customshipping extends AbstractCarrierOnline implements \Magento\Shipping\ */ public const CODE = 'uafrica'; - /** Tracking Endpoint */ - const TRACKING = 'https://api.dev.ship.uafrica.com/tracking?channel=localhost&tracking_reference='; - /*** RATES API Endpoint*/ - const RATES_ENDPOINT = 'https://api.dev.ship.uafrica.com/rates-at-checkout/woocommerce'; + const UNITS = 100; /** * Code of the carrier @@ -108,6 +106,7 @@ class Customshipping extends AbstractCarrierOnline implements \Magento\Shipping\ * @param \Magento\Framework\Controller\Result\JsonFactory $jsonFactory */ protected JsonFactory $jsonFactory; + private $cartRepository; /** @@ -212,6 +211,15 @@ class Customshipping extends AbstractCarrierOnline implements \Magento\Shipping\ } + public function beforeSaveAddressInformation($subject, $cartId, ShippingInformationInterface $addressInformation) + { + $quote = $this->cartRepository->getActive($cartId); + $deliveryNote = $addressInformation->getShippingAddress()->getExtensionAttributes()->getSuburb(); + $quote->setSuburb($deliveryNote); + //$this->cartRepository->save($quote); + return $addressInformation; + } + /** * Collect and get rates * @@ -225,6 +233,9 @@ class Customshipping extends AbstractCarrierOnline implements \Magento\Shipping\ return false; } + + + /** @var \Magento\Shipping\Model\Rate\Result $result */ $result = $this->_rateFactory->create(); @@ -235,9 +246,9 @@ class Customshipping extends AbstractCarrierOnline implements \Magento\Shipping\ $destCity = $request->getDestCity(); $destStreet = $request->getDestStreet() !== null ? str_replace("\n", ' ', $request->getDestStreet()) : ''; $destStreet1 = $destStreet; - // $destStreet2 = $destStreet; - //Get all the origin data from the request + + /** Origin Information */ list($originStreet, $originRegion, $originCountry, $originCity, $originStreet1, $originStreet2, $storeName, $baseIdentifier, $originSuburb) = $this->storeInformation(); @@ -271,7 +282,7 @@ class Customshipping extends AbstractCarrierOnline implements \Magento\Shipping\ 'destination' => [ 'company' => '', // TODO :: Add this if available 'address1' => $destStreet1, - 'address2' => '', + 'suburb' => '', 'city' => $destCity, 'province' => $destRegion, 'country_code' => $destCountry, @@ -360,7 +371,7 @@ class Customshipping extends AbstractCarrierOnline implements \Magento\Shipping\ protected function _getPerpackagePrice($cost, $handlingType, $handlingFee) { if ($handlingType == AbstractCarrier::HANDLING_TYPE_PERCENT) { - return $cost + $cost * $this->_numBoxes * $handlingFee / 100; + return $cost + $cost * $this->_numBoxes * $handlingFee / self::UNITS; } return $cost + $this->_numBoxes * $handlingFee; @@ -377,7 +388,7 @@ class Customshipping extends AbstractCarrierOnline implements \Magento\Shipping\ protected function _getPerorderPrice($cost, $handlingType, $handlingFee) { if ($handlingType == self::HANDLING_TYPE_PERCENT) { - return $cost + $cost * $handlingFee / 100; + return $cost + $cost * $handlingFee / self::UNITS; } return $cost + $handlingFee; @@ -489,7 +500,7 @@ class Customshipping extends AbstractCarrierOnline implements \Magento\Shipping\ $tracking->setCarrier(self::CODE); $tracking->setCarrierTitle($carrierTitle); - $tracking->setUrl(self::TRACKING.$item); + $tracking->setUrl(uData::TRACKING .$item); $tracking->setTracking($item); $tracking->addData($this->processTrackingDetails($item)); $result->append($tracking); @@ -693,7 +704,7 @@ class Customshipping extends AbstractCarrierOnline implements \Magento\Shipping\ */ private function getApiUrl(): string { - return self::RATES_ENDPOINT; + return uData::RATES_ENDPOINT; } /** @@ -741,23 +752,26 @@ class Customshipping extends AbstractCarrierOnline implements \Magento\Shipping\ $result->append($error); } else { - foreach ($rates['rates'] as $code => $title) { + foreach ($rates['rates'] as $title) { $method = $this->_rateMethodFactory->create(); - $method->setCarrier(self::CODE); + if (isset($title)){ + $method->setCarrier(self::CODE); + if ($this->getConfigData('additional_info') == 1) { $min_delivery_date = $this->getWorkingDays(date('Y-m-d'), $title['min_delivery_date']); $max_delivery_date = $this->getWorkingDays(date('Y-m-d'), $title['max_delivery_date']); $method->setCarrierTitle('Delivery in ' . $min_delivery_date .' - ' . $max_delivery_date .' Business Days'); - } else { - $method->setCarrierTitle($this->getConfigData('title')); + + $method->setCarrierTitle($this->getConfigData('title')); + } } $method->setMethod($title['service_code']); $method->setMethodTitle($title['service_name']); - $method->setPrice($title['total_price'] / 100); - $method->setCost($title['total_price'] / 100); + $method->setPrice($title['total_price'] / self::UNITS); + $method->setCost($title['total_price'] / self::UNITS); $result->append($method); } @@ -821,7 +835,7 @@ class Customshipping extends AbstractCarrierOnline implements \Magento\Shipping\ */ private function trackUafricaShipment($trackInfo): mixed { - $this->curl->get(self::TRACKING . $trackInfo); + $this->curl->get(uData::TRACKING . $trackInfo); $response = $this->curl->getBody(); diff --git a/Model/Carrier/uData.php b/Model/Carrier/uData.php new file mode 100644 index 0000000000000000000000000000000000000000..b293e7fd166444f63a8a91413442806e66e6d449 --- /dev/null +++ b/Model/Carrier/uData.php @@ -0,0 +1,16 @@ +<?php + +namespace uafrica\Customshipping\Model\Carrier; + +/** + * Class uData + * @package uafrica\Customshipping\Model\Carrier + */ +class uData +{ + + /** Tracking Endpoint */ + public const TRACKING = 'https://api.dev.ship.uafrica.com/tracking?channel=localhost&tracking_reference='; + /*** RATES API Endpoint*/ + public const RATES_ENDPOINT = 'https://api.dev.ship.uafrica.com/rates-at-checkout/woocommerce'; +} diff --git a/Observer/SaveOrderBeforeSalesModelQuote.php b/Observer/SaveOrderBeforeSalesModelQuote.php new file mode 100644 index 0000000000000000000000000000000000000000..1c81b724936d828e66598284be87b2da6a05db77 --- /dev/null +++ b/Observer/SaveOrderBeforeSalesModelQuote.php @@ -0,0 +1,34 @@ +<?php + +namespace uafrica\Customshipping\Observer; + +use Magento\Framework\DataObject\Copy; +use Magento\Framework\Event\Observer; +use Magento\Framework\Event\ObserverInterface; +use Magento\Quote\Model\Quote; +use Magento\Sales\Model\Order; + +class SaveOrderBeforeSalesModelQuote implements ObserverInterface +{ + public Copy $objectCopyService; + + public function __construct( + Copy $objectCopyService + ) { + $this->objectCopyService = $objectCopyService; + } + + public function execute(Observer $observer) + { + $this->objectCopyService->copyFieldsetToTarget( + 'sales_convert_quote', + 'to_order', + $observer->getEvent()->getQuote(), + $observer->getEvent()->getOrder() + ); + + + return $this; + + } +} diff --git a/Plugin/Checkout/Block/LayoutProcessorPlugin.php b/Plugin/Checkout/Block/LayoutProcessorPlugin.php index cc6ef515c515e424660c2f3c2c7703ecf79af54d..183ce35586ddd42622816608fd8dfb97ebe67848 100644 --- a/Plugin/Checkout/Block/LayoutProcessorPlugin.php +++ b/Plugin/Checkout/Block/LayoutProcessorPlugin.php @@ -1,30 +1,40 @@ <?php namespace uafrica\Customshipping\Plugin\Checkout\Block; +use Magento\Checkout\Block\Checkout\LayoutProcessor; + class LayoutProcessorPlugin { /** - * @param \Magento\Checkout\Block\Checkout\LayoutProcessor $subject + * This is the Class That Allows The Field To Appear As Required On Checkout, + * But It Does Not Save The Data To The Quote Table In The Database For The Order + * To Be Processed Correctly In The Backend And Frontend It Works With Shipping + * Information Management Class + * @param LayoutProcessor $subject * @param array $jsLayout * @return array */ public function afterProcess( - \Magento\Checkout\Block\Checkout\LayoutProcessor $subject, + LayoutProcessor $subject, array $jsLayout - ) { + ): array + { $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children'] - ['shippingAddress']['children']['shipping-address-fieldset']['children']['custom_field_text'] = [ - 'component' => 'Magento_Ui/js/form/element/abstract', + ['shippingAddress']['children']['shipping-address-fieldset']['children']['suburb'] = [ + 'component' => 'Magento_Ui/js/form/element/textarea', 'config' => [ - 'customScope' => 'shippingAddress.custom_attributes', + 'customScope' => 'shippingAddress.extension_attributes', 'customEntry' => null, 'template' => 'ui/form/field', 'elementTmpl' => 'ui/form/element/input', 'options' => [], + 'tooltip' => [ + 'description' => __('Necessary for shipping.') + ], 'id' => 'suburb' ], - 'dataScope' => 'shippingAddress.custom_attributes.custom_field_text', + 'dataScope' => 'shippingAddress.extension_attributes.suburb', 'label' => 'Suburb', 'provider' => 'checkoutProvider', 'visible' => true, diff --git a/Plugin/ShippingInformationManagement.php b/Plugin/ShippingInformationManagement.php new file mode 100644 index 0000000000000000000000000000000000000000..24b2b3a2bd0dab29e31249256742bf5e23cffd7e --- /dev/null +++ b/Plugin/ShippingInformationManagement.php @@ -0,0 +1,29 @@ +<?php + +namespace uafrica\Customshipping\Plugin; + +use Magento\Quote\Api\CartRepositoryInterface; + +use Magento\Checkout\Api\Data\ShippingInformationInterface; + +class ShippingInformationManagement +{ + public CartRepositoryInterface $cartRepository; + + public function __construct( + CartRepositoryInterface $cartRepository, + ) + { + $this->cartRepository = $cartRepository; + } + + public function beforeSaveAddressInformation($subject, $cartId, ShippingInformationInterface $addressInformation) + { + $quote = $this->cartRepository->getActive($cartId); + $deliveryNote = $addressInformation->getShippingAddress()->getExtensionAttributes()->getSuburb(); + $quote->setSuburb($deliveryNote); + $this->cartRepository->save($quote); + return [$cartId, $addressInformation]; + } + +} diff --git a/composer.json b/composer.json index 351adaa19a3a3bde10ddaef19834bce3cf8ad79e..8168ba4b1181dadc2a09d5f554b2e78359d21ee0 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "uafrica/bobgo", "description": "Streamline your shipments fulfillments with bobgo", "type": "magento2-module", - "version": "1.0.1", + "version": "1.0.0", "authors": [ { "name": "Gundo", diff --git a/etc/db_schema.xml b/etc/db_schema.xml new file mode 100644 index 0000000000000000000000000000000000000000..c4aba785c2ec895a032593a63ffd672795c1a4a5 --- /dev/null +++ b/etc/db_schema.xml @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="quote" resource="default" engine="innodb"> + <column xsi:type="text" name="suburb" nullable="true" comment="Delivery suburb"/> + <column xsi:type="text" name="service_code" nullable="true" comment="Shipping Service Code"/> + <column xsi:type="text" name="delivery_note" nullable="true" comment="Delivery Note"/> + </table> + <table name="sales_order" resource="default" engine="innodb"> + <column xsi:type="text" name="suburb" nullable="true" comment="Delivery Suburb"/> + <column xsi:type="text" name="service_code" nullable="true" comment="Shipping Service Code"/> + <column xsi:type="text" name="delivery_note" nullable="true" comment="Delivery Note"/> + </table> + <table name="customer_address_entity" resource="default" engine="innodb"> + <column xsi:type="text" name="suburb" nullable="true" comment="Customer Suburb"/> + <column xsi:type="text" name="service_code" nullable="true" comment="Shipping Service Code"/> + <column xsi:type="text" name="delivery_note" nullable="true" comment="Delivery Note"/> + </table> + +</schema> diff --git a/etc/di.xml b/etc/di.xml new file mode 100644 index 0000000000000000000000000000000000000000..f93b3182a2951ab815b2deabe8105d67dd836147 --- /dev/null +++ b/etc/di.xml @@ -0,0 +1,8 @@ +<?xml version="1.0"?> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <type name="Magento\Checkout\Model\ShippingInformationManagement"> + <plugin name="get_suburb" + type="uafrica\Customshipping\Plugin\ShippingInformationManagement" sortOrder="1"/> + </type> +</config> diff --git a/etc/events.xml b/etc/events.xml new file mode 100644 index 0000000000000000000000000000000000000000..c54fd93b7597557cc6c21f8fcc90e712dc54c5ae --- /dev/null +++ b/etc/events.xml @@ -0,0 +1,7 @@ +<?xml version="1.0"?> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd"> + <event name="sales_model_service_quote_submit_before"> + <observer name="uafrica_customshipping_sales_model_service_quote_submit_before" + instance="uafrica\Customshipping\Observer\SaveOrderBeforeSalesModelQuote" /> + </event> +</config> diff --git a/etc/extension_attributes.xml b/etc/extension_attributes.xml new file mode 100644 index 0000000000000000000000000000000000000000..82d4ec473cc139e2b5821cf7dbbe53971255bb38 --- /dev/null +++ b/etc/extension_attributes.xml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd"> + <extension_attributes for="Magento\Quote\Api\Data\AddressInterface"> + <attribute code="suburb" type="string"/> + </extension_attributes> +</config> diff --git a/etc/fieldset.xml b/etc/fieldset.xml new file mode 100644 index 0000000000000000000000000000000000000000..6773bc70b8ef293caf882255dd7587bbb95b966c --- /dev/null +++ b/etc/fieldset.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:DataObject/etc/fieldset.xsd"> + <scope id="global"> + <fieldset id="sales_convert_quote"> + <field name="suburb"> + <aspect name="to_order" /> + </field> + </fieldset> + </scope> +</config> diff --git a/etc/frontend/di.xml b/etc/frontend/di.xml index 7a9bd2b68f47505ebccc475551bf3937a4457ac8..a06930c7ab62a170f5960aab4fb2c2026509886f 100644 --- a/etc/frontend/di.xml +++ b/etc/frontend/di.xml @@ -1,5 +1,10 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Checkout\Block\Checkout\LayoutProcessor"> <plugin name="add_custom_field_checkout_shipping_form" type="uafrica\Customshipping\Plugin\Checkout\Block\LayoutProcessorPlugin" sortOrder="10"/> + <arguments> + <argument name="layoutProcessors" xsi:type="array"> + <item name="orderattribute" xsi:type="object">uafrica\Customshipping\Plugin\Checkout\Block\LayoutProcessorPlugin</item> + </argument> + </arguments> </type> </config> diff --git a/view/frontend/requirejs-config.js b/view/frontend/requirejs-config.js new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/view/frontend/web/js/model/set-shipping-information.js b/view/frontend/web/js/model/set-shipping-information.js new file mode 100644 index 0000000000000000000000000000000000000000..d506a40ff728bab5df77848fab4e7ff71d13b2a4 --- /dev/null +++ b/view/frontend/web/js/model/set-shipping-information.js @@ -0,0 +1,29 @@ +/*jshint browser:true jquery:true*/ +/*global alert*/ +define([ + 'jquery', + 'mage/utils/wrapper', + 'Magento_Checkout/js/model/quote' +], function ($, wrapper, quote) { + 'use strict'; + + return function (setShippingInformationAction) { + + return wrapper.wrap(setShippingInformationAction, function (originalAction) { + var shippingAddress = quote.shippingAddress(); + if (shippingAddress['extension_attributes'] === undefined) { + shippingAddress['extension_attributes'] = {}; + } + + var attribute = shippingAddress.customAttributes.find( + function (element) { + return element.attribute_code === 'suburb'; + } + ); + + shippingAddress['extension_attributes']['suburb'] = attribute.value; + // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information') + return originalAction(); + }); + }; +}); diff --git a/view/frontend/web/js/model/shipping-rates-validation-rules.js b/view/frontend/web/js/model/shipping-rates-validation-rules.js index 0841e9095170ae18c60fd4f95c563b39235f077a..0cf80ca2a58009b4055a599fac3a7d4d45a2e799 100644 --- a/view/frontend/web/js/model/shipping-rates-validation-rules.js +++ b/view/frontend/web/js/model/shipping-rates-validation-rules.js @@ -18,6 +18,9 @@ define( }, 'city': { 'required': true + }, + 'suburb': { + 'required': true } }; }