Add native cutting plan page
This commit is contained in:
64
src/analytics/cutting.test.ts
Normal file
64
src/analytics/cutting.test.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { buildCutPlan, classifyCutFamily } from './cutting.ts';
|
||||
import type { DateRange, ProductAnalyticsItem } from '../types.ts';
|
||||
|
||||
const range: DateRange = {
|
||||
start: new Date(2026, 6, 1),
|
||||
end: new Date(2026, 6, 7)
|
||||
};
|
||||
|
||||
const product = (overrides: Partial<ProductAnalyticsItem>): ProductAnalyticsItem => ({
|
||||
id: 'SKU-1',
|
||||
name: 'BASE LISA CAMISETA COR PRETO TAMANHO - M',
|
||||
quantitySold: 70,
|
||||
revenue: 700,
|
||||
orderLineCount: 10,
|
||||
lastPrice: 10,
|
||||
stock: 20,
|
||||
firstSaleDate: '2026-07-01',
|
||||
lastSaleDate: '2026-07-07',
|
||||
...overrides
|
||||
});
|
||||
|
||||
test('classifyCutFamily maps known product bases to internal cut families', () => {
|
||||
assert.equal(classifyCutFamily('BASE LISA CAMISETA').key, 'BLCS');
|
||||
assert.equal(classifyCutFamily('BASE LISA CAMISETA OVER').key, 'BLOS');
|
||||
assert.equal(classifyCutFamily('BASE LISA MOLETOM CANGURU').key, 'BLPM');
|
||||
assert.equal(classifyCutFamily('BONÉ').key, 'OUTROS');
|
||||
});
|
||||
|
||||
test('buildCutPlan calculates projected cut need from sales pace and stock', () => {
|
||||
const plan = buildCutPlan([product({})], range, 14);
|
||||
const [row] = plan.needRows;
|
||||
|
||||
assert.equal(row.dailySales, 10);
|
||||
assert.equal(row.projectedDemand, 140);
|
||||
assert.equal(row.availableQuantity, 20);
|
||||
assert.equal(row.suggestedCutQuantity, 120);
|
||||
assert.equal(plan.summary.suggestedCutQuantity, 120);
|
||||
});
|
||||
|
||||
test('buildCutPlan subtracts open production quantity from suggested cut need', () => {
|
||||
const plan = buildCutPlan([product({ id: 'SKU-1' })], range, 14, { 'SKU-1': 100 });
|
||||
const [row] = plan.needRows;
|
||||
|
||||
assert.equal(row.availableQuantity, 120);
|
||||
assert.equal(row.suggestedCutQuantity, 20);
|
||||
});
|
||||
|
||||
test('buildCutPlan marks products that cannot be planned cleanly for cutting', () => {
|
||||
const plan = buildCutPlan([
|
||||
product({
|
||||
id: 'SKU-2',
|
||||
name: 'BONÉ PRETO',
|
||||
quantitySold: 70,
|
||||
stock: 0
|
||||
})
|
||||
], range, 7);
|
||||
|
||||
assert.equal(plan.needRows[0].family.key, 'OUTROS');
|
||||
assert.deepEqual(plan.needRows[0].issues, ['missing_family_rule', 'missing_color', 'missing_size']);
|
||||
assert.equal(plan.summary.rowsWithIssues, 1);
|
||||
});
|
||||
Reference in New Issue
Block a user