import test from 'node:test'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import { newValueReview, switchValueReview, switchPriceContext, switchValueOrigin, valueReviewTreatments, priceContexts, valueReviewConditions, evaluateValueReview, recordValueReviews, saveValueReviewBook, valueReviewBook, valueReviewCurrent, valueReviewReportRows, } from '../../resources/js/lib/iva-value-review.ts'; import { exclusionCurrent } from '../../resources/js/lib/iva-exclusion-base.ts'; import { compositionCurrent } from '../../resources/js/lib/iva-composition-base.ts'; import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts'; const frozen = JSON.parse( fs.readFileSync( new URL('./fixtures/iva-g7h-preserved-inputs.json', import.meta.url), 'utf8', ), ); const row = (treatment = 'price_comparison') => ({ ...newValueReview('g7h-' + treatment, 'MZN'), treatment, priceContext: 'retail', description: 'SYNTHETIC QA operação A', period: '2026-12', operationRef: 'SYNTHETIC QA operação A', documentRef: 'SYNTHETIC QA G7H ' + treatment, documentDate: '2026-12-12', declaredAmount: '1000.25', referenceAmount: '1500.50', referenceRef: 'SYNTHETIC QA preço corrente A', referenceScope: 'SYNTHETIC QA bens A,retalho,dezembro2026,Manica e condições comparáveis', compositionRef: 'SYNTHETIC QA composição equivalente15(5)/(6),sem próprioIVA', evidence: 'SYNTHETIC QA pressupostos expressos,não documento real', correctedAmount: '1400.75', correctionRef: 'SYNTHETIC QA pressuposto condicionado correcção A', correctionScope: 'SYNTHETIC QA bens A/operação A/dezembro2026/condições A', correctionDate: '2026-12-20', correctionApplies: 'yes', conditions: Object.fromEntries( valueReviewConditions.map(([key]) => [key, 'yes']), ), }); const draft = () => ({ ...structuredClone(frozen), context_opportunity: 'opportunity:346', project_title: 'SYNTHETIC QA — G7H / Comparação e correcção', }); void test('P103 contexts and ownconditions/references;below comparison never replaces declaredbase automatically', () => { for (const context of priceContexts) { const input = { ...row(), priceContext: context.id }; assert.equal(evaluateValueReview(input, 'MZN').baseAmount, '1000.25'); assert.equal(evaluateValueReview(input, 'MZN').comparison, 'below'); for (const [key] of valueReviewConditions) for (const value of ['', 'unknown', 'no']) { const r = evaluateValueReview( { ...input, conditions: { ...input.conditions, [key]: value }, }, 'MZN', ); assert.equal( r.status, value === 'no' ? 'not_applicable' : 'indeterminate', ); assert.equal(r.baseAmount, null); assert.equal(r.vat, null); } for (const patch of [ { description: '' }, { operationRef: '' }, { documentRef: '' }, { documentDate: '2026-02-30' }, { referenceRef: '' }, { referenceScope: '' }, { compositionRef: '' }, { evidence: '' }, { period: '2025-12' }, { currency: 'USD' }, { priceContext: 'unknown' }, { treatment: '' }, { declaredAmount: '' }, { referenceAmount: '' }, ]) assert.equal( evaluateValueReview({ ...input, ...patch }, 'MZN').baseAmount, null, ); } for (const referenceAmount of ['1000.25', '500.00']) { const r = evaluateValueReview({ ...row(), referenceAmount }, 'MZN'); assert.equal(r.comparison, 'not_below'); assert.equal(r.baseAmount, '1000.25'); } }); void test('correction amount/reference/scope required;scenario distinct fromeffective;no maximum/default reference;exactdecimal and switches', () => { const input = row('referenced_correction'), ok = evaluateValueReview(input, 'MZN'); assert.equal(ok.baseAmount, '1400.75'); assert.equal(ok.comparison, 'below'); assert.match(ok.reason, /Cenário condicionado/); assert.equal(ok.vat, null); assert.equal(ok.rate, null); assert.match( evaluateValueReview({ ...input, origin: 'effective' }, 'MZN').reason, /dados efectivos declarados/, ); for (const patch of [ { correctedAmount: '' }, { correctionRef: '' }, { correctionScope: '' }, { correctionDate: '2026-02-30' }, { correctionApplies: '' }, ]) { const r = evaluateValueReview({ ...input, ...patch }, 'MZN'); assert.equal(r.baseAmount, null); assert.equal(r.comparison, 'below'); } assert.equal( evaluateValueReview({ ...input, correctionApplies: 'no' }, 'MZN') .status, 'not_applicable', ); assert.equal( evaluateValueReview({ ...input, referenceAmount: '500' }, 'MZN').status, 'not_applicable', ); for (const correctedAmount of ['0', '900.15', '999999999999999.999999']) assert.equal( evaluateValueReview({ ...input, correctedAmount }, 'MZN') .baseAmount, correctedAmount === '0' ? '0.00' : correctedAmount, ); for (const correctedAmount of ['-1', 'NaN', '0.0000001']) assert.equal( evaluateValueReview({ ...input, correctedAmount }, 'MZN') .baseAmount, null, ); assert.equal( evaluateValueReview( { ...row(), declaredAmount: '0', referenceAmount: '0' }, 'MZN', ).baseAmount, '0.00', ); assert.equal( evaluateValueReview( { ...row(), declaredAmount: '1.000001', referenceAmount: '1.000002', }, 'MZN', ).comparison, 'below', ); for (const changed of [ switchValueReview(input, 'price_comparison'), switchPriceContext(input, 'wholesale'), switchValueOrigin(input, 'effective'), ]) { assert.equal(changed.correctionApplies, ''); for (const field of [ 'declaredAmount', 'referenceAmount', 'correctedAmount', 'correctionRef', 'correctionScope', ]) assert.equal(changed[field], input[field]); } assert.equal( evaluateValueReview(switchValueOrigin(input, 'effective'), 'MZN') .baseAmount, null, ); assert.equal( evaluateValueReview(switchPriceContext(input, 'wholesale'), 'MZN') .baseAmount, null, ); }); void test('save/recovery/history/report preserve all85 delivered books/currentkeys including P102/P101/P095', () => { const d = draft(), prior = JSON.parse(d.modelo_a_snapshot); assert.deepEqual(valueReviewBook(d), { rows: [] }); assert.deepEqual(valueReviewReportRows(d), []); let book = recordValueReviews(d, { rows: valueReviewTreatments.map((t) => ({ ...row(t.id), conditions: {}, })), }); book = recordValueReviews(d, { ...book, rows: valueReviewTreatments.map((t) => ({ ...row(t.id), conditions: { ...row(t.id).conditions, referenceCorresponds: 'no' }, })), }); book = recordValueReviews(d, { ...book, rows: valueReviewTreatments.map((t) => row(t.id)), }); assert.equal(book.history.length, 2); assert.ok( book.history.every((h) => h.rows.every((r) => r.baseAmount === null && r.vat === null), ), ); assert.ok(valueReviewCurrent(d, book)); for (const field of [ 'priceContext', 'declaredAmount', 'referenceAmount', 'referenceScope', 'correctedAmount', 'correctionRef', 'correctionScope', 'correctionApplies', 'origin', ]) assert.ok( !valueReviewCurrent(d, { ...book, rows: book.rows.map((r) => ({ ...r, [field]: 'changed' })), }), ); for (const patch of [ { context_opportunity: 'opportunity:347' }, { currency: 'USD' }, { selection_labels: { province_id: 'Maputo' } }, ]) assert.ok(!valueReviewCurrent({ ...d, ...patch }, book)); d.modelo_a_snapshot = saveValueReviewBook(d, book); assert.deepEqual(valueReviewBook(JSON.parse(JSON.stringify(d))), book); const next = JSON.parse(d.modelo_a_snapshot); const { valueReviews: _valueReviews, ...untouched } = next; assert.deepEqual(untouched, prior); for (const [scope, previous] of Object.entries( prior.considerationExclusions, )) assert.ok( exclusionCurrent({ ...d, context_opportunity: scope }, previous), ); for (const [scope, previous] of Object.entries( prior.considerationCompositions, )) assert.ok( compositionCurrent({ ...d, context_opportunity: scope }, previous), ); assert.equal( next.considerationExclusions['opportunity:345'].result.rows[0] .baseAmount, '799.70', ); assert.equal( next.considerationCompositions['opportunity:344'].result.rows[0] .baseAmount, '1150.60', ); assert.equal( next.regulatedFuelBases['opportunity:342'].result.rows[0].baseAmount, '1400.15', ); assert.equal( next.books['opportunity:329'].result.periods[0].fields['11'], null, ); const report = JSON.stringify( createProjectDossierReport(d, { selectedSections: new Set(['finance']), version: 'QA G7H', }), ); for (const token of [ 'Base P103', '1000.25', '1400.75', '1500.50', 'IVA: Indeterminado', 'opportunity:346', 'Manica', '2026-12', '15(7)', 'condicionado', 'correcção A', 'campo11', ]) assert.ok(report.includes(token), token); assert.deepEqual( valueReviewReportRows({ ...d, context_opportunity: 'opportunity:347' }), [], ); if (process.env.IVA_G7H_CALCULATED) fs.writeFileSync(process.env.IVA_G7H_CALCULATED, JSON.stringify(d)); }); void test('corrupt review rows/store cannot overwrite originals;duplicateoperationids cannotbe recorded', () => { const d = draft(), original = d.modelo_a_snapshot; for (const patch of [ { declaredAmount: 4 }, { conditions: [] }, { correctionScope: null }, ]) assert.throws( () => saveValueReviewBook(d, { rows: [{ ...row(), ...patch }] }), /originais preservados/, ); assert.equal(d.modelo_a_snapshot, original); assert.throws( () => recordValueReviews(d, { rows: [row(), row()] }), /distintos/, ); assert.throws(() => recordValueReviews(d, { rows: [] }), /distintos/); assert.throws( () => valueReviewBook({ ...d, modelo_a_snapshot: JSON.stringify({ ...JSON.parse(original), valueReviews: [], }), }), /originais preservados/, ); });