Custom Shipping Method - Retrieve Shipping address in collectRates - php

I'm currently working on a custom shipping method for Magento 2 and I'm facing a problem : I don't know how to retrieve the shipping address.
I tried first with something like this in the collectRates() method :
$city = $request->getDestCity();
$street = $request->getDestStreet();
$postCode = $request->getDestPostcode();
But it didn't worked ($city and $street are empty).
That's strange because I don't have any issue whit the getDestPostcode() method.
Is there a another way to retrieve the shipping address ?
Thanks.

Have you tried like this?
$shippingId = $customerSession->getCustomer()->getDefaultShipping();
$address = $objectManager->create('Magento\Customer\Model\Address')- >load($shippingId);
echo "<pre>";print_r($address->getData());
Hope this helps!

As per Pallavi's answer but with more detail.
/**
* #var \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory
*/
protected $customerSession;
/**
* #param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
* #param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
* #param \Psr\Log\LoggerInterface $logger
* #param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
* #param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
* #param \Magento\Framework\App\RequestInterface $request
* #param \Magento\Framework\App\ObjectManager $objectManager
* #param \Magento\Customer\Model\Session $customerSession
* #param array $data
*/
public function __construct(
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
\Psr\Log\LoggerInterface $logger,
\Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
\Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
\Magento\Framework\App\RequestInterface $request,
\Magento\Customer\Model\Session $customerSession,
array $data = []
) {
$this->rateResultFactory = $rateResultFactory;
$this->rateMethodFactory = $rateMethodFactory;
$this->request = $request;
$this->customerSession = $customerSession;
parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
}
// ...
/**
* #param RateRequest $request
* #return bool|Result
*/
public function collectRates(RateRequest $request)
{
if (!$this->getActiveFlag()) {
// This shipping method is disabled in the configuration
return false;
}
/** #var \Magento\Shipping\Model\Rate\Result $result */
$result = $this->rateResultFactory->create();
/** #var \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
$method = $this->rateMethodFactory->create();
$method->setCarrier(self::SHIPPING_CODE);
// Get the title from the configuration, as defined in system.xml
$method->setCarrierTitle($this->getConfigData('title'));
$method->setMethod(self::SHIPPING_CODE);
// Get the title from the configuration, as defined in system.xml
$method->setMethodTitle($this->getConfigData('name'));
// Get the price from the configuration, as defined in system.xml
$amount = $this->getConfigData('price');
// Get the customer session and shipping address as specified.
$address = $this->customerSession->getCustomer()->getAddressById();
// Note: shippingId will be null on guest checkouts.
// Request to estimate-shipping-methods-by-address-id will send it.
file_put_contents('mydebug.json', '--------------------------\nRequest: \n'.json_encode($request->getData(), JSON_PRETTY_PRINT).PHP_EOL, FILE_APPEND);
file_put_contents('mydebug.json', '--------------------------\nCustomer Address: \n'.json_encode($address->getData(), JSON_PRETTY_PRINT).PHP_EOL, FILE_APPEND);
$method->setPrice($amount);
$method->setCost($amount);
$result->append($method);
return $result;
}
You will need to run a di compile after changing the constructors dependencies/args.
bin/magento setup:di:compile
Notes:
Need JS mixin files to send any custom attributes over as well if using those.
getDefaultShipping() returns null on guest checkout.
I ended up checking the URL as well.
// Get the data from post input via php://input
$request_body = file_get_contents('php://input');
$postData = json_decode($request_body, true);
if (preg_match("/^\/rest\/default\/V1\/carts\/mine\/estimate-shipping-methods-by-address-id/", $_SERVER["REQUEST_URI"])) {
$address = $this->customerSession->getCustomer()->getAddressById($postData['addressId']);
if ($address) {
file_put_contents('liamsdebug.json', '--------------------------\nCustomer Address: \n'.json_encode($address->getData(), JSON_PRETTY_PRINT).PHP_EOL, FILE_APPEND);
}
}

Related

Display flat rate on magento 2 product page

I want to display flat rate on magento 2 product page. I have that code from here:
https://www.magentoextensions.org/documentation/_carrier_2_flatrate_8php_source.html
Code:
<?php
namespace Vendor\MariuszModule\Block;
use Magento\OfflineShipping\Model\Carrier\Flatrate\ItemPriceCalculator;
use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Carrier\AbstractCarrier;
use Magento\Shipping\Model\Carrier\CarrierInterface;
use Magento\Shipping\Model\Rate\Result;
/**
* Class MariuszModule
* #package Vendor\MariuszModule\Block
*/
class MariuszModule extends \Magento\Framework\View\Element\Template
{
/**
* #var Http
*/
protected $request;
/**
* MariuszModule constructor.
* #param \Magento\Backend\Block\Template\Context $context
* #param \Magento\Framework\App\Request\Http $request
* #param array $data
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Framework\App\Request\Http $request,
\Magento\OfflineShipping\Model\Carrier\Flatrate $flatRate,
\Magento\Quote\Model\Quote\Address\RateRequest $rateRequest,
\Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
\Magento\OfflineShipping\Model\Carrier\Flatrate\ItemPriceCalculator $itemPriceCalculator,
array $data = [])
{
$this->request = $request;
$this->itemPriceCalculator = $itemPriceCalculator;
$this->_rateResultFactory = $rateResultFactory;
$this->flatRate = $flatRate;
$this->rateRequest = $rateRequest;
parent::__construct($context, $data);
}
public function saleble()
{
$flatRate = $this->flatRate;
$rateRequest = $this->rateRequest;
$freeBoxes = $flatRate->getFreeBoxesCount($rateRequest);
return $flatRate->getShippingPrice($rateRequest,$freeBoxes);
}
}
But my code display nothing. I really dont know why this don't work.
Thanks for some help

Get Customer ID in Home Page - Magento 2

I need to get the Customer ID primary in Home Page, but not have a Session Interface to give this information.
I tried theses:
\Magento\Backend\Model\Session
\Magento\Catalog\Model\Session
\Magento\Checkout\Model\Session
\Magento\Customer\Model\Session
\Magento\Newsletter\Model\Session
Exists one interface to give Customer ID on every page?
There are methods available in magento2 to get customer id, one of the method is using Object Manager as below code.
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerSession = $objectManager->get('Magento\Customer\Model\Session');
$customerId = $customerSession->getCustomer()->getId(); // get the customer Id
namespace Vendor\Module\Block;
class Form extends \Magento\Framework\View\Element\Template
protected $customerSession;
/**
* Construct
*
* #param \Magento\Framework\View\Element\Template\Context $context
* #param \Magento\Customer\Model\Session $customerSession
* #param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Customer\Model\Session $customerSession,
array $data = []
) {
parent::__construct($context, $data);
$this->customerSession = $customerSession;
}
public function _prepareLayout()
{
var_dump($this->customerSession->getCustomer()->getId());
exit();
return parent::_prepareLayout();
}

Custom shipping method error: Please specify a shipping method

I have a variety of custom shipping methods in my store, but I noticed that, if the user is logged in, the order cannot be finished. The user chooses which shipping method they want and then they cannot pass the payment method, because it keeps giving this error: Please specify a shipping method.
Here's my code:
Model/Carrier/CustomShipping.php
<?php
namespace Magenticians\Moduleshipping\Model\Carrier;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\DataObject;
use Magento\Shipping\Model\Carrier\AbstractCarrier;
use Magento\Shipping\Model\Carrier\CarrierInterface;
use Magento\Shipping\Model\Config;
use Magento\Shipping\Model\Rate\ResultFactory;
use Magento\Store\Model\ScopeInterface;
use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory;
use Magento\Quote\Model\Quote\Address\RateResult\Method;
use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory;
use Magento\Quote\Model\Quote\Address\RateRequest;
use Psr\Log\LoggerInterface;
class Customshipping extends AbstractCarrier implements CarrierInterface
{
/**
* Carrier's code
*
* #var string
*/
protected $_code = 'magenticians_moduleshipping';
/**
* Whether this carrier has fixed rates calculation
*
* #var bool
*/
protected $_isFixed = true;
/**
* #var ResultFactory
*/
protected $_rateResultFactory;
/**
* #var MethodFactory
*/
protected $_rateMethodFactory;
/**
* #param ScopeConfigInterface $scopeConfig
* #param ErrorFactory $rateErrorFactory
* #param LoggerInterface $logger
* #param ResultFactory $rateResultFactory
* #param MethodFactory $rateMethodFactory
* #param array $data
*/
public function __construct(
ScopeConfigInterface $scopeConfig,
ErrorFactory $rateErrorFactory,
LoggerInterface $logger,
ResultFactory $rateResultFactory,
MethodFactory $rateMethodFactory,
array $data = []
) {
$this->_rateResultFactory = $rateResultFactory;
$this->_rateMethodFactory = $rateMethodFactory;
parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
}
/**
* Generates list of allowed carrier's shipping methods
* Displays on cart price rules page
*
* #return array
* #api
*/
public function getAllowedMethods()
{
return [$this->getCarrierCode() => __($this->getConfigData('name'))];
}
/**
* Collect and get rates for storefront
*
* #SuppressWarnings(PHPMD.UnusedFormalParameter)
* #param RateRequest $request
* #return DataObject|bool|null
* #api
*/
public function collectRates(RateRequest $request)
{
/**
* Make sure that Shipping method is enabled
*/
if (!$this->isActive()) {
return false;
}
$weight = 0;
if ($request->getAllItems())
{
foreach ($request->getAllItems() as $item)
{
if ($item->getProduct()->isVirtual())
{
continue;
}
if ($item->getHasChildren())
{
foreach ($item->getChildren() as $child)
{
if (! $child->getProduct()->isVirtual())
{
$weight += $child->getWeight();
}
}
} else
{
$weight += $item->getWeight();
}
}
}
$final_weight = $weight;
/** #var \Magento\Shipping\Model\Rate\Result $result */
$result = $this->_rateResultFactory->create();
$shippingPrice = $this->getConfigData('price');
$method = $this->_rateMethodFactory->create();
/**
* Set carrier's method data
*/
$method->setCarrier($this->getCarrierCode());
$method->setCarrierTitle($this->getConfigData('title'));
/**
* Displayed as shipping method under Carrier
*/
$method->setMethod($this->getCarrierCode());
$method->setMethodTitle($this->getConfigData('name'));
$method->setPrice($shippingPrice);
$method->setCost($shippingPrice);
if($final_weight <= 2) {
$result->append($method);
}
return $result;
}
}
Can't seem to find a reason why, I compared my code with others and they look pretty much identical.
Thanks in advance.
Seems magento 2.2 is not loving underscore on attribute $_code.
$_code = 'magenticians_moduleshipping';
Try change to
protected $_code = 'magenticiansmoduleshipping';

How can i save custom field value in customer_entity table in Magento 2 using observer

Below is my observer code:
<?php
class CustomerOrderCountObserver implements ObserverInterface
{
/**
* #var customerFactory
*/
private $customerFactory;
/**
*
* #param CustomerFactory $customerFactory
*/
public function __construct(
CustomerFactory $customerFactory
) {
$this->customerFactory = $customerFactory;
}
/**
* Upgrade customer password hash when customer has logged in
*
* #param \Magento\Framework\Event\Observer $observer
* #return void
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
$orderInstance = $observer->getEvent()->getdata();
$orderIds = $observer->getEvent()->getdata('order_ids');
$orderCount = is_array($orderIds)?count($orderIds):0;
$orderId = current($orderIds);
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$session = $objectManager->get('Magento\Customer\Model\Session');
if($session->isLoggedIn()) {
$customer = $this->customerFactory->create()->load($session->getCustomerId());
$orderCount = $orderCount + $customer->getOrderCount();
$customer->setOrderCount($orderCount);
$customer->save($customer);
}
}
}
I don't know what I am doing wrong with this. It is not saving the customer column value order_count
Try saving using the customer data changes using a resourceModel instead of saving using the model
$customerResourceModel->save($customer);
Try loading customer from model
$customer = Mage::getModel('customer/customer')->load($session->getCustomerId());

Custom Shipping Method - Please specify a shipping method

I'm working on a custom shipping method and I've been getting exception each times I try to place an order with my method ("Please specify a shipping method").
I tried with the Magento 2 Flat Rate method and it worked.
I found that in Magento/Quote/Model/QuoteValidator.php on line 52, the getShippingMethod() returned nothing because that function :
public function getShippingMethod()
{
return $this->getData('shipping_method');
}
in Magento/Quote/Model/Quote/Address.php returned nothing.
Just in case my code was wrong, I also tried with this custom shipping method (I followed this tutorial to create the method) http://www.blog.magepsycho.com/create-custom-shipping-module-in-magento-2/ (just activate the module and tried to place an order with that method) but I'm facing the same issue.
Does someone know how I can resolve this issue ?
Thanks.
Here is my Model/Carrier/method.php :
class Method extends \Magento\Shipping\Model\Carrier\AbstractCarrier implements \Magento\Shipping\Model\Carrier\CarrierInterface
{
protected $_logger;
/**
* #var string
*/
protected $_code = 'coursierprive_transport';
/**
* #var bool
*/
protected $_isFixed = true;
/**
* #var \Magento\Shipping\Model\Rate\ResultFactory
*/
protected $_rateResultFactory;
/**
* #var \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory
*/
protected $_rateMethodFactory;
/**
* #param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
* #param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
* #param \Psr\Log\LoggerInterface $logger
* #param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
* #param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
* #param array $data
*/
public function __construct(
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
\Psr\Log\LoggerInterface $logger,
\Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
\Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
array $data = []
)
{
$this->_rateResultFactory = $rateResultFactory;
$this->_rateMethodFactory = $rateMethodFactory;
$this->_logger = $logger;
parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
}
/**
* #param RateRequest $request
* #return \Magento\Shipping\Model\Rate\Result
* #SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
public function collectRates(RateRequest $request)
{
if (!$this->getConfigFlag('active'))
return (false);
if ($request->getAllItems())
{
foreach ($request->getAllItems() as $item)
{
// Some stuff used to check dimensions, weight, post code... etc
}
}
if (//some tests)
return (false);
$result = $this->_rateResultFactory->create();
$shippingPrice = 5.5;
$method = $this->_rateMethodFactory->create();
$method->setCarrier($this->_code);
$method->setCarrierTitle($this->getConfigData('title'));
$method->setMethod($this->_code);
$method->setMethodTitle($this->getConfigData('name'));
if ($request->getFreeShipping() === true || $request->getPackageQty() == $this->getFreeBoxes())
$shippingPrice = 0;
$method->setPrice($shippingPrice);
$method->setCost($shippingPrice);
$result->append($method);
return ($result);
}
/**
* Get allowed shipping methods
*
* #return array
*/
public function getAllowedMethods()
{
return (['coursierprive_transport' => $this->getConfigData('name')]);
}
}
Here is my Config.xml :
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../Magento/Store/etc/config.xsd">
<default>
<carriers>
<coursierprive_transport>
<active>1</active>
<sallowspecific>0</sallowspecific>
<price>5.5</price>
<model>CoursierPrive\Transport\Model\Carrier\Method</model>
<name>Express</name>
<title>Coursier Privé</title>
<specificerrmsg>This shipping method is not available. To use this shipping method, please contact us.</specificerrmsg>
</coursierprive_transport>
</carriers>
</default>
</config>
I think that I know what messed up. I suppose there is a size limit for the method name and my first name contained too many chars.
Try to change the code to something short like:
protected $_code = 'couriertransport';
I am not sure if this is the issue but doing so fixed the issue:
https://github.com/MagePsycho/magento2-custom-shipping
My case : protected $_code = 'effectconnect_shipment';
=> so full code must be 'effectconnect_shipment_effectconnect_shipment'
I checked the length of this code is only 40 so rename it to $_code = 'effectconnect'; and it work !!!

Categories