checkoutSession = $checkoutSession; $this->helper = $helper; $this->json = $json; $this->logger = $logger; parent::__construct( $context, $customerSession, $customerRepository, $accountManagement ); } /** * @return void */ public function execute() { try { $shippingInfo = $this->getRequest()->getPost('ship'); if (!\is_array($shippingInfo)) { throw new LocalizedException( __('We are unable to process your request. Please, try again later.') ); } $itemsInfo = $this->collectItemsInfo($shippingInfo); $totalQuantity = array_sum($itemsInfo); $maxQuantity = $this->helper->getMaximumQty(); if ($totalQuantity > $maxQuantity) { throw new LocalizedException( __('Maximum qty allowed for Shipping to multiple addresses is %1', $maxQuantity) ); } $quote = $this->checkoutSession->getQuote(); foreach ($quote->getAllItems() as $item) { if (isset($itemsInfo[$item->getId()])) { $this->updateItemQuantity($item, $itemsInfo[$item->getId()]); } } if ($quote->getHasError()) { throw new LocalizedException(__($quote->getMessage())); } $this->jsonResponse(); } catch (LocalizedException $e) { $this->jsonResponse($e->getMessage()); } catch (\Exception $e) { $this->logger->critical($e->getMessage()); $this->jsonResponse('We are unable to process your request. Please, try again later.'); } } /** * Updates quote item quantity. * * @param Item $item * @param float $quantity * @throws LocalizedException */ private function updateItemQuantity(Item $item, float $quantity) { if ($quantity > 0) { $item->setQty($quantity); if ($item->getHasError()) { throw new LocalizedException(__($item->getMessage())); } } } /** * Group posted items. * * @param array $shippingInfo * @return array */ private function collectItemsInfo(array $shippingInfo): array { $itemsInfo = []; foreach ($shippingInfo as $itemData) { if (!\is_array($itemData)) { continue; } foreach ($itemData as $quoteItemId => $data) { if (!isset($itemsInfo[$quoteItemId])) { $itemsInfo[$quoteItemId] = 0; } $itemsInfo[$quoteItemId] += (double)$data['qty']; } } return $itemsInfo; } /** * JSON response builder. * * @param string $error * @return void */ private function jsonResponse(string $error = '') { $this->getResponse()->representJson( $this->json->serialize($this->getResponseData($error)) ); } /** * Returns response data. * * @param string $error * @return array */ private function getResponseData(string $error = ''): array { $response = [ 'success' => true, ]; if (!empty($error)) { $response = [ 'success' => false, 'error_message' => $error, ]; } return $response; } }