CheckoutFieldContainerInterfaceBuilder.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <?php
  2. /**
  3. * Refer to LICENSE.txt distributed with the Temando Shipping module for notice of license
  4. */
  5. namespace Temando\Shipping\Model\Order;
  6. use Magento\Framework\Api\AbstractSimpleObjectBuilder;
  7. use Magento\Framework\Api\AttributeInterface;
  8. use Magento\Framework\Api\ObjectFactory;
  9. use Magento\Framework\Exception\LocalizedException;
  10. use Magento\Quote\Api\Data\AddressExtensionInterface;
  11. use Magento\Quote\Model\Quote\Address\RateRequest;
  12. use Magento\Sales\Api\Data\OrderAddressExtensionInterface;
  13. use Magento\Sales\Api\Data\OrderInterface;
  14. use Temando\Shipping\Model\Checkout\Attribute\CheckoutFieldInterface;
  15. use Temando\Shipping\Model\Checkout\Attribute\CheckoutFieldInterfaceFactory;
  16. use Temando\Shipping\Model\Checkout\RateRequest\Extractor;
  17. use Temando\Shipping\Model\Checkout\Schema\CheckoutFieldsSchema;
  18. /**
  19. * Temando Order Checkout Field Container Builder
  20. *
  21. * @package Temando\Shipping\Model
  22. * @author Christoph Aßmann <christoph.assmann@netresearch.de>
  23. * @license https://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * @link https://www.temando.com/
  25. */
  26. class CheckoutFieldContainerInterfaceBuilder extends AbstractSimpleObjectBuilder
  27. {
  28. /**
  29. * @var Extractor
  30. */
  31. private $rateRequestExtractor;
  32. /**
  33. * @var CheckoutFieldsSchema
  34. */
  35. private $schema;
  36. /**
  37. * @var CheckoutFieldInterfaceFactory
  38. */
  39. private $fieldFactory;
  40. /**
  41. * @param ObjectFactory $objectFactory
  42. * @param Extractor $rateRequestExtractor
  43. * @param CheckoutFieldsSchema $schema
  44. * @param CheckoutFieldInterfaceFactory $fieldFactory
  45. */
  46. public function __construct(
  47. ObjectFactory $objectFactory,
  48. Extractor $rateRequestExtractor,
  49. CheckoutFieldsSchema $schema,
  50. CheckoutFieldInterfaceFactory $fieldFactory
  51. ) {
  52. $this->rateRequestExtractor = $rateRequestExtractor;
  53. $this->schema = $schema;
  54. $this->fieldFactory = $fieldFactory;
  55. parent::__construct($objectFactory);
  56. }
  57. /**
  58. * @param \Magento\Framework\Api\AttributeInterface[] $checkoutAttributes
  59. * @return CheckoutFieldInterface[]
  60. */
  61. private function getCheckoutFieldsFromAttributes(array $checkoutAttributes)
  62. {
  63. $availableFields = $this->schema->getFields();
  64. // remove all checkout attributes that are not/no longer in configured fields.
  65. $fnRemoveUnavailableFields = function (AttributeInterface $checkoutAttribute) use ($availableFields) {
  66. return in_array($checkoutAttribute->getAttributeCode(), array_keys($availableFields));
  67. };
  68. $checkoutAttributes = array_filter($checkoutAttributes, $fnRemoveUnavailableFields);
  69. // convert checkout attributes to checkout fields (add data path)
  70. $checkoutFields = array_map(function (AttributeInterface $checkoutAttribute) use ($availableFields) {
  71. /** @var \Temando\Shipping\Model\Checkout\Schema\CheckoutField $fieldDefinition */
  72. $fieldDefinition = $availableFields[$checkoutAttribute->getAttributeCode()];
  73. $checkoutField = $this->fieldFactory->create(['data' => [
  74. CheckoutFieldInterface::FIELD_ID => $checkoutAttribute->getAttributeCode(),
  75. CheckoutFieldInterface::VALUE => $checkoutAttribute->getValue(),
  76. CheckoutFieldInterface::ORDER_PATH => $fieldDefinition->getOrderPath(),
  77. ]]);
  78. return $checkoutField;
  79. }, $checkoutAttributes);
  80. return $checkoutFields;
  81. }
  82. /**
  83. * Set value as selected during checkout (rate request)
  84. *
  85. * For some reason the shipping method management turns the well defined
  86. * extension attribute into an untyped array. Dealing with it here.
  87. *
  88. * @see \Magento\Quote\Model\ShippingMethodManagement::getShippingMethods
  89. * @see \Magento\Quote\Model\ShippingMethodManagement::extractAddressData
  90. *
  91. * @param RateRequest $rateRequest
  92. * @return void
  93. */
  94. public function setRateRequest(RateRequest $rateRequest)
  95. {
  96. try {
  97. $shippingAddress = $this->rateRequestExtractor->getShippingAddress($rateRequest);
  98. $extensionAttributes = $shippingAddress->getExtensionAttributes();
  99. if ($extensionAttributes instanceof AddressExtensionInterface
  100. && is_array($extensionAttributes->getCheckoutFields())
  101. ) {
  102. $checkoutFields = $this->getCheckoutFieldsFromAttributes($extensionAttributes->getCheckoutFields());
  103. } else {
  104. $checkoutFields = [];
  105. }
  106. } catch (LocalizedException $e) {
  107. // detailed address data unavailable
  108. $checkoutFields = [];
  109. }
  110. $this->_set(CheckoutFieldContainerInterface::FIELDS, $checkoutFields);
  111. }
  112. /**
  113. * @param \Magento\Sales\Api\Data\OrderInterface|\Magento\Sales\Model\Order $order
  114. * @return void
  115. */
  116. public function setOrder(OrderInterface $order)
  117. {
  118. $shippingAddress = $order->getShippingAddress();
  119. $extensionAttributes = $shippingAddress->getExtensionAttributes();
  120. if ($extensionAttributes instanceof OrderAddressExtensionInterface
  121. && is_array($extensionAttributes->getCheckoutFields())
  122. ) {
  123. $checkoutFields = $this->getCheckoutFieldsFromAttributes($extensionAttributes->getCheckoutFields());
  124. } else {
  125. $checkoutFields = [];
  126. }
  127. $this->_set(CheckoutFieldContainerInterface::FIELDS, $checkoutFields);
  128. }
  129. }