8
8
use Magento \Framework \Exception \InputException ;
9
9
use Magento \Framework \Exception \StateException ;
10
10
use Magento \Framework \Exception \NoSuchEntityException ;
11
+ use Magento \Quote \Api \Data \AddressInterface ;
12
+ use Magento \Quote \Api \Data \CartInterface ;
11
13
use Psr \Log \LoggerInterface as Logger ;
12
- use \Magento \Quote \Model \QuoteAddressValidator ;
14
+ use Magento \Quote \Model \QuoteAddressValidator ;
15
+ use Magento \Quote \Api \Data \CartExtensionFactory ;
16
+ use Magento \Quote \Model \ShippingAssignmentFactory ;
17
+ use Magento \Quote \Model \ShippingFactory ;
18
+ use Magento \Framework \App \ObjectManager ;
13
19
14
20
/**
15
21
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -67,6 +73,21 @@ class ShippingInformationManagement implements \Magento\Checkout\Api\ShippingInf
67
73
*/
68
74
protected $ totalsCollector ;
69
75
76
+ /**
77
+ * @var \Magento\Quote\Api\Data\CartExtensionFactory
78
+ */
79
+ private $ cartExtensionFactory ;
80
+
81
+ /**
82
+ * @var \Magento\Quote\Model\ShippingAssignmentFactory
83
+ */
84
+ protected $ shippingAssignmentFactory ;
85
+
86
+ /**
87
+ * @var \Magento\Quote\Model\ShippingFactory
88
+ */
89
+ private $ shippingFactory ;
90
+
70
91
/**
71
92
* @param \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement
72
93
* @param \Magento\Checkout\Model\PaymentDetailsFactory $paymentDetailsFactory
@@ -103,78 +124,45 @@ public function __construct(
103
124
104
125
/**
105
126
* {@inheritDoc}
106
- * @SuppressWarnings(PHPMD.NPathComplexity)
107
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
108
127
*/
109
128
public function saveAddressInformation (
110
129
$ cartId ,
111
130
\Magento \Checkout \Api \Data \ShippingInformationInterface $ addressInformation
112
131
) {
113
132
$ address = $ addressInformation ->getShippingAddress ();
133
+ $ billingAddress = $ addressInformation ->getBillingAddress ();
114
134
$ carrierCode = $ addressInformation ->getShippingCarrierCode ();
115
135
$ methodCode = $ addressInformation ->getShippingMethodCode ();
116
136
137
+ if (!$ address ->getCountryId ()) {
138
+ throw new StateException (__ ('Shipping address is not set ' ));
139
+ }
140
+
117
141
/** @var \Magento\Quote\Model\Quote $quote */
118
142
$ quote = $ this ->quoteRepository ->getActive ($ cartId );
143
+ $ quote = $ this ->prepareShippingAssignment ($ quote , $ address , $ carrierCode . '_ ' . $ methodCode );
119
144
$ this ->validateQuote ($ quote );
120
145
$ quote ->setIsMultiShipping (false );
121
146
122
- $ saveInAddressBook = $ address ->getSaveInAddressBook () ? 1 : 0 ;
123
- $ sameAsBilling = $ address ->getSameAsBilling () ? 1 : 0 ;
124
- $ customerAddressId = $ address ->getCustomerAddressId ();
125
- $ this ->addressValidator ->validate ($ address );
126
- $ quote ->setShippingAddress ($ address );
127
- $ address = $ quote ->getShippingAddress ();
128
-
129
- if ($ customerAddressId ) {
130
- $ addressData = $ this ->addressRepository ->getById ($ customerAddressId );
131
- $ address = $ quote ->getShippingAddress ()->importCustomerAddressData ($ addressData );
132
- }
133
- $ billingAddress = $ addressInformation ->getBillingAddress ();
134
147
if ($ billingAddress ) {
135
148
$ quote ->setBillingAddress ($ billingAddress );
136
149
}
137
150
138
- $ address ->setSaveInAddressBook ($ saveInAddressBook );
139
- $ address ->setSameAsBilling ($ sameAsBilling );
140
- $ address ->setCollectShippingRates (true );
141
-
142
- if (!$ address ->getCountryId ()) {
143
- throw new StateException (__ ('Shipping address is not set ' ));
144
- }
145
-
146
- $ address ->setShippingMethod ($ carrierCode . '_ ' . $ methodCode );
147
-
148
151
try {
149
- $ this ->totalsCollector -> collectAddressTotals ($ quote, $ address );
152
+ $ this ->quoteRepository -> save ($ quote );
150
153
} catch (\Exception $ e ) {
151
154
$ this ->logger ->critical ($ e );
152
- throw new InputException (__ ('Unable to save address . Please check input data. ' ));
155
+ throw new InputException (__ ('Unable to save shipping information . Please check input data. ' ));
153
156
}
154
157
155
- if (!$ address ->getShippingRateByCode ($ address ->getShippingMethod ())) {
158
+ $ shippingAddress = $ quote ->getShippingAddress ();
159
+
160
+ if (!$ shippingAddress ->getShippingRateByCode ($ shippingAddress ->getShippingMethod ())) {
156
161
throw new NoSuchEntityException (
157
162
__ ('Carrier with such method not found: %1, %2 ' , $ carrierCode , $ methodCode )
158
163
);
159
164
}
160
165
161
- if (!$ quote ->validateMinimumAmount ($ quote ->getIsMultiShipping ())) {
162
- throw new InputException ($ this ->scopeConfig ->getValue (
163
- 'sales/minimum_order/error_message ' ,
164
- \Magento \Store \Model \ScopeInterface::SCOPE_STORE ,
165
- $ quote ->getStoreId ()
166
- ));
167
- }
168
-
169
- try {
170
- $ address ->save ();
171
- $ quote ->collectTotals ();
172
- $ this ->quoteRepository ->save ($ quote );
173
- } catch (\Exception $ e ) {
174
- $ this ->logger ->critical ($ e );
175
- throw new InputException (__ ('Unable to save shipping information. Please check input data. ' ));
176
- }
177
-
178
166
/** @var \Magento\Checkout\Api\Data\PaymentDetailsInterface $paymentDetails */
179
167
$ paymentDetails = $ this ->paymentDetailsFactory ->create ();
180
168
$ paymentDetails ->setPaymentMethods ($ this ->paymentMethodManagement ->getList ($ cartId ));
@@ -192,14 +180,70 @@ public function saveAddressInformation(
192
180
*/
193
181
protected function validateQuote (\Magento \Quote \Model \Quote $ quote )
194
182
{
195
- if ($ quote ->isVirtual ()) {
196
- throw new NoSuchEntityException (
197
- __ ('Cart contains virtual product(s) only. Shipping address is not applicable. ' )
198
- );
199
- }
200
-
201
183
if (0 == $ quote ->getItemsCount ()) {
202
184
throw new InputException (__ ('Shipping method is not applicable for empty cart ' ));
203
185
}
204
186
}
187
+
188
+ /**
189
+ * @param CartInterface $quote
190
+ * @param AddressInterface $address
191
+ * @param string $method
192
+ * @return CartInterface
193
+ */
194
+ private function prepareShippingAssignment (CartInterface $ quote , AddressInterface $ address , $ method )
195
+ {
196
+ $ cartExtension = $ quote ->getExtensionAttributes ();
197
+ if ($ cartExtension === null ) {
198
+ $ cartExtension = $ this ->getCartExtensionFactory ()->create ();
199
+ }
200
+ $ shippingAssignment = $ cartExtension ->getShippingAssignments ()[0 ];
201
+ if ($ cartExtension ->getShippingAssignments () === null ) {
202
+ $ shippingAssignment = $ this ->getShippingAssignmentFactory ()->create ();
203
+ }
204
+
205
+ $ shipping = $ shippingAssignment ->getShipping ();
206
+ if ($ shipping === null ) {
207
+ $ shipping = $ this ->getShippingFactory ()->create ();
208
+ }
209
+
210
+ $ shipping ->setAddress ($ address );
211
+ $ shipping ->setMethod ($ method );
212
+ $ shippingAssignment ->setShipping ($ shipping );
213
+ $ cartExtension ->setShippingAssignments ([$ shippingAssignment ]);
214
+ return $ quote ->setExtensionAttributes ($ cartExtension );
215
+ }
216
+
217
+ /**
218
+ * @return CartExtensionFactory
219
+ */
220
+ private function getCartExtensionFactory ()
221
+ {
222
+ if (!$ this ->cartExtensionFactory ) {
223
+ $ this ->cartExtensionFactory = ObjectManager::getInstance ()->get (CartExtensionFactory::class);
224
+ }
225
+ return $ this ->cartExtensionFactory ;
226
+ }
227
+
228
+ /**
229
+ * @return ShippingAssignmentFactory
230
+ */
231
+ private function getShippingAssignmentFactory ()
232
+ {
233
+ if (!$ this ->shippingAssignmentFactory ) {
234
+ $ this ->shippingAssignmentFactory = ObjectManager::getInstance ()->get (ShippingAssignmentFactory::class);
235
+ }
236
+ return $ this ->shippingAssignmentFactory ;
237
+ }
238
+
239
+ /**
240
+ * @return ShippingFactory
241
+ */
242
+ private function getShippingFactory ()
243
+ {
244
+ if (!$ this ->shippingFactory ) {
245
+ $ this ->shippingFactory = ObjectManager::getInstance ()->get (ShippingFactory::class);
246
+ }
247
+ return $ this ->shippingFactory ;
248
+ }
205
249
}
0 commit comments