Skip to content

Commit

Permalink
fix(SW-27165): Change consideration of graduated prices in order module
Browse files Browse the repository at this point in the history
While adding new positions to an existing order in the backend order module, graduated prices are still considered.
If an existing position is changed, the graduated price will only be checked and considered if the quantity was changed.
With this change it is possible again to also set a custom price for a position that contains a product with graduated prices.
  • Loading branch information
mitelg committed Sep 21, 2023
1 parent a819a2f commit c491cd4
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 13 deletions.
31 changes: 18 additions & 13 deletions engine/Shopware/Controllers/Backend/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class Shopware_Controllers_Backend_Order extends Shopware_Controllers_Backend_Ex

/**
* @deprecated - Will be removed in Shopware 5.8 without a replacement
* Contains the dynamic receipt repository
* Contains the order document repository
*
* @var OrderDocumentRepository
*/
Expand Down Expand Up @@ -1950,7 +1950,17 @@ private function getPositionAssociatedData(array $data, Order $order): array

$shopContext = $this->createShopContext($order);
$data = $this->checkTaxRule($data, $shopContext);
if ($this->hasProductGraduatedPrices($data['articleNumber'], $order)) {
$orderPosition = null;
foreach ($order->getDetails() as $position) {
if ($position->getId() === (int) $data['id']) {
$orderPosition = $position;
break;
}
}
// Only get graduated price if a new position should be added or quantity has changed
if (($orderPosition === null || $orderPosition->getQuantity() !== (int) $data['quantity'])
&& $this->hasProductGraduatedPrices($data['articleNumber'], $order)
) {
$data = $this->checkPrice($data, $order, $shopContext);
}

Expand Down Expand Up @@ -2106,20 +2116,15 @@ private function checkTaxRule(array $data, ShopContextInterface $shopContext): a
return $data;
}

private function hasProductGraduatedPrices(string $productNumber, ORDER $order): bool
private function hasProductGraduatedPrices(string $productNumber, Order $order): bool
{
$customerGroupKey = $this->getCustomerGroupKey($order);

$sql = 'SELECT
prices.pricegroup, count(*)
FROM
s_articles_prices AS prices
INNER JOIN
s_articles_details ON prices.articledetailsID = s_articles_details.id
WHERE
s_articles_details.ordernumber = :productNumber
GROUP BY
prices.pricegroup;';
$sql = 'SELECT prices.pricegroup, count(*)
FROM s_articles_prices AS prices
INNER JOIN s_articles_details ON prices.articledetailsID = s_articles_details.id
WHERE s_articles_details.ordernumber = :productNumber
GROUP BY prices.pricegroup;';

$result = $this->container->get(Connection::class)->executeQuery($sql, ['productNumber' => $productNumber])->fetchAllKeyValue();

Expand Down
98 changes: 98 additions & 0 deletions tests/Functional/Controllers/Backend/OrderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,104 @@ public function provideProductParamsForSavePositionActionTestingGraduatedPrices(
];
}

/**
* @dataProvider provideProductParamsForSavePositionActionOnExistingPosition
*
* @param array{quantity?: int, price?: float, total?: float} $params
* @param array{price: float, total: float} $expectedValues
*/
public function testSavePositionActionReturnValuesForGraduatedPricesOnExistingPosition(array $params, array $expectedValues): void
{
$order = $this->modelManager->getRepository(Order::class)->findOneBy([]);
static::assertInstanceOf(Order::class, $order);
$newPositionParams = [
'id' => 0,
'orderId' => $order->getId(),
'articleNumber' => self::PRODUCT_GRADUATED_PRICES_DEMODATA_ORDER_NUMBER,
'articleName' => self::PRODUCT_GRADUATED_PRICES_DEMODATA_NAME,
'articleId' => self::PRODUCT_GRADUATED_PRICES_DEMODATA_PRODUCT_ID,
'articleDetailId' => self::PRODUCT_GRADUATED_PRICES_DEMODATA_PRODUCT_VARIANT_ID,
'mode' => 0,
'quantity' => 2,
'statusId' => 0,
'statusDescription' => '',
'taxId' => 1,
'taxRate' => 19.0,
'taxDescription' => '',
'inStock' => 0,
'changed' => $order->getChanged() ? $order->getChanged()->format(DateTimeInterface::ATOM) : '',
];

$request = new Enlight_Controller_Request_RequestTestCase();
$request->setParams($newPositionParams);

$controller = $this->getController();
$controller->setRequest($request);
$controller->savePositionAction();
$results = $controller->View()->getAssign();

static::assertTrue($results['success'], $results['message'] ?? '');
static::assertSame(0.84, $results['data']['price']);
static::assertSame(1.68, $results['data']['total']);

$this->modelManager->refresh($order);
$changeQuantityParams = [
'id' => $results['data']['id'],
'price' => $results['data']['price'],
'total' => $results['data']['total'],
'changed' => $order->getChanged() ? $order->getChanged()->format(DateTimeInterface::ATOM) : '',
];
$changeQuantityParams = array_merge($newPositionParams, $changeQuantityParams, $params);

$request = new Enlight_Controller_Request_RequestTestCase();
$request->setParams($changeQuantityParams);

$controller->setRequest($request);
$controller->savePositionAction();
$results = $controller->View()->getAssign();

static::assertTrue($results['success'], $results['message'] ?? '');
static::assertSame($expectedValues['price'], $results['data']['price']);
static::assertSame($expectedValues['total'], $results['data']['total']);
}

/**
* @return Generator<array{params: array{quantity?: int, price?: float, total?: float}, expectedValues: array{price: float, total: float}}>
*/
public function provideProductParamsForSavePositionActionOnExistingPosition(): Generator
{
yield 'Only change quantity, graduated price should be considered' => [
'params' => [
'quantity' => 20,
],
'expectedValues' => [
'price' => 0.76,
'total' => 15.2,
],
];
yield 'Only change price, graduated price should be ignored' => [
'params' => [
'price' => 0.15,
'total' => 0.30,
],
'expectedValues' => [
'price' => 0.15,
'total' => 0.30,
],
];
yield 'Change quantity and price, graduated price should be considered' => [
'params' => [
'quantity' => 30,
'price' => 0.15,
'total' => 0.30,
],
'expectedValues' => [
'price' => 0.67,
'total' => 20.1,
],
];
}

/**
* @dataProvider provideTaxRuleParams
*/
Expand Down

0 comments on commit c491cd4

Please sign in to comment.