149 lines
4.8 KiB
JavaScript
149 lines
4.8 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import {
|
|
monthlyProjectedPurchaseOrders,
|
|
serializeBusinessPlanSnapshot,
|
|
} from '../../resources/js/lib/business-financial-plan.ts';
|
|
import {
|
|
modeloAComponentRows,
|
|
modeloAPurchaseReferences,
|
|
} from '../../resources/js/lib/iva-modelo-a.ts';
|
|
import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts';
|
|
|
|
void test('purchase references use active existing purchase schedules, not cost of sales or cash payments', () => {
|
|
const plan = {
|
|
periods: 3,
|
|
products: [
|
|
{
|
|
label: 'A',
|
|
monthlyUnits: '8',
|
|
unitPrice: '30',
|
|
unitVariableCost: '12',
|
|
productInventoryPurchasesByPeriod: [
|
|
{ amount: '100', leadMonths: 2 },
|
|
{ amount: '0', leadMonths: 0 },
|
|
{ amount: '', leadMonths: 1 },
|
|
],
|
|
},
|
|
],
|
|
useProductInventorySchedule: true,
|
|
monthlyInventoryPurchases: '900',
|
|
monthlyVariableCostPayments: '700',
|
|
useInventoryPurchaseSchedule: true,
|
|
inventoryPurchaseSchedule: [
|
|
{ amount: '400', leadMonths: 0 },
|
|
{ amount: '500', leadMonths: 0 },
|
|
{ amount: '600', leadMonths: 0 },
|
|
],
|
|
};
|
|
assert.deepEqual(monthlyProjectedPurchaseOrders(plan), [
|
|
'100.00',
|
|
'0.00',
|
|
null,
|
|
]);
|
|
plan.useProductInventorySchedule = false;
|
|
assert.deepEqual(monthlyProjectedPurchaseOrders(plan), [
|
|
'400.00',
|
|
'500.00',
|
|
'600.00',
|
|
]);
|
|
plan.useInventoryPurchaseSchedule = false;
|
|
assert.deepEqual(monthlyProjectedPurchaseOrders(plan), [
|
|
'900.00',
|
|
'900.00',
|
|
'900.00',
|
|
]);
|
|
});
|
|
|
|
void test('missing and zero purchase amounts are preserved without manufacturing net VAT or deduction', () => {
|
|
const plan = {
|
|
currency: 'MZN',
|
|
periods: 2,
|
|
depreciationLifeMonths: 60,
|
|
products: [
|
|
{
|
|
label: 'A',
|
|
monthlyUnits: '1',
|
|
unitPrice: '10',
|
|
unitVariableCost: '0',
|
|
},
|
|
],
|
|
useInventoryPurchaseSchedule: true,
|
|
inventoryPurchaseSchedule: [
|
|
{ amount: '0', leadMonths: 0 },
|
|
{ amount: '', leadMonths: 0 },
|
|
],
|
|
};
|
|
for (const key of [
|
|
'openingCash',
|
|
'monthlyCollections',
|
|
'monthlyVariableCostPayments',
|
|
'monthlyOperatingExpenses',
|
|
'monthlyOperatingPayments',
|
|
'monthlyPayrollExpense',
|
|
'monthlyPayrollPayments',
|
|
'assetInvestment',
|
|
'inventory',
|
|
'receivables',
|
|
'payables',
|
|
'equity',
|
|
'shareholderLoans',
|
|
'bankLoanProceeds',
|
|
'grants',
|
|
'assetDepreciation',
|
|
'monthlyInterestExpense',
|
|
'monthlyInterestPayment',
|
|
'monthlyPrincipalRepayment',
|
|
])
|
|
plan[key] = '0';
|
|
const rows = modeloAPurchaseReferences({
|
|
business_plan_snapshot: serializeBusinessPlanSnapshot(plan),
|
|
});
|
|
assert.equal(rows[0].declared, '0.00');
|
|
assert.equal(rows[1].declared, null);
|
|
for (const row of rows)
|
|
for (const field of ['net', 'vat', 'gross', 'deductible'])
|
|
assert.equal(row[field], null);
|
|
assert.deepEqual(modeloAPurchaseReferences({}), []);
|
|
assert.throws(
|
|
() => modeloAPurchaseReferences({ business_plan_snapshot: 'broken' }),
|
|
/preservado/,
|
|
);
|
|
const report = createProjectDossierReport(
|
|
{
|
|
currency: 'MZN',
|
|
business_plan_snapshot: serializeBusinessPlanSnapshot(plan),
|
|
monthly_iva_snapshot: '{}',
|
|
},
|
|
{ selectedSections: new Set(['finance']) },
|
|
);
|
|
const text = JSON.stringify(report);
|
|
assert.match(text, /Compras\/encomendas/);
|
|
assert.match(text, /0\.00/);
|
|
assert.match(text, /base\/IVA incluído por classificar/);
|
|
assert.match(text, /IVA suportado e dedutível indeterminados/);
|
|
});
|
|
|
|
void test('Modelo A report adds partial coverage without recalculating or rewriting accepted server history', () => {
|
|
const snapshot = {
|
|
monthly_projection: {
|
|
rows: [
|
|
{ date: '2026-01-01', net_sales: '1000.03', vat: '160.0048' },
|
|
],
|
|
},
|
|
result: { value: '160.0048' },
|
|
};
|
|
const before = JSON.stringify(snapshot);
|
|
const rows = modeloAComponentRows(snapshot);
|
|
assert.equal(JSON.stringify(snapshot), before);
|
|
assert.match(rows.map((row) => row.join(' ')).join('\n'), /Indeterminado/);
|
|
assert.match(
|
|
rows.map((row) => row.join(' ')).join('\n'),
|
|
/não é imposto final/,
|
|
);
|
|
assert.deepEqual(
|
|
modeloAComponentRows({ scenario_kind: 'custom_planning' }),
|
|
[],
|
|
);
|
|
});
|