@@ -17,6 +17,13 @@ class Shipping extends AbstractTotal
17
17
*/
18
18
protected $ priceCurrency ;
19
19
20
+ /**
21
+ * Tax config
22
+ *
23
+ * @var \Magento\Tax\Model\Config
24
+ */
25
+ private $ taxConfig ;
26
+
20
27
/**
21
28
* @param PriceCurrencyInterface $priceCurrency
22
29
* @param array $data
@@ -37,62 +44,64 @@ public function __construct(
37
44
public function collect (\Magento \Sales \Model \Order \Creditmemo $ creditmemo )
38
45
{
39
46
$ order = $ creditmemo ->getOrder ();
40
- $ allowedAmount = $ order ->getShippingAmount () - $ order ->getShippingRefunded ();
41
- $ baseAllowedAmount = $ order ->getBaseShippingAmount () - $ order ->getBaseShippingRefunded ();
42
47
48
+ // amounts without tax
43
49
$ orderShippingAmount = $ order ->getShippingAmount ();
44
50
$ orderBaseShippingAmount = $ order ->getBaseShippingAmount ();
51
+ $ allowedAmount = $ orderShippingAmount - $ order ->getShippingRefunded ();
52
+ $ baseAllowedAmount = $ orderBaseShippingAmount - $ order ->getBaseShippingRefunded ();
53
+
54
+ // amounts including tax
45
55
$ orderShippingInclTax = $ order ->getShippingInclTax ();
46
56
$ orderBaseShippingInclTax = $ order ->getBaseShippingInclTax ();
57
+ $ allowedTaxAmount = $ order ->getShippingTaxAmount () - $ order ->getShippingTaxRefunded ();
58
+ $ baseAllowedTaxAmount = $ order ->getBaseShippingTaxAmount () - $ order ->getBaseShippingTaxRefunded ();
59
+ $ allowedAmountInclTax = $ allowedAmount + $ allowedTaxAmount ;
60
+ $ baseAllowedAmountInclTax = $ baseAllowedAmount + $ baseAllowedTaxAmount ;
47
61
62
+ // for the credit memo
48
63
$ shippingAmount = $ baseShippingAmount = $ shippingInclTax = $ baseShippingInclTax = 0 ;
49
64
50
- /**
51
- * Check if shipping amount was specified (from invoice or another source).
52
- * Using has magic method to allow setting 0 as shipping amount.
53
- */
65
+ // Check if the desired shipping amount to refund was specified (from invoice or another source).
54
66
if ($ creditmemo ->hasBaseShippingAmount ()) {
55
- $ baseShippingAmount = $ this ->priceCurrency ->round ($ creditmemo ->getBaseShippingAmount ());
56
- /*
57
- * Rounded allowed shipping refund amount is the highest acceptable shipping refund amount.
58
- * Shipping refund amount shouldn't cause errors, if it doesn't exceed that limit.
59
- * Note: ($x < $y + 0.0001) means ($x <= $y) for floats
60
- */
61
- if ($ baseShippingAmount < $ this ->priceCurrency ->round ($ baseAllowedAmount ) + 0.0001 ) {
67
+ // For the conditional logic, we will either use amounts that always include tax -OR- never include tax.
68
+ // The logic uses the 'base' currency to be consistent with what the user (admin) provided as input.
69
+ $ useAmountsWithTax = $ this ->isSuppliedShippingAmountInclTax ($ order );
70
+
71
+ // Since the user (admin) supplied 'desiredAmount' it already has tax -OR- does not include tax
72
+ $ desiredAmount = $ this ->priceCurrency ->round ($ creditmemo ->getBaseShippingAmount ());
73
+ $ maxAllowedAmount = ($ useAmountsWithTax ? $ baseAllowedAmountInclTax : $ baseAllowedAmount );
74
+ $ originalTotalAmount = ($ useAmountsWithTax ? $ orderBaseShippingInclTax : $ orderBaseShippingAmount );
75
+
76
+ // Note: ($x < $y + 0.0001) means ($x <= $y) for floats
77
+ if ($ desiredAmount < $ this ->priceCurrency ->round ($ maxAllowedAmount ) + 0.0001 ) {
78
+ // since the admin is returning less than the allowed amount, compute the ratio being returned
62
79
$ ratio = 0 ;
63
- if ($ orderBaseShippingAmount > 0 ) {
64
- $ ratio = $ baseShippingAmount / $ orderBaseShippingAmount ;
80
+ if ($ originalTotalAmount > 0 ) {
81
+ $ ratio = $ desiredAmount / $ originalTotalAmount ;
65
82
}
66
- /*
67
- * Shipping refund amount should be equated to allowed refund amount,
68
- * if it exceeds that limit.
69
- * Note: ($x > $y - 0.0001) means ($x >= $y) for floats
70
- */
71
- if ($ baseShippingAmount > $ baseAllowedAmount - 0.0001 ) {
83
+ // capture amounts without tax
84
+ // Note: ($x > $y - 0.0001) means ($x >= $y) for floats
85
+ if ($ desiredAmount > $ maxAllowedAmount - 0.0001 ) {
72
86
$ shippingAmount = $ allowedAmount ;
73
87
$ baseShippingAmount = $ baseAllowedAmount ;
74
88
} else {
75
89
$ shippingAmount = $ this ->priceCurrency ->round ($ orderShippingAmount * $ ratio );
90
+ $ baseShippingAmount = $ this ->priceCurrency ->round ($ orderBaseShippingAmount * $ ratio );
76
91
}
77
92
$ shippingInclTax = $ this ->priceCurrency ->round ($ orderShippingInclTax * $ ratio );
78
93
$ baseShippingInclTax = $ this ->priceCurrency ->round ($ orderBaseShippingInclTax * $ ratio );
79
94
} else {
80
- $ baseAllowedAmount = $ order ->getBaseCurrency ()->format ($ baseAllowedAmount , null , false );
95
+ $ maxAllowedAmount = $ order ->getBaseCurrency ()->format ($ maxAllowedAmount , null , false );
81
96
throw new \Magento \Framework \Exception \LocalizedException (
82
- __ ('Maximum shipping amount allowed to refund is: %1 ' , $ baseAllowedAmount )
97
+ __ ('Maximum shipping amount allowed to refund is: %1 ' , $ maxAllowedAmount )
83
98
);
84
99
}
85
100
} else {
86
101
$ shippingAmount = $ allowedAmount ;
87
102
$ baseShippingAmount = $ baseAllowedAmount ;
88
-
89
- $ allowedTaxAmount = $ order ->getShippingTaxAmount () - $ order ->getShippingTaxRefunded ();
90
- $ baseAllowedTaxAmount = $ order ->getBaseShippingTaxAmount () - $ order ->getBaseShippingTaxRefunded ();
91
-
92
- $ shippingInclTax = $ this ->priceCurrency ->round ($ allowedAmount + $ allowedTaxAmount );
93
- $ baseShippingInclTax = $ this ->priceCurrency ->round (
94
- $ baseAllowedAmount + $ baseAllowedTaxAmount
95
- );
103
+ $ shippingInclTax = $ this ->priceCurrency ->round ($ allowedAmountInclTax );
104
+ $ baseShippingInclTax = $ this ->priceCurrency ->round ($ baseAllowedAmountInclTax );
96
105
}
97
106
98
107
$ creditmemo ->setShippingAmount ($ shippingAmount );
@@ -104,4 +113,32 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
104
113
$ creditmemo ->setBaseGrandTotal ($ creditmemo ->getBaseGrandTotal () + $ baseShippingAmount );
105
114
return $ this ;
106
115
}
116
+
117
+ /**
118
+ * Returns whether the user specified a shipping amount that already includes tax
119
+ *
120
+ * @param \Magento\Sales\Model\Order $order
121
+ * @return bool
122
+ */
123
+ private function isSuppliedShippingAmountInclTax ($ order )
124
+ {
125
+ // returns true if we are only displaying shipping including tax, otherwise returns false
126
+ return $ this ->getTaxConfig ()->displaySalesShippingInclTax ($ order ->getStoreId ());
127
+ }
128
+
129
+ /**
130
+ * Get the Tax Config.
131
+ * In a future release, will become a constructor parameter.
132
+ *
133
+ * @return \Magento\Tax\Model\Config
134
+ *
135
+ * @deprecated
136
+ */
137
+ private function getTaxConfig ()
138
+ {
139
+ if ($ this ->taxConfig === null ) {
140
+ $ this ->taxConfig = \Magento \Framework \App \ObjectManager::getInstance ()->get ('Magento\Tax\Model\Config ' );
141
+ }
142
+ return $ this ->taxConfig ;
143
+ }
107
144
}
0 commit comments