Skip to content

Commit 878b1c9

Browse files
authored
Merge pull request #5874 from magento-honey-badgers/MC-20637
[honey] MC-20637: MyAccount :: Order Details :: Invoice Details by Order Number
2 parents fa6d291 + b89181b commit 878b1c9

File tree

6 files changed

+904
-198
lines changed

6 files changed

+904
-198
lines changed

app/code/Magento/SalesGraphQl/Model/Resolver/InvoiceItems.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,34 @@ private function getInvoiceItemData(OrderInterface $order, InvoiceItemInterface
122122
],
123123
'quantity_invoiced' => $invoiceItem->getQty(),
124124
'model' => $invoiceItem,
125-
'product_type' => $orderItem['product_type']
125+
'product_type' => $orderItem['product_type'],
126+
'order_item' => $orderItem,
127+
'discounts' => $this->getDiscountDetails($order, $invoiceItem)
126128
];
127129
}
130+
131+
/**
132+
* Returns information about an applied discount
133+
*
134+
* @param OrderInterface $associatedOrder
135+
* @param InvoiceItemInterface $invoiceItem
136+
* @return array
137+
*/
138+
private function getDiscountDetails(OrderInterface $associatedOrder, InvoiceItemInterface $invoiceItem) : array
139+
{
140+
if ($associatedOrder->getDiscountDescription() === null && $invoiceItem->getDiscountAmount() == 0
141+
&& $associatedOrder->getDiscountAmount() == 0
142+
) {
143+
$discounts = [];
144+
} else {
145+
$discounts [] = [
146+
'label' => $associatedOrder->getDiscountDescription() ?? _('Discount'),
147+
'amount' => [
148+
'value' => abs($invoiceItem->getDiscountAmount()) ?? 0,
149+
'currency' => $associatedOrder->getOrderCurrencyCode()
150+
]
151+
];
152+
}
153+
return $discounts;
154+
}
128155
}

app/code/Magento/SalesGraphQl/Model/Resolver/InvoiceTotal.php

Lines changed: 114 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,45 @@
1313
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1414
use Magento\Sales\Api\Data\InvoiceInterface;
1515
use Magento\Sales\Api\Data\OrderInterface;
16+
use Magento\Tax\Api\OrderTaxManagementInterface;
17+
use Magento\SalesGraphQl\Model\SalesItem\ShippingTaxCalculator;
18+
use Magento\Tax\Helper\Data as TaxHelper;
1619

1720
/**
1821
* Resolver for Invoice total
1922
*/
2023
class InvoiceTotal implements ResolverInterface
2124
{
25+
/**
26+
* @var TaxHelper
27+
*/
28+
private $taxHelper;
29+
30+
/**
31+
* @var OrderTaxManagementInterface
32+
*/
33+
private $orderTaxManagement;
34+
35+
/**
36+
* @var ShippingTaxCalculator
37+
*/
38+
private $shippingTaxCalculator;
39+
40+
/**
41+
* @param OrderTaxManagementInterface $orderTaxManagement
42+
* @param TaxHelper $taxHelper
43+
* @param ShippingTaxCalculator $shippingTaxCalculator
44+
*/
45+
public function __construct(
46+
OrderTaxManagementInterface $orderTaxManagement,
47+
TaxHelper $taxHelper,
48+
ShippingTaxCalculator $shippingTaxCalculator
49+
) {
50+
$this->taxHelper = $taxHelper;
51+
$this->orderTaxManagement = $orderTaxManagement;
52+
$this->shippingTaxCalculator = $shippingTaxCalculator;
53+
}
54+
2255
/**
2356
* @inheritDoc
2457
*/
@@ -48,20 +81,98 @@ public function resolve(
4881
'subtotal' => ['value' => $invoiceModel->getSubtotal(), 'currency' => $currency],
4982
'total_tax' => ['value' => $invoiceModel->getTaxAmount(), 'currency' => $currency],
5083
'total_shipping' => ['value' => $invoiceModel->getShippingAmount(), 'currency' => $currency],
84+
'discounts' => $this->getDiscountDetails($invoiceModel),
85+
'taxes' => $this->formatTaxes(
86+
$orderModel,
87+
$this->taxHelper->getCalculatedTaxes($invoiceModel),
88+
),
5189
'shipping_handling' => [
5290
'amount_excluding_tax' => [
53-
'value' => $invoiceModel->getShippingAmount(),
91+
'value' => $invoiceModel->getShippingAmount() ?? 0,
5492
'currency' => $currency
5593
],
5694
'amount_including_tax' => [
57-
'value' => $invoiceModel->getShippingInclTax(),
95+
'value' => $invoiceModel->getShippingInclTax() ?? 0,
5896
'currency' => $currency
5997
],
6098
'total_amount' => [
61-
'value' => $invoiceModel->getShippingAmount(),
99+
'value' => $invoiceModel->getShippingAmount() ?? 0,
62100
'currency' => $currency
63101
],
102+
'discounts' => $this->getShippingDiscountDetails($invoiceModel),
103+
'taxes' => $this->formatTaxes(
104+
$orderModel,
105+
$this->shippingTaxCalculator->calculateShippingTaxes($orderModel, $invoiceModel),
106+
)
64107
]
65108
];
66109
}
110+
111+
/**
112+
* Return information about an applied discount on shipping
113+
*
114+
* @param InvoiceInterface $invoice
115+
* @return array
116+
*/
117+
private function getShippingDiscountDetails(InvoiceInterface $invoice)
118+
{
119+
$shippingDiscounts = [];
120+
if (!($invoice->getDiscountDescription() === null
121+
&& $invoice->getShippingDiscountTaxCompensationAmount() == 0)) {
122+
$shippingDiscounts[] =
123+
[
124+
'label' => $invoice->getDiscountDescription() ?? __('Discount'),
125+
'amount' => [
126+
'value' => abs($invoice->getShippingDiscountTaxCompensationAmount()),
127+
'currency' => $invoice->getOrderCurrencyCode()
128+
]
129+
];
130+
}
131+
return $shippingDiscounts;
132+
}
133+
134+
/**
135+
* Return information about an applied discount
136+
*
137+
* @param InvoiceInterface $invoice
138+
* @return array
139+
*/
140+
private function getDiscountDetails(InvoiceInterface $invoice)
141+
{
142+
$discounts = [];
143+
if (!($invoice->getDiscountDescription() === null && $invoice->getDiscountAmount() == 0)) {
144+
$discounts[] = [
145+
'label' => $invoice->getDiscountDescription() ?? __('Discount'),
146+
'amount' => [
147+
'value' => abs($invoice->getDiscountAmount()),
148+
'currency' => $invoice->getOrderCurrencyCode()
149+
]
150+
];
151+
}
152+
return $discounts;
153+
}
154+
155+
/**
156+
* Format applied taxes
157+
*
158+
* @param OrderInterface $order
159+
* @param array $appliedTaxes
160+
* @return array
161+
*/
162+
private function formatTaxes(OrderInterface $order, array $appliedTaxes)
163+
{
164+
$taxes = [];
165+
foreach ($appliedTaxes as $appliedTax) {
166+
$appliedTaxesArray = [
167+
'rate' => $appliedTax['percent'] ?? 0,
168+
'title' => $appliedTax['title'] ?? null,
169+
'amount' => [
170+
'value' => $appliedTax['tax_amount'] ?? 0,
171+
'currency' => $order->getOrderCurrencyCode()
172+
]
173+
];
174+
$taxes[] = $appliedTaxesArray;
175+
}
176+
return $taxes;
177+
}
67178
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\SalesGraphQl\Model\SalesItem;
9+
10+
use Magento\Sales\Api\Data\OrderInterface;
11+
use Magento\Sales\Model\EntityInterface;
12+
use Magento\Tax\Api\Data\OrderTaxDetailsItemInterface;
13+
use Magento\Tax\Api\OrderTaxManagementInterface;
14+
use Magento\Quote\Model\Quote\Address;
15+
use Magento\Framework\Exception\NoSuchEntityException;
16+
17+
/**
18+
* Calculates shipping taxes for sales items (Invoices, Credit memo)
19+
*/
20+
class ShippingTaxCalculator
21+
{
22+
/**
23+
* @var OrderTaxManagementInterface
24+
*/
25+
private $orderTaxManagement;
26+
27+
/**
28+
* @param OrderTaxManagementInterface $orderTaxManagement
29+
*/
30+
public function __construct(
31+
OrderTaxManagementInterface $orderTaxManagement
32+
) {
33+
$this->orderTaxManagement = $orderTaxManagement;
34+
}
35+
36+
/**
37+
* Calculate shipping taxes for sales item
38+
*
39+
* @param OrderInterface $order
40+
* @param EntityInterface $salesItem
41+
* @return array
42+
* @throws NoSuchEntityException
43+
*/
44+
public function calculateShippingTaxes(
45+
OrderInterface $order,
46+
EntityInterface $salesItem
47+
): array {
48+
$orderTaxDetails = $this->orderTaxManagement->getOrderTaxDetails($order->getId());
49+
$taxClassBreakdown = [];
50+
// Apply any taxes for shipping
51+
$shippingTaxAmount = $salesItem->getShippingTaxAmount();
52+
$originalShippingTaxAmount = $order->getShippingTaxAmount();
53+
if ($shippingTaxAmount && $originalShippingTaxAmount &&
54+
$shippingTaxAmount != 0 && (float)$originalShippingTaxAmount
55+
) {
56+
//An invoice or credit memo can have a different qty than its order
57+
$shippingRatio = $shippingTaxAmount / $originalShippingTaxAmount;
58+
$itemTaxDetails = $orderTaxDetails->getItems();
59+
foreach ($itemTaxDetails as $itemTaxDetail) {
60+
//Aggregate taxable items associated with shipping
61+
if ($itemTaxDetail->getType() == Address::TYPE_SHIPPING) {
62+
$taxClassBreakdown = $this->aggregateTaxes($taxClassBreakdown, $itemTaxDetail, $shippingRatio);
63+
}
64+
}
65+
}
66+
return $taxClassBreakdown;
67+
}
68+
69+
/**
70+
* Accumulates the pre-calculated taxes for each tax class
71+
*
72+
* This method accepts and returns the '$taxClassBreakdown' array with format:
73+
* array(
74+
* $index => array(
75+
* 'tax_amount' => $taxAmount,
76+
* 'base_tax_amount' => $baseTaxAmount,
77+
* 'title' => $title,
78+
* 'percent' => $percent
79+
* )
80+
* )
81+
*
82+
* @param array $taxClassBreakdown
83+
* @param OrderTaxDetailsItemInterface $itemTaxDetail
84+
* @param float $taxRatio
85+
* @return array
86+
*/
87+
private function aggregateTaxes(
88+
array $taxClassBreakdown,
89+
OrderTaxDetailsItemInterface $itemTaxDetail,
90+
float $taxRatio
91+
): array {
92+
$itemAppliedTaxes = $itemTaxDetail->getAppliedTaxes();
93+
foreach ($itemAppliedTaxes as $itemAppliedTax) {
94+
$taxAmount = $itemAppliedTax->getAmount() * $taxRatio;
95+
$baseTaxAmount = $itemAppliedTax->getBaseAmount() * $taxRatio;
96+
if (0 == $taxAmount && 0 == $baseTaxAmount) {
97+
continue;
98+
}
99+
$taxCode = $itemAppliedTax->getCode();
100+
if (!isset($taxClassBreakdown[$taxCode])) {
101+
$taxClassBreakdown[$taxCode]['title'] = $itemAppliedTax->getTitle();
102+
$taxClassBreakdown[$taxCode]['percent'] = $itemAppliedTax->getPercent();
103+
$taxClassBreakdown[$taxCode]['tax_amount'] = $taxAmount;
104+
$taxClassBreakdown[$taxCode]['base_tax_amount'] = $baseTaxAmount;
105+
} else {
106+
$taxClassBreakdown[$taxCode]['tax_amount'] += $taxAmount;
107+
$taxClassBreakdown[$taxCode]['base_tax_amount'] += $baseTaxAmount;
108+
}
109+
}
110+
return $taxClassBreakdown;
111+
}
112+
}

app/code/Magento/SalesGraphQl/composer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
"magento/module-sales": "*",
99
"magento/module-store": "*",
1010
"magento/module-catalog": "*",
11+
"magento/module-tax": "*",
12+
"magento/module-quote": "*",
1113
"magento/module-graph-ql": "*"
1214
},
1315
"suggest": {

0 commit comments

Comments
 (0)