197 lines
6.9 KiB
JavaScript
197 lines
6.9 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import fs from 'node:fs';
|
|
import {
|
|
pharmaAnnexEntries,
|
|
pharmaAnnexEntry,
|
|
pharmaAnnexVersion,
|
|
} from '../../resources/js/lib/iva-pharma-annex.ts';
|
|
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 rule = operationTreatments.find(
|
|
(t) => t.id === 'pharma_manufacturing_inputs',
|
|
);
|
|
const seed = () =>
|
|
JSON.parse(
|
|
fs.readFileSync(
|
|
new URL('./fixtures/iva-fundraising.json', import.meta.url),
|
|
'utf8',
|
|
),
|
|
);
|
|
const operation = (entry, i = 0) => ({
|
|
...newSalesOperation(`g2k-${i}`, '2026-12', 'MZN'),
|
|
description: `SYNTHETIC QA ${entry.code} ${entry.id}`,
|
|
establishment:
|
|
'SYNTHETIC QA estabelecimento transmitente integrado no SNS — Manica',
|
|
amount: '100',
|
|
basis: i % 2 ? 'included' : 'net',
|
|
treatment: rule.id,
|
|
pharmaAnnexItem: entry.id,
|
|
confirmed: rule.conditions.map((_, n) => n),
|
|
evidence:
|
|
'SYNTHETIC QA: integração do próprio transmitente no SNS, utilização no fabrico e correspondência código/designação expressamente pressupostas; não é certificação',
|
|
});
|
|
function fixture() {
|
|
const draft = seed();
|
|
draft.context_opportunity = 'opportunity:320';
|
|
draft.project_title = 'SYNTHETIC QA — G2K Anexo III';
|
|
const entries = [
|
|
pharmaAnnexEntries[0],
|
|
...pharmaAnnexEntries.filter(
|
|
(e) => e.code === '2912.19.00' || e.code === '2935.',
|
|
),
|
|
pharmaAnnexEntries.at(-1),
|
|
];
|
|
const book = recordSales(draft, {
|
|
currency: 'MZN',
|
|
rows: entries.map(operation),
|
|
periods: [{ period: '2026-12', complete: true }],
|
|
});
|
|
draft.modelo_a_snapshot = saveSalesBook(draft, book);
|
|
return { draft, book };
|
|
}
|
|
|
|
void test('AnexoIII has 170 documentary rows, including two distinct 2912.19.00 entries and printed 2935. position', () => {
|
|
assert.equal(pharmaAnnexEntries.length, 170);
|
|
assert.equal(new Set(pharmaAnnexEntries.map((e) => e.id)).size, 170);
|
|
assert.equal(new Set(pharmaAnnexEntries.map((e) => e.code)).size, 169);
|
|
const duplicates = pharmaAnnexEntries.filter(
|
|
(e) => e.code === '2912.19.00',
|
|
);
|
|
assert.equal(duplicates.length, 2);
|
|
assert.notEqual(duplicates[0].label, duplicates[1].label);
|
|
assert.equal(
|
|
pharmaAnnexEntries.filter((e) => e.code === '2935.').length,
|
|
1,
|
|
);
|
|
assert.equal(pharmaAnnexEntry('2935.00.00'), undefined);
|
|
assert.equal(
|
|
pharmaAnnexEntries.find((e) => e.code === '2827.39.00').lastPdfPage,
|
|
13,
|
|
);
|
|
assert.equal(
|
|
pharmaAnnexEntries.find((e) => e.code === '2922.49.00').lastPdfPage,
|
|
15,
|
|
);
|
|
for (const [i, entry] of pharmaAnnexEntries.entries()) {
|
|
const r = evaluateSalesOperation(operation(entry, i), 'MZN');
|
|
assert.equal(r.status, 'exempt');
|
|
assert.equal(r.field, '07');
|
|
assert.equal(r.vat, '0.00');
|
|
assert.equal(r.gross, '100.00');
|
|
for (const token of [
|
|
entry.id,
|
|
entry.code,
|
|
entry.label,
|
|
`PDF${entry.pdfPage}`,
|
|
pharmaAnnexVersion,
|
|
])
|
|
assert.ok(r.source.includes(token), token);
|
|
}
|
|
});
|
|
|
|
void test('P008 requires the transmitting establishment, manufacturing use, exact annex identity and evidence; unknown is not zero', () => {
|
|
const { draft, book } = fixture(),
|
|
row = book.rows[0];
|
|
assert.match(rule.conditions[1], /pelo próprio estabelecimento/);
|
|
assert.match(rule.conditions[1], /não basta.*adquirente/);
|
|
for (const missing of row.confirmed)
|
|
assert.equal(
|
|
evaluateSalesOperation(
|
|
{
|
|
...row,
|
|
confirmed: row.confirmed.filter((n) => n !== missing),
|
|
},
|
|
'MZN',
|
|
).vat,
|
|
null,
|
|
);
|
|
for (const patch of [
|
|
{ pharmaAnnexItem: undefined },
|
|
{ pharmaAnnexItem: '' },
|
|
{ pharmaAnnexItem: '1108.11.00' },
|
|
{ pharmaAnnexItem: 'annexI-2022-001' },
|
|
{ pharmaAnnexItem: 'annexIII-2017-001' },
|
|
{ evidence: '' },
|
|
{ establishment: '' },
|
|
{ amount: '' },
|
|
{ period: '2025-12' },
|
|
{ sourceCurrency: 'USD' },
|
|
])
|
|
assert.equal(
|
|
evaluateSalesOperation({ ...row, ...patch }, 'MZN').vat,
|
|
null,
|
|
);
|
|
assert.equal(evaluateSalesOperation(row, 'USD').vat, null);
|
|
const unknown = recordSales(draft, {
|
|
...book,
|
|
rows: [{ ...row, pharmaAnnexItem: '' }],
|
|
});
|
|
assert.equal(unknown.result.periods[0].fields['07'], null);
|
|
assert.deepEqual(unknown.history.at(-1), book.result);
|
|
});
|
|
|
|
void test('P008 keeps its row identity, report and selected opportunity through recovery; eleven delivered books remain current without recalculation', () => {
|
|
const { draft, book } = fixture(),
|
|
original = seed(),
|
|
old = JSON.parse(original.modelo_a_snapshot).salesOperations;
|
|
const recovered = JSON.parse(JSON.stringify(draft)),
|
|
store = JSON.parse(recovered.modelo_a_snapshot).salesOperations;
|
|
assert.equal(Object.keys(old).length, 11);
|
|
for (const [id, value] of Object.entries(old)) {
|
|
assert.deepEqual(store[id], value);
|
|
assert.equal(
|
|
salesCurrent({ ...recovered, context_opportunity: id }, value),
|
|
true,
|
|
id,
|
|
);
|
|
}
|
|
assert.equal(salesCurrent(recovered, salesBook(recovered)), true);
|
|
const report = JSON.stringify(
|
|
createProjectDossierReport(recovered, {
|
|
selectedSections: new Set(['finance']),
|
|
}),
|
|
);
|
|
for (const token of [
|
|
'500.00',
|
|
'opportunity:320',
|
|
'Manica',
|
|
'2026-12',
|
|
'MZN',
|
|
'AnexoIII/2022',
|
|
pharmaAnnexVersion,
|
|
...book.rows.map((r) => r.pharmaAnnexItem),
|
|
])
|
|
assert.ok(report.includes(token), token);
|
|
assert.equal(report.includes('fundraising_public'), false);
|
|
assert.equal(report.includes('production_forestry_opted'), false);
|
|
assert.deepEqual(recovered.selection_labels, original.selection_labels);
|
|
assert.equal(recovered.currency, original.currency);
|
|
const duplicates = pharmaAnnexEntries.filter(
|
|
(e) => e.code === '2912.19.00',
|
|
);
|
|
const changed = {
|
|
...book,
|
|
rows: book.rows.map((r) =>
|
|
r.pharmaAnnexItem === duplicates[0].id
|
|
? { ...r, pharmaAnnexItem: duplicates[1].id }
|
|
: r,
|
|
),
|
|
};
|
|
assert.equal(salesCurrent(draft, changed), false);
|
|
assert.deepEqual(changed.result, book.result);
|
|
});
|
|
if (process.env.IVA_G2K_OUT)
|
|
fs.writeFileSync(
|
|
process.env.IVA_G2K_OUT,
|
|
JSON.stringify(fixture().draft, null, 2),
|
|
);
|