import { acquisitionScope, readAcquisitionStore } from './iva-acquisitions.ts'; import { operationTreatments, newSalesOperation, evaluateSalesOperation, salesBook, type SalesOperation, } from './iva-operations.ts'; export const objectiveImportVersion = 'objective-imports/1'; export const objectiveImportSource = 'CIVA12(1)a,Lei10/2025,BR248-I/suplemento,PDF12/p2180(12),efeitos01/01/2026:importações definitivas de bens cuja transmissão interna beneficie de isenção objectiva;enumeração exemplificativa. Correspondências9(1)b/c/e/f/g,9(9)b,9(10),9(11),9(12)g/h/i;catálogo interno e anexosLei22/2022 já conferidos. Sem dedução/campo11,direitos ou alteração dos livros internos.'; const fixed = [ 'health_assistive', 'human_materials', 'mosquito_nets', 'medicines', 'pharma_manufacturing_inputs', 'cultural_publications', 'official_military_supplies', 'industrial_feed_inputs', 'annexI_goods', 'veterinary_goods', ]; export const objectiveImportTreatments = operationTreatments.filter( (t) => fixed.includes(t.id) || t.id.startsWith('listed_'), ); type Choice = '' | 'yes' | 'no'; export type ObjectiveImportRow = { id: string; description: string; period: string; currency: string; origin: 'projected' | 'effective'; importer: string; documentRef: string; documentDate: string; scope: string; evidence: string; definitive: Choice; goods: Choice; sameGoods: Choice; internalApplicable: Choice; reference: SalesOperation; reusedFrom: string; }; type Line = { id: string; status: 'exempt' | 'not_applicable' | 'indeterminate'; importVat: string | null; deduction: null; source: string; reason: string; }; export type ObjectiveImportCalculation = { version: string; revision: number; calculatedAt: string; opportunity: string; sourceKey: string; source: string; inputs: ObjectiveImportRow[]; rows: Line[]; }; export type ObjectiveImportBook = { rows: ObjectiveImportRow[]; result?: ObjectiveImportCalculation; history?: ObjectiveImportCalculation[]; }; type Store = ReturnType & { objectiveImports?: Record; }; export function newObjectiveImport( id: string, currency: string, ): ObjectiveImportRow { return { id, description: '', period: '', currency, origin: 'projected', importer: '', documentRef: '', documentDate: '', scope: '', evidence: '', definitive: '', goods: '', sameGoods: '', internalApplicable: '', reference: newSalesOperation(id + '-reference', '', currency), reusedFrom: '', }; } export function objectiveImportSources( draft: Record, ): SalesOperation[] { return salesBook(draft).rows.filter((r) => objectiveImportTreatments.some((t) => t.id === r.treatment), ); } export function reuseObjectiveImport( row: ObjectiveImportRow, source: SalesOperation, ): ObjectiveImportRow { const reference = { ...row.reference }; // This explicit action fills missing values only; confirmations belong to this import. if (!reference.treatment || reference.treatment === 'other') reference.treatment = source.treatment; if (reference.treatment === source.treatment) { reference.annexIItem ||= source.annexIItem; reference.pharmaAnnexItem ||= source.pharmaAnnexItem; reference.annexIOnly ??= source.annexIOnly; } return { ...row, description: row.description || source.description, period: row.period || source.period, evidence: row.evidence || source.evidence, reference, reusedFrom: source.id, }; } function readStore(draft: Record): Store { const s = readAcquisitionStore(draft.modelo_a_snapshot) as Store; const books = s.objectiveImports; if ( books !== undefined && (!books || typeof books !== 'object' || Array.isArray(books)) ) throw new Error( 'Importações objectivas não recuperáveis;originais preservados.', ); const fields = Object.keys(newObjectiveImport('', 'MZN')).filter( (k) => k !== 'reference', ); for (const b of Object.values(books ?? {})) if ( !b || !Array.isArray(b.rows) || (b.history !== undefined && !Array.isArray(b.history)) || b.rows.some( (r) => !r || fields.some( (k) => typeof r[k as keyof ObjectiveImportRow] !== 'string', ) || !r.reference || typeof r.reference.treatment !== 'string' || !Array.isArray(r.reference.confirmed), ) ) throw new Error( 'Linhas de importação objectiva não recuperáveis;sem substituição por lista vazia.', ); return s; } export function objectiveImportBook( draft: Record, ): ObjectiveImportBook { return ( readStore(draft).objectiveImports?.[acquisitionScope(draft)] ?? { rows: [], } ); } export function saveObjectiveImportBook( draft: Record, book: ObjectiveImportBook, ): string { const s = readStore(draft), encoded = JSON.stringify({ ...s, objectiveImports: { ...s.objectiveImports, [acquisitionScope(draft)]: book, }, }); readStore({ ...draft, modelo_a_snapshot: encoded }); return encoded; } function date(value: string): boolean { const d = new Date(value + 'T00:00:00Z'); return ( /^\d{4}-\d{2}-\d{2}$/.test(value) && Number.isFinite(d.getTime()) && d.toISOString().slice(0, 10) === value ); } export function evaluateObjectiveImport( row: ObjectiveImportRow, currency: unknown, ): Line { const rule = objectiveImportTreatments.find( (t) => t.id === row.reference.treatment, ), result: Line = { id: row.id, status: 'indeterminate', importVat: null, deduction: null, source: objectiveImportSource + (rule ? ';' + rule.source : ''), reason: '', }; const stop = ( reason: string, status: Line['status'] = 'indeterminate', ) => ({ ...result, status, reason }); if ( currency !== 'MZN' || row.currency !== currency || !/^2026-(0[1-9]|1[0-2])$/.test(row.period) ) return stop( 'Indique período2026 e moedaMZN coerente com o projecto;sem conversão presumida.', ); if ( !['projected', 'effective'].includes(row.origin) || ![ row.description, row.importer, row.documentRef, row.scope, row.evidence, ].every((v) => !!v.trim()) || !date(row.documentDate) ) return stop( 'Identifique bens,importador,documento/previsão,data,âmbito e factos/pressupostos.Reutilize os elementos disponíveis.', ); if ( [row.definitive, row.goods, row.sameGoods, row.internalApplicable].some( (v) => v === 'no', ) ) return stop( 'Este fundamento12(1)a não se aplica aos factos indicados;IVA fora deste fundamento permanece por enquadrar,sem taxa presumida.', 'not_applicable', ); if ( [row.definitive, row.goods, row.sameGoods, row.internalApplicable].some( (v) => v !== 'yes', ) ) return stop( 'Confirme importação definitiva de bens,a correspondência dos mesmos bens e a aplicabilidade da isenção objectiva interna.Desconhecido não significa IVA zero.', ); if (!rule) return stop( 'Escolha correspondência interna documentada.A lista implementada cobre as remissões expressas12(1)a;é exemplificativa e não declara excluídos outros fundamentos.Não basta descrição,isenção de serviços,exportação,taxa reduzida ou benefício terminado.', ); // Evaluate the legal hypothetical domestic transmission, never create a domestic sale or use its amount/totals. const reference = { ...row.reference, id: row.id + '-reference', description: row.description, period: row.period, sourcePeriod: row.period, sourceCurrency: row.currency, sourceAmount: null, establishment: row.importer, amount: '0', basis: 'net' as const, evidence: row.evidence, }; const v = evaluateSalesOperation(reference, row.currency); result.source = objectiveImportSource + ';' + v.source; if (v.status !== 'exempt') return stop( 'Correspondência interna ainda não demonstrada: ' + v.reason, ); return { ...result, status: 'exempt', importVat: '0.00', reason: `Isenção12(1)a por correspondência a${rule.article},nas condições ${row.origin === 'projected' ? 'expressamente assumidas da projecção' : 'efectivas declaradas'}. IVA na importação:0.00MZN. Hipótese de transmissão interna,não venda criada nem montante somado.Sem direitos,base aduaneira,dedução/campo11 ou concessão administrativa automática.`, }; } function key( draft: Record, book: ObjectiveImportBook, ): string { return JSON.stringify({ version: objectiveImportVersion, catalog: objectiveImportTreatments, scope: acquisitionScope(draft), currency: draft.currency, location: draft.selection_labels ?? {}, rows: book.rows, }); } export function objectiveImportCurrent( draft: Record, book: ObjectiveImportBook, ): boolean { return !!book.result && book.result.sourceKey === key(draft, book); } export function recordObjectiveImports( draft: Record, book: ObjectiveImportBook, ): ObjectiveImportBook { if ( !book.rows.length || new Set(book.rows.map((r) => r.id)).size !== book.rows.length ) throw new Error( 'Indique linhas com identidades distintas;originais conservados.', ); const result: ObjectiveImportCalculation = { version: objectiveImportVersion, revision: (book.result?.revision ?? 0) + 1, calculatedAt: new Date().toISOString(), opportunity: acquisitionScope(draft), sourceKey: key(draft, book), source: objectiveImportSource, inputs: structuredClone(book.rows), rows: book.rows.map((r) => evaluateObjectiveImport(r, draft.currency)), }; const next = { ...book, result, history: [ ...(book.history ?? []), ...(book.result ? [book.result] : []), ], }; saveObjectiveImportBook(draft, next); return next; } export function objectiveImportReportRows( draft: Record, ): Array<[string, string, string, string]> { try { const b = objectiveImportBook(draft), r = b.result; if (!r) return []; return r.inputs.map((row, i) => [ 'IVA mensal', `P046 — ${row.period} — ${row.id}`, `${row.description};${r.rows[i].reason};IVA importação:${r.rows[i].importVat ?? 'Indeterminado'};dedução:Não apurada`, `${r.opportunity};${objectiveImportCurrent(draft, b) ? 'Resultado actual' : 'Entradas alteradas;resultado histórico conservado'};versão${r.revision};${r.calculatedAt};${row.origin};importador${row.importer};documento${row.documentRef},${row.documentDate};âmbito${row.scope};factos${row.evidence};reutilização${row.reusedFrom || 'Introdução directa'};correspondência${row.reference.treatment};condições internas confirmadas${row.reference.confirmed.join(',')}${row.reference.treatment === 'annexI_goods' ? `;AnexoI${row.reference.annexIItem ?? ''},apenasAnexoI${String(row.reference.annexIOnly ?? 'Por esclarecer')}` : row.reference.treatment === 'pharma_manufacturing_inputs' ? `;AnexoIII${row.reference.pharmaAnnexItem ?? ''}` : ''};${r.rows[i].source};sem alteração dos livros internos,ModeloA,campo11 ou totais.`, ]); } catch { return [ [ 'IVA mensal', 'P046', 'Dados não recuperáveis', 'Originais preservados;sem classificação por defeito.', ], ]; } }