Group L1 coverage and implement documented service exemptions in QA

This commit is contained in:
2026-10-24 13:54:32 +02:00
parent 8719e916ea
commit 5030116ee5
7 changed files with 658 additions and 137 deletions
@@ -4456,5 +4456,427 @@
"types.txt": "82962651e47f564de653ad2883f8fd34e7dae4b4468e4ac459cb3331962a3879",
"build.txt": "1b5d6b7aeaec4839a52d16661dd40eacb20b8c3f77ed723d09c78a08d7f8d50c"
}
},
"iva_l1_grouped_increment_qa_20261024": {
"status": "grouped_inventory_133;G1_four_services_QA;final_Word_and_native_PDF_verified;L1_open",
"candidate": null,
"preserved_candidate": "689e7cbe",
"preserved_record": "8719e916",
"earlier_candidate_preserved": "544068e8",
"grouping": {
"functional_increments": 11,
"documentary_dependencies": 1,
"total_branches": 133,
"implemented_in_this_increment": 4,
"remaining_functional_branches": 128,
"remaining_documentary_branch": 1,
"groups": [
{
"id": "G1",
"title": "Serviços isentos por natureza e condições",
"shared_data": "Prestação/entidade, sujeição a Selo quando exigida, período, contraprestação e documento/pressuposto",
"next_step": "Executável em QA: quatro operações, sem calcular Selo",
"dependency_rule": "Cálculo/gravação/recuperação/relatório num único incremento",
"count": 4,
"rows": [
"AUD-SIM-L1-P017",
"AUD-SIM-L1-P018",
"AUD-SIM-L1-P029",
"AUD-SIM-L1-P030"
]
},
{
"id": "G2",
"title": "Outras isenções internas e listas de produtos",
"shared_data": "Natureza do bem/serviço, entidade elegível, posição de anexo, afectação, renúncia quando aplicável",
"next_step": "Próximo: núcleo de classificação de produtos/entidades; anexos/renúncia só nos ramos dependentes",
"dependency_rule": "Reutiliza G1; taxas não são inferidas do sector",
"count": 32,
"rows": [
"AUD-SIM-L1-P003",
"AUD-SIM-L1-P004",
"AUD-SIM-L1-P005",
"AUD-SIM-L1-P006",
"AUD-SIM-L1-P007",
"AUD-SIM-L1-P008",
"AUD-SIM-L1-P009",
"AUD-SIM-L1-P010",
"AUD-SIM-L1-P011",
"AUD-SIM-L1-P012",
"AUD-SIM-L1-P013",
"AUD-SIM-L1-P014",
"AUD-SIM-L1-P015",
"AUD-SIM-L1-P016",
"AUD-SIM-L1-P019",
"AUD-SIM-L1-P020",
"AUD-SIM-L1-P021",
"AUD-SIM-L1-P022",
"AUD-SIM-L1-P023",
"AUD-SIM-L1-P024",
"AUD-SIM-L1-P025",
"AUD-SIM-L1-P026",
"AUD-SIM-L1-P027",
"AUD-SIM-L1-P028",
"AUD-SIM-L1-P031",
"AUD-SIM-L1-P032",
"AUD-SIM-L1-P033",
"AUD-SIM-L1-P034",
"AUD-SIM-L1-P035",
"AUD-SIM-L1-P036",
"AUD-SIM-L1-P037",
"AUD-SIM-L1-P044"
]
},
{
"id": "G3",
"title": "Benefícios temporários e transições",
"shared_data": "Operação, data, início/fim do benefício e alteração expressa",
"next_step": "Açúcar/óleo/sabões: texto integral Lei3/2025; solar: termo31/12/2025 e eventual alteração expressa",
"dependency_rule": "A pendência temporal não bloqueia G1/G2 independentes",
"count": 7,
"rows": [
"AUD-SIM-L1-P038",
"AUD-SIM-L1-P039",
"AUD-SIM-L1-P040",
"AUD-SIM-L1-P041",
"AUD-SIM-L1-P042",
"AUD-SIM-L1-P043",
"AUD-SIM-L1-P045"
]
},
{
"id": "G4",
"title": "Exportações e operações assimiladas",
"shared_data": "Saída/destino, transportador, adquirente, embarcação/aeronave e documento de suporte",
"next_step": "Prosseguir por perfis de exportação/transporte/intermediação com condições documentadas",
"dependency_rule": "Uma estrutura de evidência e vínculo à operação; não19 desenvolvimentos",
"count": 19,
"rows": [
"AUD-SIM-L1-P061",
"AUD-SIM-L1-P062",
"AUD-SIM-L1-P063",
"AUD-SIM-L1-P064",
"AUD-SIM-L1-P065",
"AUD-SIM-L1-P066",
"AUD-SIM-L1-P067",
"AUD-SIM-L1-P068",
"AUD-SIM-L1-P069",
"AUD-SIM-L1-P070",
"AUD-SIM-L1-P071",
"AUD-SIM-L1-P072",
"AUD-SIM-L1-P073",
"AUD-SIM-L1-P074",
"AUD-SIM-L1-P075",
"AUD-SIM-L1-P076",
"AUD-SIM-L1-P077",
"AUD-SIM-L1-P078",
"AUD-SIM-L1-P079"
]
},
{
"id": "G5",
"title": "Regimes aduaneiros/fiscais especiais e ofertas",
"shared_data": "Regime autorizado, beneficiário, localização, finalidade e permanência",
"next_step": "Cotejar benefício concreto e suas condições, sem inferência de isenção pela localização",
"dependency_rule": "Reutiliza relações territoriais/documentos; sem nova validação genérica de fonte",
"count": 7,
"rows": [
"AUD-SIM-L1-P080",
"AUD-SIM-L1-P081",
"AUD-SIM-L1-P082",
"AUD-SIM-L1-P083",
"AUD-SIM-L1-P084",
"AUD-SIM-L1-P085",
"AUD-SIM-L1-P086"
]
},
{
"id": "G6",
"title": "Isenções na importação",
"shared_data": "Documento aduaneiro, código, origem, regime, beneficiário e finalidade",
"next_step": "Classificação em L1; IVA/documento/deduçãoL2 e direitosL13 preservam os lotes próprios",
"dependency_rule": "Sem bloquear operações internas por depender de importação",
"count": 15,
"rows": [
"AUD-SIM-L1-P046",
"AUD-SIM-L1-P047",
"AUD-SIM-L1-P048",
"AUD-SIM-L1-P049",
"AUD-SIM-L1-P050",
"AUD-SIM-L1-P051",
"AUD-SIM-L1-P052",
"AUD-SIM-L1-P053",
"AUD-SIM-L1-P054",
"AUD-SIM-L1-P055",
"AUD-SIM-L1-P056",
"AUD-SIM-L1-P057",
"AUD-SIM-L1-P058",
"AUD-SIM-L1-P059",
"AUD-SIM-L1-P060"
]
},
{
"id": "G7",
"title": "Bases especiais e composição da contraprestação",
"shared_data": "Preço/margem/custo, comissão, descontos, encargos, moeda e datas",
"next_step": "Implementar um motor de composição por fórmula; dados adicionais só quando a fórmula os exige",
"dependency_rule": "Dedução proporcional continuaL2; fonte/fórmula/período por alínea",
"count": 18,
"rows": [
"AUD-SIM-L1-P087",
"AUD-SIM-L1-P088",
"AUD-SIM-L1-P089",
"AUD-SIM-L1-P090",
"AUD-SIM-L1-P091",
"AUD-SIM-L1-P092",
"AUD-SIM-L1-P093",
"AUD-SIM-L1-P094",
"AUD-SIM-L1-P095",
"AUD-SIM-L1-P096",
"AUD-SIM-L1-P097",
"AUD-SIM-L1-P098",
"AUD-SIM-L1-P099",
"AUD-SIM-L1-P100",
"AUD-SIM-L1-P101",
"AUD-SIM-L1-P102",
"AUD-SIM-L1-P103",
"AUD-SIM-L1-P104"
]
},
{
"id": "G8",
"title": "Territorialidade de bens e serviços materiais",
"shared_data": "Lugar dos bens/execução/imóvel, prestador/adquirente, EP e trajecto",
"next_step": "Prosseguir pelas regras territoriais específicas, consolidando alterações2025 nas cláusulas afectadas",
"dependency_rule": "Imóveis e transporte reutilizam localização; não cliente estrangeiro→campo06",
"count": 7,
"rows": [
"AUD-SIM-L1-P002",
"AUD-SIM-L1-P105",
"AUD-SIM-L1-P106",
"AUD-SIM-L1-P107",
"AUD-SIM-L1-P108",
"AUD-SIM-L1-P109",
"AUD-SIM-L1-P110"
]
},
{
"id": "G9",
"title": "Serviços transfronteiriços e digitais",
"shared_data": "Natureza, residência/EP, destinatário/utilização e responsável pela liquidação",
"next_step": "Consolidar Lei10/2025 e obrigações/autoliquidação por operação",
"dependency_rule": "Uma identificação comum de partes/localização; especialidades digitais delimitadas",
"count": 11,
"rows": [
"AUD-SIM-L1-P111",
"AUD-SIM-L1-P112",
"AUD-SIM-L1-P113",
"AUD-SIM-L1-P114",
"AUD-SIM-L1-P115",
"AUD-SIM-L1-P116",
"AUD-SIM-L1-P117",
"AUD-SIM-L1-P118",
"AUD-SIM-L1-P119",
"AUD-SIM-L1-P120",
"AUD-SIM-L1-P121"
]
},
{
"id": "G10",
"title": "Operações assimiladas e especiais",
"shared_data": "Comissão, stocks, uso próprio, gratuitidade, unidade de negócio e histórico de dedução",
"next_step": "Prosseguir por perfis de operação e critérios de incidência/valoração documentados",
"dependency_rule": "Não exigir todos os campos a uma venda normal",
"count": 9,
"rows": [
"AUD-SIM-L1-P122",
"AUD-SIM-L1-P123",
"AUD-SIM-L1-P124",
"AUD-SIM-L1-P125",
"AUD-SIM-L1-P126",
"AUD-SIM-L1-P127",
"AUD-SIM-L1-P128",
"AUD-SIM-L1-P129",
"AUD-SIM-L1-P130"
]
},
{
"id": "G11",
"title": "Facto gerador e período fiscal",
"shared_data": "Entrega, execução, factura, recebimento, antecipação e duração",
"next_step": "Implementar calendário comum de eventos com regras por perfil",
"dependency_rule": "Mês orçamental não é automaticamente período de exigibilidade",
"count": 3,
"rows": [
"AUD-SIM-L1-P131",
"AUD-SIM-L1-P132",
"AUD-SIM-L1-P133"
]
},
{
"id": "D06",
"title": "Correspondência declarativa do campo06",
"shared_data": "Edição e instrução que distinga05/06 nos exemplares recebidos",
"next_step": "Pendente documental específico; não bloquear os onze grupos",
"dependency_rule": "Sem substituir remissão legal por inferência de layout",
"count": 1,
"rows": [
"AUD-SIM-L1-P001"
]
}
],
"meaning": "Shared rules/data per increment; not133developments or approvals",
"matrix": "docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv",
"new_rows": 0,
"existing_rows_updated": 133,
"parent": "AUD-SIM-INT02"
},
"G1": {
"rows": [
"AUD-SIM-L1-P017",
"AUD-SIM-L1-P018",
"AUD-SIM-L1-P029",
"AUD-SIM-L1-P030"
],
"treatments": [
"financial_stamp",
"insurance_stamp",
"public_waste",
"public_funeral"
],
"scope": "2026/MZN; conditions and evidence required per operation; field07 without automatic purchase deduction",
"source": "Lei22/2022 art1, CIVA9(4),9(6),9(12)(b)/(c), PDF2 p2252(26); publicentity10(1) samepage; CIVA19(1),2016 PDF15 p1426(273)",
"additional_information": "Treatment choice and confirmation of specific conditions using existing controls; reuse opportunity,original currency,establishment,period,price representation and evidence",
"Selo": "Documented subjection condition only; Selo calculation remainsL12 and does not blockG1"
},
"D06": {
"status": "specific_documentary_dependency_not_resolved",
"missing": "Instruction applicable to supplied edition distinguishing fields05/06 or express applicable administrative mapping",
"independent_operations_blocked": false
},
"preservation": {
"catalogue_key": "Only rules actually used; accepts prior full-catalogue key. Independent extension leaves accepted rational snapshot current and byte-identical without recalculation. Changed inputs/context/used-source invalidate the correspondence.",
"accepted_ten_treatments_retested": false,
"accepted_rational_calculation_repeated": false,
"exporters_changed": false,
"experimental_pagination_change": "Removed after enlarged rendering disproved initial overlap suspicion; no pagination regression claimed",
"previous_receipt_keys_unchanged": true,
"legacy_key_members": "Frozen12originaltreatmentIDs; future unrelated catalogue extension tested without recalculating accepted snapshot"
},
"proofs": {
"frontend_tests": 2,
"frontend_status": "passed",
"private_API_tests": 1,
"API_assertions": 11,
"API_status": "passed",
"database": "simulator_fiscal_delta_20261021_test:55441",
"rollback": true,
"actual_UI": "Real SimulationOperations component in isolated synthetic harness18627; missingSelo condition -> indeterminate, restored ->400MZN field07; UI snapshot used by private API and recovered identically",
"types": "passed",
"build": "passed",
"build_warning": "Optionalfontaine missing; build succeeded",
"native_PDF_renderer": "MicrosoftEdge headless print of actual application exporter",
"Word_renderer": "LibreOffice25.8.3.1 opens actualDOCX; PDF pages rasterized by PyMuPDF1.25",
"render_limitations": [
"Bundled render_docx helper initially failed ModuleNotFoundError:pdf2image; used direct LibreOffice conversion+PyMuPDF",
"MicrosoftWord COM attempt did not complete; no claim of MicrosoftWord-engine proof",
"LibreOffice reports platform-independent-library warning but exits0 and renders all pages"
],
"visual_review": "All18pages visually inspected (native7+3, DOCX6+2). FinalDOCX renders pixel-identical to reviewed pages. Native final pages reviewed; enlarged crops resolve reduced-preview artefacts.",
"formats": {
"rational-native": {
"file": "rational-final.pdf",
"pages": 7,
"sha256": "af27fa65c2af09c261ecb9f64e33e1099b979ca0203f99654408c0d97b165da0",
"tokens": [
"20/21",
"1/21",
"10102/105",
"5051/1050",
"0.047619",
"4.810476",
"Manica",
"MZN",
"2026-01"
]
},
"rational-word": {
"file": "word-render\\rational-checked.pdf",
"pages": 6,
"sha256": "5f8e5057388391dc1794b0eea6d6c792dfa2bb6e006be661addd5f5ce670d47a",
"tokens": [
"20/21",
"1/21",
"10102/105",
"5051/1050",
"0.047619",
"4.810476",
"Manica",
"MZN",
"2026-01"
]
},
"services-native": {
"file": "services-final.pdf",
"pages": 3,
"sha256": "9e8fe2d9b96b93613741f255c585479079d19792eda26d0737f8519b35c10ff2",
"tokens": [
"financial_stamp",
"insurance_stamp",
"public_waste",
"public_funeral",
"400.00",
"Manica",
"MZN"
]
},
"services-word": {
"file": "word-render\\services-checked.pdf",
"pages": 2,
"sha256": "ef489dadf4c32eacc58e8d04671c4783f83f5a0a12075c5f040ca6f5a4f22cad",
"tokens": [
"financial_stamp",
"insurance_stamp",
"public_waste",
"public_funeral",
"400.00",
"Manica",
"MZN"
]
}
},
"actual_UI_reload": "Revision3,Manica,MZN andfield07=400 preserved after reload; screenshotqa-result.png"
},
"QA_runtime": "Official DocumentFoundation archive MSI; Authenticode Valid, signer TheDocumentFoundation; administrative extraction into ignored outputs only, no system installation",
"limits": [
"L1 remains open;128functional branches +D06 pending",
"No homologation integration/deployment",
"No new fiscal tax/rate or published-rule activation",
"SISA/IPRA remain inventoried with separate effort;544-912h estimate preliminary"
],
"active_changes": false,
"schema_or_permission_changes": false,
"homologation_delivery": false,
"artifacts": {
"group-plan.json": "d337b04a8402aece40327cd830a68a230b8ea8c007645ebbc8925f9aa6a25ae4",
"ui-calculated.json": "9204723c3fde6440ffdcd1ddb10a4a5fab8acba9879d68cda1236f73dc19b8d0",
"recovered.json": "8b215b97f4044d259a6f6d0075738591eccb4a1abd1b06cd4f819d5d83c430d2",
"frontend-tests.txt": "056781c35ca74d03eeeee1c16f706117ce605e22106dc7040c57269b534fddc3",
"api-tests.xml": "27d9c6eeca4564c72fd12726500f76505e02f3f0f7f6365b6132bc47162c74c9",
"api-tests-ui.txt": "1bd41594555bc7d92c77551dbdc8df4c02566ea93e7a5368825e5348736c3166",
"rational-checked.docx": "438c6b86437d3a3fce49924012800a8b68bc1e1b54a4783aa5b382ff1f155c36",
"services-checked.docx": "47bb45ec7a21c24138a2c4ebe46e8196e4155ca157dac7627cd1aff30d251b8c",
"rational-final.pdf": "af27fa65c2af09c261ecb9f64e33e1099b979ca0203f99654408c0d97b165da0",
"services-final.pdf": "9e8fe2d9b96b93613741f255c585479079d19792eda26d0737f8519b35c10ff2",
"word-render/rational-checked.pdf": "5f8e5057388391dc1794b0eea6d6c792dfa2bb6e006be661addd5f5ce670d47a",
"word-render/services-checked.pdf": "ef489dadf4c32eacc58e8d04671c4783f83f5a0a12075c5f040ca6f5a4f22cad",
"final-render.json": "85c5f1175e7914b4b153967ac3041f245bac0acb292d4f85e7b5f29fa2087363",
"visual-comparison.json": "939d739db853feb1a9b2055547a21765cce1e86d1316c2f8feee9c6f36739035",
"types.txt": "5346ac8a6566c1c38cb0bbda6a029579df58cd78af78e2c4845d9c82b5d1d76c",
"build.txt": "0cc11857f1eb65c25f2209d41b7defb82482f396f3616819970da9f2f98f973c",
"checks.json": "f366fb2d17bd44e91ee7642dd28e935d71f574652e62868f612a83de257eacea",
"qa-recovered.png": "00a9deb00cbad607fc58fe2252ed96b385f7d2b3a1e9b749621a90faf096ffa6",
"qa-result.png": "350f12a8f2abd57c907eee2f93991e4ff06432afe3624dd08f089026f59edd2c"
}
}
}
@@ -1,5 +1,45 @@
# Rastreabilidade, utilização e formação
## 24/10/2026 — L1: incrementos por regras/dados comuns e primeiro grupo executável
**Continuação exclusivamente em QA, sobre `689e7cbe`/registo `8719e916`. L1 aberto; homologação inalterada.** Os 133 ramos foram distribuídos, sem duplicação, por onze incrementos funcionais e uma dependência documental. Não são 133 desenvolvimentos nem 133 aprovações. A correspondência individual está na mesma matriz, coluna «Grupo de execução», linhas `AUD-SIM-L1-P001`–`P133`; não foi criada outra matriz/backlog.
| Grupo | Ramos | Regra/dados comuns e próximo incremento |
| --- | ---: | --- |
| G1 — serviços isentos | 4 | Executável em QA: natureza do serviço, entidade, sujeição a Selo quando exigida, fundamento, preço e período. |
| G2 — outras isenções internas | 32 | Classificação de bens/serviços e entidades, anexos, afectação e renúncia apenas quando aplicáveis. Próximo núcleo de classificação. |
| G3 — benefícios temporários | 7 | Calendário, início/termo e alteração expressa. Texto integral Lei3/2025 para açúcar/óleo/sabões; solar com termo31/12/2025, sem presumir prorrogação. |
| G4 — exportações/assimiladas | 19 | Destino, transportador/adquirente, embarcação/aeronave e documentos; perfis partilhados de exportação, transporte e intermediação. |
| G5 — regimes especiais/ofertas | 7 | Regime, beneficiário, localização e finalidade; condições específicas do benefício, sem isenção inferida do mapa. |
| G6 — isenções na importação | 15 | Documento aduaneiro, código, origem, regime e destino. Classificação L1; dedução/documento L2 e direitos L13 conservam âmbito próprio. |
| G7 — bases especiais | 18 | Motor comum de composição: preço/margem/custo, descontos, encargos, comissão, moeda e datas; fórmula por alínea. |
| G8 — territorialidade material | 7 | Lugar dos bens/execução/imóvel, partes/estabelecimento e trajecto; consolidar alterações apenas nas cláusulas afectadas. |
| G9 — transfronteiriços/digitais | 11 | Natureza, residência/estabelecimento, destinatário/utilização e responsável pela liquidação; consolidar Lei10/2025 por operação. |
| G10 — assimiladas/especiais | 9 | Perfis de comissão, stocks, uso próprio, gratuitidade e transmissão de negócio; histórico de dedução quando necessário. |
| G11 — exigibilidade/período | 3 | Calendário comum de entrega, execução, factura, pagamento e adiantamento; mês orçamental não determina sozinho o período fiscal. |
| D06 — correspondência do formulário | 1 | Falta a instrução da edição recebida que distinga05/06 ou correspondência administrativa expressa aplicável. Não bloqueia grupos independentes. |
Sequência proposta após G1: G2 e perfis documentados de G4; G8/G11 para localização e período; G7/G10; G5/G6/G9 conforme a dependência concreta. G3 avança nas operações cuja regra temporal esteja determinada. D06 mantém trilho documental próprio. Cada incremento percorre dados → condições → cálculo/não aplicação/indeterminação → gravação → recuperação → relatório. As linhas conservam as dependências específicas; a tabela não as substitui. A estimativa544–912h continua preliminar, a rever por reaproveitamento medido; não se multiplica por133. SISA/IPRA continuam inventariados, com esforço separado.
### G1 — quatro tratamentos, um incremento comum
Linhas `P017`, `P018`, `P029`, `P030`: operações bancárias/financeiras sujeitas a Selo; seguro/resseguro/mediação conexa sujeitos a Selo; remoção de lixo por entidade pública ou por ela contratada; serviços funerários/cremação e bens acessórios efectuados por entidade pública. Fonte: **Lei22/2022, art.1, CIVA art.9(4),9(6),9(12)(b)/(c), PDF2, p.2252(26)**; natureza de entidade pública definida em10(1), na mesma página; direito à dedução confrontado com CIVA19(1), republicação2016 PDF15, p.1426(273). Aplicação técnica delimitada a2026/MZN, sem alterar taxa/regra fiscal nem activar regra publicada no servidor.
Reutilizados oportunidade, moeda original, estabelecimento, período, preço/representação e documento/pressuposto. Os únicos dados específicos são a escolha do tratamento e a confirmação fundamentada das suas condições, nos controlos já existentes. A sujeição a Selo é condição nas duas operações que a exigem; o cálculo de Selo não integra G1 nem é dependência técnica deste enquadramento. Não se presume isenção de toda a entidade, nem de funerárias privadas ou qualquer serviço de limpeza. Dados insuficientes produzem indeterminação, não zero. Campo07 apenas nas operações enquadradas; sem dedução automática de compras.
Provas novas: dois testes frontend; um teste API/11asserções, transacção revertida em `simulator_fiscal_delta_20261021_test:55441`. No componente real em QA, retirada a condição de Selo: operação/totais indeterminados; reposta: quatro linhas de100MZN, campo07=400MZN e IVA0. O resultado de interface foi guardado/recuperado pela API privada, sem diferença no snapshot, e usado nos exportadores reais. Os dez tratamentos aceites não foram reensaiados.
Preservação: a chave de actualidade passa a depender das regras efectivamente usadas, aceitando também a chave do catálogo anterior. Adicionar regras independentes não invalida o snapshot racional aceite. Teste dirigido confirma que permanece actual e byte a byte inalterado, sem recálculo; alterações das entradas/contexto continuam a invalidar a correspondência.
### Formatos finais — conferência e limite
Conferência dos DOCX produzidos pelo exportador existente e dos PDFs nativos do percurso de impressão, usando o snapshot racional já aceite e o novo resultado G1 recuperado. A suspeita inicial de corte/sobreposição foi afastada pela renderização ampliada: os originais estão legíveis. A alteração experimental de paginação foi retirada, sem mudança nos exportadores. Não se declara uma regressão nem uma correcção inexistente.
Os resultados exactos `20/21`, `1/21`, total base `10102/105` e IVA `5051/1050`, os decimais de apresentação `0.047619`/`4.810476`, MZN, oportunidade Manica, período, fonte e versão permanecem nos ficheiros finais. Prova concluída: DOCX efectivamente renderizados em LibreOffice25.8.3.1 (seis páginas racional, duas G1), com todas as páginas inspeccionadas; PDF nativo Edge (sete páginas racional, três G1). Não se afirma renderização pelo Microsoft Word: a automação local desse programa não terminou; o renderizador alternativo abriu os DOCX reais. O auxiliar bundled falhou inicialmente por falta de pdf2image; usaram-se conversão LibreOffice e renderização PyMuPDF. O registo identifica ficheiros e hashes.
**Saldo:** G1 com quatro ramos executáveis em QA;128ramos funcionais nos outros dez grupos e uma pendência D06. Agrupamento não equivale a implementação dos restantes. Não se declara L1 concluído nem disponibilizado na homologação. Fechos anteriores preservados; IRPC/IRPS e restantes lotes mantêm o plano acordado.
## 24/10/2026 — delta L1: precisão racional, cotejo do campo06 e inventário por operação
**Incremento em QA, candidata `689e7cbe`, sem integração/homologação.** Preservados candidata `544068e8`, registo `d89912e5` e as provas dos dez tratamentos. A Tempo apreciou o relatório comunicado; não lhe é atribuída conferência do manual ou da demonstração. L1 continua aberto. As referências abaixo actualizam os limites correntes, conservando o histórico anterior.
File diff suppressed because one or more lines are too long
+9 -2
View File
@@ -3,6 +3,9 @@ import { monthlySalesFromDraft, readMonthlyIvaSettings } from './monthly-iva.ts'
import { addFractions, decimalFraction, fraction, fractionLabel, fractionPresentation, type FiscalFraction } from './fiscal-rational.ts';
export const operationVersion = 'iva-operations-l1/2';
// The accepted v2 full-catalogue key predates scoped keys. Freeze its members
// so later, independent catalogue additions cannot invalidate those snapshots.
const legacyV2TreatmentIds = ['general','private_health','private_education','private_training','personal_lessons','export_goods','housing_rent','public_health','public_education','public_training','foreign_operation','other'];
const source2022 = 'Lei22/2022, BR250, 2.º suplemento, PDF1–4 (2252(25)–(28)); arts.1/2/6; efeitos01/01/2023';
const source2016 = 'CIVA republicado Lei13/2016, BR156, 10.º suplemento, PDF9–15 (1426(267)–(273))';
const source2025 = 'Lei10/2025, BR248, suplemento1, PDF14–15 (2180(14)–(15)); arts.1/2/3/5; efeitos01/01/2026';
@@ -19,6 +22,10 @@ export const operationTreatments:OperationTreatment[] = [
{id:'public_health',label:'Serviços médicos e sanitários públicos',field:'07',rate:0,article:'CIVA arts.9(1)(a),10(1),19(1)',source:source2022,conditions:['Serviço médico/sanitário ou operação estreitamente conexa','Estabelecimento hospitalar público, dispensário ou similar; natureza pública confirmada']},
{id:'public_education',label:'Ensino público reconhecido',field:'07',rate:0,article:'CIVA arts.9(3)(a),10(1),19(1)',source:source2022,conditions:['Ensino ou fornecimentos conexos pelo estabelecimento','Estabelecimento público integrado no Sistema Nacional de Ensino e reconhecido pelo Ministério competente']},
{id:'public_training',label:'Formação profissional pública',field:'07',rate:0,article:'CIVA arts.9(3)(b),10(1),19(1)',source:source2022,conditions:['Formação profissional ou fornecimentos conexos pelo prestador','Prestador público']},
{id:'financial_stamp',label:'Operação bancária/financeira sujeita a Selo',field:'07',rate:0,article:'CIVA art.9(4), redacção Lei22/2022; art.19(1)',source:`${source2022}; ${source2016}`,conditions:['A operação é bancária ou financeira, não um serviço acessório autónomo','Sujeição a Imposto do Selo identificada para esta operação; não depende de calcular o Selo neste bloco']},
{id:'insurance_stamp',label:'Seguro/resseguro ou mediação conexa sujeitos a Selo',field:'07',rate:0,article:'CIVA art.9(6), redacção Lei22/2022; art.19(1)',source:`${source2022}; ${source2016}`,conditions:['Seguro/resseguro ou serviço conexo efectuado por corrector ou outro mediador de seguros','Sujeição a Imposto do Selo identificada para esta operação']},
{id:'public_waste',label:'Remoção de lixo pública ou por entidade contratada',field:'07',rate:0,article:'CIVA art.9(12)(b), redacção Lei22/2022; art.19(1)',source:`${source2022}; ${source2016}`,conditions:['Prestação de serviço de remoção de lixo, não qualquer serviço de limpeza','Efectuada por entidade pública ou por entidade por ela contratada, com relação identificada']},
{id:'public_funeral',label:'Serviços funerários/cremação públicos e bens acessórios',field:'07',rate:0,article:'CIVA art.9(12)(c), redacção Lei22/2022; art.19(1)',source:`${source2022}; ${source2016}`,conditions:['Serviço funerário/cremação ou transmissão de bem acessório a esse serviço','Efectuado por entidade pública; não aplicar automaticamente a funerária privada']},
{id:'foreign_operation',label:'Operação no estrangeiro — analisar territorialidade',field:null,rate:null,article:'CIVA art.6: localização por natureza da operação; art.19(1)(b)(ii) não determina sozinho a caixa06 do formulário',source:source2016,conditions:[]},
{id:'other',label:'Outra operação / enquadramento ainda desconhecido',field:null,rate:null,article:'Fundamento específico ainda necessário; não presumir taxa ou isenção',source:'Sem fonte operacional determinada para esta linha',conditions:[]},
];
@@ -79,8 +86,8 @@ export function evaluateSalesOperation(row:SalesOperation,currency:string):Sales
else vat=(n*BigInt(rule.rate)+50n)/100n;
return {...result,net:money(net),vat:money(vat),gross:money(row.basis==='included'?n:net+vat),status:rule.rate===0?'exempt':'calculated',reason:rule.rate===0?(rule.field==='05'?'Isenção com direito à dedução nas condições legais; não é taxa zero nem dedução automática de compras.':'Isenção sem direito à dedução para esta operação; não é isenção geral da entidade.'):'IVA da operação projectada; não é imposto final a pagar nem declaração submetida.'};
}
function key(draft:Record<string,unknown>,book:SalesBook):string {return JSON.stringify([operationVersion,operationTreatments,acquisitionScope(draft),draft.currency,draft.province_id,draft.district_id,draft.business_plan_snapshot,draft.cashflow_snapshot,draft.monthly_iva_settings,book.currency,book.rows,book.periods]);}
export function salesCurrent(draft:Record<string,unknown>,book:SalesBook):boolean {return !!book.result&&book.result.version===operationVersion&&book.result.opportunity===acquisitionScope(draft)&&book.result.key===key(draft,book);}
function key(draft:Record<string,unknown>,book:SalesBook,catalog=operationTreatments.filter(t=>book.rows.some(r=>r.treatment===t.id))):string {return JSON.stringify([operationVersion,catalog,acquisitionScope(draft),draft.currency,draft.province_id,draft.district_id,draft.business_plan_snapshot,draft.cashflow_snapshot,draft.monthly_iva_settings,book.currency,book.rows,book.periods]);}
export function salesCurrent(draft:Record<string,unknown>,book:SalesBook):boolean {return !!book.result&&book.result.version===operationVersion&&book.result.opportunity===acquisitionScope(draft)&&(book.result.key===key(draft,book)||book.result.key===key(draft,book,operationTreatments.filter(t=>legacyV2TreatmentIds.includes(t.id))));}
export function calculateSales(draft:Record<string,unknown>,book:SalesBook,now=new Date().toISOString()):SalesResult {
if(book.currency!=='MZN'||draft.currency!==book.currency)throw new Error('Confirme a moeda original MZN; sem conversão ou reinterpretação.');
if(new Set(book.rows.map(r=>r.id)).size!==book.rows.length||new Set(book.periods.map(p=>p.period)).size!==book.periods.length)throw new Error('Identificadores/períodos duplicados; corrija sem somar em duplicado.');
@@ -0,0 +1,30 @@
<?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 IvaServicesGroupDraftTest extends TestCase
{
use DatabaseTransactions;
public function test_services_group_round_trips_with_conditions_and_source(): 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()]));
$draft = json_decode(file_get_contents(getenv('IVA_G1_INPUT') ?: base_path('outputs/iva-l1-groups-20261024/calculated.json')), true, flags: JSON_THROW_ON_ERROR);
$id = $this->postJson('/api/v1/simulation-drafts', ['personal_snapshot' => [], 'economic_snapshot' => $draft], ['Idempotency-Key' => (string) Str::uuid()])->assertCreated()->json('data.id');
$recovered = $this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk()->json('data.economic_snapshot');
$this->assertSame($draft['modelo_a_snapshot'], $recovered['modelo_a_snapshot']);
$book = json_decode($recovered['modelo_a_snapshot'], true)['salesOperations']['opportunity:310'];
$this->assertCount(4, $book['result']['rows']);
$this->assertSame('400.00', $book['result']['periods'][0]['fields']['07']);
foreach ($book['result']['rows'] as $row) $this->assertSame('0.00', $row['vat']);
if (getenv('IVA_G1_RECOVERED')) file_put_contents(getenv('IVA_G1_RECOVERED'), json_encode($recovered, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE));
}
}
+22
View File
@@ -0,0 +1,22 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import fs from 'node:fs';
import {operationTreatments,newSalesOperation,evaluateSalesOperation,recordSales,saveSalesBook,salesBook,salesCurrent} from '../../resources/js/lib/iva-operations.ts';
import {createProjectDossierReport} from '../../resources/js/lib/project-dossier-report.ts';
const ids=['financial_stamp','insurance_stamp','public_waste','public_funeral'];
function fixture(){const draft={purpose:'simulate_only',currency:'MZN',context_opportunity:'opportunity:310',project_title:'SYNTHETIC QA — G1 serviços isentos',province_id:'cf5e81f1-ffbc-535d-b1b6-b44b445c4421',selection_labels:{province_id:'Manica'}};
let book={currency:'MZN',rows:ids.map((id,i)=>({...newSalesOperation(`g1-${i}`,'2026-01','MZN'),description:`SYNTHETIC QA ${id}`,establishment:'SYNTHETIC QA estabelecimento',amount:'100',basis:'net',treatment:id,confirmed:[0,1],evidence:'SYNTHETIC QA — condições documentadas pressupostas, sem certificação'})),periods:[{period:'2026-01',complete:true}]};book=recordSales(draft,book);draft.modelo_a_snapshot=saveSalesBook(draft,book);return {draft,book};}
test('G1 four documented operations use the same conditions and persistence, with independent applicability',()=>{
const {draft,book}=fixture();for(const row of book.rows){const r=evaluateSalesOperation(row,'MZN');assert.equal(r.vat,'0.00');assert.equal(r.field,'07');assert.match(r.article,/9\(/);assert.match(r.source,/Lei22/);assert.equal(evaluateSalesOperation({...row,confirmed:[0]},'MZN').vat,null);assert.equal(evaluateSalesOperation({...row,evidence:''},'MZN').vat,null);}
assert.equal(book.result.periods[0].fields['07'],'400.00');const recovered=JSON.parse(JSON.stringify(draft));assert.equal(salesCurrent(recovered,salesBook(recovered)),true);assert.match(JSON.stringify(createProjectDossierReport(recovered,{selectedSections:new Set(['finance'])})),/400\.00/);
assert.equal(salesCurrent({...recovered,currency:'USD'},salesBook(recovered)),false);
assert.equal(salesCurrent({...recovered,context_opportunity:'opportunity:309'},salesBook(recovered)),false);
const rule=operationTreatments.find(t=>t.id==='financial_stamp');const source=rule.source;
try{rule.source+=' — changed source';assert.equal(salesCurrent(recovered,salesBook(recovered)),false);}finally{rule.source=source;}
});
test('adding independent catalogue rules does not invalidate or recalculate accepted rational snapshots',()=>{
const draft=JSON.parse(fs.readFileSync(new URL('./fixtures/iva-rational.json',import.meta.url),'utf8'));const original=draft.modelo_a_snapshot;assert.equal(salesCurrent(draft,salesBook(draft)),true);assert.equal(draft.modelo_a_snapshot,original);assert.equal(operationTreatments.filter(t=>ids.includes(t.id)).length,4);
operationTreatments.push({...operationTreatments[0],id:'synthetic_future_independent'});
try{assert.equal(salesCurrent(draft,salesBook(draft)),true);assert.equal(draft.modelo_a_snapshot,original);}finally{operationTreatments.pop();}
});
if(process.env.IVA_G1_OUT)fs.writeFileSync(process.env.IVA_G1_OUT,JSON.stringify(fixture().draft,null,2));
+1 -1
View File
@@ -8,7 +8,7 @@ import {createProjectDossierReport} from '../../resources/js/lib/project-dossier
export function operationsFixture(){
const draft=closureFixture().draft;draft.project_title='SYNTHETIC QA — L1 operações IVA';draft.province_id='cf5e81f1-ffbc-535d-b1b6-b44b445c4421';draft.selection_labels={province_id:'Manica'};
const rows=operationTreatments.map((t,i)=>({...newSalesOperation(`qa-${i}`,'2026-01','MZN'),description:`SYNTHETIC QA ${t.label}`,establishment:'SYNTHETIC QA estabelecimento Manica',amount:t.id==='general'?'1161':'100',basis:t.id==='general'?'included':'net',treatment:t.id,confirmed:t.conditions.map((_,i)=>i),evidence:'SYNTHETIC QA — pressupostos de ensaio, não documento real'}));
const rows=operationTreatments.filter(t=>!['financial_stamp','insurance_stamp','public_waste','public_funeral'].includes(t.id)).map((t,i)=>({...newSalesOperation(`qa-${i}`,'2026-01','MZN'),description:`SYNTHETIC QA ${t.label}`,establishment:'SYNTHETIC QA estabelecimento Manica',amount:t.id==='general'?'1161':'100',basis:t.id==='general'?'included':'net',treatment:t.id,confirmed:t.conditions.map((_,i)=>i),evidence:'SYNTHETIC QA — pressupostos de ensaio, não documento real'}));
const book={currency:'MZN',rows,periods:[{period:'2026-01',complete:true}]};return {draft,book};
}
test('each enumerated treatment calculates only with its conditions, article and source',()=>{