1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?php
/**
* @copyright Vertex. All rights reserved. https://www.vertexinc.com/
* @author Mediotype https://www.mediotype.com/
*/
namespace Vertex\Tax\Model\Api\Data\InvoiceRequestBuilder;
use Magento\Sales\Api\Data\CreditmemoInterface;
use Magento\Sales\Api\Data\CreditmemoItemInterface;
use Vertex\Data\LineItemInterface;
use Vertex\Services\Invoice\RequestInterface;
/**
* Processes Shipping on a Creditmemo and adds it to a Vertex Invoice's LineItems
*/
class CreditmemoShippingProcessor implements CreditmemoProcessorInterface
{
/** @var ShippingProcessor */
private $shippingProcessor;
/**
* @param ShippingProcessor $shippingProcessor
*/
public function __construct(ShippingProcessor $shippingProcessor)
{
$this->shippingProcessor = $shippingProcessor;
}
/**
* @inheritdoc
*/
public function process(RequestInterface $request, CreditmemoInterface $creditmemo)
{
if (!$creditmemo->getBaseShippingAmount()) {
return $request;
}
/** @var LineItemInterface[] $lineItems */
$lineItems = array_map(
function (LineItemInterface $lineItem) {
// Since we are creating an Invoice record, make these negative
$lineItem->setUnitPrice(-1 * $lineItem->getUnitPrice());
$lineItem->setExtendedPrice(-1 * $lineItem->getExtendedPrice());
return $lineItem;
},
$this->shippingProcessor->getShippingLineItems(
$creditmemo->getOrderId(),
$creditmemo->getBaseShippingAmount() - $this->getBaseShippingDiscountAmount($creditmemo)
)
);
$request->setLineItems(array_merge($request->getLineItems(), $lineItems));
return $request;
}
/**
* Retrieve total discount less line item discounts
*
* At the time of this writing, Magento only applies discounts to line items
* and to the shipping. Unfortunately for invoices and creditmemos it does
* not record the amount of shipping being discounted at the time of invoice
* or credit. As such, to attempt to figure out what that is, we have to
* remove the line item discounts from the total discount.
*
* This code will break if Magento ever allows discounts to apply to other
* items like Giftwrapping and Printed Cards
*
* @param CreditmemoInterface $creditmemo
* @return float
*/
private function getBaseShippingDiscountAmount(CreditmemoInterface $creditmemo)
{
$totalDiscount = $creditmemo->getBaseDiscountAmount() * -1; // discount is stored as a negative here
$lineItemDiscount = array_reduce(
$creditmemo->getItems(),
function ($result, CreditmemoItemInterface $item) {
return $result + (float)$item->getDiscountAmount();
},
0
);
return $totalDiscount - $lineItemDiscount;
}
}