import { inputText } from '../lib/input-text.ts'; import { useState } from 'react'; import { fundraisingActivities } from '@/lib/iva-fundraising'; import { pharmaAnnexEntries, pharmaAnnexEntry, pharmaAnnexReference, } from '@/lib/iva-pharma-annex'; import { annexIEntries, annexIEntry, annexIReference } from '@/lib/iva-annex-i'; import { temporaryBenefit, temporaryBenefitNotice, } from '@/lib/iva-temporary-benefits'; import { isExportService } from '@/lib/iva-export-services'; import { isSpecialRegime, specialRegimesFor, specialRegimeIssue, type SpecialRegime, } from '@/lib/iva-special-regimes'; import { isOnboardSupply, supplyCategories, onboardSupplyIssue, type SupplyCategory, } from '@/lib/iva-onboard-supplies'; import { emptyProductionTaxOption, type ProductionTaxOption, } from '@/lib/iva-production-option'; import { referenceExportOperation, continueTemporaryOperation, continueAnnexIOperation, modeloA06Correspondence, newSalesOperation, operationTreatments, recordSales, reuseSales, salesBook, salesCurrent, salesReportRows, saveSalesBook, splitSales, type SalesBook, type SalesOperation, } from '@/lib/iva-operations'; export function SimulationOperations({ draft, onChange, }: { draft: Record; onChange: (field: string, value: string) => void; }) { const [error, setError] = useState(''); const [reuseOption, setReuseOption] = useState<{ rowId: string; sourceId: string; } | null>(null); const [annexSearch, setAnnexSearch] = useState>({}); let book: SalesBook; try { book = salesBook(draft); } catch (cause) { return

{String(cause)}

; } const run = (action: () => void) => { try { action(); setError(''); } catch (cause) { setError(cause instanceof Error ? cause.message : String(cause)); } }; const save = (next: SalesBook) => onChange('modelo_a_snapshot', saveSalesBook(draft, next)); const change = (id: string, patch: Partial) => run(() => save({ ...book, rows: book.rows.map((r) => r.id === id ? { ...r, ...patch } : r, ), }), ); const continueTemporary = (id: string, target: string) => run(() => save({ ...book, rows: book.rows.map((row) => row.id === id ? continueTemporaryOperation(row, target) : row, ), }), ); return (

Operações de IVA — enquadramento das vendas

Oportunidade{' '} {inputText(draft.context_opportunity || 'entrada geral')}; moeda original {book.currency || 'por indicar'}. Cobertura2026/MZN. Reutilize as vendas e complete apenas o enquadramento. Este bloco classifica as operações; não substitui nem soma novamente a execução mensal geral acima.

Uma empresa pode ter operações com tratamentos diferentes. Os valores são projecções sob pressupostos declarados, sem certificar facturas, reconhecer créditos ou submeter uma declaração à AT.

Correspondência dos campos05/06/07 e contagem única

{modeloA06Correspondence}

{error &&

{error}

} {book.rows.map((row) => { const rule = operationTreatments.find( (r) => r.id === row.treatment, ), annexI = annexIEntry(row.annexIItem); return (
{row.description || 'Operação adicional'} —{' '} {row.period}

Origem: {row.source};{' '} {row.sourceAmount ?? 'sem valor de origem'}{' '} {row.sourceCurrency}; {row.sourcePeriod}. O estabelecimento não é inferido da localização do projecto.

{isSpecialRegime(row.treatment) && (
Regime aduaneiro ou fiscal da operação

Identifique no fundamento os bens, a operação e o documento ou pressuposto expresso do regime. A escolha conserva preço, moeda e período e pede a revisão das condições; não comprova o enquadramento por estar numa zona. Bens e serviço de transporte ou serviço conexo têm preços próprios, sem duplicar o valor.

{specialRegimeIssue( row.treatment, row.specialRegime, ) && (

{specialRegimeIssue( row.treatment, row.specialRegime, )}

)}
)} {isOnboardSupply(row.treatment) && (
Natureza do abastecimento a bordo

A escolha conserva o preço, a moeda e o período; reveja as condições. Para fornecimento misto, discrimine as parcelas efectivas sem repetir o total em cada linha. Desconhecido não equivale a «sem bebidas».

{onboardSupplyIssue( row.treatment, row.supplyCategory, ) && (

{onboardSupplyIssue( row.treatment, row.supplyCategory, )}

)}
)} {isExportService(row.treatment) && (
Referência à operação relacionada

Se a operação já consta desta oportunidade,pode referenciá-la sem preencher de novo a descrição. A escolha conserva o preço,moeda,período e fundamento deste serviço;limpa as confirmações para revisão. Não copia o valor dos bens para o preço do serviço nem comprova automaticamente a isenção. Para operação documentada fora deste livro,use o fundamento abaixo.

{row.relatedExport && ( <>

Referência guardada:{' '} {row.relatedExport.description}; ID{' '} {row.relatedExport.id};{' '} {row.relatedExport.treatment}.

{book.rows.some( (item) => item.id === row.relatedExport!.id, ) && ( )} )}
)} {temporaryBenefit(row.treatment) && (
Benefício temporário — prazo e continuidade

{temporaryBenefitNotice( row.treatment, row.period, )}

{ temporaryBenefit(row.treatment)! .historicalScope }

Não precisa de preencher documentos de uma isenção já terminada para prosseguir em2026. Antes de escolher outro tratamento, confirme a natureza da operação: a escolha conserva valor,moeda,período,estabelecimento eorigem; limpa as confirmações para revisão e mantém o resultado anterior no histórico.

{row.treatment === 'temporary_sugar_cane' && ( )}

Para outro enquadramento disponível,use a escolha «Tratamento da operação». Nenhum resultado é recalculado automaticamente.

)} {temporaryBenefit(row.temporaryBenefitOrigin) && !temporaryBenefit(row.treatment) && (

Origem conservada:{' '} { temporaryBenefit( row.temporaryBenefitOrigin, )!.label } ,benefício com termo31/12/2025. Enquadramento actual escolhido expressamente;confirme as respectivas condições antes de calcular.

)} {row.treatment === 'annexI_goods' && (
Bem do Anexo I — edição Lei22/2022

Escolha código e designação e confira apenas os qualificadores dessa linha. A pesquisa conserva a escolha actual; mudar de posição exige rever as condições específicas. O anexo não dispensa o enquadramento de outras isenções aplicáveis ao mesmo bem.

{row.annexIItem && (

{annexI ? annexIReference(annexI) : `Posição guardada não encontrada nesta edição: ${row.annexIItem}. Original conservado; escolha explicitamente a correspondência.`}

)} {!!annexI?.relatedTreatments?.length && (

Confira a natureza e o destino: há um tratamento existente que pode abranger este bem. Se for aplicável, use-o para conservar também o direito à dedução nas condições legais. Ao confirmar a passagem, conserva valores e origem e terá de rever as condições do tratamento escolhido; nenhum resultado anterior é substituído automaticamente.

{annexI.relatedTreatments.map((id) => { const target = operationTreatments.find( (t) => t.id === id, ); return ( target && ( ) ); })} {!annexI.relatedRequired && ( )}
)}
)} {row.treatment === 'pharma_manufacturing_inputs' && (
Bem do Anexo III — edição Lei22/2022

Escolha a linha pelo código e pela designação. O estabelecimento que transmite deve estar integrado no SNS; o destino hospitalar não substitui essa condição. A selecção não classifica automaticamente uma mercadoria nem confirma a sua utilização.

{row.pharmaAnnexItem && (

{pharmaAnnexEntry(row.pharmaAnnexItem) ? pharmaAnnexReference( pharmaAnnexEntry( row.pharmaAnnexItem, )!, ) : `Escolha guardada não encontrada nesta edição: ${row.pharmaAnnexItem}. Original conservado; seleccione explicitamente a correspondência.`}

)}

O exemplar repete2912.19.00 em duas linhas com designações diferentes e imprime2935. sem completar a posição. As linhas mantêm identidades próprias; não se inventam dígitos nem se estende a isenção apenas pelo código.

)} {row.treatment.startsWith('fundraising_') && (
Manifestação ocasional — limite anual da entidade

O total é declarado para a entidade em todo o ano, incluindo manifestações fora deste dossier. Várias vendas da mesma manifestação não são novas manifestações.

{( [ [ 'entityReference', 'Referência da entidade organizadora', ], [ 'annualEvents', 'Total anual de manifestações da entidade, incluindo esta', ], [ 'eventNumber', 'Número desta manifestação no ano', ], ] as const ).map(([field, label]) => ( ))}
)} {row.treatment.startsWith('production_') && row.treatment.endsWith('_opted') && (
Opção de tributação da produção — artigo11

Complete apenas as datas em falta. A opção não cessa automaticamente ao fim de cinco anos. O prazo termina às 24 horas do dia correspondente; se faltar esse dia, no último dia do mesmo mês. O artigo11(3) exige declaração antes de expirar o prazo e fixa os efeitos em 1 de Janeiro seguinte, respeitando a permanência mínima.

{book.rows.some( (source) => source.id !== row.id && source.taxOption, ) && ( )} {reuseOption?.rowId === row.id && (

Ao confirmar, substituirá o enquadramento e as datas da opção desta linha pelos da origem escolhida, conservando a data desta operação. Confirme que se aplicam ao mesmo sujeito passivo; o resultado anterior permanece no histórico.

)} {( [ [ 'declarationDate', 'Data da declaração de opção', ], ...(row.taxOption?.mode === 'startup' ? [ [ 'startupDate', 'Data de início da actividade', ], ] : []), [ 'operationDate', 'Data da operação nesta linha', ], ...(row.taxOption?.returnStatus === 'declared' || row.taxOption?.returnDeclarationDate ? [ [ 'returnDeclarationDate', 'Data da declaração de regresso à isenção', ], ] : []), ] as Array< [ ( | 'declarationDate' | 'startupDate' | 'operationDate' | 'returnDeclarationDate' ), string, ] > ).map(([field, label]) => ( ))}
)}

{rule?.article}; {rule?.source}. Aplicação nesta versão: Janeiro–Dezembro2026, sujeita às condições seguintes.

{rule?.conditions.map((condition, index) => ( ))}