import assert from 'node:assert/strict'; import test from 'node:test'; import { buildCutPlan, buildOpenProductionByProductId, classifyCutFamily } from './cutting.ts'; import type { DateRange, ProductAnalyticsItem, ProductionOrderItem } from '../types.ts'; const range: DateRange = { start: new Date(2026, 6, 1), end: new Date(2026, 6, 7) }; const product = (overrides: Partial): 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 }); const productionOrder = (overrides: Partial): ProductionOrderItem => ({ id: 1, tinyId: '', number: 'OP-1', status: 'in_progress', statusLabel: 'Em andamento', orderReference: '', issueDate: '2026-07-01', expectedDate: '2026-07-15', productSku: '', productDescription: 'BASE LISA CAMISETA COR PRETO TAMANHO - M', quantity: 40, unit: 'UN', integrationStatus: '', markers: [], createdAt: null, updatedAt: null, ...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(row.estimatedRolls, null); assert.deepEqual(row.issues, ['missing_yield_rule']); 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 estimates rolls when a family yield is configured', () => { const plan = buildCutPlan([product({})], range, 14, {}, { familyYields: { BLCS: 50 } }); const [row] = plan.needRows; assert.equal(row.suggestedCutQuantity, 120); assert.equal(row.estimatedRolls, 3); assert.deepEqual(row.issues, []); assert.equal(plan.summary.estimatedRolls, 3); }); test('buildCutPlan applies per-product planning overrides to finished apparel', () => { const plan = buildCutPlan([ product({ id: 'SKU-2', name: 'CAMISETA SEM PADRAO', quantitySold: 70, stock: 0 }) ], range, 7, {}, { familyYields: { BLCS: 35 }, productOverrides: { 'SKU-2': { familyKey: 'BLCS', color: 'Preto', size: 'M' } } }); assert.equal(plan.needRows[0].family.key, 'BLCS'); assert.equal(plan.needRows[0].color, 'Preto'); assert.equal(plan.needRows[0].size, 'M'); assert.equal(plan.needRows[0].estimatedRolls, 2); assert.deepEqual(plan.needRows[0].issues, []); }); test('buildCutPlan excludes non-apparel products from cut planning', () => { const plan = buildCutPlan([ product({ id: 'SKU-2', name: 'BONÉ PRETO', quantitySold: 70, stock: 0 }), product({ id: 'SKU-3', name: 'TRANSPARENTE PP MILHEIRO - 25x35', quantitySold: 70, stock: 0 }) ], range, 7); assert.equal(plan.rows.length, 0); assert.equal(plan.summary.skuCount, 0); }); test('buildOpenProductionByProductId matches open OPs by SKU and normalized product variant', () => { const products = [ product({ id: 'SKU-1' }), product({ id: 'SKU-2', name: 'BASE LISA CAMISETA COR BRANCO TAMANHO - G' }) ]; const totals = buildOpenProductionByProductId(products, [ productionOrder({ productSku: 'SKU-1', productDescription: '', quantity: 10 }), productionOrder({ productSku: '', productDescription: 'Base Lisa Camiseta Cor Branco Tamanho - G', quantity: 20 }), productionOrder({ productSku: 'SKU-1', status: 'finished', quantity: 999 }) ]); assert.deepEqual(totals, { 'SKU-1': 10, 'SKU-2': 20 }); }); test('buildCutPlan marks apparel products that cannot be planned cleanly for cutting', () => { const plan = buildCutPlan([ product({ id: 'SKU-2', name: 'VESTUARIO SEM PADRAO', 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); });