How can I get the customer and cart during collectRates() function of my custom shipping method.
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\Checkout\Model\Cart $cart,
\Magento\Customer\Model\Session $customerSession,
array $data = []
) {
$this->_cart = $cart;
$this->_rateResultFactory = $rateResultFactory;
$this->_rateMethodFactory = $rateMethodFactory;
$this->_customerSession = $customerSession;
parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
}
public function collectRates(RateRequest $request)
{
if (!$this->getConfigFlag('active')) {
return false;
}
if(!$this->_customerSession->isLoggedIn()) {
return false;
}
$customer = $this->_customerSession->getCustomer();
$qty = $this->_cart->getItemsQty();
...
Using customer session and checking if isLoggedIn() only works for frontend but returns false when placing order in the admin.
How can I get customer properly and calculate my price per item for both frontend and admin order placement?
If you can detect when your code runs in Admin, you can use \Magento\Backend\Model\Session\Quote as your [admin_session] and use [admin_session]->getCustomerId(), along with the customer repository (inject interfaces in constructor and let DI pass the correct objects) to fetch the customer object.
I would suggest to check the contents of the \Magento\Backend\Model\Session\Quote object, as it might contain a pre-loaded customer object already, in which case you can avoid loading it.
You could use \Magento\Framework\App\State::getAreaCode() to check if within admin