Fix limited backoffice price save reset
This commit is contained in:
@@ -474,26 +474,26 @@ class limited_backoffice_service
|
||||
$mysqli->begin_transaction();
|
||||
|
||||
try {
|
||||
$priceUpdateAssignments = ['`price` = VALUES(`price`)'];
|
||||
if ($this->tableHasColumn('product_department_prices', 'updated_at')) {
|
||||
$priceUpdateAssignments[] = '`updated_at` = CURRENT_TIMESTAMP';
|
||||
}
|
||||
|
||||
$statement = $mysqli->prepare(
|
||||
'INSERT INTO `product_department_prices` (`department_id`, `product_id`, `price`)
|
||||
VALUES (?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE ' . implode(', ', $priceUpdateAssignments)
|
||||
$deleteStatement = $mysqli->prepare(
|
||||
'DELETE FROM `product_department_prices` WHERE `department_id` = ? AND `product_id` = ?'
|
||||
);
|
||||
if ($statement === false) {
|
||||
$insertStatement = $mysqli->prepare(
|
||||
'INSERT INTO `product_department_prices` (`department_id`, `product_id`, `price`) VALUES (?, ?, ?)'
|
||||
);
|
||||
if ($deleteStatement === false || $insertStatement === false) {
|
||||
throw new \RuntimeException('Unable to prepare department price update.');
|
||||
}
|
||||
|
||||
foreach ($normalizedPrices as $productId => $price) {
|
||||
$statement->bind_param('iii', $departmentId, $productId, $price);
|
||||
$statement->execute();
|
||||
$deleteStatement->bind_param('ii', $departmentId, $productId);
|
||||
$deleteStatement->execute();
|
||||
|
||||
$insertStatement->bind_param('iii', $departmentId, $productId, $price);
|
||||
$insertStatement->execute();
|
||||
}
|
||||
|
||||
$statement->close();
|
||||
$deleteStatement->close();
|
||||
$insertStatement->close();
|
||||
$mysqli->commit();
|
||||
} catch (\Throwable $throwable) {
|
||||
$mysqli->rollback();
|
||||
@@ -868,8 +868,14 @@ class limited_backoffice_service
|
||||
INNER JOIN `categories` c ON c.`id` = dc.`category_id`
|
||||
INNER JOIN `products` p ON p.`category` = dc.`category_id`
|
||||
LEFT JOIN `product_department_prices` pdp
|
||||
ON pdp.`department_id` = dc.`department_id`
|
||||
AND pdp.`product_id` = p.`id`
|
||||
ON pdp.`id` = (
|
||||
SELECT pdp_latest.`id`
|
||||
FROM `product_department_prices` pdp_latest
|
||||
WHERE pdp_latest.`department_id` = dc.`department_id`
|
||||
AND pdp_latest.`product_id` = p.`id`
|
||||
ORDER BY pdp_latest.`id` DESC
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE ' . implode(' AND ', $where) . '
|
||||
ORDER BY c.`name` ASC, c.`id` ASC, p.`order_priority` ASC, p.`name` ASC, p.`id` ASC'
|
||||
);
|
||||
|
||||
@@ -75,6 +75,14 @@ function limited_backoffice_price_value(int $departmentId, int $productId): ?int
|
||||
return $row === null ? null : (int)$row['price'];
|
||||
}
|
||||
|
||||
function limited_backoffice_price_rows(int $departmentId, int $productId): array
|
||||
{
|
||||
return api_test_runtime()->db()->query(
|
||||
'SELECT `id`, `price` FROM `product_department_prices` WHERE `department_id` = ' . $departmentId .
|
||||
' AND `product_id` = ' . $productId . ' ORDER BY `id` ASC'
|
||||
)->fetch_all(MYSQLI_ASSOC);
|
||||
}
|
||||
|
||||
function limited_backoffice_cleanup_created_employee(int $employeeId): void
|
||||
{
|
||||
$row = api_test_runtime()->queryOne(
|
||||
@@ -200,6 +208,63 @@ it('lists and updates explicit prices only for assigned departments', function (
|
||||
|
||||
expect(limited_backoffice_price_value((int)$department['id'], (int)$product['id']))->toBe(2222);
|
||||
expect(limited_backoffice_price_value((int)$otherDepartment['id'], (int)$product['id']))->toBe(4321);
|
||||
expect($updated->data()['categories'][0]['products'][0]['price'] ?? null)->toBe(2222);
|
||||
});
|
||||
|
||||
it('returns saved prices and collapses legacy duplicate department price rows', function (): void {
|
||||
api_test_covers('PUT /limited-backoffice/departments/{departmentId}/prices', 'legacy duplicates');
|
||||
|
||||
$department = api_fixtures()->createDepartment(['name' => 'Limited Legacy Duplicate Prices']);
|
||||
$category = api_fixtures()->createCategory(['name' => 'Limited Legacy Duplicate Category']);
|
||||
$product = api_fixtures()->createProduct([
|
||||
'name' => 'Legacy Duplicate Price',
|
||||
'category' => $category['id'],
|
||||
]);
|
||||
api_fixtures()->linkDepartmentCategory((int)$department['id'], (int)$category['id']);
|
||||
|
||||
$db = api_test_runtime()->db();
|
||||
$index = $db->query("SHOW INDEX FROM `product_department_prices` WHERE `Key_name` = 'uniq_product_department_prices_lookup'");
|
||||
if ($index === false) {
|
||||
throw new RuntimeException('Unable to inspect product_department_prices lookup index.');
|
||||
}
|
||||
$hadIndex = (int)$index->num_rows > 0;
|
||||
if ($hadIndex) {
|
||||
$db->query('ALTER TABLE `product_department_prices` DROP INDEX `uniq_product_department_prices_lookup`');
|
||||
}
|
||||
|
||||
try {
|
||||
limited_backoffice_price_insert((int)$department['id'], (int)$product['id'], 111);
|
||||
limited_backoffice_price_insert((int)$department['id'], (int)$product['id'], 222);
|
||||
expect(limited_backoffice_price_rows((int)$department['id'], (int)$product['id']))->toHaveCount(2);
|
||||
|
||||
$session = limited_backoffice_manager_session([(int)$department['id']]);
|
||||
$updated = api_client()->put('/limited-backoffice/departments/' . (int)$department['id'] . '/prices', [
|
||||
'prices' => [
|
||||
['product_id' => (int)$product['id'], 'price' => 333],
|
||||
],
|
||||
], $session['headers']);
|
||||
|
||||
$updated
|
||||
->assertStatus(200)
|
||||
->assertEnvelope()
|
||||
->assertSuccess();
|
||||
|
||||
$rows = limited_backoffice_price_rows((int)$department['id'], (int)$product['id']);
|
||||
expect($rows)->toHaveCount(1);
|
||||
expect((int)$rows[0]['price'])->toBe(333);
|
||||
expect($updated->data()['categories'][0]['products'][0]['price'] ?? null)->toBe(333);
|
||||
} finally {
|
||||
$db->query(
|
||||
'DELETE FROM `product_department_prices` WHERE `department_id` = ' . (int)$department['id'] .
|
||||
' AND `product_id` = ' . (int)$product['id']
|
||||
);
|
||||
if ($hadIndex) {
|
||||
$db->query(
|
||||
'ALTER TABLE `product_department_prices`
|
||||
ADD UNIQUE KEY `uniq_product_department_prices_lookup` (`department_id`, `product_id`)'
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('updates department prices when the price table has no updated_at column', function (): void {
|
||||
|
||||
Reference in New Issue
Block a user