194 lines
7.9 KiB
JavaScript
194 lines
7.9 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import {
|
|
recordSales,
|
|
saveSalesBook,
|
|
salesBook,
|
|
} from '../../resources/js/lib/iva-operations.ts';
|
|
import {
|
|
recordAcquisitions,
|
|
saveAcquisitionBook,
|
|
acquisitionBook,
|
|
acquisitionCurrent,
|
|
} from '../../resources/js/lib/iva-acquisitions.ts';
|
|
import '../../resources/js/lib/iva-acquisition-right.ts';
|
|
import '../../resources/js/lib/iva-acquisition-bc.ts';
|
|
import {
|
|
beverageRestitutionSources,
|
|
recordBeverageRestitution,
|
|
saveBeverageRestitutionBook,
|
|
beverageRestitutionCurrent,
|
|
beverageRestitutionReportRows,
|
|
} from '../../resources/js/lib/iva-beverage-restitution.ts';
|
|
import { fixture } from './fixtures/iva-beverage-fixture.mjs';
|
|
const n = (v) => v && `${v.numerator}/${v.denominator}`;
|
|
void test('E reuses classified supply and invoice;VAT16 is not deducted,12recognised/7received/5waiting remain distinct', () => {
|
|
const { d, b, acq } = fixture();
|
|
assert.equal(acq.result.rows[0].deductible, '0.00');
|
|
assert.ok(b.rows[0].source);
|
|
const r = recordBeverageRestitution(d, b).result.rows[0];
|
|
assert.equal(r.status, 'determined', r.reason);
|
|
assert.equal(n(r.requested), '16/1');
|
|
assert.equal(n(r.approved), '12/1');
|
|
assert.equal(n(r.received), '7/1');
|
|
assert.equal(n(r.awaitingReceipt), '5/1');
|
|
assert.equal(n(r.notGranted), '4/1');
|
|
assert.equal(b.rows[0].source.operationId, 'beverage-supply');
|
|
assert.equal(b.rows[0].source.documentLine, '1-bebidas');
|
|
});
|
|
void test('c/d/h retain their distinct conditions;warships,coastal fishing,ordinary beverages and changedL1 are not inherited', () => {
|
|
for (const t of [
|
|
'onboard_seagoing_ship',
|
|
'onboard_rescue_coastal_ship',
|
|
'onboard_international_aircraft',
|
|
])
|
|
assert.ok(fixture(t).b.rows[0].source, t);
|
|
assert.equal(fixture('onboard_departing_warship').b.rows[0].source, null);
|
|
const { d } = fixture('onboard_rescue_coastal_ship'),
|
|
a = acquisitionBook(d);
|
|
a.rows[0].bc.facts.notCoastalFishing = 'no';
|
|
d.modelo_a_snapshot = saveAcquisitionBook(d, recordAcquisitions(d, a));
|
|
assert.deepEqual(beverageRestitutionSources(d), []);
|
|
const f = fixture();
|
|
const ops = salesBook(f.d);
|
|
ops.rows[0].evidence = 'changed';
|
|
f.d.modelo_a_snapshot = saveSalesBook(f.d, recordSales(f.d, ops));
|
|
assert.equal(
|
|
recordBeverageRestitution(f.d, f.b).result.rows[0].requested,
|
|
null,
|
|
);
|
|
});
|
|
void test('a projected alternative may change its route explicitly;effective past deduction cannot be erased to obtain restitution', () => {
|
|
const { d, b } = fixture(),
|
|
a = acquisitionBook(d);
|
|
a.rows[0].origin = 'effective';
|
|
a.rows[0].bc.beveragePath = 'deduction';
|
|
a.rows[0].bc.facts.onlyDeduction = 'yes';
|
|
let actual = recordAcquisitions(d, a);
|
|
assert.equal(actual.result.rows[0].deductible, '16.00');
|
|
d.modelo_a_snapshot = saveAcquisitionBook(d, actual);
|
|
actual.rows[0].bc.beveragePath = 'refund';
|
|
actual = recordAcquisitions(d, actual);
|
|
d.modelo_a_snapshot = saveAcquisitionBook(d, actual);
|
|
b.rows[0].source = beverageRestitutionSources(d)[0];
|
|
assert.equal(
|
|
recordBeverageRestitution(d, b).result.rows[0].requested,
|
|
null,
|
|
);
|
|
assert.equal(actual.history.at(-1).rows[0].deductible, '16.00');
|
|
});
|
|
void test('an exact historical deduction is not zero merely because its presentation rounds tozero', () => {
|
|
const { d, b } = fixture(),
|
|
a = acquisitionBook(d);
|
|
a.rows[0].origin = 'effective';
|
|
const actual = recordAcquisitions(d, a),
|
|
prior = structuredClone(actual.result);
|
|
prior.rows[0].deductible = '0.00';
|
|
prior.rows[0].deductibleExact = {
|
|
numerator: '1',
|
|
denominator: '100000000',
|
|
};
|
|
actual.history = [prior];
|
|
d.modelo_a_snapshot = saveAcquisitionBook(d, actual);
|
|
b.rows[0].source = beverageRestitutionSources(d)[0];
|
|
assert.equal(
|
|
recordBeverageRestitution(d, b).result.rows[0].requested,
|
|
null,
|
|
);
|
|
});
|
|
void test('submitted/decided restitution blocks deduction of the same parcel even after removing current preparation', () => {
|
|
const { d, b } = fixture();
|
|
let book = recordBeverageRestitution(d, b);
|
|
d.modelo_a_snapshot = saveBeverageRestitutionBook(d, book);
|
|
assert.ok(acquisitionCurrent(d, acquisitionBook(d)));
|
|
let a = acquisitionBook(d);
|
|
a.rows[0].bc.beveragePath = 'deduction';
|
|
a.rows[0].bc.facts.onlyDeduction = 'yes';
|
|
let result = recordAcquisitions(d, a);
|
|
assert.equal(result.result.rows[0].deductible, null);
|
|
assert.match(result.result.rows[0].reason, /Parcela ligada/);
|
|
book = recordBeverageRestitution(d, { ...book, rows: [] });
|
|
d.modelo_a_snapshot = saveBeverageRestitutionBook(d, book);
|
|
result = recordAcquisitions(d, a);
|
|
assert.equal(result.result.rows[0].deductible, null);
|
|
});
|
|
void test('duplicate requests/receipts and receipts beyond decision do not create another benefit or cash', () => {
|
|
const { d, b } = fixture();
|
|
const dup = structuredClone(b);
|
|
dup.rows.push({ ...structuredClone(dup.rows[0]), id: 'copy' });
|
|
assert.ok(
|
|
recordBeverageRestitution(d, dup).result.rows.every(
|
|
(r) => r.requested === null,
|
|
),
|
|
);
|
|
const rec = structuredClone(b);
|
|
rec.rows[0].receipts.push({ ...rec.rows[0].receipts[0], id: 'copy' });
|
|
assert.equal(
|
|
recordBeverageRestitution(d, rec).result.rows[0].received,
|
|
null,
|
|
);
|
|
rec.rows[0].receipts = [{ ...rec.rows[0].receipts[0], amount: '13' }];
|
|
assert.equal(
|
|
recordBeverageRestitution(d, rec).result.rows[0].status,
|
|
'indeterminate',
|
|
);
|
|
});
|
|
void test('preparation,pending decision and missing facts never imply exemption,approval or receipt', () => {
|
|
const { d, b } = fixture();
|
|
for (const patch of [
|
|
{ entityRef: '' },
|
|
{ exclusive: '' },
|
|
{ requestDate: '' },
|
|
{ decisionReference: '' },
|
|
{ approvedAmount: '' },
|
|
{ stage: 'preparation' },
|
|
]) {
|
|
const v = structuredClone(b);
|
|
Object.assign(v.rows[0], patch);
|
|
assert.equal(
|
|
recordBeverageRestitution(d, v).result.rows[0].status,
|
|
'indeterminate',
|
|
);
|
|
}
|
|
Object.assign(b.rows[0], {
|
|
stage: 'preparation',
|
|
decision: 'pending',
|
|
receipts: [],
|
|
});
|
|
const r = recordBeverageRestitution(d, b).result.rows[0];
|
|
assert.equal(r.status, 'determined');
|
|
assert.equal(r.approved, null);
|
|
assert.equal(r.received, null);
|
|
});
|
|
void test('all prior maps and original documents survive save/recovery;report uses frozen inputs and recalculation appends history', () => {
|
|
const { d, b } = fixture(),
|
|
before = JSON.parse(d.modelo_a_snapshot);
|
|
let book = recordBeverageRestitution(d, b);
|
|
d.modelo_a_snapshot = saveBeverageRestitutionBook(d, book);
|
|
for (const [k, v] of Object.entries(before))
|
|
assert.deepEqual(JSON.parse(d.modelo_a_snapshot)[k], v, k);
|
|
assert.ok(beverageRestitutionCurrent(d, book));
|
|
book.rows[0].requestReference = 'deliberate edit';
|
|
assert.equal(beverageRestitutionCurrent(d, book), false);
|
|
d.modelo_a_snapshot = saveBeverageRestitutionBook(d, book);
|
|
assert.doesNotMatch(
|
|
beverageRestitutionReportRows(d)
|
|
.map((r) => r.join(' '))
|
|
.join(' '),
|
|
/deliberate edit/,
|
|
);
|
|
const old = structuredClone(book.result);
|
|
book = recordBeverageRestitution(d, book);
|
|
assert.deepEqual(book.history.at(-1), old);
|
|
});
|
|
void test('export synthetic source-linkedE for guardedAPI and real component proof', () => {
|
|
const { d, b } = fixture();
|
|
let book = recordBeverageRestitution(d, b, '2026-10-25T14:00:00Z');
|
|
book = recordBeverageRestitution(d, book, '2026-10-25T14:01:00Z');
|
|
d.modelo_a_snapshot = saveBeverageRestitutionBook(d, book);
|
|
assert.ok(beverageRestitutionCurrent(d, book));
|
|
if (process.env.IVA_L3E_CALCULATED)
|
|
fs.writeFileSync(process.env.IVA_L3E_CALCULATED, JSON.stringify(d));
|
|
});
|