This commit is contained in:
@@ -1,5 +1,18 @@
|
||||
# Rastreabilidade, utilização e formação
|
||||
|
||||
## 10/11/2026 — económico instalado; CDT Portugal avançada em QA
|
||||
|
||||
**Homologação: `ac67f9c13a6561b66c5da788a48849beac90a905`**, promovida pelo executor Git existente às11:32:14UTC e conferida às11:33:16UTC (13:33 locais). Revisão HTTPS e27hashes Git iguais; portal/login/up/revision HTTP200; .env preservado, zero migrations/importações. Backup/restauro190tabelas com contagens/checksums iguais e369ficheiros/configuração extraídos/conferidos. Release c359364d conservada. Recibos `outputs/economic-special-delivery-20261110/{backup,restore,files-restore,verification}.json`. Credencial não guardada; sessão SSH encerrada. Inclui quota económica, inclusão/reconciliação ordinária e especial L6, partilha64(3) e associações64(4). Entradas anteriores «apenas QA» são históricas nestes recortes; não reinstalar por consequência.
|
||||
|
||||
**Delta posterior, ainda QA:** correspondência CDT PT–MZ para royalties ordinárias não digitais, dividendos e juros ordinários de fonte portuguesa de residente convencional em Moçambique. País não activa a convenção. Exige beneficiário efectivo, definição/natureza, fonte/pagador, ausência de EP/instalação fixa ligada, período e suporte documentados; relações especiais verificadas nos juros/royalties, isenção governamental11(3) separada. Limite10% do bruto nos ramos suportados; dividendos usam alteração do Protocolo2009 art6, evitando taxa15% do texto1992. Não usa retenção L5 em sentido inverso nem tax sparing presumido. Mantém limite manual/históricos e parcela líquida nacional.
|
||||
|
||||
Prova sintética por ramo: bruto60 → limiteCDT6, imposto pago10/fracção nacional8 → crédito6 → saldo702 MZN. Cálculo/gravação/recuperação/HTML/dossier por API existente no QA55441; sem novo writer, schema, direito ou escrita activa. Provas `outputs/irpc-pt-mz-{credit,dividend,interest}-20261110/verification.json`. Fracções mantêm exactidão, sem arredondamento fiscal presumido. País/condição/período inválidos deixam apenas o caso dependente indeterminado. Este delta não integra ac67f9c1.
|
||||
|
||||
Restam CDT de outros Estados/naturezas, EP/instalação fixa, juros governamentais, excessos/relações especiais e casos fora do recorte, além dos demais resíduos L1–L7/L8/L9–L16. Conferência visual continua pendente no mesmo registo. Não declarar L8 ou o portal integralmente concluídos.
|
||||
Conjunto CDT agrupado em `outputs/entrega-cdt-pt-20261110.zip`, base exacta ac67f9c1, aplicação/reversão conferidas; tipos/lint/Pint e build QA aprovados. Instalação deste delta ainda não executada.
|
||||
|
||||
|
||||
|
||||
## 10/11/2026 — crédito económico: partilha e associações em QA
|
||||
|
||||
Homologação mantém `c359364d`. Avanço posterior em QA, sem instalação: art64(3) distingue a parcela elegível do rendimento da partilha e o excesso com natureza de mais-valia; art64(4) distingue associação em participação e à quota, exigindo tributação efectiva documentada na participação. Reutiliza cálculo60%, prova do imposto subjacente, limites, prioridades, isolamento e writer privado existentes. Não calcula a mais-valia como crédito nem pressupõe inclusão L6 ou reconferência da colecta. Campos antigos e históricos são preservados; fontes incompletas ficam recuperáveis e indeterminadas.
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
## 10/11/2026 — económico instalado; CDT Portugal avançada em QA
|
||||
|
||||
**Homologação: `ac67f9c13a6561b66c5da788a48849beac90a905`**, promovida pelo executor Git existente às11:32:14UTC e conferida às11:33:16UTC (13:33 locais). Revisão HTTPS e27hashes Git iguais; portal/login/up/revision HTTP200; .env preservado, zero migrations/importações. Backup/restauro190tabelas com contagens/checksums iguais e369ficheiros/configuração extraídos/conferidos. Release c359364d conservada. Recibos `outputs/economic-special-delivery-20261110/{backup,restore,files-restore,verification}.json`. Credencial não guardada; sessão SSH encerrada. Inclui quota económica, inclusão/reconciliação ordinária e especial L6, partilha64(3) e associações64(4). Entradas anteriores «apenas QA» são históricas nestes recortes; não reinstalar por consequência.
|
||||
|
||||
**Delta posterior, ainda QA:** correspondência CDT PT–MZ para royalties ordinárias não digitais, dividendos e juros ordinários de fonte portuguesa de residente convencional em Moçambique. País não activa a convenção. Exige beneficiário efectivo, definição/natureza, fonte/pagador, ausência de EP/instalação fixa ligada, período e suporte documentados; relações especiais verificadas nos juros/royalties, isenção governamental11(3) separada. Limite10% do bruto nos ramos suportados; dividendos usam alteração do Protocolo2009 art6, evitando taxa15% do texto1992. Não usa retenção L5 em sentido inverso nem tax sparing presumido. Mantém limite manual/históricos e parcela líquida nacional.
|
||||
|
||||
Prova sintética por ramo: bruto60 → limiteCDT6, imposto pago10/fracção nacional8 → crédito6 → saldo702 MZN. Cálculo/gravação/recuperação/HTML/dossier por API existente no QA55441; sem novo writer, schema, direito ou escrita activa. Provas `outputs/irpc-pt-mz-{credit,dividend,interest}-20261110/verification.json`. Fracções mantêm exactidão, sem arredondamento fiscal presumido. País/condição/período inválidos deixam apenas o caso dependente indeterminado. Este delta não integra ac67f9c1.
|
||||
|
||||
Restam CDT de outros Estados/naturezas, EP/instalação fixa, juros governamentais, excessos/relações especiais e casos fora do recorte, além dos demais resíduos L1–L7/L8/L9–L16. Conferência visual continua pendente no mesmo registo. Não declarar L8 ou o portal integralmente concluídos.
|
||||
Conjunto CDT agrupado em `outputs/entrega-cdt-pt-20261110.zip`, base exacta ac67f9c1, aplicação/reversão conferidas; tipos/lint/Pint e build QA aprovados. Instalação deste delta ainda não executada.
|
||||
|
||||
|
||||
## 10/11/2026 — crédito económico: partilha e associações em QA
|
||||
|
||||
Homologação mantém `c359364d`. Avanço posterior em QA, sem instalação: art64(3) distingue a parcela elegível do rendimento da partilha e o excesso com natureza de mais-valia; art64(4) distingue associação em participação e à quota, exigindo tributação efectiva documentada na participação. Reutiliza cálculo60%, prova do imposto subjacente, limites, prioridades, isolamento e writer privado existentes. Não calcula a mais-valia como crédito nem pressupõe inclusão L6 ou reconferência da colecta. Campos antigos e históricos são preservados; fontes incompletas ficam recuperáveis e indeterminadas.
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,3 +1,15 @@
|
||||
## 10/11/2026 — económico instalado; CDT Portugal avançada em QA
|
||||
|
||||
**Homologação: `ac67f9c13a6561b66c5da788a48849beac90a905`**, promovida pelo executor Git existente às11:32:14UTC e conferida às11:33:16UTC (13:33 locais). Revisão HTTPS e27hashes Git iguais; portal/login/up/revision HTTP200; .env preservado, zero migrations/importações. Backup/restauro190tabelas com contagens/checksums iguais e369ficheiros/configuração extraídos/conferidos. Release c359364d conservada. Recibos `outputs/economic-special-delivery-20261110/{backup,restore,files-restore,verification}.json`. Credencial não guardada; sessão SSH encerrada. Inclui quota económica, inclusão/reconciliação ordinária e especial L6, partilha64(3) e associações64(4). Entradas anteriores «apenas QA» são históricas nestes recortes; não reinstalar por consequência.
|
||||
|
||||
**Delta posterior, ainda QA:** correspondência CDT PT–MZ para royalties ordinárias não digitais, dividendos e juros ordinários de fonte portuguesa de residente convencional em Moçambique. País não activa a convenção. Exige beneficiário efectivo, definição/natureza, fonte/pagador, ausência de EP/instalação fixa ligada, período e suporte documentados; relações especiais verificadas nos juros/royalties, isenção governamental11(3) separada. Limite10% do bruto nos ramos suportados; dividendos usam alteração do Protocolo2009 art6, evitando taxa15% do texto1992. Não usa retenção L5 em sentido inverso nem tax sparing presumido. Mantém limite manual/históricos e parcela líquida nacional.
|
||||
|
||||
Prova sintética por ramo: bruto60 → limiteCDT6, imposto pago10/fracção nacional8 → crédito6 → saldo702 MZN. Cálculo/gravação/recuperação/HTML/dossier por API existente no QA55441; sem novo writer, schema, direito ou escrita activa. Provas `outputs/irpc-pt-mz-{credit,dividend,interest}-20261110/verification.json`. Fracções mantêm exactidão, sem arredondamento fiscal presumido. País/condição/período inválidos deixam apenas o caso dependente indeterminado. Este delta não integra ac67f9c1.
|
||||
|
||||
Restam CDT de outros Estados/naturezas, EP/instalação fixa, juros governamentais, excessos/relações especiais e casos fora do recorte, além dos demais resíduos L1–L7/L8/L9–L16. Conferência visual continua pendente no mesmo registo. Não declarar L8 ou o portal integralmente concluídos.
|
||||
Conjunto CDT agrupado em `outputs/entrega-cdt-pt-20261110.zip`, base exacta ac67f9c1, aplicação/reversão conferidas; tipos/lint/Pint e build QA aprovados. Instalação deste delta ainda não executada.
|
||||
|
||||
|
||||
## 10/11/2026 — crédito económico: partilha e associações em QA
|
||||
|
||||
Homologação mantém `c359364d`. Avanço posterior em QA, sem instalação: art64(3) distingue a parcela elegível do rendimento da partilha e o excesso com natureza de mais-valia; art64(4) distingue associação em participação e à quota, exigindo tributação efectiva documentada na participação. Reutiliza cálculo60%, prova do imposto subjacente, limites, prioridades, isolamento e writer privado existentes. Não calcula a mais-valia como crédito nem pressupõe inclusão L6 ou reconferência da colecta. Campos antigos e históricos são preservados; fontes incompletas ficam recuperáveis e indeterminadas.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SimulationIrpcPtCdt } from './simulation-irpc-pt-cdt';
|
||||
import { FiscalProofParcelFields } from './fiscal-proof-parcel';
|
||||
import CountrySelect, { type Country } from '@/components/country-select';
|
||||
import { countryIsoCodes } from '@/lib/country-iso-codes';
|
||||
@@ -387,23 +388,65 @@ export function SimulationIrpcInternational({
|
||||
</option>
|
||||
</select>
|
||||
</label>
|
||||
{(p.treaty === 'yes' || p.treatyLimit) && (
|
||||
{p.treaty === 'yes' && (
|
||||
<label className="block">
|
||||
Imposto pago elegível nos termos da convenção —
|
||||
limite MZN
|
||||
<input
|
||||
Determinar limite da convenção
|
||||
<select
|
||||
aria-label={
|
||||
'Internacional ' +
|
||||
(index + 1) +
|
||||
' — Limite CDT'
|
||||
' — Método CDT'
|
||||
}
|
||||
value={p.treatyLimit}
|
||||
value={p.treatyMethod ?? 'documented'}
|
||||
onChange={(e) =>
|
||||
patch({ treatyLimit: e.target.value })
|
||||
patch({
|
||||
treatyMethod: e.target
|
||||
.value as InternationalPosition['treatyMethod'],
|
||||
})
|
||||
}
|
||||
/>
|
||||
>
|
||||
<option value="documented">
|
||||
Limite documentado
|
||||
</option>
|
||||
<option value="ptMzRoyalty">
|
||||
Portugal — royalties ordinárias,
|
||||
art.12/23(3)a
|
||||
</option>
|
||||
<option value="ptMzDividend">
|
||||
Portugal — dividendos, art.10/23(3)a
|
||||
</option>
|
||||
<option value="ptMzInterest">
|
||||
Portugal — juros ordinários,
|
||||
art.11/23(3)a
|
||||
</option>
|
||||
</select>
|
||||
</label>
|
||||
)}
|
||||
<SimulationIrpcPtCdt
|
||||
position={p}
|
||||
patch={patch}
|
||||
prefix={'Internacional ' + (index + 1) + ' — '}
|
||||
/>
|
||||
{(p.treatyMethod ?? 'documented') === 'documented' &&
|
||||
(p.treaty === 'yes' || p.treatyLimit) && (
|
||||
<label className="block">
|
||||
Imposto pago elegível nos termos da
|
||||
convenção — limite MZN
|
||||
<input
|
||||
aria-label={
|
||||
'Internacional ' +
|
||||
(index + 1) +
|
||||
' — Limite CDT'
|
||||
}
|
||||
value={p.treatyLimit}
|
||||
onChange={(e) =>
|
||||
patch({
|
||||
treatyLimit: e.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</label>
|
||||
)}
|
||||
<label className="block">
|
||||
Suporte da convenção ou da não aplicação
|
||||
<input
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
import {
|
||||
newPtMzRoyaltyPreparation,
|
||||
type InternationalPosition,
|
||||
type PtMzRoyaltyPreparation,
|
||||
} from '@/lib/irpc-international-credit';
|
||||
export function SimulationIrpcPtCdt({
|
||||
position: p,
|
||||
patch,
|
||||
prefix,
|
||||
}: {
|
||||
position: InternationalPosition;
|
||||
patch: (v: Partial<InternationalPosition>) => void;
|
||||
prefix: string;
|
||||
}) {
|
||||
if (!p.treatyMethod || p.treatyMethod === 'documented') return null;
|
||||
const change = (key: keyof PtMzRoyaltyPreparation, value: string) =>
|
||||
patch({
|
||||
treatyPreparation: {
|
||||
...newPtMzRoyaltyPreparation(),
|
||||
...p.treatyPreparation,
|
||||
[key]: value,
|
||||
},
|
||||
});
|
||||
const facts: [keyof PtMzRoyaltyPreparation, string][] = [
|
||||
['residentMz', 'Beneficiário residente convencional em Moçambique'],
|
||||
['beneficialOwner', 'Beneficiário efectivo do rendimento'],
|
||||
[
|
||||
'payerResidentPt',
|
||||
'Devedor/sociedade distribuidora residente em Portugal',
|
||||
],
|
||||
[
|
||||
'sourcePortugal',
|
||||
'Fonte portuguesa, incluindo correspondência de quem suporta o encargo',
|
||||
],
|
||||
['noLinkedEstablishment', 'Sem EP/instalação fixa ligada em Portugal'],
|
||||
];
|
||||
if (p.treatyMethod !== 'ptMzDividend')
|
||||
facts.push(['armLength', 'Sem excesso por relações especiais']);
|
||||
if (p.treatyMethod === 'ptMzRoyalty')
|
||||
facts.push(
|
||||
[
|
||||
'royaltyDefinition',
|
||||
'Definição convencional de royalties documentada',
|
||||
],
|
||||
['nonDigital', 'Caso ordinário não digital'],
|
||||
);
|
||||
else
|
||||
facts.push([
|
||||
'capitalDefinition',
|
||||
'Definição convencional de dividendos/juros documentada',
|
||||
]);
|
||||
if (p.treatyMethod === 'ptMzInterest')
|
||||
facts.push([
|
||||
'governmentInterestExemption',
|
||||
'Juros abrangidos pela isenção governamental do art.11(3) (o cálculo ordinário exige Não)',
|
||||
]);
|
||||
return (
|
||||
<fieldset className="space-y-2 rounded border p-3">
|
||||
<legend>Portugal — correspondência CDT</legend>
|
||||
<p>
|
||||
Confirme rendimento bruto em MZN, residência convencional,
|
||||
natureza e período coberto pelos documentos. A taxa de 10%
|
||||
limita o imposto estrangeiro elegível; não altera a parcela
|
||||
líquida nacional nem prova pagamento. O limite manual anterior
|
||||
fica conservado.
|
||||
</p>
|
||||
{(
|
||||
[
|
||||
['gross', 'Rendimento bruto — MZN'],
|
||||
['from', 'Início do período documentado — AAAA-MM-DD'],
|
||||
['to', 'Fim do período documentado — AAAA-MM-DD'],
|
||||
[
|
||||
'reference',
|
||||
'Suporte da residência, contrato e condições convencionais',
|
||||
],
|
||||
] as const
|
||||
).map(([key, label]) => (
|
||||
<label key={key} className="block">
|
||||
{label}
|
||||
<input
|
||||
aria-label={prefix + label}
|
||||
value={p.treatyPreparation?.[key] ?? ''}
|
||||
onChange={(e) => change(key, e.target.value)}
|
||||
/>
|
||||
</label>
|
||||
))}
|
||||
{facts.map(([key, label]) => (
|
||||
<label key={key} className="block">
|
||||
{label}
|
||||
<select
|
||||
aria-label={prefix + label}
|
||||
value={p.treatyPreparation?.[key] ?? ''}
|
||||
onChange={(e) => change(key, e.target.value)}
|
||||
>
|
||||
<option value="">Informação em falta</option>
|
||||
<option value="yes">Sim — documentado</option>
|
||||
<option value="no">Não — documentado</option>
|
||||
</select>
|
||||
</label>
|
||||
))}
|
||||
</fieldset>
|
||||
);
|
||||
}
|
||||
@@ -1740,6 +1740,22 @@ export function annualReportRows(
|
||||
(p.input.treaty === 'no'
|
||||
? 'Não aplicável documentado'
|
||||
: show(p.treatyLimit)) +
|
||||
(p.treatyDerivation
|
||||
? '; ' +
|
||||
p.treatyDerivation.version +
|
||||
'; bruto ' +
|
||||
show(p.treatyDerivation.gross) +
|
||||
' × ' +
|
||||
p.treatyDerivation.rate +
|
||||
'%; período ' +
|
||||
p.treatyDerivation.from +
|
||||
' a ' +
|
||||
p.treatyDerivation.to +
|
||||
'; ' +
|
||||
p.treatyDerivation.reference +
|
||||
'; ' +
|
||||
p.treatyDerivation.source
|
||||
: '') +
|
||||
'; elegível: ' +
|
||||
show(p.eligible) +
|
||||
'; utilização anterior: ' +
|
||||
|
||||
@@ -26,6 +26,36 @@ export type InternationalTaxProof = AnnualPpc & {
|
||||
taxReference: string;
|
||||
exerciseReference: string;
|
||||
};
|
||||
export type PtMzRoyaltyPreparation = {
|
||||
capitalDefinition?: '' | 'yes' | 'no';
|
||||
governmentInterestExemption?: '' | 'yes' | 'no';
|
||||
gross: string;
|
||||
from: string;
|
||||
to: string;
|
||||
reference: string;
|
||||
residentMz: '' | 'yes' | 'no';
|
||||
beneficialOwner: '' | 'yes' | 'no';
|
||||
sourcePortugal: '' | 'yes' | 'no';
|
||||
payerResidentPt: '' | 'yes' | 'no';
|
||||
noLinkedEstablishment: '' | 'yes' | 'no';
|
||||
armLength: '' | 'yes' | 'no';
|
||||
royaltyDefinition: '' | 'yes' | 'no';
|
||||
nonDigital: '' | 'yes' | 'no';
|
||||
};
|
||||
export const newPtMzRoyaltyPreparation = (): PtMzRoyaltyPreparation => ({
|
||||
gross: '',
|
||||
from: '',
|
||||
to: '',
|
||||
reference: '',
|
||||
residentMz: '',
|
||||
beneficialOwner: '',
|
||||
sourcePortugal: '',
|
||||
payerResidentPt: '',
|
||||
noLinkedEstablishment: '',
|
||||
armLength: '',
|
||||
royaltyDefinition: '',
|
||||
nonDigital: '',
|
||||
});
|
||||
export type InternationalPosition = {
|
||||
id: string;
|
||||
country: string;
|
||||
@@ -40,6 +70,12 @@ export type InternationalPosition = {
|
||||
nationalLimitReference: string;
|
||||
nationalMethod?: 'documented' | 'proportional';
|
||||
nationalBasisReference?: string;
|
||||
treatyMethod?:
|
||||
| 'documented'
|
||||
| 'ptMzRoyalty'
|
||||
| 'ptMzDividend'
|
||||
| 'ptMzInterest';
|
||||
treatyPreparation?: PtMzRoyaltyPreparation;
|
||||
treaty: '' | 'yes' | 'no';
|
||||
treatyLimit: string;
|
||||
treatyReference: string;
|
||||
@@ -151,10 +187,63 @@ export function validateInternational(c: InternationalCredits) {
|
||||
) ||
|
||||
!yesNo.includes(p.incomeIncluded) ||
|
||||
!yesNo.includes(p.treaty) ||
|
||||
(p.treatyMethod !== undefined &&
|
||||
![
|
||||
'documented',
|
||||
'ptMzRoyalty',
|
||||
'ptMzDividend',
|
||||
'ptMzInterest',
|
||||
].includes(p.treatyMethod)) ||
|
||||
(p.treatyPreparation !== undefined &&
|
||||
(!p.treatyPreparation ||
|
||||
Object.keys(newPtMzRoyaltyPreparation()).some(
|
||||
(k) =>
|
||||
typeof (
|
||||
p.treatyPreparation as unknown as Record<
|
||||
string,
|
||||
unknown
|
||||
>
|
||||
)[k] !== 'string',
|
||||
) ||
|
||||
[
|
||||
'residentMz',
|
||||
'beneficialOwner',
|
||||
'sourcePortugal',
|
||||
'payerResidentPt',
|
||||
'noLinkedEstablishment',
|
||||
'armLength',
|
||||
'royaltyDefinition',
|
||||
'nonDigital',
|
||||
].some(
|
||||
(k) =>
|
||||
!yesNo.includes(
|
||||
(
|
||||
p.treatyPreparation as unknown as Record<
|
||||
string,
|
||||
string
|
||||
>
|
||||
)[k],
|
||||
),
|
||||
))) ||
|
||||
(p.nationalMethod !== undefined &&
|
||||
!['documented', 'proportional'].includes(p.nationalMethod)) ||
|
||||
(p.nationalBasisReference !== undefined &&
|
||||
typeof p.nationalBasisReference !== 'string') ||
|
||||
(p.treatyPreparation &&
|
||||
['capitalDefinition', 'governmentInterestExemption'].some(
|
||||
(k) => {
|
||||
const v = (
|
||||
p.treatyPreparation as unknown as Record<
|
||||
string,
|
||||
unknown
|
||||
>
|
||||
)[k];
|
||||
return (
|
||||
v !== undefined &&
|
||||
(typeof v !== 'string' || !yesNo.includes(v))
|
||||
);
|
||||
},
|
||||
)) ||
|
||||
!evidenceValid(p.previousUse) ||
|
||||
!Array.isArray(p.payments)
|
||||
)
|
||||
@@ -277,6 +366,102 @@ export function internationalGroupPending(
|
||||
}
|
||||
return pending;
|
||||
}
|
||||
const validDate = (s: string) =>
|
||||
/^20\d{2}-\d{2}-\d{2}$/.test(s) &&
|
||||
Number.isFinite(Date.parse(s)) &&
|
||||
new Date(s).toISOString().slice(0, 10) === s;
|
||||
export function ptMzTreatyLimit(p: InternationalPosition) {
|
||||
const q = p.treatyPreparation;
|
||||
if (
|
||||
p.treaty !== 'yes' ||
|
||||
p.country !== 'PT' ||
|
||||
p.qualificationCountry !== 'PT' ||
|
||||
p.year !== '2026' ||
|
||||
!q?.reference.trim()
|
||||
)
|
||||
throw Error(
|
||||
'CDT PT–MZ12/23(3)a: royalties de fonte portuguesa de residente em Moçambique, exercício2026 e suporte por corresponder.',
|
||||
);
|
||||
for (const key of [
|
||||
'residentMz',
|
||||
'beneficialOwner',
|
||||
'sourcePortugal',
|
||||
'payerResidentPt',
|
||||
'noLinkedEstablishment',
|
||||
] as const)
|
||||
if (q[key] !== 'yes')
|
||||
throw Error(
|
||||
'CDT PT–MZ royalties: condição por documentar — ' + key + '.',
|
||||
);
|
||||
if (p.treatyMethod !== 'ptMzDividend' && q.armLength !== 'yes')
|
||||
throw Error(
|
||||
'Excesso por relações especiais em juros/royalties por corresponder.',
|
||||
);
|
||||
if (
|
||||
p.treatyMethod === 'ptMzRoyalty' &&
|
||||
(q.royaltyDefinition !== 'yes' || q.nonDigital !== 'yes')
|
||||
)
|
||||
throw Error(
|
||||
'Royalties ordinárias não digitais e definição convencional por documentar.',
|
||||
);
|
||||
if (p.treatyMethod !== 'ptMzRoyalty' && q.capitalDefinition !== 'yes')
|
||||
throw Error(
|
||||
'Definição convencional de dividendos/juros por documentar.',
|
||||
);
|
||||
if (
|
||||
p.treatyMethod === 'ptMzInterest' &&
|
||||
q.governmentInterestExemption !== 'no'
|
||||
)
|
||||
throw Error(
|
||||
'Juros abrangidos ou por corresponder à isenção governamental11(3) exigem tratamento próprio; não presumir limite ordinário.',
|
||||
);
|
||||
if (
|
||||
!validDate(q.from) ||
|
||||
!validDate(q.to) ||
|
||||
q.from > q.to ||
|
||||
!p.payments.length ||
|
||||
p.payments.some(
|
||||
(r) => !validDate(r.date) || r.date < q.from || r.date > q.to,
|
||||
)
|
||||
)
|
||||
throw Error(
|
||||
'Comprovativos fora do período documentado da CDT/residência; não presumir cobertura.',
|
||||
);
|
||||
const gross = creditMoney(q.gross);
|
||||
if (creditCompare(gross, creditMoney(p.incomeAmount)) < 0n)
|
||||
throw Error(
|
||||
'Rendimento bruto inferior à parcela líquida incluída; reconcilie custos/perdas e base.',
|
||||
);
|
||||
return {
|
||||
version:
|
||||
p.treatyMethod === 'ptMzRoyalty'
|
||||
? 'IRPC-PT-MZ-royalty-credit/1'
|
||||
: 'IRPC-PT-MZ-capital-credit/1',
|
||||
...(p.treatyMethod !== 'ptMzRoyalty' ? { nature: p.treatyMethod } : {}),
|
||||
gross,
|
||||
rate: '10',
|
||||
limit: fraction(
|
||||
BigInt(gross.numerator),
|
||||
BigInt(gross.denominator) * 10n,
|
||||
),
|
||||
from: q.from,
|
||||
to: q.to,
|
||||
reference: q.reference,
|
||||
source:
|
||||
p.treatyMethod === 'ptMzRoyalty'
|
||||
? 'CDT PT–MZ, RAR36/1992 art12(2/4–6),PDF13–14 e23(3)a,PDF21; Protocolo RAR36/2009 arts1/7,PDF1–2; CIRPC65(2). Royalties ordinárias não digitais, sem EP/instalação fixa ligada nem excesso por relações especiais. Não confundir com retenção L5 paga por devedor moçambicano; sem isenção ou tax sparing presumidos.'
|
||||
: 'CDT PT–MZ, RAR36/1992 art23(3)a,PDF21; CIRPC65(2). ' +
|
||||
(p.treatyMethod === 'ptMzDividend'
|
||||
? 'Dividendos10(2–4),PDF10; taxa10% actualizada pelo Protocolo RAR36/2009 art6,PDF2; IRPC/art2 actualizado pelo art1.'
|
||||
: p.treatyMethod === 'ptMzInterest'
|
||||
? 'Juros11(2–7),PDF11–12, excluída a isenção11(3); IRPC/art2 actualizado pelo Protocolo RAR36/2009 art1.'
|
||||
: 'Royalties12(2/4–6),PDF13–14; definição actualizada pelo Protocolo RAR36/2009 art7,PDF2; IRPC/art2 actualizado pelo art1. Recorte ordinário não digital.') +
|
||||
(p.treatyMethod === 'ptMzDividend'
|
||||
? ' Sem EP/instalação fixa ligada.'
|
||||
: ' Sem EP/instalação fixa ligada ou excesso convencional por relações especiais.') +
|
||||
' Não confundir com retenção L5 de devedor moçambicano; sem isenção ou tax sparing presumidos.',
|
||||
};
|
||||
}
|
||||
export function internationalPosition(
|
||||
p: InternationalPosition,
|
||||
paid: FiscalFraction,
|
||||
@@ -297,6 +482,7 @@ export function internationalPosition(
|
||||
eligible: FiscalFraction | null = null,
|
||||
available: FiscalFraction | null = null,
|
||||
aboveLimit: FiscalFraction | null = null;
|
||||
let treatyDerivation: ReturnType<typeof ptMzTreatyLimit> | null = null;
|
||||
let nationalDerivation: {
|
||||
version: string;
|
||||
income: FiscalFraction;
|
||||
@@ -381,7 +567,10 @@ export function internationalPosition(
|
||||
);
|
||||
if (!p.treaty || !p.treatyReference.trim())
|
||||
throw Error('Aplicabilidade da convenção e suporte em falta.');
|
||||
if (p.treaty === 'yes') treatyLimit = creditLimit(p.treatyLimit);
|
||||
if (p.treatyMethod && p.treatyMethod !== 'documented') {
|
||||
treatyDerivation = ptMzTreatyLimit(p);
|
||||
treatyLimit = treatyDerivation.limit;
|
||||
} else if (p.treaty === 'yes') treatyLimit = creditLimit(p.treatyLimit);
|
||||
else if (p.treatyLimit.trim())
|
||||
throw Error('Ausência de convenção contradiz limite preenchido.');
|
||||
if (!p.previousUse.state || !p.previousUse.reference.trim())
|
||||
@@ -421,6 +610,7 @@ export function internationalPosition(
|
||||
nationalLimit,
|
||||
...(nationalDerivation ? { nationalDerivation } : {}),
|
||||
treatyLimit,
|
||||
...(treatyDerivation ? { treatyDerivation } : {}),
|
||||
previousUse,
|
||||
eligible,
|
||||
available,
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Tests\TestCase;
|
||||
|
||||
final class IrpcPtMzCapitalDraftTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function test_derived_pt_mz_capital_credit_uses_the_existing_private_draft_writer(): void
|
||||
{
|
||||
$target = DB::selectOne('select current_database() as name,inet_server_port() as port');
|
||||
$this->assertSame('proactive_investment_20261027_test', $target->name);
|
||||
$this->assertSame(55441, (int) $target->port);
|
||||
config(['investor-path.enabled' => true, 'suitecrm.enabled' => false]);
|
||||
$this->actingAs(User::findOrFail(1021));
|
||||
$id = null;
|
||||
$etag = null;
|
||||
foreach (['dividend', 'interest'] as $kind) {
|
||||
$d = json_decode(file_get_contents(base_path('outputs/irpc-pt-mz-'.$kind.'-20261110/fixture.json')), true, flags: JSON_THROW_ON_ERROR);
|
||||
$personal = ['person_type' => $d['person_type']];
|
||||
unset($d['person_type']);
|
||||
$payload = ['personal_snapshot' => $personal, 'economic_snapshot' => $d];
|
||||
if ($id === null) {
|
||||
$id = $this->postJson('/api/v1/simulation-drafts', $payload, ['Idempotency-Key' => (string) Str::uuid()])->assertCreated()->json('data.id');
|
||||
} else {
|
||||
$this->putJson('/api/v1/simulation-drafts/'.$id, $payload, ['If-Match' => $etag])->assertOk();
|
||||
}
|
||||
$response = $this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk();
|
||||
$etag = $response->headers->get('ETag');
|
||||
$back = $response->json('data.economic_snapshot');
|
||||
$this->assertSame($d['modelo_a_snapshot'], $back['modelo_a_snapshot']);
|
||||
$this->assertSame($d['business_plan_snapshot'], $back['business_plan_snapshot']);
|
||||
$b = json_decode($back['modelo_a_snapshot'], true, flags: JSON_THROW_ON_ERROR)['irpcAnnual'][$d['context_opportunity']];
|
||||
$this->assertSame($kind === 'dividend' ? 'ptMzDividend' : 'ptMzInterest', $b['internationalCredits']['positions'][0]['treatyMethod']);
|
||||
$this->assertSame(['numerator' => '6', 'denominator' => '1'], $b['result']['model']['internationalCredit']['positions'][0]['treatyLimit']);
|
||||
$this->assertSame(['numerator' => '702', 'denominator' => '1'], $b['result']['model']['arithmeticBalance']);
|
||||
file_put_contents(base_path('outputs/irpc-pt-mz-'.$kind.'-20261110/recovered.json'), json_encode($back, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Tests\TestCase;
|
||||
|
||||
final class IrpcPtMzCreditDraftTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function test_derived_pt_mz_credit_uses_the_existing_private_draft_writer(): void
|
||||
{
|
||||
$target = DB::selectOne('select current_database() as name,inet_server_port() as port');
|
||||
$this->assertSame('proactive_investment_20261027_test', $target->name);
|
||||
$this->assertSame(55441, (int) $target->port);
|
||||
config(['investor-path.enabled' => true, 'suitecrm.enabled' => false]);
|
||||
$this->actingAs(User::findOrFail(1021));
|
||||
$d = json_decode(file_get_contents(base_path('outputs/irpc-pt-mz-credit-20261110/fixture.json')), true, flags: JSON_THROW_ON_ERROR);
|
||||
$personal = ['person_type' => $d['person_type']];
|
||||
unset($d['person_type']);
|
||||
$id = $this->postJson('/api/v1/simulation-drafts', ['personal_snapshot' => $personal, 'economic_snapshot' => $d], ['Idempotency-Key' => (string) Str::uuid()])->assertCreated()->json('data.id');
|
||||
$back = $this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk()->json('data.economic_snapshot');
|
||||
$this->assertSame($d['modelo_a_snapshot'], $back['modelo_a_snapshot']);
|
||||
$this->assertSame($d['business_plan_snapshot'], $back['business_plan_snapshot']);
|
||||
$b = json_decode($back['modelo_a_snapshot'], true, flags: JSON_THROW_ON_ERROR)['irpcAnnual'][$d['context_opportunity']];
|
||||
$this->assertSame('ptMzRoyalty', $b['internationalCredits']['positions'][0]['treatyMethod']);
|
||||
$this->assertSame(['numerator' => '6', 'denominator' => '1'], $b['result']['model']['internationalCredit']['positions'][0]['treatyLimit']);
|
||||
$this->assertSame(['numerator' => '702', 'denominator' => '1'], $b['result']['model']['arithmeticBalance']);
|
||||
file_put_contents(base_path('outputs/irpc-pt-mz-credit-20261110/recovered.json'), json_encode($back, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { internationalCase } from './helpers/irpc-international-case.mjs';
|
||||
import { newPtMzRoyaltyPreparation } from '../../resources/js/lib/irpc-international-credit.ts';
|
||||
import {
|
||||
calculateAnnual,
|
||||
recordAnnual,
|
||||
saveAnnualBook,
|
||||
annualBook,
|
||||
annualCurrent,
|
||||
annualHtml,
|
||||
} from '../../resources/js/lib/irpc-annual-settlement.ts';
|
||||
import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts';
|
||||
function treatyCase() {
|
||||
const c = internationalCase();
|
||||
Object.assign(c.b.internationalCredits.positions[0], {
|
||||
country: 'PT',
|
||||
qualificationCountry: 'PT',
|
||||
incomeAmount: '40',
|
||||
treaty: 'yes',
|
||||
treatyMethod: 'ptMzRoyalty',
|
||||
treatyReference:
|
||||
'SYNTHETIC QA PT-MZ12/23(3)a actual royalty qualification, no real treaty decision',
|
||||
treatyPreparation: {
|
||||
...newPtMzRoyaltyPreparation(),
|
||||
gross: '60',
|
||||
from: '2026-01-01',
|
||||
to: '2026-12-31',
|
||||
reference:
|
||||
'SYNTHETIC QA residence certificate, royalty contract and all conditions documented',
|
||||
residentMz: 'yes',
|
||||
beneficialOwner: 'yes',
|
||||
sourcePortugal: 'yes',
|
||||
payerResidentPt: 'yes',
|
||||
noLinkedEstablishment: 'yes',
|
||||
armLength: 'yes',
|
||||
royaltyDefinition: 'yes',
|
||||
nonDigital: 'yes',
|
||||
},
|
||||
});
|
||||
return c;
|
||||
}
|
||||
void test('PT royalty credit derives a6 treaty ceiling from gross60 and leaves national fraction,paid tax and L6 separate', () => {
|
||||
const c = treatyCase(),
|
||||
before = c.d.modelo_a_snapshot,
|
||||
m = calculateAnnual(c.d, c.b),
|
||||
p = m.internationalCredit.positions[0];
|
||||
assert.deepEqual(m.pending, []);
|
||||
assert.deepEqual(p.treatyLimit, { numerator: '6', denominator: '1' });
|
||||
assert.deepEqual(p.eligible, { numerator: '6', denominator: '1' });
|
||||
assert.deepEqual(m.arithmeticBalance, {
|
||||
numerator: '702',
|
||||
denominator: '1',
|
||||
});
|
||||
assert.equal(c.d.modelo_a_snapshot, before);
|
||||
});
|
||||
void test('PT royalty matching rejects wrong country,unknown facts,expired coverage and contradictory gross without silently using the manual limit', () => {
|
||||
for (const patch of [
|
||||
{ country: 'ZA' },
|
||||
{ treaty: 'no' },
|
||||
{ treatyPreparation: { beneficialOwner: '' } },
|
||||
{ treatyPreparation: { sourcePortugal: 'no' } },
|
||||
{ treatyPreparation: { to: '2026-09-01' } },
|
||||
{ treatyPreparation: { gross: '30' } },
|
||||
{ treatyPreparation: { from: '2026-02-30' } },
|
||||
]) {
|
||||
const c = treatyCase(),
|
||||
p = c.b.internationalCredits.positions[0];
|
||||
const q = patch.treatyPreparation;
|
||||
if (q) Object.assign(p.treatyPreparation, q);
|
||||
else Object.assign(p, patch);
|
||||
assert.equal(calculateAnnual(c.d, c.b).arithmeticBalance, null);
|
||||
}
|
||||
});
|
||||
void test('PT royalty ceiling is exact and can be lower than paid tax without creating official use or refund', () => {
|
||||
const c = treatyCase();
|
||||
c.b.internationalCredits.positions[0].treatyPreparation.gross = '60.01';
|
||||
const m = calculateAnnual(c.d, c.b);
|
||||
assert.deepEqual(m.internationalCredit.positions[0].treatyLimit, {
|
||||
numerator: '6001',
|
||||
denominator: '1000',
|
||||
});
|
||||
assert.equal(m.internationalCredit.officialBalancesConsumed, false);
|
||||
});
|
||||
void test('PT royalty limit survives save,recovery and both report consumers; previous documented mode stays unchanged', () => {
|
||||
const c = treatyCase(),
|
||||
b = recordAnnual(c.d, c.b, '2026-11-10T17:00:00+02:00'),
|
||||
d = JSON.parse(
|
||||
JSON.stringify({
|
||||
...c.d,
|
||||
modelo_a_snapshot: saveAnnualBook(c.d, b),
|
||||
}),
|
||||
),
|
||||
back = annualBook(d);
|
||||
assert.equal(annualCurrent(d, back), true);
|
||||
assert.deepEqual(
|
||||
calculateAnnual(d, back).internationalCredit,
|
||||
back.result.model.internationalCredit,
|
||||
);
|
||||
assert.match(annualHtml(d), /IRPC-PT-MZ-royalty-credit\/1/);
|
||||
assert.match(
|
||||
JSON.stringify(
|
||||
createProjectDossierReport(d, {
|
||||
selectedSections: new Set(['finance']),
|
||||
generatedAt: '2026-11-10T17:00:00+02:00',
|
||||
}),
|
||||
),
|
||||
/IRPC-PT-MZ-royalty-credit\/1/,
|
||||
);
|
||||
const old = internationalCase();
|
||||
assert.equal(
|
||||
calculateAnnual(old.d, old.b).internationalCredit.positions[0]
|
||||
.treatyDerivation,
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
||||
void test('PT dividends use the2009 treaty10percent ceiling and interest uses ordinary11 conditions, preserving royalty evidence', () => {
|
||||
for (const method of ['ptMzDividend', 'ptMzInterest']) {
|
||||
const c = treatyCase(),
|
||||
p = c.b.internationalCredits.positions[0];
|
||||
p.treatyMethod = method;
|
||||
Object.assign(p.treatyPreparation, {
|
||||
capitalDefinition: 'yes',
|
||||
governmentInterestExemption: 'no',
|
||||
royaltyDefinition: '',
|
||||
nonDigital: '',
|
||||
...(method === 'ptMzDividend' ? { armLength: '' } : {}),
|
||||
});
|
||||
const m = calculateAnnual(c.d, c.b),
|
||||
r = m.internationalCredit.positions[0];
|
||||
assert.deepEqual(m.pending, []);
|
||||
assert.deepEqual(r.treatyLimit, { numerator: '6', denominator: '1' });
|
||||
assert.equal(r.treatyDerivation.nature, method);
|
||||
assert.match(
|
||||
r.treatyDerivation.source,
|
||||
method === 'ptMzDividend' ? /art6/ : /11/,
|
||||
);
|
||||
const d = {
|
||||
...c.d,
|
||||
modelo_a_snapshot: saveAnnualBook(
|
||||
c.d,
|
||||
recordAnnual(c.d, c.b, '2026-11-10T17:10:00+02:00'),
|
||||
),
|
||||
};
|
||||
assert.match(annualHtml(d), /IRPC-PT-MZ-capital-credit\/1/);
|
||||
assert.match(
|
||||
JSON.stringify(
|
||||
createProjectDossierReport(d, {
|
||||
selectedSections: new Set(['finance']),
|
||||
generatedAt: '2026-11-10T17:10:00+02:00',
|
||||
}),
|
||||
),
|
||||
/IRPC-PT-MZ-capital-credit\/1/,
|
||||
);
|
||||
}
|
||||
});
|
||||
void test('PT capital matching does not presume article11 governmental exemption or classification', () => {
|
||||
for (const patch of [
|
||||
{ capitalDefinition: '' },
|
||||
{ governmentInterestExemption: '' },
|
||||
{ governmentInterestExemption: 'yes' },
|
||||
{ armLength: '' },
|
||||
]) {
|
||||
const c = treatyCase(),
|
||||
p = c.b.internationalCredits.positions[0];
|
||||
p.treatyMethod = 'ptMzInterest';
|
||||
Object.assign(
|
||||
p.treatyPreparation,
|
||||
{ capitalDefinition: 'yes', governmentInterestExemption: 'no' },
|
||||
patch,
|
||||
);
|
||||
assert.equal(calculateAnnual(c.d, c.b).arithmeticBalance, null);
|
||||
}
|
||||
});
|
||||
@@ -18,7 +18,7 @@ $identity = $pdo->query('select current_database() as name,inet_server_port() as
|
||||
if ($identity['name'] !== 'proactive_investment_20261027_test' || (int) $identity['port'] !== 55441) {
|
||||
throw new RuntimeException('Isolated QA identity required.');
|
||||
}
|
||||
$case = ['quota' => 'IrpcEconomicQuotaDraftTest', 'inclusion' => 'IrpcEconomicInclusionDraftTest', 'liquidation' => 'IrpcEconomicLiquidationDraftTest', 'association' => 'IrpcEconomicAssociationDraftTest', 'special-inclusion' => 'IrpcEconomicSpecialInclusionDraftTest'][$argv[2] ?? ''] ?? throw new RuntimeException('Choose quota, inclusion, liquidation or association explicitly.');
|
||||
$case = ['quota' => 'IrpcEconomicQuotaDraftTest', 'inclusion' => 'IrpcEconomicInclusionDraftTest', 'liquidation' => 'IrpcEconomicLiquidationDraftTest', 'association' => 'IrpcEconomicAssociationDraftTest', 'special-inclusion' => 'IrpcEconomicSpecialInclusionDraftTest', 'pt-royalty' => 'IrpcPtMzCreditDraftTest', 'pt-capital' => 'IrpcPtMzCapitalDraftTest'][$argv[2] ?? ''] ?? throw new RuntimeException('Choose an explicit supported QA case.');
|
||||
$argv = ['phpunit', '-c', 'phpunit.investmoz.xml', '--do-not-cache-result', 'tests/Feature/'.$case.'.php'];
|
||||
$argc = count($argv);
|
||||
$_SERVER['argv'] = $argv;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { createProjectDossierReport } from '../resources/js/lib/project-dossier-report.ts';
|
||||
import fs from 'node:fs';
|
||||
import { internationalCase } from '../tests/frontend/helpers/irpc-international-case.mjs';
|
||||
import { recordAnnual, saveAnnualBook, annualBook, calculateAnnual, annualHtml } from '../resources/js/lib/irpc-annual-settlement.ts';
|
||||
import assert from 'node:assert/strict';
|
||||
const capital = ['dividend','interest'].find(k=>process.argv.includes(k));
|
||||
const out = new URL(capital ? '../outputs/irpc-pt-mz-'+capital+'-20261110/' : '../outputs/irpc-pt-mz-credit-20261110/', import.meta.url);
|
||||
fs.mkdirSync(out, { recursive: true });
|
||||
if (process.argv[2] === 'recovered') {
|
||||
const d = JSON.parse(fs.readFileSync(new URL('recovered.json', out), 'utf8'));
|
||||
const b = annualBook(d), m = b.result.model;
|
||||
assert.deepEqual(calculateAnnual(d, b).internationalCredit, m.internationalCredit);
|
||||
const html = annualHtml(d);assert.match(html, /IRPC-PT-MZ-(royalty|capital)-credit\/1/);
|
||||
const report=createProjectDossierReport(d,{selectedSections:new Set(['finance']),generatedAt:'2026-11-10T17:10:00+02:00'});
|
||||
assert.match(JSON.stringify(report),/IRPC-PT-MZ-(royalty|capital)-credit\/1/);
|
||||
fs.writeFileSync(new URL('report.html', out), html);
|
||||
fs.writeFileSync(new URL('verification.json', out), JSON.stringify({ synthetic: true, apiRecovered: true, dossierReport: true, currentRecalculation: true, html: true, quota: m.internationalCredit.positions[0].treatyLimit, balance: m.arithmeticBalance, activeChanged: false }, null, 2));
|
||||
} else {
|
||||
const c = internationalCase();
|
||||
Object.assign(c.b.internationalCredits.positions[0],{country:'PT',qualificationCountry:'PT',incomeAmount:'40',treaty:'yes',treatyMethod:'ptMzRoyalty',treatyReference:'SYNTHETIC QA qualified PT-MZ12/23(3)a ordinary royalties',treatyPreparation:{gross:'60',from:'2026-01-01',to:'2026-12-31',reference:'SYNTHETIC QA residence certificate and royalty agreement covering conditions',residentMz:'yes',beneficialOwner:'yes',sourcePortugal:'yes',payerResidentPt:'yes',noLinkedEstablishment:'yes',armLength:'yes',royaltyDefinition:'yes',nonDigital:'yes'}});
|
||||
if(capital) {const p=c.b.internationalCredits.positions[0];p.treatyMethod=capital==='dividend'?'ptMzDividend':'ptMzInterest';p.treatyReference='SYNTHETIC QA explicit PT-MZ article'+(capital==='dividend'?'10 updated2009':'11 ordinary non-governmental')+'/23(3)a qualification';p.treatyPreparation.reference='SYNTHETIC QA residence certificate and '+capital+' contract, source and conditions documented';Object.assign(p.treatyPreparation,{capitalDefinition:'yes',governmentInterestExemption:'no'});}
|
||||
const b = recordAnnual(c.d, c.b, '2026-11-10T14:00:00+02:00');
|
||||
fs.writeFileSync(new URL('fixture.json', out), JSON.stringify({ ...c.d, modelo_a_snapshot: saveAnnualBook(c.d, b) }));
|
||||
}
|
||||
Reference in New Issue
Block a user