import {newSpecialCombinations,specialCombinationsSource} from '@/lib/irpc-special-combinations'; import type {NormalBook} from '@/lib/irpc-normal'; import {newSpecialInput,newSpecialExpense,newAcceleratedAsset,specialAccelerationSource,specialCessationPriorSource,specialStartPeriodSource,specialMonthlySource,specialSources,type SpecialInput,type Qualification} from '@/lib/irpc-special'; type Props={draft:Record;book:NormalBook;save:(b:NormalBook)=>void}; const states=[['','Informação em falta'],['known','Tratamento conhecido — qualificar condições'],['absent','Ausência declarada com suporte'],['not_applicable','Tratamento não aplicável — justificar']]as const; function QualificationFields({label,value,onChange}:{label:string;value:Qualification;onChange:(v:Qualification)=>void}){ const field=(key:'from'|'to'|'reference'|'periodReference',text:string)=>; return
{value.state==='known'&&}{field('reference','Prova das condições, ausência ou não aplicação')}{field('from','Período — início (AAAA-MM-DD)')}{field('to','Período — termo (AAAA-MM-DD)')}{field('periodReference','Suporte do período e da vigência aplicável')}
; } export function SimulationIrpcSpecial({draft,book:b,save}:Props){ const i=b.special; const start=()=>{const next=newSpecialInput(),p=b.periodsFx??b.schedules?.period;for(const part of[next.expenses,next.cooperative,next.acceleration])Object.assign(part.qualification,{from:p?.from??b.year+'-01-01',to:p?.to??b.year+'-12-31'});save({...b,special:next});}; if(!i)return
L7 — benefícios e casos especiais

Preparação opcional e separada do percursoL6 já entregue. Localização e sector não activam benefícios. A liquidação final permanece emL8.

; const change=(patch:Partial)=>save({...b,special:{...i,...patch}}); const yesno=(label:string,value:string,onChange:(v:''|'yes'|'no')=>void)=>; return
L7 — qualificação comum e tratamentos documentados

Reutiliza sujeito, NUIT, período, despesas e activos L6. Contexto herdado:sector {String(draft.sector_id??'por identificar')};província {String(draft.province_id??'por identificar')}. A localização, por si só, não concede benefícios. Os valores L6 continuam como referência;os efeitosL7 são apresentados separadamente. Saldo final a pagar/recuperar:âmbitoL8.

{!i.combinations?:
Cumulações — tratamentos, incompatibilidades e limites

{specialCombinationsSource} Reutiliza a cooperativa,os activos,as despesas e os períodos já declarados abaixo. Esta preparação discrimina os benefícios em vez da confirmação global de ausência de outros benefícios;conserva os valores anteriores e não altera automaticamente qualificações ou activos.

{i.combinations.specificState==='known'&&}

Não somar de novo a amortização contabilística ou a parcela anterior recuperada. A redução cooperativa afecta só a colecta sobre a base elegível;o imposto autónomo continua separado. Uma incompatibilidade não escolhe o benefício a conservar nem apaga o declarado. Outros benefícios/excepções sem regra correspondida mantêm o totalL7 indeterminado.

}
Despesas — tributação autónoma61(4)

{specialSources.expenses}

change({expenses:{...i.expenses,qualification}})}/> {i.expenses.rows.map((r,index)=>{const origin=b.schedules?.rows.find(x=>x.id===r.scheduleId),patch=(p:Partial)=>change({expenses:{...i.expenses,rows:i.expenses.rows.map(x=>x.id===r.id?{...x,...p}:x)}});return
{origin?origin.document+'/'+origin.line:'Parcela por corresponder'} — {origin?.amount??'Indeterminado'} MZN

O acréscimo36g já pertence aL6;esta linha só apura o eventual imposto autónomo.

{yesno('Incidência61(4) — parcela '+(index+1),r.eligible,eligible=>patch({eligible}))}
;})}
Cooperativas abrangidas — artigo12

{specialSources.cooperative} Este incremento exige base integralmente elegível;parcelas mistas continuam explícitas.

change({cooperative:{...i.cooperative,qualification}})}/>{(i.cooperative.qualification.state==='known'||i.cooperative.kind!==''||i.cooperative.allIncomeEligible!==''||i.cooperative.withheldIncome!=='')&&<>{yesno('Base ordinária integralmente elegível',i.cooperative.allIncomeEligible,allIncomeEligible=>change({cooperative:{...i.cooperative,allIncomeEligible}}))}}
Amortizações aceleradas — CBF16

{i.combinations?specialAccelerationSource(i):i.acceleration.monthly?.continuation?specialCessationPriorSource:i.acceleration.monthly?.startPeriod?specialStartPeriodSource:specialSources.acceleration} Apenas activos já suportados e método constante;prepare explicitamente o recorte anual ou de início de actividade.

change({acceleration:{...i.acceleration,qualification}})}/>{i.acceleration.qualification.state==='known'&&<>{yesno('EnquadramentoCBF3 e pressupostos9 documentados',i.acceleration.cbfRequirements,cbfRequirements=>change({acceleration:{...i.acceleration,cbfRequirements}}))}{!i.combinations&&yesno('Ausência documentada de outros benefícios a cumular',i.acceleration.noOtherBenefits,noOtherBenefits=>change({acceleration:{...i.acceleration,noOtherBenefits}}))}} {!i.acceleration.monthly?:
CBF16 — reutilizar duodécimos L6

{i.combinations?specialAccelerationSource(i):i.acceleration.monthly.continuation?specialCessationPriorSource:i.acceleration.monthly.startPeriod?specialStartPeriodSource:specialMonthlySource} Conserva datas,opção mensal e valores do activo existente;preencha no mapaL6 apenas o que falta ou precisa de correcção.

{!i.acceleration.monthly.continuation&&(!i.acceleration.monthly.startPeriod?:
CBF16 — período curto de início de actividade

Período L6:{b.periodsFx?.from||'Por identificar'} a {b.periodsFx?.to||'Por identificar'};tipo:{b.periodsFx?.kind||'Por identificar'}. Reutiliza o período declarado;esta opção não altera datas,activos ou enquadramento.

)}{!i.acceleration.monthly.startPeriod&&(!i.acceleration.monthly.continuation?:
CBF16 — cessação e quotas anteriores

{specialCessationPriorSource} Reutiliza o mapaL6;nenhum saldo declarado ou histórico é alterado. PeríodoL6:{b.periodsFx?.from||b.year+'-01-01'} a {b.periodsFx?.to||b.year+'-12-31'};tipo:{b.periodsFx?.kind||'anual'}. Corrija dados de origem nos mapasL6 quando necessário.

{yesno('Duodécimos desde a entrada emuso documentados',i.acceleration.monthly.continuation.monthlyFromStart,monthlyFromStart=>change({acceleration:{...i.acceleration,monthly:{...i.acceleration.monthly!,continuation:{...i.acceleration.monthly!.continuation!,monthlyFromStart}}}}))}

Cessação da actividade e saída do activo são eventos distintos. Só a saída documentada emL6 exclui o mês do evento. A recuperação de quotas anteriores é aritmética para esta simulação;saldo oficial não é consumido.

)}

Não altera automaticamente o activo nem transforma ausência de documentos em elegibilidade. A versão anterior permanece no histórico depois de calcular e guardar.

} {i.acceleration.rows.map((r,index)=>{const patch=(p:Partial)=>change({acceleration:{...i.acceleration,rows:i.acceleration.rows.map(x=>x.id===r.id?{...x,...p}:x)}});return
Activo qualificado {index+1}{yesno('Condições do activoCBF16 — '+(index+1),r.eligible,eligible=>patch({eligible}))}
;})}

Use «Calcular e guardar» abaixo para gravar uma nova versão e apresentar os efeitos. Os históricos anteriores são conservados. M20/M22 mantém apenas correspondências demonstradas;camposL7 não são preenchidos por aproximação.

; }