Skip to content

Commit b947b62

Browse files
ENGCOM-8705: Bundle product: incorrect child item invoice_qty when dynamic price is set to false #31750
- Merge Pull Request #31750 from engcom-Hotel/magento2:Bundle_product_incorrect_child_item_invoice_qty_when_dynamic_price_is_set_to_false_#30802 - Merged commits: 1. c9d0dc5 2. 1542608 3. f41c34a 4. 06e5543
2 parents f6e06ec + 06e5543 commit b947b62

File tree

4 files changed

+144
-10
lines changed

4 files changed

+144
-10
lines changed

app/code/Magento/Sales/Model/Service/InvoiceService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ private function prepareItemsQty(
194194
): array {
195195
foreach ($order->getAllItems() as $orderItem) {
196196
if (isset($orderItemsQtyToInvoice[$orderItem->getId()])) {
197-
if ($orderItem->isDummy() && $orderItem->getHasChildren()) {
197+
if ($orderItem->getHasChildren()) {
198198
$orderItemsQtyToInvoice = $this->setChildItemsQtyToInvoice($orderItem, $orderItemsQtyToInvoice);
199199
}
200200
} else {

dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Invoice/SaveTest.php

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -218,19 +218,21 @@ public function testPartialInvoiceWitConfigurableProduct(): void
218218
}
219219

220220
/**
221-
* Get order items qty invoiced
221+
* @magentoDataFixture Magento/Sales/_files/order_with_bundle_dynamic_price_no.php
222222
*
223-
* @param int $orderId
224-
* @return array
223+
* @return void
225224
*/
226-
private function getOrderItemsQtyInvoiced(int $orderId): array
225+
public function testOrderItemsQtyInvoicedForBundleDynamicPriceFalse(): void
227226
{
228-
$connection = $this->orderItemResource->getConnection();
229-
$select = $connection->select()
230-
->from($this->orderItemResource->getMainTable(), OrderItemInterface::QTY_INVOICED)
231-
->where(OrderItemInterface::ORDER_ID . ' = ?', $orderId);
227+
$order = $this->getOrder('100000001');
228+
$entityId = $order->getEntityId();
232229

233-
return $connection->fetchCol($select);
230+
$this->prepareRequest([], ['order_id' => $entityId]);
231+
$this->dispatch('backend/sales/order_invoice/save');
232+
233+
$ordered = $this->getOrderItemsQtyOrdered((int)$entityId);
234+
$invoiced = $this->getOrderItemsQtyInvoiced((int)$entityId);
235+
$this->assertEquals($ordered, $invoiced);
234236
}
235237

236238
/**
@@ -314,4 +316,36 @@ private function checkSuccess(
314316
);
315317
$this->assertSessionMessages($this->containsEqual((string)__($message)));
316318
}
319+
320+
/**
321+
* Get order items qty invoiced
322+
*
323+
* @param int $orderId
324+
* @return array
325+
*/
326+
private function getOrderItemsQtyInvoiced(int $orderId): array
327+
{
328+
$connection = $this->orderItemResource->getConnection();
329+
$select = $connection->select()
330+
->from($this->orderItemResource->getMainTable(), OrderItemInterface::QTY_INVOICED)
331+
->where(OrderItemInterface::ORDER_ID . ' = ?', $orderId);
332+
333+
return $connection->fetchCol($select);
334+
}
335+
336+
/**
337+
* Get order items qty ordered
338+
*
339+
* @param int $orderId
340+
* @return array
341+
*/
342+
private function getOrderItemsQtyOrdered(int $orderId): array
343+
{
344+
$connection = $this->orderItemResource->getConnection();
345+
$select = $connection->select()
346+
->from($this->orderItemResource->getMainTable(), OrderItemInterface::QTY_ORDERED)
347+
->where(OrderItemInterface::ORDER_ID . ' = ?', $orderId);
348+
349+
return $connection->fetchCol($select);
350+
}
317351
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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+
use Magento\Sales\Api\Data\OrderInterfaceFactory;
9+
use Magento\Sales\Api\Data\OrderItemInterface;
10+
use Magento\Sales\Api\OrderRepositoryInterface;
11+
use Magento\Sales\Model\Order;
12+
use Magento\Sales\Model\Order\Item;
13+
use Magento\TestFramework\ObjectManager;
14+
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;
15+
16+
Resolver::getInstance()->requireDataFixture('Magento/Sales/_files/order.php');
17+
18+
$objectManager = ObjectManager::getInstance();
19+
/** @var Order $order */
20+
$order = $objectManager->get(OrderInterfaceFactory::class)->create()->loadByIncrementId('100000001');
21+
22+
$orderItems = [
23+
[
24+
OrderItemInterface::SKU => 'bundle_1',
25+
OrderItemInterface::NAME => 'bundle_1',
26+
OrderItemInterface::PRODUCT_ID => 2,
27+
OrderItemInterface::BASE_PRICE => 100,
28+
OrderItemInterface::ORDER_ID => $order->getId(),
29+
OrderItemInterface::QTY_ORDERED => 2,
30+
OrderItemInterface::PRICE => 100,
31+
OrderItemInterface::ROW_TOTAL => 102,
32+
OrderItemInterface::PRODUCT_TYPE => 'bundle',
33+
'product_options' => [
34+
'product_calculations' => 1,
35+
'info_buyRequest' => [
36+
'bundle_option' => [1 => 1],
37+
'bundle_option_qty' => 1,
38+
]
39+
],
40+
'children' => [
41+
[
42+
OrderItemInterface::SKU => 'bundle_simple_1',
43+
OrderItemInterface::NAME => 'bundle_simple_1',
44+
OrderItemInterface::PRODUCT_ID => 13,
45+
OrderItemInterface::ORDER_ID => $order->getId(),
46+
OrderItemInterface::QTY_ORDERED => 10,
47+
OrderItemInterface::BASE_PRICE => 90,
48+
OrderItemInterface::PRICE => 90,
49+
OrderItemInterface::ROW_TOTAL => 92,
50+
OrderItemInterface::PRODUCT_TYPE => 'simple',
51+
'product_options' => [
52+
'bundle_selection_attributes' => '{"qty":5}',
53+
],
54+
],
55+
],
56+
],
57+
];
58+
59+
if (!function_exists('saveOrderItems')) {
60+
/**
61+
* Save Order Items.
62+
*
63+
* @param array $orderItems
64+
* @param Item|null $parentOrderItem [optional]
65+
* @return void
66+
*/
67+
function saveOrderItems(array $orderItems, Order $order, $parentOrderItem = null)
68+
{
69+
$objectManager = ObjectManager::getInstance();
70+
71+
foreach ($orderItems as $orderItemData) {
72+
/** @var Item $orderItem */
73+
$orderItem = $objectManager->create(Item::class);
74+
if (null !== $parentOrderItem) {
75+
$orderItemData['parent_item'] = $parentOrderItem;
76+
}
77+
$orderItem->setData($orderItemData);
78+
$order->addItem($orderItem);
79+
80+
if (isset($orderItemData['children'])) {
81+
saveOrderItems($orderItemData['children'], $order, $orderItem);
82+
}
83+
}
84+
}
85+
}
86+
87+
saveOrderItems($orderItems, $order);
88+
/** @var OrderRepositoryInterface $orderRepository */
89+
$orderRepository = $objectManager->get(OrderRepositoryInterface::class);
90+
$order = $orderRepository->save($order);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
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+
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;
9+
10+
Resolver::getInstance()->requireDataFixture('Magento/Sales/_files/order_rollback.php');

0 commit comments

Comments
 (0)