77
88namespace Magento \Quote \Model ;
99
10+ use Magento \Customer \Api \AddressRepositoryInterface ;
1011use Magento \Framework \App \ObjectManager ;
1112use Magento \Framework \Exception \InputException ;
1213use Magento \Quote \Api \BillingAddressManagementInterface ;
14+ use Magento \Quote \Api \CartRepositoryInterface ;
1315use Magento \Quote \Api \Data \AddressInterface ;
1416use Psr \Log \LoggerInterface as Logger ;
1517
1618/**
1719 * Quote billing address write service object.
20+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1821 */
1922class BillingAddressManagement implements BillingAddressManagementInterface
2023{
24+ /**
25+ * Billing address lock const
26+ *
27+ * @var string
28+ */
29+ private const CART_BILLING_ADDRESS_LOCK = 'cart_billing_address_lock_ ' ;
30+
2131 /**
2232 * Validator.
2333 *
@@ -35,12 +45,12 @@ class BillingAddressManagement implements BillingAddressManagementInterface
3545 /**
3646 * Quote repository object.
3747 *
38- * @var \Magento\Quote\Api\ CartRepositoryInterface
48+ * @var CartRepositoryInterface
3949 */
4050 protected $ quoteRepository ;
4151
4252 /**
43- * @var \Magento\Customer\Api\ AddressRepositoryInterface
53+ * @var AddressRepositoryInterface
4454 */
4555 protected $ addressRepository ;
4656
@@ -49,24 +59,33 @@ class BillingAddressManagement implements BillingAddressManagementInterface
4959 */
5060 private $ shippingAddressAssignment ;
5161
62+ /**
63+ * @var CartAddressMutexInterface
64+ */
65+ private $ cartAddressMutex ;
66+
5267 /**
5368 * Constructs a quote billing address service object.
5469 *
55- * @param \Magento\Quote\Api\ CartRepositoryInterface $quoteRepository Quote repository.
70+ * @param CartRepositoryInterface $quoteRepository Quote repository.
5671 * @param QuoteAddressValidator $addressValidator Address validator.
5772 * @param Logger $logger Logger.
58- * @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository
73+ * @param AddressRepositoryInterface $addressRepository
74+ * @param CartAddressMutexInterface|null $cartAddressMutex
5975 */
6076 public function __construct (
61- \ Magento \ Quote \ Api \ CartRepositoryInterface $ quoteRepository ,
77+ CartRepositoryInterface $ quoteRepository ,
6278 QuoteAddressValidator $ addressValidator ,
6379 Logger $ logger ,
64- \Magento \Customer \Api \AddressRepositoryInterface $ addressRepository
80+ AddressRepositoryInterface $ addressRepository ,
81+ ?CartAddressMutexInterface $ cartAddressMutex = null
6582 ) {
6683 $ this ->addressValidator = $ addressValidator ;
6784 $ this ->logger = $ logger ;
6885 $ this ->quoteRepository = $ quoteRepository ;
6986 $ this ->addressRepository = $ addressRepository ;
87+ $ this ->cartAddressMutex = $ cartAddressMutex ??
88+ ObjectManager::getInstance ()->get (CartAddressMutex::class);
7089 }
7190
7291 /**
@@ -75,8 +94,29 @@ public function __construct(
7594 */
7695 public function assign ($ cartId , AddressInterface $ address , $ useForShipping = false )
7796 {
78- /** @var \Magento\Quote\Model\ Quote $quote */
97+ /** @var Quote $quote */
7998 $ quote = $ this ->quoteRepository ->getActive ($ cartId );
99+ $ billingAddressId = (int ) $ quote ->getBillingAddress ()->getId ();
100+
101+ return $ this ->cartAddressMutex ->execute (
102+ self ::CART_BILLING_ADDRESS_LOCK .$ billingAddressId ,
103+ $ this ->assignBillingAddress (...),
104+ $ billingAddressId ,
105+ [$ address , $ quote , $ useForShipping ]
106+ );
107+ }
108+
109+ /**
110+ * Assign billing address to cart
111+ *
112+ * @param AddressInterface $address
113+ * @param Quote $quote
114+ * @param bool $useForShipping
115+ * @return mixed
116+ * @throws InputException
117+ */
118+ private function assignBillingAddress (AddressInterface $ address , Quote $ quote , bool $ useForShipping = false )
119+ {
80120 $ address ->setCustomerId ($ quote ->getCustomerId ());
81121 $ quote ->removeAddress ($ quote ->getBillingAddress ()->getId ());
82122 $ quote ->setBillingAddress ($ address );
@@ -85,9 +125,10 @@ public function assign($cartId, AddressInterface $address, $useForShipping = fal
85125 $ quote ->setDataChanges (true );
86126 $ this ->quoteRepository ->save ($ quote );
87127 } catch (\Exception $ e ) {
88- $ this ->logger ->critical ($ e );
128+ $ this ->logger ->critical ($ e-> getMessage () );
89129 throw new InputException (__ ('The address failed to save. Verify the address and try again. ' ));
90130 }
131+
91132 return $ quote ->getBillingAddress ()->getId ();
92133 }
93134
0 commit comments