diff --git a/Block/System/Config/Form/Field/Version.php b/Block/System/Config/Form/Field/Version.php
index a3df7a2101114c9be2527e139fe5e10db9143ec1..5d071801a406da9f220bf1fd0093996f8eeb5b3d 100644
--- a/Block/System/Config/Form/Field/Version.php
+++ b/Block/System/Config/Form/Field/Version.php
@@ -1,53 +1,53 @@
 <?php
-//namespace BobGroup\BobGo\Block\System\Config\Form\Field;
-//
-//use Magento\Framework\Data\Form\Element\AbstractElement;
-//
-///**
-// * Displays Version number in System Configuration
-// * @category   BobGroup
-// * @package    bobgo_CustomShipping
-// * @author     info@bob.co.za
-// * @website    https://www.bob.co.za
-// */
-//class Version extends \Magento\Config\Block\System\Config\Form\Field
-//{
-//    const EXTENSION_URL = 'https://www.bobgo.co.za';
-//
-//    /**
-//     * @var \BobGroup\BobGo\Helper\Data $helper
-//     */
-//    protected $_helper;
-//
-//    /**
-//     * @param \Magento\Backend\Block\Template\Context $context
-//     * @param \BobGroup\BobGo\Helper\Data $helper
-//     */
-//    public function __construct(
-//        \Magento\Backend\Block\Template\Context $context,
-//        \BobGroup\BobGo\Helper\Data $helper
-//    ) {
-//        $this->_helper = $helper;
-//        parent::__construct($context);
-//    }
-//
-//
-//    /**
-//     * @param AbstractElement $element
-//     * @return string
-//     */
-//    protected function _getElementHtml(AbstractElement $element)
-//    {
-//        $extensionVersion   = $this->_helper->getExtensionVersion();
-//        $extensionTitle     = 'BobGo';
-//        $versionLabel       = sprintf(
-//            '<a href="%s" title="%s" target="_blank">%s</a>',
-//            self::EXTENSION_URL,
-//            $extensionTitle,
-//            $extensionVersion
-//        );
-//        $element->setValue($versionLabel);
-//
-//        return $element->getValue();
-//    }
-//}
+namespace BobGroup\BobGo\Block\System\Config\Form\Field;
+
+use Magento\Framework\Data\Form\Element\AbstractElement;
+
+/**
+ * Displays Version number in System Configuration
+ * @category   BobGroup
+ * @package    bobgo_CustomShipping
+ * @author     info@bob.co.za
+ * @website    https://www.bob.co.za
+ */
+class Version extends \Magento\Config\Block\System\Config\Form\Field
+{
+    const EXTENSION_URL = 'https://www.bob.co.za';
+
+    /**
+     * @var \BobGroup\BobGo\Helper\Data $helper
+     */
+    protected $_helper;
+
+    /**
+     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \BobGroup\BobGo\Helper\Data $helper
+     */
+    public function __construct(
+        \Magento\Backend\Block\Template\Context $context,
+        \BobGroup\BobGo\Helper\Data $helper
+    ) {
+        $this->_helper = $helper;
+        parent::__construct($context);
+    }
+
+
+    /**
+     * @param AbstractElement $element
+     * @return string
+     */
+    protected function _getElementHtml(AbstractElement $element)
+    {
+        $extensionVersion   = $this->_helper->getExtensionVersion();
+        $extensionTitle     = 'BobGo';
+        $versionLabel       = sprintf(
+            '<a href="%s" title="%s" target="_blank">%s</a>',
+            self::EXTENSION_URL,
+            $extensionTitle,
+            $extensionVersion
+        );
+        $element->setValue($versionLabel);
+
+        return $element->getValue();
+    }
+}
diff --git a/Helper/Data.php b/Helper/Data.php
index e502d61b28c4395bd907f2c88b17e4d3e93a0aa7..d0627eefd27a235e7b0b5b498f8e22ab4fd1a215 100644
--- a/Helper/Data.php
+++ b/Helper/Data.php
@@ -1,88 +1,88 @@
 <?php
-//namespace BobGroup\BobGo\Helper;
-//
-//use Magento\Framework\App\Helper\AbstractHelper;
-//use Magento\Framework\App\Helper\Context;
-//use Magento\Framework\Module\ModuleListInterface;
-//use Magento\Store\Model\ScopeInterface;
-//
-///**
-// * @category   Bob Go
-// * @package    bobgo_CustomShipping
-// * @author     Bob Go
-// * @website    https://www.bobgo.co.za
-// */
-//class Data extends AbstractHelper
-//{
-//
-//    const XML_PATH_ENABLED = 'BobGroup_BobGo/general/enabled';
-//    const XML_PATH_DEBUG   = 'BobGroup_BobGo/general/debug';
-//
-//    /**
-//     * @var \Psr\Log\LoggerInterface
-//     */
-//    protected $_logger;
-//
-//    /**
-//     * @var ModuleListInterface
-//     */
-//    protected $_moduleList;
-//
-//    /**
-//     * @param Context $context
-//     * @param ModuleListInterface $moduleList
-//     */
-//    public function __construct(
-//        Context $context,
-//        ModuleListInterface $moduleList
-//    ) {
-//        $this->_logger                  = $context->getLogger();
-//        $this->_moduleList              = $moduleList;
-//
-//        parent::__construct($context);
-//    }
-//
-//    /**
-//     * Check if enabled
-//     *
-//     * @return string|null
-//     */
-//    public function isEnabled()
-//    {
-//        return $this->scopeConfig->getValue(
-//            self::XML_PATH_ENABLED,
-//            ScopeInterface::SCOPE_STORE
-//        );
-//    }
-//
-//    public function getDebugStatus()
-//    {
-//        return $this->scopeConfig->getValue(
-//            self::XML_PATH_DEBUG,
-//            ScopeInterface::SCOPE_STORE
-//        );
-//    }
-//
-//    public function getExtensionVersion()
-//    {
-//        $moduleCode = 'BobGroup_BobGo';
-//        $moduleInfo = $this->_moduleList->getOne($moduleCode);
-//        return $moduleInfo['setup_version'];
-//    }
-//
-//    /**
-//     *
-//     * @param $message
-//     * @param bool|false $useSeparator
-//     */
-//    public function log($message, $useSeparator = false)
-//    {
-//        if ($this->getDebugStatus()) {
-//            if ($useSeparator) {
-//                $this->_logger->addDebug(str_repeat('=', 100));
-//            }
-//
-//            $this->_logger->addDebug($message);
-//        }
-//    }
-//}
+namespace BobGroup\BobGo\Helper;
+
+use Magento\Framework\App\Helper\AbstractHelper;
+use Magento\Framework\App\Helper\Context;
+use Magento\Framework\Module\ModuleListInterface;
+use Magento\Store\Model\ScopeInterface;
+
+/**
+ * @category   Bob Go
+ * @package    bobgo_CustomShipping
+ * @author     Bob Go
+ * @website    https://www.bobgo.co.za
+ */
+class Data extends AbstractHelper
+{
+
+    const XML_PATH_ENABLED = 'BobGroup_BobGo/general/enabled';
+    const XML_PATH_DEBUG   = 'BobGroup_BobGo/general/debug';
+
+    /**
+     * @var \Psr\Log\LoggerInterface
+     */
+    protected $_logger;
+
+    /**
+     * @var ModuleListInterface
+     */
+    protected $_moduleList;
+
+    /**
+     * @param Context $context
+     * @param ModuleListInterface $moduleList
+     */
+    public function __construct(
+        Context $context,
+        ModuleListInterface $moduleList
+    ) {
+        $this->_logger                  = $context->getLogger();
+        $this->_moduleList              = $moduleList;
+
+        parent::__construct($context);
+    }
+
+    /**
+     * Check if enabled
+     *
+     * @return string|null
+     */
+    public function isEnabled()
+    {
+        return $this->scopeConfig->getValue(
+            self::XML_PATH_ENABLED,
+            ScopeInterface::SCOPE_STORE
+        );
+    }
+
+    public function getDebugStatus()
+    {
+        return $this->scopeConfig->getValue(
+            self::XML_PATH_DEBUG,
+            ScopeInterface::SCOPE_STORE
+        );
+    }
+
+    public function getExtensionVersion()
+    {
+        $moduleCode = 'BobGroup_BobGo';
+        $moduleInfo = $this->_moduleList->getOne($moduleCode);
+        return $moduleInfo['setup_version'];
+    }
+
+    /**
+     *
+     * @param $message
+     * @param bool|false $useSeparator
+     */
+    public function log($message, $useSeparator = false)
+    {
+        if ($this->getDebugStatus()) {
+            if ($useSeparator) {
+                $this->_logger->addDebug(str_repeat('=', 100));
+            }
+
+            $this->_logger->addDebug($message);
+        }
+    }
+}
diff --git a/Logger/Handler.php b/Logger/Handler.php
deleted file mode 100644
index 22703cb87bd424fb05dbfb6fdbfac58187146b53..0000000000000000000000000000000000000000
--- a/Logger/Handler.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-//
-//namespace BobGroup\BobGo\Logger;
-//
-//use Monolog\Logger;
-//use Magento\Framework\Logger\Handler\Base as MagentoBaseHandler;
-//
-//class Handler extends MagentoBaseHandler
-//{
-//    protected $fileName = '/var/log/bobgo_plugin.log';
-//    protected $loggerType = Logger::DEBUG;
-//}
diff --git a/Model/Carrier/AdditionalInfo.php b/Model/Carrier/AdditionalInfo.php
index c102df5e4f8f7c82bff08dcfa8c920252f494ebe..fff3c92920d53e977feaccbe27b64432d1f295a0 100644
--- a/Model/Carrier/AdditionalInfo.php
+++ b/Model/Carrier/AdditionalInfo.php
@@ -1,123 +1,123 @@
 <?php
-//
-//namespace BobGroup\BobGo\Model\Carrier;
-//
-///**
-// * Get the AdditionalInfo information from the request body and return it
-// */
-//class AdditionalInfo
-//{
-//
-//    /**
-//     * @return mixed|string
-//     */
-//    public function getDestComp(): mixed
+
+namespace BobGroup\BobGo\Model\Carrier;
+
+/**
+ * Get the AdditionalInfo information from the request body and return it
+ */
+class AdditionalInfo
+{
+
+    /**
+     * @return mixed|string
+     */
+    public function getDestComp(): mixed
+    {
+        $data = json_decode(file_get_contents('php://input'), true);
+
+        if (isset($data['address']['company'])) {
+            $destComp = $data['address']['company'];
+        } else {
+            $destComp = '';
+        }
+        return $destComp;
+    }
+
+    public function getSuburb(): mixed
+    {
+
+        $data = json_decode(file_get_contents('php://input'), true);
+
+        if (isset($data['address']['custom_attributes'][0]['value'])) {
+            $destSub = $data['address']['custom_attributes'][0]['value'];
+            //print_r($destSub);
+        } else {
+            $destSub = '';
+        }
+        return $destSub;
+    }
+
+    /**
+     * @return mixed|string
+     */
+    public function getDestTelephone(): mixed
+    {
+        $data = json_decode(file_get_contents('php://input'), true);
+
+        if (isset($data['address']['telephone'])) {
+            $destTelephone = $data['address']['telephone'];
+        } else {
+            $destTelephone = '';
+        }
+        return $destTelephone;
+    }
+
+
+    /**
+     * @var \BobGroup\BobGo\Model\Carrier\AdditionalInfo
+     */
+    public $countryFactory;
+
+    public function __construct($countryFactory)
+    {
+        $this->countryFactory = $countryFactory;
+    }
+
+    /**
+     * country full name
+     *
+     * @return string
+     */
+    public function getCountryName($countryId): string
+    {
+        $countryName = '';
+        $country = $this->countryFactory->create()->loadByCode($countryId);
+        if ($country) {
+            $countryName = $country->getName();
+        }
+        return $countryName;
+    }
+
+//    // Method to get the per-package price
+//    protected function _getPerpackagePrice($cost, $handlingType, $handlingFee)
 //    {
-//        $data = json_decode(file_get_contents('php://input'), true);
-//
-//        if (isset($data['address']['company'])) {
-//            $destComp = $data['address']['company'];
-//        } else {
-//            $destComp = '';
+//        if ($handlingType == AbstractCarrier::HANDLING_TYPE_PERCENT) {
+//            return $cost + $cost * $this->_numBoxes * $handlingFee / self::UNITS;
 //        }
-//        return $destComp;
+//        return $cost + $this->_numBoxes * $handlingFee;
 //    }
 //
-//    public function getSuburb(): mixed
+//    // Method to get the per-order price
+//    protected function _getPerorderPrice($cost, $handlingType, $handlingFee)
 //    {
-//
-//        $data = json_decode(file_get_contents('php://input'), true);
-//
-//        if (isset($data['address']['custom_attributes'][0]['value'])) {
-//            $destSub = $data['address']['custom_attributes'][0]['value'];
-//            //print_r($destSub);
-//        } else {
-//            $destSub = '';
+//        if ($handlingType == self::HANDLING_TYPE_PERCENT) {
+//            return $cost + $cost * $handlingFee / self::UNITS;
 //        }
-//        return $destSub;
+//        return $cost + $handlingFee;
 //    }
 //
-//    /**
-//     * @return mixed|string
-//     */
-//    public function getDestTelephone(): mixed
+//    // Method to get configuration data of the carrier
+//    public function getCode($type, $code = '')
 //    {
-//        $data = json_decode(file_get_contents('php://input'), true);
-//
-//        if (isset($data['address']['telephone'])) {
-//            $destTelephone = $data['address']['telephone'];
-//        } else {
-//            $destTelephone = '';
+//        $codes = [
+//            'method' => [
+//                'bobGo' => __('BobGo'),
+//            ],
+//            'unit_of_measure' => [
+//                'KGS' => __('Kilograms'),
+//                'LBS' => __('Pounds'),
+//            ],
+//        ];
+//        if (!isset($codes[$type])) {
+//            return false;
+//        } elseif ('' === $code) {
+//            return $codes[$type];
 //        }
-//        return $destTelephone;
-//    }
-//
-//
-//    /**
-//     * @var \BobGroup\BobGo\Model\Carrier\AdditionalInfo
-//     */
-//    public $countryFactory;
-//
-//    public function __construct($countryFactory)
-//    {
-//        $this->countryFactory = $countryFactory;
-//    }
-//
-//    /**
-//     * country full name
-//     *
-//     * @return string
-//     */
-//    public function getCountryName($countryId): string
-//    {
-//        $countryName = '';
-//        $country = $this->countryFactory->create()->loadByCode($countryId);
-//        if ($country) {
-//            $countryName = $country->getName();
+//        if (!isset($codes[$type][$code])) {
+//            return false;
+//        } else {
+//            return $codes[$type][$code];
 //        }
-//        return $countryName;
 //    }
-//
-////    // Method to get the per-package price
-////    protected function _getPerpackagePrice($cost, $handlingType, $handlingFee)
-////    {
-////        if ($handlingType == AbstractCarrier::HANDLING_TYPE_PERCENT) {
-////            return $cost + $cost * $this->_numBoxes * $handlingFee / self::UNITS;
-////        }
-////        return $cost + $this->_numBoxes * $handlingFee;
-////    }
-////
-////    // Method to get the per-order price
-////    protected function _getPerorderPrice($cost, $handlingType, $handlingFee)
-////    {
-////        if ($handlingType == self::HANDLING_TYPE_PERCENT) {
-////            return $cost + $cost * $handlingFee / self::UNITS;
-////        }
-////        return $cost + $handlingFee;
-////    }
-////
-////    // Method to get configuration data of the carrier
-////    public function getCode($type, $code = '')
-////    {
-////        $codes = [
-////            'method' => [
-////                'bobGo' => __('BobGo'),
-////            ],
-////            'unit_of_measure' => [
-////                'KGS' => __('Kilograms'),
-////                'LBS' => __('Pounds'),
-////            ],
-////        ];
-////        if (!isset($codes[$type])) {
-////            return false;
-////        } elseif ('' === $code) {
-////            return $codes[$type];
-////        }
-////        if (!isset($codes[$type][$code])) {
-////            return false;
-////        } else {
-////            return $codes[$type][$code];
-////        }
-////    }
-//
-//}
+
+}
diff --git a/Model/Carrier/BobGo.php b/Model/Carrier/BobGo.php
index 83e3c1507032657b53bba794d8c6876970bea412..ee0dd134877f41b1b11a8e795c3af813fd04ec4f 100644
--- a/Model/Carrier/BobGo.php
+++ b/Model/Carrier/BobGo.php
@@ -1,73 +1,1051 @@
 <?php
+declare(strict_types=1);
 
 namespace BobGroup\BobGo\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;
+use Magento\Directory\Model\RegionFactory;
 use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\Controller\Result\JsonFactory;
+use Magento\Framework\DataObject;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\HTTP\Client\CurlFactory;
+use Magento\Framework\Module\Dir\Reader;
+use Magento\Framework\Xml\Security;
 use Magento\Quote\Model\Quote\Address\RateRequest;
-use Magento\Quote\Model\Quote\Address\RateResult\Method;
-use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory;
 use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory;
+use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory;
+use Magento\Sales\Model\Order\Shipment;
 use Magento\Shipping\Model\Carrier\AbstractCarrier;
-use Magento\Shipping\Model\Carrier\CarrierInterface;
+use Magento\Shipping\Model\Carrier\AbstractCarrierOnline;
 use Magento\Shipping\Model\Rate\Result;
 use Magento\Shipping\Model\Rate\ResultFactory;
+use Magento\Shipping\Model\Simplexml\ElementFactory;
+use Magento\Shipping\Model\Tracking\Result\StatusFactory;
+use Magento\Store\Model\ScopeInterface;
+use Magento\Store\Model\StoreManagerInterface;
 use Psr\Log\LoggerInterface;
 
-class BobGo extends AbstractCarrier implements CarrierInterface
+/**
+ * Bob Go shipping implementation
+ * @category   Bob Go
+ * @package    bobgo_CustomShipping
+ * @author     Bob Go
+ * @website    https://www.bobgo.co.za
+ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.TooManyFields)
+ */
+class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Carrier\CarrierInterface
 {
-    protected $_code = 'bobgo';
+    /**
+     * Code of the carrier
+     * @var string
+     */
+    public const CODE = 'bobgo';
+
+    const UNITS = 100;
+
+    /**
+     * Code of the carrier
+     *
+     * @var string
+     */
+    protected $_code = self::CODE;
+
+
+    /**
+     * Rate request data
+     *
+     * @var RateRequest|null
+     */
+    protected $_request = null;
+
+    /**
+     * Rate result data
+     *
+     * @var Result|null
+     */
+    protected $_result = null;
+
+    /**
+     * Container types that could be customized for bobgo carrier
+     *
+     * @var string[]
+     */
+    protected $_customizableContainerTypes = ['YOUR_PACKAGING'];
 
-    protected $rateResultFactory;
-    protected $rateMethodFactory;
-    protected $logger;
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $_storeManager;
 
+    /**
+     * @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
+     */
+    protected $_productCollectionFactory;
+
+
+    /**
+     * @var DataObject
+     */
+    private $_rawTrackingRequest;
+
+    /**
+     * @var \Magento\Framework\HTTP\Client\Curl
+     */
+    protected \Magento\Framework\HTTP\Client\Curl $curl;
+
+
+    /**
+     * @param \Magento\Framework\Controller\Result\JsonFactory $jsonFactory
+     */
+    protected JsonFactory $jsonFactory;
+    private $cartRepository;
+    public Company $company;
+
+
+    /**
+     * @param ScopeConfigInterface $scopeConfig
+     * @param ErrorFactory $rateErrorFactory
+     * @param LoggerInterface $logger
+     * @param Security $xmlSecurity
+     * @param ElementFactory $xmlElFactory
+     * @param ResultFactory $rateFactory
+     * @param MethodFactory $rateMethodFactory
+     * @param \Magento\Shipping\Model\Tracking\ResultFactory $trackFactory
+     * @param \Magento\Shipping\Model\Tracking\Result\ErrorFactory $trackErrorFactory
+     * @param StatusFactory $trackStatusFactory
+     * @param RegionFactory $regionFactory
+     * @param CountryFactory $countryFactory
+     * @param CurrencyFactory $currencyFactory
+     * @param Data $directoryData
+     * @param StockRegistryInterface $stockRegistry
+     * @param StoreManagerInterface $storeManager
+     * @param Reader $configReader
+     * @param CollectionFactory $productCollectionFactory
+     * @param JsonFactory $jsonFactory
+     * @param CurlFactory $curlFactory
+     * @param array $data
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     */
     public function __construct(
-        ScopeConfigInterface $scopeConfig,
-        ErrorFactory $rateErrorFactory,
-        LoggerInterface $logger,
-        ResultFactory $rateResultFactory,
-        MethodFactory $rateMethodFactory,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
+        \Psr\Log\LoggerInterface $logger,
+        Security $xmlSecurity,
+        \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
+        \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
+        \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
+        \Magento\Shipping\Model\Tracking\ResultFactory $trackFactory,
+        \Magento\Shipping\Model\Tracking\Result\ErrorFactory $trackErrorFactory,
+        \Magento\Shipping\Model\Tracking\Result\StatusFactory $trackStatusFactory,
+        \Magento\Directory\Model\RegionFactory $regionFactory,
+        \Magento\Directory\Model\CountryFactory $countryFactory,
+        \Magento\Directory\Model\CurrencyFactory $currencyFactory,
+        \Magento\Directory\Helper\Data $directoryData,
+        \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\Framework\Module\Dir\Reader $configReader,
+        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
+        JsonFactory $jsonFactory,
+        CurlFactory $curlFactory,
         array $data = []
+
     ) {
-        $this->rateResultFactory = $rateResultFactory;
-        $this->rateMethodFactory = $rateMethodFactory;
-        $this->logger = $logger;
-        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
+
+        $this->_storeManager = $storeManager;
+        $this->_productCollectionFactory = $productCollectionFactory;
+        parent::__construct(
+            $scopeConfig,
+            $rateErrorFactory,
+            $logger,
+            $xmlSecurity,
+            $xmlElFactory,
+            $rateFactory,
+            $rateMethodFactory,
+            $trackFactory,
+            $trackErrorFactory,
+            $trackStatusFactory,
+            $regionFactory,
+            $countryFactory,
+            $currencyFactory,
+            $directoryData,
+            $stockRegistry,
+            $data
+        );
+        $this->jsonFactory = $jsonFactory;
+        $this->curl = $curlFactory->create();
+        $this->company = new Company();
     }
 
-    public function collectRates(RateRequest $request)
+    /*
+     * Gets the base url of the store by stripping the http:// or https:// and wwww. from the url
+     * leaving just "example.com" since Bob Go API uses this format and not the full url as the Identifier
+     * @var \Magento\Store\Model\StoreManagerInterface $this->_storeManager
+     * @return string
+     */
+    public function getBaseUrl(): string
+    {
+        $storeBase = $this->_storeManager->getStore()->getBaseUrl();
+        return parse_url($storeBase, PHP_URL_HOST);
+    }
+
+
+    /**
+     *  Make request to Bob Go API to get shipping rates for the cart
+     * After all the required data is collected, it makes a request to the Bob Go API to get the shipping rates
+     * @param $payload
+     * @return array
+     */
+    public function getRates($payload): array
     {
-        $this->logger->debug('BobGo collectRates method called');
+        return $this->uRates($payload);
+    }
 
-        if (!$this->getConfigFlag('active')) {
-            $this->logger->debug('BobGo is not active');
+    /**
+     * Processing additional validation to check if carrier applicable.
+     *
+     * @param \Magento\Framework\DataObject $request
+     * @return $this|bool|\Magento\Framework\DataObject
+     */
+    public function processAdditionalValidation(\Magento\Framework\DataObject $request)
+    {
+        if (!count($this->getAllItems($request))) {
             return false;
         }
 
-        $this->logger->debug('BobGo is active');
+        $maxAllowedWeight = 500; //$this->getConfigData('max_package_weight');
+        $errorMsg = '';
+        $configErrorMsg = $this->getConfigData('specificerrmsg');
+        $defaultErrorMsg = __('The shipping module is not available.');
+        $showMethod = $this->getConfigData('showmethod');
 
-        $result = $this->rateResultFactory->create();
-        $method = $this->rateMethodFactory->create();
+        /** @var $item \Magento\Quote\Model\Quote\Item */
+        foreach ($this->getAllItems($request) as $item) {
+            $product = $item->getProduct();
+            if ($product && $product->getId()) {
+                $weight = $product->getWeight();
+                $stockItemData = $this->stockRegistry->getStockItem(
+                    $product->getId(),
+                    $item->getStore()->getWebsiteId()
+                );
+                $doValidation = true;
 
-        $method->setCarrier($this->_code);
-        $method->setCarrierTitle($this->getConfigData('title'));
+                if ($stockItemData->getIsQtyDecimal() && $stockItemData->getIsDecimalDivided()) {
+                    if ($stockItemData->getEnableQtyIncrements() && $stockItemData->getQtyIncrements()
+                    ) {
+                        $weight = $weight * $stockItemData->getQtyIncrements();
+                    } else {
+                        $doValidation = false;
+                    }
+                } elseif ($stockItemData->getIsQtyDecimal() && !$stockItemData->getIsDecimalDivided()) {
+                    $weight = $weight * $item->getQty();
+                }
 
-        $method->setMethod($this->_code);
-        $method->setMethodTitle($this->getConfigData('name'));
 
-        $shippingCost = (float)$this->getConfigData('shipping_cost');
-        $this->logger->debug('Shipping Cost: ' . $shippingCost);
+                if ($doValidation && $weight > $maxAllowedWeight) {
+                    $errorMsg = $configErrorMsg ? $configErrorMsg : $defaultErrorMsg;
+                    break;
+                }
+            }
+        }
+
+        if (!$errorMsg && !$request->getDestPostcode() && $this->isZipCodeRequired($request->getDestCountryId())) {
 
-        $method->setPrice($shippingCost);
-        $method->setCost($shippingCost);
+            $errorMsg = __('This shipping method is not available. Please specify the zip code.');
+        }
 
-        $result->append($method);
+        if ($request->getDestCountryId() == 'ZA') {
+            $errorMsg = '';
+        } else {
+            $errorMsg = $configErrorMsg ? $configErrorMsg : $defaultErrorMsg;
+        }
+
+        if ($errorMsg && $showMethod) {
+            $error = $this->_rateErrorFactory->create();
+            $error->setCarrier($this->_code);
+            $error->setCarrierTitle($this->getConfigData('title'));
+            $error->setErrorMessage($errorMsg);
+
+            return $error;
+        } elseif ($errorMsg) {
+            return false;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Collect and get rates for this shipping method based on information in $request
+     * This is a default function that is called by Magento to get the shipping rates for the cart
+     * @param RateRequest $request
+     * @return Result|bool|null
+     */
+    public function collectRates(RateRequest $request)
+    {
+        /*** Make sure that Shipping method is enabled*/
+        if (!$this->isActive()) {
+            return false;
+        }
+        /**
+         * Gets the destination company name from Company Name field in the checkout page
+         * This method is used is the last resort to get the company name since the company name is not available in _rateFactory
+         */
+        $destComp = $this->getDestComp();
+        $destSuburb = $this->getDestSuburb();
+
+        /** @var \Magento\Shipping\Model\Rate\Result $result */
+
+        $result = $this->_rateFactory->create();
+
+        $destination = $request->getDestPostcode();
+        $destCountry = $request->getDestCountryId();
+        $destRegion = $request->getDestRegionCode();
+        $destCity = $request->getDestCity();
+        $destStreet = $request->getDestStreet();
+
+        /**  Destination Information  */
+        [$destStreet1, $destStreet2, $destStreet3] = $this->destStreet($destStreet);
+
+
+
+        /**  Origin Information  */
+        [$originStreet, $originRegion, $originCountry, $originCity, $originStreet1, $originStreet2, $storeName, $baseIdentifier, $originSuburb,$weightUnit] = $this->storeInformation();
+
+        /**  Get all items in cart  */
+        $items = $request->getAllItems();
+        $itemsArray = [];
+        $itemsArray = $this->getStoreItems($items, $weightUnit, $itemsArray);
+
+        $payload = [
+            'identifier' => $baseIdentifier,
+            'rate' => [
+                'origin' => [
+                    'company' => $storeName,
+                    'address1' => $originStreet1,
+                    'address2' => $originStreet2,
+                    'city' => $originCity,
+                    'suburb' => $originSuburb,
+                    'province' => $originRegion,
+                    'country_code' => $originCountry,
+                    'postal_code' => $originStreet,
+
+                ],
+                'destination' => [
+                    'company' => $destComp,
+                    'address1' => $destStreet1,
+                    'address2' => $destStreet2,
+                    'suburb' => $destSuburb,
+                    'city' => $destCity,
+                    'province' => $destRegion,
+                    'country_code' => $destCountry,
+                    'postal_code' => $destination,
+                ],
+                'items' => $itemsArray,
+            ]
+        ];
+
+        $this->_getRates($payload, $result);
 
         return $result;
     }
 
+    /**
+     * @return array
+     */
+    public function storeInformation(): array
+    {
+        /** Store Origin details */
+        $originCountry = $this->_scopeConfig->getValue(
+            'general/store_information/country_id',
+            ScopeInterface::SCOPE_STORE
+        );
+        $originRegion = $this->_scopeConfig->getValue(
+            'general/store_information/region_id',
+            ScopeInterface::SCOPE_STORE
+        );
+        $originCity = $this->_scopeConfig->getValue(
+            'general/store_information/city',
+            ScopeInterface::SCOPE_STORE
+        );
+
+        $originStreet = $this->_scopeConfig->getValue(
+            'general/store_information/postcode',
+            ScopeInterface::SCOPE_STORE
+        );
+
+        $originStreet1 = $this->_scopeConfig->getValue(
+            'general/store_information/street_line1',
+            ScopeInterface::SCOPE_STORE
+        );
+
+        $originStreet2 = $this->_scopeConfig->getValue(
+            'general/store_information/street_line2',
+            ScopeInterface::SCOPE_STORE
+        );
+
+        $storeName = $this->_scopeConfig->getValue(
+            'general/store_information/name',
+            ScopeInterface::SCOPE_STORE
+        );
+
+        $originSuburb = $this->_scopeConfig->getValue(
+            'general/store_information/suburb',
+            ScopeInterface::SCOPE_STORE
+        );
+        $weightUnit = $this->_scopeConfig->getValue(
+            'general/locale/weight_unit',
+            ScopeInterface::SCOPE_STORE
+        );
+
+        $baseIdentifier = $this->getBaseUrl();
+
+        return array($originStreet, $originRegion, $originCountry, $originCity, $originStreet1, $originStreet2, $storeName, $baseIdentifier, $originSuburb, $weightUnit);
+    }
+
+
+    /**
+     * Get result of request
+     *
+     * @return Result|null
+     */
+    public function getResult()
+    {
+        if (!$this->_result) {
+            $this->_result = $this->_trackFactory->create();
+        }
+        return $this->_result;
+    }
+
+
+    /**
+     * Get final price for shipping method with handling fee per package
+     *
+     * @param float $cost
+     * @param string $handlingType
+     * @param float $handlingFee
+     * @return float
+     */
+    protected function _getPerpackagePrice($cost, $handlingType, $handlingFee)
+    {
+        if ($handlingType == AbstractCarrier::HANDLING_TYPE_PERCENT) {
+            return $cost + $cost * $this->_numBoxes * $handlingFee / self::UNITS;
+        }
+
+        return $cost + $this->_numBoxes * $handlingFee;
+    }
+
+    /**
+     * Get final price for shipping method with handling fee per order
+     *
+     * @param float $cost
+     * @param string $handlingType
+     * @param float $handlingFee
+     * @return float
+     */
+    protected function _getPerorderPrice($cost, $handlingType, $handlingFee)
+    {
+        if ($handlingType == self::HANDLING_TYPE_PERCENT) {
+            return $cost + $cost * $handlingFee / self::UNITS;
+        }
+
+        return $cost + $handlingFee;
+    }
+
+
+    /**
+     * Get configuration data of carrier
+     *
+     * @param string $type
+     * @param string $code
+     * @return array|false
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function getCode($type, $code = '')
+    {
+        $codes = [
+            'method' => [
+                'bobGo' => __('BobGo'),
+            ],
+            'unit_of_measure' => [
+                'KGS' => __('Kilograms'),
+                'LBS' => __('Pounds'),
+            ],
+        ];
+
+        if (!isset($codes[$type])) {
+            return false;
+        } elseif ('' === $code) {
+            return $codes[$type];
+        }
+
+        if (!isset($codes[$type][$code])) {
+            return false;
+        } else {
+            return $codes[$type][$code];
+        }
+    }
+
+
+    /**
+     * Get tracking
+     *
+     * @param string|string[] $trackings
+     * @return Result|null
+     */
+    public function getTracking($trackings)
+    {
+        $this->setTrackingReqeust();
+
+        if (!is_array($trackings)) {
+            $trackings = [$trackings];
+        }
+
+        foreach ($trackings as $tracking) {
+            $this->_getXMLTracking($tracking);
+        }
+
+        return $this->_result;
+    }
+
+    /**
+     * Set tracking request
+     *
+     * @return void
+     */
+    protected function setTrackingReqeust()
+    {
+        $r = new \Magento\Framework\DataObject();
+
+        $account = $this->getConfigData('account');
+        $r->setAccount($account);
+
+        $this->_rawTrackingRequest = $r;
+    }
+
+    /**
+     * Send request for tracking
+     *
+     * @param string[] $tracking
+     * @return void
+     */
+    protected function _getXMLTracking($tracking)
+    {
+        $this->_parseTrackingResponse($tracking);
+    }
+
+    /**
+     * Parse tracking response
+     *
+     * @param string $trackingValue
+     * @return void
+     */
+    protected function _parseTrackingResponse($trackingValue)
+    {
+        $result = $this->getResult();
+        $carrierTitle = $this->getConfigData('title');
+        $counter = 0;
+        if (!is_array($trackingValue)) {
+            $trackingValue = [$trackingValue];
+        }
+        foreach ($trackingValue as $trackingReference) {
+            $tracking = $this->_trackStatusFactory->create();
+
+            $tracking->setCarrier(self::CODE);
+            $tracking->setCarrierTitle($carrierTitle);
+
+            //Production
+            /*   $tracking->setUrl(sprintf(uData::TRACKING, $this->getBaseUrl(), $trackingReference));
+            $tracking->setTracking($trackingReference);
+            $tracking->addData($this->processTrackingDetails($trackingReference));
+           */
+
+            //Dev
+            $tracking->setUrl(uData::TRACKING .$trackingReference);
+            $tracking->setTracking($trackingReference);
+            $tracking->addData($this->processTrackingDetails($trackingReference));
+
+            $result->append($tracking);
+            $counter ++;
+        }
+
+        //Tracking Details Not Available
+        if (!$counter) {
+            $this->appendTrackingError(
+                $trackingValue,
+                __('For some reason we can\'t retrieve tracking info right now.')
+            );
+        }
+    }
+
+    /**
+     * Get tracking response
+     *
+     * @return string
+     */
+    public function getResponse()
+    {
+        $statuses = '';
+        if ($this->_result instanceof \Magento\Shipping\Model\Tracking\Result) {
+            if ($trackings = $this->_result->getAllTrackings()) {
+                foreach ($trackings as $tracking) {
+                    if ($data = $tracking->getAllData()) {
+                        if (!empty($data['status'])) {
+                            $statuses .= __($data['status']) . "\n<br/>";
+                        } else {
+                            $statuses .= __('Empty response') . "\n<br/>";
+                        }
+                    }
+                }
+            }
+        }
+        // phpstan:ignore
+        if (empty($statuses)) {
+            $statuses = __('Empty response');
+        }
+
+        return $statuses;
+    }
+
+    /**
+     * Get allowed shipping methods
+     *
+     * @return array
+     */
     public function getAllowedMethods()
     {
-        return [$this->_code => $this->getConfigData('name')];
+        $allowed = explode(',', $this->getConfigData('allowed_methods'));
+        $arr = [];
+        foreach ($allowed as $k) {
+            $arr[$k] = $this->getCode('method', $k);
+        }
+
+        return $arr;
+    }
+
+
+    /**
+     * Do shipment request to carrier web service, obtain Print Shipping Labels and process errors in response
+     * Also another magic function that is required to be implemented by carrier model
+     * @param \Magento\Framework\DataObject $request
+     * @return \Magento\Framework\DataObject
+     */
+    protected function _doShipmentRequest(\Magento\Framework\DataObject $request)
+    {
+        return null;
+
+    }
+
+    /**
+     * For multi package shipments. Delete requested shipments if the current shipment request is failed
+     *
+     * @param array $data
+     *
+     * @return bool
+     */
+    public function rollBack($data)
+    {
+        return true;
+    }
+
+    /**
+     * Return container types of carrier
+     *
+     * @param \Magento\Framework\DataObject|null $params
+     *
+     * @return array|bool
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     */
+    public function getContainerTypes(\Magento\Framework\DataObject $params = null)
+    {
+        $result = [];
+        $allowedContainers = $this->getConfigData('containers');
+        if ($allowedContainers) {
+            $allowedContainers = explode(',', $allowedContainers);
+        }
+        if ($allowedContainers) {
+            foreach ($allowedContainers as $container) {
+                $result[$container] = $this->getCode('container_types', $container);
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Return delivery confirmation types of carrier
+     *
+     * @param \Magento\Framework\DataObject|null $params
+     *
+     * @return array
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function getDeliveryConfirmationTypes(\Magento\Framework\DataObject $params = null)
+    {
+        return $this->getCode('delivery_confirmation_types');
+    }
+
+    /**
+     * Recursive replace sensitive fields in debug data by the mask
+     *
+     * @param string $data
+     * @return string
+     */
+    protected function filterDebugData($data)
+    {
+        foreach (array_keys($data) as $key) {
+            if (is_array($data[$key])) {
+                $data[$key] = $this->filterDebugData($data[$key]);
+            } elseif (in_array($key, $this->_debugReplacePrivateDataKeys)) {
+                $data[$key] = self::DEBUG_KEYS_MASK;
+            }
+        }
+        return $data;
+    }
+
+    /**
+     * Parse track details response from Bob Go
+     *
+     * @return array
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     **/
+    private function processTrackingDetails($trackInfo): array
+    {
+        $result = [
+            'shippeddate' => null,
+            'deliverydate' => null,
+            'deliverytime' => null,
+            'deliverylocation' => null,
+            'weight' => null,
+            'progressdetail' => [],
+        ];
+
+        $result = $this->_requestTracking($trackInfo, $result);
+
+        return $result;
+    }
+
+    /**
+     * Append error message to rate result instance
+     *
+     * @param string $trackingValue
+     * @param string $errorMessage
+     */
+    private function appendTrackingError($trackingValue, $errorMessage)
+    {
+        $error = $this->_trackErrorFactory->create();
+        $error->setCarrier(self::CODE);
+        $error->setCarrierTitle($this->getConfigData('title'));
+        $error->setTracking($trackingValue);
+        $error->setErrorMessage($errorMessage);
+        $result = $this->getResult();
+        $result->append($error);
+    }
+
+    /**
+     * @param string $date
+     * @return string
+     */
+    public function formatDate(string $date): string
+    {
+        return date('d M Y', strtotime($date));
+    }
+
+    /**
+     * @param string $time
+     * @return string
+     */
+    public function formatTime(string $time): string
+    {
+        return date('H:i', strtotime($time));
+    }
+
+    /**
+     * @return string
+     */
+    private function getApiUrl(): string
+    {
+        return uData::RATES_ENDPOINT;
+    }
+
+    /**
+     *  Perfom API Request to bobgo API and return response
+     * @param array $payload
+     * @param Result $result
+     * @return void
+     */
+    protected function _getRates(array $payload, Result $result): void
+    {
+
+        $rates = $this->uRates($payload);
+
+        $this->_formatRates($rates, $result);
+
+    }
+
+    /**
+     * Perform API Request for Shipment Tracking to Bob Go API and return response
+     * @param $trackInfo
+     * @param array $result
+     * @return array
+     */
+    private function _requestTracking($trackInfo, array $result): array
+    {
+        $response = $this->trackbobgoShipment($trackInfo);
+
+        $result = $this->prepareActivity($response[0], $result);
+
+        return $result;
+    }
+
+    /**
+     * Format rates from Bob Go API response and append to rate result instance of carrier
+     * @param mixed $rates
+     * @param Result $result
+     * @return void
+     */
+    protected function _formatRates(mixed $rates, Result $result): void
+    {
+        if (empty($rates)) {
+            $error = $this->_rateErrorFactory->create();
+            $error->setCarrierTitle($this->getConfigData('title'));
+            $error->setErrorMessage($this->getConfigData('specificerrmsg'));
+
+            $result->append($error);
+        } else {
+            $this->_logger->info('Rates is not empty:');
+            foreach ($rates['rates'] as $title) {
+
+                $method = $this->_rateMethodFactory->create();
+                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']);
+
+                        $this->deliveryDays($min_delivery_date, $max_delivery_date, $method);
+
+                    } else {
+                        $method->setCarrierTitle($this->getConfigData('title'));
+                    }
+
+                }
+
+                $method->setMethod($title['service_code']);
+                $method->setMethodTitle($title['service_name']);
+                $price = $title['total_price'];
+                $cost = $title['total_price'];
+
+                // Log the values
+                $this->_logger->info('Price: ' . $price);
+                $this->_logger->info('Cost: ' . $cost);
+
+                // Set the values
+                $method->setPrice($price);
+                $method->setCost($cost);
+
+                $result->append($method);
+            }
+        }
+    }
+
+
+    /**
+     * Prepare received checkpoints and activity from Bob Go Shipment Tracking API
+     * @param $response
+     * @param array $result
+     * @return array
+     */
+    private function prepareActivity($response, array $result): array
+    {
+
+        foreach ($response['checkpoints'] as $checkpoint) {
+            $result['progressdetail'][] = [
+                'activity' => $checkpoint['status'],
+                'deliverydate' => $this->formatDate($checkpoint['time']),
+                'deliverytime' => $this->formatTime($checkpoint['time']),
+                //  'deliverylocation' => 'Unavailable',//TODO: remove this line
+            ];
+        }
+        return $result;
+    }
+
+    /**
+     *  Get Working Days between time of checkout and delivery date (min and max)
+     * @param string $startDate
+     * @param string $endDate
+     * @return int
+     */
+    public function getWorkingDays(string $startDate, string $endDate): int
+    {
+        $begin = strtotime($startDate);
+        $end = strtotime($endDate);
+        if ($begin > $end) {
+//            echo "Start Date Cannot Be In The Future! <br />";
+            return 0;
+        } else {
+            $no_days = 0;
+            $weekends = 0;
+            while ($begin <= $end) {
+                $no_days++; // no of days in the given interval
+                $what_day = date("N", $begin);
+                if ($what_day > 5) { // 6 and 7 are weekend days
+                    $weekends++;
+                };
+                $begin += 86400; // +1 day
+            };
+            return $no_days - $weekends;
+        }
+    }
+
+
+    /**
+     * Curl request to Bob Go Shipment Tracking API
+     * @param $trackInfo
+     * @return mixed
+     */
+    private function trackbobgoShipment($trackInfo): mixed
+    {
+        $this->curl->get(uData::TRACKING . $trackInfo);
+
+        $response = $this->curl->getBody();
+
+        return json_decode($response, true);
+    }
+
+    /**
+     * Build The Payload for Bob Go API Request and return response
+     * @param array $payload
+     * @return mixed
+     */
+    protected function uRates(array $payload): mixed
+    {
+
+        $this->curl->addHeader('Content-Type', 'application/json');
+        $this->curl->post($this->getApiUrl(), json_encode($payload));
+        $rates = $this->curl->getBody();
+
+        $rates = json_decode($rates, true);
+        return $rates;
+    }
+
+
+    /**
+     * @param string $destStreet
+     * @return string[]
+     */
+    protected function destStreet(string $destStreet): array
+    {
+        if (strpos($destStreet, "\n") !== false) {
+            $destStreet = explode("\n", $destStreet);
+            $destStreet1 = $destStreet[0];
+            $destStreet2 = $destStreet[1];
+            $destStreet3 = $destStreet[2] ?? '';
+        } else {
+            $destStreet1 = $destStreet;
+            $destStreet2 = '';
+            $destStreet3 = '';
+        }
+        return array($destStreet1, $destStreet2, $destStreet3);
+    }
+
+    /**
+     * @param int $min_delivery_date
+     * @param int $max_delivery_date
+     * @param $method
+     * @return void
+     */
+    protected function deliveryDays(int $min_delivery_date, int $max_delivery_date, $method): void
+    {
+        if ($min_delivery_date !== $max_delivery_date) {
+            $method->setCarrierTitle('Delivery in '.$min_delivery_date . ' - ' . $max_delivery_date . ' days');
+        }else{
+            $method->setCarrierTitle('Delivery in ' . $min_delivery_date . ' days');
+            if ($min_delivery_date && $max_delivery_date == 1) {
+                $method->setCarrierTitle('Delivery in '.$min_delivery_date . ' day');
+            }
+        }
+    }
+
+    /**
+     * @return mixed|string
+     */
+    public function getDestComp(): mixed
+    {
+        return $this->company->getDestComp();
+    }
+    /**
+     * @return mixed|string
+     */
+    public function getDestSuburb(): mixed
+    {
+        return $this->company->getSuburb();
+    }
+
+    /**
+     * @param mixed $weightUnit
+     * @param mixed $item
+     * @return float|int
+     */
+    public function getItemWeight(mixed $weightUnit, mixed $item): int|float
+    {
+        //1 lb = 453.59237 g exact. 1 kg = 1000 g. 1 lb = 0.45359237 kg
+        if ($weightUnit == 'KGS') {
+            $mass = $item->getWeight() ? $item->getWeight() * 1000 : 0;
+        } else {
+            $mass = $item->getWeight() ? $item->getWeight() * 0.45359237 * 1000 : 0;//Pound to Kilogram Conversion Formula
+        }
+        return $mass;
+    }
+
+    /**
+     * @param array $items
+     * @param mixed $weightUnit
+     * @param array $itemsArray
+     * @return array
+     */
+    public function getStoreItems(array $items, mixed $weightUnit, array $itemsArray): array
+    {
+        foreach ($items as $item) {
+
+            $mass = $this->getItemWeight($weightUnit, $item);
+
+            $itemsArray[] = [
+                'sku' => $item->getSku(),
+                'quantity' => $item->getQty(),
+                'price' => $item->getPrice(),
+                'weight' => round($mass),
+            ];
+
+        }
+        return $itemsArray;
+    }
+
+    /**
+     * Get the list of required data fields
+     * @return bool
+     */
+    public function hasRequiredData(DataObject $request): bool
+    {
+        $requiredFields = [
+            'dest_country_id',
+            'dest_region_id',
+        ];
+
+        foreach ($requiredFields as $field) {
+            if (!$request->getData($field)) {
+                return false;
+            }
+        }
+        return true;
     }
 }
diff --git a/Model/Carrier/uData.php b/Model/Carrier/uData.php
index 7c240efb8efc98617b8b88a1aa1c53c75b5b9069..df3a1686e3fd01edd219516128a84d8b410cd56d 100644
--- a/Model/Carrier/uData.php
+++ b/Model/Carrier/uData.php
@@ -1,17 +1,17 @@
 <?php
-//
-//namespace BobGroup\BobGo\Model\Carrier;
-//
-///**
-// * Class uData
-// * @package BobGroup\BobGo\Model\Carrier
-// */
-//class uData
-//{
-//
-//    /** Tracking Endpoint */
-//    public const TRACKING = 'https://api.dev.bobgo.co.za/tracking?channel=%s&tracking_reference=%s';
-//
-//    /*** RATES API Endpoint*/
-//    public const RATES_ENDPOINT = 'https://api.dev.bobgo.co.za/rates-at-checkout/magento';
-//}
+
+namespace BobGroup\BobGo\Model\Carrier;
+
+/**
+ * Class uData
+ * @package BobGroup\BobGo\Model\Carrier
+ */
+class uData
+{
+
+    /** Tracking Endpoint */
+    public const TRACKING = 'https://api.dev.bobgo.co.za/tracking?channel=%s&tracking_reference=%s';
+
+    /*** RATES API Endpoint*/
+    public const RATES_ENDPOINT = 'https://api.dev.bobgo.co.za/rates-at-checkout/magento';
+}
diff --git a/Model/Carrier/uSubs.php b/Model/Carrier/uSubs.php
index ad685c683356e3af47f0ac7c2926f113d93b9ea4..283f8b5b7ddc9614c9aeef7848cec348ac303707 100644
--- a/Model/Carrier/uSubs.php
+++ b/Model/Carrier/uSubs.php
@@ -1,18 +1,23 @@
 <?php
-//
-//namespace BobGroup\BobGo\Model\Carrier;
-//
-///** Get AdditionalInfo information if available from the Estimate Shipping Methods Request Body */
-//class uSubs
-//{
-//
-//    /**
-//     * @return mixed|string
-//     */
-//    public function getDestComp(): mixed
-//    {
-//        $data = json_decode(file_get_contents('php://input'), true);
-//        return isset($data['address']['company']) ? $data['address']['company'] : '';
-//    }
-//}
-//
+
+namespace BobGroup\BobGo\Model\Carrier;
+
+/** Get Company information if available from the Estimate Shipping Methods Request Body */
+class uSubs
+{
+
+    /**
+     * @return mixed|string
+     */
+    public function getDestComp(): mixed
+    {
+        $data = json_decode(file_get_contents('php://input'), true);
+
+        if (isset($data['address']['company'])) {
+            $destComp = $data['address']['company'];
+        } else {
+            $destComp = '';
+        }
+        return $destComp;
+    }
+}
diff --git a/Model/Source/Dropoff.php b/Model/Source/Dropoff.php
index 79f26d24a7251459b6a74c890187280d18c6624f..e355c3ad31e4bb0c5d66c438ef6880afc30a786a 100644
--- a/Model/Source/Dropoff.php
+++ b/Model/Source/Dropoff.php
@@ -1,12 +1,12 @@
 <?php
-//
-//namespace BobGroup\BobGo\Model\Source;
-//
-//class Dropoff extends Generic
-//{
-//    /**
-//     * Carrier code
-//     * @var string
-//     */
-//    protected string $_code = 'dropoff';
-//}
+
+namespace BobGroup\BobGo\Model\Source;
+
+class Dropoff extends Generic
+{
+    /**
+     * Carrier code
+     * @var string
+     */
+    protected string $_code = 'dropoff';
+}
diff --git a/Model/Source/Freemethod.php b/Model/Source/Freemethod.php
index 57c470f983b16493b73405beab768c175608f219..674f68706a72978fd580ecb1f6ebd157e78b9bfc 100644
--- a/Model/Source/Freemethod.php
+++ b/Model/Source/Freemethod.php
@@ -1,20 +1,20 @@
 <?php
-//
-//namespace BobGroup\BobGo\Model\Source;
-//
-///**
-// * Bob Go Free Method source implementation
-// */
-//class Freemethod extends Method
-//{
-//    /**
-//     * {@inheritdoc}
-//     */
-//    public function toOptionArray()
-//    {
-//        //Returns an array of arrays, each of which has a 'value' and a 'label'. The 'value' is the code for the shipping method, and the 'label' is the name of the shipping method.
-//        $arr = parent::toOptionArray();
-//        array_unshift($arr, ['value' => '', 'label' => __('None')]);
-//        return $arr;
-//    }
-//}
+
+namespace BobGroup\BobGo\Model\Source;
+
+/**
+ * Bob Go Free Method source implementation
+ */
+class Freemethod extends Method
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function toOptionArray()
+    {
+        //Returns an array of arrays, each of which has a 'value' and a 'label'. The 'value' is the code for the shipping method, and the 'label' is the name of the shipping method.
+        $arr = parent::toOptionArray();
+        array_unshift($arr, ['value' => '', 'label' => __('None')]);
+        return $arr;
+    }
+}
diff --git a/Model/Source/Generic.php b/Model/Source/Generic.php
index f1c536ffde3b996d576188759b1e880c39edcdab..674f68706a72978fd580ecb1f6ebd157e78b9bfc 100644
--- a/Model/Source/Generic.php
+++ b/Model/Source/Generic.php
@@ -1,57 +1,20 @@
 <?php
-//
-//namespace BobGroup\BobGo\Model\Source;
-//
-//
-//use Magento\Framework\Data\OptionSourceInterface;
-//use BobGroup\BobGo\Model\Carrier\BobGo;
-//
-///**
-// * bobgo generic source implementation
-// */
-//class Generic implements OptionSourceInterface
-//{
-//    /**
-//     * @var BobGo
-//     */
-//    protected BobGo $_shippingBobGo;
-//
-//    /**
-//     * Carrier code
-//     * @var string
-//     */
-//    protected string $_code = '';
-//
-//    /**
-//     * @param BobGo $shippingBobGo
-//     */
-//    public function __construct(BobGo $shippingBobGo)
-//    {
-//        $this->_shippingBobGo = $shippingBobGo;
-//    }
-//
-//    /**
-//     * Returns array to be used in multiselect on back-end
-//     * @return array
-//     */
-//    public function toOptionArray()
-//    {
-//        $configData = $this->_shippingBobGo->getCode($this->_code);
-//        $arr = [];
-//        if ($configData) {
-//            $arr = array_map(
-//                function ($code, $title) {
-//                    return [
-//                        'value' => $code,
-//                        'label' => $title
-//                    ];
-//                },
-//                array_keys($configData),
-//                $configData
-//            );
-//        }
-//
-//        return $arr;
-//    }
-//
-//}
+
+namespace BobGroup\BobGo\Model\Source;
+
+/**
+ * Bob Go Free Method source implementation
+ */
+class Freemethod extends Method
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function toOptionArray()
+    {
+        //Returns an array of arrays, each of which has a 'value' and a 'label'. The 'value' is the code for the shipping method, and the 'label' is the name of the shipping method.
+        $arr = parent::toOptionArray();
+        array_unshift($arr, ['value' => '', 'label' => __('None')]);
+        return $arr;
+    }
+}
diff --git a/Model/Source/Method.php b/Model/Source/Method.php
index e18b4aaabc9ef584b508064bfcfac2ecae5fc6f0..fe13c122b58ad9be911db099da5774bcec6fe30d 100644
--- a/Model/Source/Method.php
+++ b/Model/Source/Method.php
@@ -1,12 +1,12 @@
 <?php
-//
-//namespace BobGroup\BobGo\Model\Source;
-//
-//class Method extends Generic
-//{
-//    /**
-//     * Carrier code
-//     * @var string
-//     */
-//    protected string $_code = 'method';
-//}
+
+namespace BobGroup\BobGo\Model\Source;
+
+class Method extends Generic
+{
+    /**
+     * Carrier code
+     * @var string
+     */
+    protected string $_code = 'method';
+}
diff --git a/Model/Source/Packaging.php b/Model/Source/Packaging.php
index 2ed2262ec8b670a340e400f55ac8b9d734392df6..a7fce6356606f0bc366c4d8b0b45acd40da71df6 100644
--- a/Model/Source/Packaging.php
+++ b/Model/Source/Packaging.php
@@ -1,12 +1,12 @@
 <?php
-//
-//namespace BobGroup\BobGo\Model\Source;
-//
-//class Packaging extends Generic
-//{
-//    /**
-//     * Carrier code
-//     * @var string
-//     */
-//    protected string $_code = 'packaging';
-//}
+
+namespace BobGroup\BobGo\Model\Source;
+
+class Packaging extends Generic
+{
+    /**
+     * Carrier code
+     * @var string
+     */
+    protected string $_code = 'packaging';
+}
diff --git a/Model/Source/Unitofmeasure.php b/Model/Source/Unitofmeasure.php
index a70e5d3192301214d9dc4df3b91a0af1e975e0ba..be8d13b0455812d4f308f45a235ab4888eb19aa5 100644
--- a/Model/Source/Unitofmeasure.php
+++ b/Model/Source/Unitofmeasure.php
@@ -1,29 +1,13 @@
 <?php
-////
-////namespace BobGroup\BobGo\Model\Source;
-////
-////class Unitofmeasure extends Generic
-////{
-////    /**
-////     * Carrier code
-////     * @var string
-////     */
-////    protected string $_code = 'unit_of_measure';
-////
-////}
-//
-//
-//namespace BobGroup\BobGo\Model\Source;
-//
-//use Magento\Framework\Option\ArrayInterface;
-//
-//class Unitofmeasure implements ArrayInterface
-//{
-//    public function toOptionArray()
-//    {
-//        return [
-//            ['value' => 'KGS', 'label' => __('Kilograms')],
-//            ['value' => 'LBS', 'label' => __('Pounds')]
-//        ];
-//    }
-//}
+
+namespace BobGroup\BobGo\Model\Source;
+
+class Unitofmeasure extends Generic
+{
+    /**
+     * Carrier code
+     * @var string
+     */
+    protected string $_code = 'unit_of_measure';
+
+}
diff --git a/Observer/ConfigChangeObserver.php b/Observer/ConfigChangeObserver.php
deleted file mode 100644
index ad1c4420a3762fe1999559d8562b63f3ce9fe2a9..0000000000000000000000000000000000000000
--- a/Observer/ConfigChangeObserver.php
+++ /dev/null
@@ -1,125 +0,0 @@
-<?php
-//
-//namespace BobGroup\BobGo\Observer;
-//
-//use Magento\Framework\Event\Observer;
-//use Magento\Framework\Event\ObserverInterface;
-//use Magento\Framework\App\Config\ScopeConfigInterface;
-//use Magento\Framework\HTTP\Client\Curl;
-//use Psr\Log\LoggerInterface;
-//
-//class ConfigChangeObserver implements ObserverInterface
-//{
-//    protected $scopeConfig;
-//    protected $curl;
-//    protected $logger;
-//
-//    public function __construct(
-//        ScopeConfigInterface $scopeConfig,
-//        Curl $curl,
-//        LoggerInterface $logger
-//    ) {
-//        $this->scopeConfig = $scopeConfig;
-//        $this->curl = $curl;
-//        $this->logger = $logger;
-//    }
-//
-//    public function execute(Observer $observer)
-//    {
-//        $sectionId = $observer->getEvent()->getSection();
-//
-//        // Ensure we're working with the 'carriers' section
-//        if ($sectionId === 'carriers') {
-//            $isEnabled = $this->scopeConfig->getValue('carriers/bobgo/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
-//
-//            // Check if the extension is enabled
-//            if ($isEnabled) {
-//                $url = 'https://api.dev.bobgo.co.za/rates-at-checkout/magento';
-//
-//                // Prepare the payload
-//                $payload = json_encode([
-//                    "identifier" => "woodemo3.bobgo.co.za",
-//                    "rate" => [
-//                        "origin" => [
-//                            "country" => "ZA",
-//                            "postal_code" => "0181",
-//                            "province" => "GP",
-//                            "city" => "Pretoria",
-//                            "name" => null,
-//                            "address1" => "125 Dallas Avenue",
-//                            "address2" => "Newlands",
-//                            "address3" => null,
-//                            "phone" => "",
-//                            "fax" => "",
-//                            "email" => null,
-//                            "address_type" => null,
-//                            "company_name" => ""
-//                        ],
-//                        "destination" => [
-//                            "country" => "ZA",
-//                            "postal_code" => "0181",
-//                            "province" => "GP",
-//                            "city" => "Pretoria",
-//                            "name" => null,
-//                            "address1" => null,
-//                            "address2" => "",
-//                            "address3" => null,
-//                            "phone" => "",
-//                            "fax" => "",
-//                            "email" => null,
-//                            "address_type" => null,
-//                            "company_name" => "",
-//                            "shipping_suburb" => "Elarduspark"
-//                        ],
-//                        "currency" => "ZAR",
-//                        "locale" => "en",
-//                        "items" => [
-//                            [
-//                                "name" => "Colours With Variants - Has dimensions - Red",
-//                                "sku" => "sku-1",
-//                                "quantity" => 2,
-//                                "price" => 500,
-//                                "vendor" => "",
-//                                "requires_shipping" => true,
-//                                "taxable" => true,
-//                                "fulfillment_service" => "manual",
-//                                "properties" => null,
-//                                "product_id" => 160824,
-//                                "grams" => 2000,
-//                                "height" => 20,
-//                                "length" => 43,
-//                                "width" => 63,
-//                                "variant_id" => 160826,
-//                                "shipping_class" => "colours",
-//                                "shipping_class_id" => 41
-//                            ]
-//                        ]
-//                    ]
-//                ]);
-//
-//                try {
-//                    // Set headers
-//                    $this->curl->addHeader("Accept", "*/*");
-//                    $this->curl->addHeader("Accept-Encoding", "deflate, gzip, br");
-//                    $this->curl->addHeader("Content-Type", "application/json; charset=utf-8");
-//                    $this->curl->addHeader("Host", "api.dev.bobgo.co.za");
-//                    $this->curl->addHeader("User-Agent", "Magento/2.x");
-//
-//                    // Send the request
-//                    $this->curl->post($url, $payload);
-//
-//                    // Check response status
-//                    if ($this->curl->getStatus() == 200) {
-//                        $response = $this->curl->getBody();
-//                        $this->logger->info('Bob Go API response:', ['response' => $response]);
-//                    } else {
-//                        $status = $this->curl->getStatus();
-//                        $this->logger->error('Bob Go API request failed.', ['status' => $status, 'url' => $url]);
-//                    }
-//                } catch (\Exception $e) {
-//                    $this->logger->error('Bob Go API request error:', ['exception' => $e->getMessage()]);
-//                }
-//            }
-//        }
-//    }
-//}
diff --git a/Plugin/Block/DataProviders/Tracking/ChangeTitle.php b/Plugin/Block/DataProviders/Tracking/ChangeTitle.php
index 8c6b58b532fba1a04ed86409c04a94f0036ae923..03d6b4c431d49ef9588960332a9e4213a815173e 100644
--- a/Plugin/Block/DataProviders/Tracking/ChangeTitle.php
+++ b/Plugin/Block/DataProviders/Tracking/ChangeTitle.php
@@ -1,32 +1,32 @@
 <?php
-//
-//namespace BobGroup\BobGo\Plugin\Block\DataProviders\Tracking;
-//
-//use BobGroup\BobGo\Model\Carrier;
-//use Magento\Shipping\Model\Tracking\Result\Status;
-//use Magento\Shipping\Block\DataProviders\Tracking\DeliveryDateTitle as Subject;
-//
-//
-///**
-// * Plugin to change delivery date title with bobgo customized value
-// */
-//
-//class ChangeTitle
-//{
-//    /**
-//     * Title modification in case if bobgo used as carrier
-//     *
-//     * @param Subject $subject
-//     * @param \Magento\Framework\Phrase|string $result
-//     * @param Status $trackingStatus
-//     * @return \Magento\Framework\Phrase|string
-//     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-//     */
-//    public function afterGetTitle(Subject $subject, $result, Status $trackingStatus)
-//    {
-//        if ($trackingStatus->getCarrier() === Carrier::CODE) {
-//            $result = __('Expected Delivery:');
-//        }
-//        return $result;
-//    }
-//}
+
+namespace BobGroup\BobGo\Plugin\Block\DataProviders\Tracking;
+
+use BobGroup\BobGo\Model\Carrier;
+use Magento\Shipping\Model\Tracking\Result\Status;
+use Magento\Shipping\Block\DataProviders\Tracking\DeliveryDateTitle as Subject;
+
+
+/**
+ * Plugin to change delivery date title with bobgo customized value
+ */
+
+class ChangeTitle
+{
+    /**
+     * Title modification in case if bobgo used as carrier
+     *
+     * @param Subject $subject
+     * @param \Magento\Framework\Phrase|string $result
+     * @param Status $trackingStatus
+     * @return \Magento\Framework\Phrase|string
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function afterGetTitle(Subject $subject, $result, Status $trackingStatus)
+    {
+        if ($trackingStatus->getCarrier() === Carrier::CODE) {
+            $result = __('Expected Delivery:');
+        }
+        return $result;
+    }
+}
diff --git a/Plugin/Block/Tracking/PopUpDeliveryDate.php b/Plugin/Block/Tracking/PopUpDeliveryDate.php
index d0d2f1cf8e6dfae77fd5aa5d75d4467a09dd4aee..18c07ebf94298a5a8703f3f80f3efe5cb44e0f01 100644
--- a/Plugin/Block/Tracking/PopUpDeliveryDate.php
+++ b/Plugin/Block/Tracking/PopUpDeliveryDate.php
@@ -1,49 +1,49 @@
 <?php
-//
-//namespace BobGroup\BobGo\Plugin\Block\Tracking;
-//
-//use Magento\Shipping\Block\Tracking\Popup;
-//use Magento\Shipping\Model\Tracking\Result\Status;
-//use Magento\Shipping\Model\Carrier;
-//
-///*
-// * Plugin to update delivery date value in case if Bob Go is a carrier used
-// */
-//class PopupDeliveryDate
-//{
-//    /**
-//     * Show only date for expected delivery in case if Bob Go is a carrier
-//     *
-//     * @param Popup $subject
-//     * @param string $result
-//     * @param string $date
-//     * @param string $time
-//     * @return string
-//     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-//     */
-//    public function afterFormatDeliveryDateTime(Popup $subject, $result, $date, $time)
-//    {
-//        if ($this->getCarrier($subject) === Carrier::CODE) {
-//            $result = $subject->formatDeliveryDate($date);
-//        }
-//        return $result;
-//    }
-//
-//    /**
-//     * Retrieve carrier name from tracking info
-//     *
-//     * @param Popup $subject
-//     * @return string
-//     */
-//    private function getCarrier(Popup $subject): string
-//    {
-//        foreach ($subject->getTrackingInfo() as $trackingData) {
-//            foreach ($trackingData as $trackingInfo) {
-//                if ($trackingInfo instanceof Status) {
-//                    return $trackingInfo->getCarrier();
-//                }
-//            }
-//        }
-//        return '';
-//    }
-//}
+
+namespace BobGroup\BobGo\Plugin\Block\Tracking;
+
+use Magento\Shipping\Block\Tracking\Popup;
+use Magento\Shipping\Model\Tracking\Result\Status;
+use Magento\Shipping\Model\Carrier;
+
+/*
+ * Plugin to update delivery date value in case if Bob Go is a carrier used
+ */
+class PopupDeliveryDate
+{
+    /**
+     * Show only date for expected delivery in case if Bob Go is a carrier
+     *
+     * @param Popup $subject
+     * @param string $result
+     * @param string $date
+     * @param string $time
+     * @return string
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function afterFormatDeliveryDateTime(Popup $subject, $result, $date, $time)
+    {
+        if ($this->getCarrier($subject) === Carrier::CODE) {
+            $result = $subject->formatDeliveryDate($date);
+        }
+        return $result;
+    }
+
+    /**
+     * Retrieve carrier name from tracking info
+     *
+     * @param Popup $subject
+     * @return string
+     */
+    private function getCarrier(Popup $subject): string
+    {
+        foreach ($subject->getTrackingInfo() as $trackingData) {
+            foreach ($trackingData as $trackingInfo) {
+                if ($trackingInfo instanceof Status) {
+                    return $trackingInfo->getCarrier();
+                }
+            }
+        }
+        return '';
+    }
+}
diff --git a/Plugin/Checkout/Block/LayoutProcessorPlugin.php b/Plugin/Checkout/Block/LayoutProcessorPlugin.php
index 62064bf9321d63338ddaae98db4635b806130e9c..1c32fb6afc4d8e9b0956ec0534ad9adc237f88ab 100644
--- a/Plugin/Checkout/Block/LayoutProcessorPlugin.php
+++ b/Plugin/Checkout/Block/LayoutProcessorPlugin.php
@@ -1,55 +1,55 @@
 <?php
-//namespace BobGroup\BobGo\Plugin\Checkout\Block;
-//
-//use Magento\Checkout\Block\Checkout\LayoutProcessor;
-//
-///**
-// * Class LayoutProcessorPlugin
-// * @package BobGroup\BobGo\Plugin\Checkout\Block
-// * This class is supposed to add a new field to the checkout page for the suburb. It is supposed to be used in conjunction with the SaveOrderBeforeSalesModelQuote observer.
-// * At the moment, it overrides the 2 Address fields and adds a new 3 Address field to accommodate the suburb on the checkout page( including placeholders).
-// * This is not the best way to do it, but it is the only way I could get it to work.
-// */
-//class LayoutProcessorPlugin
-//{
-//    /**
-//     * @param \Magento\Checkout\Block\Checkout\LayoutProcessor $subject
-//     * @param array $jsLayout
-//     * @return array
-//     */
-//
-//    public function afterProcess(
-//        \Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
-//        array  $jsLayout
-//    ) {
-//        $suburbAttribute = 'suburb';
-//        $suburb = [
-//            'component' => 'Magento_Ui/js/form/element/abstract',
-//            'config' => [
-//                'customScope' => 'shippingAddress.custom_attributes',
-//                'customEntry' => null,
-//                'template' => 'ui/form/field',
-//                'elementTmpl' => 'ui/form/element/input',
-//                'tooltip' => [
-//                    'description' => 'Required for shipping accuracy',
-//                ],
-//            ],
-//            'dataScope' => 'shippingAddress.custom_attributes' . '.' . $suburbAttribute,
-//            'label' => 'Suburb',
-//            'provider' => 'checkoutProvider',
-//            'sortOrder' => 80,
-//            'validation' => [
-//                'required-entry' => true
-//            ],
-//            'options' => [],
-//            'filterBy' => null,
-//            'customEntry' => null,
-//            'visible' => true,
-//            'value' => '' // value field is used to set a default value of the attribute
-//        ];
-//
-//        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children'][$suburbAttribute] = $suburb;
-//
-//        return $jsLayout;
-//    }
-//}
+namespace BobGroup\BobGo\Plugin\Checkout\Block;
+
+use Magento\Checkout\Block\Checkout\LayoutProcessor;
+
+/**
+ * Class LayoutProcessorPlugin
+ * @package BobGroup\BobGo\Plugin\Checkout\Block
+ * This class is supposed to add a new field to the checkout page for the suburb. It is supposed to be used in conjunction with the SaveOrderBeforeSalesModelQuote observer.
+ * At the moment, it overrides the 2 Address fields and adds a new 3 Address field to accommodate the suburb on the checkout page( including placeholders).
+ * This is not the best way to do it, but it is the only way I could get it to work.
+ */
+class LayoutProcessorPlugin
+{
+    /**
+     * @param \Magento\Checkout\Block\Checkout\LayoutProcessor $subject
+     * @param array $jsLayout
+     * @return array
+     */
+
+    public function afterProcess(
+        \Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
+        array  $jsLayout
+    ) {
+        $suburbAttribute = 'suburb';
+        $suburb = [
+            'component' => 'Magento_Ui/js/form/element/abstract',
+            'config' => [
+                'customScope' => 'shippingAddress.custom_attributes',
+                'customEntry' => null,
+                'template' => 'ui/form/field',
+                'elementTmpl' => 'ui/form/element/input',
+                'tooltip' => [
+                    'description' => 'Required for shipping accuracy',
+                ],
+            ],
+            'dataScope' => 'shippingAddress.custom_attributes' . '.' . $suburbAttribute,
+            'label' => 'Suburb',
+            'provider' => 'checkoutProvider',
+            'sortOrder' => 80,
+            'validation' => [
+                'required-entry' => true
+            ],
+            'options' => [],
+            'filterBy' => null,
+            'customEntry' => null,
+            'visible' => true,
+            'value' => '' // value field is used to set a default value of the attribute
+        ];
+
+        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children'][$suburbAttribute] = $suburb;
+
+        return $jsLayout;
+    }
+}
diff --git a/composer.json b/composer.json
index 011eabb3535d13996f7789c37cba274b7267c292..b7c15e0d0b804af9ba3fda5d14a4b0ec2ae67d59 100644
--- a/composer.json
+++ b/composer.json
@@ -1,23 +1,25 @@
 {
-  "name": "bobgroup/bobgo",
-  "description": "A simple flat rate shipping method for Magento 2",
-  "require": {
-    "php": "~7.1.3||~7.2.0||~7.3.0||~7.4.0",
-    "magento/framework": "*"
-  },
+  "name": "bobgo/bobgo",
+  "description": "Streamline your shipments fulfillment's with Bob Go",
   "type": "magento2-module",
   "version": "1.0.0",
+  "authors": [
+    {
+      "name": "Bob Go",
+      "email": "support@bobgo.co.za",
+      "homepage": "https://www.bobgo.co.za"
+    }
+  ],
   "license": [
-    "OSL-3.0",
-    "AFL-3.0"
+    "AFL-3.0",
+    "OSL-3.0"
   ],
   "autoload": {
     "files": [
       "registration.php"
     ],
     "psr-4": {
-      "BobGroup\\BobGo\\": ""
+      "bobgo\\BobGo\\": ""
     }
   }
 }
-
diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml
index 3ab835f9bd136165898e6ed822019319ccb89ffe..0d3fa3adc894f9aa28968138ba8856ee6379a46f 100644
--- a/etc/adminhtml/system.xml
+++ b/etc/adminhtml/system.xml
@@ -1,40 +1,82 @@
 <?xml version="1.0"?>
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
     <system>
-        <section id="carriers">
-            <group id="bobgo" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
-                <label>Bob Go</label>
-                <field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Enabled</label>
+
+        <tab id="bobgo" translate="label" sortOrder="2">
+            <label>Bob Go</label>
+        </tab>
+        <section id="BobGroup_BobGo"  showInDefault="1">
+            <tab>bobgo</tab>
+            <label>Settings</label>
+            <resource>Magento_Config::config</resource>
+            <group id="general"  showInDefault="1">
+                <label>Settings</label>
+                <field id="enabled" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Extension enabled</label>
                     <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                 </field>
-                <field id="title" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Title</label>
+            </group>
+        </section>
+
+        <section id="general" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+            <group id="store_information" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+                <field id="suburb" translate="label" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Suburb</label>
+                    <can_be_empty>1</can_be_empty>
                 </field>
-                <field id="name" translate="label" type="text" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Method Name</label>
+            </group>
+        </section>
+
+        <section id="carriers" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
+            <group id="bobgo" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
+                <label>Bob Go</label>
+                <field id="version" translate="label" type="label" sortOrder="0" showInDefault="1" showInWebsite="0" showInStore="0">
+                    <label>Version</label>
+                    <frontend_model>BobGroup\BobGo\Block\System\Config\Form\Field\Version</frontend_model>
                 </field>
-                <field id="shipping_cost" translate="label" type="text" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Shipping Cost</label>
-                    <validate>validate-number validate-zero-or-greater</validate>
+                <field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Show rates for checkout</label>
+                    <comment>When this setting is enabled, your customers will be presented with shipping rates at checkout, as configured on the Bob Go platform under Rates at checkout.</comment>
+                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
+                </field>
+                <field id="specificerrmsg" translate="label" type="textarea" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Displayed Error Message</label>
+                    <comment>The message displayed to the customer when no rates were available on Bob Go.</comment>
                 </field>
-                <field id="sallowspecific" translate="label" type="select" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="1">
+
+                <field id="sallowspecific" translate="label" type="select" sortOrder="90" showInDefault="1" showInWebsite="1" showInStore="0">
                     <label>Ship to Applicable Countries</label>
+                    <frontend_class>shipping-applicable-country</frontend_class>
                     <source_model>Magento\Shipping\Model\Config\Source\Allspecificcountries</source_model>
                 </field>
-                <field id="specificcountry" translate="label" type="multiselect" sortOrder="6" showInDefault="1" showInWebsite="1" showInStore="1">
+
+                <field id="specificcountry" translate="label" type="multiselect" sortOrder="91" showInDefault="1" showInWebsite="1" showInStore="0">
                     <label>Ship to Specific Countries</label>
                     <source_model>Magento\Directory\Model\Config\Source\Country</source_model>
+                    <can_be_empty>1</can_be_empty>
                 </field>
-                <field id="showmethod" translate="label" type="select" sortOrder="7" showInDefault="1" showInWebsite="1" showInStore="1">
+
+                <field id="showmethod" translate="label" type="select" sortOrder="92" showInDefault="1" showInWebsite="1" showInStore="0">
                     <label>Show Method if Not Applicable</label>
+                    <frontend_class>shipping-skip-hide</frontend_class>
                     <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                 </field>
-                <field id="sort_order" translate="label" type="text" sortOrder="8" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Sort Order</label>
+                <field id="unit_of_measure" translate="label" type="select" sortOrder="73" showInDefault="1" showInWebsite="1">
+                    <label>Weight Unit</label>
+                    <source_model>BobGroup\BobGo\Model\Source\Unitofmeasure</source_model>
+                </field>
+                <field id="max_package_weight" translate="label" type="text" sortOrder="90" showInDefault="1" showInWebsite="1">
+                    <label>Maximum Package Weight (Please consult your shipping carrier for maximum supported shipping weight)</label>
+                    <validate>validate-number validate-zero-or-greater</validate>
+                </field>
+                <field id="additional_info" translate="label" type="select" sortOrder="7" showInDefault="1" showInWebsite="1">
+                    <label>Show additional rate information</label>
+                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
+                    <comment>Displays the delivery timeframe and additional service level description as configured on Bob Go.</comment>
                 </field>
             </group>
         </section>
+
+
     </system>
 </config>
diff --git a/etc/config.xml b/etc/config.xml
index bc3eea048bff01fcd31c06cb4f89a049aae6c5a2..76bb4d731ccc6063b50651f3112ce20cadaa962b 100644
--- a/etc/config.xml
+++ b/etc/config.xml
@@ -1,19 +1,25 @@
 <?xml version="1.0"?>
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
     <default>
+        <BobGroup_BobGo>
+            <general>
+                <debug>0</debug>
+            </general>
+        </BobGroup_BobGo>
+
         <carriers>
             <bobgo>
-                <active>1</active>
-                <title>Bob Go</title>
-                <name>BobGo</name>
-                <shipping_cost>5.00</shipping_cost>
-                <sallowspecific>0</sallowspecific>
-                <specificcountry></specificcountry>
-                <showmethod>1</showmethod>
-                <sort_order>15</sort_order>
+                <active>0</active>
+                <!--                <sallowspecific>1</sallowspecific>
+                                <specificcountry>ZA</specificcountry>-->
+                <price>0.00</price>
                 <model>BobGroup\BobGo\Model\Carrier\BobGo</model>
+                <name>Fixed</name>
+                <max_package_weight>300</max_package_weight>
+                <title>Bob Go</title>
+                <specificerrmsg>We could not find any shipping rates for your delivery address. Please make sure your address is correct. If you are experiencing problems, please contact us.</specificerrmsg>
             </bobgo>
         </carriers>
+
     </default>
 </config>
diff --git a/etc/di.xml b/etc/di.xml
deleted file mode 100644
index d56202c8ac4a2449e376762cd8cadd58ccfedb66..0000000000000000000000000000000000000000
--- a/etc/di.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0"?>
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
-    <preference for="Magento\Shipping\Model\Carrier\CarrierInterface" type="BobGroup\BobGo\Model\Carrier\BobGo"/>
-</config>
diff --git a/etc/extension_attributes.xml b/etc/extension_attributes.xml
index 35a9f29de875a550866fe822961ddede219448ee..82d4ec473cc139e2b5821cf7dbbe53971255bb38 100644
--- a/etc/extension_attributes.xml
+++ b/etc/extension_attributes.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0"?>
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Company:etc/extension_attributes.xsd">
+<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/frontend/di.xml b/etc/frontend/di.xml
index d56202c8ac4a2449e376762cd8cadd58ccfedb66..2ee6f54f96f9264b803de3a8dd8f99b923988f76 100644
--- a/etc/frontend/di.xml
+++ b/etc/frontend/di.xml
@@ -1,4 +1,10 @@
-<?xml version="1.0"?>
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
-    <preference for="Magento\Shipping\Model\Carrier\CarrierInterface" type="BobGroup\BobGo\Model\Carrier\BobGo"/>
+    <type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
+        <plugin name="add_custom_field_checkout_shipping_form" type="BobGroup\BobGo\Plugin\Checkout\Block\LayoutProcessorPlugin" sortOrder="10"/>
+        <arguments>
+            <argument name="layoutProcessors" xsi:type="array">
+                <item name="orderattribute" xsi:type="object">BobGroup\BobGo\Plugin\Checkout\Block\LayoutProcessorPlugin</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/etc/module.xml b/etc/module.xml
index 4dfe6ef9065421f4ee88e71cd427bd2975228999..d736136edb4535fca984abcd0b7d2b08fed15e6d 100644
--- a/etc/module.xml
+++ b/etc/module.xml
@@ -1,5 +1,20 @@
 <?xml version="1.0"?>
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
-    <module name="BobGroup_BobGo" setup_version="1.0.0"/>
+<!--
+/**
+ * @category   Bob Go
+ * @package    bobgo_CustomShipping
+ * @author     Bob Go
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
+    <module name="BobGroup_BobGo" setup_version="1.0.0">
+        <sequence>
+            <module name="Magento_Webapi"/>
+            <module name="Magento_Catalog"/>
+            <module name="Magento_Store"/>
+            <module name="Magento_Sales"/>
+            <module name="Magento_Quote"/>
+            <module name="Magento_SalesRule"/>
+        </sequence>
+    </module>
 </config>