90 lines
4.2 KiB
TypeScript
90 lines
4.2 KiB
TypeScript
export const irpcSpecialCombinationsVersion = 'IRPC-normal-adjustments/14';
|
|
export const specialCombinationsSource =
|
|
'CBF4/13,compilação oficial APIEX pp66/70:benefícios específicos não cumuláveis entre si ou com genéricos,salvo excepção expressa;CBF16 é genérico. CIRPC12/14 e61(1):cooperativa abrangida,redução50% da taxa geral32%=16%,base integralmente elegível,sem rendimentos sujeitos a retenção. Recorte de combinação destes tratamentos já qualificados:primeiro a diferença fiscalCBF16,depois a matéria colectável e a taxa16%;imposto autónomo61(4) separado a35%,sem redução cooperativa. Não se aplica automaticamente benefício específico,outro benefício ou excepção sem correspondência.';
|
|
export type SpecialCombinationsInput = {
|
|
version: 1;
|
|
reference: string;
|
|
specificState: '' | 'absent' | 'known';
|
|
specificReference: string;
|
|
specificException: '' | 'absent' | 'claimed';
|
|
otherState: '' | 'absent' | 'known';
|
|
otherReference: string;
|
|
};
|
|
export const newSpecialCombinations = (): SpecialCombinationsInput => ({
|
|
version: 1,
|
|
reference: '',
|
|
specificState: '',
|
|
specificReference: '',
|
|
specificException: '',
|
|
otherState: '',
|
|
otherReference: '',
|
|
});
|
|
export function validateSpecialCombinations(i: SpecialCombinationsInput) {
|
|
if (
|
|
!i ||
|
|
i.version !== 1 ||
|
|
['reference', 'specificReference', 'otherReference'].some(
|
|
(k) => typeof i[k as 'reference'] !== 'string',
|
|
) ||
|
|
!['', 'absent', 'known'].includes(i.specificState) ||
|
|
!['', 'absent', 'claimed'].includes(i.specificException) ||
|
|
!['', 'absent', 'known'].includes(i.otherState)
|
|
)
|
|
throw Error(
|
|
'Mapa de cumulações não recuperável;históricos conservados.',
|
|
);
|
|
}
|
|
export function qualifySpecialCombinations(
|
|
i: SpecialCombinationsInput,
|
|
genericRequested = true,
|
|
) {
|
|
validateSpecialCombinations(i);
|
|
const pending: string[] = [];
|
|
let incompatible = false;
|
|
if (!i.reference.trim())
|
|
pending.push(
|
|
'Falta suporte da combinação dos tratamentos registados no mesmo sujeito/projecto/período.',
|
|
);
|
|
if (!i.specificState || !i.specificReference.trim())
|
|
pending.push(
|
|
'Benefícios específicosCBF:identifique presença ou ausência documentada;localização não prova estatuto.',
|
|
);
|
|
if (!i.otherState || !i.otherReference.trim())
|
|
pending.push(
|
|
'Outros benefícios além dos tratamentosL7 registados:identifique presença ou ausência com suporte.',
|
|
);
|
|
if (i.specificState === 'absent' && i.specificException)
|
|
pending.push(
|
|
'Ausência de benefício específico contradiz excepção preenchida;reconcilie a declaração.',
|
|
);
|
|
if (i.specificState === 'known') {
|
|
if (i.specificException === 'absent' && genericRequested) {
|
|
incompatible = true;
|
|
pending.push(
|
|
'IncompatibilidadeCBF4/13:benefício específico declarado e genéricoCBF16 sem excepção expressa;nenhum benefício é escolhido ou removido automaticamente.',
|
|
);
|
|
} else
|
|
pending.push(
|
|
i.specificException === 'absent'
|
|
? 'Benefício específico declarado sem cálculo próprio correspondido;não é ignorado na totalização.'
|
|
: i.specificException === 'claimed'
|
|
? 'Excepção expressa invocada:ligar artigo,âmbito,período e limites à combinação antes de calcular;esta excepção ainda não está correspondida.'
|
|
: 'Benefício específico declarado:identifique excepção expressa ou ausência;sem presumir acumulação.',
|
|
);
|
|
}
|
|
if (i.otherState === 'known')
|
|
pending.push(
|
|
'Outro benefício declarado ainda sem cálculo/ordem/limite correspondidos;sem o aplicar ou ignorar por presunção.',
|
|
);
|
|
return {
|
|
status: incompatible
|
|
? ('incompatible' as const)
|
|
: pending.length
|
|
? ('indeterminate' as const)
|
|
: ('compatible' as const),
|
|
ready: pending.length === 0,
|
|
pending,
|
|
source: specialCombinationsSource,
|
|
};
|
|
}
|