122 lines
4.1 KiB
JavaScript
122 lines
4.1 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import fs from 'node:fs';
|
|
import {
|
|
operationTreatments,
|
|
newSalesOperation,
|
|
evaluateSalesOperation,
|
|
recordSales,
|
|
saveSalesBook,
|
|
salesBook,
|
|
salesCurrent,
|
|
} from '../../resources/js/lib/iva-operations.ts';
|
|
import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts';
|
|
const ids = [
|
|
'health_assistive',
|
|
'human_materials',
|
|
'patient_transport',
|
|
'mosquito_nets',
|
|
'medicines',
|
|
];
|
|
export function healthFixture() {
|
|
const draft = JSON.parse(
|
|
fs.readFileSync(
|
|
new URL('./fixtures/iva-services.json', import.meta.url),
|
|
'utf8',
|
|
),
|
|
);
|
|
draft.context_opportunity = 'opportunity:309';
|
|
draft.project_title = 'SYNTHETIC QA — G2A saúde';
|
|
let book = {
|
|
currency: 'MZN',
|
|
rows: ids.map((id, i) => ({
|
|
...newSalesOperation(`g2a-${i}`, '2026-02', 'MZN'),
|
|
description: `SYNTHETIC QA ${id}`,
|
|
establishment: 'SYNTHETIC QA estabelecimento Manica',
|
|
amount: '100',
|
|
basis: i % 2 ? 'included' : 'net',
|
|
treatment: id,
|
|
confirmed: operationTreatments
|
|
.find((t) => t.id === id)
|
|
.conditions.map((_, n) => n),
|
|
evidence:
|
|
'SYNTHETIC QA — natureza, destino e autorização quando aplicável pressupostos documentados; sem certificação',
|
|
})),
|
|
periods: [{ period: '2026-02', complete: true }],
|
|
};
|
|
book = recordSales(draft, book);
|
|
draft.modelo_a_snapshot = saveSalesBook(draft, book);
|
|
return { draft, book };
|
|
}
|
|
void test('G2A five health branches require their own nature, location, purpose and authorization, not the health sector', () => {
|
|
const { book } = healthFixture();
|
|
for (const row of book.rows) {
|
|
const r = evaluateSalesOperation(row, 'MZN');
|
|
assert.equal(r.field, '07');
|
|
assert.equal(r.net, '100.00');
|
|
assert.equal(r.vat, '0.00');
|
|
assert.equal(r.gross, '100.00');
|
|
assert.match(r.source, /1426\(267\)/);
|
|
const count = operationTreatments.find((t) => t.id === row.treatment)
|
|
.conditions.length;
|
|
for (let missing = 0; missing < count; missing++)
|
|
assert.equal(
|
|
evaluateSalesOperation(
|
|
{
|
|
...row,
|
|
confirmed: row.confirmed.filter((n) => n !== missing),
|
|
},
|
|
'MZN',
|
|
).vat,
|
|
null,
|
|
);
|
|
assert.equal(
|
|
evaluateSalesOperation({ ...row, evidence: '' }, 'MZN').vat,
|
|
null,
|
|
);
|
|
}
|
|
assert.equal(book.result.periods[0].fields['07'], '500.00');
|
|
});
|
|
void test('G2A reuses saved dossier data, retains G1 unchanged, and reports recovered context without recalculating accepted treatments', () => {
|
|
const original = JSON.parse(
|
|
fs.readFileSync(
|
|
new URL('./fixtures/iva-services.json', import.meta.url),
|
|
'utf8',
|
|
),
|
|
);
|
|
const before = JSON.parse(original.modelo_a_snapshot).salesOperations[
|
|
'opportunity:310'
|
|
];
|
|
const { draft } = healthFixture();
|
|
const recovered = JSON.parse(JSON.stringify(draft));
|
|
assert.equal(salesCurrent(recovered, salesBook(recovered)), true);
|
|
assert.deepEqual(
|
|
JSON.parse(recovered.modelo_a_snapshot).salesOperations[
|
|
'opportunity:310'
|
|
],
|
|
before,
|
|
);
|
|
const model = JSON.stringify(
|
|
createProjectDossierReport(recovered, {
|
|
selectedSections: new Set(['finance']),
|
|
}),
|
|
);
|
|
for (const token of [
|
|
...ids,
|
|
'500.00',
|
|
'opportunity:309',
|
|
'Manica',
|
|
'MZN',
|
|
'2026-02',
|
|
])
|
|
assert.ok(model.includes(token), token);
|
|
assert.equal(model.includes('financial_stamp'), false);
|
|
assert.equal(draft.province_id, original.province_id);
|
|
assert.deepEqual(draft.selection_labels, original.selection_labels);
|
|
});
|
|
if (process.env.IVA_G2A_OUT)
|
|
fs.writeFileSync(
|
|
process.env.IVA_G2A_OUT,
|
|
JSON.stringify(healthFixture().draft, null, 2),
|
|
);
|