I have created a custom shipping module which calculate the rate according to ordered products weight and selected location(postcode).
There are 3 weights:
- 1: small
- 2: medium
- 3: large
Locations: for locations : 'V' and 'W', The shipping rate is as follow:
- 1: small weight: 5
- 2: medium weight: 10
- 3: large weight: 12
for locations : 'X' and 'Y', The shipping rate is as follow:
- 1: small weight: 15
- 2: medium weight: 40
- 3: large weight: 50
The modules gets all order items then it gets the largest weight. After that it gets the corresponding rate.
The postcode is dropdown on checkout page, When user changes postcode, magento recalculates shipping rate and print the rate in two places:
The logic is working fine in order review, however the rate is not updated as expected under shipping address. If user chooses location V for medium weight item, Both rates updated successfully on checkout to 10, but if he changes the location to location Y, the rate in order review changes to 40 but in shipping method remains the same.
Here is the logic
public function collectRates(RateRequest $request)
{
/**
* Make sure that Shipping method is enabled
*/
if (!$this->isActive()) {
return false;
}
/** @var \Magento\Shipping\Model\Rate\Result $result */
$result = $this->_rateResultFactory->create();
$method = $this->_rateMethodFactory->create();
/**
* Set carrier's method data
*/
$method->setCarrier($this->_code);
$method->setCarrierTitle($this->getConfigData('title'));
/**
* Displayed as shipping method under Carrier
*/
/**
* Get Order Items
*/
$items = $request->getAllItems();
$postcode = $request->getDestPostcode();
$method->setMethod($this->_code);
$method->setMethodTitle($this->getConfigData('name'));
$weight = 1;
/**
* set Weight to the largest item weight
* 1:small, 2:medium, 3:large
*/
foreach ($items as $_item) {
if ($weight < $_item->getWeight()) {
$weight = $_item->getWeight();
}
}
$cityCharges = [
[
'city' => [
'V',
'W'
],
'charge' => [
'price_small' => 5,
'price_medium' => 10,
'price_large' => 12,
]
],
[
'city' => [
'X',
'Y',
],
'charge' => [
'price_small' => 15,
'price_medium' => 40,
'price_large' => 50,
]
],
[
'city' => [
'Z'
],
'charge' => [
'price_small' => 5,
'price_medium' => 10,
'price_large' => 50,
]
],
];
$selectedChargesList = null;
foreach ($cityCharges as $cityCharge) {
if (in_array($postcode, $cityCharge['city'])) {
$selectedChargesList = $cityCharge['charge'];
}
}
switch ($weight) {
case 1:
$price = $selectedChargesList['price_small'];
break;
case 2:
$price = $selectedChargesList['price_medium'];
break;
case 3:
$price = $selectedChargesList['price_large'];
break;
}
$method->setPrice($price);
$method->setCost($price);
$result->append($method);
return $result;
}
protected function getCurrentQuote($quoteId)
{
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$quoteFactory = $objectManager->get('\Magento\Quote\Model\QuoteFactory');
return $quoteFactory->create()->load($quoteId);
}
I think the problem is with this :
https://www.example.com/rest/default/V1/guest-carts/xxxxxxxxx/estimate-shipping-methods
however https://www.example.com/rest/default/V1/guest-carts/xxxxxxxxx/shipping-information is getting the correct rate.