src/Module/Checkout/Subscriber/OrderAddressToCustomerSubscriber.php line 77

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Module\Checkout\Subscriber;
  4. use App\Module\Account\Entity\User;
  5. use App\Module\Account\Repository\CustomerRepository;
  6. use App\Module\Checkout\Provider\DeniosCustomerProviderInterface;
  7. use BestIt\CommercetoolsODM\Exception\ResponseException;
  8. use App\Module\ShortSimpleCheckout\Event\Cart\CartCreateOrderEvent;
  9. use App\Module\ShortSimpleCheckout\Events;
  10. use BestIt\CommercetoolsODM\Exception\APIException;
  11. use Commercetools\Core\Model\Customer\Customer;
  12. use Commercetools\Core\Model\CustomField\CustomFieldObject;
  13. use Commercetools\Core\Model\Type\TypeReference;
  14. use Denios\SharedConstant\Order\OrderCustom;
  15. use Denios\SharedConstant\Types\CustomTypes;
  16. use Psr\Log\LoggerInterface;
  17. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  18. use Symfony\Component\HttpFoundation\RequestStack;
  19. use \App\Module\Shared\Repository\Commercetools\CustomerRepository as sdkCustomerRepository;
  20. /**
  21. * Handling events before the order is created.
  22. *
  23. * @see OrderCreatedSubscriber for events after the order has been created
  24. *
  25. * @author André Varelmann <andre.varelmann@bestit-online.de>
  26. * @package App\Module\Checkout\Subscriber
  27. *
  28. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  29. */
  30. class OrderAddressToCustomerSubscriber implements EventSubscriberInterface
  31. {
  32. private CustomerRepository $customerRepository;
  33. private RequestStack $requestStack;
  34. private DeniosCustomerProviderInterface $deniosCustomerProvider;
  35. private sdkCustomerRepository $sdkCustomerRepository;
  36. /**
  37. * @param CustomerRepository $customerRepository
  38. * @param RequestStack $requestStack
  39. * @param DeniosCustomerProviderInterface $deniosCustomerProvider
  40. * @param LoggerInterface $logger
  41. * @param SdkCustomerRepository $sdkCustomerRepository
  42. */
  43. public function __construct(
  44. CustomerRepository $customerRepository,
  45. RequestStack $requestStack,
  46. DeniosCustomerProviderInterface $deniosCustomerProvider,
  47. LoggerInterface $logger,
  48. SdkCustomerRepository $sdkCustomerRepository,
  49. ) {
  50. $this->customerRepository = $customerRepository;
  51. $this->requestStack = $requestStack;
  52. $this->deniosCustomerProvider = $deniosCustomerProvider;
  53. $this->logger = $logger;
  54. $this->sdkCustomerRepository = $sdkCustomerRepository;
  55. }
  56. /**
  57. * @return array
  58. */
  59. public static function getSubscribedEvents(): array
  60. {
  61. return [
  62. Events::CART_CREATE_ORDER => [
  63. ['updateCustomerAddress'],
  64. ]
  65. ];
  66. }
  67. public function updateCustomerAddress(CartCreateOrderEvent $event): void
  68. {
  69. $cart = $event->getCart();
  70. $customerId = $cart->getCustomerId();
  71. if ($customerId === null) {
  72. return;
  73. }
  74. /** @var Customer|null $customer */
  75. $customer = $this->customerRepository->find($customerId);
  76. if (!$customer instanceof Customer) {
  77. return;
  78. }
  79. $request = $this->requestStack->getMainRequest();
  80. if ($request !== null && $request->request->getInt('savePayment') !== 1) {
  81. $customer->setCustom($this->updateCustomerPaymentType($cart, $customer));
  82. }
  83. $customerCustomData = $customer->getCustom()->getFields()->toArray();
  84. if (array_key_exists('companyNumber', $customerCustomData) && $customerCustomData['companyNumber'] !== null)
  85. {
  86. $customer = $this->sdkCustomerRepository->setDefaultAddressesByIds(
  87. $customer,
  88. $cart->getBillingAddress()->getId() ?? null,
  89. $cart->getShippingAddress()->getId() ?? null
  90. );
  91. } elseif (array_key_exists('businessPartner', $customerCustomData) && $customerCustomData['companyNumber'] !== null) {
  92. $customer->setCustom($this->setCustomerCustomField(
  93. $customer,
  94. 'defaultBillingAddressId',
  95. $cart->getBillingAddress()->getId()
  96. ));
  97. $customer->setCustom($this->setCustomerCustomField(
  98. $customer,
  99. 'defaultShippingAddressId',
  100. $cart->getShippingAddress()->getId()
  101. ));
  102. }
  103. $customer = $this->sdkCustomerRepository->updateCustomFields($customer);
  104. $this->customerRepository->getDocumentManager()->getUnitOfWork()->registerAsManaged(
  105. $customer,
  106. $customer->getId(),
  107. $customer->getVersion()
  108. );
  109. }
  110. public function updateCustomerPaymentType ($cart, $customer): CustomFieldObject
  111. {
  112. return $this->setCustomerCustomField(
  113. $customer,
  114. 'preferredPaymentType',
  115. $cart->getCustom()->getFields()->getFieldAsString(OrderCustom::PAYMENT_TYPE)
  116. );
  117. }
  118. /**
  119. * @param CartCreateOrderEvent $event
  120. *
  121. * @return void
  122. * @throws ResponseException
  123. * @deprecated
  124. */
  125. public function onCreateOrder(CartCreateOrderEvent $event): void
  126. {
  127. $deniosCustomer = $this->deniosCustomerProvider->getCustomer();
  128. if (!$deniosCustomer instanceof User) {
  129. return;
  130. }
  131. /** @var Customer|null $customer */
  132. $customer = $this->customerRepository->find($deniosCustomer->getId());
  133. if ($customer !== null) {
  134. $cart = $event->getCart();
  135. $request = $this->requestStack->getMainRequest();
  136. if ($request !== null && $request->request->getInt('savePayment') !== 1) {
  137. $customer->setCustom($this->setCustomerCustomField(
  138. $customer,
  139. 'preferredPaymentType',
  140. $cart->getCustom()->getFields()->getFieldAsString(OrderCustom::PAYMENT_TYPE)
  141. ));
  142. }
  143. if ($deniosCustomer->getCompanyNumber() !== null) {
  144. $defaultBillingAddress = $customer->getAddresses()->getByKey(
  145. $cart->getBillingAddress()->getKey()
  146. );
  147. if (null !== $defaultBillingAddress) {
  148. $customer->setDefaultBillingAddressId($defaultBillingAddress->getId());
  149. }
  150. $defaultShippingAddress = $customer->getAddresses()->getByKey(
  151. $cart->getShippingAddress()->getKey()
  152. );
  153. if (null !== $defaultShippingAddress) {
  154. $customer->setDefaultShippingAddressId($defaultShippingAddress->getId());
  155. }
  156. } elseif ($deniosCustomer->getBusinessPartner() !== null) {
  157. $customer->setCustom($this->setCustomerCustomField(
  158. $customer,
  159. 'defaultBillingAddressId',
  160. $cart->getBillingAddress()->getId()
  161. ));
  162. $customer->setCustom($this->setCustomerCustomField(
  163. $customer,
  164. 'defaultShippingAddressId',
  165. $cart->getShippingAddress()->getId()
  166. ));
  167. }
  168. try {
  169. $this->customerRepository->save($customer, true);
  170. } catch (APIException $e) {
  171. $this->logger->error('broken cart can not set customer data:'.$cart->getId());
  172. }
  173. }
  174. }
  175. /**
  176. * Sets a custom field with a value on the customer
  177. *
  178. * @param Customer $customer
  179. * @param string $key
  180. * @param string $value
  181. *
  182. * @return CustomFieldObject
  183. */
  184. private function setCustomerCustomField(Customer $customer, string $key, string $value): CustomFieldObject
  185. {
  186. $customs = [];
  187. $custom = $customer->getCustom();
  188. /** @phpstan-ignore-next-line */
  189. if ($custom) {
  190. $customs = $custom->getFields()->toArray();
  191. }
  192. $customs[$key] = $value;
  193. return CustomFieldObject::fromArray([
  194. 'type' => TypeReference::ofKey(CustomTypes::CUSTOMER_TYPE),
  195. 'fields' => $customs
  196. ]);
  197. }
  198. }