Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aed020d19e | ||
|
|
1649710cf7 | ||
|
|
e07f89da3d | ||
|
|
ab2ff2fdbc | ||
|
|
a2122dc34c | ||
|
|
d37fffb2d2 | ||
|
|
17d633c99c | ||
|
|
8f1ab24b22 |
@@ -775,3 +775,148 @@ Referência actual após a entrega `5aaf1a56`: percurso normal demonstrado até
|
||||
| Norma sectorial de provisões reguladas | Provisão200 de uma entidade financeira sujeita ao28d não herda os1,5%/6% do regime ordinário29. | Identificar sector,regulador,norma de supervisão aplicável e saldos/condições necessários,antes da implementação específica. A fonte oficial fornecida é aceite;falta a regra concreta do caso,não certificação genérica da fonte. Só provisão regulada respectiva;provisões ordinárias demonstradas preservadas. |
|
||||
|
||||
**Base da decisão operacional:** o âmbito demonstrado e as suas limitações permanecem disponíveis na interface e nas exportações;as provas aceites mantêm validade. Um fecho operacional delimitado pode referir esse âmbito,com estas extensões/documentos fora da cobertura e retoma por caso. Esta consolidação **não declara L6 integralmente concluído nem regista uma decisão de fecho ainda não tomada**. Permite preparar o avanço paraL7 sem condicionar os casos independentes à resolução de todo este saldo. Benefícios/isenções/taxas reduzidas/tributações autónomas e operações especiais mantêm âmbitoL7;retenções,pagamentos,créditos e saldo anual mantêm âmbitoL8. As dez dúvidasL5 só afectam dependências efectivas e não foram pesquisadas novamente.
|
||||
|
||||
## 26/10/2026 — L6 operacional no âmbito demonstrado e delimitação de L7
|
||||
|
||||
**Decisão expressa da Tempo:** L6 fica operacional no âmbito demonstrado disponível em `5aaf1a56`, com limitações explícitas. Não é conclusão integral de L6 ou do IRPC. Os cinco grupos de código e cinco grupos documentais da secção «saldo consolidado de L6» permanecem separados, com exemplos e condições de retoma. As notas anteriores que deixavam a decisão operacional por tomar conservam o seu valor histórico; esta decisão é posterior. As provas aceites são reutilizadas. As pendências de L5/L6 só impedem tratamentos que dependam delas.
|
||||
|
||||
**Estado deste incremento:** delimitação documental de L7, sem novo cálculo, instalação, migração, importação ou alteração de dados activos. A colecta normal entregue mantém-se distinta do saldo a pagar/recuperar. Retenções, pagamentos, aplicação anual de créditos e liquidação final permanecem em L8. Recibo: `simulations/irpc-l7-scope-20261026.json` (relativo a `docs/investmoz/`).
|
||||
|
||||
### Dados existentes e fronteiras de integração
|
||||
|
||||
| Reutilização | Contrato para L7 e limite |
|
||||
| --- | --- |
|
||||
| Oportunidade/dossier: `context_opportunity`, `context_opportunity_snapshot`, `context_applicability_snapshot`, `context_reuse` | Conservar origem e data, selecção de campos compatíveis e edições deliberadas; `context-inheritance.ts` e `dossier-prefill.tsx` já sustentam esta reutilização. Associação documental a oportunidade/âncora não confirma implantação ou incentivo. |
|
||||
| `sector_id`, `province_id`, `district_id`, `admin_post_id`, `locality_id` e respectivas designações | Servem para identificar candidatos e pedir apenas elementos em falta. Confirmar actividade efectivamente exercida, estabelecimento/projecto e parcela abrangida por documentos do caso. Localização, polígono, DUAT ou código sectorial isolados não concedem benefício. |
|
||||
| Sujeito, NUIT, residência/EP, período, início de actividade/exploração e dados do plano | Reutilizar valores declarados e respectivas provas. Data prevista no dossier não substitui início efectivo quando esse for o termo inicial da norma. Distinguir conhecido, ausência declarada e desconhecido. |
|
||||
| `business_plan_snapshot`, livro `modelo_a_snapshot.irpcNormal` e versões L6 | Receber lucro/base/colecta e parcelas identificadas, com chave e versão de origem. Só alterar o ponto previsto pela norma: ajustamento ao lucro, dedução à base, taxa por parcela ou tributação autónoma separada. Não alterar nem recalcular silenciosamente históricos. |
|
||||
| Activos, quotas anteriores e despesas já registadas | Reutilizar os mesmos identificadores e montantes; calcular apenas o efeito adicional permitido. Não repetir o acréscimo de uma despesa nem deduzir duas vezes a amortização do mesmo activo. Um caso dependente de regra L6 não implementada conserva essa dependência específica. |
|
||||
| Preparação M20/M22 e aritmética racional existentes | Conservar montante exacto, unidade/moeda e parcela. Transporte só com correspondência demonstrada para a edição; campo desconhecido, fracção não representável ou divergência editorial não invalida o cálculo independente. Não arredondar por conveniência. |
|
||||
|
||||
O motor actual de matéria colectável não subtrai benefícios positivos livres: exige regra, condições, limite e ordem. A colecta normal cobre a taxa geral no recorte demonstrado; escolher «outro tratamento» não implementa uma taxa especial. A presença de campos ou de fontes no portal não equivale a execução de L7.
|
||||
|
||||
### Famílias de tratamentos a implementar por casos compatíveis
|
||||
|
||||
As referências seguintes delimitam a regra e o ponto de integração; **não constituem benefícios concedidos nem cobertura executável nova**. O exercício do caso, alterações aplicáveis e duração individual ficam associados à versão da regra. Não se transportam taxas temporárias para outro período.
|
||||
|
||||
| Família / fonte identificada | Condições e período a guardar | Efeito e exemplo de dúvida delimitada / condição de retoma |
|
||||
| --- | --- | --- |
|
||||
| **Despesas com tributação autónoma** — CIRPC, Lei34/2007, art.61(4), com art.36(1)g; PDF17/p768(71) | Natureza legal documentada da despesa não devidamente documentada, confidencial ou ilícita; valor e exercício; taxa de 35% da disposição e versão aplicável ao período. Não classificar pela simples falta de ficheiro anexado. | Parcela autónoma separada da colecta normal; reutilizar o acréscimo36g já feito, sem duplicação. Ex.: despesa100 já acrescida em L6 → parcela autónoma35 no caso qualificado; não é saldo final. Se só falta anexo, pedir a caracterização/prova da despesa e manter indeterminado apenas este tratamento. |
|
||||
| **Mais-valias autónomas** — Lei12/2025, art.2, CIRPC61-A; art.3 revoga39/47; art.6 vigora em01/01/2026; PDF20/p2180(20) | Alienação, activo, datas, realização/valor fiscal, origem contabilística, período e parcela identificados; taxa32% do61-A. Separar eventos anteriores a2026. | Apurar parcela autónoma, reconciliando o que já integra o resultado L6, sem dupla incidência ordinária/autónoma nem compensação presumida de perdas. Ex.: ganho100 incluído no resultado exige identificar a sua parcela antes de integrar a colecta autónoma32. Retoma: implementar essa reconciliação e a regra de apuramento aplicável ao activo; não bloqueia despesas autónomas ou benefícios independentes. |
|
||||
| **Isenções e redução por natureza da entidade** — CIRPC9–14; cooperativas no art.12, PDF5/p768(59), e taxa geral61(1) | Tipo efectivo da entidade, rendimentos elegíveis/excluídos, destino dos rendimentos, constituição e reconhecimento apenas onde exigido pela disposição; exercício e norma aplicável. Art.12 refere cooperativas agrárias, de artesanato e culturais e redução de50% da taxa geral; não todas as cooperativas. Arts.12(2)/14 separam rendimentos sujeitos a retenção. | Isenção ou taxa reduzida apenas na parcela coberta; actividade comercial acessória não se torna isenta por designação da entidade. Ex.: cooperativa com actividade elegível e outra não abrangida exige separar rendimentos e custos. Retoma: classificação documental e segregação da parcela, sem transportar a dispensa para retenções L5 ou liquidar créditos L8. |
|
||||
| **Amortização acelerada** — CBF, Lei4/2009, art.16; compilaçãoAPIEX p72 | Imóveis novos usados no projecto; imóveis reabilitados e máquinas/equipamentos industriais/agro-industriais nas condições da disposição; enquadramento CBF3/9/10 quando aplicável, entrada em uso, taxa normal, base, quota contabilizada e quotas anteriores. Incremento de50% sobre a taxa normal, não cinquenta pontos percentuais. | Efeito no ajustamento ao lucro e, através da cadeia L6, na base/colecta. Ex.: taxa normal10% → taxa acelerada15%, antes das restantes condições/limites; não autoriza uma segunda dedução integral. Retoma por activo com classificação/documentos e conciliação de quotas/custo disponíveis; tabelas L6 em falta bloqueiam só o activo dependente. |
|
||||
| **Deduções e majorações de despesas/investimentos** — CBF17–19; compilaçãoAPIEX pp73–74 | Tecnologia de ponta, formação de trabalhadores moçambicanos e despesas elegíveis de utilidade pública: natureza, base, exercício inicial, janela dos primeiros cinco anos/exercícios conforme artigo, limites, exclusões, ordem e não cumulaçãoCBF4. Distinguir dedução à matéria colectável de majoração de custo. | Efeito no ponto exacto previsto pela disposição. Ex.: formação sem prova do tipo não permite escolher entre o limite5% e o ramo10% para novas tecnologias do art.18. Retoma: identificar tipo/base de limite e conciliar a despesa já contabilizada; não converter percentagem em dedução livre. |
|
||||
| **Crédito fiscal por investimento** — CBF15; compilaçãoAPIEX pp71–72 | Investimento novo elegível, exclusões, início, Maputo/outras províncias como uma das condições, parcela da colecta atribuível ao projecto e prazo de utilização/transporte de cinco exercícios. Taxas5%/10% distinguem os ramos da disposição, sem direito automático por localização. | **L7 identifica origem, elegibilidade e crédito potencial; L8 aplica o crédito anual, limites/saldos e liquidação.** Ex.: projecto situado fora de Maputo, sem discriminação do investimento elegível, não gera automaticamente10% de crédito. Retoma: base elegível e calendário documentados; utilização anual aguarda o mecanismo L8. |
|
||||
| **Tratamentos sectoriais/territoriais CBF** — infra-estruturas20–22; agricultura/pescas27–29; turismo30–33; parques de ciência34–35; grandes projectos36–38; zonas de rápido desenvolvimento39–44; ZFI45–46; ZEE47–48 | Seleccionar a disposição de IRPC efectivamente pertinente, actividade/projecto, delimitação/estabelecimento e estatuto comprovados, data de autorização/início quando exigidos, escalões, duração, cumulação e cessaçãoCBF49–52. ZFI46 e ZEE48 são os artigos de impostos sobre rendimento. Não tratar benefícios exclusivamente aduaneiros como benefícios IRPC. | Isenção, redução ou dedução por parcela e intervalo próprio, em vez de taxa comum ao sector/localização. Ex.: endereço numa ZEE sem estatuto documentado deixa o ramo ZEE pendente; o cálculo normal independente continua. CIRPC61(2) na Lei20/2022 tem termo31/12/2025: não presumir prorrogação para2026. Retoma de cada ramo: condições e cronologia da disposição específica preenchidas, com regra versionada; não exigir pesquisa repetida de todos os sectores. |
|
||||
| **Operações e regimes especiais** — CIRPC54–56 (entradas de activos, fusões/cisões e sócios), transferência de perdas41-A; regimes sectoriais específicos do acervo | Tipo de operação, intervenientes, residência, datas, activos/passivos/valores fiscais e continuidade; identificar diploma sectorial/artigo e regra aplicável antes de escolher tratamento. Não inferir neutralidade por chamar «fusão» à operação nem aplicar regime mineiro/petrolífero por rótulo sectorial. | Continuidade/ajustamento/tributação diferida ou parcela própria conforme norma, mantendo bases históricas. Ex.: perda recebida de outra sociedade não é perda própria ordinária41 de L6. Retoma: correspondência específica41-A e operação documentada; regras sectoriais sem artigo correspondido ficam candidatas, sem taxa provisória. Não há bloqueio transversal de L7. |
|
||||
|
||||
### Registo por tratamento e demonstração a exigir ao código novo
|
||||
|
||||
Cada tratamento terá: identificador estável; sujeito/NUIT; oportunidade/projecto/estabelecimento e parcela; contexto herdado e divergências; fonte/exemplar/hash/artigo/versão; intervalo de vigência e período do caso; facto que inicia/termina a duração; condições individualizadas em «sim/não/desconhecido» com prova ou ausência declarada; título/reconhecimento somente quando a regra o exige; base elegível, taxa, limite, ordem e compatibilidade com outros tratamentos; resultado normal de origem; efeito adicional e ponto da cadeia; moeda/conversão e pressupostos; montante exacto; motivos de exclusão/informação em falta; versão/histórico e dependência concreta.
|
||||
|
||||
Os estados «candidato», «não aplicável», «informação em falta» e «calculado por regra implementada» não se confundem. Ausência declarada pode produzir efeito zero justificado; desconhecido não produz benefício zero nem benefício presumido. Uma condição negativa exclui o tratamento e conserva o percurso normal quando os seus dados são suficientes. Com potencial benefício ainda indeterminado, apresentar o cenário normal de referência e a parcela pendente sem declarar total fiscal definitivo. Mudança de sector/localização/documento invalida apenas a correspondência dependente e pede confirmação de reutilização; conserva o original e as edições deliberadas.
|
||||
|
||||
**Primeiro incremento delimitado para implementação:** qualificação comum e segregação de efeitos, acompanhadas do caso35% do61(4), com despesa já ajustada36g e caso de informação insuficiente. É independente de transporte M20/M22 não correspondido e de amortizações L6 em falta. **Incremento compatível seguinte:** cooperativa abrangida pelo12 com parcela elegível separada e amortização acelerada16 para activo já suportado em L6; cada caso só acompanha a entrega se demonstrado. Mais-valias61-A, deduções17–19, ramos sectoriais e operações especiais seguem separadamente quando as respectivas parcelas/regras estiverem correspondidas. Crédito15 prepara direito potencial em L7 e contrato de passagem para L8, sem antecipar liquidação anual.
|
||||
|
||||
Para cada nova regra: condição satisfeita, negativa, informação em falta, período incompatível/benefício expirado, sobreposição com ajustamento existente e alteração de contexto. Demonstrar apenas o delta: cálculo → gravação → recuperação → relatório, incluindo fonte, período, condições, efeito no lucro/base/colecta ou parcela autónoma e saldo final L8 por determinar. Recuperar históricos anteriores sem os alterar; não duplicar ajustamentos ao voltar a guardar. Reutilizar as provas aceites; não reabrir L3, ISPC, câmbio ou percursos L5/L6 independentes.
|
||||
|
||||
### Fontes consultadas e pendências delimitadas
|
||||
|
||||
Reutilizado o inventário autorizado de **8143ficheiros**, sem nova varredura de pastas. Para delimitação foram consultados os originais CIRPC/alterações já arquivados, a Lei4/2009 local e a compilação oficial [APIEX — Legislação de Investimentos em Moçambique](https://pt.apiex.gov.mz/wp-content/uploads/2025/02/LEGISLACAO-DE-INVESTIMENTOS-EM-MOCAMBIQUE.pdf), que reúne Lei8/2023, Decreto8/2024 e CBF4/2009. Disponibilidade, situação documental/jurídica e uso no cálculo continuam estados independentes. O acesso actual à cópia CBF supera a indisponibilidade assinalada em notas antigas; não activa regra nem apaga a nota histórica. Artigos, páginas, hashes e limites no recibo. A compilação não dispensa o período/alterações de cada tratamento, nem cria validação jurídica genérica adicional.
|
||||
|
||||
**Código por implementar em L7:** qualificação e persistência específicas; efeitos segregados; regras das famílias acima, por parcelas; conciliação sem duplicação; relatório/exportação correspondente. **Documentação por caso:** estatuto/reconhecimento ou enquadramento individual quando a fonte o exige; identificação de parcela/limite/cronologia; norma sectorial ainda sem correspondência; edição/campo de transporte afectado. Cada uma conserva exemplo e condição de retoma na linha correspondente. Não é necessário resolver todos os documentos para começar o primeiro incremento independente. L6 operacional não elimina este desenvolvimento; L7 delimitado não é L7 implementado; L8 conserva a liquidação final.
|
||||
|
||||
## 26/10/2026 — L7: qualificação, despesas autónomas e casos compatíveis em QA
|
||||
|
||||
**QA, sem instalação.** Base instalada preservada `5aaf1a56`; delimitação `d37fffb2`; ramo `codex/irpc-l7-common-autonomous-qa-20261026`, fotografia opcional `IRPC-normal-adjustments/10`. L6 continua operacional no âmbito demonstrado, com os cinco grupos de código e cinco documentais preservados. A implementação abaixo acrescenta apenas os tratamentos demonstrados; não conclui L7 nem o IRPC. Saldo final, retenções, pagamentos e aplicação anual de créditos permanecem em L8.
|
||||
|
||||
**Qualificação comum executável:** reutiliza sujeito/NUIT, âmbito, período, origem da oportunidade/dossier, sector e território; guarda condições, prova, fonte/artigo e período por tratamento. «Informação em falta», «ausência declarada», «não aplicável/condição negativa» e «calculado» têm resultados distintos. Desconhecido não vira zero. Período incompatível, identidade por reconciliar ou contradição afectam só o resultado dependente. A localização não escolhe taxa nem activa benefício. Os snapshots de origem ficam internos; o relatório apresenta contexto legível e as condições documentadas.
|
||||
|
||||
**Despesas61(4):** cada parcela aponta para uma linha `undocumented` do mapa36(1)g de L6, com acréscimo integral já calculado. Montante, documento e linha são reutilizados; L7 não introduz outro acréscimo nem outra despesa. A classificação legal e incidência são declaradas com prova própria; falta de anexo não classifica uma despesa. O imposto autónomo usa35% apenas nos casos qualificados. Duplicação da referência, parcela não correspondida, ausência contraditória ou informação insuficiente deixam o imposto reconciliado indeterminado; as parcelas conhecidas permanecem discriminadas. Condição negativa documentada conserva o ajustamentoL6 e não aplica imposto autónomo à parcela.
|
||||
|
||||
**Cooperativas12/14:** agrárias, artesanato ou culturais, residentes, com base ordinária integralmente elegível e ausência documentada de rendimentos sujeitos a retenção, aplicam redução de50% à taxa geral32%, ou16%. Não depende de seleccionar um sector semelhante. A qualificação especial pode coexistir com a opção «outro tratamento» da colectaL6: não exige fingir que a taxa reduzida é regime geral. Parcela mista, rendimentos retidos, outra entidade ou ausência contraditória conservam pendência própria; não recebem redução global presumida. O imposto autónomo de despesas não é reduzido por esta taxa.
|
||||
|
||||
**CBF16:** reutiliza identificadores e valores dos activosL6 suportados; imóvel novo do projecto ou máquinas industriais/agro-industriais das categorias correspondidas, com enquadramentoCBF3/9 e reconhecimento10 quando exigido (ou excepção identificada). Recorte inicial: primeiro exercício anual civil2026, método constante pela taxa normal máxima da tabela, activo desde01/01/2026, custo histórico novo, sem quotas anteriores/saída e sem cumulação de outros benefícios. Incrementa a taxa normal em50% e reutiliza limites de contabilização/saldo fiscal. Deduz apenas a diferença entre o mapa normal e o acelerado, sem alterar o activo de origem, os documentos ou os saldos oficiais. Quotas constantes gerais e demais cálculosL6 conservam o comportamento anterior quandoL7 está ausente.
|
||||
|
||||
| Caso sintético recuperado da API QA | Lucro/base e colecta de referênciaL6 | EfeitoL7 demonstrado | Resultado e limite |
|
||||
| --- | --- | --- | --- |
|
||||
| Despesa100 já acrescida36g | Lucro/base3230;colecta1033,60MZN | Novo ajustamento ao lucro0;imposto autónomo35 | Colecta combinada1068,60MZN;saldo finalL8indeterminado |
|
||||
| Classificação da mesma despesa em falta | Lucro/base3230;colecta1033,60MZN preservados | Imposto autónomo indeterminado | Colecta combinada indeterminada;sem perda dos cálculos independentes |
|
||||
| Condição negativa documentada na parcela | Ajustamento36g100 preservado | Parcela não aplicável;imposto autónomo0 justificado | Não confunde condição negativa com informação em falta |
|
||||
| Ausência declarada de despesas autónomas | Lucro/base3130;colecta1001,60MZN | Ausência com suporte;imposto autónomo0 | Ausência contraditória com despesa36g fica pendente |
|
||||
| Cooperativa integralmente abrangida | Base3130;colecta geral1001,60MZN | Taxa16%;colecta500,80MZN | Base/proveitos não alterados;sem retenções/créditos abatidos |
|
||||
| Máquina industrial existente:base1000,taxa10%,quota contabilística120 | Quota normal100;lucro/base6260;colecta2003,20MZN | Quota acelerada150,mas dedução limitada120;diferença adicional20 | Lucro/base6240;colecta1996,80MZN;sem deduzir50 nem150 outra vez |
|
||||
|
||||
**Cálculo → gravação → recuperação → relatório:** fotografia10 opcional no mesmo livro/snapshot, chave com entradas/contexto e histórico imutável anterior. SemL7, a fotografia9 aceite e a sua chave/totais permanecem iguais. Recalcular não acumula imposto nem duplica o acréscimo. HTML e dossier financeiro mostram referênciaL6, efeitosL7, parcelas autónomas, fonte, condições, período e limitações; recuperação e download demonstrados no componente real. Uma mudança de origem/entradas torna a fotografia anterior histórica; não altera o registo anterior. M20/M22 conservam a preparaçãoL6 de referência: **este incremento não transporta efeitosL7 para campos oficiais por aproximação**, nem resolve as divergências documentais existentes.
|
||||
|
||||
**Provas novas:** Wayfinder `--with-form` gerou routes/actions pelo wrapper QA; TypeScript e build QA passaram. Dezanove testes dirigidos novos passaram, incluindo comparação exacta com a fotografia9 aceite, duplicação, período curto, opção especial de cooperativa, ausência contraditória, dados em falta e contexto apresentado sem despejar snapshots internos. API privada:1teste/108asserções, `simulator_fiscal_delta_20261021_test`,127.0.0.1:55441, transacção com rollback e guarda de identidade/base; seis casos recuperados com plano/livro/históricos idênticos. UI do componente real: alteração de classificação, informação em falta, ausência, cooperativa mista, cumulação pendente, gravação/recuperação local e exportação; sem erros de página. A prova local é distinta da API. Não houve testes/escrita no activo nem repetição das suites funcionais aceites de L3, ISPC, câmbio ou L5/L6.
|
||||
|
||||
**Entrega agrupada preparada:** qualificação + despesas autónomas, cooperativa integralmente elegível e amortizaçãoCBF16 no recorte acima. Despesa autónoma e cooperativa também foram demonstradas juntas:parcela35 sem redução,colecta sobre a base516,80 e combinada551,80MZN no exemplo de base3230. Isto não autoriza cumulação cooperativa+CBF16: essa combinação mantém resultado dependente indeterminado. A futura instalação segue o procedimento Git existente, com backup/restauro fresco e conferência do delta; não foi executada nesta passagem.
|
||||
|
||||
**SaldoL7 na mesma matriz:**
|
||||
|
||||
| Natureza | Ainda fora da cobertura / exemplo | Condição concreta de retoma |
|
||||
| --- | --- | --- |
|
||||
| Código | Despesa autónoma fora de linha36g calculada ou parcela ainda não segregada | Implementar origem/segregação correspondente e prova da incidência;não copiar montante para uma segunda despesa |
|
||||
| Código | Cooperativa com actividade abrangida e outra não abrangida,ou rendimento sujeito a retenção | Segregar proveitos/custos/base e aplicar o tratamento apenas à parcela elegível;L5 conserva a retenção |
|
||||
| Código | CBF16 em imóvel reabilitado,outra categoria,quota inferior à máxima,método degressivo,duodécimos,quotas anteriores ou exercício posterior | Corresponder regra e cronologia respectivas e reutilizar o activo/quotas existentes;pendênciaL6 limita apenas o activo dependente |
|
||||
| Código/documento por caso | Cooperativa+CBF16 ou outro benefício positivo a cumular | Identificar compatibilidade,ordem e limites específicos;implementar a combinação,sem presumir soma de benefícios |
|
||||
| Código | Mais-valias61-A,demais isenções/deduçõesCBF17–19,regimes sectoriais/territoriais e operações especiais | Implementar a família/parcelas já delimitadas na secção anterior;período e fonte específicos,sem nova pesquisa transversal |
|
||||
| Documento por caso | Estatuto/título/excepçãoCBF ou prova das condições em falta;endereçoZEE sem estatuto | Juntar o elemento que a disposição exige ou registar condição negativa;localização isolada permanece insuficiente |
|
||||
| Transporte/documento | CampoM20/M22 para efeitoL7,edição divergente ou representação não correspondida | Correspondência do campo/edição e regra de representação demonstradas;preservar o cálculo independente exacto |
|
||||
| ÂmbitoL8 | Direito potencial ao créditoCBF15,aplicação anual de créditos,retenções,pagamentos e saldo final | Executar o mecanismo próprioL8;nenhuma dedução/compensação anual é presumida neste lote |
|
||||
|
||||
Fontes reutilizadas: inventário autorizado8143ficheiros; originaisCIRPC/alterações e CBF/compilaçãoAPIEX já identificados na delimitação,com hashes conservados. Sem activação por consulta ou revalidação jurídica genérica. Recibo: `docs/investmoz/simulations/irpc-l7-common-qa-20261026.json`. Provas locais: `outputs/irpc-l7-common/`; reprodução dirigida: `node --test tests/frontend/irpc-special.test.mjs`, `php tools/irpc-special-qa.php routes`, `php tools/irpc-special-qa.php test`, `tsc --noEmit`, build com `INVESTMOZ_QA_BUILD=1`.
|
||||
|
||||
## 26/10/2026 — preparação da entrega L7 e preservação do main concorrente
|
||||
|
||||
A entrega do âmbito QA `ab2ff2fd` integra o `main` concorrente `a2122dc3`, sem substituir as alterações de apresentação/navegação. Os seis ficheiros de execução L7 conservam exactamente o código QA;os oito ficheiros concorrentes conservam exactamente o código do main. Reutilizadas as provas19testes/API108/UI/tipos/build de L7. O conflito documental foi resolvido recuperando586linhas de histórico do manual que tinham sido removidas no merge concorrente,sem apagar a sua notaV2-01 no CSV. As3555linhas mantêm-se,com o único delta fiscal emAUD-SIM-INT02. O registo de instalação só será actualizado após backup/restauro fresco,conferência do destino e conclusão da entrega Git;esta nota não a antecipa.
|
||||
|
||||
## 26/10/2026 — primeira entrega agrupada L7 instalada pelo Git
|
||||
|
||||
Instalada `e07f89da3d59d06aa1b8c50c22a478b7b167bfdd` (integração do código QA `ab2ff2fdbcbe6fb94f03e4bc4cc7ccbd647d94fc` com o main concorrente`a2122dc3`),com `5aaf1a56f9d928331364fcc8b0d1528e51dba327` preservado como versão anterior. Os seis ficheiros de execução L7 são exactamente os da prova QA aceite;as sete alterações concorrentes de apresentação/navegação e o respectivo teste foram preservados. Recuperadas586linhas de histórico do manual removidas no merge concorrente;notaV2-01 conservada,sem alterar o seu conteúdo.
|
||||
|
||||
Backup fresco `2026-10-26T10:55:59Z`;restauro isolado sem rede/55441 verificou174tabelas por contagem/checksum e369ficheiros/configuração. Conferidos13ficheiros de execução do delta,50protegidos e31originais. Schema,roles/grants e permissões mantêm-se;172tabelas de negócio iguais ao backup. Cache/sessões reconciliadas por eventos operacionais e acessos públicos,sem inferir perda por RLS. A versão activa e a anterior foram preservadas durante o arquivo conferido de dependências antigas para recuperar espaço;nenhum dado,original ou backup foi eliminado.
|
||||
|
||||
Revisão/manifest público,marcadoresL7/L6/câmbio,assets e simuladorHTTP200 conferidos. Procedimento Git concluído;provas funcionais aceites19testes/API108/UI/tipos/build reutilizadas. Os controlos automáticos obrigatórios da instalação ficaram registados no recibo,sem nova ronda manual dos casos aceites. Sem migrações,importações,recálculo de históricos ou escrita privada sintética no activo.
|
||||
|
||||
Disponíveis apenas qualificação e tratamentos demonstrados:despesas61(4) sobre36g já ajustado,cooperativas12 integralmente abrangidas eCBF16 no recorte documentado. L6 permanece operacional no âmbito aceite;as suas pendências condicionam só dependentes. L7/IRPC não estão integralmente concluídos;localização não concede benefício;saldo final permaneceL8. O estado anterior deQA sem instalação é histórico. Recibo:`docs/investmoz/simulations/irpc-l7-common-delivery-20261026.json`.
|
||||
|
||||
## 26/10/2026 — saldo concreto de L7 após a primeira entrega agrupada
|
||||
|
||||
O âmbito demonstrado compreende qualificação comum, imposto autónomo61(4) sobre parcelas36g já calculadas emL6, cooperativas12 integralmente abrangidas e amortizaçãoCBF16 nos activos/período/método expressamente suportados. L7 permanece parcial. Este saldo distingue implementação de prova documental por caso; não cria outra matriz nem exige revalidação genérica das fontes aceites. L6 mantém o estado operacional delimitado e as suas pendências; só condiciona tratamentos que efectivamente dependam delas.
|
||||
|
||||
### Código ainda por implementar
|
||||
|
||||
| Tratamento / caso fora da cobertura | Exemplo | Condição concreta de retoma |
|
||||
| --- | --- | --- |
|
||||
| Despesas autónomas fora de parcela36g calculada e segregações adicionais | Despesa100 com apenas60 correspondidos no mapa de origem,ou encargo não incluído no resultado de partida | Implementar origem/parcela e reconciliação próprias,documentar incidência61(4) e impedir nova contabilização/acréscimo da mesma despesa. O ramo já entregue36g não é reaberto. |
|
||||
| Cooperativas com rendimentos mistos/retidos;demais isenções por natureza da entidade,CIRPC9–14 | Cooperativa com actividade agrária e serviços não abrangidos;associação com rendimentos comerciais acessórios | Segregar proveitos,custos e base elegível e implementar o artigo específico. Não reduzir a base inteira nem estender a redução às retençõesL5. |
|
||||
| ExtensõesCBF16 e combinações de benefícios | Imóvel reabilitado,método degressivo,quota inferior à máxima,duodécimos,quotas anteriores,ano posterior,cooperativa+CBF16 | Corresponder a regra temporal/método/contabilização e a compatibilidade/ordem/limite da combinação;reutilizar activo e quotas. Tabela ou casoL6 em falta impede apenas o activo dependente. |
|
||||
| Mais-valias autónomas61-A e operações especiais | Ganho100 já incluído no resultado em2026;entrada de activos/fusão;perda transferida de outra sociedade | Implementar apuramento/parcela e reconciliação com resultadoL6,sem dupla incidência ou compensação de perdas presumida;para operações,aplicar54–56/41-A e preservar valores históricos. |
|
||||
| Deduções/majoraçõesCBF17–19 e crédito potencialCBF15 | Formação sem ramo/base de limite;investimento novo com activos elegíveis e excluídos | Implementar elegibilidade,base,limite,ordem,janela temporal e não cumulação. CBF15 emL7 delimita direito/origem/crédito potencial;utilização anual,limitação por créditos/saldos e liquidação ficam emL8. |
|
||||
| Regimes sectoriais/territoriais e disposições especiais | Projecto emZEE sem tratamentoIRPC correspondido;actividade mineira/petrolífera com regime próprio | Implementar a disposição/versão/período aplicáveis ao projecto e à parcela (CBF20–48 ou diploma específico). Endereço/código sectorial só identifica candidato;benefício aduaneiro não se transforma em benefícioIRPC. |
|
||||
| Transporte de efeitosL7 paraM20/M22 | Imposto autónomo ou redução calculados mas sem campo/edição correspondente | Implementar apenas a correspondência demonstrada e a representação aplicável;conservar os montantes exactos e a preparaçãoL6 de referência,sem campo/taxa provisórios. |
|
||||
|
||||
### Dependências documentais que condicionam apenas o caso afectado
|
||||
|
||||
| Elemento em falta / dúvida concreta | Exemplo | Condição de retoma |
|
||||
| --- | --- | --- |
|
||||
| Classificação/incidência,parcela e período da operação | Há uma despesa36g e falta qualificar61(4);ou há actividade elegível e outra não abrangida | Associar prova/declaração da natureza e parcela ao exercício correcto. Informação em falta continua indeterminada;condição negativa e ausência declarada têm suporte próprio. Não inferir pela falta de anexo. |
|
||||
| Estatuto e reconhecimento exigidos pela disposição | Endereço numaZEE sem estatuto do projecto;CBF16 sem instrumento10 ou norma de excepção | Juntar o elemento concreto exigido ou documentar a condição negativa/excepção aplicável. Não pedir aprovador ou parecer jurídico genérico adicional. |
|
||||
| Norma/período/compatibilidade específicos ainda não correspondidos | Redução com termo31/12/2025 pretendida em2026;cumulação cooperativa+CBF16 | Disposição de vigência/prorrogação efectiva ou correspondência da combinação e seus limites. Sem informação nova,não repetir pesquisa transversal;prosseguir com os restantes casos. |
|
||||
| Edição,campo ou representação do formulário | EfectoL7 com campoM20/M22 não identificado ou fracção sem regra de representação | Identificar exemplar/edição,instrução/campo e forma de representar o valor;limitar a pendência ao transporte afectado. O cálculo independente mantém-se disponível. |
|
||||
|
||||
**Limites conservados:** localização não concede benefícios automaticamente;benefício desconhecido não é zero;colecta normal,L7 e imposto autónomo permanecem discriminados. Retenções,pagamentos,aplicação anual de créditos e saldo final a pagar/recuperar continuam emL8. As provas aceites não são invalidadas por esta lista nem por uma dúvida documental num caso independente.
|
||||
|
||||
## 26/10/2026 — reconciliação do estado servido L7 e capacidade do instalador
|
||||
|
||||
Conferência autenticada por leitura em `2026-10-26T13:56:51.412248+02:00` (Africa/Johannesburg):o portal,o registo do instalador e o main actual coincidem em `e07f89da3d59d06aa1b8c50c22a478b7b167bfdd`. **L7 já está instalado no âmbito demonstrado**,com origemQA`ab2ff2fd`;o estado «ainda emQA,sem instalação» é histórico/desactualizado. A instalação terminou em26/10/2026 às13:02:35 locais;backup anterior às12:55:59 e restauro174tabelas/369ficheiros permanecem comprovados pelo recibo de entrega. Nesta passagem,o dump e o arquivo de ficheiros ainda coincidem com os hashes desse backup e a prova de restauro refere o mesmo dump. Não foi apresentado um novo backup/restauro como executado,nem repetida a instalação da revisão já activa.
|
||||
|
||||
**Partição do instalador e backup:**`/dev/md2 / ext4`;release,state,backup,tmp eDocker no mesmo dispositivo. Livres5.52GiB e21448231inodes de29089792. O código do instalador mantém o limiar5GiB;os ficheiros do backup observado ocupam0.164GiB. A leitura satisfaz5GiB+um backup desse tamanho,com margem0.35GiB. A release actual tem28674ficheiros e2503directórios sem seguir links,como referência de escala,não um novo limite arbitrário de inodes. Futuras entregas devem voltar a medir a capacidade imediatamente antes da operação;estes números não garantem uma carga futura diferente. Nenhuma limpeza local/remota foi executada;SGF TEMPO não foi afectado.
|
||||
|
||||
**Só o delta L7:**seis hashes de código correspondem à provaQA;revisão/manifest,sete marcadoresL7,quatroassets e entrada do simuladorHTTP200 conferidos. Reutilizadas as provas19testes/API108/UI/tipos/build e as provas anteriores de preservaçãoL6/L3/ISPC/câmbio;sem nova ronda funcional,escrita privada sintética,migração ou importação. A revisão activa e a anterior permanecem preservadas.
|
||||
|
||||
**Próximo conjunto delimitado para implementaçãoQA:CBF16 com duodécimos.** Reutilizar activos,tabela/taxa normal máxima,método constante,qualificaçãoCBF e periodizaçãoL6 existentes. Primeiro caso:exercício anual civil2026 com entrada em uso durante o ano;imóvel novo do projecto ou máquina industrial/agro-industrial já suportada;sem quotas anteriores,saída ou cumulação de outros benefícios. Ligar a quota mensalL6 ao incrementoCBF16,limitando ao contabilizado/saldo fiscal e mostrando apenas a diferença adicional. Demonstrar condição satisfeita,negativa,informação em falta e ausência declarada,cálculo→gravação→recuperação→relatório,efeitos no lucro/base/colecta e conservação dos históricos. Este conjunto está apenas delimitado:não é novo cálculo instalado.
|
||||
|
||||
Degressivo,reabilitados/usados/reavaliados,quotas anteriores e cumulação cooperativa+CBF16 continuam nos casos próprios. O saldo anterior de sete grupos de código e quatro dependências documentais permanece na mesma matriz,com exemplos/condições de retoma;nenhuma pendência foi apagada. Documento individual em falta limita só o activo/caso dependente. Localização não concede benefício. **L6 operacional delimitado;L7 parcial;retenções,pagamentos,créditos anuais e saldo final emL8.** Recibo:`docs/investmoz/simulations/irpc-l7-server-state-20261026.json`.
|
||||
|
||||
@@ -0,0 +1,585 @@
|
||||
{
|
||||
"status": "installed_first_grouped_L7_demonstrated_scope",
|
||||
"installed": {
|
||||
"status": "installed",
|
||||
"commit": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
|
||||
"release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
|
||||
"previous_release": "/var/www/investmoz-homologacao/releases/5aaf1a56f9d928331364fcc8b0d1528e51dba327-c1543f3e",
|
||||
"database_migrations": 0,
|
||||
"content_imports": 0
|
||||
},
|
||||
"QA_candidate": "ab2ff2fdbcbe6fb94f03e4bc4cc7ccbd647d94fc",
|
||||
"integration_candidate": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
|
||||
"previous_main": "a2122dc34cc9d3e8b64938c3d6b31cc36f336154",
|
||||
"previous_installed": "5aaf1a56f9d928331364fcc8b0d1528e51dba327",
|
||||
"authorization": "Tempo:disponibilizar entrega agrupadaL7 peloGit,backup/restauro fresco,conferência do delta,preservarL6/provas aceites e apresentar saldo concreto",
|
||||
"backup": {
|
||||
"stage": "/var/backups/investmoz-irpc-l7-common-delivery-20261026/backup",
|
||||
"created_at": "2026-10-26T10:55:59Z",
|
||||
"target": {
|
||||
"database": "teste_investidor",
|
||||
"port": 5432
|
||||
},
|
||||
"tables": 174,
|
||||
"files_verified": 369,
|
||||
"dump_sha256": "a3d46de6c10b37bd6f211125686da8c489f879ab243f082e7b72a397638901f9",
|
||||
"files_sha256": "409d378ce59ca3d82e39cbf44f139114a839e1aa56457755316a2fecdd7e5b07",
|
||||
"restore_verified": false
|
||||
},
|
||||
"restore": {
|
||||
"restore_verified": true,
|
||||
"tables_verified": 174,
|
||||
"container_network": "none",
|
||||
"database": "irpc_l7_restore_20261026",
|
||||
"port": 55441,
|
||||
"source_dump_sha256": "a3d46de6c10b37bd6f211125686da8c489f879ab243f082e7b72a397638901f9",
|
||||
"active_database_writes": 0
|
||||
},
|
||||
"preservation": {
|
||||
"previous_release_preserved": "/var/www/investmoz-homologacao/releases/5aaf1a56f9d928331364fcc8b0d1528e51dba327-c1543f3e",
|
||||
"installed": {
|
||||
"status": "installed",
|
||||
"commit": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
|
||||
"release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
|
||||
"previous_release": "/var/www/investmoz-homologacao/releases/5aaf1a56f9d928331364fcc8b0d1528e51dba327-c1543f3e",
|
||||
"database_migrations": 0,
|
||||
"content_imports": 0
|
||||
},
|
||||
"runtime_files_verified": 13,
|
||||
"preserved_L3_ISPC_FX_runtime_files_verified": 50,
|
||||
"documentary_files_verified": 31,
|
||||
"persistent_files_and_env_verified": 369,
|
||||
"tables_compared": 174,
|
||||
"changed_tables": {
|
||||
"cache": {
|
||||
"before": {
|
||||
"rows": 106,
|
||||
"checksum": "63f3ceed97ce2f40106530ef6eb6e083"
|
||||
},
|
||||
"after": {
|
||||
"rows": 106,
|
||||
"checksum": "38aa09dc08f13ff12ac1e71dbae22d0b"
|
||||
}
|
||||
},
|
||||
"sessions": {
|
||||
"before": {
|
||||
"rows": 11,
|
||||
"checksum": "823228a21cb8173718f6010a9aaa319a"
|
||||
},
|
||||
"after": {
|
||||
"rows": 14,
|
||||
"checksum": "1529684ad387db4b9aaa40ac775ebe74"
|
||||
}
|
||||
}
|
||||
},
|
||||
"preserved_counts": {
|
||||
"published_fiches": 29,
|
||||
"relations": 28,
|
||||
"geometries": 408
|
||||
},
|
||||
"migration_count": 0,
|
||||
"content_imports": 0,
|
||||
"comparison_role": "postgres_before_and_after;sameexportedsnapshotbaseline;noapplicationRLSvisibilityinference",
|
||||
"writes_by_verification": 0
|
||||
},
|
||||
"schema_permissions_before": {
|
||||
"schema_sha256": "5045b3e51d2185377aa3d9ac7fa07a44fad3ec620cdfa83ffe31c8884ee1601d",
|
||||
"roles_grants_sha256": "1530c33cb016e67bfdc64891ddfce7f185b13b56b2cd87c012871a685e118109",
|
||||
"filesystem_permissions": {
|
||||
".env": {
|
||||
"mode": 416,
|
||||
"uid": 1001,
|
||||
"gid": 33
|
||||
},
|
||||
"storage": {
|
||||
"mode": 1533,
|
||||
"uid": 1001,
|
||||
"gid": 33
|
||||
},
|
||||
"storage/app": {
|
||||
"mode": 1533,
|
||||
"uid": 1001,
|
||||
"gid": 33
|
||||
},
|
||||
"bootstrap/cache": {
|
||||
"mode": 1528,
|
||||
"uid": 1001,
|
||||
"gid": 33
|
||||
}
|
||||
},
|
||||
"comparison_identity": "postgres;catalogue read only;no passwords collected"
|
||||
},
|
||||
"schema_permissions_after": {
|
||||
"schema_sha256": "5045b3e51d2185377aa3d9ac7fa07a44fad3ec620cdfa83ffe31c8884ee1601d",
|
||||
"roles_grants_sha256": "1530c33cb016e67bfdc64891ddfce7f185b13b56b2cd87c012871a685e118109",
|
||||
"filesystem_permissions": {
|
||||
".env": {
|
||||
"mode": 416,
|
||||
"uid": 1001,
|
||||
"gid": 33
|
||||
},
|
||||
"storage": {
|
||||
"mode": 1533,
|
||||
"uid": 1001,
|
||||
"gid": 33
|
||||
},
|
||||
"storage/app": {
|
||||
"mode": 1533,
|
||||
"uid": 1001,
|
||||
"gid": 33
|
||||
},
|
||||
"bootstrap/cache": {
|
||||
"mode": 1528,
|
||||
"uid": 1001,
|
||||
"gid": 33
|
||||
}
|
||||
},
|
||||
"comparison_identity": "postgres;catalogue read only;no passwords collected",
|
||||
"unchanged": true
|
||||
},
|
||||
"operational_delta": {
|
||||
"status": "operational_delta_reconciled",
|
||||
"comparison_identity": "postgres before/after;isolated restored baseline;no RLS visibility inference",
|
||||
"cache": "queue:restart;requestthrottle;identical home-sector cached value with refreshed expiry(HomeController remember10min);no deletedcache",
|
||||
"sessions": "anonymous sessions from delivery user-agent or exactUA/time correlated with nginx public request;deleted sessions individually expired beyond configured lifetime,normal database session garbage collection(config/session lottery2/100)",
|
||||
"delta": {
|
||||
"cache": {
|
||||
"before_rows": 106,
|
||||
"after_rows": 106,
|
||||
"changes": [
|
||||
{
|
||||
"key_sha256": "8d6ea77eb4b34d86d207362d583cfa8bf2880b907becd9b00398964482c6b4bd",
|
||||
"kind": "updated",
|
||||
"fields": [
|
||||
"expiration"
|
||||
],
|
||||
"key_pattern": "investemoz-cache-{hash}",
|
||||
"is_queue_restart_key": false,
|
||||
"expiration_unchanged": false,
|
||||
"throttle_timer_pair": true,
|
||||
"same_value_home_cache_expiry_refresh": false
|
||||
},
|
||||
{
|
||||
"key_sha256": "2f251473865d14b953236ab95b1521764754d76abd79b58ca7d38c96dfe2fab1",
|
||||
"kind": "updated",
|
||||
"fields": [
|
||||
"value",
|
||||
"expiration"
|
||||
],
|
||||
"key_pattern": "investemoz-cache-{hash}:timer",
|
||||
"is_queue_restart_key": false,
|
||||
"expiration_unchanged": false,
|
||||
"throttle_timer_pair": true,
|
||||
"same_value_home_cache_expiry_refresh": false
|
||||
},
|
||||
{
|
||||
"key_sha256": "7f7dd83f47f5bf404d55e6e9f1367948721579970b195680645e356031a070ff",
|
||||
"kind": "updated",
|
||||
"fields": [
|
||||
"value",
|
||||
"expiration"
|
||||
],
|
||||
"key_pattern": "investemoz-cache-illuminate:queue:restart",
|
||||
"is_queue_restart_key": true,
|
||||
"expiration_unchanged": false,
|
||||
"throttle_timer_pair": false,
|
||||
"same_value_home_cache_expiry_refresh": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"sessions": {
|
||||
"before_rows": 11,
|
||||
"after_rows": 14,
|
||||
"changes": [
|
||||
{
|
||||
"key_sha256": "cd8c2106a4f4ab7802317e6602c26cfa4cf82a23a86f67a0abbc27fbd82edfb8",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "a89dca10cb8a95f4451ff60eeefe7ac3cd7751b779b0bf97a7e5f5b894f9b115",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
},
|
||||
{
|
||||
"key_sha256": "7fb2119013f872a5e4dd70952cc896a4ac8291134e02362bd60805eb77e9587a",
|
||||
"kind": "added",
|
||||
"fields": [
|
||||
"id",
|
||||
"ip_address",
|
||||
"user_agent",
|
||||
"payload",
|
||||
"last_activity"
|
||||
],
|
||||
"anonymous_user": true,
|
||||
"delivery_user_agent": true,
|
||||
"expired_before_comparison": false,
|
||||
"session_lifetime_minutes": 120,
|
||||
"anonymous_public_request_logged": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"business_tables_to_confirm_separately": 172,
|
||||
"active_data_writes_by_comparison": 0,
|
||||
"restore_network": "none"
|
||||
},
|
||||
"public": {
|
||||
"status": "installed_delta_verified",
|
||||
"served_revision": {
|
||||
"commit": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
|
||||
"branch": "main",
|
||||
"built_at": "2026-10-26T11:02:32.435267+00:00",
|
||||
"manifest_sha256": "d78a1bdb503c10849f5ea8d8879753653c2c2fc22f6182f6d68ec9f6adf635b5"
|
||||
},
|
||||
"manifest_hash_matches": true,
|
||||
"compiled_delta_markers": {
|
||||
"IRPC-normal-adjustments/10": [
|
||||
"assets/project-dossier-KEyrPtc6.js"
|
||||
],
|
||||
"Preparar qualificação L7": [
|
||||
"assets/services-BSj1SuMk.js"
|
||||
],
|
||||
"Despesas — imposto autónomo": [
|
||||
"assets/project-dossier-KEyrPtc6.js"
|
||||
],
|
||||
"Cooperativa — redução da taxa": [
|
||||
"assets/project-dossier-KEyrPtc6.js"
|
||||
],
|
||||
"Amortizações aceleradas": [
|
||||
"assets/services-BSj1SuMk.js",
|
||||
"assets/project-dossier-KEyrPtc6.js"
|
||||
],
|
||||
"novo ajustamento ao lucro:": [
|
||||
"assets/project-dossier-KEyrPtc6.js"
|
||||
],
|
||||
"colecta combinada:": [
|
||||
"assets/project-dossier-KEyrPtc6.js"
|
||||
],
|
||||
"Saldo final — âmbito L8": [
|
||||
"assets/project-dossier-KEyrPtc6.js"
|
||||
],
|
||||
"Reutilizar selecção cambial": [
|
||||
"assets/services-BSj1SuMk.js"
|
||||
]
|
||||
},
|
||||
"assets": [
|
||||
{
|
||||
"file": "assets/project-dossier-document-BRdhvWgC.js",
|
||||
"status": 200,
|
||||
"sha256": "5b1de561be552259de776a2dbaf4b49909a3edd2647fec7c296a96054c929a9f"
|
||||
},
|
||||
{
|
||||
"file": "assets/services-BSj1SuMk.js",
|
||||
"status": 200,
|
||||
"sha256": "ea1a3812cbced72f4df115e8e379ae6d2307e97b2152d288b1c80d357f03f78b"
|
||||
},
|
||||
{
|
||||
"file": "assets/simulation-form-BqVD91Ek.js",
|
||||
"status": 200,
|
||||
"sha256": "85cbd533c5bc92af5a448db71da006d4346d2d0adb09dde825db0aa19ad5048c"
|
||||
},
|
||||
{
|
||||
"file": "assets/project-dossier-KEyrPtc6.js",
|
||||
"status": 200,
|
||||
"sha256": "b6ae250a30b5030a6e40e7dfb140a3335ce6d5bc16835098d3d7c5828fc526c5"
|
||||
}
|
||||
],
|
||||
"simulator_status": 200,
|
||||
"simulator_entry": "assets/app-ByAQSjfI.js",
|
||||
"existing_fiscal_availability": {
|
||||
"data": {
|
||||
"enabled": true,
|
||||
"coverage_start": "2026-01-01",
|
||||
"coverage_end": "2026-12-31",
|
||||
"message": "IVA geral sobre base líquida disponível; enquadramento declarado."
|
||||
}
|
||||
},
|
||||
"synthetic_private_writes": 0,
|
||||
"method": "Read-only installedrevision/manifest/newcompiledcatalogueandreaders/simulatorentry;acceptedQAproofsreused"
|
||||
},
|
||||
"pipeline": {
|
||||
"service": "ExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
|
||||
"installed": {
|
||||
"status": "installed",
|
||||
"commit": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
|
||||
"release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
|
||||
"previous_release": "/var/www/investmoz-homologacao/releases/5aaf1a56f9d928331364fcc8b0d1528e51dba327-c1543f3e",
|
||||
"database_migrations": 0,
|
||||
"content_imports": 0
|
||||
},
|
||||
"latest_report": {
|
||||
"status": "installed",
|
||||
"commit": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
|
||||
"release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
|
||||
"previous_release": "/var/www/investmoz-homologacao/releases/5aaf1a56f9d928331364fcc8b0d1528e51dba327-c1543f3e",
|
||||
"database_migrations": 0,
|
||||
"content_imports": 0,
|
||||
"requested_commits": [
|
||||
"e07f89da3d59d06aa1b8c50c22a478b7b167bfdd"
|
||||
],
|
||||
"finished_at": "2026-10-26T11:02:35.885260+00:00"
|
||||
},
|
||||
"log_file": "1793012270105316629.log",
|
||||
"summaries": [
|
||||
"OK (1 test, 3106 assertions)",
|
||||
"built in 33.69s",
|
||||
"OK (59 tests, 317 assertions)",
|
||||
"# tests 1007",
|
||||
"# pass 1007",
|
||||
"# fail 0"
|
||||
],
|
||||
"log_bytes": 287128
|
||||
},
|
||||
"concurrent_main_reconciliation": {
|
||||
"QA_candidate": "ab2ff2fdbcbe6fb94f03e4bc4cc7ccbd647d94fc",
|
||||
"concurrent_main": "a2122dc34cc9d3e8b64938c3d6b31cc36f336154",
|
||||
"installed_baseline": "5aaf1a56f9d928331364fcc8b0d1528e51dba327",
|
||||
"runtime_QA_files_exact": [
|
||||
"resources/js/lib/irpc-special.ts",
|
||||
"resources/js/components/simulation-irpc-special.tsx",
|
||||
"resources/js/lib/irpc-normal.ts",
|
||||
"resources/js/lib/irpc-normal-depreciation.ts",
|
||||
"resources/js/components/simulation-irpc-normal.tsx",
|
||||
"resources/js/lib/project-dossier-report.ts"
|
||||
],
|
||||
"concurrent_files_preserved": {
|
||||
"resources/js/components/portal-hero.tsx": "0ebe2c3e2ae2615d966d050864699a90dac2fef36ebfc174aa1059b83db9a514",
|
||||
"resources/js/components/tempo-brand.tsx": "27c01d317ec59c9a4ddb2a184c0a8a9427fcf92d34a916060287d07226364d02",
|
||||
"resources/js/layouts/portal-navigation.tsx": "f1f66b645035f56c9bcc7fbc8c2983e84eb29ae3ecb99461e3963a7deefbaaa6",
|
||||
"resources/js/lib/portal-navigation.ts": "12aad264eeb5cebe7c9bf467391c611f58d1b84cc9d5fd30db983ba640e25951",
|
||||
"resources/js/pages/PortalInvestidor.tsx": "d418f960f82ae0d054acfe094047bc80a16f7b418506f054e6d7da07edf6ef00",
|
||||
"resources/js/pages/investment/shared.tsx": "00098334435de3bb5c7b13608c0e53c63a4bdee7d9cdf07f24b3aec54441f05e",
|
||||
"resources/js/pages/portal/why-invest.tsx": "3917efa7b0d33fe8fe6e4562c3b9e2f53200b9e07807cd29bade328f8e5ae7e2",
|
||||
"tests/frontend/portal-navigation.test.mjs": "518c7e1de6fb1b385caffe39914e2905bf8f561d938f0527561156602a0e3098"
|
||||
},
|
||||
"CSV_concurrent_V2_01_preserved": true,
|
||||
"removed_manual_history_lines_restored": 586,
|
||||
"resolution": "main changed only by removing586tail lines from the manual;candidate manual retained in full;CSV auto-merge preserved V2-01 and changed only fiscal rowAUD-SIM-INT02",
|
||||
"new_functional_round": false,
|
||||
"accepted_QA_proofs_reused": {
|
||||
"new_frontend_tests": 19,
|
||||
"API_tests": 1,
|
||||
"API_assertions": 108,
|
||||
"API_database": "simulator_fiscal_delta_20261021_test",
|
||||
"API_host": "127.0.0.1",
|
||||
"API_port": 55441,
|
||||
"API_transaction_rollback": true,
|
||||
"QA_identity_guard": true,
|
||||
"Wayfinder_generated_with_form": true,
|
||||
"typescript_noEmit": true,
|
||||
"QA_build": true,
|
||||
"API_recovered_to_HTML_and_financial_dossier_cases": 6,
|
||||
"UI": {
|
||||
"actualComponent": true,
|
||||
"expenseL6Addback100Autonomous35": true,
|
||||
"missingClassificationDoesNotEraseNormalProfit": true,
|
||||
"absenceExplicit": true,
|
||||
"cooperative16MixedCaseBlockedOnly": true,
|
||||
"acceleratedQuota150LimitedToAccounted120": true,
|
||||
"netAdditionalDeduction20": true,
|
||||
"cumulationMissingExplicit": true,
|
||||
"saveRecoveryDownload": true,
|
||||
"finalBalanceL8Unknown": true,
|
||||
"errors": []
|
||||
},
|
||||
"old_functional_suites_repeated": false,
|
||||
"building_and_lower_optional_quota_cases": true
|
||||
}
|
||||
},
|
||||
"dependency_archiving": {
|
||||
"status": "dependencies_archived_and_verified",
|
||||
"versions": 8,
|
||||
"free_before": 4349009920,
|
||||
"free_after": 6454341632,
|
||||
"receipt": "/var/backups/investmoz-build-dependencies-irpc-l7-common-20261026/receipt.json",
|
||||
"protected": [
|
||||
"/var/www/investmoz-homologacao/releases/5aaf1a56f9d928331364fcc8b0d1528e51dba327-c1543f3e",
|
||||
"/var/www/investmoz-homologacao/releases/56475acb2f39e58cb51664913f7fb499f58eb7ab-694b3932"
|
||||
],
|
||||
"active_or_previous_release_modified": false,
|
||||
"source_data_backups_deleted": 0
|
||||
},
|
||||
"accepted_QA_proofs_reused": {
|
||||
"new_frontend_tests": 19,
|
||||
"API_tests": 1,
|
||||
"API_assertions": 108,
|
||||
"API_database": "simulator_fiscal_delta_20261021_test",
|
||||
"API_host": "127.0.0.1",
|
||||
"API_port": 55441,
|
||||
"API_transaction_rollback": true,
|
||||
"QA_identity_guard": true,
|
||||
"Wayfinder_generated_with_form": true,
|
||||
"typescript_noEmit": true,
|
||||
"QA_build": true,
|
||||
"API_recovered_to_HTML_and_financial_dossier_cases": 6,
|
||||
"UI": {
|
||||
"actualComponent": true,
|
||||
"expenseL6Addback100Autonomous35": true,
|
||||
"missingClassificationDoesNotEraseNormalProfit": true,
|
||||
"absenceExplicit": true,
|
||||
"cooperative16MixedCaseBlockedOnly": true,
|
||||
"acceleratedQuota150LimitedToAccounted120": true,
|
||||
"netAdditionalDeduction20": true,
|
||||
"cumulationMissingExplicit": true,
|
||||
"saveRecoveryDownload": true,
|
||||
"finalBalanceL8Unknown": true,
|
||||
"errors": []
|
||||
},
|
||||
"old_functional_suites_repeated": false,
|
||||
"building_and_lower_optional_quota_cases": true
|
||||
},
|
||||
"source_inventory_reused": {
|
||||
"files_reused": 8143,
|
||||
"broad_search_repeated": false,
|
||||
"receipt": "irpc-l7-scope-20261026.json",
|
||||
"sources": [
|
||||
{
|
||||
"id": "CIRPC",
|
||||
"title": "Lei34/2007",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\docs\\investmoz\\simulations\\source-archive\\Lei-34-2007-BR52.pdf",
|
||||
"bytes": 1676884,
|
||||
"sha256": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e",
|
||||
"references": "PDF5/p768(59):12,14,15; PDF15–16:54–56; PDF17/p768(71):61",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
},
|
||||
{
|
||||
"id": "IRPC-2026",
|
||||
"title": "Lei12/2025",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\docs\\investmoz\\simulations\\source-archive\\BR-248-I-Suplemento-1-2025.pdf",
|
||||
"bytes": 440018,
|
||||
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251",
|
||||
"references": "PDF18–20; PDF20:art2/61-A,art3,art6; vigência01/01/2026",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
},
|
||||
{
|
||||
"id": "IRPC-2022",
|
||||
"title": "Lei20/2022",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\docs\\investmoz\\simulations\\source-archive\\BR252-I-Serie-2022-Lei20-PESOE.pdf",
|
||||
"bytes": 17966640,
|
||||
"sha256": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d",
|
||||
"references": "PDF1/p2731:61(2), termo31/12/2025",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
},
|
||||
{
|
||||
"id": "CBF-local",
|
||||
"title": "Lei4/2009",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\outputs\\irpc-l7-scope\\CBF-Lei4-2009-APIEX.pdf",
|
||||
"bytes": 10998765,
|
||||
"sha256": "4231a5b6783e603cedb98992f3e93ecaf1c1d5be341b093560cf2fdd0845b0dc",
|
||||
"references": "Original local disponível; scan sem extracção textual útil; cotejo textual pela compilação oficial",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false,
|
||||
"authorised_original": "\\\\Mac\\Home\\Documents\\TEMPO\\Portal Tempo\\Legislacao\\Apiex\\3.-Lei-no4-2009-de-12-de-Janeiro-Codigo-dos-Beneficios-Fiscais.pdf"
|
||||
},
|
||||
{
|
||||
"id": "APIEX",
|
||||
"title": "Compilação oficial APIEX",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\outputs\\irpc-l7-scope\\APIEX-legislacao-investimentos-2025.pdf",
|
||||
"bytes": 6467655,
|
||||
"sha256": "ba1e9eaabfec5d0c4cb2d9f2444a6860f7a90f222034764197829be402d408ed",
|
||||
"references": "pp8–32:Lei8/2023; pp36–59:Decreto8/2024; pp64–92:CBF4/2009; p68:9/10;p71–74:15–19",
|
||||
"official_url": "https://pt.apiex.gov.mz/wp-content/uploads/2025/02/LEGISLACAO-DE-INVESTIMENTOS-EM-MOCAMBIQUE.pdf",
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
},
|
||||
{
|
||||
"id": "RCBF",
|
||||
"title": "Decreto56/2009",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\outputs\\irpc-l7-scope\\Decreto56-2009-BR40.pdf",
|
||||
"bytes": 422005,
|
||||
"sha256": "6ea1b8d93daed48c6d590481d874010fa1708211d8f27c319dc9a31328456017",
|
||||
"references": "Procedimento já cotejado em iva-l1-p084-p085-model-i1-cotejo-20261024.json; não estende isenções IVA a IRPC",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
}
|
||||
],
|
||||
"document_consultation_activates_calculation": false
|
||||
},
|
||||
"L6_operational_demonstrated_scope_preserved": true,
|
||||
"L6_pending_code_and_documentation_preserved": true,
|
||||
"L7_integrally_complete": false,
|
||||
"IRPC_integrally_complete": false,
|
||||
"new_private_synthetic_writes_on_active": 0,
|
||||
"location_grants_benefit": false,
|
||||
"L8_retentions_payments_annual_credit_application_final_balance_separate": true,
|
||||
"remaining_scope": {
|
||||
"implementation": [
|
||||
"61(4) sources/partial segregation outside calculated36g",
|
||||
"cooperative mixed/withheld income and other entity exemptions9–14",
|
||||
"CBF16 other assets/methods/optional lower quota/periods/prior quotas and combinations",
|
||||
"61-A capital gains and special operations54–56/41-A",
|
||||
"CBF17–19 deductions/magnifications andCBF15 potential credit origin/eligibility",
|
||||
"sector/territory and specific special regimes",
|
||||
"L7 M20/M22 official transport"
|
||||
],
|
||||
"documentary_case_dependencies": [
|
||||
"nature/incidence/parcel and correct period",
|
||||
"individual statute/title/recognition or applicable exception only where required",
|
||||
"specific norm/validity/compatibility/order/limit not corresponded",
|
||||
"affected form edition/field/representation"
|
||||
],
|
||||
"examples_and_resume_conditions": "same consolidated matrix and manual section:saldo concreto de L7 após a primeira entrega agrupada"
|
||||
},
|
||||
"evidence": {
|
||||
"backup.txt": "dac1a5cddac111160d64f4f34184f999cb40655b210582b9a18dbef20aedd8d0",
|
||||
"baseline.txt": "6e4bf2e80c29cc3c81d14c3da9f44e1ef3d576b0eb25f9c7ecb85f060c15b196",
|
||||
"compact-dependencies.txt": "a2385728e917cc20008da8b8144ff57a1bcbe3a1a352848c548b11bdf38fbbf0",
|
||||
"concurrent-main-reconciliation.json": "8a6aefa957e2b28905f89dca161de53bcffdc9dba2575e9f76efb13ac80a6c16",
|
||||
"installed-protected.txt": "e2fc267572cf8c29ee15e4efa524679843377766d19456ccba4e9187b7c55a21",
|
||||
"installed-public-delta.json": "557cbdc9ec7db9b0eb6865d0998c83a9c4a957ee041ba1bce0e54cd2df4ee3cb",
|
||||
"installed-public.txt": "4efa54256c1de8af63f80f0ff245f529cb581746f165a1299d7389ffd8047ee9",
|
||||
"integration.txt": "c320a8d33ea33e1f70a291b7da2fa4934658b2f87fc9a26a9521325e23cfac7d",
|
||||
"manifest-served.json": "d78a1bdb503c10849f5ea8d8879753653c2c2fc22f6182f6d68ec9f6adf635b5",
|
||||
"operational-delta.txt": "18793b0013b52e87ad088317b49ef3ef31e582dfb073500fa29a5822e237f61c",
|
||||
"preflight-ready.txt": "ffe2dfba440adebbd45ba72336d56668735f4916d3ae5385a4d750c5775a6a04",
|
||||
"preflight.txt": "6bf42bb982a7e5807123569ba9a4951bd639132b628965586b7ed60f36b5f0ea",
|
||||
"preparation.json": "46c078247bb3b68f2aabdb9aa5c0e40bf648dbc07e467933ce82d749b9741a00",
|
||||
"process-progress.txt": "721a9cf3e8b3892122dabe8b05e8c377b097d94ed0123b7135dcf83c53a40cd6",
|
||||
"progress-2.txt": "df6ae7b7f2e49c9da3ffbe12c0de6746a191f51dcf30428a93a3db4693c7972b",
|
||||
"progress-3.txt": "de4fa512b1e124d6c48c34eec14ab50fb66ebb718b49c0fd039e6a148598688d",
|
||||
"progress-4.txt": "de4fa512b1e124d6c48c34eec14ab50fb66ebb718b49c0fd039e6a148598688d",
|
||||
"restore.txt": "fcf1cbf5a6de6c0ac9172c3b5acd39c7c0438f950a2297be5f84964268ef4c24",
|
||||
"schema-permissions-after.txt": "76b5a4d8af11e4898a205062766cfb7ab6ec0783200e77e60a1927aa1ca18597",
|
||||
"schema-permissions-before.txt": "0ab7c964792acdd8917bce256c472e55e034b103500a58b49f020b5084823ed7",
|
||||
"status-before.txt": "290e99722a17dabbeb4bb609b2c3df423357dd1e34b3cc6f4e45cd64e758c797",
|
||||
"status-final.txt": "3814636ae1e3d45f6da832b42b3a9215503598bc20c0c080b3ab5181a074bea0",
|
||||
"status-progress-1.txt": "b289c9824a293d6b97db770712ce92e65c714fe72f22e0410ef6447b655d47d6"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,570 @@
|
||||
{
|
||||
"status": "L7_common_qualification_autonomous_expenses_cooperative_acceleration_QA_prepared_not_installed",
|
||||
"recorded_date": "2026-10-26",
|
||||
"installed_baseline": "5aaf1a56f9d928331364fcc8b0d1528e51dba327",
|
||||
"scope_baseline": "d37fffb2d2eacef6300f1c81fc29993178532f35",
|
||||
"branch": "codex/irpc-l7-common-autonomous-qa-20261026",
|
||||
"version": "IRPC-normal-adjustments/10",
|
||||
"installed": false,
|
||||
"L6_operational_scope_preserved": true,
|
||||
"IRPC_integrally_complete": false,
|
||||
"runtime_delta": {
|
||||
"resources/js/lib/irpc-special.ts": "5d261cdb54506bd892fa49776bb53a20600e62e64a4c180ef26cdcdb8b6a3806",
|
||||
"resources/js/components/simulation-irpc-special.tsx": "9ccd89e46703f9dd14c1110459b22673623a19bd652d137f40ec83e0f7c223db",
|
||||
"resources/js/lib/irpc-normal.ts": "7e63e7e5928a90c5305fd1fca49db883fec32666381ee99ae6fa4b06c711d9a7",
|
||||
"resources/js/lib/irpc-normal-depreciation.ts": "00ba22e449b23e570bfbbf3895bd334029a16f938d5a5ff999ca67b4318f58c3",
|
||||
"resources/js/components/simulation-irpc-normal.tsx": "e01e54dee4cd2555a8a27ed77512cf220056b5899ea9dacbaaae6d4063ce2d42",
|
||||
"resources/js/lib/project-dossier-report.ts": "cba66c88391da83b4fdb345a9570eca5ae83979cbbd508eb44b53995d812718d"
|
||||
},
|
||||
"cases_recovered": {
|
||||
"expense": {
|
||||
"L6_reference": {
|
||||
"taxableProfit": {
|
||||
"numerator": "3230",
|
||||
"denominator": "1"
|
||||
},
|
||||
"taxableBase": {
|
||||
"numerator": "3230",
|
||||
"denominator": "1"
|
||||
},
|
||||
"colecta": {
|
||||
"numerator": "5168",
|
||||
"denominator": "5"
|
||||
}
|
||||
},
|
||||
"L7_profit": {
|
||||
"numerator": "3230",
|
||||
"denominator": "1"
|
||||
},
|
||||
"L7_base": {
|
||||
"numerator": "3230",
|
||||
"denominator": "1"
|
||||
},
|
||||
"L7_colecta": {
|
||||
"numerator": "5168",
|
||||
"denominator": "5"
|
||||
},
|
||||
"autonomous_tax": {
|
||||
"numerator": "35",
|
||||
"denominator": "1"
|
||||
},
|
||||
"combined_colecta": {
|
||||
"numerator": "5343",
|
||||
"denominator": "5"
|
||||
},
|
||||
"expense_status": "calculated",
|
||||
"cooperative_status": "absent",
|
||||
"acceleration_status": "absent",
|
||||
"additional_depreciation_deduction": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"history_versions": [
|
||||
"IRPC-normal-adjustments/1",
|
||||
"IRPC-normal-adjustments/2",
|
||||
"IRPC-normal-adjustments/3",
|
||||
"IRPC-normal-adjustments/4",
|
||||
"IRPC-normal-adjustments/5",
|
||||
"IRPC-normal-adjustments/6",
|
||||
"IRPC-normal-adjustments/7",
|
||||
"IRPC-normal-adjustments/8",
|
||||
"IRPC-normal-adjustments/9"
|
||||
],
|
||||
"final_balance": {
|
||||
"scope": "L8",
|
||||
"payable": null,
|
||||
"recoverable": null
|
||||
}
|
||||
},
|
||||
"missing": {
|
||||
"L6_reference": {
|
||||
"taxableProfit": {
|
||||
"numerator": "3230",
|
||||
"denominator": "1"
|
||||
},
|
||||
"taxableBase": {
|
||||
"numerator": "3230",
|
||||
"denominator": "1"
|
||||
},
|
||||
"colecta": {
|
||||
"numerator": "5168",
|
||||
"denominator": "5"
|
||||
}
|
||||
},
|
||||
"L7_profit": {
|
||||
"numerator": "3230",
|
||||
"denominator": "1"
|
||||
},
|
||||
"L7_base": {
|
||||
"numerator": "3230",
|
||||
"denominator": "1"
|
||||
},
|
||||
"L7_colecta": {
|
||||
"numerator": "5168",
|
||||
"denominator": "5"
|
||||
},
|
||||
"autonomous_tax": null,
|
||||
"combined_colecta": null,
|
||||
"expense_status": "indeterminate",
|
||||
"cooperative_status": "absent",
|
||||
"acceleration_status": "absent",
|
||||
"additional_depreciation_deduction": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"history_versions": [
|
||||
"IRPC-normal-adjustments/1",
|
||||
"IRPC-normal-adjustments/2",
|
||||
"IRPC-normal-adjustments/3",
|
||||
"IRPC-normal-adjustments/4",
|
||||
"IRPC-normal-adjustments/5",
|
||||
"IRPC-normal-adjustments/6",
|
||||
"IRPC-normal-adjustments/7",
|
||||
"IRPC-normal-adjustments/8",
|
||||
"IRPC-normal-adjustments/9"
|
||||
],
|
||||
"final_balance": {
|
||||
"scope": "L8",
|
||||
"payable": null,
|
||||
"recoverable": null
|
||||
}
|
||||
},
|
||||
"negative": {
|
||||
"L6_reference": {
|
||||
"taxableProfit": {
|
||||
"numerator": "3230",
|
||||
"denominator": "1"
|
||||
},
|
||||
"taxableBase": {
|
||||
"numerator": "3230",
|
||||
"denominator": "1"
|
||||
},
|
||||
"colecta": {
|
||||
"numerator": "5168",
|
||||
"denominator": "5"
|
||||
}
|
||||
},
|
||||
"L7_profit": {
|
||||
"numerator": "3230",
|
||||
"denominator": "1"
|
||||
},
|
||||
"L7_base": {
|
||||
"numerator": "3230",
|
||||
"denominator": "1"
|
||||
},
|
||||
"L7_colecta": {
|
||||
"numerator": "5168",
|
||||
"denominator": "5"
|
||||
},
|
||||
"autonomous_tax": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"combined_colecta": {
|
||||
"numerator": "5168",
|
||||
"denominator": "5"
|
||||
},
|
||||
"expense_status": "calculated",
|
||||
"cooperative_status": "absent",
|
||||
"acceleration_status": "absent",
|
||||
"additional_depreciation_deduction": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"history_versions": [
|
||||
"IRPC-normal-adjustments/1",
|
||||
"IRPC-normal-adjustments/2",
|
||||
"IRPC-normal-adjustments/3",
|
||||
"IRPC-normal-adjustments/4",
|
||||
"IRPC-normal-adjustments/5",
|
||||
"IRPC-normal-adjustments/6",
|
||||
"IRPC-normal-adjustments/7",
|
||||
"IRPC-normal-adjustments/8",
|
||||
"IRPC-normal-adjustments/9"
|
||||
],
|
||||
"final_balance": {
|
||||
"scope": "L8",
|
||||
"payable": null,
|
||||
"recoverable": null
|
||||
}
|
||||
},
|
||||
"absent": {
|
||||
"L6_reference": {
|
||||
"taxableProfit": {
|
||||
"numerator": "3130",
|
||||
"denominator": "1"
|
||||
},
|
||||
"taxableBase": {
|
||||
"numerator": "3130",
|
||||
"denominator": "1"
|
||||
},
|
||||
"colecta": {
|
||||
"numerator": "5008",
|
||||
"denominator": "5"
|
||||
}
|
||||
},
|
||||
"L7_profit": {
|
||||
"numerator": "3130",
|
||||
"denominator": "1"
|
||||
},
|
||||
"L7_base": {
|
||||
"numerator": "3130",
|
||||
"denominator": "1"
|
||||
},
|
||||
"L7_colecta": {
|
||||
"numerator": "5008",
|
||||
"denominator": "5"
|
||||
},
|
||||
"autonomous_tax": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"combined_colecta": {
|
||||
"numerator": "5008",
|
||||
"denominator": "5"
|
||||
},
|
||||
"expense_status": "absent",
|
||||
"cooperative_status": "absent",
|
||||
"acceleration_status": "absent",
|
||||
"additional_depreciation_deduction": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"history_versions": [
|
||||
"IRPC-normal-adjustments/1",
|
||||
"IRPC-normal-adjustments/2",
|
||||
"IRPC-normal-adjustments/3",
|
||||
"IRPC-normal-adjustments/4",
|
||||
"IRPC-normal-adjustments/5",
|
||||
"IRPC-normal-adjustments/6",
|
||||
"IRPC-normal-adjustments/7",
|
||||
"IRPC-normal-adjustments/8",
|
||||
"IRPC-normal-adjustments/9"
|
||||
],
|
||||
"final_balance": {
|
||||
"scope": "L8",
|
||||
"payable": null,
|
||||
"recoverable": null
|
||||
}
|
||||
},
|
||||
"cooperative": {
|
||||
"L6_reference": {
|
||||
"taxableProfit": {
|
||||
"numerator": "3130",
|
||||
"denominator": "1"
|
||||
},
|
||||
"taxableBase": {
|
||||
"numerator": "3130",
|
||||
"denominator": "1"
|
||||
},
|
||||
"colecta": {
|
||||
"numerator": "5008",
|
||||
"denominator": "5"
|
||||
}
|
||||
},
|
||||
"L7_profit": {
|
||||
"numerator": "3130",
|
||||
"denominator": "1"
|
||||
},
|
||||
"L7_base": {
|
||||
"numerator": "3130",
|
||||
"denominator": "1"
|
||||
},
|
||||
"L7_colecta": {
|
||||
"numerator": "2504",
|
||||
"denominator": "5"
|
||||
},
|
||||
"autonomous_tax": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"combined_colecta": {
|
||||
"numerator": "2504",
|
||||
"denominator": "5"
|
||||
},
|
||||
"expense_status": "absent",
|
||||
"cooperative_status": "calculated",
|
||||
"acceleration_status": "absent",
|
||||
"additional_depreciation_deduction": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"history_versions": [
|
||||
"IRPC-normal-adjustments/1",
|
||||
"IRPC-normal-adjustments/2",
|
||||
"IRPC-normal-adjustments/3",
|
||||
"IRPC-normal-adjustments/4",
|
||||
"IRPC-normal-adjustments/5",
|
||||
"IRPC-normal-adjustments/6",
|
||||
"IRPC-normal-adjustments/7",
|
||||
"IRPC-normal-adjustments/8",
|
||||
"IRPC-normal-adjustments/9"
|
||||
],
|
||||
"final_balance": {
|
||||
"scope": "L8",
|
||||
"payable": null,
|
||||
"recoverable": null
|
||||
}
|
||||
},
|
||||
"acceleration": {
|
||||
"L6_reference": {
|
||||
"taxableProfit": {
|
||||
"numerator": "6260",
|
||||
"denominator": "1"
|
||||
},
|
||||
"taxableBase": {
|
||||
"numerator": "6260",
|
||||
"denominator": "1"
|
||||
},
|
||||
"colecta": {
|
||||
"numerator": "10016",
|
||||
"denominator": "5"
|
||||
}
|
||||
},
|
||||
"L7_profit": {
|
||||
"numerator": "6240",
|
||||
"denominator": "1"
|
||||
},
|
||||
"L7_base": {
|
||||
"numerator": "6240",
|
||||
"denominator": "1"
|
||||
},
|
||||
"L7_colecta": {
|
||||
"numerator": "9984",
|
||||
"denominator": "5"
|
||||
},
|
||||
"autonomous_tax": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"combined_colecta": {
|
||||
"numerator": "9984",
|
||||
"denominator": "5"
|
||||
},
|
||||
"expense_status": "absent",
|
||||
"cooperative_status": "absent",
|
||||
"acceleration_status": "calculated",
|
||||
"additional_depreciation_deduction": {
|
||||
"numerator": "20",
|
||||
"denominator": "1"
|
||||
},
|
||||
"history_versions": [
|
||||
"IRPC-normal-adjustments/1",
|
||||
"IRPC-normal-adjustments/2",
|
||||
"IRPC-normal-adjustments/3",
|
||||
"IRPC-normal-adjustments/4",
|
||||
"IRPC-normal-adjustments/5",
|
||||
"IRPC-normal-adjustments/6",
|
||||
"IRPC-normal-adjustments/7",
|
||||
"IRPC-normal-adjustments/8",
|
||||
"IRPC-normal-adjustments/9"
|
||||
],
|
||||
"final_balance": {
|
||||
"scope": "L8",
|
||||
"payable": null,
|
||||
"recoverable": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"source_inventory": {
|
||||
"files_reused": 8143,
|
||||
"broad_search_repeated": false,
|
||||
"receipt": "irpc-l7-scope-20261026.json",
|
||||
"sources": [
|
||||
{
|
||||
"id": "CIRPC",
|
||||
"title": "Lei34/2007",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\docs\\investmoz\\simulations\\source-archive\\Lei-34-2007-BR52.pdf",
|
||||
"bytes": 1676884,
|
||||
"sha256": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e",
|
||||
"references": "PDF5/p768(59):12,14,15; PDF15–16:54–56; PDF17/p768(71):61",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
},
|
||||
{
|
||||
"id": "IRPC-2026",
|
||||
"title": "Lei12/2025",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\docs\\investmoz\\simulations\\source-archive\\BR-248-I-Suplemento-1-2025.pdf",
|
||||
"bytes": 440018,
|
||||
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251",
|
||||
"references": "PDF18–20; PDF20:art2/61-A,art3,art6; vigência01/01/2026",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
},
|
||||
{
|
||||
"id": "IRPC-2022",
|
||||
"title": "Lei20/2022",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\docs\\investmoz\\simulations\\source-archive\\BR252-I-Serie-2022-Lei20-PESOE.pdf",
|
||||
"bytes": 17966640,
|
||||
"sha256": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d",
|
||||
"references": "PDF1/p2731:61(2), termo31/12/2025",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
},
|
||||
{
|
||||
"id": "CBF-local",
|
||||
"title": "Lei4/2009",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\outputs\\irpc-l7-scope\\CBF-Lei4-2009-APIEX.pdf",
|
||||
"bytes": 10998765,
|
||||
"sha256": "4231a5b6783e603cedb98992f3e93ecaf1c1d5be341b093560cf2fdd0845b0dc",
|
||||
"references": "Original local disponível; scan sem extracção textual útil; cotejo textual pela compilação oficial",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false,
|
||||
"authorised_original": "\\\\Mac\\Home\\Documents\\TEMPO\\Portal Tempo\\Legislacao\\Apiex\\3.-Lei-no4-2009-de-12-de-Janeiro-Codigo-dos-Beneficios-Fiscais.pdf"
|
||||
},
|
||||
{
|
||||
"id": "APIEX",
|
||||
"title": "Compilação oficial APIEX",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\outputs\\irpc-l7-scope\\APIEX-legislacao-investimentos-2025.pdf",
|
||||
"bytes": 6467655,
|
||||
"sha256": "ba1e9eaabfec5d0c4cb2d9f2444a6860f7a90f222034764197829be402d408ed",
|
||||
"references": "pp8–32:Lei8/2023; pp36–59:Decreto8/2024; pp64–92:CBF4/2009; p68:9/10;p71–74:15–19",
|
||||
"official_url": "https://pt.apiex.gov.mz/wp-content/uploads/2025/02/LEGISLACAO-DE-INVESTIMENTOS-EM-MOCAMBIQUE.pdf",
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
},
|
||||
{
|
||||
"id": "RCBF",
|
||||
"title": "Decreto56/2009",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\outputs\\irpc-l7-scope\\Decreto56-2009-BR40.pdf",
|
||||
"bytes": 422005,
|
||||
"sha256": "6ea1b8d93daed48c6d590481d874010fa1708211d8f27c319dc9a31328456017",
|
||||
"references": "Procedimento já cotejado em iva-l1-p084-p085-model-i1-cotejo-20261024.json; não estende isenções IVA a IRPC",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
}
|
||||
],
|
||||
"document_consultation_activates_calculation": false
|
||||
},
|
||||
"coverage": {
|
||||
"optional_input_backward_compatible": true,
|
||||
"accepted_version9_current_key_and_result_unchanged_without_L7": true,
|
||||
"expense_source": "calculated36(1)g schedule ID;full amount reused;no parallel amount",
|
||||
"expense_rate": "35/100",
|
||||
"expense_additional_profit_adjustment": "0",
|
||||
"cooperative_rate": "32/100 × 1/2 =16/100;eligible ordinary base only",
|
||||
"accelerated_rate": "normal maximum table rate ×3/2;lower optional quota not covered;first full civil2026,new supported asset,prior quotas zero",
|
||||
"accelerated_deduction": "min calculated quota/accounted eligible amount/fiscal remaining balance;only difference over normal map",
|
||||
"mixed_cases": "cooperative+autonomous expense demonstrated;cooperative+CBF16 not supported",
|
||||
"context": "reuses documented sector/territory/provenance;no benefit by location alone;raw snapshots not dumped in report",
|
||||
"states": [
|
||||
"information_missing",
|
||||
"declared_absence",
|
||||
"not_applicable_or_negative_condition",
|
||||
"calculated"
|
||||
],
|
||||
"report": "same normalReportRows/HTML and financial project dossier;L6 reference separated from L7 effects",
|
||||
"final_settlement": "not calculated;L8"
|
||||
},
|
||||
"pending": {
|
||||
"code": [
|
||||
"autonomous expenses outside already-calculated36g parcel",
|
||||
"mixed cooperative income/withheld parcels",
|
||||
"CBF16 rehabilitated/other categories/lower optional quota/methods/months/prior quotas/later years",
|
||||
"specific benefit combinations and cumulation",
|
||||
"61-A capital gains and other previously delimited treatment families",
|
||||
"L7 official form transport"
|
||||
],
|
||||
"documents_per_case": [
|
||||
"individual status/title/exception and qualification proof when required by applicable norm",
|
||||
"parcel/limit/order/cumulation/chronology not evidenced",
|
||||
"affected form field/edition/representation correspondence"
|
||||
],
|
||||
"resume_conditions": "same existing matrix/manual L7 QA section;no blanket validation or repeated transversal research",
|
||||
"L6_pending_unchanged": true,
|
||||
"L8_annual_credit_application_retentions_payments_final_balance_separate": true
|
||||
},
|
||||
"checks": {
|
||||
"new_frontend_tests": 19,
|
||||
"API_tests": 1,
|
||||
"API_assertions": 108,
|
||||
"API_database": "simulator_fiscal_delta_20261021_test",
|
||||
"API_host": "127.0.0.1",
|
||||
"API_port": 55441,
|
||||
"API_transaction_rollback": true,
|
||||
"QA_identity_guard": true,
|
||||
"Wayfinder_generated_with_form": true,
|
||||
"typescript_noEmit": true,
|
||||
"QA_build": true,
|
||||
"API_recovered_to_HTML_and_financial_dossier_cases": 6,
|
||||
"UI": {
|
||||
"actualComponent": true,
|
||||
"expenseL6Addback100Autonomous35": true,
|
||||
"missingClassificationDoesNotEraseNormalProfit": true,
|
||||
"absenceExplicit": true,
|
||||
"cooperative16MixedCaseBlockedOnly": true,
|
||||
"acceleratedQuota150LimitedToAccounted120": true,
|
||||
"netAdditionalDeduction20": true,
|
||||
"cumulationMissingExplicit": true,
|
||||
"saveRecoveryDownload": true,
|
||||
"finalBalanceL8Unknown": true,
|
||||
"errors": []
|
||||
},
|
||||
"old_functional_suites_repeated": false,
|
||||
"building_and_lower_optional_quota_cases": true
|
||||
},
|
||||
"preservation": {
|
||||
"baseline": "d37fffb2d2eacef6300f1c81fc29993178532f35",
|
||||
"files_compared": 662,
|
||||
"only_existing_changed": [
|
||||
"resources/js/lib/irpc-normal-depreciation.ts",
|
||||
"resources/js/lib/irpc-normal.ts",
|
||||
"resources/js/lib/project-dossier-report.ts"
|
||||
],
|
||||
"protected_code_schema_config_routes_contract_files": 576,
|
||||
"originals": {
|
||||
"docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973",
|
||||
"docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b",
|
||||
"docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c",
|
||||
"docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57",
|
||||
"docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html": "00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063",
|
||||
"docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee",
|
||||
"docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251",
|
||||
"docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5",
|
||||
"docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358",
|
||||
"docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d",
|
||||
"docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5",
|
||||
"docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb",
|
||||
"docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8",
|
||||
"docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be",
|
||||
"docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c",
|
||||
"docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697",
|
||||
"docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b",
|
||||
"docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56",
|
||||
"docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4",
|
||||
"docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a",
|
||||
"docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76",
|
||||
"docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d",
|
||||
"docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899",
|
||||
"docs/investmoz/simulations/source-archive/Lei-20-2009-BR36-AT-exemplar19.pdf": "fc1c8144db42960cbf73e717e095896f511ece0f907f58f78819b27d6917a7ee",
|
||||
"docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53",
|
||||
"docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e",
|
||||
"docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e",
|
||||
"docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121",
|
||||
"docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d",
|
||||
"docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d",
|
||||
"docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b"
|
||||
},
|
||||
"active_writes": 0,
|
||||
"migrations": 0,
|
||||
"permission_changes": false
|
||||
},
|
||||
"evidence_directory": "outputs/irpc-l7-common",
|
||||
"delivery": {
|
||||
"prepared_only": true,
|
||||
"Git_branch_isolated": true,
|
||||
"active_installation": false,
|
||||
"fresh_backup_restore_and_delta_check_required_at_future_installation": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
{
|
||||
"status": "L6_operational_demonstrated_scope_accepted_L7_delimited_not_implemented",
|
||||
"recorded_date": "2026-10-26",
|
||||
"authority": {
|
||||
"origin": "express_user_instruction",
|
||||
"decision": "L6 operacional no âmbito demonstrado, com limitações explícitas; delimitar L7; L8 conserva liquidação final",
|
||||
"new_generic_approval_required": false
|
||||
},
|
||||
"baseline": {
|
||||
"installed_commit": "5aaf1a56f9d928331364fcc8b0d1528e51dba327",
|
||||
"reused_delivery_receipt": "irpc-l6-values-forms-delivery-20261026.json",
|
||||
"documentation_parent": "45fd591c7faa765f33de0a0b9000c3ceb4057abe",
|
||||
"root_documentation_parent": "31651a76b11ed50576c52cd274e3c59cda0f8924"
|
||||
},
|
||||
"L6": {
|
||||
"operational_scope_accepted": true,
|
||||
"integrally_complete": false,
|
||||
"existing_code_pending_groups": 5,
|
||||
"existing_documentary_pending_groups": 5,
|
||||
"pending_list": "same matrix/manual: saldo consolidado de L6",
|
||||
"old_pending_decision_records_preserved_as_history": true,
|
||||
"dependent_cases_only_blocked": true,
|
||||
"accepted_proofs_reused": true
|
||||
},
|
||||
"L7": {
|
||||
"state": "delimited; no new executable treatment",
|
||||
"context_reused": [
|
||||
"opportunity/dossier snapshots",
|
||||
"sector and territorial IDs/labels/provenance",
|
||||
"subject/NUIT/residence/EP/period",
|
||||
"business_plan_snapshot",
|
||||
"modelo_a_snapshot.irpcNormal versions",
|
||||
"asset and expense IDs/previous quotas",
|
||||
"exact rational values and demonstrated form mappings"
|
||||
],
|
||||
"location_grants_benefit": false,
|
||||
"effect_types": [
|
||||
"profit_adjustment",
|
||||
"taxable_base_deduction",
|
||||
"rate_by_eligible_parcel",
|
||||
"separate_autonomous_tax",
|
||||
"potential_credit_entitlement_for_L8"
|
||||
],
|
||||
"families": [
|
||||
"61(4) expenses autonomous tax",
|
||||
"61-A capital gains autonomous tax from2026",
|
||||
"CIRPC9–14 entity exemptions/cooperative12",
|
||||
"CBF16 accelerated depreciation",
|
||||
"CBF17–19 deductions/magnifications",
|
||||
"CBF15 potential investment credit; annual use L8",
|
||||
"CBF sector/territory specific provisions",
|
||||
"special operations54–56/41-A and specifically mapped sector regimes"
|
||||
],
|
||||
"first_increment": [
|
||||
"common qualification, provenance, period and separate effects",
|
||||
"61(4) expense35% with existing36g addback, no duplicate",
|
||||
"missing-information and negative-condition cases"
|
||||
],
|
||||
"next_compatible_cases": [
|
||||
"cooperative12 eligible parcel",
|
||||
"CBF16 supported asset and reconciled prior quotas"
|
||||
],
|
||||
"not_implemented_yet": [
|
||||
"specific qualification/persistence",
|
||||
"new treatment calculations and per-parcel reconciliation",
|
||||
"treatment-specific reporting/exports"
|
||||
],
|
||||
"documentary_pending_scope": "Only individual status/title where required, parcel/limit/chronology, unmapped specific sector norm or affected form edition/field; examples and resume conditions in same matrix/manual",
|
||||
"historical_mutation_permitted": false
|
||||
},
|
||||
"L8": {
|
||||
"retentions_payments_annual_credit_application_final_settlement": true,
|
||||
"final_balance_calculated": false
|
||||
},
|
||||
"source_inventory": {
|
||||
"reused_inventory": "C:\\laragon\\www\\portal-investidor\\outputs\\ispc-l4a-20261025\\preservation-before-tests.json",
|
||||
"files": 8143,
|
||||
"fresh_broad_scan": false,
|
||||
"sources": [
|
||||
{
|
||||
"id": "CIRPC",
|
||||
"title": "Lei34/2007",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\docs\\investmoz\\simulations\\source-archive\\Lei-34-2007-BR52.pdf",
|
||||
"bytes": 1676884,
|
||||
"sha256": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e",
|
||||
"references": "PDF5/p768(59):12,14,15; PDF15–16:54–56; PDF17/p768(71):61",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
},
|
||||
{
|
||||
"id": "IRPC-2026",
|
||||
"title": "Lei12/2025",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\docs\\investmoz\\simulations\\source-archive\\BR-248-I-Suplemento-1-2025.pdf",
|
||||
"bytes": 440018,
|
||||
"sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251",
|
||||
"references": "PDF18–20; PDF20:art2/61-A,art3,art6; vigência01/01/2026",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
},
|
||||
{
|
||||
"id": "IRPC-2022",
|
||||
"title": "Lei20/2022",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\docs\\investmoz\\simulations\\source-archive\\BR252-I-Serie-2022-Lei20-PESOE.pdf",
|
||||
"bytes": 17966640,
|
||||
"sha256": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d",
|
||||
"references": "PDF1/p2731:61(2), termo31/12/2025",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
},
|
||||
{
|
||||
"id": "CBF-local",
|
||||
"title": "Lei4/2009",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\outputs\\irpc-l7-scope\\CBF-Lei4-2009-APIEX.pdf",
|
||||
"bytes": 10998765,
|
||||
"sha256": "4231a5b6783e603cedb98992f3e93ecaf1c1d5be341b093560cf2fdd0845b0dc",
|
||||
"references": "Original local disponível; scan sem extracção textual útil; cotejo textual pela compilação oficial",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false,
|
||||
"authorised_original": "\\\\Mac\\Home\\Documents\\TEMPO\\Portal Tempo\\Legislacao\\Apiex\\3.-Lei-no4-2009-de-12-de-Janeiro-Codigo-dos-Beneficios-Fiscais.pdf"
|
||||
},
|
||||
{
|
||||
"id": "APIEX",
|
||||
"title": "Compilação oficial APIEX",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\outputs\\irpc-l7-scope\\APIEX-legislacao-investimentos-2025.pdf",
|
||||
"bytes": 6467655,
|
||||
"sha256": "ba1e9eaabfec5d0c4cb2d9f2444a6860f7a90f222034764197829be402d408ed",
|
||||
"references": "pp8–32:Lei8/2023; pp36–59:Decreto8/2024; pp64–92:CBF4/2009; p68:9/10;p71–74:15–19",
|
||||
"official_url": "https://pt.apiex.gov.mz/wp-content/uploads/2025/02/LEGISLACAO-DE-INVESTIMENTOS-EM-MOCAMBIQUE.pdf",
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
},
|
||||
{
|
||||
"id": "RCBF",
|
||||
"title": "Decreto56/2009",
|
||||
"exemplar": "C:\\laragon\\www\\portal-investidor-irpc-l7-scope-20261026\\outputs\\irpc-l7-scope\\Decreto56-2009-BR40.pdf",
|
||||
"bytes": 422005,
|
||||
"sha256": "6ea1b8d93daed48c6d590481d874010fa1708211d8f27c319dc9a31328456017",
|
||||
"references": "Procedimento já cotejado em iva-l1-p084-p085-model-i1-cotejo-20261024.json; não estende isenções IVA a IRPC",
|
||||
"official_url": null,
|
||||
"available_for_consultation": true,
|
||||
"documentary_status": "official_source_accepted; applicability/version/period_per_treatment",
|
||||
"new_calculation_activation": false
|
||||
}
|
||||
],
|
||||
"rendered_pages_reviewed": [
|
||||
"CIRPC PDF5",
|
||||
"CIRPC PDF17",
|
||||
"APIEX PDF68",
|
||||
"APIEX PDF72",
|
||||
"Lei12/2025 PDF20"
|
||||
],
|
||||
"no_period_extension_presumed": "61(2) Law20/2022 ends31/12/2025; no automatic2026 rate",
|
||||
"availability_is_not_rule_activation": true
|
||||
},
|
||||
"preservation": {
|
||||
"source_archive_files": {
|
||||
"docs/investmoz/simulations/source-archive/AT-Comunicado-9-2026-ISPC.pdf": "106f8a9ce9255c03549c70bf07fe999d32e6e55302d009b509862aa74ccb4973",
|
||||
"docs/investmoz/simulations/source-archive/AT-Modelo-30-ISPC.pdf": "6802edd06b6ff638a0b851a3ec7ecf69af8f07840faa47446becad67d35d445c",
|
||||
"docs/investmoz/simulations/source-archive/AT-Modelo-B-Geral.pdf": "bd977c7c59d4d98befd92e2c566b1bf168cb1343bb519f51b41a3807f431fc57",
|
||||
"docs/investmoz/simulations/source-archive/AT-MRFTA-19-39.pdf": "8ea62c53066b482f87078a7a7b1ecf15ca98a12a122e8d7abca63acfc993186b",
|
||||
"docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html": "00e8a7e0d3a1db4ca3beb56d5361b2084a0f1684f3d40fc1c203702a2190e063",
|
||||
"docs/investmoz/simulations/source-archive/BR-16-I-Serie-2008-04-16.pdf": "fc373ff5637edf75ec6a9595dec8763a8503d4ee786e3b7d8f1c742eae9d80ee",
|
||||
"docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251",
|
||||
"docs/investmoz/simulations/source-archive/BR-89-I-Serie-2017-06-08.pdf": "11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5",
|
||||
"docs/investmoz/simulations/source-archive/BR-95-I-Suplemento-2025-05-21.pdf": "e0e682e2c027c3cd9c1d46a73a3f48bc5f6bdbf05667fd97314d7a3f6a456358",
|
||||
"docs/investmoz/simulations/source-archive/BR252-I-Serie-2022-Lei20-PESOE.pdf": "1159fd3ce1ba5581671796d083534da48bd3c5578298819e896f1c2a8026318d",
|
||||
"docs/investmoz/simulations/source-archive/Decreto-22-2021-BR70.pdf": "a8fac38dcfe08f9c7a8e46254cff10e1ec82fc4f7a8d88ad6e4fe7d91ffc21a5",
|
||||
"docs/investmoz/simulations/source-archive/Decreto-27-2026-BR123.pdf": "26249c3fa58f149c81de36e99d1aac2819a4771379d9e8833159660dabf539bb",
|
||||
"docs/investmoz/simulations/source-archive/Decreto-29-1998-BR22-5-suplemento.pdf": "6242cbe675faadf085f43f95ec8c7e8868aafe67c3b2ab2bb010992288f954f8",
|
||||
"docs/investmoz/simulations/source-archive/Decreto-3-2011-BR-11-I-mineiros.pdf": "5bca1133666ba9c69870b89823420175b7b5b8d0eccb667ecdf5c29716f3b6be",
|
||||
"docs/investmoz/simulations/source-archive/Decreto-37-2023-BR124.pdf": "7e680b191481faa0e2e9057fa5053587eb2a29d1d8c819e0eb9f02814255a04c",
|
||||
"docs/investmoz/simulations/source-archive/Decreto-9-2008-BR16.pdf": "96fccdecbfdc11c9eafb90fbc6c7bc259f88bbd4c7507d1ac3af1fa03f960697",
|
||||
"docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b",
|
||||
"docs/investmoz/simulations/source-archive/Lei-14-1992-BR42.pdf": "089fff7423e99a70a230a73ca379e4ea3a91d124703f91016e57ff82794b9e56",
|
||||
"docs/investmoz/simulations/source-archive/Lei-17-2022-BR251-exemplar-MCNet5.pdf": "14eb34f0af91a8f5cb1770c7b52d6ff839c6818302d1ed96d79afbfb9fe999d4",
|
||||
"docs/investmoz/simulations/source-archive/Lei-17-2022-IPP-BR250-Parlamento.pdf": "978cd22403ffd336a631704ecd7a5bbd814a427c815b9acdaca5515591dd9e2a",
|
||||
"docs/investmoz/simulations/source-archive/Lei-19-2013-BR76.pdf": "bba96d645cc935ffc3d1a79b9f0f73ac1c693d6459c2ad41f56cd2841accae76",
|
||||
"docs/investmoz/simulations/source-archive/Lei-19-2017-IRPS-BR-OCAM.pdf": "c3a0186cb9ad090d7a9533006295dc9bb6a62ad0d6150173cbd49dba4ee4b52d",
|
||||
"docs/investmoz/simulations/source-archive/Lei-2-2011-BR-1-4-suplemento-MCNet.pdf": "a7543a68cc3287a46a83c39a04821b40f649dd06c4e9b5dc51ff0b47fba08899",
|
||||
"docs/investmoz/simulations/source-archive/Lei-20-2009-BR36-AT-exemplar19.pdf": "fc1c8144db42960cbf73e717e095896f511ece0f907f58f78819b27d6917a7ee",
|
||||
"docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53",
|
||||
"docs/investmoz/simulations/source-archive/Lei-34-2007-BR52.pdf": "cdbef875ad7ccc1517b12faf5de0e893a70ed2ed81e33913cd6dc4a674474e6e",
|
||||
"docs/investmoz/simulations/source-archive/Lei-4-1994-BR37-3-suplemento.pdf": "210df9db8980d0a5690cd187a6eeec7e37a900d743e39062c16f4e0d12215c7e",
|
||||
"docs/investmoz/simulations/source-archive/Lei-4-2012-BR3.pdf": "b8845cef41dcbd9ba50c43dbfa743a56030dd3d348242a107e1ae30279eec121",
|
||||
"docs/investmoz/simulations/source-archive/Lei-7-1991-Partidos-IFES.pdf": "6b783a0bb3330688ef10660a58060d9724aa2da6a873d234fe902f0eaaeda42d",
|
||||
"docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf": "d504e1024b28aee5c6acf4592acb96ec9c915a8414f67a61ab6984d6acf9df9d",
|
||||
"docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf": "f353773dcf41f09f4daa6cf5ba5a5f7994f3e02615867c2dcffc61c3d901bf9b"
|
||||
},
|
||||
"source_archive_count": 31,
|
||||
"root_existing_source_files": 28,
|
||||
"root_preexisting_branch_absences": [
|
||||
"docs/investmoz/simulations/source-archive/BM-Mercado-Monetario-MAIBOR-20261025.html",
|
||||
"docs/investmoz/simulations/source-archive/PT-MZ-CDT-1992.pdf",
|
||||
"docs/investmoz/simulations/source-archive/PT-MZ-Protocolo-2009.pdf"
|
||||
],
|
||||
"root_absences_introduced_by_this_change": false,
|
||||
"runtime_schema_config_permissions_changed": false,
|
||||
"active_writes": 0,
|
||||
"migrations": 0,
|
||||
"imports": 0,
|
||||
"deployment": false,
|
||||
"functional_tests_repeated": false,
|
||||
"existing_accepted_proofs_reused": true
|
||||
},
|
||||
"validation": {
|
||||
"expected_tracked_delta": [
|
||||
"docs/investmoz/consolidated-review-matrix-2026-10-03.md",
|
||||
"docs/investmoz/unification/traceability-and-manual.md",
|
||||
"docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv",
|
||||
"docs/investmoz/simulations/irpc-l7-scope-20261026.json"
|
||||
],
|
||||
"csv_only_changed_id": "AUD-SIM-INT02",
|
||||
"scope_present_in_existing_matrix_and_manual": true,
|
||||
"new_backlog_created": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
{
|
||||
"status": "L7_installed_reconfirmed_not_reinstalled",
|
||||
"checked_at_UTC": "2026-10-26T11:56:51.412248+00:00",
|
||||
"checked_at_Africa_Johannesburg": "2026-10-26T13:56:51.412248+02:00",
|
||||
"main": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
|
||||
"QA_origin": "ab2ff2fdbcbe6fb94f03e4bc4cc7ccbd647d94fc",
|
||||
"installed_commit": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
|
||||
"previous_delivery_receipt": "irpc-l7-common-delivery-20261026.json",
|
||||
"server_read_only": {
|
||||
"checked_at_UTC": "2026-10-26T11:56:51.412248+00:00",
|
||||
"read_only": true,
|
||||
"installed": {
|
||||
"status": "installed",
|
||||
"commit": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
|
||||
"release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
|
||||
"previous_release": "/var/www/investmoz-homologacao/releases/5aaf1a56f9d928331364fcc8b0d1528e51dba327-c1543f3e",
|
||||
"database_migrations": 0,
|
||||
"content_imports": 0
|
||||
},
|
||||
"release_revision": {
|
||||
"commit": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
|
||||
"branch": "main",
|
||||
"built_at": "2026-10-26T11:02:32.435267+00:00",
|
||||
"manifest_sha256": "d78a1bdb503c10849f5ea8d8879753653c2c2fc22f6182f6d68ec9f6adf635b5"
|
||||
},
|
||||
"latest_report": {
|
||||
"status": "installed",
|
||||
"commit": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
|
||||
"release": "/var/www/investmoz-homologacao/releases/e07f89da3d59d06aa1b8c50c22a478b7b167bfdd-6b82c3f2",
|
||||
"previous_release": "/var/www/investmoz-homologacao/releases/5aaf1a56f9d928331364fcc8b0d1528e51dba327-c1543f3e",
|
||||
"database_migrations": 0,
|
||||
"content_imports": 0,
|
||||
"requested_commits": [
|
||||
"e07f89da3d59d06aa1b8c50c22a478b7b167bfdd"
|
||||
],
|
||||
"finished_at": "2026-10-26T11:02:35.885260+00:00"
|
||||
},
|
||||
"service": "ExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
|
||||
"volumes": [
|
||||
{
|
||||
"path": "/var/www/investmoz-homologacao/releases",
|
||||
"mount": "/dev/md2 / ext4",
|
||||
"device": 2306,
|
||||
"total_bytes": 467909804032,
|
||||
"available_bytes": 5922545664,
|
||||
"total_inodes": 29089792,
|
||||
"available_inodes": 21448231
|
||||
},
|
||||
{
|
||||
"path": "/var/lib/investmoz-deploy",
|
||||
"mount": "/dev/md2 / ext4",
|
||||
"device": 2306,
|
||||
"total_bytes": 467909804032,
|
||||
"available_bytes": 5922545664,
|
||||
"total_inodes": 29089792,
|
||||
"available_inodes": 21448231
|
||||
},
|
||||
{
|
||||
"path": "/var/backups",
|
||||
"mount": "/dev/md2 / ext4",
|
||||
"device": 2306,
|
||||
"total_bytes": 467909804032,
|
||||
"available_bytes": 5922545664,
|
||||
"total_inodes": 29089792,
|
||||
"available_inodes": 21448231
|
||||
},
|
||||
{
|
||||
"path": "/tmp",
|
||||
"mount": "/dev/md2 / ext4",
|
||||
"device": 2306,
|
||||
"total_bytes": 467909804032,
|
||||
"available_bytes": 5922545664,
|
||||
"total_inodes": 29089792,
|
||||
"available_inodes": 21448231
|
||||
},
|
||||
{
|
||||
"path": "/var/lib/docker",
|
||||
"mount": "/dev/md2 / ext4",
|
||||
"device": 2306,
|
||||
"total_bytes": 467909804032,
|
||||
"available_bytes": 5922545664,
|
||||
"total_inodes": 29089792,
|
||||
"available_inodes": 21448231
|
||||
}
|
||||
],
|
||||
"existing_pipeline_space_guard_excerpt": [
|
||||
" self.releases.mkdir(parents=True,exist_ok=True)",
|
||||
" if shutil.disk_usage(self.releases).free < 5 * 1024**3:",
|
||||
" raise RuntimeError('Insufficient free space for an isolated build; active release preserved')",
|
||||
" release=self.releases/(target+'-'+uuid.uuid4().hex[:8]);release.mkdir(mode=0o750)"
|
||||
],
|
||||
"pipeline_sha256": "adec1c17654f3a8658b83b134f1e75f95391b235738552721906c3236e388604",
|
||||
"L7_delta_hashes_match": {
|
||||
"resources/js/components/simulation-irpc-normal.tsx": true,
|
||||
"resources/js/components/simulation-irpc-special.tsx": true,
|
||||
"resources/js/lib/irpc-normal-depreciation.ts": true,
|
||||
"resources/js/lib/irpc-normal.ts": true,
|
||||
"resources/js/lib/irpc-special.ts": true,
|
||||
"resources/js/lib/project-dossier-report.ts": true
|
||||
},
|
||||
"installed_release_nonlinked_files": 28674,
|
||||
"installed_release_nonlinked_directories": 2503,
|
||||
"inode_requirement_note": "Current release file/directory counts are an observed reference,not a guarantee for another build;no new inode threshold introduced.",
|
||||
"prior_installation_backup": {
|
||||
"created_at": "2026-10-26T10:55:59Z",
|
||||
"tables": 174,
|
||||
"files": 369,
|
||||
"dump_sha256": "a3d46de6c10b37bd6f211125686da8c489f879ab243f082e7b72a397638901f9",
|
||||
"restore": {
|
||||
"restore_verified": true,
|
||||
"tables_verified": 174,
|
||||
"container_network": "none",
|
||||
"database": "irpc_l7_restore_20261026",
|
||||
"port": 55441,
|
||||
"source_dump_sha256": "a3d46de6c10b37bd6f211125686da8c489f879ab243f082e7b72a397638901f9",
|
||||
"active_database_writes": 0
|
||||
},
|
||||
"files_present": {
|
||||
"database.dump": {
|
||||
"present": true,
|
||||
"bytes": 22880589
|
||||
},
|
||||
"files-before.tar.gz": {
|
||||
"present": true,
|
||||
"bytes": 153036740
|
||||
},
|
||||
"backup-receipt.json": {
|
||||
"present": true,
|
||||
"bytes": 94539
|
||||
},
|
||||
"restore-receipt.json": {
|
||||
"present": true,
|
||||
"bytes": 269
|
||||
}
|
||||
}
|
||||
},
|
||||
"new_backup_or_restore_executed": false,
|
||||
"deployment_executed": false,
|
||||
"cleanup_executed": false,
|
||||
"active_data_writes": 0
|
||||
},
|
||||
"capacity_assessment": {
|
||||
"mount": "/dev/md2 / ext4",
|
||||
"existing_pipeline_guard_bytes": 5368709120,
|
||||
"available_bytes": 5922545664,
|
||||
"available_inodes": 21448231,
|
||||
"total_inodes": 29089792,
|
||||
"same_partition_for_release_state_backup_tmp_docker": true,
|
||||
"observed_existing_backup_files_bytes": 176012137,
|
||||
"available_minus_guard_and_one_observed_backup_bytes": 377824407,
|
||||
"existing_space_guard_plus_observed_backup_satisfied": true,
|
||||
"inode_reference_files_plus_directories": 31177,
|
||||
"inode_note": "Available21million vs31thousand entries in current nonlinked release;no new arbitrary threshold or guarantee for changed future payload",
|
||||
"new_deployment_needed": false
|
||||
},
|
||||
"existing_backup_integrity": {
|
||||
"backup_created_at": "2026-10-26T10:55:59Z",
|
||||
"existing_dump_hash_matches": true,
|
||||
"existing_files_archive_hash_matches": true,
|
||||
"accepted_restore_proof_matches_same_dump": true,
|
||||
"restored_tables": 174,
|
||||
"new_backup_or_restore_executed": false,
|
||||
"active_writes": 0
|
||||
},
|
||||
"public_delta": {
|
||||
"status": "installed_delta_verified",
|
||||
"served_revision": {
|
||||
"commit": "e07f89da3d59d06aa1b8c50c22a478b7b167bfdd",
|
||||
"branch": "main",
|
||||
"built_at": "2026-10-26T11:02:32.435267+00:00",
|
||||
"manifest_sha256": "d78a1bdb503c10849f5ea8d8879753653c2c2fc22f6182f6d68ec9f6adf635b5"
|
||||
},
|
||||
"manifest_hash_matches": true,
|
||||
"compiled_delta_markers": {
|
||||
"IRPC-normal-adjustments/10": [
|
||||
"assets/project-dossier-KEyrPtc6.js"
|
||||
],
|
||||
"Preparar qualificação L7": [
|
||||
"assets/services-BSj1SuMk.js"
|
||||
],
|
||||
"Despesas — imposto autónomo": [
|
||||
"assets/project-dossier-KEyrPtc6.js"
|
||||
],
|
||||
"Cooperativa — redução da taxa": [
|
||||
"assets/project-dossier-KEyrPtc6.js"
|
||||
],
|
||||
"Amortizações aceleradas": [
|
||||
"assets/project-dossier-KEyrPtc6.js",
|
||||
"assets/services-BSj1SuMk.js"
|
||||
],
|
||||
"novo ajustamento ao lucro:": [
|
||||
"assets/project-dossier-KEyrPtc6.js"
|
||||
],
|
||||
"colecta combinada:": [
|
||||
"assets/project-dossier-KEyrPtc6.js"
|
||||
]
|
||||
},
|
||||
"assets": [
|
||||
{
|
||||
"file": "assets/project-dossier-KEyrPtc6.js",
|
||||
"status": 200,
|
||||
"sha256": "b6ae250a30b5030a6e40e7dfb140a3335ce6d5bc16835098d3d7c5828fc526c5"
|
||||
},
|
||||
{
|
||||
"file": "assets/simulation-form-BqVD91Ek.js",
|
||||
"status": 200,
|
||||
"sha256": "85cbd533c5bc92af5a448db71da006d4346d2d0adb09dde825db0aa19ad5048c"
|
||||
},
|
||||
{
|
||||
"file": "assets/services-BSj1SuMk.js",
|
||||
"status": 200,
|
||||
"sha256": "ea1a3812cbced72f4df115e8e379ae6d2307e97b2152d288b1c80d357f03f78b"
|
||||
},
|
||||
{
|
||||
"file": "assets/project-dossier-document-BRdhvWgC.js",
|
||||
"status": 200,
|
||||
"sha256": "5b1de561be552259de776a2dbaf4b49909a3edd2647fec7c296a96054c929a9f"
|
||||
}
|
||||
],
|
||||
"simulator_status": 200,
|
||||
"simulator_entry": "assets/app-ByAQSjfI.js",
|
||||
"synthetic_private_writes": 0,
|
||||
"method": "Read-only L7 revision/manifest/compiled delta/simulator entry;accepted functional proofs reused"
|
||||
},
|
||||
"accepted_proofs_reused": {
|
||||
"QA_frontend_tests": 19,
|
||||
"QA_API_assertions": 108,
|
||||
"QA_UI_types_build": true,
|
||||
"prior_installation_backup_restore_tables": 174,
|
||||
"prior_installation_files": 369,
|
||||
"prior_preservation_runtime_files": 50,
|
||||
"prior_originals": 31,
|
||||
"new_functional_round": false
|
||||
},
|
||||
"next_compatible_QA_scope": {
|
||||
"status": "delimited_for_next_QA_not_implemented",
|
||||
"treatment": "CBF16 constant-method depreciation by monthly fractions for supported new assets entering service during2026",
|
||||
"reuse": [
|
||||
"existing asset IDs/classification and maximum normal catalogue rates",
|
||||
"L6 monthly timing/financial source and normal reference result",
|
||||
"existing qualification/source/title/provenance and versioned book"
|
||||
],
|
||||
"first_case": "Civil annual2026,new supported industrial/agroindustrial machine or new project building entering service during the year;documented CBF eligibility,no previous quotas/no other benefits",
|
||||
"acceptance": [
|
||||
"normal vs accelerated quota and accounted/fiscal balance caps",
|
||||
"additional effect only,without second deduction or changes to original asset/history",
|
||||
"conditions true,false,missing and declared absence",
|
||||
"calculation-save-recover-report with profit/base/colecta effects and final L8 balance unknown"
|
||||
],
|
||||
"out_of_scope": [
|
||||
"declining method",
|
||||
"rehabilitated/used/revalued assets",
|
||||
"recovery of previous quotas",
|
||||
"cooperative+CBF16 or other benefit combinations",
|
||||
"unmapped official form fields"
|
||||
],
|
||||
"resume_condition": "Link already-demonstrated L6 monthly timing to qualified CBF16 rate increment,retain exact values/caps and prove only new effects in isolated QA;missing project evidence affects that asset only"
|
||||
},
|
||||
"remaining_L7_groups_preserved": {
|
||||
"implementation_groups": 7,
|
||||
"documentary_case_dependencies": 4,
|
||||
"section": "saldo concreto de L7 após a primeira entrega agrupada"
|
||||
},
|
||||
"L6_operational_scope_and_pending_preserved": true,
|
||||
"L7_integrally_complete": false,
|
||||
"L8_final_settlement_separate": true,
|
||||
"local_cleanup": false,
|
||||
"SGF_affected": false,
|
||||
"new_backup_restore_or_installation": false
|
||||
}
|
||||
@@ -2522,8 +2522,8 @@ As estimativas são **horas de trabalho técnico**, não calendário nem mediç
|
||||
| L3 — IVA: saldo e fecho do Modelo A | Totais14–18 quando todas as parcelas estão determinadas | Campos19–27 aplicáveis, transporte de crédito, rectificações/substituição, imposto a entregar e pedido de reembolso; estados documentados e relação com tesouraria; via de restituição de bebidas13(2), identificada porG4D e ainda não apurada, conforme procedimento próprio | Execuções mensais, parcelas L1/L2, documentos e histórico | L1/L2 para apuramento integral; saldo anterior identificado e procedimento de reembolso aplicável. Pedido não significa deferimento/recebimento | 48–80 h |
|
||||
| L4 — ISPC: elegibilidade e apuramento | Campos de enquadramento e motor genérico | Regime/actividade/volume elegível, opções/exclusões, escalões/taxas aplicáveis, mínimo, trimestre e retenções específicas; comparação só entre regimes admissíveis | Vendas por actividade, custos, NUIT, natureza jurídica e residência confirmada | Lei9/2025 e regulamentação/período; distinguir receita anual, trimestre e excesso | 40–64 h |
|
||||
| L5 — retenções IRPC e guias | Documentos de compras/vendas e guia M/39 como exemplar | Rendimento pago/recebido, entidade que retém, residente/não residente/EP, evento temporal, excepções e casos digitais/e-money; guia e comprovativo ligados à operação | Contrapartes, facturas, pagamentos, período, moeda, oportunidade | Artigos aplicáveis por rendimento, taxa/convenção se invocada; corrigir remissões do exemplar. Sem submissão electrónica AT presumida | 32–56 h |
|
||||
| L6 — IRPC anual: regime normal | Disponível5aaf1a56:percurso normal demonstrado atécolecta,períodos/moedas e preparação parcialM20/M22;históricos/provas preservados | Saldo consolidado:5grupos de código e5de esclarecimentos documentais,com exemplo/retoma;ver secção «saldo consolidado deL6». L6parcial;fecho operacional delimitado ainda por decidir;L7/L8 próprios | Plano financeiro,dados comuns,activos/livros e histórico;retenções/pagamentos/créditos anuais reservadosL8 | CódigoIRPC/período/caso;benefícios e tratamentos especiais anuaisL7;sem dependência genérica do fechoL8 | Estimativa inicial48–80h;saldo não reestimado |
|
||||
| L7 — IRPC: tratamentos específicos | Contexto sectorial/territorial e fontes cadastradas | Casos identificados: tributação autónoma de despesas e mais-valias, taxas reduzidas/cooperativas, isenções/benefícios e operações especiais com condições rastreadas | Base L6, despesas, activos, relação territorial documentada | Disposição e período por tratamento; localização por si só não concede benefício. Lista de tratamentos aplicáveis explicitada no lote | 48–80 h |
|
||||
| L6 — IRPC anual: regime normal | Disponível5aaf1a56:percurso normal demonstrado atécolecta,períodos/moedas e preparação parcialM20/M22 | Operacional no âmbito demonstrado por decisãoTempo26/10;limitações explícitas;5grupos código+5documentais preservados;sem conclusão integral | Plano financeiro,dados comuns,activos/livros e histórico;retenções/pagamentos/créditos anuaisL8 | Pendências bloqueiam só os casos dependentes;L7/L8 próprios | Estimativa inicial48–80h;saldo não reestimado |
|
||||
| L7 — IRPC: tratamentos específicos | e07f89da instalado,reconfirmado26/10:main/revisão/delta6QAab2ff2fd coincidem | L7parcial;7grupos código/4documentais preservados. PróximoQA:CBF16 com duodécimos,activo novo suportado,método constante eano civil2026 | Reutilizar qualificação,activos/taxas eperiodizaçãoL6;sem benefício por localização | Provar só novos efeitos eguarda/recuperação/relatório;limites contabilístico/fiscal;sem repetir instalação;L8 separado | Estimativa inicial48–80h;saldo não reestimado |
|
||||
| L8 — IRPC: liquidação e pagamentos | Parcelas L5–L7 e formulários originais | PPC/PEC, deduções/créditos, dupla tributação quando aplicável, saldo anual a pagar/recuperar; calendário e reconciliação com pagamentos | Retenções, colecta, saldos anteriores, pagamentos/comprovativos | Base anterior para PPC/PEC, regras de limitação/transporte; não usar cinco anos ou compensação automática sem cotejo específico | 32–56 h |
|
||||
| L9 — INSS: contribuição social | Massa salarial agregada e referência TCO3%+4% | Trabalhadores, remuneração/base contributiva, exclusões, empregador/trabalhador, TCO/TCP, declaração e encargos por período | Equipa/custos, entidade e calendário; cadastro de pessoa partilhado com L10 | Regulamento e alterações aplicáveis, natureza do vínculo; confirmar base antes da taxa. Contribuição social, distinta dos impostos | 24–40 h |
|
||||
| L10 — IRPS: retenção mensal e líquido | Entrada IRPS, custos salariais e escalões anuais documentais | Tabela mensal própria, remunerações/benefícios, situação pessoal relevante, retenção, salário líquido e contribuição ligada a L9 | Mesmo trabalhador/folha salarial, pagamentos e retenções | Tabela mensal do período, residência e condições familiares necessárias; não dividir escalões anuais por12 | 40–64 h |
|
||||
@@ -6292,3 +6292,148 @@ Referência actual após a entrega `5aaf1a56`: percurso normal demonstrado até
|
||||
| Norma sectorial de provisões reguladas | Provisão200 de uma entidade financeira sujeita ao28d não herda os1,5%/6% do regime ordinário29. | Identificar sector,regulador,norma de supervisão aplicável e saldos/condições necessários,antes da implementação específica. A fonte oficial fornecida é aceite;falta a regra concreta do caso,não certificação genérica da fonte. Só provisão regulada respectiva;provisões ordinárias demonstradas preservadas. |
|
||||
|
||||
**Base da decisão operacional:** o âmbito demonstrado e as suas limitações permanecem disponíveis na interface e nas exportações;as provas aceites mantêm validade. Um fecho operacional delimitado pode referir esse âmbito,com estas extensões/documentos fora da cobertura e retoma por caso. Esta consolidação **não declara L6 integralmente concluído nem regista uma decisão de fecho ainda não tomada**. Permite preparar o avanço paraL7 sem condicionar os casos independentes à resolução de todo este saldo. Benefícios/isenções/taxas reduzidas/tributações autónomas e operações especiais mantêm âmbitoL7;retenções,pagamentos,créditos e saldo anual mantêm âmbitoL8. As dez dúvidasL5 só afectam dependências efectivas e não foram pesquisadas novamente.
|
||||
|
||||
## 26/10/2026 — L6 operacional no âmbito demonstrado e delimitação de L7
|
||||
|
||||
**Decisão expressa da Tempo:** L6 fica operacional no âmbito demonstrado disponível em `5aaf1a56`, com limitações explícitas. Não é conclusão integral de L6 ou do IRPC. Os cinco grupos de código e cinco grupos documentais da secção «saldo consolidado de L6» permanecem separados, com exemplos e condições de retoma. As notas anteriores que deixavam a decisão operacional por tomar conservam o seu valor histórico; esta decisão é posterior. As provas aceites são reutilizadas. As pendências de L5/L6 só impedem tratamentos que dependam delas.
|
||||
|
||||
**Estado deste incremento:** delimitação documental de L7, sem novo cálculo, instalação, migração, importação ou alteração de dados activos. A colecta normal entregue mantém-se distinta do saldo a pagar/recuperar. Retenções, pagamentos, aplicação anual de créditos e liquidação final permanecem em L8. Recibo: `simulations/irpc-l7-scope-20261026.json` (relativo a `docs/investmoz/`).
|
||||
|
||||
### Dados existentes e fronteiras de integração
|
||||
|
||||
| Reutilização | Contrato para L7 e limite |
|
||||
| --- | --- |
|
||||
| Oportunidade/dossier: `context_opportunity`, `context_opportunity_snapshot`, `context_applicability_snapshot`, `context_reuse` | Conservar origem e data, selecção de campos compatíveis e edições deliberadas; `context-inheritance.ts` e `dossier-prefill.tsx` já sustentam esta reutilização. Associação documental a oportunidade/âncora não confirma implantação ou incentivo. |
|
||||
| `sector_id`, `province_id`, `district_id`, `admin_post_id`, `locality_id` e respectivas designações | Servem para identificar candidatos e pedir apenas elementos em falta. Confirmar actividade efectivamente exercida, estabelecimento/projecto e parcela abrangida por documentos do caso. Localização, polígono, DUAT ou código sectorial isolados não concedem benefício. |
|
||||
| Sujeito, NUIT, residência/EP, período, início de actividade/exploração e dados do plano | Reutilizar valores declarados e respectivas provas. Data prevista no dossier não substitui início efectivo quando esse for o termo inicial da norma. Distinguir conhecido, ausência declarada e desconhecido. |
|
||||
| `business_plan_snapshot`, livro `modelo_a_snapshot.irpcNormal` e versões L6 | Receber lucro/base/colecta e parcelas identificadas, com chave e versão de origem. Só alterar o ponto previsto pela norma: ajustamento ao lucro, dedução à base, taxa por parcela ou tributação autónoma separada. Não alterar nem recalcular silenciosamente históricos. |
|
||||
| Activos, quotas anteriores e despesas já registadas | Reutilizar os mesmos identificadores e montantes; calcular apenas o efeito adicional permitido. Não repetir o acréscimo de uma despesa nem deduzir duas vezes a amortização do mesmo activo. Um caso dependente de regra L6 não implementada conserva essa dependência específica. |
|
||||
| Preparação M20/M22 e aritmética racional existentes | Conservar montante exacto, unidade/moeda e parcela. Transporte só com correspondência demonstrada para a edição; campo desconhecido, fracção não representável ou divergência editorial não invalida o cálculo independente. Não arredondar por conveniência. |
|
||||
|
||||
O motor actual de matéria colectável não subtrai benefícios positivos livres: exige regra, condições, limite e ordem. A colecta normal cobre a taxa geral no recorte demonstrado; escolher «outro tratamento» não implementa uma taxa especial. A presença de campos ou de fontes no portal não equivale a execução de L7.
|
||||
|
||||
### Famílias de tratamentos a implementar por casos compatíveis
|
||||
|
||||
As referências seguintes delimitam a regra e o ponto de integração; **não constituem benefícios concedidos nem cobertura executável nova**. O exercício do caso, alterações aplicáveis e duração individual ficam associados à versão da regra. Não se transportam taxas temporárias para outro período.
|
||||
|
||||
| Família / fonte identificada | Condições e período a guardar | Efeito e exemplo de dúvida delimitada / condição de retoma |
|
||||
| --- | --- | --- |
|
||||
| **Despesas com tributação autónoma** — CIRPC, Lei34/2007, art.61(4), com art.36(1)g; PDF17/p768(71) | Natureza legal documentada da despesa não devidamente documentada, confidencial ou ilícita; valor e exercício; taxa de 35% da disposição e versão aplicável ao período. Não classificar pela simples falta de ficheiro anexado. | Parcela autónoma separada da colecta normal; reutilizar o acréscimo36g já feito, sem duplicação. Ex.: despesa100 já acrescida em L6 → parcela autónoma35 no caso qualificado; não é saldo final. Se só falta anexo, pedir a caracterização/prova da despesa e manter indeterminado apenas este tratamento. |
|
||||
| **Mais-valias autónomas** — Lei12/2025, art.2, CIRPC61-A; art.3 revoga39/47; art.6 vigora em01/01/2026; PDF20/p2180(20) | Alienação, activo, datas, realização/valor fiscal, origem contabilística, período e parcela identificados; taxa32% do61-A. Separar eventos anteriores a2026. | Apurar parcela autónoma, reconciliando o que já integra o resultado L6, sem dupla incidência ordinária/autónoma nem compensação presumida de perdas. Ex.: ganho100 incluído no resultado exige identificar a sua parcela antes de integrar a colecta autónoma32. Retoma: implementar essa reconciliação e a regra de apuramento aplicável ao activo; não bloqueia despesas autónomas ou benefícios independentes. |
|
||||
| **Isenções e redução por natureza da entidade** — CIRPC9–14; cooperativas no art.12, PDF5/p768(59), e taxa geral61(1) | Tipo efectivo da entidade, rendimentos elegíveis/excluídos, destino dos rendimentos, constituição e reconhecimento apenas onde exigido pela disposição; exercício e norma aplicável. Art.12 refere cooperativas agrárias, de artesanato e culturais e redução de50% da taxa geral; não todas as cooperativas. Arts.12(2)/14 separam rendimentos sujeitos a retenção. | Isenção ou taxa reduzida apenas na parcela coberta; actividade comercial acessória não se torna isenta por designação da entidade. Ex.: cooperativa com actividade elegível e outra não abrangida exige separar rendimentos e custos. Retoma: classificação documental e segregação da parcela, sem transportar a dispensa para retenções L5 ou liquidar créditos L8. |
|
||||
| **Amortização acelerada** — CBF, Lei4/2009, art.16; compilaçãoAPIEX p72 | Imóveis novos usados no projecto; imóveis reabilitados e máquinas/equipamentos industriais/agro-industriais nas condições da disposição; enquadramento CBF3/9/10 quando aplicável, entrada em uso, taxa normal, base, quota contabilizada e quotas anteriores. Incremento de50% sobre a taxa normal, não cinquenta pontos percentuais. | Efeito no ajustamento ao lucro e, através da cadeia L6, na base/colecta. Ex.: taxa normal10% → taxa acelerada15%, antes das restantes condições/limites; não autoriza uma segunda dedução integral. Retoma por activo com classificação/documentos e conciliação de quotas/custo disponíveis; tabelas L6 em falta bloqueiam só o activo dependente. |
|
||||
| **Deduções e majorações de despesas/investimentos** — CBF17–19; compilaçãoAPIEX pp73–74 | Tecnologia de ponta, formação de trabalhadores moçambicanos e despesas elegíveis de utilidade pública: natureza, base, exercício inicial, janela dos primeiros cinco anos/exercícios conforme artigo, limites, exclusões, ordem e não cumulaçãoCBF4. Distinguir dedução à matéria colectável de majoração de custo. | Efeito no ponto exacto previsto pela disposição. Ex.: formação sem prova do tipo não permite escolher entre o limite5% e o ramo10% para novas tecnologias do art.18. Retoma: identificar tipo/base de limite e conciliar a despesa já contabilizada; não converter percentagem em dedução livre. |
|
||||
| **Crédito fiscal por investimento** — CBF15; compilaçãoAPIEX pp71–72 | Investimento novo elegível, exclusões, início, Maputo/outras províncias como uma das condições, parcela da colecta atribuível ao projecto e prazo de utilização/transporte de cinco exercícios. Taxas5%/10% distinguem os ramos da disposição, sem direito automático por localização. | **L7 identifica origem, elegibilidade e crédito potencial; L8 aplica o crédito anual, limites/saldos e liquidação.** Ex.: projecto situado fora de Maputo, sem discriminação do investimento elegível, não gera automaticamente10% de crédito. Retoma: base elegível e calendário documentados; utilização anual aguarda o mecanismo L8. |
|
||||
| **Tratamentos sectoriais/territoriais CBF** — infra-estruturas20–22; agricultura/pescas27–29; turismo30–33; parques de ciência34–35; grandes projectos36–38; zonas de rápido desenvolvimento39–44; ZFI45–46; ZEE47–48 | Seleccionar a disposição de IRPC efectivamente pertinente, actividade/projecto, delimitação/estabelecimento e estatuto comprovados, data de autorização/início quando exigidos, escalões, duração, cumulação e cessaçãoCBF49–52. ZFI46 e ZEE48 são os artigos de impostos sobre rendimento. Não tratar benefícios exclusivamente aduaneiros como benefícios IRPC. | Isenção, redução ou dedução por parcela e intervalo próprio, em vez de taxa comum ao sector/localização. Ex.: endereço numa ZEE sem estatuto documentado deixa o ramo ZEE pendente; o cálculo normal independente continua. CIRPC61(2) na Lei20/2022 tem termo31/12/2025: não presumir prorrogação para2026. Retoma de cada ramo: condições e cronologia da disposição específica preenchidas, com regra versionada; não exigir pesquisa repetida de todos os sectores. |
|
||||
| **Operações e regimes especiais** — CIRPC54–56 (entradas de activos, fusões/cisões e sócios), transferência de perdas41-A; regimes sectoriais específicos do acervo | Tipo de operação, intervenientes, residência, datas, activos/passivos/valores fiscais e continuidade; identificar diploma sectorial/artigo e regra aplicável antes de escolher tratamento. Não inferir neutralidade por chamar «fusão» à operação nem aplicar regime mineiro/petrolífero por rótulo sectorial. | Continuidade/ajustamento/tributação diferida ou parcela própria conforme norma, mantendo bases históricas. Ex.: perda recebida de outra sociedade não é perda própria ordinária41 de L6. Retoma: correspondência específica41-A e operação documentada; regras sectoriais sem artigo correspondido ficam candidatas, sem taxa provisória. Não há bloqueio transversal de L7. |
|
||||
|
||||
### Registo por tratamento e demonstração a exigir ao código novo
|
||||
|
||||
Cada tratamento terá: identificador estável; sujeito/NUIT; oportunidade/projecto/estabelecimento e parcela; contexto herdado e divergências; fonte/exemplar/hash/artigo/versão; intervalo de vigência e período do caso; facto que inicia/termina a duração; condições individualizadas em «sim/não/desconhecido» com prova ou ausência declarada; título/reconhecimento somente quando a regra o exige; base elegível, taxa, limite, ordem e compatibilidade com outros tratamentos; resultado normal de origem; efeito adicional e ponto da cadeia; moeda/conversão e pressupostos; montante exacto; motivos de exclusão/informação em falta; versão/histórico e dependência concreta.
|
||||
|
||||
Os estados «candidato», «não aplicável», «informação em falta» e «calculado por regra implementada» não se confundem. Ausência declarada pode produzir efeito zero justificado; desconhecido não produz benefício zero nem benefício presumido. Uma condição negativa exclui o tratamento e conserva o percurso normal quando os seus dados são suficientes. Com potencial benefício ainda indeterminado, apresentar o cenário normal de referência e a parcela pendente sem declarar total fiscal definitivo. Mudança de sector/localização/documento invalida apenas a correspondência dependente e pede confirmação de reutilização; conserva o original e as edições deliberadas.
|
||||
|
||||
**Primeiro incremento delimitado para implementação:** qualificação comum e segregação de efeitos, acompanhadas do caso35% do61(4), com despesa já ajustada36g e caso de informação insuficiente. É independente de transporte M20/M22 não correspondido e de amortizações L6 em falta. **Incremento compatível seguinte:** cooperativa abrangida pelo12 com parcela elegível separada e amortização acelerada16 para activo já suportado em L6; cada caso só acompanha a entrega se demonstrado. Mais-valias61-A, deduções17–19, ramos sectoriais e operações especiais seguem separadamente quando as respectivas parcelas/regras estiverem correspondidas. Crédito15 prepara direito potencial em L7 e contrato de passagem para L8, sem antecipar liquidação anual.
|
||||
|
||||
Para cada nova regra: condição satisfeita, negativa, informação em falta, período incompatível/benefício expirado, sobreposição com ajustamento existente e alteração de contexto. Demonstrar apenas o delta: cálculo → gravação → recuperação → relatório, incluindo fonte, período, condições, efeito no lucro/base/colecta ou parcela autónoma e saldo final L8 por determinar. Recuperar históricos anteriores sem os alterar; não duplicar ajustamentos ao voltar a guardar. Reutilizar as provas aceites; não reabrir L3, ISPC, câmbio ou percursos L5/L6 independentes.
|
||||
|
||||
### Fontes consultadas e pendências delimitadas
|
||||
|
||||
Reutilizado o inventário autorizado de **8143ficheiros**, sem nova varredura de pastas. Para delimitação foram consultados os originais CIRPC/alterações já arquivados, a Lei4/2009 local e a compilação oficial [APIEX — Legislação de Investimentos em Moçambique](https://pt.apiex.gov.mz/wp-content/uploads/2025/02/LEGISLACAO-DE-INVESTIMENTOS-EM-MOCAMBIQUE.pdf), que reúne Lei8/2023, Decreto8/2024 e CBF4/2009. Disponibilidade, situação documental/jurídica e uso no cálculo continuam estados independentes. O acesso actual à cópia CBF supera a indisponibilidade assinalada em notas antigas; não activa regra nem apaga a nota histórica. Artigos, páginas, hashes e limites no recibo. A compilação não dispensa o período/alterações de cada tratamento, nem cria validação jurídica genérica adicional.
|
||||
|
||||
**Código por implementar em L7:** qualificação e persistência específicas; efeitos segregados; regras das famílias acima, por parcelas; conciliação sem duplicação; relatório/exportação correspondente. **Documentação por caso:** estatuto/reconhecimento ou enquadramento individual quando a fonte o exige; identificação de parcela/limite/cronologia; norma sectorial ainda sem correspondência; edição/campo de transporte afectado. Cada uma conserva exemplo e condição de retoma na linha correspondente. Não é necessário resolver todos os documentos para começar o primeiro incremento independente. L6 operacional não elimina este desenvolvimento; L7 delimitado não é L7 implementado; L8 conserva a liquidação final.
|
||||
|
||||
## 26/10/2026 — L7: qualificação, despesas autónomas e casos compatíveis em QA
|
||||
|
||||
**QA, sem instalação.** Base instalada preservada `5aaf1a56`; delimitação `d37fffb2`; ramo `codex/irpc-l7-common-autonomous-qa-20261026`, fotografia opcional `IRPC-normal-adjustments/10`. L6 continua operacional no âmbito demonstrado, com os cinco grupos de código e cinco documentais preservados. A implementação abaixo acrescenta apenas os tratamentos demonstrados; não conclui L7 nem o IRPC. Saldo final, retenções, pagamentos e aplicação anual de créditos permanecem em L8.
|
||||
|
||||
**Qualificação comum executável:** reutiliza sujeito/NUIT, âmbito, período, origem da oportunidade/dossier, sector e território; guarda condições, prova, fonte/artigo e período por tratamento. «Informação em falta», «ausência declarada», «não aplicável/condição negativa» e «calculado» têm resultados distintos. Desconhecido não vira zero. Período incompatível, identidade por reconciliar ou contradição afectam só o resultado dependente. A localização não escolhe taxa nem activa benefício. Os snapshots de origem ficam internos; o relatório apresenta contexto legível e as condições documentadas.
|
||||
|
||||
**Despesas61(4):** cada parcela aponta para uma linha `undocumented` do mapa36(1)g de L6, com acréscimo integral já calculado. Montante, documento e linha são reutilizados; L7 não introduz outro acréscimo nem outra despesa. A classificação legal e incidência são declaradas com prova própria; falta de anexo não classifica uma despesa. O imposto autónomo usa35% apenas nos casos qualificados. Duplicação da referência, parcela não correspondida, ausência contraditória ou informação insuficiente deixam o imposto reconciliado indeterminado; as parcelas conhecidas permanecem discriminadas. Condição negativa documentada conserva o ajustamentoL6 e não aplica imposto autónomo à parcela.
|
||||
|
||||
**Cooperativas12/14:** agrárias, artesanato ou culturais, residentes, com base ordinária integralmente elegível e ausência documentada de rendimentos sujeitos a retenção, aplicam redução de50% à taxa geral32%, ou16%. Não depende de seleccionar um sector semelhante. A qualificação especial pode coexistir com a opção «outro tratamento» da colectaL6: não exige fingir que a taxa reduzida é regime geral. Parcela mista, rendimentos retidos, outra entidade ou ausência contraditória conservam pendência própria; não recebem redução global presumida. O imposto autónomo de despesas não é reduzido por esta taxa.
|
||||
|
||||
**CBF16:** reutiliza identificadores e valores dos activosL6 suportados; imóvel novo do projecto ou máquinas industriais/agro-industriais das categorias correspondidas, com enquadramentoCBF3/9 e reconhecimento10 quando exigido (ou excepção identificada). Recorte inicial: primeiro exercício anual civil2026, método constante pela taxa normal máxima da tabela, activo desde01/01/2026, custo histórico novo, sem quotas anteriores/saída e sem cumulação de outros benefícios. Incrementa a taxa normal em50% e reutiliza limites de contabilização/saldo fiscal. Deduz apenas a diferença entre o mapa normal e o acelerado, sem alterar o activo de origem, os documentos ou os saldos oficiais. Quotas constantes gerais e demais cálculosL6 conservam o comportamento anterior quandoL7 está ausente.
|
||||
|
||||
| Caso sintético recuperado da API QA | Lucro/base e colecta de referênciaL6 | EfeitoL7 demonstrado | Resultado e limite |
|
||||
| --- | --- | --- | --- |
|
||||
| Despesa100 já acrescida36g | Lucro/base3230;colecta1033,60MZN | Novo ajustamento ao lucro0;imposto autónomo35 | Colecta combinada1068,60MZN;saldo finalL8indeterminado |
|
||||
| Classificação da mesma despesa em falta | Lucro/base3230;colecta1033,60MZN preservados | Imposto autónomo indeterminado | Colecta combinada indeterminada;sem perda dos cálculos independentes |
|
||||
| Condição negativa documentada na parcela | Ajustamento36g100 preservado | Parcela não aplicável;imposto autónomo0 justificado | Não confunde condição negativa com informação em falta |
|
||||
| Ausência declarada de despesas autónomas | Lucro/base3130;colecta1001,60MZN | Ausência com suporte;imposto autónomo0 | Ausência contraditória com despesa36g fica pendente |
|
||||
| Cooperativa integralmente abrangida | Base3130;colecta geral1001,60MZN | Taxa16%;colecta500,80MZN | Base/proveitos não alterados;sem retenções/créditos abatidos |
|
||||
| Máquina industrial existente:base1000,taxa10%,quota contabilística120 | Quota normal100;lucro/base6260;colecta2003,20MZN | Quota acelerada150,mas dedução limitada120;diferença adicional20 | Lucro/base6240;colecta1996,80MZN;sem deduzir50 nem150 outra vez |
|
||||
|
||||
**Cálculo → gravação → recuperação → relatório:** fotografia10 opcional no mesmo livro/snapshot, chave com entradas/contexto e histórico imutável anterior. SemL7, a fotografia9 aceite e a sua chave/totais permanecem iguais. Recalcular não acumula imposto nem duplica o acréscimo. HTML e dossier financeiro mostram referênciaL6, efeitosL7, parcelas autónomas, fonte, condições, período e limitações; recuperação e download demonstrados no componente real. Uma mudança de origem/entradas torna a fotografia anterior histórica; não altera o registo anterior. M20/M22 conservam a preparaçãoL6 de referência: **este incremento não transporta efeitosL7 para campos oficiais por aproximação**, nem resolve as divergências documentais existentes.
|
||||
|
||||
**Provas novas:** Wayfinder `--with-form` gerou routes/actions pelo wrapper QA; TypeScript e build QA passaram. Dezanove testes dirigidos novos passaram, incluindo comparação exacta com a fotografia9 aceite, duplicação, período curto, opção especial de cooperativa, ausência contraditória, dados em falta e contexto apresentado sem despejar snapshots internos. API privada:1teste/108asserções, `simulator_fiscal_delta_20261021_test`,127.0.0.1:55441, transacção com rollback e guarda de identidade/base; seis casos recuperados com plano/livro/históricos idênticos. UI do componente real: alteração de classificação, informação em falta, ausência, cooperativa mista, cumulação pendente, gravação/recuperação local e exportação; sem erros de página. A prova local é distinta da API. Não houve testes/escrita no activo nem repetição das suites funcionais aceites de L3, ISPC, câmbio ou L5/L6.
|
||||
|
||||
**Entrega agrupada preparada:** qualificação + despesas autónomas, cooperativa integralmente elegível e amortizaçãoCBF16 no recorte acima. Despesa autónoma e cooperativa também foram demonstradas juntas:parcela35 sem redução,colecta sobre a base516,80 e combinada551,80MZN no exemplo de base3230. Isto não autoriza cumulação cooperativa+CBF16: essa combinação mantém resultado dependente indeterminado. A futura instalação segue o procedimento Git existente, com backup/restauro fresco e conferência do delta; não foi executada nesta passagem.
|
||||
|
||||
**SaldoL7 na mesma matriz:**
|
||||
|
||||
| Natureza | Ainda fora da cobertura / exemplo | Condição concreta de retoma |
|
||||
| --- | --- | --- |
|
||||
| Código | Despesa autónoma fora de linha36g calculada ou parcela ainda não segregada | Implementar origem/segregação correspondente e prova da incidência;não copiar montante para uma segunda despesa |
|
||||
| Código | Cooperativa com actividade abrangida e outra não abrangida,ou rendimento sujeito a retenção | Segregar proveitos/custos/base e aplicar o tratamento apenas à parcela elegível;L5 conserva a retenção |
|
||||
| Código | CBF16 em imóvel reabilitado,outra categoria,quota inferior à máxima,método degressivo,duodécimos,quotas anteriores ou exercício posterior | Corresponder regra e cronologia respectivas e reutilizar o activo/quotas existentes;pendênciaL6 limita apenas o activo dependente |
|
||||
| Código/documento por caso | Cooperativa+CBF16 ou outro benefício positivo a cumular | Identificar compatibilidade,ordem e limites específicos;implementar a combinação,sem presumir soma de benefícios |
|
||||
| Código | Mais-valias61-A,demais isenções/deduçõesCBF17–19,regimes sectoriais/territoriais e operações especiais | Implementar a família/parcelas já delimitadas na secção anterior;período e fonte específicos,sem nova pesquisa transversal |
|
||||
| Documento por caso | Estatuto/título/excepçãoCBF ou prova das condições em falta;endereçoZEE sem estatuto | Juntar o elemento que a disposição exige ou registar condição negativa;localização isolada permanece insuficiente |
|
||||
| Transporte/documento | CampoM20/M22 para efeitoL7,edição divergente ou representação não correspondida | Correspondência do campo/edição e regra de representação demonstradas;preservar o cálculo independente exacto |
|
||||
| ÂmbitoL8 | Direito potencial ao créditoCBF15,aplicação anual de créditos,retenções,pagamentos e saldo final | Executar o mecanismo próprioL8;nenhuma dedução/compensação anual é presumida neste lote |
|
||||
|
||||
Fontes reutilizadas: inventário autorizado8143ficheiros; originaisCIRPC/alterações e CBF/compilaçãoAPIEX já identificados na delimitação,com hashes conservados. Sem activação por consulta ou revalidação jurídica genérica. Recibo: `docs/investmoz/simulations/irpc-l7-common-qa-20261026.json`. Provas locais: `outputs/irpc-l7-common/`; reprodução dirigida: `node --test tests/frontend/irpc-special.test.mjs`, `php tools/irpc-special-qa.php routes`, `php tools/irpc-special-qa.php test`, `tsc --noEmit`, build com `INVESTMOZ_QA_BUILD=1`.
|
||||
|
||||
## 26/10/2026 — preparação da entrega L7 e preservação do main concorrente
|
||||
|
||||
A entrega do âmbito QA `ab2ff2fd` integra o `main` concorrente `a2122dc3`, sem substituir as alterações de apresentação/navegação. Os seis ficheiros de execução L7 conservam exactamente o código QA;os oito ficheiros concorrentes conservam exactamente o código do main. Reutilizadas as provas19testes/API108/UI/tipos/build de L7. O conflito documental foi resolvido recuperando586linhas de histórico do manual que tinham sido removidas no merge concorrente,sem apagar a sua notaV2-01 no CSV. As3555linhas mantêm-se,com o único delta fiscal emAUD-SIM-INT02. O registo de instalação só será actualizado após backup/restauro fresco,conferência do destino e conclusão da entrega Git;esta nota não a antecipa.
|
||||
|
||||
## 26/10/2026 — primeira entrega agrupada L7 instalada pelo Git
|
||||
|
||||
Instalada `e07f89da3d59d06aa1b8c50c22a478b7b167bfdd` (integração do código QA `ab2ff2fdbcbe6fb94f03e4bc4cc7ccbd647d94fc` com o main concorrente`a2122dc3`),com `5aaf1a56f9d928331364fcc8b0d1528e51dba327` preservado como versão anterior. Os seis ficheiros de execução L7 são exactamente os da prova QA aceite;as sete alterações concorrentes de apresentação/navegação e o respectivo teste foram preservados. Recuperadas586linhas de histórico do manual removidas no merge concorrente;notaV2-01 conservada,sem alterar o seu conteúdo.
|
||||
|
||||
Backup fresco `2026-10-26T10:55:59Z`;restauro isolado sem rede/55441 verificou174tabelas por contagem/checksum e369ficheiros/configuração. Conferidos13ficheiros de execução do delta,50protegidos e31originais. Schema,roles/grants e permissões mantêm-se;172tabelas de negócio iguais ao backup. Cache/sessões reconciliadas por eventos operacionais e acessos públicos,sem inferir perda por RLS. A versão activa e a anterior foram preservadas durante o arquivo conferido de dependências antigas para recuperar espaço;nenhum dado,original ou backup foi eliminado.
|
||||
|
||||
Revisão/manifest público,marcadoresL7/L6/câmbio,assets e simuladorHTTP200 conferidos. Procedimento Git concluído;provas funcionais aceites19testes/API108/UI/tipos/build reutilizadas. Os controlos automáticos obrigatórios da instalação ficaram registados no recibo,sem nova ronda manual dos casos aceites. Sem migrações,importações,recálculo de históricos ou escrita privada sintética no activo.
|
||||
|
||||
Disponíveis apenas qualificação e tratamentos demonstrados:despesas61(4) sobre36g já ajustado,cooperativas12 integralmente abrangidas eCBF16 no recorte documentado. L6 permanece operacional no âmbito aceite;as suas pendências condicionam só dependentes. L7/IRPC não estão integralmente concluídos;localização não concede benefício;saldo final permaneceL8. O estado anterior deQA sem instalação é histórico. Recibo:`docs/investmoz/simulations/irpc-l7-common-delivery-20261026.json`.
|
||||
|
||||
## 26/10/2026 — saldo concreto de L7 após a primeira entrega agrupada
|
||||
|
||||
O âmbito demonstrado compreende qualificação comum, imposto autónomo61(4) sobre parcelas36g já calculadas emL6, cooperativas12 integralmente abrangidas e amortizaçãoCBF16 nos activos/período/método expressamente suportados. L7 permanece parcial. Este saldo distingue implementação de prova documental por caso; não cria outra matriz nem exige revalidação genérica das fontes aceites. L6 mantém o estado operacional delimitado e as suas pendências; só condiciona tratamentos que efectivamente dependam delas.
|
||||
|
||||
### Código ainda por implementar
|
||||
|
||||
| Tratamento / caso fora da cobertura | Exemplo | Condição concreta de retoma |
|
||||
| --- | --- | --- |
|
||||
| Despesas autónomas fora de parcela36g calculada e segregações adicionais | Despesa100 com apenas60 correspondidos no mapa de origem,ou encargo não incluído no resultado de partida | Implementar origem/parcela e reconciliação próprias,documentar incidência61(4) e impedir nova contabilização/acréscimo da mesma despesa. O ramo já entregue36g não é reaberto. |
|
||||
| Cooperativas com rendimentos mistos/retidos;demais isenções por natureza da entidade,CIRPC9–14 | Cooperativa com actividade agrária e serviços não abrangidos;associação com rendimentos comerciais acessórios | Segregar proveitos,custos e base elegível e implementar o artigo específico. Não reduzir a base inteira nem estender a redução às retençõesL5. |
|
||||
| ExtensõesCBF16 e combinações de benefícios | Imóvel reabilitado,método degressivo,quota inferior à máxima,duodécimos,quotas anteriores,ano posterior,cooperativa+CBF16 | Corresponder a regra temporal/método/contabilização e a compatibilidade/ordem/limite da combinação;reutilizar activo e quotas. Tabela ou casoL6 em falta impede apenas o activo dependente. |
|
||||
| Mais-valias autónomas61-A e operações especiais | Ganho100 já incluído no resultado em2026;entrada de activos/fusão;perda transferida de outra sociedade | Implementar apuramento/parcela e reconciliação com resultadoL6,sem dupla incidência ou compensação de perdas presumida;para operações,aplicar54–56/41-A e preservar valores históricos. |
|
||||
| Deduções/majoraçõesCBF17–19 e crédito potencialCBF15 | Formação sem ramo/base de limite;investimento novo com activos elegíveis e excluídos | Implementar elegibilidade,base,limite,ordem,janela temporal e não cumulação. CBF15 emL7 delimita direito/origem/crédito potencial;utilização anual,limitação por créditos/saldos e liquidação ficam emL8. |
|
||||
| Regimes sectoriais/territoriais e disposições especiais | Projecto emZEE sem tratamentoIRPC correspondido;actividade mineira/petrolífera com regime próprio | Implementar a disposição/versão/período aplicáveis ao projecto e à parcela (CBF20–48 ou diploma específico). Endereço/código sectorial só identifica candidato;benefício aduaneiro não se transforma em benefícioIRPC. |
|
||||
| Transporte de efeitosL7 paraM20/M22 | Imposto autónomo ou redução calculados mas sem campo/edição correspondente | Implementar apenas a correspondência demonstrada e a representação aplicável;conservar os montantes exactos e a preparaçãoL6 de referência,sem campo/taxa provisórios. |
|
||||
|
||||
### Dependências documentais que condicionam apenas o caso afectado
|
||||
|
||||
| Elemento em falta / dúvida concreta | Exemplo | Condição de retoma |
|
||||
| --- | --- | --- |
|
||||
| Classificação/incidência,parcela e período da operação | Há uma despesa36g e falta qualificar61(4);ou há actividade elegível e outra não abrangida | Associar prova/declaração da natureza e parcela ao exercício correcto. Informação em falta continua indeterminada;condição negativa e ausência declarada têm suporte próprio. Não inferir pela falta de anexo. |
|
||||
| Estatuto e reconhecimento exigidos pela disposição | Endereço numaZEE sem estatuto do projecto;CBF16 sem instrumento10 ou norma de excepção | Juntar o elemento concreto exigido ou documentar a condição negativa/excepção aplicável. Não pedir aprovador ou parecer jurídico genérico adicional. |
|
||||
| Norma/período/compatibilidade específicos ainda não correspondidos | Redução com termo31/12/2025 pretendida em2026;cumulação cooperativa+CBF16 | Disposição de vigência/prorrogação efectiva ou correspondência da combinação e seus limites. Sem informação nova,não repetir pesquisa transversal;prosseguir com os restantes casos. |
|
||||
| Edição,campo ou representação do formulário | EfectoL7 com campoM20/M22 não identificado ou fracção sem regra de representação | Identificar exemplar/edição,instrução/campo e forma de representar o valor;limitar a pendência ao transporte afectado. O cálculo independente mantém-se disponível. |
|
||||
|
||||
**Limites conservados:** localização não concede benefícios automaticamente;benefício desconhecido não é zero;colecta normal,L7 e imposto autónomo permanecem discriminados. Retenções,pagamentos,aplicação anual de créditos e saldo final a pagar/recuperar continuam emL8. As provas aceites não são invalidadas por esta lista nem por uma dúvida documental num caso independente.
|
||||
|
||||
## 26/10/2026 — reconciliação do estado servido L7 e capacidade do instalador
|
||||
|
||||
Conferência autenticada por leitura em `2026-10-26T13:56:51.412248+02:00` (Africa/Johannesburg):o portal,o registo do instalador e o main actual coincidem em `e07f89da3d59d06aa1b8c50c22a478b7b167bfdd`. **L7 já está instalado no âmbito demonstrado**,com origemQA`ab2ff2fd`;o estado «ainda emQA,sem instalação» é histórico/desactualizado. A instalação terminou em26/10/2026 às13:02:35 locais;backup anterior às12:55:59 e restauro174tabelas/369ficheiros permanecem comprovados pelo recibo de entrega. Nesta passagem,o dump e o arquivo de ficheiros ainda coincidem com os hashes desse backup e a prova de restauro refere o mesmo dump. Não foi apresentado um novo backup/restauro como executado,nem repetida a instalação da revisão já activa.
|
||||
|
||||
**Partição do instalador e backup:**`/dev/md2 / ext4`;release,state,backup,tmp eDocker no mesmo dispositivo. Livres5.52GiB e21448231inodes de29089792. O código do instalador mantém o limiar5GiB;os ficheiros do backup observado ocupam0.164GiB. A leitura satisfaz5GiB+um backup desse tamanho,com margem0.35GiB. A release actual tem28674ficheiros e2503directórios sem seguir links,como referência de escala,não um novo limite arbitrário de inodes. Futuras entregas devem voltar a medir a capacidade imediatamente antes da operação;estes números não garantem uma carga futura diferente. Nenhuma limpeza local/remota foi executada;SGF TEMPO não foi afectado.
|
||||
|
||||
**Só o delta L7:**seis hashes de código correspondem à provaQA;revisão/manifest,sete marcadoresL7,quatroassets e entrada do simuladorHTTP200 conferidos. Reutilizadas as provas19testes/API108/UI/tipos/build e as provas anteriores de preservaçãoL6/L3/ISPC/câmbio;sem nova ronda funcional,escrita privada sintética,migração ou importação. A revisão activa e a anterior permanecem preservadas.
|
||||
|
||||
**Próximo conjunto delimitado para implementaçãoQA:CBF16 com duodécimos.** Reutilizar activos,tabela/taxa normal máxima,método constante,qualificaçãoCBF e periodizaçãoL6 existentes. Primeiro caso:exercício anual civil2026 com entrada em uso durante o ano;imóvel novo do projecto ou máquina industrial/agro-industrial já suportada;sem quotas anteriores,saída ou cumulação de outros benefícios. Ligar a quota mensalL6 ao incrementoCBF16,limitando ao contabilizado/saldo fiscal e mostrando apenas a diferença adicional. Demonstrar condição satisfeita,negativa,informação em falta e ausência declarada,cálculo→gravação→recuperação→relatório,efeitos no lucro/base/colecta e conservação dos históricos. Este conjunto está apenas delimitado:não é novo cálculo instalado.
|
||||
|
||||
Degressivo,reabilitados/usados/reavaliados,quotas anteriores e cumulação cooperativa+CBF16 continuam nos casos próprios. O saldo anterior de sete grupos de código e quatro dependências documentais permanece na mesma matriz,com exemplos/condições de retoma;nenhuma pendência foi apagada. Documento individual em falta limita só o activo/caso dependente. Localização não concede benefício. **L6 operacional delimitado;L7 parcial;retenções,pagamentos,créditos anuais e saldo final emL8.** Recibo:`docs/investmoz/simulations/irpc-l7-server-state-20261026.json`.
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,3 +1,4 @@
|
||||
import { Link } from '@inertiajs/react';
|
||||
import { ArrowRight, Search } from 'lucide-react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import type { FormEvent } from 'react';
|
||||
@@ -127,7 +128,6 @@ type PortalHeroProps = {
|
||||
query: string;
|
||||
setQuery: (value: string) => void;
|
||||
onSearch: (event: FormEvent<HTMLFormElement>) => void;
|
||||
onNavigate: (view: 'opportunities') => void;
|
||||
stats?: HomeResponse['data']['stats'];
|
||||
};
|
||||
|
||||
@@ -136,7 +136,6 @@ export default function PortalHero({
|
||||
query,
|
||||
setQuery,
|
||||
onSearch,
|
||||
onNavigate,
|
||||
stats,
|
||||
}: PortalHeroProps) {
|
||||
const [currentSlide, setCurrentSlide] = useState(0);
|
||||
@@ -261,20 +260,38 @@ export default function PortalHero({
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div className="mt-6 flex flex-wrap items-center justify-center gap-3">
|
||||
<button
|
||||
onClick={() => onNavigate('opportunities')}
|
||||
className="inline-flex min-h-11 items-center gap-2 rounded-xl bg-white px-5 py-3 text-sm font-semibold text-[#101820] transition-colors hover:bg-slate-100 focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-white"
|
||||
<div className="mt-4 flex flex-wrap items-center justify-center gap-2">
|
||||
<Link
|
||||
href="/porque-investir"
|
||||
className="inline-flex min-h-11 items-center rounded-lg border border-white/50 bg-black/15 px-3 py-1.5 text-sm font-semibold text-white transition-colors hover:bg-white/15 focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-white sm:min-h-9"
|
||||
>
|
||||
Consultar oportunidades{' '}
|
||||
Porquê investir em Moçambique?
|
||||
</Link>
|
||||
<Link
|
||||
href="/investimentos/iniciar"
|
||||
className="inline-flex min-h-11 items-center rounded-lg border border-white/50 bg-black/15 px-3 py-1.5 text-sm font-semibold text-white transition-colors hover:bg-white/15 focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-white sm:min-h-9"
|
||||
>
|
||||
Partir de uma ideia
|
||||
</Link>
|
||||
<Link
|
||||
href="/oportunidades"
|
||||
className="inline-flex min-h-11 items-center gap-1.5 rounded-lg bg-white px-3 py-1.5 text-sm font-semibold text-[#101820] transition-colors hover:bg-slate-100 focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-white sm:min-h-9"
|
||||
>
|
||||
Consultar oportunidades
|
||||
<ArrowRight size={16} aria-hidden="true" />
|
||||
</button>
|
||||
<a
|
||||
</Link>
|
||||
<Link
|
||||
href="/simulador-fiscal"
|
||||
className="inline-flex min-h-11 items-center rounded-xl border border-white/50 bg-black/15 px-5 py-3 text-sm font-semibold text-white transition-colors hover:bg-white/15 focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-white"
|
||||
className="inline-flex min-h-11 items-center rounded-lg border border-white/50 bg-black/15 px-3 py-1.5 text-sm font-semibold text-white transition-colors hover:bg-white/15 focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-white sm:min-h-9"
|
||||
>
|
||||
Simulador Fiscal
|
||||
</a>
|
||||
</Link>
|
||||
<Link
|
||||
href="/sectores"
|
||||
className="inline-flex min-h-11 items-center rounded-lg border border-white/50 bg-black/15 px-3 py-1.5 text-sm font-semibold text-white transition-colors hover:bg-white/15 focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-white sm:min-h-9"
|
||||
>
|
||||
Sectores de investimento
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<dl
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import {SimulationIrpcSpecial} from '@/components/simulation-irpc-special';
|
||||
import {SimulationIrpcFormPreparation} from '@/components/simulation-irpc-form-preparation';
|
||||
import {SimulationIrpcPeriodFx} from '@/components/simulation-irpc-period-fx';
|
||||
import {SimulationIrpcDepreciation} from '@/components/simulation-irpc-depreciation';
|
||||
@@ -39,8 +40,9 @@ export function SimulationIrpcNormal({draft,onChange}:{draft:Record<string,unkno
|
||||
<SimulationIrpcCosts draft={draft} book={b} save={save}/>
|
||||
<SimulationIrpcTaxableBase draft={draft} book={b} save={save}/>
|
||||
<SimulationIrpcAssessment book={b} save={save}/>
|
||||
<SimulationIrpcSpecial draft={draft} book={b} save={save}/>
|
||||
<SimulationIrpcFormPreparation draft={draft} book={b} save={save}/>
|
||||
<button type="button" onClick={()=>{try{save(recordNormal(draft,b));}catch(e){setError(String(e));}}}>Calcular e guardar ajustamentos L6</button>
|
||||
<button type="button" onClick={()=>{try{save(recordNormal(draft,b));}catch(e){setError(String(e));}}}>Calcular e guardar L6 e tratamentos L7 preparados</button>
|
||||
<button type="button" onClick={()=>{try{const html=normalHtml(draft),url=URL.createObjectURL(new Blob([html],{type:'text/html;charset=utf-8'})),a=document.createElement('a');a.href=url;a.download='IRPC-normal-ajustamentos.html';a.click();URL.revokeObjectURL(url);setError('');}catch(e){setError(String(e));}}}>Exportar mapa parcial L6</button>
|
||||
{normalReportRows(draft).map((r,n)=><p key={n}>{r[1]} — {r[2]} — {r[3]}</p>)}
|
||||
</section>;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import type {NormalBook} from '@/lib/irpc-normal';
|
||||
import {newSpecialInput,newSpecialExpense,newAcceleratedAsset,specialSources,type SpecialInput,type Qualification} from '@/lib/irpc-special';
|
||||
|
||||
type Props={draft:Record<string,unknown>;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)=><label className="block">{text}<input aria-label={label+' — '+text} value={value[key]} onChange={e=>onChange({...value,[key]:e.target.value})}/></label>;
|
||||
return<div className="space-y-2"><label className="block">Estado — {label}<select aria-label={'Estado — '+label} value={value.state} onChange={e=>onChange({...value,state:e.target.value as Qualification['state'],eligible:''})}>{states.map(([v,t])=><option key={v} value={v}>{t}</option>)}</select></label>{value.state==='known'&&<label className="block">Condições — {label}<select aria-label={'Condições — '+label} value={value.eligible} onChange={e=>onChange({...value,eligible:e.target.value as Qualification['eligible']})}><option value="">Por esclarecer</option><option value="yes">Sim — condições documentadas</option><option value="no">Não — condição negativa documentada</option></select></label>}{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')}</div>;
|
||||
}
|
||||
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<section className="rounded border p-3"><h5>L7 — benefícios e casos especiais</h5><p>Preparação opcional e separada do percursoL6 já entregue. Localização e sector não activam benefícios. A liquidação final permanece emL8.</p><button type="button" onClick={start}>Preparar qualificação L7</button></section>;
|
||||
const change=(patch:Partial<SpecialInput>)=>save({...b,special:{...i,...patch}});
|
||||
const yesno=(label:string,value:string,onChange:(v:''|'yes'|'no')=>void)=><label className="block">{label}<select aria-label={label} value={value} onChange={e=>onChange(e.target.value as ''|'yes'|'no')}><option value="">Informação em falta</option><option value="yes">Sim — documentado</option><option value="no">Não — documentado</option></select></label>;
|
||||
return<section aria-label="L7 — qualificação e tratamentos" className="space-y-3 rounded border p-3"><h5>L7 — qualificação comum e tratamentos documentados</h5><p>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.</p>
|
||||
<fieldset className="space-y-2 rounded border p-3"><legend>Despesas — tributação autónoma61(4)</legend><p>{specialSources.expenses}</p><QualificationFields label="Despesas autónomas" value={i.expenses.qualification} onChange={qualification=>change({expenses:{...i.expenses,qualification}})}/>
|
||||
<button type="button" onClick={()=>change({expenses:{...i.expenses,rows:[...i.expenses.rows,...(b.schedules?.rows??[]).filter(r=>r.rule==='undocumented'&&!i.expenses.rows.some(x=>x.scheduleId===r.id)).map(r=>({...newSpecialExpense('expense-'+r.id),scheduleId:r.id}))]}})}>Reutilizar despesas36g de L6 para qualificar</button>
|
||||
{i.expenses.rows.map((r,index)=>{const origin=b.schedules?.rows.find(x=>x.id===r.scheduleId),patch=(p:Partial<typeof r>)=>change({expenses:{...i.expenses,rows:i.expenses.rows.map(x=>x.id===r.id?{...x,...p}:x)}});return<fieldset key={r.id} className="rounded border p-2"><legend>{origin?origin.document+'/'+origin.line:'Parcela por corresponder'} — {origin?.amount??'Indeterminado'} MZN</legend><p>O acréscimo36g já pertence aL6;esta linha só apura o eventual imposto autónomo.</p><label className="block">Natureza legal da despesa<select aria-label={'Natureza da despesa '+(index+1)} value={r.nature} onChange={e=>patch({nature:e.target.value as typeof r.nature})}><option value="">Informação em falta</option><option value="undocumented">Encargo não devidamente documentado</option><option value="confidential">Despesa confidencial</option><option value="illicit">Despesa ilícita</option><option value="other">Outra natureza — correspondência própria</option></select></label>{yesno('Incidência61(4) — parcela '+(index+1),r.eligible,eligible=>patch({eligible}))}<label className="block">Suporte da classificação e incidência<input aria-label={'Suporte da despesa '+(index+1)} value={r.reference} onChange={e=>patch({reference:e.target.value})}/></label><button type="button" onClick={()=>change({expenses:{...i.expenses,rows:i.expenses.rows.filter(x=>x.id!==r.id)}})}>Retirar qualificação da parcela {index+1}</button></fieldset>;})}</fieldset>
|
||||
<fieldset className="space-y-2 rounded border p-3"><legend>Cooperativas abrangidas — artigo12</legend><p>{specialSources.cooperative} Este incremento exige base integralmente elegível;parcelas mistas continuam explícitas.</p><QualificationFields label="Cooperativa" value={i.cooperative.qualification} onChange={qualification=>change({cooperative:{...i.cooperative,qualification}})}/>{(i.cooperative.qualification.state==='known'||i.cooperative.kind!==''||i.cooperative.allIncomeEligible!==''||i.cooperative.withheldIncome!=='')&&<><label className="block">Tipo de cooperativa documentado<select value={i.cooperative.kind} onChange={e=>change({cooperative:{...i.cooperative,kind:e.target.value as typeof i.cooperative.kind}})}><option value="">Por identificar</option><option value="agrarian">Agrária</option><option value="craft">Artesanato</option><option value="cultural">Cultural</option><option value="other">Outra — não correspondida</option></select></label>{yesno('Base ordinária integralmente elegível',i.cooperative.allIncomeEligible,allIncomeEligible=>change({cooperative:{...i.cooperative,allIncomeEligible}}))}<label className="block">Rendimentos sujeitos a retenção<select value={i.cooperative.withheldIncome} onChange={e=>change({cooperative:{...i.cooperative,withheldIncome:e.target.value as typeof i.cooperative.withheldIncome}})}><option value="">Informação em falta</option><option value="absent">Ausência documentada</option><option value="known">Existem — segregação própria em falta</option></select></label></>}</fieldset>
|
||||
<fieldset className="space-y-2 rounded border p-3"><legend>Amortizações aceleradas — CBF16</legend><p>{specialSources.acceleration} Apenas activos já suportados,primeiro ano civil2026 e método constante;outras combinações permanecem por corresponder.</p><QualificationFields label="Amortização acelerada" value={i.acceleration.qualification} onChange={qualification=>change({acceleration:{...i.acceleration,qualification}})}/>{i.acceleration.qualification.state==='known'&&<>{yesno('EnquadramentoCBF3 e pressupostos9 documentados',i.acceleration.cbfRequirements,cbfRequirements=>change({acceleration:{...i.acceleration,cbfRequirements}}))}<label className="block">ReconhecimentoCBF10<select value={i.acceleration.recognition} onChange={e=>change({acceleration:{...i.acceleration,recognition:e.target.value as typeof i.acceleration.recognition}})}><option value="">Informação em falta</option><option value="documented">Instrumento/reconhecimento documentado</option><option value="not_required">Excepção prevista — identificar norma e suporte</option></select></label><label className="block">Instrumento ou norma da excepção<input value={i.acceleration.recognitionReference} onChange={e=>change({acceleration:{...i.acceleration,recognitionReference:e.target.value}})}/></label>{yesno('Ausência documentada de outros benefícios a cumular',i.acceleration.noOtherBenefits,noOtherBenefits=>change({acceleration:{...i.acceleration,noOtherBenefits}}))}</>}
|
||||
<button type="button" onClick={()=>change({acceleration:{...i.acceleration,rows:[...i.acceleration.rows,newAcceleratedAsset(crypto.randomUUID())]}})}>Qualificar activo existente paraCBF16</button>{i.acceleration.rows.map((r,index)=>{const patch=(p:Partial<typeof r>)=>change({acceleration:{...i.acceleration,rows:i.acceleration.rows.map(x=>x.id===r.id?{...x,...p}:x)}});return<fieldset key={r.id} className="rounded border p-2"><legend>Activo qualificado {index+1}</legend><label className="block">Activo do mapaL6<select value={r.assetId} onChange={e=>patch({assetId:e.target.value})}><option value="">Seleccione activo existente</option>{b.depreciation?.assets.map(a=><option key={a.id} value={a.id}>{a.description} — {a.assetKey}</option>)}</select></label><label className="block">Afectação documentada<select value={r.kind} onChange={e=>patch({kind:e.target.value as typeof r.kind})}><option value="">Por identificar</option><option value="new_project_building">Imóvel novo utilizado no projecto</option><option value="rehabilitated_project_building">Imóvel reabilitado — regra ainda por corresponder</option><option value="industrial_equipment">Máquina/equipamento industrial</option><option value="agroindustrial_equipment">Máquina/equipamento agro-industrial</option><option value="other">Outro — correspondência própria</option></select></label>{yesno('Condições do activoCBF16 — '+(index+1),r.eligible,eligible=>patch({eligible}))}<label className="block">Prova da afectação e condições do activo<input value={r.reference} onChange={e=>patch({reference:e.target.value})}/></label><button type="button" onClick={()=>change({acceleration:{...i.acceleration,rows:i.acceleration.rows.filter(x=>x.id!==r.id)}})}>Retirar tratamento do activo {index+1}</button></fieldset>;})}</fieldset>
|
||||
<p>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.</p></section>;
|
||||
}
|
||||
@@ -58,10 +58,28 @@ const menuTranslations = [
|
||||
'solicitudes recibidas',
|
||||
],
|
||||
[
|
||||
'Porquê investir em Moçambique',
|
||||
'Why invest in Mozambique',
|
||||
'Pourquoi investir au Mozambique',
|
||||
'Por qué invertir en Mozambique',
|
||||
'Porquê investir em Moçambique?',
|
||||
'Why invest in Mozambique?',
|
||||
'Pourquoi investir au Mozambique ?',
|
||||
'Por qué invertir en Mozambique?',
|
||||
],
|
||||
[
|
||||
'Partir de uma ideia',
|
||||
'Start with an idea',
|
||||
'Partir d’une idée',
|
||||
'Partir de una idea',
|
||||
],
|
||||
[
|
||||
'Consultar oportunidades',
|
||||
'Browse opportunities',
|
||||
'Consulter les opportunités',
|
||||
'Consultar oportunidades',
|
||||
],
|
||||
[
|
||||
'Simulador Fiscal',
|
||||
'Tax simulator',
|
||||
'Simulateur fiscal',
|
||||
'Simulador fiscal',
|
||||
],
|
||||
[
|
||||
'Oportunidades de investimento',
|
||||
|
||||
@@ -30,7 +30,7 @@ const names: Record<string, string> = {
|
||||
'/contacto': 'Contacto',
|
||||
'/politica-de-privacidade': 'Política de Privacidade',
|
||||
'/termos-de-uso': 'Termos de Uso',
|
||||
'/porque-investir': 'Porquê investir em Moçambique',
|
||||
'/porque-investir': 'Porquê investir em Moçambique?',
|
||||
'/investimentos/iniciar': 'Iniciar ou continuar investimento',
|
||||
'/explorar/agronegocio': 'Explorar agronegócio',
|
||||
'/agronegocio': 'Artigo de agronegócio',
|
||||
|
||||
@@ -30,7 +30,7 @@ const ratio=(a:FiscalFraction,b:FiscalFraction)=>fraction(BigInt(a.numerator)*Bi
|
||||
const date=(v:string)=>/^20\d{2}-\d{2}-\d{2}$/.test(v)&&Number.isFinite(Date.parse(v))&&new Date(v).toISOString().slice(0,10)===v;
|
||||
const month=(v:string)=>Number(v.slice(0,4))*12+Number(v.slice(5,7))-1;
|
||||
const show=(v:FiscalFraction|null)=>{if(!v)return'Indeterminado';const p=fractionPresentation(v);return(p.approximate?'≈':'')+p.decimal+' MZN'+(p.approximate?' (exacto '+v.numerator+'/'+v.denominator+')':'');};
|
||||
export function calculateNormalDepreciation(input:NormalDepreciationInput,source:{currency:string;accountingLines:Array<{code:string;total:string}>}|null,period:{from:string;to:string},claims:Array<{sourceCode:string;document:string;line:string;amount:string}>,short=false){
|
||||
export function calculateNormalDepreciation(input:NormalDepreciationInput,source:{currency:string;accountingLines:Array<{code:string;total:string}>}|null,period:{from:string;to:string},claims:Array<{sourceCode:string;document:string;line:string;amount:string}>,short=false,acceleratedIds:ReadonlySet<string>=new Set()){
|
||||
validateNormalDepreciation(input);const pending:string[]=[];
|
||||
if(!input.completenessReference.trim())pending.push('Reconciliação integral dos activos e quotas anteriores com a depreciação da origem em falta.');
|
||||
if(source?.currency!=='MZN'||!date(period.from)||!date(period.to)||!period.to.startsWith('2026-')||(!short&&month(period.to)-month(period.from)!==11||short&&(month(period.to)<month(period.from)||month(period.to)-month(period.from)>=11)))pending.push('Período anual emMZN com termo em2026 por reconciliar; períodos curtos permanecem separados.');
|
||||
@@ -60,7 +60,7 @@ export function calculateNormalDepreciation(input:NormalDepreciationInput,source
|
||||
if(a.method==='low_value'){if(cmp(cost,fraction(20000n))>0n||!yesno(a.individual,'Activo individual fora de conjunto depreciado como um todo')||cmp(priorFiscal,zero())!==0n||a.start<period.from||a.start>period.to)throw Error('Art17:valor unitário até20000MZN,activo individual e início no período,sem amortização fiscal anterior; condições em falta/incompatíveis.');quota=remaining;months=month(period.to)-month(a.start)+1;notes.push('Art17:opção de depreciação integral em um período,limitada ao que está contabilizado e ao saldo fiscal.');}
|
||||
else{
|
||||
if(!entry||!maxRate||!maxLifeMonths)throw Error('Taxa aplicável não identificada.');
|
||||
if(a.method==='constant'){if(!/^\d+(?:\.\d{1,6})?$/.test(a.rate))throw Error('Taxa constante escolhida por identificar.');const selected=decimalFraction(a.rate);if(cmp(selected,multiply(maxRate,fraction(1n,2n)))<0n||cmp(selected,maxRate)>0n)throw Error('Taxa constante fora do recorte entre metade da máxima e a máxima;quotas inferiores exigem correspondência própria dos limites de vida útil, artigos5/7.');quota=multiply(taxBasis,multiply(selected,fraction(1n,100n)));notes.push('Quota constante pela taxa escolhida:'+a.rate+'%;tabela'+entry.table+'/'+entry.code+'.');}
|
||||
if(a.method==='constant'){if(!/^\d+(?:\.\d{1,6})?$/.test(a.rate))throw Error('Taxa constante escolhida por identificar.');const selected=decimalFraction(a.rate);if(cmp(selected,multiply(maxRate,fraction(1n,2n)))<0n||cmp(selected,maxRate)>0n)throw Error('Taxa constante fora do recorte entre metade da máxima e a máxima;quotas inferiores exigem correspondência própria dos limites de vida útil, artigos5/7.');quota=multiply(taxBasis,multiply(selected,fraction(acceleratedIds.has(a.id)?3n:1n,acceleratedIds.has(a.id)?200n:100n)));if(acceleratedIds.has(a.id))notes.push('CBF16:L7 qualificado,incremento50% da taxa normal;mantidos contabilização e saldo fiscal.');notes.push('Quota constante pela taxa escolhida:'+a.rate+'%;tabela'+entry.table+'/'+entry.code+'.');}
|
||||
else if(a.method==='declining'){if(!yesno(a.newTangible,'Activo tangível novo adquirido a terceiros/construído')||['building','furniture','software'].includes(entry.kind)||entry.kind==='vehicle'&&a.vehicleException!=='yes')throw Error('Art6:quotas degressivas só nos activos tangíveis novos elegíveis;edifícios,mobiliário/equipamento social,intangíveis e veículos sem excepção ficam separados.');const life=ratio(fraction(100n),maxRate),maxFactor=cmp(life,fraction(5n))<0n?fraction(3n,2n):cmp(life,fraction(6n))<=0n?fraction(2n):fraction(5n,2n);if(!/^\d+(?:\.\d{1,6})?$/.test(a.factor))throw Error('Coeficiente degressivo escolhido em falta.');const factor=decimalFraction(a.factor);if(cmp(factor,zero())<=0n||cmp(factor,maxFactor)>0n)throw Error('Coeficiente degressivo excede o máximo do artigo8:1,5/2/2,5 conforme vida útil mínima.');quota=multiply(remaining,multiply(maxRate,multiply(factor,fraction(1n,100n))));notes.push('Art8:saldo fiscal por amortizar ×taxa máxima'+entry.rate+'% ×coeficiente'+a.factor+';máximo'+fractionPresentation(maxFactor).decimal+'.');
|
||||
if(yesno(a.switchToStraight,'Opção pela regra de saldo/vida útil restante8(2)')){if(!yesno(a.priorFullQuotas,'Condição das quotas anteriores8(2)')||!a.start.endsWith('-01-01')||period.from!=='2026-01-01'||a.timing!=='annual')throw Error('Art8(2):condição das quotas anteriores por documentar;este recorte da opção exige início emJaneiro e período anual civil.');const remainingYears=subtractFractions(life,fraction(BigInt(2026-Number(a.start.slice(0,4)))));if(cmp(remainingYears,zero())<=0n)throw Error('Art8(2):vida útil mínima esgotada;sem dividir por anos inexistentes.');const linear=ratio(remaining,remainingYears);if(cmp(quota,linear)<0n){quota=linear;notes.push('Art8(2):usado saldo/número de anos de vida útil mínima restantes,com condições anteriores documentadas.');}}
|
||||
}else throw Error('Método de amortização por identificar.');
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import {irpcSpecialVersion,validateSpecial,calculateSpecial,specialReportRows,specialDependency,type SpecialInput,type SpecialModel} from './irpc-special.ts';
|
||||
import {normalFormPreparationVersion,validateNormalFormPreparation,prepareNormalForms,normalFormPreparationReport,type NormalFormPreparationInput,type NormalFormPreparationModel} from './irpc-normal-form-preparation.ts';
|
||||
import {normalPeriodFxVersion,validateNormalPeriodFx,mapNormalPeriodFx,normalPeriodFxDependency,normalPeriodFxReport,type NormalPeriodFxInput,type NormalPeriodFxModel} from './irpc-normal-period-fx.ts';
|
||||
import {normalDepreciationVersion,validateNormalDepreciation,calculateNormalDepreciation,normalDepreciationReport,type NormalDepreciationInput,type NormalDepreciationModel} from './irpc-normal-depreciation.ts';
|
||||
@@ -15,8 +16,8 @@ import {addFractions,decimalFraction,fraction,fractionPresentation,type FiscalFr
|
||||
export const irpcNormalVersion='IRPC-normal-adjustments/1';
|
||||
export const irpcNormalSource='CIRPC Lei34/2007 art17(1),PDF6/p768(60):resultado e correcções;art36(1)c,PDF10/p768(64):multas e encargos por infracções sem origem contratual,incluindo juros compensatórios. Lei4/2012 PDF2 altera17(6)/acrescenta36(1)o;Lei19/2013 PDF2 mantém36(1)a–o e acrescenta p/q. Lei12/2025 altera3/5/20/62/67/75,adita61-A e revoga39/47/75(2)/76;sem alteração deste recorte36(1)c. Não é apuramento integral nem Modelo20/22.';
|
||||
export type NormalAdjustment={id:string;sourceCode:string;document:string;line:string;amount:string;rule:''|'noncontractual_fine'|'compensatory_interest'|'other';included:''|'yes'|'no';reference:string};
|
||||
export type NormalBook={version:1;year:string;mappingReference:string;scope:''|'resident_general'|'ep_general'|'other';scopeReference:string;rows:NormalAdjustment[];profit?:NormalProfitInput;base?:NormalBaseInput;assessment?:NormalAssessmentInput;schedules?:NormalSchedules;costs?:NormalCostsInput;depreciation?:NormalDepreciationInput;forms?:NormalFormPreparationInput;periodsFx?:NormalPeriodFxInput;result?:NormalRecord;history?:NormalRecord[]};
|
||||
type NormalModel={formPreparation?:NormalFormPreparationModel;periodsFx?:NormalPeriodFxModel;depreciation?:NormalDepreciationModel;costs?:NormalCostsModel;fiscalPeriod?:{kind:string;from:string;to:string;reference:string;pending:string[]};schedules?:SchedulesModel;currentLoss?:FiscalFraction|null;assessment?:NormalAssessmentModel;colecta?:FiscalFraction|null;base?:NormalBaseModel;profit?:NormalProfitModel;version:string;year:string;currency:string;origin:'projected';accountingProfit:FiscalFraction|null;additions:FiscalFraction;partialAdjustedResult:FiscalFraction|null;taxableProfit:FiscalFraction|null;taxableBase:FiscalFraction|null;tax:null;rows:Array<NormalAdjustment&{status:'calculated'|'indeterminate'|'outside_scope';adjustment:FiscalFraction|null;reason:string}>;pending:string[];source:string};
|
||||
export type NormalBook={version:1;year:string;mappingReference:string;scope:''|'resident_general'|'ep_general'|'other';scopeReference:string;rows:NormalAdjustment[];special?:SpecialInput;profit?:NormalProfitInput;base?:NormalBaseInput;assessment?:NormalAssessmentInput;schedules?:NormalSchedules;costs?:NormalCostsInput;depreciation?:NormalDepreciationInput;forms?:NormalFormPreparationInput;periodsFx?:NormalPeriodFxInput;result?:NormalRecord;history?:NormalRecord[]};
|
||||
export type NormalModel={special?:SpecialModel;formPreparation?:NormalFormPreparationModel;periodsFx?:NormalPeriodFxModel;depreciation?:NormalDepreciationModel;costs?:NormalCostsModel;fiscalPeriod?:{kind:string;from:string;to:string;reference:string;pending:string[]};schedules?:SchedulesModel;currentLoss?:FiscalFraction|null;assessment?:NormalAssessmentModel;colecta?:FiscalFraction|null;base?:NormalBaseModel;profit?:NormalProfitModel;version:string;year:string;currency:string;origin:'projected';accountingProfit:FiscalFraction|null;additions:FiscalFraction;partialAdjustedResult:FiscalFraction|null;taxableProfit:FiscalFraction|null;taxableBase:FiscalFraction|null;tax:null;rows:Array<NormalAdjustment&{status:'calculated'|'indeterminate'|'outside_scope';adjustment:FiscalFraction|null;reason:string}>;pending:string[];source:string};
|
||||
type NormalRecord={key:string;createdAt:string;model:NormalModel};
|
||||
export const newNormalBook=():NormalBook=>({version:1,year:'',mappingReference:'',scope:'',scopeReference:'',rows:[]});
|
||||
export const newNormalAdjustment=(id:string):NormalAdjustment=>({id,sourceCode:'',document:'',line:'',amount:'',rule:'',included:'',reference:''});
|
||||
@@ -28,6 +29,7 @@ export function rawNormalFinancialSource(d:Record<string,unknown>){
|
||||
export function normalFinancialSource(d:Record<string,unknown>){const raw=rawNormalFinancialSource(d),input=normalBook(d).periodsFx;return input?mapNormalPeriodFx(d,input,raw).source:raw;}
|
||||
function store(d:Record<string,unknown>){const s=JSON.parse(String(d.modelo_a_snapshot||'{"version":1,"books":{}}'));if(s.version!==1||!s.books||typeof s.books!=='object'||Array.isArray(s.books))throw Error('Livros fiscais não recuperáveis;originais preservados.');return s;}
|
||||
export function validateNormal(b:NormalBook){
|
||||
if(b?.special!==undefined)validateSpecial(b.special);
|
||||
if(b?.forms!==undefined)validateNormalFormPreparation(b.forms);
|
||||
if(b?.periodsFx!==undefined)validateNormalPeriodFx(b.periodsFx);
|
||||
if(b?.depreciation!==undefined)validateNormalDepreciation(b.depreciation);
|
||||
@@ -39,13 +41,13 @@ export function validateNormal(b:NormalBook){
|
||||
if(!b||b.version!==1||['year','mappingReference','scopeReference'].some(k=>typeof b[k as 'year']!=='string')||!['','resident_general','ep_general','other'].includes(b.scope)||!Array.isArray(b.rows)||b.history!==undefined&&!Array.isArray(b.history))throw Error('Preparação IRPC normal não recuperável.');
|
||||
for(const r of b.rows)if(!r||Object.keys(newNormalAdjustment('')).some(k=>typeof r[k as keyof NormalAdjustment]!=='string')||!['','noncontractual_fine','compensatory_interest','other'].includes(r.rule)||!['','yes','no'].includes(r.included))throw Error('Ajustamento IRPC não recuperável;original conservado.');
|
||||
if(new Set(b.rows.map(r=>r.id)).size!==b.rows.length)throw Error('Identificador de ajustamento duplicado.');
|
||||
for(const r of [b.result,...(b.history??[])])if(r&&(!r.model||![irpcNormalVersion,normalProfitVersion,normalBaseVersion,normalAssessmentVersion,normalSchedulesVersion,normalCostsVersion,normalDepreciationVersion,normalPeriodFxVersion,normalFormPreparationVersion].includes(r.model.version)||typeof r.key!=='string'||typeof r.createdAt!=='string'||!Array.isArray(r.model.rows)||!Array.isArray(r.model.pending)))throw Error('Histórico IRPC normal não recuperável.');
|
||||
for(const r of [b.result,...(b.history??[])])if(r&&(!r.model||![irpcSpecialVersion,irpcNormalVersion,normalProfitVersion,normalBaseVersion,normalAssessmentVersion,normalSchedulesVersion,normalCostsVersion,normalDepreciationVersion,normalPeriodFxVersion,normalFormPreparationVersion].includes(r.model.version)||typeof r.key!=='string'||typeof r.createdAt!=='string'||!Array.isArray(r.model.rows)||!Array.isArray(r.model.pending)))throw Error('Histórico IRPC normal não recuperável.');
|
||||
}
|
||||
export function normalBook(d:Record<string,unknown>):NormalBook{
|
||||
const m=store(d).irpcNormal;if(m===undefined)return newNormalBook();if(!m||typeof m!=='object'||Array.isArray(m))throw Error('Mapa IRPC normal não recuperável.');const b=m[acquisitionScope(d)]??newNormalBook();validateNormal(b);return b;
|
||||
}
|
||||
export function saveNormalBook(d:Record<string,unknown>,b:NormalBook){validateNormal(b);const s=store(d);if(s.irpcNormal!==undefined&&(!s.irpcNormal||typeof s.irpcNormal!=='object'||Array.isArray(s.irpcNormal)))throw Error('Mapa IRPC normal não recuperável.');return JSON.stringify({...s,irpcNormal:{...s.irpcNormal,[acquisitionScope(d)]:b}});}
|
||||
function key(d:Record<string,unknown>,b:NormalBook){return JSON.stringify([b.forms?normalFormPreparationVersion:b.periodsFx?normalPeriodFxVersion:b.depreciation?normalDepreciationVersion:b.costs?normalCostsVersion:b.schedules?normalSchedulesVersion:b.assessment?normalAssessmentVersion:b.base?normalBaseVersion:b.profit?normalProfitVersion:irpcNormalVersion,acquisitionScope(d),d.business_plan_snapshot??'',b.year,b.mappingReference,b.scope,b.scopeReference,b.rows,...(b.profit?[b.profit]:[]),...(b.base?[b.base]:[]),...(b.assessment?[b.assessment]:[]),...(b.schedules?[b.schedules]:[]),...(b.costs?[b.costs]:[]),...(b.depreciation?[b.depreciation]:[]),...(b.periodsFx?[b.periodsFx,normalPeriodFxDependency(d,b.periodsFx)]:[]),...(b.forms?[b.forms]:[])]);}
|
||||
function key(d:Record<string,unknown>,b:NormalBook){return JSON.stringify([b.special?irpcSpecialVersion:b.forms?normalFormPreparationVersion:b.periodsFx?normalPeriodFxVersion:b.depreciation?normalDepreciationVersion:b.costs?normalCostsVersion:b.schedules?normalSchedulesVersion:b.assessment?normalAssessmentVersion:b.base?normalBaseVersion:b.profit?normalProfitVersion:irpcNormalVersion,acquisitionScope(d),d.business_plan_snapshot??'',b.year,b.mappingReference,b.scope,b.scopeReference,b.rows,...(b.profit?[b.profit]:[]),...(b.base?[b.base]:[]),...(b.assessment?[b.assessment]:[]),...(b.schedules?[b.schedules]:[]),...(b.costs?[b.costs]:[]),...(b.depreciation?[b.depreciation]:[]),...(b.periodsFx?[b.periodsFx,normalPeriodFxDependency(d,b.periodsFx)]:[]),...(b.forms?[b.forms]:[]),...(b.special?[b.special,specialDependency(d)]:[])]);}
|
||||
export function normalCurrent(d:Record<string,unknown>,b:NormalBook){return !!b.result&&b.result.key===key(d,b);}
|
||||
const zero=()=>fraction(0n,1n);
|
||||
const cents=(s:string)=>{if(!/^-?\d+(?:\.\d{1,2})?$/.test(s))throw Error('Montante MZN inválido;máximo dois decimais.');const v=decimalFraction(s.startsWith('-')?s.slice(1):s);return s.startsWith('-')?fraction(-BigInt(v.numerator),BigInt(v.denominator)):v;};
|
||||
@@ -94,7 +96,8 @@ export function calculateNormal(d:Record<string,unknown>,b:NormalBook):NormalMod
|
||||
const assessment=b.assessment?calculateNormalAssessment(b.assessment,base?.taxableBase??null,{year:b.year,scope:b.scope,extended:!!b.schedules||!!periodsFx,short:!!periodsFx?.short,currency:source?.currency??'',...(fiscalPeriod?{period:{from:fiscalPeriod.from,to:fiscalPeriod.to}}:{})}):undefined;
|
||||
if(assessment)pending.push(...assessment.pending,assessment.finalBalance.reason);
|
||||
const currentLoss=b.schedules&&profit?.taxableProfit&&BigInt(profit.taxableProfit.numerator)<0n?fraction(-BigInt(profit.taxableProfit.numerator),BigInt(profit.taxableProfit.denominator)):null;
|
||||
const model:NormalModel={...(periodsFx?{periodsFx}:{}),...(depreciation?{depreciation}:{}),...(costs?{costs}:{}),...(schedules?{schedules,currentLoss,fiscalPeriod}:{}),...(assessment?{assessment,colecta:assessment.colecta}:{}),...(base?{base}:{}),...(profit?{profit}:{}),version:b.forms?normalFormPreparationVersion:b.periodsFx?normalPeriodFxVersion:b.depreciation?normalDepreciationVersion:b.costs?normalCostsVersion:b.schedules?normalSchedulesVersion:b.assessment?normalAssessmentVersion:b.base?normalBaseVersion:b.profit?normalProfitVersion:irpcNormalVersion,year:b.year,currency:source?.currency??'',origin:'projected',accountingProfit,additions,partialAdjustedResult:contextReady&&rows.length>0&&rows.every(r=>r.status==='calculated')&&accountingProfit?addFractions([accountingProfit,additions]):null,taxableProfit:profit?.taxableProfit??null,taxableBase:base?.taxableBase??null,tax:null,rows,pending,source:irpcNormalSource+(periodsFx?' '+periodsFx.rule:b.schedules?' Mapas complementares: CIRPC18/21/22/24/36; Decreto72/2013 art3–7. EP: CIRPC15(1)c, apenas resultado imputável ao estabelecimento no regime geral, anual2026/MZN.':'')};
|
||||
const model:NormalModel={...(periodsFx?{periodsFx}:{}),...(depreciation?{depreciation}:{}),...(costs?{costs}:{}),...(schedules?{schedules,currentLoss,fiscalPeriod}:{}),...(assessment?{assessment,colecta:assessment.colecta}:{}),...(base?{base}:{}),...(profit?{profit}:{}),version:b.special?irpcSpecialVersion:b.forms?normalFormPreparationVersion:b.periodsFx?normalPeriodFxVersion:b.depreciation?normalDepreciationVersion:b.costs?normalCostsVersion:b.schedules?normalSchedulesVersion:b.assessment?normalAssessmentVersion:b.base?normalBaseVersion:b.profit?normalProfitVersion:irpcNormalVersion,year:b.year,currency:source?.currency??'',origin:'projected',accountingProfit,additions,partialAdjustedResult:contextReady&&rows.length>0&&rows.every(r=>r.status==='calculated')&&accountingProfit?addFractions([accountingProfit,additions]):null,taxableProfit:profit?.taxableProfit??null,taxableBase:base?.taxableBase??null,tax:null,rows,pending,source:irpcNormalSource+(periodsFx?' '+periodsFx.rule:b.schedules?' Mapas complementares: CIRPC18/21/22/24/36; Decreto72/2013 art3–7. EP: CIRPC15(1)c, apenas resultado imputável ao estabelecimento no regime geral, anual2026/MZN.':'')};
|
||||
if(b.special)model.special=calculateSpecial(d,b,model,source);
|
||||
if(b.forms){model.formPreparation=prepareNormalForms(b.forms,model,source);model.pending.push(...model.formPreparation.pending.map(p=>'Preparação M20/M22: '+p));}
|
||||
return model;
|
||||
}
|
||||
@@ -102,5 +105,5 @@ export function recordNormal(d:Record<string,unknown>,b:NormalBook,now=new Date(
|
||||
const money=(v:FiscalFraction|null)=>v?fractionPresentation(v).decimal+' MZN':'Indeterminado';
|
||||
function normalBaseReport(m:NormalBaseModel):Array<[string,string,string,string]>{return[['IRPC normal — L6','Matéria colectável — deduções/perdas',`Lucro tributável:${money(m.taxableProfit)};perdas propostas elegíveis:${money(m.requestedLosses)};perdas deduzidas nesta simulação:${money(m.deductedLosses)};benefícios deduzidos:${money(m.benefitDeduction)};matéria colectável simulada:${money(m.taxableBase)};imposto a pagar:Indeterminado. ${m.pending.join(' | ')}`,`NUIT:${m.input.subjectNuit};${m.input.identityReference};método:${m.input.method==='direct'?'Declarativo/directo':m.input.method==='indirect'?'Indirecto':'Por identificar'};${m.input.methodReference};perdas:${m.input.lossesState==='absent'?'Ausência declarada':m.input.lossesState==='known'?'Conhecidas':'Informação em falta'};${m.input.lossesReference};objecto:${m.input.unchangedObject==='yes'?'Sem alteração declarada':m.input.unchangedObject==='no'?'Alteração declarada':'Por esclarecer'};${m.input.objectReference};${m.source}`],['IRPC normal — L6','Benefícios à matéria colectável',`Estado:${m.input.benefits.state==='known'?'Valor conhecido':m.input.benefits.state==='absent'?'Ausência declarada':'Informação em falta'};montante original:${m.input.benefits.amount||'Não preenchido'};dedução:${money(m.benefitDeduction)};não inclui créditos à colecta ou retenções sofridas.`,m.input.benefits.reference],...m.losses.map(l=>['IRPC normal — L6','Perda fiscal de '+l.year,`Estado:${l.status==='eligible'?'Elegível neste recorte':l.status==='excluded'?'Excluída neste exercício':'Indeterminada'};apurada:${l.assessed};utilizada antes:${l.previouslyUsed};saldo:${money(l.available)};utilização proposta:${l.requested};dedução nesta simulação:${money(l.deducted)};saldo aritmético posterior:${money(l.remaining)};último exercício ordinário:${l.lastOrdinaryYear??'Por determinar'};${l.reason}`,`NUIT:${l.subjectNuit};${l.reference};sem consumo do saldo oficial nem reporte automático.`]as[string,string,string,string])];}
|
||||
function normalAssessmentReport(m:NormalAssessmentModel):Array<[string,string,string,string]>{return[['IRPC normal — L6','Colecta — regime normal',`Matéria colectável:${money(m.taxableBase)};taxa:${m.rate?m.rate.numerator+'%':'Por identificar'};colecta simulada:${money(m.colecta)};${m.classification};${m.centExact===false?'Valor racional exacto com fracção de cêntimo;sem arredondamento fiscal aplicado.':''}${m.pending.join(' | ')}`,`Exercício:${m.period.year};período:${m.period.from}–${m.period.to};${m.input.reference};${m.rule};${m.source}`],['IRPC normal — L6','Saldo final — âmbito L8','A pagar:Indeterminado;a recuperar:Indeterminado. '+m.finalBalance.reason,'Sequência:lucro tributável → matéria colectável → colecta → saldo final;retenções,pagamentos e créditos anuais reservados aL8.']];}
|
||||
export function normalReportRows(d:Record<string,unknown>):Array<[string,string,string,string]>{try{const b=normalBook(d),r=b.result;if(!r)return[];const m=r.model;return[['IRPC normal — L6','Ajustamentos ao resultado financeiro',`Exercício:${m.year};resultado contabilístico antes de imposto:${money(m.accountingProfit)};acréscimos demonstrados:${money(m.additions)};resultado parcial ajustado:${money(m.partialAdjustedResult)};${m.profit?'lucro tributável simulado:'+money(m.taxableProfit)+(m.base?';matéria colectável simulada:'+money(m.taxableBase)+(m.assessment?';colecta simulada:'+money(m.colecta??null)+';saldo final a pagar ou recuperar:Indeterminado (L8).':';imposto a pagar:Indeterminado.'):';matéria colectável/imposto:Indeterminados.'):'lucro tributável/matéria colectável/imposto:Indeterminados.'} Projecção com pressupostos;${m.pending.join(' | ')}`,`${normalCurrent(d,b)?'Entradas correspondentes':'Histórico;origem ou entradas alteradas'};${r.createdAt};${m.source}`],...(m.formPreparation?normalFormPreparationReport(m.formPreparation):[]),...(m.periodsFx?normalPeriodFxReport(m.periodsFx):[]),...(m.depreciation?normalDepreciationReport(m.depreciation):[]),...(m.costs?normalCostReport(m.costs):[]),...(m.base?normalBaseReport(m.base):[]),...(m.assessment?normalAssessmentReport(m.assessment):[]),...(m.schedules?[['IRPC normal — L6','Mapas complementares',`Efeito líquido adicional:${money(m.schedules.net)};perda fiscal do próprio exercício:${money(m.currentLoss??null)};sem reporte ou consumo automático. ${m.schedules.pending.join(' | ')}`,m.schedules.source]as[string,string,string,string],...m.schedules.effects.map(e=>{const i=m.schedules!.input.rows.find(r=>r.id===e.id)!;return['IRPC normal — L6',i.document+'/'+i.line,`Montante:${money(e.amount)};efeito:${money(e.effect)};${e.reason}`,`${i.reference};exercício de imputação:${i.fiscalYear||'Não aplicável'}`]as[string,string,string,string];}),...m.schedules.assets.map(a=>['IRPC normal — L6',a.description,`Depreciação contabilística:${money(a.accountingValue)};quota fiscal:${money(a.fiscal)};acréscimo:${money(a.adjustment)};${a.reason}`,`${a.tableReference};${a.reference}`]as[string,string,string,string]),['IRPC normal — L6','Juros financeiros ordinários',`Remanescente aceite no recorte:${money(m.schedules.interest)};não corresponde a juros de mora/compensatórios L5.`,m.schedules.input.interest.reference]as[string,string,string,string]]:[]),...(m.schedules&&!m.formPreparation?[...normalFormFields(m).fields.map(f=>['IRPC normal — L6','M22 campo '+f.code+' — '+f.label,`${f.display};exacto:${f.value?f.value.numerator+'/'+f.value.denominator:'Indeterminado'};transcrição:${f.transcriptionReady?'Preparação parcial com valor exacto ao cêntimo':'Pendente ou sem aplicação'};${f.reason}`,normalFormFields(m).source]as[string,string,string,string]),...normalFormFields(m).m20.fields.map(f=>['IRPC normal — L6','M20 A.1 — conta '+f.account+' — '+f.label,`${f.display};representação em meticais inteiros:${f.transcriptionReady?'Exacta':'Pendente'};${f.reason}`,`${f.reference};${normalFormFields(m).m20.source}`]as[string,string,string,string]),['IRPC normal — L6','M20 — correspondência',normalFormFields(m).m20.reason,normalFormFields(m).m20.source]as[string,string,string,string]]:[]),...m.rows.map(r=>['IRPC normal — L6',r.document+'/'+r.line,`${({calculated:'Calculado neste recorte',indeterminate:'Indeterminado',outside_scope:'Fora deste recorte'})[r.status]};montante:${r.amount};acréscimo:${money(r.adjustment)};${r.reason}`,`Origem:${({revenue:'Receitas',cost_of_sales:'Custo das vendas',operating_expenses:'Despesas operacionais',personnel:'Pessoal',depreciation:'Depreciação contabilística',interest_expense:'Juros reconhecidos'}as Record<string,string>)[r.sourceCode]??'Por corresponder'};incluído:${r.included==='yes'?'Sim':r.included==='no'?'Não':'Por demonstrar'};suporte:${r.reference}`]as[string,string,string,string]),...(m.profit?[...m.profit.lines.map(l=>['IRPC normal — L6','Conferência: '+l.label,`Estado:${l.state==='known'?'Valor conhecido':l.state==='absent'?'Ausência declarada':'Informação em falta'};origem:${l.amount};acréscimos:${money(l.addedBack)};remanescente:${money(l.remainder)};${l.reason}`,l.reference]as[string,string,string,string]),...m.profit.topics.map(t=>['IRPC normal — L6',t.label,`Estado:${t.state==='known'?'Valor conhecido':t.state==='absent'?'Ausência declarada':'Informação em falta'};montante:${money(t.value)};${t.reason}`,t.reference]as[string,string,string,string]),['IRPC normal — L6','Âmbito da conferência',m.profit.input.completenessReference,m.profit.source]as[string,string,string,string]]:[])];}catch(e){return[['IRPC normal — L6','Não recuperável',String(e),'Originais conservados.']];}}
|
||||
export function normalHtml(d:Record<string,unknown>){const b=normalBook(d);if(!normalCurrent(d,b))throw Error('Calcule e guarde as entradas actuais antes de exportar.');const esc=(s:string)=>s.replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]!));return'<!doctype html><html lang="pt"><meta charset="utf-8"><title>IRPC normal — ajustamentos</title><h1>L6 — mapa parcial de ajustamentos</h1><p>Projecção pelos pressupostos do plano. Não é demonstração contabilística,liquidação ou Modelo20/22.</p>'+normalReportRows(d).map(r=>'<section><h2>'+esc(r[1])+'</h2><p>'+esc(r[2])+'</p><small>'+esc(r[3])+'</small></section>').join('')+'</html>';}
|
||||
export function normalReportRows(d:Record<string,unknown>):Array<[string,string,string,string]>{try{const b=normalBook(d),r=b.result;if(!r)return[];const m=r.model;return[['IRPC normal — L6','Ajustamentos ao resultado financeiro',`Exercício:${m.year};resultado contabilístico antes de imposto:${money(m.accountingProfit)};acréscimos demonstrados:${money(m.additions)};resultado parcial ajustado:${money(m.partialAdjustedResult)};${m.profit?'lucro tributável simulado:'+money(m.taxableProfit)+(m.base?';matéria colectável simulada:'+money(m.taxableBase)+(m.assessment?';colecta simulada:'+money(m.colecta??null)+';saldo final a pagar ou recuperar:Indeterminado (L8).':';imposto a pagar:Indeterminado.'):';matéria colectável/imposto:Indeterminados.'):'lucro tributável/matéria colectável/imposto:Indeterminados.'} Projecção com pressupostos;${m.pending.join(' | ')}`,`${normalCurrent(d,b)?'Entradas correspondentes':'Histórico;origem ou entradas alteradas'};${r.createdAt};${m.source}`],...(m.special?specialReportRows(m.special):[]),...(m.formPreparation?normalFormPreparationReport(m.formPreparation):[]),...(m.periodsFx?normalPeriodFxReport(m.periodsFx):[]),...(m.depreciation?normalDepreciationReport(m.depreciation):[]),...(m.costs?normalCostReport(m.costs):[]),...(m.base?normalBaseReport(m.base):[]),...(m.assessment?normalAssessmentReport(m.assessment):[]),...(m.schedules?[['IRPC normal — L6','Mapas complementares',`Efeito líquido adicional:${money(m.schedules.net)};perda fiscal do próprio exercício:${money(m.currentLoss??null)};sem reporte ou consumo automático. ${m.schedules.pending.join(' | ')}`,m.schedules.source]as[string,string,string,string],...m.schedules.effects.map(e=>{const i=m.schedules!.input.rows.find(r=>r.id===e.id)!;return['IRPC normal — L6',i.document+'/'+i.line,`Montante:${money(e.amount)};efeito:${money(e.effect)};${e.reason}`,`${i.reference};exercício de imputação:${i.fiscalYear||'Não aplicável'}`]as[string,string,string,string];}),...m.schedules.assets.map(a=>['IRPC normal — L6',a.description,`Depreciação contabilística:${money(a.accountingValue)};quota fiscal:${money(a.fiscal)};acréscimo:${money(a.adjustment)};${a.reason}`,`${a.tableReference};${a.reference}`]as[string,string,string,string]),['IRPC normal — L6','Juros financeiros ordinários',`Remanescente aceite no recorte:${money(m.schedules.interest)};não corresponde a juros de mora/compensatórios L5.`,m.schedules.input.interest.reference]as[string,string,string,string]]:[]),...(m.schedules&&!m.formPreparation?[...normalFormFields(m).fields.map(f=>['IRPC normal — L6','M22 campo '+f.code+' — '+f.label,`${f.display};exacto:${f.value?f.value.numerator+'/'+f.value.denominator:'Indeterminado'};transcrição:${f.transcriptionReady?'Preparação parcial com valor exacto ao cêntimo':'Pendente ou sem aplicação'};${f.reason}`,normalFormFields(m).source]as[string,string,string,string]),...normalFormFields(m).m20.fields.map(f=>['IRPC normal — L6','M20 A.1 — conta '+f.account+' — '+f.label,`${f.display};representação em meticais inteiros:${f.transcriptionReady?'Exacta':'Pendente'};${f.reason}`,`${f.reference};${normalFormFields(m).m20.source}`]as[string,string,string,string]),['IRPC normal — L6','M20 — correspondência',normalFormFields(m).m20.reason,normalFormFields(m).m20.source]as[string,string,string,string]]:[]),...m.rows.map(r=>['IRPC normal — L6',r.document+'/'+r.line,`${({calculated:'Calculado neste recorte',indeterminate:'Indeterminado',outside_scope:'Fora deste recorte'})[r.status]};montante:${r.amount};acréscimo:${money(r.adjustment)};${r.reason}`,`Origem:${({revenue:'Receitas',cost_of_sales:'Custo das vendas',operating_expenses:'Despesas operacionais',personnel:'Pessoal',depreciation:'Depreciação contabilística',interest_expense:'Juros reconhecidos'}as Record<string,string>)[r.sourceCode]??'Por corresponder'};incluído:${r.included==='yes'?'Sim':r.included==='no'?'Não':'Por demonstrar'};suporte:${r.reference}`]as[string,string,string,string]),...(m.profit?[...m.profit.lines.map(l=>['IRPC normal — L6','Conferência: '+l.label,`Estado:${l.state==='known'?'Valor conhecido':l.state==='absent'?'Ausência declarada':'Informação em falta'};origem:${l.amount};acréscimos:${money(l.addedBack)};remanescente:${money(l.remainder)};${l.reason}`,l.reference]as[string,string,string,string]),...m.profit.topics.map(t=>['IRPC normal — L6',t.label,`Estado:${t.state==='known'?'Valor conhecido':t.state==='absent'?'Ausência declarada':'Informação em falta'};montante:${money(t.value)};${t.reason}`,t.reference]as[string,string,string,string]),['IRPC normal — L6','Âmbito da conferência',m.profit.input.completenessReference,m.profit.source]as[string,string,string,string]]:[])];}catch(e){return[['IRPC normal — L6','Não recuperável',String(e),'Originais conservados.']];}}
|
||||
export function normalHtml(d:Record<string,unknown>){const b=normalBook(d);if(!normalCurrent(d,b))throw Error('Calcule e guarde as entradas actuais antes de exportar.');const esc=(s:string)=>s.replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]!));return'<!doctype html><html lang="pt"><meta charset="utf-8"><title>IRPC normal — ajustamentos</title><h1>IRPC — L6 de referência e tratamentos L7 quando qualificados</h1><p>Projecção pelos pressupostos do plano. Não é demonstração contabilística,liquidação ou Modelo20/22.</p>'+normalReportRows(d).map(r=>'<section><h2>'+esc(r[1])+'</h2><p>'+esc(r[2])+'</p><small>'+esc(r[3])+'</small></section>').join('')+'</html>';}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
import type {NormalBook,NormalModel} from './irpc-normal.ts';
|
||||
import {calculateNormalBase} from './irpc-normal-base.ts';
|
||||
import {calculateNormalAssessment} from './irpc-normal-assessment.ts';
|
||||
import {calculateNormalDepreciation,type NormalDepreciationModel} from './irpc-normal-depreciation.ts';
|
||||
import {addFractions,subtractFractions,decimalFraction,fraction,fractionPresentation,type FiscalFraction} from './fiscal-rational.ts';
|
||||
|
||||
export const irpcSpecialVersion='IRPC-normal-adjustments/10';
|
||||
export const specialSources={expenses:'CIRPC,Lei34/2007,art61(4),PDF17/p768(71):35% sobre encargos não devidamente documentados e despesas confidenciais/ilícitas,sem prejuízo do36(1)g. Exercício2026;sem regra inferida da falta de anexo.',cooperative:'CIRPC,Lei34/2007,art12/14,PDF5/p768(59),e61(1):cooperativas agrárias,de artesanato e culturais;redução de50% da taxa geral32%=16%;rendimentos sujeitos a retenção excluídos deste benefício. Recorte2026,residente,parcela ordinária integralmente elegível.',acceleration:'CBF,Lei4/2009,art3/4/9/10/16;compilação oficial APIEX pp66–68/72:incremento50% das taxas normais nos imóveis novos do projecto e,nas mesmas condições,imóveis reabilitados/máquinas e equipamentos industriais ou agro-industriais. Decreto72/2013 art3(3):limite contabilizado e saldo fiscal. Recorte constante pela taxa normal máxima da tabela,primeiro exercício anual2026,sem cumulação presumida.'}as const;
|
||||
export type Qualification={state:''|'known'|'absent'|'not_applicable';eligible:''|'yes'|'no';from:string;to:string;reference:string;periodReference:string};
|
||||
export const newQualification=():Qualification=>({state:'',eligible:'',from:'',to:'',reference:'',periodReference:''});
|
||||
export type SpecialExpense={id:string;scheduleId:string;nature:''|'undocumented'|'confidential'|'illicit'|'other';eligible:''|'yes'|'no';reference:string};
|
||||
export type AcceleratedAsset={id:string;assetId:string;kind:''|'new_project_building'|'rehabilitated_project_building'|'industrial_equipment'|'agroindustrial_equipment'|'other';eligible:''|'yes'|'no';reference:string};
|
||||
export type SpecialInput={version:1;expenses:{qualification:Qualification;rows:SpecialExpense[]};cooperative:{qualification:Qualification;kind:''|'agrarian'|'craft'|'cultural'|'other';allIncomeEligible:''|'yes'|'no';withheldIncome:''|'absent'|'known'};acceleration:{qualification:Qualification;cbfRequirements:''|'yes'|'no';recognition:''|'documented'|'not_required';recognitionReference:string;noOtherBenefits:''|'yes'|'no';rows:AcceleratedAsset[]}};
|
||||
export const newSpecialInput=():SpecialInput=>({version:1,expenses:{qualification:newQualification(),rows:[]},cooperative:{qualification:newQualification(),kind:'',allIncomeEligible:'',withheldIncome:''},acceleration:{qualification:newQualification(),cbfRequirements:'',recognition:'',recognitionReference:'',noOtherBenefits:'',rows:[]}});
|
||||
export const newSpecialExpense=(id:string):SpecialExpense=>({id,scheduleId:'',nature:'',eligible:'',reference:''});
|
||||
export const newAcceleratedAsset=(id:string):AcceleratedAsset=>({id,assetId:'',kind:'',eligible:'',reference:''});
|
||||
const choices=(v:unknown,allowed:string[])=>typeof v==='string'&&allowed.includes(v);
|
||||
export function validateSpecial(i:SpecialInput){
|
||||
if(!i||i.version!==1||!i.expenses||!i.cooperative||!i.acceleration)throw Error('Qualificação L7 não recuperável;originais conservados.');
|
||||
for(const q of[i.expenses.qualification,i.cooperative.qualification,i.acceleration.qualification])if(!q||!choices(q.state,['','known','absent','not_applicable'])||!choices(q.eligible,['','yes','no'])||['from','to','reference','periodReference'].some(k=>typeof q[k as 'from']!=='string'))throw Error('Condição/período L7 não recuperável.');
|
||||
for(const [rows,keys]of [[i.expenses.rows,Object.keys(newSpecialExpense(''))],[i.acceleration.rows,Object.keys(newAcceleratedAsset(''))]]as const){if(!Array.isArray(rows)||new Set(rows.map(r=>r.id)).size!==rows.length||rows.some(r=>!r||keys.some(k=>typeof(r as unknown as Record<string,unknown>)[k]!=='string')||!choices(r.eligible,['','yes','no'])))throw Error('Parcela L7 não recuperável ou identificador repetido.');}
|
||||
if(i.expenses.rows.some(r=>!choices(r.nature,['','undocumented','confidential','illicit','other']))||i.acceleration.rows.some(r=>!choices(r.kind,['','new_project_building','rehabilitated_project_building','industrial_equipment','agroindustrial_equipment','other'])))throw Error('Natureza L7 desconhecida.');
|
||||
if(!choices(i.cooperative.kind,['','agrarian','craft','cultural','other'])||!choices(i.cooperative.allIncomeEligible,['','yes','no'])||!choices(i.cooperative.withheldIncome,['','absent','known'])||!choices(i.acceleration.cbfRequirements,['','yes','no'])||!choices(i.acceleration.noOtherBenefits,['','yes','no'])||!choices(i.acceleration.recognition,['','documented','not_required'])||typeof i.acceleration.recognitionReference!=='string')throw Error('Parâmetro L7 não recuperável.');
|
||||
}
|
||||
type Status='calculated'|'absent'|'not_applicable'|'indeterminate';
|
||||
type Decision={status:Status;reason:string;pending:string[]};
|
||||
const z=()=>fraction(0n),mul=(v:FiscalFraction,n:bigint,d=1n)=>fraction(BigInt(v.numerator)*n,BigInt(v.denominator)*d);
|
||||
const cmp=(a:FiscalFraction,b:FiscalFraction)=>BigInt(a.numerator)*BigInt(b.denominator)-BigInt(b.numerator)*BigInt(a.denominator);
|
||||
const iso=(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 specialContext(d:Record<string,unknown>){return Object.fromEntries(['context_opportunity','context_opportunity_snapshot','context_applicability_snapshot','context_reuse','sector_id','sector_id_label','province_id','province_id_label','district_id','district_id_label','admin_post_id','admin_post_id_label','locality_id','locality_id_label','selection_labels'].map(k=>[k,d[k]??null]));}
|
||||
export const specialDependency=(d:Record<string,unknown>)=>JSON.stringify(specialContext(d));
|
||||
const specialPeriod=(b:NormalBook,m:NormalModel)=>b.periodsFx?{from:b.periodsFx.from,to:b.periodsFx.to,pending:m.periodsFx?.pending??[]}:m.fiscalPeriod??{from:b.year+'-01-01',to:b.year+'-12-31',pending:[]};
|
||||
function qualify(q:Qualification,b:NormalBook,m:NormalModel):Decision{
|
||||
const pending:string[]=[],p=specialPeriod(b,m);
|
||||
if(!q.state)pending.push('Informação em falta:identifique o estado do tratamento.');
|
||||
if(!q.reference.trim())pending.push('Falta prova/declaração das condições ou da ausência/não aplicação.');
|
||||
if(!iso(q.from)||!iso(q.to)||q.from!==p.from||q.to!==p.to||!q.periodReference.trim())pending.push('Período do tratamento deve corresponder ao período fiscal documentado,com suporte próprio;sem transpor vigência.');
|
||||
if(b.year!=='2026'||m.currency!=='MZN'||!b.base?.subjectNuit.match(/^\d{9}$/)||!b.base.identityReference.trim()||!b.scopeReference.trim()||!['resident_general','ep_general'].includes(b.scope)||p.pending.length)pending.push('Sujeito/NUIT,âmbito ou período2026 emMZN por reconciliar na base existente.');
|
||||
if(q.state==='known'&&!q.eligible)pending.push('Condições documentadas por qualificar:sim,não ou informação em falta.');
|
||||
if(q.state!=='known'&&q.eligible)pending.push('Estado de ausência/não aplicação/informação em falta não admite condição de benefício preenchida.');
|
||||
if(pending.length)return{status:'indeterminate',pending,reason:pending.join(' ')};
|
||||
const status=q.state==='absent'?'absent':q.state==='not_applicable'||q.eligible==='no'?'not_applicable':'calculated';
|
||||
return{status,pending,reason:status==='absent'?'Ausência declarada com suporte;efeito zero neste período.':status==='not_applicable'?'Tratamento não aplicável/condição negativa documentada;percurso normal conservado.':'Condições e período documentados no recorte.'};
|
||||
}
|
||||
function fail(d:Decision,reason:string){d.status='indeterminate';d.pending.push(reason);d.reason=d.pending.join(' ');}
|
||||
export function calculateSpecial(draft:Record<string,unknown>,b:NormalBook,m:NormalModel,source:Parameters<typeof calculateNormalDepreciation>[1]){
|
||||
const i=b.special!;validateSpecial(i);const expenseDecision=qualify(i.expenses.qualification,b,m),coopDecision=qualify(i.cooperative.qualification,b,m),accDecision=qualify(i.acceleration.qualification,b,m);
|
||||
const existing=(b.schedules?.rows??[]).filter(r=>r.rule==='undocumented');
|
||||
if(expenseDecision.status==='absent'&&(existing.length||i.expenses.rows.length))fail(expenseDecision,'Ausência declarada contradiz despesas36g ou linhasL7 presentes;reconcilie sem apagar o ajustamento.');
|
||||
if(expenseDecision.status!=='calculated'&&i.expenses.rows.length&&expenseDecision.status!=='indeterminate')fail(expenseDecision,'Estado global e parcelas da despesa contraditórios;qualifique as parcelas ou conserve apenas a declaração.');
|
||||
const expenses=i.expenses.rows.map(r=>{
|
||||
const origin=existing.find(x=>x.id===r.scheduleId),effect=m.schedules?.effects.find(x=>x.id===r.scheduleId);let amount:FiscalFraction|null=effect?.amount??null,tax:FiscalFraction|null=null,status:Status='indeterminate';const reasons:string[]=[];
|
||||
if(expenseDecision.status!=='calculated')reasons.push(expenseDecision.reason);
|
||||
if(!origin||!effect?.effect||!effect.amount||cmp(effect.effect,effect.amount)!==0n)reasons.push('Seleccione ajustamento36g calculado emL6;imposto autónomo não acrescenta novamente a despesa.');
|
||||
if(i.expenses.rows.filter(x=>x.scheduleId===r.scheduleId).length!==1)reasons.push('Despesa L6 repetida no imposto autónomo;uma referência por parcela.');
|
||||
if(!r.reference.trim()||!r.eligible||!r.nature)reasons.push('Falta classificação legal documentada da despesa;ausência de anexo não prova61(4).');
|
||||
if(!reasons.length){status=r.eligible==='no'?'not_applicable':r.nature==='other'?'indeterminate':'calculated';if(status==='indeterminate')reasons.push('Outra natureza por corresponder;sem taxa provisória.');else tax=status==='calculated'?mul(amount!,35n,100n):z();}
|
||||
return{...structuredClone(r),document:origin?.document??'',line:origin?.line??'',sourceCode:origin?.sourceCode??'',amount,l6Adjustment:effect?.effect??null,additionalProfitAdjustment:z(),rate:status==='calculated'?fraction(35n):null,tax,status,reason:reasons.join(' ')||(status==='calculated'?'CIRPC61(4):despesa ×35%;ajustamento36g reutilizado,sem duplicação.':'Condição negativa documentada;sem imposto autónomo aplicado à parcela.')};
|
||||
});
|
||||
if(expenseDecision.status==='calculated'){
|
||||
if(!existing.length&&!expenses.length)fail(expenseDecision,'Não há parcelas conhecidas;declare ausência com suporte ou seleccione despesas36g.');
|
||||
if(existing.some(r=>!expenses.some(x=>x.scheduleId===r.id)))fail(expenseDecision,'Há despesa36g sem qualificação autónoma;corresponda cada parcela ou justifique a sua não aplicação.');
|
||||
for(const r of expenses)if(r.status==='indeterminate')fail(expenseDecision,(r.document||r.id)+': '+r.reason);
|
||||
}
|
||||
const knownAutonomous=addFractions(expenses.flatMap(r=>r.tax?[r.tax]:[])),autonomousTax=expenseDecision.status==='indeterminate'?null:expenseDecision.status==='calculated'?knownAutonomous:z();
|
||||
if(coopDecision.status==='absent'&&['agrarian','craft','cultural'].includes(i.cooperative.kind)&&i.cooperative.allIncomeEligible==='yes'&&i.cooperative.withheldIncome==='absent')fail(coopDecision,'Ausência de redução contradiz os dados positivos de cooperativa integralmente elegível;reconcilie a declaração sem apagar os dados.');
|
||||
if(coopDecision.status==='calculated'){
|
||||
if(b.scope!=='resident_general'||!['agrarian','craft','cultural'].includes(i.cooperative.kind))fail(coopDecision,'Art12:tipo de cooperativa abrangida e residência por documentar;outras entidades têm correspondência própria.');
|
||||
if(i.cooperative.allIncomeEligible!=='yes'||i.cooperative.withheldIncome!=='absent')fail(coopDecision,'Recorte exige base ordinária integralmente elegível e ausência documentada de rendimentos sujeitos a retenção;parcelas mistas/retidas exigem segregação própria,sem redução global presumida.');
|
||||
}
|
||||
if(accDecision.status==='absent'&&i.acceleration.rows.length)fail(accDecision,'Ausência de amortização acelerada contradiz activos seleccionados.');
|
||||
if(accDecision.status!=='calculated'&&i.acceleration.rows.length&&accDecision.status!=='indeterminate')fail(accDecision,'Não aplicação global com activos seleccionados:reconcilie o estado e as parcelas.');
|
||||
if(accDecision.status==='calculated'){
|
||||
if(i.acceleration.cbfRequirements!=='yes'||!i.acceleration.recognition||!i.acceleration.recognitionReference.trim())fail(accDecision,'Falta enquadramentoCBF3/9 e reconhecimento10 quando exigido;excepção deve ter norma/suporte,não localização.');
|
||||
if(i.acceleration.noOtherBenefits!=='yes')fail(accDecision,'CumulaçãoCBF4 por corresponder;este recorte não combina outros benefícios positivos.');
|
||||
if(coopDecision.status==='calculated')fail(accDecision,'Combinação de redução cooperativa comCBF16 ainda não correspondida;cada caso independente continua demonstrável.');
|
||||
if(!b.depreciation||!m.depreciation||!i.acceleration.rows.length)fail(accDecision,'Seleccione activos do mapaL6 já reconciliado;sem criar activo ou quota paralelos.');
|
||||
}
|
||||
const accelerations=i.acceleration.rows.map(r=>{
|
||||
const a=b.depreciation?.assets.find(x=>x.id===r.assetId),base=m.depreciation?.assets.find(x=>x.id===r.assetId),issues:string[]=[];let status:Status='indeterminate';
|
||||
if(accDecision.status!=='calculated')issues.push(accDecision.reason);
|
||||
if(!r.reference.trim()||!r.eligible||!r.kind)issues.push('Condição/afectação do activo ao projecto por documentar.');
|
||||
if(i.acceleration.rows.filter(x=>x.assetId===r.assetId).length!==1)issues.push('Activo repetido no benefício.');
|
||||
if(!a||base?.status!=='calculated')issues.push('ActivoL6 inexistente ou cálculo de origem indeterminado.');
|
||||
if(!issues.length&&r.eligible==='no')status='not_applicable';
|
||||
else if(!issues.length&&a){
|
||||
const building=r.kind==='new_project_building'&&base?.catalog?.kind==='building',equipment=['industrial_equipment','agroindustrial_equipment'].includes(r.kind)&&['machine','laundry_machine'].includes(a.category);
|
||||
if(!building&&!equipment)issues.push('Categoria/afectação fora do recorte:imóvel novo ou máquina industrial/agro-industrial correspondida;reabilitados e outras categorias/métodos exigem regra própria.');
|
||||
if(base?.catalog&&cmp(decimalFraction(a.rate),decimalFraction(base.catalog.rate))!==0n)issues.push('RecorteCBF16 usa a taxa normal máxima da tabela;opção por quota inferior exige correspondência própria,sem a acelerar por aproximação.');
|
||||
if(a.method!=='constant'||a.timing!=='annual'||a.start!=='2026-01-01'||a.exitState!=='absent'||a.previousAccounting!=='0'||a.previousFiscal!=='0'||a.priorAvailable!=='0'||m.fiscalPeriod?.from!=='2026-01-01'||m.fiscalPeriod?.to!=='2026-12-31')issues.push('CBF16 inicial:primeiro exercício anual civil2026,método constante,sem quotas anteriores ou saída;duodécimos e recuperação anterior continuam separados.');
|
||||
if(!issues.length)status='calculated';
|
||||
}
|
||||
return{...structuredClone(r),assetKey:a?.assetKey??'',description:a?.description??'',status,reason:issues.join(' ')||(status==='calculated'?'Activo existente elegível;taxa normal ×1,5,com limite contabilístico e saldo fiscal.':'Condição negativa documentada;quota normal mantida.')};
|
||||
});
|
||||
let acceleratedDepreciation:NormalDepreciationModel|null=null,additionalDeduction:FiscalFraction|null=accDecision.status==='indeterminate'?null:z();
|
||||
if(accDecision.status==='calculated'){
|
||||
for(const r of accelerations)if(r.status==='indeterminate')fail(accDecision,(r.description||r.id)+': '+r.reason);
|
||||
if(accDecision.status==='calculated'&&b.depreciation&&m.depreciation?.adjustment){
|
||||
acceleratedDepreciation=calculateNormalDepreciation(b.depreciation,source,{from:'2026-01-01',to:'2026-12-31'},[...b.rows,...(b.schedules?.rows??[]),...(b.costs?.rows??[])],false,new Set(accelerations.filter(r=>r.status==='calculated').map(r=>r.assetId)));
|
||||
if(acceleratedDepreciation.adjustment===null)fail(accDecision,acceleratedDepreciation.pending.join(' '));
|
||||
else additionalDeduction=subtractFractions(m.depreciation.adjustment,acceleratedDepreciation.adjustment);
|
||||
}else if(accDecision.status==='calculated')fail(accDecision,'Reconciliação da amortização normal em falta.');
|
||||
}
|
||||
if(accDecision.status==='indeterminate')additionalDeduction=null;
|
||||
const taxableProfit=m.taxableProfit&&additionalDeduction?subtractFractions(m.taxableProfit,additionalDeduction):null;
|
||||
const base=b.base?calculateNormalBase(b.base,taxableProfit,b.year,b.schedules?.currentLossReference,!!m.periodsFx?.short):null;
|
||||
const assessmentInput=coopDecision.status==='calculated'?{version:1 as const,treatment:'general_61_1' as const,reference:i.cooperative.qualification.reference}:b.assessment;
|
||||
const assessment=assessmentInput?calculateNormalAssessment(assessmentInput,base?.taxableBase??null,{year:b.year,scope:b.scope,currency:m.currency,extended:!!b.schedules||!!b.periodsFx,short:!!m.periodsFx?.short,period:specialPeriod(b,m)}):null;
|
||||
const normalColecta=assessment?.colecta??null,colecta=coopDecision.status==='indeterminate'?null:normalColecta?(coopDecision.status==='calculated'?mul(normalColecta,1n,2n):normalColecta):null;
|
||||
const combinedColecta=colecta&&autonomousTax?addFractions([colecta,autonomousTax]):null;
|
||||
return{input:structuredClone(i),context:structuredClone(specialContext(draft)),subjectNuit:b.base?.subjectNuit??'',period:specialPeriod(b,m),expenses:{...expenseDecision,rows:expenses,knownAutonomous,autonomousTax,source:specialSources.expenses},cooperative:{...coopDecision,rate:coopDecision.status==='calculated'?fraction(16n):null,source:specialSources.cooperative},acceleration:{...accDecision,rows:accelerations,additionalDeduction,normal:m.depreciation??null,accelerated:acceleratedDepreciation,source:specialSources.acceleration},reference:{taxableProfit:m.taxableProfit,taxableBase:m.taxableBase,colecta:m.colecta??null},taxableProfit,taxableBase:base?.taxableBase??null,colecta,combinedColecta,pending:[...expenseDecision.pending,...coopDecision.pending,...accDecision.pending,...(base?.pending??[]),...(assessment?.pending??[])],limitations:['L7 parcial:apenas61(4),cooperativa integralmente elegível12 eCBF16 no recorte documentado.','Localização/sector só contextualizam;não activam benefícios.','Parcelas mistas,cumulação,mais-valias e demais famílias têm correspondência própria.','M20/M22 permanecem preparaçãoL6 de referência;efeitosL7 sem campo oficial presumido.','Colecta combinada não é saldo final a pagar/recuperar;retenções,pagamentos e créditos anuais emL8.'],finalBalance:{scope:'L8',payable:null,recoverable:null}};
|
||||
}
|
||||
export type SpecialModel=ReturnType<typeof calculateSpecial>;
|
||||
const money=(v:FiscalFraction|null)=>{if(!v)return'Indeterminado';const p=fractionPresentation(v);return(p.approximate?'≈':'')+p.decimal+' MZN (exacto '+v.numerator+'/'+v.denominator+')';};
|
||||
const status=(s:Status)=>({calculated:'Calculado no recorte',absent:'Ausência declarada',not_applicable:'Não aplicável',indeterminate:'Informação em falta'})[s];
|
||||
const contextDescription=(c:Record<string,unknown>)=>[['Sector','sector_id'],['Província','province_id'],['Distrito','district_id'],['Posto administrativo','admin_post_id'],['Localidade','locality_id']].map(([label,key])=>label+': '+String(c[key+'_label']||c[key]||'Por identificar')).join(';');
|
||||
export function specialReportRows(m:SpecialModel):Array<[string,string,string,string]>{return[
|
||||
['IRPC — L7','Qualificação comum',`NUIT:${m.subjectNuit};período:${m.period.from}–${m.period.to};${contextDescription(m.context)};${m.limitations.join(' ')}`,'Origem herdada conservada;fonte/condições/período por tratamento;sem concessão pela localização.'],
|
||||
['IRPC — L7','Despesas — imposto autónomo',`${status(m.expenses.status)};parcela conhecida:${money(m.expenses.knownAutonomous)};imposto autónomo reconciliado:${money(m.expenses.autonomousTax)};${m.expenses.reason}`,`${m.input.expenses.qualification.reference};${m.input.expenses.qualification.periodReference};${m.expenses.source}`],
|
||||
...m.expenses.rows.map(r=>['IRPC — L7',r.document+'/'+r.line,`${status(r.status)};natureza:${r.nature||'Por identificar'};despesa:${money(r.amount)};ajustamento36g já emL6:${money(r.l6Adjustment)};novo ajustamento ao lucro:${money(r.additionalProfitAdjustment)};taxa:${r.rate?'35%':'Não aplicada'};imposto autónomo:${money(r.tax)};${r.reason}`,r.reference]as[string,string,string,string]),
|
||||
['IRPC — L7','Cooperativa — redução da taxa',`${status(m.cooperative.status)};tipo:${m.input.cooperative.kind||'Por identificar'};taxa:${m.cooperative.rate?'16%':'Não aplicada'};${m.cooperative.reason}`,`${m.input.cooperative.qualification.reference};${m.input.cooperative.qualification.periodReference};${m.cooperative.source}`],
|
||||
['IRPC — L7','Amortizações aceleradas',`${status(m.acceleration.status)};dedução adicional conciliada:${money(m.acceleration.additionalDeduction)};${m.acceleration.reason}`,`${m.input.acceleration.qualification.reference};${m.input.acceleration.qualification.periodReference};${m.input.acceleration.recognitionReference};${m.acceleration.source}`],
|
||||
...m.acceleration.rows.map(r=>{const a=m.acceleration.accelerated?.assets.find(a=>a.id===r.assetId),n=m.acceleration.normal?.assets.find(a=>a.id===r.assetId);return['IRPC — L7',r.description||r.assetId,`${status(r.status)};quota normal:${money(n?.quota??null)};quota acelerada:${money(a?.quota??null)};dedução normal:${money(n?.deduction??null)};dedução acelerada:${money(a?.deduction??null)};${r.reason}`,r.reference]as[string,string,string,string];}),
|
||||
['IRPC — L7','Efeitos nos totais',`ReferênciaL6:lucro:${money(m.reference.taxableProfit)};base:${money(m.reference.taxableBase)};colecta:${money(m.reference.colecta)}. Após tratamentosL7:lucro:${money(m.taxableProfit)};base:${money(m.taxableBase)};colecta sobre a base:${money(m.colecta)};imposto autónomo:${money(m.expenses.autonomousTax)};colecta combinada:${money(m.combinedColecta)}. Saldo final a pagar/recuperar:Indeterminado (L8).`,m.pending.join(' | ')||'Regras/parcelas reconciliadas neste recorte;simulação,não liquidação final.'],
|
||||
];}
|
||||
@@ -445,20 +445,25 @@ export function portalNavigation(access: PortalNavAccess): PortalNavItem[] {
|
||||
id: 'discovery',
|
||||
label: 'Descoberta',
|
||||
children: [
|
||||
link(
|
||||
'why',
|
||||
'Porquê investir em Moçambique?',
|
||||
'/porque-investir',
|
||||
),
|
||||
link(
|
||||
'idea-entry',
|
||||
'Partir de uma ideia',
|
||||
'/investimentos/iniciar',
|
||||
),
|
||||
link(
|
||||
'why',
|
||||
'Porquê investir em Moçambique',
|
||||
'/porque-investir',
|
||||
'opportunities',
|
||||
'Consultar oportunidades',
|
||||
'/oportunidades',
|
||||
),
|
||||
link(
|
||||
'opportunities',
|
||||
'Oportunidades de investimento',
|
||||
'/oportunidades',
|
||||
'simulator',
|
||||
'Simulador Fiscal',
|
||||
access.context?.simulator || '/simulador-fiscal',
|
||||
),
|
||||
link('sectors', 'Sectores de investimento', '/sectores'),
|
||||
link('locations', 'Localizações', '/oportunidades?view=map'),
|
||||
@@ -500,11 +505,6 @@ export function portalNavigation(access: PortalNavAccess): PortalNavItem[] {
|
||||
label: 'Realização',
|
||||
children: [
|
||||
link('start', 'Iniciar investimento', '/investimentos/iniciar'),
|
||||
link(
|
||||
'simulator',
|
||||
'Incentivos e simulador fiscal',
|
||||
access.context?.simulator || '/simulador-fiscal',
|
||||
),
|
||||
link(
|
||||
'licensing',
|
||||
'Licenciamento',
|
||||
|
||||
@@ -178,6 +178,7 @@ const rowSection: Record<string, DossierReportSectionId> = {
|
||||
ISPC: 'finance',
|
||||
'IRPC — retenções': 'finance',
|
||||
'IRPC normal — L6': 'finance',
|
||||
'IRPC — L7': 'finance',
|
||||
Equipa: 'team',
|
||||
'Necessidade de negócio': 'resources',
|
||||
Financiamento: 'resources',
|
||||
|
||||
@@ -1001,7 +1001,6 @@ export default function PortalInvestidorApp({
|
||||
setQuery={setHeroQuery}
|
||||
onSearch={handleHeroSearch}
|
||||
stats={home.data?.data.stats}
|
||||
onNavigate={navigate}
|
||||
/>
|
||||
<InvestmentContextCards />
|
||||
<QueryStatus
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Head, Link, usePage } from '@inertiajs/react';
|
||||
import type { ReactNode } from 'react';
|
||||
import { PortalMenu } from '@/layouts/portal-navigation';
|
||||
import { cn } from '@/lib/utils';
|
||||
import type { TerritorialSourceEvidence } from '@/components/territorial-source-evidence';
|
||||
import type {
|
||||
StructureGeography,
|
||||
@@ -101,9 +102,11 @@ export const card = 'rounded-xl border border-slate-200 bg-white p-5 shadow-sm';
|
||||
export function Frame({
|
||||
title,
|
||||
children,
|
||||
mainClassName,
|
||||
}: {
|
||||
title: string;
|
||||
children: ReactNode;
|
||||
mainClassName?: string;
|
||||
}) {
|
||||
const { flash } = usePage<{
|
||||
flash?: { success?: string; warning?: string };
|
||||
@@ -112,7 +115,12 @@ export function Frame({
|
||||
<div className="min-h-screen bg-slate-50 text-slate-900">
|
||||
<Head title={title} />
|
||||
<PortalMenu />
|
||||
<main className="mx-auto max-w-7xl space-y-6 px-5 py-9">
|
||||
<main
|
||||
className={cn(
|
||||
'mx-auto max-w-7xl space-y-6 px-5 py-9',
|
||||
mainClassName,
|
||||
)}
|
||||
>
|
||||
<h1 className="text-3xl font-bold">{title}</h1>
|
||||
{flash?.warning && (
|
||||
<p
|
||||
|
||||
@@ -1,99 +1,201 @@
|
||||
import { Link } from '@inertiajs/react';
|
||||
import { Frame, card, button } from '@/pages/investment/shared';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
const compactCard = cn(card, 'p-4');
|
||||
const compactButton = cn(button, 'min-h-11 px-3 py-1.5 text-sm sm:min-h-9');
|
||||
|
||||
export default function WhyInvest() {
|
||||
return (
|
||||
<Frame title="Porquê investir em Moçambique">
|
||||
<section className={card + ' space-y-4'}>
|
||||
<h2 className="text-2xl font-bold">
|
||||
Encontrar possibilidades e avaliar as condições
|
||||
</h2>
|
||||
<p>
|
||||
Investir começa por identificar uma necessidade, um mercado
|
||||
e uma forma de criar valor. Em Moçambique, explore as
|
||||
possibilidades de produção, transformação, logística,
|
||||
turismo e serviços e compare as condições de cada projecto.
|
||||
Este percurso destina-se a investidores nacionais e
|
||||
estrangeiros, em todo o território nacional.
|
||||
</p>
|
||||
<p>
|
||||
A informação do portal ajuda a comparar possibilidades e a
|
||||
organizar os elementos do dossier. Uma página setorial ou
|
||||
artigo educativo não representa uma oportunidade concreta
|
||||
nem uma recomendação de retorno.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<Link className={button} href="/oportunidades">
|
||||
Explorar oportunidades publicadas
|
||||
</Link>
|
||||
<Link className={button} href="/investimentos/iniciar">
|
||||
Iniciar ou continuar uma ideia
|
||||
</Link>
|
||||
<Frame
|
||||
title="Porquê investir em Moçambique?"
|
||||
mainClassName="space-y-4 py-6"
|
||||
>
|
||||
<div className="flow-root">
|
||||
<div className="-mx-2 flow-root">
|
||||
<article
|
||||
aria-label="Investir em Moçambique"
|
||||
className="p-2 lg:float-left lg:w-2/3"
|
||||
>
|
||||
<div className="space-y-3 text-base leading-6 text-slate-700">
|
||||
<p>
|
||||
Investir em Moçambique é escolher um mercado em
|
||||
forte expansão, estrategicamente posicionado na
|
||||
África Austral e integrado na SADC, com acesso
|
||||
directo a seis países vizinhos e a um dos
|
||||
maiores blocos económicos da região. A
|
||||
estabilidade política, a segurança e um ambiente
|
||||
regulatório cada vez mais favorável tornam o
|
||||
país um destino confiável e competitivo para
|
||||
investidores nacionais e estrangeiros.
|
||||
</p>
|
||||
<p>
|
||||
A localização privilegiada faz de Moçambique uma
|
||||
plataforma logística natural. Os portos de
|
||||
Maputo, Beira e Nacala — este último, o porto
|
||||
natural mais profundo da costa oriental africana
|
||||
— funcionam como corredores eficientes para
|
||||
economias sem litoral como as de Malawi, Zâmbia
|
||||
e Zimbabué. Esta infraestrutura sólida consolida
|
||||
o país como um hub regional de comércio,
|
||||
transporte e distribuição.
|
||||
</p>
|
||||
<p>
|
||||
Moçambique reforça a confiança dos investidores
|
||||
por meio de acordos bilaterais de investimento e
|
||||
de tratados de dupla tributação com economias
|
||||
estratégicas, garantindo estabilidade jurídica e
|
||||
protecção aos investimentos. Além disso, oferece
|
||||
incentivos fiscais e aduaneiros competitivos,
|
||||
aliados ao acesso preferencial a grandes
|
||||
mercados internacionais via AGOA (EUA), EBA
|
||||
(União Europeia), preferências comerciais com a
|
||||
China e parcerias com a Índia. Estes mecanismos
|
||||
aumentam a competitividade das empresas que se
|
||||
instalam no país e ampliam o seu alcance global.
|
||||
</p>
|
||||
<p>
|
||||
O país oferece garantias essenciais, como
|
||||
protecção da propriedade, repatriação livre de
|
||||
lucros e incentivos específicos, incluindo
|
||||
isenção de direitos aduaneiros para
|
||||
equipamentos, crédito fiscal, depreciação
|
||||
acelerada e benefícios para tecnologias,
|
||||
formação, inovação e infraestruturas. Sectores
|
||||
prioritários — agricultura, pescas, indústrias
|
||||
rurais, turismo, mineração, petróleo e gás — bem
|
||||
como zonas francas e zonas económicas especiais
|
||||
dispõem de regimes particularmente vantajosos.
|
||||
</p>
|
||||
<p>
|
||||
<strong>
|
||||
Investir em Moçambique é integrar um país em
|
||||
transformação
|
||||
</strong>
|
||||
, rico em recursos, com enorme potencial
|
||||
energético, agricultura fértil, projectos
|
||||
estruturantes em curso e uma visão clara de
|
||||
industrialização. Com reformas consistentes,
|
||||
vantagens logísticas e acesso preferencial a
|
||||
mercados internacionais, o país destaca-se como
|
||||
um dos destinos mais promissores para
|
||||
investidores que buscam crescimento sustentável,
|
||||
estabilidade e oportunidades concretas na África
|
||||
Austral.
|
||||
</p>
|
||||
</div>
|
||||
</article>
|
||||
<div className="p-2 lg:inline-block lg:w-1/3 lg:align-top">
|
||||
<section className={compactCard + ' space-y-3'}>
|
||||
<h2 className="text-xl leading-snug font-bold">
|
||||
Encontrar possibilidades e avaliar as condições
|
||||
</h2>
|
||||
<p>
|
||||
Investir começa por identificar uma necessidade,
|
||||
um mercado e uma forma de criar valor. Em
|
||||
Moçambique, explore as possibilidades de
|
||||
produção, transformação, logística, turismo e
|
||||
serviços e compare as condições de cada
|
||||
projecto. Este percurso destina-se a
|
||||
investidores nacionais e estrangeiros, em todo o
|
||||
território nacional.
|
||||
</p>
|
||||
<p>
|
||||
A informação do portal ajuda a comparar
|
||||
possibilidades e a organizar os elementos do
|
||||
dossier. Uma página setorial ou artigo educativo
|
||||
não representa uma oportunidade concreta nem uma
|
||||
recomendação de retorno.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Link
|
||||
className={compactButton}
|
||||
href="/oportunidades"
|
||||
>
|
||||
Explorar oportunidades publicadas
|
||||
</Link>
|
||||
<Link
|
||||
className={compactButton}
|
||||
href="/investimentos/iniciar"
|
||||
>
|
||||
Iniciar ou continuar uma ideia
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
{[
|
||||
[
|
||||
'Produção e transformação',
|
||||
'Compare fornecimento, processamento e comercialização. Avalie matérias-primas, fornecedores, energia, água e procura antes de escolher a escala do projecto.',
|
||||
'/sectores',
|
||||
],
|
||||
[
|
||||
'Território e ligações',
|
||||
'Compare localizações, corredores e parques com o mercado que pretende servir. Confira acessos, logística, infra-estruturas e as condições documentadas de cada ficha.',
|
||||
'/oportunidades?view=map',
|
||||
],
|
||||
[
|
||||
'Serviços e parcerias',
|
||||
'Explore necessidades de empresas e comunidades e possibilidades de cooperação. Distinga uma ideia a desenvolver de uma oportunidade publicada ou de uma parceria formalizada.',
|
||||
'/parcerias',
|
||||
],
|
||||
].map(([title, text, href]) => (
|
||||
<div
|
||||
className="p-2 md:inline-block md:w-1/2 md:align-top lg:w-1/3"
|
||||
key={title}
|
||||
>
|
||||
<article className={compactCard + ' space-y-2'}>
|
||||
<h2 className="text-lg leading-snug font-bold">
|
||||
{title}
|
||||
</h2>
|
||||
<p>{text}</p>
|
||||
<Link className="underline" href={href}>
|
||||
Explorar {title.toLowerCase()}
|
||||
</Link>
|
||||
</article>
|
||||
</div>
|
||||
))}
|
||||
{[
|
||||
[
|
||||
'Sectores e modelos de negócio',
|
||||
'Consulte o conteúdo educativo e as oportunidades cadastradas. Pode iniciar uma ideia mesmo sem um anúncio publicado.',
|
||||
'/sectores',
|
||||
],
|
||||
[
|
||||
'Localizações e enquadramentos',
|
||||
'Explore o mapa e as fichas de corredores, clusters, zonas, parques e projectos. Cada referência conserva a natureza e o fundamento que lhe estão associados.',
|
||||
'/oportunidades?view=map',
|
||||
],
|
||||
[
|
||||
'Fontes para decidir',
|
||||
'Consulte documentos e legislação do acervo publicado. Confirme o âmbito e o período aplicável antes de usar uma informação no seu processo.',
|
||||
'/documentos',
|
||||
],
|
||||
[
|
||||
'Um dossier para desenvolver a ideia',
|
||||
'A oportunidade, o sector e a localização convergem num dossier com cinco fases e 19 etapas. A orientação permite preparar etapas em paralelo e respeita a aplicabilidade de terra e licenciamento.',
|
||||
'/como-investir',
|
||||
],
|
||||
].map(([title, text, href]) => (
|
||||
<div
|
||||
className="p-2 md:inline-block md:w-1/2 md:align-top lg:w-1/3"
|
||||
key={title}
|
||||
>
|
||||
<article className={compactCard + ' space-y-2'}>
|
||||
<h2 className="text-lg leading-snug font-bold">
|
||||
{title}
|
||||
</h2>
|
||||
<p>{text}</p>
|
||||
<Link className="underline" href={href}>
|
||||
Consultar {title.toLowerCase()}
|
||||
</Link>
|
||||
</article>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
<section
|
||||
aria-label="Perspectivas para avaliar o investimento"
|
||||
className="grid gap-4 md:grid-cols-3"
|
||||
>
|
||||
{[
|
||||
[
|
||||
'Produção e transformação',
|
||||
'Compare fornecimento, processamento e comercialização. Avalie matérias-primas, fornecedores, energia, água e procura antes de escolher a escala do projecto.',
|
||||
'/sectores',
|
||||
],
|
||||
[
|
||||
'Território e ligações',
|
||||
'Compare localizações, corredores e parques com o mercado que pretende servir. Confira acessos, logística, infra-estruturas e as condições documentadas de cada ficha.',
|
||||
'/oportunidades?view=map',
|
||||
],
|
||||
[
|
||||
'Serviços e parcerias',
|
||||
'Explore necessidades de empresas e comunidades e possibilidades de cooperação. Distinga uma ideia a desenvolver de uma oportunidade publicada ou de uma parceria formalizada.',
|
||||
'/parcerias',
|
||||
],
|
||||
].map(([title, text, href]) => (
|
||||
<article className={card + ' space-y-3'} key={title}>
|
||||
<h2 className="text-xl font-bold">{title}</h2>
|
||||
<p>{text}</p>
|
||||
<Link className="underline" href={href}>
|
||||
Explorar {title.toLowerCase()}
|
||||
</Link>
|
||||
</article>
|
||||
))}
|
||||
</section>
|
||||
<section className="grid gap-4 md:grid-cols-2">
|
||||
{[
|
||||
[
|
||||
'Sectores e modelos de negócio',
|
||||
'Consulte o conteúdo educativo e as oportunidades cadastradas. Pode iniciar uma ideia mesmo sem um anúncio publicado.',
|
||||
'/sectores',
|
||||
],
|
||||
[
|
||||
'Localizações e enquadramentos',
|
||||
'Explore o mapa e as fichas de corredores, clusters, zonas, parques e projectos. Cada referência conserva a natureza e o fundamento que lhe estão associados.',
|
||||
'/oportunidades?view=map',
|
||||
],
|
||||
[
|
||||
'Fontes para decidir',
|
||||
'Consulte documentos e legislação do acervo publicado. Confirme o âmbito e o período aplicável antes de usar uma informação no seu processo.',
|
||||
'/documentos',
|
||||
],
|
||||
[
|
||||
'Um dossier para desenvolver a ideia',
|
||||
'A oportunidade, o sector e a localização convergem num dossier com cinco fases e 19 etapas. A orientação permite preparar etapas em paralelo e respeita a aplicabilidade de terra e licenciamento.',
|
||||
'/como-investir',
|
||||
],
|
||||
].map(([title, text, href]) => (
|
||||
<article className={card + ' space-y-3'} key={title}>
|
||||
<h2 className="text-xl font-bold">{title}</h2>
|
||||
<p>{text}</p>
|
||||
<Link className="underline" href={href}>
|
||||
Consultar {title.toLowerCase()}
|
||||
</Link>
|
||||
</article>
|
||||
))}
|
||||
</section>
|
||||
<section className={card + ' space-y-3'}>
|
||||
<h2 className="text-xl font-bold">
|
||||
</div>
|
||||
<section className={compactCard + ' space-y-2'}>
|
||||
<h2 className="text-lg leading-snug font-bold">
|
||||
Preparar condições, documentação e apoio
|
||||
</h2>
|
||||
<p>
|
||||
@@ -109,7 +211,7 @@ export default function WhyInvest() {
|
||||
retorno do investimento. Informação desconhecida deve
|
||||
continuar identificada como tal.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<div className="flex flex-wrap gap-x-3 gap-y-2">
|
||||
<Link className="underline" href="/legislacao">
|
||||
Legislação e enquadramento
|
||||
</Link>
|
||||
@@ -121,8 +223,8 @@ export default function WhyInvest() {
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
<section className={card + ' space-y-3'}>
|
||||
<h2 className="text-xl font-bold">
|
||||
<section className={compactCard + ' space-y-2'}>
|
||||
<h2 className="text-lg leading-snug font-bold">
|
||||
Apoio ao longo do percurso
|
||||
</h2>
|
||||
<p>
|
||||
@@ -131,8 +233,8 @@ export default function WhyInvest() {
|
||||
distinto de submeter um pedido; uma comunicação interna não
|
||||
equivale a uma decisão oficial.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<Link className={button} href="/balcao-virtual">
|
||||
<div className="flex flex-wrap gap-x-3 gap-y-2">
|
||||
<Link className={compactButton} href="/balcao-virtual">
|
||||
Serviços ao investidor
|
||||
</Link>
|
||||
<Link className="underline" href="/apoio">
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<?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 IrpcSpecialDraftTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function test_special_treatments_recover_with_original_plan_history_and_indeterminate_cases(): void
|
||||
{
|
||||
$target=DB::selectOne('select current_database() as name,inet_server_port() as port');
|
||||
$this->assertSame('simulator_fiscal_delta_20261021_test',$target->name);
|
||||
$this->assertSame(55441,(int)$target->port);
|
||||
config(['investor-path.enabled'=>true,'suitecrm.enabled'=>false]);
|
||||
$this->actingAs(User::factory()->create(['email_verified_at'=>now()]));
|
||||
$id=null;$etag=null;
|
||||
foreach(['expense','missing','negative','absent','cooperative','acceleration'] as $case){
|
||||
$d=json_decode(file_get_contents(base_path('outputs/irpc-l7-common/'.$case.'.json')),true,flags:JSON_THROW_ON_ERROR);
|
||||
$personal=['person_type'=>$d['person_type']];unset($d['person_type']);
|
||||
if($id===null)$id=$this->postJson('/api/v1/simulation-drafts',['personal_snapshot'=>$personal,'economic_snapshot'=>$d],['Idempotency-Key'=>(string)Str::uuid()])->assertCreated()->json('data.id');
|
||||
else $this->putJson('/api/v1/simulation-drafts/'.$id,['personal_snapshot'=>$personal,'economic_snapshot'=>$d],['If-Match'=>$etag])->assertOk();
|
||||
$r=$this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk();$etag=$r->headers->get('ETag');$back=$r->json('data.economic_snapshot');
|
||||
$this->assertSame($d['business_plan_snapshot'],$back['business_plan_snapshot']);
|
||||
$this->assertSame($d['modelo_a_snapshot'],$back['modelo_a_snapshot']);
|
||||
$s=json_decode($back['modelo_a_snapshot'],true,flags:JSON_THROW_ON_ERROR);$b=$s['irpcNormal'][$d['context_opportunity']];$m=$b['result']['model'];$l7=$m['special'];
|
||||
$this->assertSame('IRPC-normal-adjustments/10',$m['version']);
|
||||
$this->assertSame($b['special'],$l7['input']);
|
||||
$this->assertContains('IRPC-normal-adjustments/9',array_column(array_column($b['history'],'model'),'version'));
|
||||
$this->assertArrayHasKey('irpcWithholdings',$s);$this->assertArrayHasKey('books',$s);
|
||||
$this->assertNull($m['tax']);$this->assertNull($l7['finalBalance']['payable']);$this->assertNull($l7['finalBalance']['recoverable']);
|
||||
$this->assertSame('123456789',$l7['subjectNuit']);
|
||||
$this->assertStringContainsString('61(4)',$l7['expenses']['source']);
|
||||
if($case==='expense'){
|
||||
$this->assertSame('35',$l7['expenses']['autonomousTax']['numerator']);
|
||||
$this->assertSame('100',$l7['expenses']['rows'][0]['l6Adjustment']['numerator']);
|
||||
$this->assertSame('0',$l7['expenses']['rows'][0]['additionalProfitAdjustment']['numerator']);
|
||||
$this->assertSame($m['taxableProfit'],$l7['taxableProfit']);
|
||||
$this->assertSame(['numerator'=>'5343','denominator'=>'5'],$l7['combinedColecta']);
|
||||
}elseif($case==='missing'){
|
||||
$this->assertSame('indeterminate',$l7['expenses']['status']);$this->assertNull($l7['expenses']['autonomousTax']);$this->assertNull($l7['combinedColecta']);
|
||||
$this->assertSame('3230',$m['taxableProfit']['numerator']);
|
||||
}elseif($case==='negative'){
|
||||
$this->assertSame('not_applicable',$l7['expenses']['rows'][0]['status']);$this->assertSame('0',$l7['expenses']['autonomousTax']['numerator']);
|
||||
}elseif($case==='absent'){
|
||||
$this->assertSame('absent',$l7['expenses']['status']);$this->assertSame('0',$l7['expenses']['autonomousTax']['numerator']);
|
||||
}elseif($case==='cooperative'){
|
||||
$this->assertSame('16',$l7['cooperative']['rate']['numerator']);$this->assertSame(['numerator'=>'2504','denominator'=>'5'],$l7['colecta']);
|
||||
$this->assertSame(['numerator'=>'5008','denominator'=>'5'],$m['colecta']);
|
||||
}else{
|
||||
$this->assertSame('20',$l7['acceleration']['additionalDeduction']['numerator']);
|
||||
$this->assertSame('150',$l7['acceleration']['accelerated']['assets'][0]['quota']['numerator']);
|
||||
$this->assertSame('120',$l7['acceleration']['accelerated']['assets'][0]['deduction']['numerator']);
|
||||
$this->assertSame('6240',$l7['taxableProfit']['numerator']);$this->assertSame('6260',$m['taxableProfit']['numerator']);
|
||||
$this->assertSame($b['depreciation'],$l7['acceleration']['accelerated']['input']);
|
||||
}
|
||||
file_put_contents(base_path('outputs/irpc-l7-common/recovered-'.$case.'.json'),json_encode($back,JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,32 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import {normalBook,normalCurrent,calculateNormal,recordNormal,saveNormalBook,normalHtml} from '../../resources/js/lib/irpc-normal.ts';
|
||||
import {newSpecialInput,newQualification,newSpecialExpense,newAcceleratedAsset} from '../../resources/js/lib/irpc-special.ts';
|
||||
import {createProjectDossierReport} from '../../resources/js/lib/project-dossier-report.ts';
|
||||
const seed=()=>JSON.parse(fs.readFileSync(new URL('./fixtures/irpc-l6-values-preserved.json',import.meta.url),'utf8'));
|
||||
const value=v=>v?Number(v.numerator)/Number(v.denominator):null;
|
||||
const qualification=(state='absent',from='2026-07-01',to='2026-12-31')=>({...newQualification(),state,eligible:state==='known'?'yes':'',from,to,reference:'QA declaração/prova das condições legais no sujeito e parcela,sem inferência territorial',periodReference:'QA norma/exercício2026 e período documentado'});
|
||||
function setup(){const d=seed(),b=normalBook(d);b.special=newSpecialInput();for(const part of[b.special.expenses,b.special.cooperative,b.special.acceleration])part.qualification=qualification();return{d,b};}
|
||||
function expenses(){const{d,b}=setup();b.schedules.rows.push({id:'expense36g',rule:'undocumented',amount:'100',sourceCode:'operating_expenses',document:'QA-despesa',line:'1',reference:'QA despesa100 efectivamente incluída e não documentada36g',fiscalYear:'',conditions:'yes'});b.profit.topics.expenseCorrections={state:'known',amount:'100',reference:'QA acréscimo36g já conferido,sem outra correcção'};b.special.expenses.qualification=qualification('known');b.special.expenses.rows=[{...newSpecialExpense('autonomous1'),scheduleId:'expense36g',nature:'undocumented',eligible:'yes',reference:'QA qualificação legal61(4),não inferida de anexo em falta'}];return{d,b};}
|
||||
function cooperative(){const{d,b}=setup();b.special.cooperative={qualification:qualification('known'),kind:'agrarian',allIncomeEligible:'yes',withheldIncome:'absent'};return{d,b};}
|
||||
function acceleration(){const{d,b}=setup();delete b.periodsFx;delete b.forms;b.schedules.interest.amount='240';Object.assign(b.depreciation.assets[0],{category:'machine',description:'Máquina industrial existente QA',cost:'1000',rate:'10',accounting:'120',start:'2026-01-01',timing:'annual'});for(const part of[b.special.expenses,b.special.cooperative,b.special.acceleration])part.qualification=qualification('absent','2026-01-01','2026-12-31');b.special.acceleration={qualification:qualification('known','2026-01-01','2026-12-31'),cbfRequirements:'yes',recognition:'documented',recognitionReference:'QA instrumento do projecto/reconhecimento10,pressupostos3/9 e afectação industrial documentados',noOtherBenefits:'yes',rows:[{...newAcceleratedAsset('accelerated1'),assetId:b.depreciation.assets[0].id,kind:'industrial_equipment',eligible:'yes',reference:'QA factura/afectação da máquina ao projecto industrialCBF16'}]};return{d,b};}
|
||||
test('no optionalL7 keeps exact accepted9 result and key; installed history is not recalculated on read',()=>{const d=seed(),b=normalBook(d),old=structuredClone(b.result);assert.equal(normalCurrent(d,b),true);assert.deepEqual(calculateNormal(d,b),old.model);assert.deepEqual(normalBook(d).result,old);});
|
||||
test('61(4) reuses100 addback36g and computes35 autonomously without another profit adjustment',()=>{const{d,b}=expenses(),m=calculateNormal(d,b),s=m.special;assert.equal(m.version,'IRPC-normal-adjustments/10');assert.equal(value(m.taxableProfit),3230);assert.equal(value(m.colecta),1033.6);assert.equal(value(s.taxableProfit),3230);assert.equal(value(s.expenses.rows[0].l6Adjustment),100);assert.equal(value(s.expenses.rows[0].additionalProfitAdjustment),0);assert.equal(value(s.expenses.autonomousTax),35);assert.equal(value(s.combinedColecta),1068.6);assert.equal(s.finalBalance.payable,null);});
|
||||
test('missing, absent and notapplicable differ; attachment presence alone never classifies an expense',()=>{const{d,b}=setup();b.special.expenses.qualification=qualification('');let s=calculateNormal(d,b).special;assert.equal(s.expenses.status,'indeterminate');assert.equal(s.expenses.autonomousTax,null);b.special.expenses.qualification=qualification('absent');s=calculateNormal(d,b).special;assert.equal(s.expenses.status,'absent');assert.equal(value(s.expenses.autonomousTax),0);b.special.expenses.qualification=qualification('not_applicable');assert.equal(calculateNormal(d,b).special.expenses.status,'not_applicable');const c=expenses();c.b.special.expenses.rows[0].nature='';assert.equal(calculateNormal(c.d,c.b).special.expenses.autonomousTax,null);});
|
||||
test('false condition keeps existing addback and no autonomous tax; contradictory absence cannot erase expense',()=>{const{d,b}=expenses();b.special.expenses.rows[0].eligible='no';let m=calculateNormal(d,b);assert.equal(m.special.expenses.rows[0].status,'not_applicable');assert.equal(value(m.special.expenses.autonomousTax),0);assert.equal(value(m.taxableProfit),3230);b.special.expenses.rows=[];b.special.expenses.qualification=qualification('absent');m=calculateNormal(d,b);assert.equal(m.special.expenses.status,'indeterminate');assert.equal(value(m.taxableProfit),3230);});
|
||||
test('duplicate, unlinked or uncalculated36g cannot doublecharge or manufacture tax',()=>{for(const mode of['duplicate','unlinked','uncalculated','missingcoverage']){const{d,b}=expenses();if(mode==='duplicate')b.special.expenses.rows.push({...b.special.expenses.rows[0],id:'duplicate'});if(mode==='unlinked')b.special.expenses.rows[0].scheduleId='not-found';if(mode==='uncalculated')b.schedules.rows[0].conditions='';if(mode==='missingcoverage')b.special.expenses.rows=[];assert.equal(calculateNormal(d,b).special.expenses.autonomousTax,null,mode);}});
|
||||
test('common qualification rejects wrong period/year or missing identity without blocking independent L6 totals',()=>{for(const mutate of[b=>b.special.expenses.qualification.to='2025-12-31',b=>b.special.expenses.qualification.periodReference='',b=>b.base.subjectNuit='']){const{d,b}=expenses();mutate(b);const m=calculateNormal(d,b);assert.equal(m.special.expenses.autonomousTax,null);if(b.base.subjectNuit)assert.equal(value(m.colecta),1033.6);}});
|
||||
test('unknown benefit does not suppress separately calculable autonomous expense or normal reference',()=>{const{d,b}=expenses();b.special.acceleration.qualification=qualification('');const m=calculateNormal(d,b);assert.equal(value(m.special.expenses.autonomousTax),35);assert.equal(value(m.special.reference.colecta),1033.6);assert.equal(m.special.combinedColecta,null);});
|
||||
test('eligible cooperative uses16percent without changing reference32percent or autonomous expense rate',()=>{const{d,b}=cooperative(),m=calculateNormal(d,b);assert.equal(value(m.colecta),1001.6);assert.equal(m.special.cooperative.status,'calculated');assert.equal(value(m.special.cooperative.rate),16);assert.equal(value(m.special.colecta),500.8);assert.equal(value(m.special.taxableBase),3130);assert.equal(value(m.special.combinedColecta),500.8);const x=expenses();x.b.special.cooperative=structuredClone(b.special.cooperative);assert.equal(value(calculateNormal(x.d,x.b).special.combinedColecta),551.8);});
|
||||
test('mixed, withheld, unclassified or false cooperative conditions never grant blanket reduction',()=>{for(const mutate of[c=>c.allIncomeEligible='no',c=>c.withheldIncome='known',c=>c.kind='other']){const{d,b}=cooperative();mutate(b.special.cooperative);const m=calculateNormal(d,b);assert.equal(m.special.cooperative.status,'indeterminate');assert.equal(m.special.colecta,null);assert.equal(value(m.colecta),1001.6);}const{d,b}=cooperative();b.special.cooperative.qualification.eligible='no';assert.equal(value(calculateNormal(d,b).special.colecta),1001.6);});
|
||||
test('cooperative treatment does not require mislabelling special rate as L6 general; contradictory absence remains pending',()=>{const{d,b}=cooperative();b.assessment.treatment='other';let m=calculateNormal(d,b);assert.equal(m.colecta,null);assert.equal(value(m.special.colecta),500.8);b.special.cooperative.qualification=qualification('absent');m=calculateNormal(d,b);assert.equal(m.special.cooperative.status,'indeterminate');assert.equal(m.special.colecta,null);});
|
||||
test('common period follows declared shortperiod even without schedules; calendar dates cannot replace it',()=>{const{d,b}=cooperative();delete b.schedules;b.special.expenses.qualification=qualification('absent','2026-01-01','2026-12-31');const m=calculateNormal(d,b);assert.equal(m.special.period.from,'2026-07-01');assert.equal(m.special.expenses.status,'indeterminate');});
|
||||
test('CBF16 reuses asset and rate10to15 but respects120 accounted cap; additional deduction20 not50',()=>{const{d,b}=acceleration(),input=JSON.stringify(b.depreciation),m=calculateNormal(d,b),s=m.special;assert.equal(s.acceleration.status,'calculated',s.acceleration.reason);assert.equal(value(m.depreciation.assets[0].quota),100);assert.equal(value(s.acceleration.accelerated.assets[0].quota),150);assert.equal(value(s.acceleration.accelerated.assets[0].deduction),120);assert.equal(value(s.acceleration.additionalDeduction),20);assert.equal(value(m.taxableProfit),6260);assert.equal(value(s.taxableProfit),6240);assert.equal(value(s.taxableBase),6240);assert.equal(value(s.colecta),1996.8);assert.equal(JSON.stringify(b.depreciation),input);});
|
||||
test('new project building reuses land separation and legal table rate before bounded acceleration',()=>{const{d,b}=acceleration();Object.assign(b.depreciation.assets[0],{category:'commercial_building',cost:'5000',land:'0',rate:'2'});b.special.acceleration.rows[0].kind='new_project_building';const m=calculateNormal(d,b);assert.equal(m.special.acceleration.status,'calculated');assert.equal(value(m.special.acceleration.accelerated.assets[0].quota),150);assert.equal(value(m.special.acceleration.additionalDeduction),20);});
|
||||
test('lower optional normal quota remains valid L6 but is not treated as legally fixed rate in CBF16',()=>{const{d,b}=acceleration();b.depreciation.assets[0].rate='5';const m=calculateNormal(d,b);assert.equal(m.depreciation.assets[0].status,'calculated');assert.equal(m.special.acceleration.additionalDeduction,null);assert.match(m.special.acceleration.reason,/quota inferior/);});
|
||||
test('location alone, wrong activity, prior quotas, unsupported periods and benefit combinations cannot accelerate',()=>{for(const mutate of[b=>b.special.acceleration.cbfRequirements='',b=>b.special.acceleration.recognitionReference='',b=>b.special.acceleration.rows[0].kind='other',b=>b.depreciation.assets[0].timing='months',b=>b.depreciation.assets[0].previousAccounting='1',b=>b.special.acceleration.noOtherBenefits='no',b=>{b.special.cooperative={qualification:qualification('known','2026-01-01','2026-12-31'),kind:'agrarian',allIncomeEligible:'yes',withheldIncome:'absent'};}]){const{d,b}=acceleration();d.province_id='ZEE-candidate';mutate(b);const m=calculateNormal(d,b);assert.equal(m.special.acceleration.additionalDeduction,null);assert.notEqual(m.taxableProfit,null);assert.equal(m.special.acceleration.status,'indeterminate');}});
|
||||
test('save/recover/report preserves9history and L5/books; repeated calculation never accumulates tax or asset deduction',()=>{const{d,b}=expenses(),old=structuredClone(b.result),plan=d.business_plan_snapshot;d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,b,'2026-10-26T14:00:00+02:00'));let back=normalBook(JSON.parse(JSON.stringify(d)));assert.equal(normalCurrent(d,back),true);assert.deepEqual(back.history.at(-1),old);assert.equal(d.business_plan_snapshot,plan);assert.ok(JSON.parse(d.modelo_a_snapshot).irpcWithholdings);const html=normalHtml(d);assert.match(html,/imposto autónomo:35/);assert.match(html,/novo ajustamento ao lucro:0/);assert.match(html,/Saldo final a pagar\/recuperar:Indeterminado/);assert.match(JSON.stringify(createProjectDossierReport(d,{selectedSections:new Set(['finance'])})),/Despesas — imposto autónomo/);d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,back));back=normalBook(d);assert.equal(value(back.result.model.special.expenses.autonomousTax),35);assert.equal(value(back.result.model.taxableProfit),3230);d.province_id='changed';assert.equal(normalCurrent(d,normalBook(d)),false);assert.throws(()=>normalHtml(d),/Calcule/);});
|
||||
test('new evidence changes key; malformedqualification or duplicate row ID cannot overwrite book',()=>{const{d,b}=expenses();d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,b));const back=normalBook(d);back.special.expenses.rows[0].reference+=' alterado';assert.equal(normalCurrent(d,back),false);back.special.expenses.rows.push(structuredClone(back.special.expenses.rows[0]));assert.throws(()=>saveNormalBook(d,back),/identificador repetido/);});
|
||||
test('report presents context labels and retains provenance internally without dumping raw context snapshots',()=>{const{d,b}=setup();d.province_id_label='Província QA';d.context_opportunity_snapshot='{"internal":"QA implementation blob"}';d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,b));assert.match(normalHtml(d),/Província: Província QA/);assert.doesNotMatch(normalHtml(d),/QA implementation blob/);assert.equal(normalBook(d).result.model.special.context.context_opportunity_snapshot,d.context_opportunity_snapshot);});
|
||||
test('write only new QA cases for transactional API and recovered reports',()=>{const missing=expenses(),negative=expenses();missing.b.special.expenses.rows[0].nature='';negative.b.special.expenses.rows[0].eligible='no';const cases={expense:expenses(),missing,negative,absent:setup(),cooperative:cooperative(),acceleration:acceleration()};fs.mkdirSync('outputs/irpc-l7-common',{recursive:true});for(const[name,{d,b}]of Object.entries(cases)){d.modelo_a_snapshot=saveNormalBook(d,recordNormal(d,b,'2026-10-26T14:00:00+02:00'));fs.writeFileSync('outputs/irpc-l7-common/'+name+'.json',JSON.stringify(d));fs.writeFileSync('outputs/irpc-l7-common/'+name+'.html',normalHtml(d));}});
|
||||
@@ -100,7 +100,7 @@ void test('reconciled navigation selects discovery, realization and private supp
|
||||
);
|
||||
assert.equal(
|
||||
currentNavigationGroup(groups, '/simulador-fiscal'),
|
||||
'realization',
|
||||
'discovery',
|
||||
);
|
||||
assert.equal(
|
||||
currentNavigationGroup(groups, '/balcao-virtual/dossiers/fixture'),
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
$root=dirname(__DIR__);
|
||||
$operation=$argv[1]??'';
|
||||
if(!in_array($operation,['routes','test'],true)||basename($root)!=='portal-investidor-irpc-l7-common-qa-20261026')throw new RuntimeException('Explicit L7 QA workspace and routes/test operation required.');
|
||||
foreach(['storage/framework/views','storage/framework/cache','storage/framework/sessions','bootstrap/cache','storage/logs','outputs/irpc-l7-common']as$dir)if(!is_dir($root.'/'.$dir))mkdir($root.'/'.$dir,0700,true);
|
||||
foreach(['APP_BASE_PATH'=>$root,'APP_ENV'=>'testing','APP_KEY'=>'base64:'.base64_encode(str_repeat('Q',32)),'DB_CONNECTION'=>'pgsql','DB_HOST'=>'127.0.0.1','DB_PORT'=>'55441','DB_DATABASE'=>'simulator_fiscal_delta_20261021_test','DB_USERNAME'=>'postgres','DB_PASSWORD'=>'','DB_URL'=>'','CACHE_STORE'=>'array','SESSION_DRIVER'=>'array','QUEUE_CONNECTION'=>'sync','MAIL_MAILER'=>'array'] as $k=>$v){putenv($k.'='.$v);$_ENV[$k]=$_SERVER[$k]=$v;}
|
||||
$loader=require $root.'/vendor/autoload.php';
|
||||
spl_autoload_register(function($class)use($root){foreach(['App\\'=>'app/','Tests\\'=>'tests/','Database\\Factories\\'=>'database/factories/']as$prefix=>$dir){if(str_starts_with($class,$prefix)){$file=$root.'/'.$dir.str_replace('\\','/',substr($class,strlen($prefix))).'.php';if(is_file($file)){require $file;return;}}}},true,true);
|
||||
$app=require $root.'/bootstrap/app.php';
|
||||
(new Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables)->bootstrap($app);
|
||||
(new Illuminate\Foundation\Bootstrap\LoadConfiguration)->bootstrap($app);
|
||||
$c=config('database.connections.pgsql');
|
||||
if($app->configurationIsCached()||$c['host']!=='127.0.0.1'||(int)$c['port']!==55441||$c['database']!=='simulator_fiscal_delta_20261021_test'||!empty($c['url']))throw new RuntimeException('QA guard');
|
||||
$pdo=new PDO('pgsql:host=127.0.0.1;port=55441;dbname='.$c['database'],$c['username'],$c['password']);
|
||||
if($pdo->query('select current_database()')->fetchColumn()!==$c['database'])throw new RuntimeException('QA identity');
|
||||
if($operation==='routes'){
|
||||
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
|
||||
$status=Illuminate\Support\Facades\Artisan::call('wayfinder:generate',['--with-form'=>true]);
|
||||
echo Illuminate\Support\Facades\Artisan::output();exit($status);
|
||||
}
|
||||
$argv=['phpunit','-c','phpunit.investmoz.xml','tests/Feature/IrpcSpecialDraftTest.php'];$argc=count($argv);$_SERVER['argv']=$argv;$_SERVER['argc']=$argc;require $root.'/vendor/phpunit/phpunit/phpunit';
|
||||
Reference in New Issue
Block a user