16
16
use Magento \Sales \Model \Order \Creditmemo ;
17
17
use Magento \Sales \Model \Order \Item ;
18
18
use Magento \Sales \Model \ValidatorInterface ;
19
+ use Magento \Sales \Api \Data \CreditmemoItemInterface ;
20
+ use Magento \Framework \Phrase ;
19
21
20
22
/**
21
23
* Creditmemo QuantityValidator
@@ -74,23 +76,13 @@ public function validate($entity)
74
76
75
77
$ totalQuantity = 0 ;
76
78
foreach ($ entity ->getItems () as $ item ) {
77
- if (!isset ($ orderItemsById [$ item ->getOrderItemId ()])) {
78
- $ messages [] = __ (
79
- 'The creditmemo contains product SKU "%1" that is not part of the original order. ' ,
80
- $ item ->getSku ()
81
- );
82
- continue ;
83
- }
84
- $ orderItem = $ orderItemsById [$ item ->getOrderItemId ()];
85
-
86
- if (!$ this ->canRefundItem ($ orderItem , $ item ->getQty (), $ invoiceQtysRefundLimits ) ||
87
- !$ this ->isQtyAvailable ($ orderItem , $ item ->getQty ())
88
- ) {
89
- $ messages [] =__ (
90
- 'The quantity to creditmemo must not be greater than the unrefunded quantity '
91
- . ' for product SKU "%1". ' ,
92
- $ orderItem ->getSku ()
93
- );
79
+ $ message = $ this ->validateTotalQuantityRefundable (
80
+ $ orderItemsById ,
81
+ $ item ,
82
+ $ invoiceQtysRefundLimits
83
+ );
84
+ if ($ message ) {
85
+ $ messages [] = $ message ;
94
86
} else {
95
87
$ totalQuantity += $ item ->getQty ();
96
88
}
@@ -105,6 +97,60 @@ public function validate($entity)
105
97
return $ messages ;
106
98
}
107
99
100
+ /**
101
+ * To check the refund qty is decimal if getIsQtyDecimal is unset.
102
+ *
103
+ * @param mixed $isQtyDecimal
104
+ * @param float $itemQty
105
+ * @return bool
106
+ */
107
+ private function isValidDecimalRefundQty ($ isQtyDecimal , float $ itemQty ): bool
108
+ {
109
+ if (!$ isQtyDecimal && (floor ($ itemQty ) !== $ itemQty )) {
110
+ return false ;
111
+ }
112
+ return true ;
113
+ }
114
+
115
+ /**
116
+ * Calculate total quantity.
117
+ *
118
+ * @param array $orderItemsById
119
+ * @param CreditmemoItemInterface $item
120
+ * @param array $invoiceQtysRefundLimits
121
+ * @return Phrase|void
122
+ */
123
+ private function validateTotalQuantityRefundable (
124
+ array $ orderItemsById ,
125
+ CreditmemoItemInterface $ item ,
126
+ array $ invoiceQtysRefundLimits
127
+ ) {
128
+ if (!isset ($ orderItemsById [$ item ->getOrderItemId ()])) {
129
+ return __ (
130
+ 'The creditmemo contains product SKU "%1" that is not part of the original order. ' ,
131
+ $ item ->getSku ()
132
+ );
133
+ }
134
+ $ orderItem = $ orderItemsById [$ item ->getOrderItemId ()];
135
+
136
+ if (!$ this ->isValidDecimalRefundQty ($ orderItem ->getIsQtyDecimal (), $ item ->getQty ())) {
137
+ return __ (
138
+ 'We found an invalid quantity to refund item "%1". ' ,
139
+ $ orderItem ->getSku ()
140
+ );
141
+ }
142
+
143
+ if (!$ this ->canRefundItem ($ orderItem , $ item ->getQty (), $ invoiceQtysRefundLimits ) ||
144
+ !$ this ->isQtyAvailable ($ orderItem , $ item ->getQty ())
145
+ ) {
146
+ return __ (
147
+ 'The quantity to creditmemo must not be greater than the unrefunded quantity '
148
+ . ' for product SKU "%1". ' ,
149
+ $ orderItem ->getSku ()
150
+ );
151
+ }
152
+ }
153
+
108
154
/**
109
155
* We can have problem with float in php (on some server $a=762.73;$b=762.73; $a-$b!=0)
110
156
* for this we have additional diapason for 0
0 commit comments