updated on shelfon store catalogue

This commit is contained in:
2026-08-31 16:26:58 +05:30
parent 55ed13c284
commit 5304d9aeb6
3 changed files with 177 additions and 22 deletions

View File

@@ -0,0 +1,62 @@
/**
* Releasing several products at once must not give them all one price.
*
* `publishproduct` writes `products.retailprice` as well as the per-outlet
* price, at every branch. So publishing the seventeen products R mart imported
* on 2026-08-31 — ₹395 rice, ₹30 crisps, ₹105 cleaner — with the single figure
* the dialog prefilled from the first row would have set all seventeen to ₹395
* and left nothing to restore the real prices from.
*/
import assert from 'node:assert/strict';
import { test } from 'node:test';
import { needingPrice, planPublish } from './publishPlan';
import type { Product } from '@/api/types';
const product = (id: number, price: number, retail = 0, tax?: number) =>
({ productid: id, price, retailprice: retail, ...(tax === undefined ? {} : { taxpercent: tax }) }) as Product;
test('each product is released at its own price', () => {
const plan = planPublish(
[product(7089, 395), product(7103, 30), product(7104, 105)],
{ price: 395, taxpercent: 0 },
);
assert.deepEqual(
plan.map((line) => line.price),
[395, 30, 105],
);
});
// The whole point of the fallback: a product with no price of its own is the
// only one the typed figure may touch.
test('only a product with no price uses the typed figure', () => {
const plan = planPublish([product(1, 0), product(2, 250)], { price: 99, taxpercent: 5 });
assert.equal(plan[0]?.price, 99);
assert.equal(plan[1]?.price, 250);
});
/*
The per-outlet price and the tenant master are two columns and either can be the
one that holds the figure — an imported product carries both, a hand-priced one
may carry only the master. `effectivePrice` already resolves that, and publish
has to use the same resolution or it would "fill in" a price that exists.
*/
test('the master price counts as having a price', () => {
const plan = planPublish([product(1, 0, 175)], { price: 99, taxpercent: 0 });
assert.equal(plan[0]?.price, 175);
});
test('tax follows the same rule as price', () => {
const plan = planPublish([product(1, 100, 0, 12), product(2, 100)], { price: 0, taxpercent: 5 });
assert.equal(plan[0]?.taxpercent, 12);
assert.equal(plan[1]?.taxpercent, 5);
});
// Zero is a real tax rate and must survive, not fall through to the fallback.
test('a tax rate of zero is kept, not treated as missing', () => {
const plan = planPublish([product(1, 100, 0, 0)], { price: 0, taxpercent: 18 });
assert.equal(plan[0]?.taxpercent, 0);
});
test('only the unpriced products are counted as needing one', () => {
assert.equal(needingPrice([product(1, 395), product(2, 0), product(3, 0, 88)]).length, 1);
});