Files
Investidor-V2/tests/frontend/iva-import-beneficiaries.test.mjs
T

255 lines
9.0 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import {
newImportExemption,
evaluateImportExemption,
recordImportExemptions,
saveImportExemptionBook,
importExemptionBook,
importExemptionCurrent,
importExemptionRules,
importBeneficiarySource,
} from '../../resources/js/lib/iva-import-exemptions.ts';
import { salesCurrent } from '../../resources/js/lib/iva-operations.ts';
import { acquisitionCurrent } from '../../resources/js/lib/iva-acquisitions.ts';
import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts';
const frozen = JSON.parse(
fs.readFileSync(
new URL('./fixtures/iva-g6a-inputs.json', import.meta.url),
'utf8',
),
);
const row = (treatment = 'author_art_import') => ({
...newImportExemption('g6b-' + treatment, 'MZN'),
treatment,
description:
treatment === 'author_art_import'
? 'SYNTHETIC QA objecto de arte'
: 'SYNTHETIC QA veículo de combate a incêndios',
period: '2026-12',
declaredValue: '2500',
importer:
treatment === 'author_art_import'
? 'SYNTHETIC QA artista-autor residente'
: 'SYNTHETIC QA corporação de bombeiros',
documentRef: 'SYNTHETIC QA G6B ' + treatment,
documentDate: '2026-11-12',
evidence:
treatment === 'author_art_import'
? 'SYNTHETIC QA autor residente em Manica e importador próprio; pressuposto, não é documento real'
: 'SYNTHETIC QA corporação e utilização exclusiva na sua actividade própria; pressuposto, não é documento real',
conditions:
treatment === 'author_art_import'
? { artObjects: 'yes', eligibleArtImporter: 'yes' }
: {
fireVehicle: 'yes',
fireBrigade: 'yes',
exclusiveOwnUse: 'yes',
},
});
const draft = () => ({
...structuredClone(frozen),
context_opportunity: 'opportunity:331',
project_title: 'SYNTHETIC QA — G6B / Arte e bombeiros',
});
void test('P055 and P057 require own statutory conditions;unknown and failed never become exempt zero or ordinary tax', () => {
for (const treatment of ['author_art_import', 'fire_brigade_vehicle']) {
const input = row(treatment),
rule = importExemptionRules.find((r) => r.id === treatment);
assert.equal(evaluateImportExemption(input, 'MZN').importVat, '0.00');
for (const [key] of rule.conditions)
for (const value of ['', 'no', 'unknown']) {
const result = evaluateImportExemption(
{
...input,
conditions: { ...input.conditions, [key]: value },
},
'MZN',
);
assert.equal(
result.status,
value === 'no' ? 'not_applicable' : 'indeterminate',
);
assert.equal(result.importVat, null);
}
for (const patch of [
{ evidence: '' },
{ documentRef: '' },
{ currency: 'USD' },
{ period: '2025-12' },
{ importer: '' },
{ documentDate: '2026-02-30' },
])
assert.equal(
evaluateImportExemption({ ...input, ...patch }, 'MZN')
.importVat,
null,
);
assert.deepEqual(input, row(treatment));
}
assert.match(importBeneficiarySource, /12\(1\)\(j\/l\)/);
assert.match(
importExemptionRules.find((r) => r.branch === 'P055').conditions[1][1],
/residentes.*herdeiros ou legatários/,
);
});
void test('art importer alternatives retain exact factual basis;not every art dealer or public entity qualifies', () => {
for (const importer of [
'artista-autor residente',
'herdeiro de artista-autor residente',
'legatário de artista-autor residente',
]) {
const input = {
...row(),
importer: 'SYNTHETIC QA ' + importer,
evidence:
'SYNTHETIC QA ' +
importer +
'; identidade, residência e relação expressamente assumidas',
};
assert.equal(evaluateImportExemption(input, 'MZN').status, 'exempt');
assert.ok(input.evidence.includes(importer));
}
assert.equal(
evaluateImportExemption(
{
...row(),
importer: 'Comerciante de arte',
conditions: { artObjects: 'yes', eligibleArtImporter: 'no' },
},
'MZN',
).status,
'not_applicable',
);
assert.equal(
evaluateImportExemption(
{
...row('fire_brigade_vehicle'),
conditions: {
fireVehicle: 'yes',
fireBrigade: 'no',
exclusiveOwnUse: 'yes',
},
},
'MZN',
).status,
'not_applicable',
);
});
void test('editing treatment keeps document and answers;explicit classification archives nonapplication and unknown results', () => {
const d = draft(),
input = row();
let book = recordImportExemptions(d, {
rows: [{ ...input, conditions: { artObjects: 'yes' } }],
});
assert.equal(book.result.rows[0].status, 'indeterminate');
book = recordImportExemptions(d, {
...book,
rows: [
{
...input,
conditions: { ...input.conditions, eligibleArtImporter: 'no' },
},
],
});
assert.equal(book.result.rows[0].status, 'not_applicable');
const switched = {
...input,
treatment: 'fire_brigade_vehicle',
conditions: {
...input.conditions,
...row('fire_brigade_vehicle').conditions,
},
};
assert.equal(switched.documentRef, input.documentRef);
assert.equal(switched.conditions.eligibleArtImporter, 'yes');
const returned = { ...switched, treatment: 'author_art_import' };
assert.equal(evaluateImportExemption(returned, 'MZN').status, 'exempt');
book = recordImportExemptions(d, {
...book,
rows: [returned, row('fire_brigade_vehicle')],
});
assert.equal(book.history.length, 2);
assert.equal(book.history[0].rows[0].status, 'indeterminate');
assert.equal(book.history[1].rows[0].status, 'not_applicable');
assert.ok(importExemptionCurrent(d, book));
for (const patch of [
{ currency: 'USD' },
{ context_opportunity: 'opportunity:330' },
{ selection_labels: { province_id: 'Maputo' } },
])
assert.ok(!importExemptionCurrent({ ...d, ...patch }, book));
});
void test('save/recovery/report keep all22acceptedbooks current and unchanged;only newly selected treatments add scoped version/source', () => {
const d = draft(),
prior = JSON.parse(frozen.modelo_a_snapshot);
let book = recordImportExemptions(d, {
rows: [
{ ...row(), conditions: { artObjects: 'yes' } },
row('fire_brigade_vehicle'),
],
});
book = recordImportExemptions(d, {
...book,
rows: [row(), row('fire_brigade_vehicle')],
});
d.modelo_a_snapshot = saveImportExemptionBook(d, book);
assert.deepEqual(importExemptionBook(JSON.parse(JSON.stringify(d))), book);
assert.match(book.result.sourceKey, /import-beneficiaries\/1/);
assert.match(book.result.source, /12\(1\)\(j\/l\)/);
const next = JSON.parse(d.modelo_a_snapshot);
assert.deepEqual(next.salesOperations, prior.salesOperations);
assert.deepEqual(next.books, prior.books);
assert.deepEqual(
next.importExemptions['opportunity:330'],
prior.importExemptions['opportunity:330'],
);
for (const [scope, sales] of Object.entries(next.salesOperations))
assert.ok(salesCurrent({ ...d, context_opportunity: scope }, sales));
assert.ok(
acquisitionCurrent(
{ ...d, context_opportunity: 'opportunity:329' },
next.books['opportunity:329'],
),
);
assert.ok(
importExemptionCurrent(
{ ...d, context_opportunity: 'opportunity:330' },
next.importExemptions['opportunity:330'],
),
);
const report = JSON.stringify(
createProjectDossierReport(d, {
selectedSections: new Set(['finance']),
version: 'QA G6B',
}),
);
for (const token of [
'P055',
'P057',
'opportunity:331',
'Manica',
'2026-12',
'SYNTHETIC QA G6B',
'0.00',
'12(1)(j/l)',
'campo11',
])
assert.ok(report.includes(token), token);
assert.equal(
next.books['opportunity:329'].result.periods[0].fields['11'],
null,
);
assert.equal(
next.books['opportunity:329'].result.periods[0].fields['17'],
null,
);
if (process.env.IVA_G6B_CALCULATED)
fs.writeFileSync(process.env.IVA_G6B_CALCULATED, JSON.stringify(d));
});