161 lines
5.6 KiB
JavaScript
161 lines
5.6 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import {
|
|
newOfferPreparation,
|
|
offerPreparationBook,
|
|
saveOfferPreparationBook,
|
|
recordOfferPreparations,
|
|
offerReusableData,
|
|
reuseOfferData,
|
|
offerPreparationReportRows,
|
|
} from '../../resources/js/lib/iva-offer-preparations.ts';
|
|
import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts';
|
|
const frozen = JSON.parse(
|
|
fs.readFileSync(
|
|
new URL('./fixtures/iva-g5c-inputs.json', import.meta.url),
|
|
'utf8',
|
|
),
|
|
);
|
|
const draft = () => structuredClone(frozen);
|
|
void test('incomplete P084/P085 drafts save without authorizations,zeroVAT or a benefit result;prior26books remain exact', () => {
|
|
const d = draft(),
|
|
before = JSON.parse(d.modelo_a_snapshot),
|
|
rows = ['P084', 'P085'].map((branch) =>
|
|
newOfferPreparation('gift-' + branch, branch, 'MZN'),
|
|
);
|
|
d.modelo_a_snapshot = saveOfferPreparationBook(d, { rows });
|
|
const next = JSON.parse(d.modelo_a_snapshot);
|
|
for (const key of Object.keys(before))
|
|
assert.deepEqual(next[key], before[key]);
|
|
assert.deepEqual(
|
|
offerPreparationBook(JSON.parse(JSON.stringify(d))).rows,
|
|
rows,
|
|
);
|
|
assert.equal(rows[1].operation, 'acquisition');
|
|
assert.equal(
|
|
'result' in next.offerPreparations[d.context_opportunity],
|
|
false,
|
|
);
|
|
for (const row of offerPreparationReportRows(d))
|
|
assert.match(row[2], /bénéfice|benefício não aplicado/);
|
|
assert.equal(
|
|
next.books['opportunity:329'].result.periods[0].fields['11'],
|
|
null,
|
|
);
|
|
});
|
|
void test('explicit reuse fills only empty fields,same opportunity;currency mismatch and P085 import rejected without mutation', () => {
|
|
const d = draft(),
|
|
sources = offerReusableData(d);
|
|
assert.equal(sources.length, 6);
|
|
const source = sources.find((x) => x.operation === 'import'),
|
|
original = structuredClone(source),
|
|
row = {
|
|
...newOfferPreparation('gift', 'P084', 'MZN'),
|
|
description: 'Edição deliberada',
|
|
beneficiary: 'Instituição QA',
|
|
};
|
|
const next = reuseOfferData(row, source);
|
|
assert.equal(next.description, row.description);
|
|
assert.equal(next.beneficiary, row.beneficiary);
|
|
assert.equal(next.documentRef, source.values.documentRef);
|
|
assert.equal(next.operation, 'import');
|
|
assert.equal(next.reusedFrom.key, source.key);
|
|
assert.deepEqual(source, original);
|
|
assert.equal(row.documentRef, '');
|
|
assert.throws(
|
|
() => reuseOfferData(newOfferPreparation('g', 'P085', 'MZN'), source),
|
|
/P085/,
|
|
);
|
|
assert.throws(
|
|
() => reuseOfferData({ ...row, currency: 'USD' }, source),
|
|
/Moeda/,
|
|
);
|
|
assert.equal(
|
|
offerReusableData({
|
|
...d,
|
|
context_opportunity: 'opportunity:does-not-exist',
|
|
}).length,
|
|
0,
|
|
);
|
|
});
|
|
void test('versions preserve deliberate edits and own branch conditions;report from saved/recovered draft does not extend benefit or field11', () => {
|
|
const d = draft();
|
|
let p84 = reuseOfferData(
|
|
newOfferPreparation('gift84', 'P084', 'MZN'),
|
|
offerReusableData(d).find((x) => x.operation === 'import'),
|
|
);
|
|
p84 = {
|
|
...p84,
|
|
beneficiary: 'SYNTHETIC QA instituição',
|
|
nationalInstitution: 'yes',
|
|
publicSocialInstitution: 'yes',
|
|
goodsSuitable: 'yes',
|
|
publicInterestUse: 'yes',
|
|
};
|
|
const p85 = {
|
|
...newOfferPreparation('gift85', 'P085', 'MZN'),
|
|
description: 'SYNTHETIC QA bens para cheias',
|
|
disaster: 'SYNTHETIC QA cheias',
|
|
disasterKind: 'Cheias',
|
|
mitigation: 'yes',
|
|
};
|
|
let book = recordOfferPreparations({ rows: [p84, p85] });
|
|
book = recordOfferPreparations({
|
|
...book,
|
|
rows: [{ ...p84, purpose: 'Edição posterior' }, p85],
|
|
});
|
|
assert.equal(book.history.length, 1);
|
|
assert.equal(book.history[0].rows[0].purpose, '');
|
|
d.modelo_a_snapshot = saveOfferPreparationBook(d, book);
|
|
assert.deepEqual(offerPreparationBook(JSON.parse(JSON.stringify(d))), book);
|
|
const report = JSON.stringify(
|
|
createProjectDossierReport(d, {
|
|
selectedSections: new Set(['finance']),
|
|
version: 'QA drafts',
|
|
}),
|
|
);
|
|
for (const token of [
|
|
'P084',
|
|
'P085',
|
|
'benefício não aplicado',
|
|
'SYNTHETIC QA cheias',
|
|
'Edição posterior',
|
|
'14(2)(a/b)',
|
|
'opportunity:334',
|
|
])
|
|
assert.ok(report.includes(token), token);
|
|
assert.equal(
|
|
offerPreparationBook({ ...d, context_opportunity: 'opportunity:333' })
|
|
.rows.length,
|
|
0,
|
|
);
|
|
if (process.env.IVA_OFFERS_CALCULATED)
|
|
fs.writeFileSync(process.env.IVA_OFFERS_CALCULATED, JSON.stringify(d));
|
|
});
|
|
void test('corrupt draft data cannot be replaced with empty book and P085 never accepts imported operation', () => {
|
|
for (const offerPreparations of [
|
|
[],
|
|
null,
|
|
{ 'opportunity:334': { rows: [{ id: 'broken' }] } },
|
|
]) {
|
|
const d = draft(),
|
|
s = JSON.parse(d.modelo_a_snapshot);
|
|
s.offerPreparations = offerPreparations;
|
|
d.modelo_a_snapshot = JSON.stringify(s);
|
|
assert.throws(() => saveOfferPreparationBook(d, { rows: [] }));
|
|
}
|
|
assert.throws(
|
|
() =>
|
|
saveOfferPreparationBook(draft(), {
|
|
rows: [
|
|
{
|
|
...newOfferPreparation('x', 'P085', 'MZN'),
|
|
operation: 'import',
|
|
},
|
|
],
|
|
}),
|
|
/operação/,
|
|
);
|
|
});
|