Files
Investidor-V2/resources/js/components/simulation-irpc-form-preparation.tsx
T

328 lines
13 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { normalFinancialSource, type NormalBook } from '@/lib/irpc-normal';
import {
m20Accounts,
newNormalFormPreparation,
newFormAllocation,
reuseDirectFormAllocations,
normalFormAccountsFor,
type NormalFormPreparationInput,
type FormAllocation,
} from '@/lib/irpc-normal-form-preparation';
export function SimulationIrpcFormPreparation({
draft,
book,
save,
}: {
draft: Record<string, unknown>;
book: NormalBook;
save: (b: NormalBook) => void;
}) {
const i = book.forms,
source = normalFinancialSource(draft);
if (!i)
return (
<button
type="button"
onClick={() =>
save({ ...book, forms: newNormalFormPreparation() })
}
>
Preparar representação dos valores e campos M20/M22
</button>
);
const patch = (p: Partial<NormalFormPreparationInput>) =>
save({ ...book, forms: { ...i, ...p } }),
row = (id: string, p: Partial<FormAllocation>) =>
patch({
allocations: i.allocations.map((a) =>
a.id === id ? { ...a, ...p } : a,
),
});
return (
<fieldset
aria-label="Preparação de valores M20 M22"
className="space-y-3 rounded border p-3"
>
<legend>Representação dos valores e correspondência M20/M22</legend>
<p>
Reutiliza os valores exactos do cálculo e do período/moeda já
documentados. A preparação dos campos não altera lucro
tributável,matéria colectável ou colecta. M20A.1 exige meticais
sem centavos;fracções conservam o valor exacto e ficam pendentes
de regra de representação. O transporte201/quadro8
versus200/quadro10 continua identificado,só no resultado
afectado. Não gera declaração oficial nem saldo finalL8.
</p>
<label className="block">
Exemplares de preparação
<select
value={i.edition}
onChange={(e) =>
patch({
edition: e.target
.value as NormalFormPreparationInput['edition'],
})
}
>
<option value="">Por identificar</option>
<option value="accepted_pdf_and_m20a1">
PDF M22 quadros10–12 e M20A.1 inventariados — edições
distintas
</option>
</select>
</label>
<label className="block">
Suporte da edição e do período
<input
value={i.reference}
onChange={(e) => patch({ reference: e.target.value })}
/>
</label>
<label className="block">
Completude das contas e discriminação das linhas do plano
<input
value={i.completenessReference}
onChange={(e) =>
patch({ completenessReference: e.target.value })
}
/>
</label>
<button
type="button"
onClick={() =>
patch({
allocations: [
...i.allocations,
...reuseDirectFormAllocations(source).filter(
(a) =>
!i.allocations.some(
(r) => r.sourceCode === a.sourceCode,
),
),
],
})
}
>
Reutilizar contas directas ainda não discriminadas
</button>
<button
type="button"
onClick={() =>
patch({
allocations: [
...i.allocations,
newFormAllocation(crypto.randomUUID()),
],
})
}
>
Acrescentar parcela contabilística M20
</button>
{i.allocations.map((a, n) => (
<fieldset key={a.id} className="rounded border p-2">
<legend>Parcela M20 {n + 1}</legend>
<label className="block">
Linha de origem
<select
aria-label={'Origem M20 ' + (n + 1)}
value={a.sourceCode}
onChange={(e) =>
row(a.id, { sourceCode: e.target.value })
}
>
<option value="">Seleccione</option>
{source?.accountingLines.map((l) => (
<option key={l.code} value={l.code}>
{l.origin}: {l.total} MZN
</option>
))}
</select>
</label>
<label className="block">
Conta M20A.1
<select
aria-label={'Conta M20 ' + (n + 1)}
value={a.account}
onChange={(e) =>
row(a.id, {
account: e.target
.value as FormAllocation['account'],
})
}
>
<option value="">Por corresponder</option>
{Object.entries(m20Accounts)
.filter(
([k]) =>
normalFormAccountsFor(
a.sourceCode,
).includes(k) || k === a.account,
)
.map(([k, v]) => (
<option key={k} value={k}>
{k} — {v}
</option>
))}
</select>
</label>
<label className="block">
Montante MZN
<input
aria-label={'Montante M20 ' + (n + 1)}
value={a.amount}
onChange={(e) =>
row(a.id, { amount: e.target.value })
}
/>
</label>
<label className="block">
Suporte da classificação
<input
aria-label={'Suporte M20 ' + (n + 1)}
value={a.reference}
onChange={(e) =>
row(a.id, { reference: e.target.value })
}
/>
</label>
</fieldset>
))}
<fieldset className="rounded border p-2">
<legend>Imposto contabilizado e resultado líquido</legend>
<p>
Colecta e saldo a pagar não são usados como gasto
contabilístico presumido. Indique imposto reconhecido e se
já está incluído numa linha do plano,para evitar subtracção
duplicada.
</p>
<label className="block">
Estado do imposto contabilizado
<select
aria-label="Estado do imposto contabilizado"
value={i.incomeTax.state}
onChange={(e) =>
patch({
incomeTax: {
...i.incomeTax,
state: e.target.value as
| ''
| 'known'
| 'absent',
},
})
}
>
<option value="">Informação em falta</option>
<option value="known">Valor conhecido</option>
<option value="absent">
Ausência declarada com suporte
</option>
</select>
</label>
{(i.incomeTax.state === 'known' ||
i.incomeTax.amount !== '' ||
i.incomeTax.placement !== '') && (
<>
<label className="block">
Imposto contabilizado em MZN
<input
value={i.incomeTax.amount}
onChange={(e) =>
patch({
incomeTax: {
...i.incomeTax,
amount: e.target.value,
},
})
}
/>
</label>
<label className="block">
Localização do imposto contabilizado
<select
value={i.incomeTax.placement}
onChange={(e) =>
patch({
incomeTax: {
...i.incomeTax,
placement: e.target.value as
| ''
| 'included'
| 'outside',
},
})
}
>
<option value="">Por identificar</option>
<option value="included">
Já incluído no resultado do plano —
discriminado na conta8.5
</option>
<option value="outside">
Exterior ao resultado antes de imposto do
plano
</option>
</select>
</label>
</>
)}
<label className="block">
Suporte do imposto contabilizado
<input
value={i.incomeTax.reference}
onChange={(e) =>
patch({
incomeTax: {
...i.incomeTax,
reference: e.target.value,
},
})
}
/>
</label>
</fieldset>
<label className="block">
Parcela de taxa reduzida para a colecta total302
<select
aria-label="Parcela de taxa reduzida para a colecta total302"
value={i.reducedRate.state}
onChange={(e) =>
patch({
reducedRate: {
...i.reducedRate,
state: e.target.value as
| ''
| 'known'
| 'absent',
},
})
}
>
<option value="">Informação em falta</option>
<option value="absent">
Ausência declarada — sem parcela reduzida neste
sujeito/período
</option>
<option value="known">
Situação conhecida — âmbitoL7 por tratar
</option>
</select>
</label>
<label className="block">
Suporte da situação da taxa reduzida
<input
value={i.reducedRate.reference}
onChange={(e) =>
patch({
reducedRate: {
...i.reducedRate,
reference: e.target.value,
},
})
}
/>
</label>
</fieldset>
);
}