import assert from 'node:assert/strict' import test from 'node:test' import { measuredSources, configurationPayload, sourceLabel, stopUsageRows, unitConversions, coefficientFromQuantities, permitQuantityFromCoefficient } from '../src/components/business/pl-plan-quota-dialog/stop-model' const load: any = { sourceStopType: 'load', sourceStopProductId: 'a', planProductId: 'p', productName: '硫酸', stopOrder: 1, quantity: 100, unit: '吨', contractId: 'c1', contractProductId: 'cp1' } const delivery: any = { ...load, sourceStopType: 'delivery', sourceStopProductId: 'b', quantity: 40, contractId: 'c2', contractProductId: 'cp2' } const plan: any = { measurementVersion: 'per_stop_v2', configuration: {}, sourceOptions: [load, delivery], usages: [] } test('v2 measures every stop and never sends legacy pairs; absent version stays legacy', () => { assert.deepEqual(measuredSources(plan, { p: 'load' }), [load, delivery]) assert.equal( configurationPayload(plan, { sourceMapping: [{ old: true }] } as any, [load], {}).sourceMapping, null ) assert.deepEqual(measuredSources({ ...plan, measurementVersion: undefined }, { p: 'load' }), [ load ]) }) test('source labels use stop and product instead of source UUID', () => { assert.equal(sourceLabel('delivery:b', plan.sourceOptions), '送货段1 · 硫酸') assert.equal(sourceLabel('load:unknown', []), '来源已不可用') }) test('all stop products are visible and each certificate keeps its unit and quantity', () => { const data = { ...plan, stopProducts: [ { ...load, isToxic: true }, { ...delivery, isToxic: true }, { ...load, sourceStopProductId: 'e', isToxic: false, isExplosive: true } ], usages: [ { certType: 'purchase', certNoSnapshot: 'BUY', quantityUnit: '吨', items: [ { sourceStopType: 'load', sourceStopProductId: 'a', reservedQty: '100', usedQty: '0' } ] }, { certType: 'transport', certNoSnapshot: 'MOVE', quantityUnit: '千克', items: [ { sourceStopType: 'load', sourceStopProductId: 'a', reservedQty: '100000', usedQty: '0' } ] } ] } const rows = stopUsageRows(data) assert.equal(rows.length, 3) assert.equal(rows[0].purchase, 'BUY · 预占 100.000 吨 · 已用 0.000 吨') assert.equal(rows[0].transport, 'MOVE · 预占 100000.000 千克 · 已用 0.000 千克') assert.equal(rows[1].purchase, '缺配') assert.equal(rows[2].purchase, '无需两证') }) test('draft bindings show zeros in their own units and hidden scope never claims missing', () => { const rows = stopUsageRows({ ...plan, stopProducts: [ { ...load, isToxic: true, bindingsReadable: true, certificates: [{ certType: 'purchase', certId: 'cert', certNo: 'BUY', quantityUnit: '桶' }] }, { ...delivery, isToxic: true, bindingsReadable: false } ] }) assert.equal(rows[0].purchase, 'BUY · 已绑定 · 预占 0.000 桶 · 已用 0.000 桶') assert.equal(rows[1].purchase, '合同或证件不可读取') }) test('legacy counterpart is traceability only, never a second missing allocation', () => { const legacy = { ...plan, measurementVersion: 'legacy_single_side', configuration: { sourceMapping: [ { sourceStopType: 'load', sourceStopProductId: 'a', relatedStopProductIds: ['b'] } ] } } assert.equal(stopUsageRows(legacy as any)[1].purchase, '原口径:关联追溯,不另计量') }) test('unit conversion is only required when the plan unit differs from a bound certificate', () => { const same = unitConversions( { ...plan, stopProducts: [ { ...load, certificates: [{ certType: 'purchase', certId: 'buy', certNo: 'BUY', quantityUnit: '吨' }] } ] }, [load] ) const different = unitConversions( { ...plan, stopProducts: [ { ...load, certificates: [ { certType: 'purchase', certId: 'buy', certNo: 'BUY', quantityUnit: '吨' }, { certType: 'transport', certId: 'move', certNo: 'MOVE', quantityUnit: '千克' } ] } ] }, [load] ) assert.deepEqual(same, []) assert.deepEqual( different.map((row) => row.cert.certNo), ['MOVE'] ) const labelAndCode = unitConversions( { ...plan, stopProducts: [ { ...load, certificates: [ { certType: 'purchase', certId: 'buy', certNo: 'BUY', quantityUnit: '吨' }, { certType: 'transport', certId: 'move', certNo: 'MOVE', quantityUnit: '千克' } ] } ] }, [{ ...load, unit: 'dun' }] ) assert.deepEqual( labelAndCode.map((row) => row.cert.certNo), ['MOVE'] ) }) test('conversion coefficient scales the certificate quantity and can be recovered', () => { assert.equal(permitQuantityFromCoefficient(30, '1000'), '30000') assert.equal(permitQuantityFromCoefficient(30, '0'), '') assert.equal(coefficientFromQuantities('30.000', '30000'), '1000') })