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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<?php
/**
* @copyright Vertex. All rights reserved. https://www.vertexinc.com/
* @author Mediotype https://www.mediotype.com/
*/
namespace Vertex\Tax\Observer;
use Magento\Sales\Api\Data\InvoiceExtensionFactory;
use Magento\Sales\Api\OrderAddressRepositoryInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Invoice;
/**
* Handles loading and assignment of necessary data for Tax Calculation purposes
*/
class VertexCalculationExtensionLoader
{
/** @var OrderAddressRepositoryInterface */
private $addressRepository;
/** @var InvoiceExtensionFactory */
private $invoiceExtensionFactory;
/** @var OrderRepositoryInterface */
private $orderRepository;
/**
* @param InvoiceExtensionFactory $invoiceExtensionFactory
* @param OrderAddressRepositoryInterface $addressRepository
* @param OrderRepositoryInterface $orderRepository
*/
public function __construct(
InvoiceExtensionFactory $invoiceExtensionFactory,
OrderAddressRepositoryInterface $addressRepository,
OrderRepositoryInterface $orderRepository
) {
$this->invoiceExtensionFactory = $invoiceExtensionFactory;
$this->addressRepository = $addressRepository;
$this->orderRepository = $orderRepository;
}
/**
* Load the addresses and Order for an Invoice onto the Vertex Tax Calculation extension attributes
*
* This is necessary as there are two different ways an Invoice comes across the wire with respect to the addresses
* attached to it:
*
* The first way is when it is an existing Order that is invoiced. In this scenario, the Billing Address ID and the
* Shipping Address ID are set on the Invoice.
*
* The second way is when it is a newly placed Order on the frontend, with an online payment method that captures
* payment and triggers an invoice. In this scenario, the Order's addresses are not yet in the database and are not
* yet tied to the Invoice.
*
* Additionally, during the second scenario we do not want to load up the Order through the repository, as it can
* cause additional issues. In this scenario, we want to use the Order that is already attached to the Invoice.
*
* @param Invoice $originalInvoice
* @return Invoice
*/
public function loadOnInvoice(Invoice $originalInvoice)
{
$invoice = clone $originalInvoice;
if (!$invoice->getExtensionAttributes()) {
$invoice->setExtensionAttributes($this->invoiceExtensionFactory->create());
} else {
$invoice->setExtensionAttributes(clone $originalInvoice->getExtensionAttributes());
}
try {
$order = $invoice->getOrder() ?: $this->orderRepository->get($invoice->getOrderId());
} catch (\Exception $e) {
$order = null;
}
$invoice->getExtensionAttributes()
->setVertexTaxCalculationOrder($order);
if ($order && $order->getBillingAddress()) {
$invoice->getExtensionAttributes()
->setVertexTaxCalculationBillingAddress($order->getBillingAddress());
} elseif ($invoice->getBillingAddressId()) {
$invoice->getExtensionAttributes()
->setVertexTaxCalculationBillingAddress(
$this->addressRepository->get($invoice->getBillingAddressId())
);
}
if ($order instanceof Order && $order->getShippingAddress()) {
$invoice->getExtensionAttributes()
->setVertexTaxCalculationShippingAddress($order->getShippingAddress());
} elseif ($invoice->getShippingAddressId()) {
$invoice->getExtensionAttributes()
->setVertexTaxCalculationShippingAddress(
$this->addressRepository->get($invoice->getShippingAddressId())
);
}
return $invoice;
}
}