123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- <?php
- /**
- * Refer to LICENSE.txt distributed with the Temando Shipping module for notice of license
- */
- namespace Temando\Shipping\ViewModel\Order;
- use Magento\Directory\Helper\Data as DirectoryHelper;
- use Magento\Framework\App\Config\ScopeConfigInterface;
- use Magento\Framework\Exception\LocalizedException;
- use Magento\Framework\Serialize\Serializer\Json;
- use Magento\Framework\UrlInterface;
- use Magento\Framework\View\Element\Block\ArgumentInterface;
- use Magento\Sales\Api\Data\OrderInterface;
- use Magento\Store\Model\ScopeInterface;
- use Psr\Log\LoggerInterface;
- use Temando\Shipping\Model\Pickup\PickupLoader;
- use Temando\Shipping\Model\ResourceModel\Repository\OrderCollectionPointRepositoryInterface;
- use Temando\Shipping\Model\ResourceModel\Repository\OrderRepositoryInterface;
- use Temando\Shipping\Model\Shipment\ShipmentProviderInterface;
- use Temando\Shipping\ViewModel\CoreApiInterface;
- use Temando\Shipping\ViewModel\DataProvider\CoreApiAccess;
- use Temando\Shipping\ViewModel\DataProvider\CoreApiAccessInterface;
- use Temando\Shipping\ViewModel\DataProvider\DeliveryType;
- use Temando\Shipping\ViewModel\DataProvider\ShippingApiAccess;
- use Temando\Shipping\ViewModel\DataProvider\ShippingApiAccessInterface;
- use Temando\Shipping\ViewModel\OrderShipInterface;
- use Temando\Shipping\ViewModel\Pickup\PickupItems;
- use Temando\Shipping\ViewModel\ShippingApiInterface;
- /**
- * View model for order ship JS component.
- *
- * @package Temando\Shipping\ViewModel
- * @author Christoph Aßmann <christoph.assmann@netresearch.de>
- * @license https://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
- * @link https://www.temando.com/
- */
- class OrderShip implements ArgumentInterface, CoreApiInterface, OrderShipInterface, ShippingApiInterface
- {
- /**
- * @var CoreApiAccess
- */
- private $coreApiAccess;
- /**
- * @var ShippingApiAccess
- */
- private $shippingApiAccess;
- /**
- * @var UrlInterface
- */
- private $urlBuilder;
- /**
- * @var ScopeConfigInterface
- */
- private $scopeConfig;
- /**
- * @var Json
- */
- private $serializer;
- /**
- * @var DeliveryType
- */
- private $deliveryType;
- /**
- * @var OrderRepositoryInterface
- */
- private $orderRepository;
- /**
- * @var ShipmentProviderInterface
- */
- private $shipmentProvider;
- /**
- * @var OrderCollectionPointRepositoryInterface
- */
- private $collectionPointRepository;
- /**
- * @var PickupLoader
- */
- private $pickupLoader;
- /**
- * @var PickupItems
- */
- private $pickupItems;
- /**
- * @var LoggerInterface
- */
- private $logger;
- /**
- * OrderShip constructor.
- * @param CoreApiAccess $coreApiAccess
- * @param ShippingApiAccess $shippingApiAccess
- * @param UrlInterface $urlBuilder
- * @param ScopeConfigInterface $scopeConfig
- * @param Json $serializer
- * @param DeliveryType $deliveryType
- * @param OrderRepositoryInterface $orderRepository
- * @param ShipmentProviderInterface $shipmentProvider
- * @param OrderCollectionPointRepositoryInterface $collectionPointRepository
- * @param PickupLoader $pickupLoader
- * @param PickupItems $pickupItems
- * @param LoggerInterface $logger
- */
- public function __construct(
- CoreApiAccess $coreApiAccess,
- ShippingApiAccess $shippingApiAccess,
- UrlInterface $urlBuilder,
- ScopeConfigInterface $scopeConfig,
- Json $serializer,
- DeliveryType $deliveryType,
- OrderRepositoryInterface $orderRepository,
- ShipmentProviderInterface $shipmentProvider,
- OrderCollectionPointRepositoryInterface $collectionPointRepository,
- PickupLoader $pickupLoader,
- PickupItems $pickupItems,
- LoggerInterface $logger
- ) {
- $this->coreApiAccess = $coreApiAccess;
- $this->shippingApiAccess = $shippingApiAccess;
- $this->urlBuilder = $urlBuilder;
- $this->scopeConfig = $scopeConfig;
- $this->serializer = $serializer;
- $this->deliveryType = $deliveryType;
- $this->orderRepository = $orderRepository;
- $this->shipmentProvider = $shipmentProvider;
- $this->collectionPointRepository = $collectionPointRepository;
- $this->pickupLoader = $pickupLoader;
- $this->pickupItems = $pickupItems;
- $this->logger = $logger;
- }
- /**
- * Obtain order properties for JSON serialization.
- *
- * @return string[]
- */
- private function getOrderProperties(): array
- {
- return [
- 'entity_id',
- 'increment_id',
- 'is_virtual',
- 'store_id',
- 'customer_id',
- 'base_shipping_amount',
- 'customer_is_guest',
- 'billing_address_id',
- 'shipping_address_id',
- 'weight',
- 'total_qty_ordered',
- 'base_currency_code'
- ];
- }
- /**
- * Obtain order item properties for JSON serialization.
- *
- * @return string[]
- */
- private function getOrderItemProperties(): array
- {
- return [
- 'item_id',
- 'order_id',
- 'store_id',
- 'product_id',
- 'weight',
- 'is_virtual',
- 'sku',
- 'name',
- 'qty_ordered',
- 'qty_shipped',
- 'base_price',
- 'base_row_total'
- ];
- }
- /**
- * Obtain order address properties for JSON serialization.
- *
- * @return string[]
- */
- private function getOrderAddressProperties(): array
- {
- return [
- 'entity_id',
- 'postcode',
- 'lastname',
- 'street',
- 'city',
- 'email',
- 'telephone',
- 'country_id',
- 'firstname',
- 'address_type',
- 'prefix',
- 'middlename',
- 'suffix',
- 'company'
- ];
- }
- /**
- * @return OrderInterface|\Magento\Sales\Model\Order
- */
- private function getOrder(): OrderInterface
- {
- /** @var \Magento\Sales\Model\Order\Shipment $shipment */
- $shipment = $this->shipmentProvider->getSalesShipment();
- $order = $shipment->getOrder();
- return $order;
- }
- /**
- * Determine the quantity to be excluded from shipments, e.g. due to them
- * being already prepared for store pickup.
- *
- * @param string $itemSku
- * @return int
- */
- private function getReservedQty(string $itemSku): int
- {
- $order = $this->getOrder();
- if (!$this->deliveryType->isPickupOrder($order)) {
- return 0;
- }
- $orderId = (int)$order->getEntityId();
- $pickups = $this->pickupLoader->load($orderId);
- $this->pickupLoader->register($pickups, $orderId);
- return $this->pickupItems->getQtyPrepared($itemSku);
- }
- /**
- * @return CoreApiAccessInterface
- */
- public function getCoreApiAccess(): CoreApiAccessInterface
- {
- return $this->coreApiAccess;
- }
- /**
- * @return ShippingApiAccessInterface
- */
- public function getShippingApiAccess(): ShippingApiAccessInterface
- {
- return $this->shippingApiAccess;
- }
- /**
- * Obtain Magento REST API endpoint for shipment creation.
- *
- * @return string
- */
- public function getShipEndpoint(): string
- {
- $orderId = $this->getOrder()->getId();
- $endpoint = $this->urlBuilder->getDirectUrl("rest/V1/order/$orderId/ship", ['_secure' => true]);
- // core bug workaround, route parameter "_direct" does not get reset
- $this->urlBuilder->getUrl("rest/V1/order/$orderId/ship", ['_direct' => null]);
- return $endpoint;
- }
- /**
- * Obtain a JSON representation of relevant order data for usage in the
- * OrderShip UI component.
- *
- * @return string
- */
- public function getOrderData(): string
- {
- $order = $this->getOrder();
- $orderItems = [];
- foreach ($order->getAllItems() as $orderItem) {
- if (!$orderItem->getIsVirtual() && !$orderItem->getParentItem()) {
- // skip virtual and child items
- $qtyShipped = $orderItem->getQtyShipped() + $this->getReservedQty($orderItem->getSku());
- $orderItems[$orderItem->getId()] = $orderItem->toArray($this->getOrderItemProperties());
- $orderItems[$orderItem->getId()]['qty_shipped'] = number_format($qtyShipped, 3);
- }
- }
- $orderAddresses = [];
- /** @var \Magento\Sales\Model\Order\Address $orderAddress */
- foreach ($order->getAddresses() as $orderAddress) {
- $orderAddresses[$orderAddress->getId()] = $orderAddress->toArray($this->getOrderAddressProperties());
- $orderAddresses[$orderAddress->getId()]['region'] = $orderAddress->getRegionCode();
- }
- $orderData = $order->toArray($this->getOrderProperties());
- $orderData['items'] = $orderItems;
- $orderData['addresses'] = $orderAddresses;
- try {
- $collectionPoint = $this->collectionPointRepository->get($orderData['shipping_address_id']);
- $orderData['final_recipient_address_id'] = $orderData['shipping_address_id'];
- $orderData['shipping_address_id'] = $collectionPoint->getCollectionPointId();
- $orderData['addresses'][$collectionPoint->getCollectionPointId()] = [
- 'entity_id' => $collectionPoint->getCollectionPointId(),
- 'postcode' => $collectionPoint->getPostcode(),
- 'street' => implode("\n", $collectionPoint->getStreet()),
- 'city' => $collectionPoint->getCity(),
- 'country_id' => $collectionPoint->getCountry(),
- 'address_type' => 'collection_point',
- 'company' => $collectionPoint->getName(),
- 'region' => $collectionPoint->getRegion(),
- ];
- } catch (LocalizedException $exception) {
- $orderData['final_recipient_address_id'] = $orderData['shipping_address_id'];
- }
- return $this->serializer->serialize($orderData);
- }
- /**
- * Obtain a JSON representation of relevant order metadata for usage in the
- * OrderShip UI component.
- *
- * @return string
- */
- public function getOrderMeta(): string
- {
- $order = $this->getOrder();
- $shippingAddressId = $order->getShippingAddress()->getId();
- try {
- $collectionPoint = $this->collectionPointRepository->get($shippingAddressId);
- $isCollectionPoint = (bool) $collectionPoint->getRecipientAddressId();
- } catch (LocalizedException $e) {
- $isCollectionPoint = false;
- }
- $orderMeta = ['isCollectionPoint' => $isCollectionPoint];
- return $this->serializer->serialize($orderMeta);
- }
- /**
- * @return string
- */
- public function getSelectedExperience(): string
- {
- $order = $this->getOrder();
- $shippingMethod = $order->getShippingMethod(true);
- $experienceCode = $shippingMethod->getData('method');
- return $experienceCode;
- }
- /**
- * @return string
- */
- public function getExtOrderId(): string
- {
- $order = $this->getOrder();
- try {
- $orderReference = $this->orderRepository->getReferenceByOrderId($order->getId());
- $extOrderId = $orderReference->getExtOrderId();
- } catch (LocalizedException $e) {
- $this->logger->critical($e->getMessage(), ['exception' => $e]);
- $extOrderId = '';
- }
- return $extOrderId;
- }
- /**
- * @return string
- */
- public function getShipmentViewPageUrl(): string
- {
- return $this->urlBuilder->getUrl('sales/shipment/view', ['shipment_id' => '--id--']);
- }
- /**
- * @return string
- */
- public function getDefaultCurrency(): string
- {
- $order = $this->getOrder();
- return $order->getBaseCurrencyCode();
- }
- /**
- * @return string
- */
- public function getDefaultDimensionsUnit(): string
- {
- $weightUnit = $this->getDefaultWeightUnit();
- if ($weightUnit === 'lbs') {
- return 'in';
- }
- return 'cm';
- }
- /**
- * @return string
- */
- public function getDefaultWeightUnit(): string
- {
- $order = $this->getOrder();
- $weightUnit = $this->scopeConfig->getValue(
- DirectoryHelper::XML_PATH_WEIGHT_UNIT,
- ScopeInterface::SCOPE_STORE,
- $order->getStore()->getCode()
- );
- return $weightUnit;
- }
- /**
- * @return string
- */
- public function getConfigUrl(): string
- {
- return $this->urlBuilder->getUrl('adminhtml/system_config/edit', [
- 'section' => 'carriers',
- '_fragment' => 'carriers_temando-link',
- ]);
- }
- /**
- * Check if a shipment was registered for component rendering.
- * @see \Temando\Shipping\Plugin\Shipping\Order\ShipmentLoaderPlugin::afterLoad
- *
- * @return bool
- */
- public function hasSalesShipment(): bool
- {
- /** @var \Magento\Sales\Model\Order\Shipment $shipment */
- return (bool) $this->shipmentProvider->getSalesShipment();
- }
- }
|