258 lines
8.9 KiB
JavaScript
258 lines
8.9 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,
|
|
importRuleSource,
|
|
} from '../../resources/js/lib/iva-import-exemptions.ts';
|
|
import {
|
|
internationalShipEligibility,
|
|
internationalAircraftEligibility,
|
|
internationalAssetTreatments,
|
|
} from '../../resources/js/lib/iva-international-assets.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-g6b-inputs.json', import.meta.url),
|
|
'utf8',
|
|
),
|
|
);
|
|
const ids = [
|
|
'eligible_ship_import',
|
|
'ship_operation_object_import',
|
|
'eligible_aircraft_import',
|
|
'aircraft_operation_object_import',
|
|
];
|
|
const row = (treatment = 'eligible_ship_import') => ({
|
|
...newImportExemption('g6c-' + treatment, 'MZN'),
|
|
treatment,
|
|
description: 'SYNTHETIC QA ' + treatment,
|
|
period: '2026-12',
|
|
declaredValue: '4000',
|
|
importer: 'SYNTHETIC QA operador',
|
|
documentRef: 'SYNTHETIC QA G6C ' + treatment,
|
|
documentDate: '2026-11-13',
|
|
evidence:
|
|
'SYNTHETIC QA meio identificado, utilização elegível e ligação do bem importado expressamente assumidas; não é documento real',
|
|
conditions: Object.fromEntries(
|
|
importExemptionRules
|
|
.find((r) => r.id === treatment)
|
|
.conditions.map(([key]) => [key, 'yes']),
|
|
),
|
|
});
|
|
const draft = () => ({
|
|
...structuredClone(frozen),
|
|
context_opportunity: 'opportunity:332',
|
|
project_title: 'SYNTHETIC QA — G6C / Embarcações e aviões',
|
|
});
|
|
|
|
void test('P053/P054 four treatments require every own condition;unknown and false never become exempt zero or ordinary tax', () => {
|
|
for (const id of ids) {
|
|
const input = row(id),
|
|
rule = importExemptionRules.find((r) => r.id === id);
|
|
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 [
|
|
{ period: '2025-12' },
|
|
{ currency: 'USD' },
|
|
{ evidence: '' },
|
|
{ documentRef: '' },
|
|
{ documentDate: '2026-02-30' },
|
|
])
|
|
assert.equal(
|
|
evaluateImportExemption({ ...input, ...patch }, 'MZN')
|
|
.importVat,
|
|
null,
|
|
);
|
|
assert.deepEqual(input, row(id));
|
|
}
|
|
assert.equal(
|
|
new Set(
|
|
ids.map(
|
|
(id) => importExemptionRules.find((r) => r.id === id).branch,
|
|
),
|
|
).size,
|
|
2,
|
|
);
|
|
});
|
|
|
|
void test('import definitions reuse accepted vessel/aircraft eligibility;principal asset does not substitute for linked object', () => {
|
|
assert.equal(
|
|
importExemptionRules.find((r) => r.id === ids[0]).conditions[0][1],
|
|
internationalShipEligibility,
|
|
);
|
|
assert.equal(
|
|
importExemptionRules.find((r) => r.id === ids[2]).conditions[0][1],
|
|
internationalAircraftEligibility,
|
|
);
|
|
assert.ok(
|
|
internationalAssetTreatments
|
|
.find((r) => r.id === 'international_ship_operations')
|
|
.conditions.includes(internationalShipEligibility),
|
|
);
|
|
assert.ok(
|
|
internationalAssetTreatments
|
|
.find((r) => r.id === 'international_aircraft_operations')
|
|
.conditions.includes(internationalAircraftEligibility),
|
|
);
|
|
assert.match(
|
|
internationalAircraftEligibility,
|
|
/principalmente.*internacional/,
|
|
);
|
|
assert.match(internationalAircraftEligibility, /voo internacional isolado/);
|
|
const ship = row();
|
|
const object = { ...ship, treatment: 'ship_operation_object_import' };
|
|
assert.equal(
|
|
evaluateImportExemption(object, 'MZN').status,
|
|
'indeterminate',
|
|
);
|
|
assert.equal(object.conditions.importedShip, 'yes');
|
|
assert.equal(object.documentRef, ship.documentRef);
|
|
assert.equal(
|
|
evaluateImportExemption(
|
|
{
|
|
...object,
|
|
conditions: { ...object.conditions, shipObjectLink: 'yes' },
|
|
},
|
|
'MZN',
|
|
).status,
|
|
'exempt',
|
|
);
|
|
assert.equal(
|
|
evaluateImportExemption(
|
|
{
|
|
...row('aircraft_operation_object_import'),
|
|
conditions: {
|
|
eligibleAircraft: 'yes',
|
|
importedAircraft: 'yes',
|
|
},
|
|
},
|
|
'MZN',
|
|
).status,
|
|
'indeterminate',
|
|
);
|
|
assert.match(importRuleSource(ids[1]), /12\(1\)\(h\/i\)/);
|
|
assert.match(importRuleSource(ids[3]), /13\(1\)\(f\/g\)/);
|
|
});
|
|
|
|
void test('classification archives unknown and failed versions;edits preserve earlier result and mark it historical', () => {
|
|
const d = draft(),
|
|
input = row();
|
|
let book = recordImportExemptions(d, {
|
|
rows: [{ ...input, conditions: { eligibleShip: 'yes' } }],
|
|
});
|
|
assert.equal(book.result.rows[0].status, 'indeterminate');
|
|
book = recordImportExemptions(d, {
|
|
...book,
|
|
rows: [
|
|
{
|
|
...input,
|
|
conditions: { ...input.conditions, eligibleShip: 'no' },
|
|
},
|
|
],
|
|
});
|
|
assert.equal(book.result.rows[0].status, 'not_applicable');
|
|
book = recordImportExemptions(d, { ...book, rows: ids.map(row) });
|
|
assert.equal(book.history.length, 2);
|
|
assert.equal(book.history[0].rows[0].importVat, null);
|
|
assert.equal(book.history[1].rows[0].importVat, null);
|
|
assert.ok(importExemptionCurrent(d, book));
|
|
for (const patch of [
|
|
{ currency: 'USD' },
|
|
{ context_opportunity: 'opportunity:331' },
|
|
{ selection_labels: { province_id: 'Maputo' } },
|
|
])
|
|
assert.ok(!importExemptionCurrent({ ...d, ...patch }, book));
|
|
assert.ok(
|
|
!importExemptionCurrent(d, {
|
|
...book,
|
|
rows: [{ ...input, declaredValue: '4100' }],
|
|
}),
|
|
);
|
|
});
|
|
|
|
void test('save/recover/report preserve23acceptedbooks current;only new asset treatments add version and do not populate field11', () => {
|
|
const d = draft(),
|
|
prior = JSON.parse(frozen.modelo_a_snapshot);
|
|
let book = recordImportExemptions(d, {
|
|
rows: ids.map((id) => ({ ...row(id), conditions: {} })),
|
|
});
|
|
book = recordImportExemptions(d, { ...book, rows: ids.map(row) });
|
|
d.modelo_a_snapshot = saveImportExemptionBook(d, book);
|
|
assert.deepEqual(importExemptionBook(JSON.parse(JSON.stringify(d))), book);
|
|
assert.match(book.result.sourceKey, /import-assets\/1/);
|
|
assert.doesNotMatch(book.result.sourceKey, /beneficiaryVersion/);
|
|
assert.match(book.result.source, /12\(1\)\(h\/i\)/);
|
|
const next = JSON.parse(d.modelo_a_snapshot);
|
|
assert.deepEqual(next.salesOperations, prior.salesOperations);
|
|
assert.deepEqual(next.books, prior.books);
|
|
for (const [scope, imports] of Object.entries(prior.importExemptions)) {
|
|
assert.deepEqual(next.importExemptions[scope], imports);
|
|
assert.ok(
|
|
importExemptionCurrent(
|
|
{ ...d, context_opportunity: scope },
|
|
imports,
|
|
),
|
|
);
|
|
}
|
|
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.equal(
|
|
next.books['opportunity:329'].result.periods[0].fields['11'],
|
|
null,
|
|
);
|
|
assert.equal(
|
|
next.books['opportunity:329'].result.periods[0].fields['17'],
|
|
null,
|
|
);
|
|
const report = JSON.stringify(
|
|
createProjectDossierReport(d, {
|
|
selectedSections: new Set(['finance']),
|
|
version: 'QA G6C',
|
|
}),
|
|
);
|
|
for (const token of [
|
|
'P053',
|
|
'P054',
|
|
'opportunity:332',
|
|
'Manica',
|
|
'2026-12',
|
|
'SYNTHETIC QA G6C',
|
|
'0.00',
|
|
'12(1)(h/i)',
|
|
'campo11',
|
|
...ids,
|
|
])
|
|
assert.ok(report.includes(token), token);
|
|
if (process.env.IVA_G6C_CALCULATED)
|
|
fs.writeFileSync(process.env.IVA_G6C_CALCULATED, JSON.stringify(d));
|
|
});
|