5
5
*/
6
6
namespace Magento \Sales \Model \Order ;
7
7
8
+ use Magento \Bundle \Ui \DataProvider \Product \Listing \Collector \BundlePrice ;
9
+ use Magento \Sales \Api \Data \OrderItemInterface ;
10
+
8
11
/**
9
12
* Factory class for @see \Magento\Sales\Model\Order\Creditmemo
10
13
*/
11
14
class CreditmemoFactory
12
15
{
13
16
/**
14
- * Quote convert object
17
+ * Order convert object.
15
18
*
16
19
* @var \Magento\Sales\Model\Convert\Order
17
20
*/
@@ -63,31 +66,15 @@ public function createByOrder(\Magento\Sales\Model\Order $order, array $data = [
63
66
{
64
67
$ totalQty = 0 ;
65
68
$ creditmemo = $ this ->convertor ->toCreditmemo ($ order );
66
- $ qtys = isset ($ data ['qtys ' ]) ? $ data ['qtys ' ] : [];
69
+ $ qtyList = isset ($ data ['qtys ' ]) ? $ data ['qtys ' ] : [];
67
70
68
71
foreach ($ order ->getAllItems () as $ orderItem ) {
69
- if (!$ this ->canRefundItem ($ orderItem , $ qtys )) {
72
+ if (!$ this ->canRefundItem ($ orderItem , $ qtyList )) {
70
73
continue ;
71
74
}
72
75
73
76
$ item = $ this ->convertor ->itemToCreditmemoItem ($ orderItem );
74
- if ($ orderItem ->isDummy ()) {
75
- if (isset ($ data ['qtys ' ][$ orderItem ->getParentItemId ()])) {
76
- $ parentQty = $ data ['qtys ' ][$ orderItem ->getParentItemId ()];
77
- } else {
78
- $ parentQty = $ orderItem ->getParentItem () ? $ orderItem ->getParentItem ()->getQtyToRefund () : 1 ;
79
- }
80
- $ qty = $ this ->calculateProductOptions ($ orderItem , $ parentQty );
81
- $ orderItem ->setLockedDoShip (true );
82
- } else {
83
- if (isset ($ qtys [$ orderItem ->getId ()])) {
84
- $ qty = (double )$ qtys [$ orderItem ->getId ()];
85
- } elseif (!count ($ qtys )) {
86
- $ qty = $ orderItem ->getQtyToRefund ();
87
- } else {
88
- continue ;
89
- }
90
- }
77
+ $ qty = $ this ->getQtyToRefund ($ orderItem , $ qtyList );
91
78
$ totalQty += $ qty ;
92
79
$ item ->setQty ($ qty );
93
80
$ creditmemo ->addItem ($ item );
@@ -106,88 +93,39 @@ public function createByOrder(\Magento\Sales\Model\Order $order, array $data = [
106
93
* @param \Magento\Sales\Model\Order\Invoice $invoice
107
94
* @param array $data
108
95
* @return Creditmemo
109
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
110
- * @SuppressWarnings(PHPMD.NPathComplexity)
111
96
*/
112
97
public function createByInvoice (\Magento \Sales \Model \Order \Invoice $ invoice , array $ data = [])
113
98
{
114
99
$ order = $ invoice ->getOrder ();
115
100
$ totalQty = 0 ;
116
- $ qtys = isset ($ data ['qtys ' ]) ? $ data ['qtys ' ] : [];
101
+ $ qtyList = isset ($ data ['qtys ' ]) ? $ data ['qtys ' ] : [];
117
102
$ creditmemo = $ this ->convertor ->toCreditmemo ($ order );
118
103
$ creditmemo ->setInvoice ($ invoice );
119
104
120
- $ invoiceQtysRefunded = [];
121
- foreach ($ invoice ->getOrder ()->getCreditmemosCollection () as $ createdCreditmemo ) {
122
- if ($ createdCreditmemo ->getState () != Creditmemo::STATE_CANCELED &&
123
- $ createdCreditmemo ->getInvoiceId () == $ invoice ->getId ()
124
- ) {
125
- foreach ($ createdCreditmemo ->getAllItems () as $ createdCreditmemoItem ) {
126
- $ orderItemId = $ createdCreditmemoItem ->getOrderItem ()->getId ();
127
- if (isset ($ invoiceQtysRefunded [$ orderItemId ])) {
128
- $ invoiceQtysRefunded [$ orderItemId ] += $ createdCreditmemoItem ->getQty ();
129
- } else {
130
- $ invoiceQtysRefunded [$ orderItemId ] = $ createdCreditmemoItem ->getQty ();
131
- }
132
- }
133
- }
134
- }
135
-
136
- $ invoiceQtysRefundLimits = [];
137
- foreach ($ invoice ->getAllItems () as $ invoiceItem ) {
138
- $ invoiceQtyCanBeRefunded = $ invoiceItem ->getQty ();
139
- $ orderItemId = $ invoiceItem ->getOrderItem ()->getId ();
140
- if (isset ($ invoiceQtysRefunded [$ orderItemId ])) {
141
- $ invoiceQtyCanBeRefunded = $ invoiceQtyCanBeRefunded - $ invoiceQtysRefunded [$ orderItemId ];
142
- }
143
- $ invoiceQtysRefundLimits [$ orderItemId ] = $ invoiceQtyCanBeRefunded ;
144
- }
105
+ $ invoiceRefundLimitsQtyList = $ this ->getInvoiceRefundLimitsQtyList ($ invoice );
145
106
146
107
foreach ($ invoice ->getAllItems () as $ invoiceItem ) {
108
+ /** @var OrderItemInterface $orderItem */
147
109
$ orderItem = $ invoiceItem ->getOrderItem ();
148
110
149
- if (!$ this ->canRefundItem ($ orderItem , $ qtys , $ invoiceQtysRefundLimits )) {
111
+ if (!$ this ->canRefundItem ($ orderItem , $ qtyList , $ invoiceRefundLimitsQtyList )) {
150
112
continue ;
151
113
}
152
114
153
- $ item = $ this ->convertor ->itemToCreditmemoItem ($ orderItem );
154
- if ($ orderItem ->isDummy ()) {
155
- if (isset ($ data ['qtys ' ][$ orderItem ->getParentItemId ()])) {
156
- $ parentQty = $ data ['qtys ' ][$ orderItem ->getParentItemId ()];
157
- } else {
158
- $ parentQty = $ orderItem ->getParentItem () ? $ orderItem ->getParentItem ()->getQtyToRefund () : 1 ;
159
- }
160
- $ qty = $ this ->calculateProductOptions ($ orderItem , $ parentQty );
161
- } else {
162
- if (isset ($ qtys [$ orderItem ->getId ()])) {
163
- $ qty = (double )$ qtys [$ orderItem ->getId ()];
164
- } elseif (!count ($ qtys )) {
165
- $ qty = $ orderItem ->getQtyToRefund ();
166
- } else {
167
- continue ;
168
- }
169
- if (isset ($ invoiceQtysRefundLimits [$ orderItem ->getId ()])) {
170
- $ qty = min ($ qty , $ invoiceQtysRefundLimits [$ orderItem ->getId ()]);
171
- }
172
- }
173
- $ qty = min ($ qty , $ invoiceItem ->getQty ());
115
+ $ qty = min (
116
+ $ this ->getQtyToRefund ($ orderItem , $ qtyList , $ invoiceRefundLimitsQtyList ),
117
+ $ invoiceItem ->getQty ()
118
+ );
174
119
$ totalQty += $ qty ;
120
+ $ item = $ this ->convertor ->itemToCreditmemoItem ($ orderItem );
175
121
$ item ->setQty ($ qty );
176
122
$ creditmemo ->addItem ($ item );
177
123
}
178
124
$ creditmemo ->setTotalQty ($ totalQty );
179
125
180
126
$ this ->initData ($ creditmemo , $ data );
181
127
if (!isset ($ data ['shipping_amount ' ])) {
182
- $ isShippingInclTax = $ this ->taxConfig ->displaySalesShippingInclTax ($ order ->getStoreId ());
183
- if ($ isShippingInclTax ) {
184
- $ baseAllowedAmount = $ order ->getBaseShippingInclTax () -
185
- $ order ->getBaseShippingRefunded () -
186
- $ order ->getBaseShippingTaxRefunded ();
187
- } else {
188
- $ baseAllowedAmount = $ order ->getBaseShippingAmount () - $ order ->getBaseShippingRefunded ();
189
- $ baseAllowedAmount = min ($ baseAllowedAmount , $ invoice ->getBaseShippingAmount ());
190
- }
128
+ $ baseAllowedAmount = $ this ->getShippingAmount ($ invoice );
191
129
$ creditmemo ->setBaseShippingAmount ($ baseAllowedAmount );
192
130
}
193
131
@@ -272,11 +210,11 @@ protected function initData($creditmemo, $data)
272
210
}
273
211
274
212
/**
275
- * @param \Magento\Sales\Api\Data\OrderItemInterface $orderItem
213
+ * @param Item $orderItem
276
214
* @param int $parentQty
277
215
* @return int
278
216
*/
279
- private function calculateProductOptions (\ Magento \ Sales \ Api \ Data \ OrderItemInterface $ orderItem , $ parentQty )
217
+ private function calculateProductOptions (Item $ orderItem , int $ parentQty ): int
280
218
{
281
219
$ qty = $ parentQty ;
282
220
$ productOptions = $ orderItem ->getProductOptions ();
@@ -290,4 +228,113 @@ private function calculateProductOptions(\Magento\Sales\Api\Data\OrderItemInterf
290
228
}
291
229
return $ qty ;
292
230
}
231
+
232
+ /**
233
+ * Gets list of quantities based on invoice refunded items.
234
+ *
235
+ * @param Invoice $invoice
236
+ * @return array
237
+ */
238
+ private function getInvoiceRefundedQtyList (Invoice $ invoice ): array
239
+ {
240
+ $ invoiceRefundedQtyList = [];
241
+ foreach ($ invoice ->getOrder ()->getCreditmemosCollection () as $ creditmemo ) {
242
+ if ($ creditmemo ->getState () !== Creditmemo::STATE_CANCELED &&
243
+ $ creditmemo ->getInvoiceId () === $ invoice ->getId ()
244
+ ) {
245
+ foreach ($ creditmemo ->getAllItems () as $ creditmemoItem ) {
246
+ $ orderItemId = $ creditmemoItem ->getOrderItem ()->getId ();
247
+ if (isset ($ invoiceRefundedQtyList [$ orderItemId ])) {
248
+ $ invoiceRefundedQtyList [$ orderItemId ] += $ creditmemoItem ->getQty ();
249
+ } else {
250
+ $ invoiceRefundedQtyList [$ orderItemId ] = $ creditmemoItem ->getQty ();
251
+ }
252
+ }
253
+ }
254
+ }
255
+
256
+ return $ invoiceRefundedQtyList ;
257
+ }
258
+
259
+ /**
260
+ * Gets limits of refund based on invoice items.
261
+ *
262
+ * @param Invoice $invoice
263
+ * @return array
264
+ */
265
+ private function getInvoiceRefundLimitsQtyList (Invoice $ invoice ): array
266
+ {
267
+ $ invoiceRefundLimitsQtyList = [];
268
+ $ invoiceRefundedQtyList = $ this ->getInvoiceRefundedQtyList ($ invoice );
269
+
270
+ foreach ($ invoice ->getAllItems () as $ invoiceItem ) {
271
+ $ qtyCanBeRefunded = $ invoiceItem ->getQty ();
272
+ $ orderItemId = $ invoiceItem ->getOrderItem ()->getId ();
273
+ if (isset ($ invoiceRefundedQtyList [$ orderItemId ])) {
274
+ $ qtyCanBeRefunded = $ qtyCanBeRefunded - $ invoiceRefundedQtyList [$ orderItemId ];
275
+ }
276
+ $ invoiceRefundLimitsQtyList [$ orderItemId ] = $ qtyCanBeRefunded ;
277
+ }
278
+
279
+ return $ invoiceRefundLimitsQtyList ;
280
+ }
281
+
282
+ /**
283
+ * Gets quantity of items to refund based on order item.
284
+ *
285
+ * @param Item $orderItem
286
+ * @param array $qtyList
287
+ * @param array $refundLimits
288
+ * @return float
289
+ */
290
+ private function getQtyToRefund (Item $ orderItem , array $ qtyList , array $ refundLimits = []): float
291
+ {
292
+ $ qty = 0 ;
293
+ if ($ orderItem ->isDummy ()) {
294
+ if (isset ($ qtyList [$ orderItem ->getParentItemId ()])) {
295
+ $ parentQty = $ qtyList [$ orderItem ->getParentItemId ()];
296
+ } elseif ($ orderItem ->getProductType () === BundlePrice::PRODUCT_TYPE ) {
297
+ $ parentQty = $ orderItem ->getQtyInvoiced ();
298
+ } else {
299
+ $ parentQty = $ orderItem ->getParentItem () ? $ orderItem ->getParentItem ()->getQtyToRefund () : 1 ;
300
+ }
301
+ $ qty = $ this ->calculateProductOptions ($ orderItem , $ parentQty );
302
+ } else {
303
+ if (isset ($ qtyList [$ orderItem ->getId ()])) {
304
+ $ qty = $ qtyList [$ orderItem ->getId ()];
305
+ } elseif (!count ($ qtyList )) {
306
+ $ qty = $ orderItem ->getQtyToRefund ();
307
+ } else {
308
+ return (float )$ qty ;
309
+ }
310
+
311
+ if (isset ($ refundLimits [$ orderItem ->getId ()])) {
312
+ $ qty = min ($ qty , $ refundLimits [$ orderItem ->getId ()]);
313
+ }
314
+ }
315
+
316
+ return (float )$ qty ;
317
+ }
318
+
319
+ /**
320
+ * Gets shipping amount based on invoice.
321
+ *
322
+ * @param Invoice $invoice
323
+ * @return float
324
+ */
325
+ private function getShippingAmount (Invoice $ invoice ): float
326
+ {
327
+ $ order = $ invoice ->getOrder ();
328
+ $ isShippingInclTax = $ this ->taxConfig ->displaySalesShippingInclTax ($ order ->getStoreId ());
329
+ if ($ isShippingInclTax ) {
330
+ $ amount = $ order ->getBaseShippingInclTax () -
331
+ $ order ->getBaseShippingRefunded () -
332
+ $ order ->getBaseShippingTaxRefunded ();
333
+ } else {
334
+ $ amount = $ order ->getBaseShippingAmount () - $ order ->getBaseShippingRefunded ();
335
+ $ amount = min ($ amount , $ invoice ->getBaseShippingAmount ());
336
+ }
337
+
338
+ return (float )$ amount ;
339
+ }
293
340
}
0 commit comments