From bd5166bd11fc8a1f037f632cd1fde50a72a986a4 Mon Sep 17 00:00:00 2001 From: nala Date: Wed, 21 Oct 2026 12:57:40 +0200 Subject: [PATCH 1/4] docs: record authorised fiscal rule publication and consumer activation --- ...-review-continuation-20261020-receipt.json | 440 ++++++++++++++++++ .../unification/traceability-and-manual.md | 18 + .../v2/auditoria-portal/matriz-requisitos.csv | 2 +- 3 files changed, 459 insertions(+), 1 deletion(-) diff --git a/docs/investmoz/simulations/integrated-review-continuation-20261020-receipt.json b/docs/investmoz/simulations/integrated-review-continuation-20261020-receipt.json index 11ebdbf4..ea8583c9 100644 --- a/docs/investmoz/simulations/integrated-review-continuation-20261020-receipt.json +++ b/docs/investmoz/simulations/integrated-review-continuation-20261020-receipt.json @@ -739,5 +739,445 @@ "fiscal_acceptance_column": true, "active_database_changed": false } + }, + "authorised_fiscal_rollout_execution_20261021": { + "recorded_utc": "2026-10-21T10:57:04.072315+00:00", + "authorisation": "Tempo authorised incorporating 4a4d1212 and the remaining source/rule registration, publication and consumer activation in current conversation", + "integrated_delta": "4a4d1212751726da6a71d465b3ea2266e720cf28", + "integration_completed": true, + "served_revision": { + "commit": "d3fe8a02ec7f5dcd01984c4f4a1eba18b5a0cf19", + "branch": "main", + "built_at": "2026-10-21T10:48:46.529930+00:00", + "manifest_sha256": "f417509cfa060240801c6a956a787a90d0e283c3c08e77b5be655d63394a4cb9" + }, + "team_merge": "d3fe8a02 includes 4a4d1212; fiscal files unchanged; additional team navigation/presentation changes preserved", + "backup_restore": { + "utc": "2026-10-21T10:43:03.077516+00:00", + "source_database": "teste_investidor", + "served_commit": "226fd308dd45d2805ef4678b20ca4398d7fef6c6", + "backup_directory": "/var/backups/investmoz/iva-rollout-20261021_104253", + "dump_sha256": "b37bf4aad0abd839bc81d70adf802535ad7738fabe75fda61d74f39dfc11e74b", + "dump_bytes": 4584693, + "environment_backup_sha256": "537eff52f0f28b83ccc56bf9a9b85c2d8fca1da2f678c30b929b46c67c09491b", + "environment_path": "/var/www/html/teste-investidor.tempo.co.mz/.env", + "restore_database": "iva_rollout_20261021_104253_test", + "restore_database_public_connect": false, + "restore_equal": true, + "table_count": 171, + "method": "Exported repeatable-read snapshot, custom pg_dump, isolated restore, all public table counts and canonical row hashes compared", + "active_data_writes": false, + "qa_fixture_imported": false + }, + "schema_operation": { + "utc": "2026-10-21T10:44:11.639087+00:00", + "operation": "Explicit authenticated destination schema application of reviewed QA DDL; QA migration not executed or weakened", + "authorisation": "Tempo current conversation", + "ssh_actor": "root", + "database": "teste_investidor", + "migration": "2026_10_21_130000_correct_fiscal_maintenance_actor_constraints", + "migration_sha256": "66102bc9f2f546c9a76df5c3cc03b0bf14e0b9f7afbcf4b2c75db6a047b223f9", + "ddl_sha256": "89125b27f5a8ce3855c9a4c0d8abe4e5821a298f54a8e084607212bc10956cd2", + "backup_directory": "/var/backups/investmoz/iva-rollout-20261021_104253", + "existing_rows_preserved": true, + "unrelated_constraints_preserved": true, + "qa_fixture_imported": false + }, + "schema_contract": { + "utc": "2026-10-21T10:46:20.853594+00:00", + "target": "4a4d1212751726da6a71d465b3ea2266e720cf28", + "reviewed_schema_delta": [ + "database/migrations/2026_10_21_130000_correct_fiscal_maintenance_actor_constraints.php" + ], + "compatibility_decision": "Tempo authorised correction; reviewed destination DDL applied with restored backup and preserved existing rows. Consumer remains off. Executor retains no-migration policy.", + "schema_contract_sha256": "4bf1ed9c79a795e55f83785efad54ed6b5beb4ac205644887a9a672a352917ae" + }, + "consumer_availability": { + "enabled": true, + "coverage_start": "2026-01-01", + "coverage_end": "2026-12-31", + "message": "IVA geral sobre base líquida disponível; enquadramento declarado." + }, + "rule_publication_completed": true, + "consumer_activation_completed": true, + "qa_fixture_imported": false, + "accepted_calculation_export_proofs_repeated": false, + "user_local_file_review_claimed": false, + "legal_opinion_attributed_to_user": false, + "authentication_note": "Normal portal login and MFA completed by user through loopback-only browser helper. Real account nala@tempo.co.mz (ID15) performed source registration and all governance stages through existing HTTPS endpoints. Cookies remained in memory; password/MFA not logged or saved. Synthetic QA session not used. Tool-created console not visible to user and Edge automation timeouts were limitations of tooling; browser helper access succeeded manually.", + "real_rule": { + "id": "01a15e1a-5338-700f-8a45-f87707d696a7", + "rule_code": "IVA-GERAL-BASE-LIQUIDA", + "rule_version": 1, + "component": "IVA", + "scope_key": "mz.internal-general-net.mzn", + "valid_from": "2023-01-01", + "valid_until": null, + "status": "published", + "rule_definition": { + "nodes": { + "base": { + "op": "input", + "key": "base_tributavel" + }, + "rate": { + "op": "parameter", + "key": "iva_general_rate" + }, + "hundred": { + "op": "literal", + "value": "100" + }, + "product": { + "op": "multiply", + "args": [ + "base", + "rate" + ] + }, + "intermediate": { + "op": "divide", + "args": [ + "product", + "hundred" + ] + } + }, + "result": "intermediate", + "language": "investmoz.tax.v1" + }, + "parameters": { + "IVA_GENERAL_RATE": { + "unit": "percent", + "value": "16", + "conditions": { + "currency": "MZN", + "operation": "internal_general_net" + } + } + }, + "rounding_policy": { + "ties": "not_applicable_without_rounding", + "method": "none", + "status": "not_applied", + "purpose": "operation_tax_not_payment", + "evidence": "Orientação expressa Tempo: calcular este lote IVA sem arredondamento automático; ficha v1.2", + "precision": "exact_decimal", + "aggregation": "single_declared_taxable_base", + "coverage_end": "2026-12-31", + "coverage_start": "2026-01-01" + }, + "legal_source_id": "01a15e1a-44a8-7316-82ba-008c432609ef", + "source_version_no": 1, + "source_sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53", + "author_id": 15, + "reviewer_id": 15, + "approver_id": 15, + "publisher_id": 15, + "review_evidence": "Manutenção fiscal autorizada pela Tempo nesta conversa; ficha v1.2 e fontes oficiais aceites em08/10/2026. Mesma conta autorizada, sem parecer jurídico ou revisão independente. civa2016=01a15e1a-3f26-713b-8964-3511cb2fea08 SHA256 b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b; iva2022=01a15e1a-44a8-7316-82ba-008c432609ef SHA256 ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53; iva2025=01a15e1a-4dc2-7021-bbd4-6052db9fcf36 SHA256 ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251. Conferência técnica do cadastro contra a ficha e os exemplares já documentados. Excluídos preço comIVA incluído, taxas reduzidas, isenções, regimes especiais, importações, digitais não residentes, dedução/crédito/reembolso, incentivos, pagamento/declaração e outros impostos. Não certifica elegibilidade individual.", + "approval_evidence": "Manutenção fiscal autorizada pela Tempo nesta conversa; ficha v1.2 e fontes oficiais aceites em08/10/2026. Mesma conta autorizada, sem parecer jurídico ou revisão independente. civa2016=01a15e1a-3f26-713b-8964-3511cb2fea08 SHA256 b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b; iva2022=01a15e1a-44a8-7316-82ba-008c432609ef SHA256 ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53; iva2025=01a15e1a-4dc2-7021-bbd4-6052db9fcf36 SHA256 ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251. Aprovação operacional do lote delimitado já autorizada pela Tempo; não é validação jurídica atribuída ao utilizador. Estimativa de IVA calculado sobre base declarada, sem apuramento final do imposto a pagar. Precisão calculada distinta de apresentação monetária.", + "publication_evidence": "Manutenção fiscal autorizada pela Tempo nesta conversa; ficha v1.2 e fontes oficiais aceites em08/10/2026. Mesma conta autorizada, sem parecer jurídico ou revisão independente. civa2016=01a15e1a-3f26-713b-8964-3511cb2fea08 SHA256 b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b; iva2022=01a15e1a-44a8-7316-82ba-008c432609ef SHA256 ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53; iva2025=01a15e1a-4dc2-7021-bbd4-6052db9fcf36 SHA256 ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251. Publicação apenas da versão1 fundamentada. Taxa eficaz desde01/01/2023, cobertura do consumidor01/01/2026–31/12/2026. Activação continua separada. Suspensão recusa novas admissões; execuções admitidas conservam versão congelada, históricos e relatórios.", + "closure_evidence": null, + "submitted_at": "2026-10-21 10:55:47+00", + "reviewed_at": "2026-10-21T10:55:49.000000Z", + "approved_at": "2026-10-21T10:55:51.000000Z", + "published_at": "2026-10-21T10:55:53.000000Z", + "suspended_at": null, + "archived_at": null, + "version_no": 5, + "created_at": "2026-10-21T10:55:45.000000Z", + "updated_at": "2026-10-21T10:55:53.000000Z" + }, + "real_sources": { + "civa2016": { + "id": "01a15e1a-3f26-713b-8964-3511cb2fea08", + "title": "Lei n.º 13/2016 — CIVA republicado", + "url": "https://www.inm.gov.mz/pt-br/content/suplemento-n%C2%BA-10-de-301216-pag-1426-259-290-br-n%C2%BA-156-boletim-da-rep%C3%BAblica-i-serie", + "diploma": "Lei 13/2016", + "article": "Arts. 1–4, 6–7, 15, 17(2), 27 do CIVA; art. 4 da Lei", + "competent_entity": "Assembleia da República de Moçambique", + "valid_from": "2017-01-01", + "valid_until": null, + "validation_status": "pending", + "owner_id": 15, + "validator_id": null, + "validated_at": null, + "version_no": 1, + "created_at": "2026-10-21T10:55:40.000000Z", + "updated_at": "2026-10-21T10:55:40.000000Z", + "fiscal_acceptance": { + "basis": "Tempo-official-sources-20261008", + "scope": "fiscal_parameters", + "sha256": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b", + "citation": "BR156, 10.º suplemento, 30/12/2016. PDF6–8,13–14,17–18: âmbito, base tributável declarada e cálculo. Taxa histórica 17% não utilizada. Consulta dirigida da ficha v1.2; não certifica anexos ou elegibilidade individual.", + "accepted_at": "2026-10-21T10:55:40.836454Z", + "legal_opinion": false, + "official_origin": "Boletim da República; exemplar do acervo oficial já aceite pela decisão Tempo de 08/10/2026, arquivado em docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf. Cadastro fiscal rastreável; sem atribuição de parecer jurídico ou revisão independente à Tempo.", + "independent_review": false, + "responsible_user_id": 15 + } + }, + "iva2022": { + "id": "01a15e1a-44a8-7316-82ba-008c432609ef", + "title": "Lei n.º 22/2022 — republicação oficial do IVA", + "url": "https://www.inm.gov.mz/pt-br/content/assembleia-da-rep%C3%BAblica-suplemento-n%C2%BA-2-de-281222-pag-2252-25-42-br-n%C2%BA-250-boletim-da", + "diploma": "Lei 22/2022", + "article": "Art. 17(1) do CIVA e art. 6 da Lei", + "competent_entity": "Assembleia da República de Moçambique", + "valid_from": "2023-01-01", + "valid_until": null, + "validation_status": "pending", + "owner_id": 15, + "validator_id": null, + "validated_at": null, + "version_no": 1, + "created_at": "2026-10-21T10:55:42.000000Z", + "updated_at": "2026-10-21T10:55:42.000000Z", + "fiscal_acceptance": { + "basis": "Tempo-official-sources-20261008", + "scope": "fiscal_parameters", + "sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53", + "citation": "BR250, 2.º suplemento, 28/12/2022; PDF3/BR2252-(27): taxa geral 16%; PDF4, art.6: eficácia 01/01/2023. Exemplar republicado; publicação inicial sem efeito. Aplicação delimitada à base líquida declarada em MZN e cobertura do consumidor 2026, ficha v1.2.", + "accepted_at": "2026-10-21T10:55:42.246583Z", + "legal_opinion": false, + "official_origin": "Boletim da República; exemplar do acervo oficial já aceite pela decisão Tempo de 08/10/2026, arquivado em docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf. Cadastro fiscal rastreável; sem atribuição de parecer jurídico ou revisão independente à Tempo.", + "independent_review": false, + "responsible_user_id": 15 + } + }, + "iva2025": { + "id": "01a15e1a-4dc2-7021-bbd4-6052db9fcf36", + "title": "Lei n.º 10/2025 — alterações ao CIVA, BR248 suplemento1", + "url": "https://www.at.gov.mz/api/webdav?path=%2FLEGISLA%C3%87%C3%83O%2FLEGISLA%C3%87%C3%83O%20FISCAL%2FLEI%2FBR_248_I_SERIE_SUPLEMENTO_2025.pdf", + "diploma": "Lei 10/2025", + "article": "Art. 1 (artigos alterados) e disposição de entrada em vigor", + "competent_entity": "Assembleia da República de Moçambique", + "valid_from": "2026-01-01", + "valid_until": null, + "validation_status": "pending", + "owner_id": 15, + "validator_id": null, + "validated_at": null, + "version_no": 1, + "created_at": "2026-10-21T10:55:44.000000Z", + "updated_at": "2026-10-21T10:55:44.000000Z", + "fiscal_acceptance": { + "basis": "Tempo-official-sources-20261008", + "scope": "fiscal_parameters", + "sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251", + "citation": "BR248, suplemento1, 29/12/2025, PDF12–15: Lei10/2025 efectiva 01/01/2026; não altera arts.15/17 nas disposições consultadas. Apoio à cadeia temporal 2026 do lote delimitado, não implementação de regimes ou obrigações adicionais.", + "accepted_at": "2026-10-21T10:55:44.576628Z", + "legal_opinion": false, + "official_origin": "Boletim da República; exemplar do acervo oficial já aceite pela decisão Tempo de 08/10/2026, arquivado em docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf. Cadastro fiscal rastreável; sem atribuição de parecer jurídico ou revisão independente à Tempo.", + "independent_review": false, + "responsible_user_id": 15 + } + } + }, + "publication_events": [ + { + "action": "submit", + "status": "submitted", + "version_no": 2, + "utc": "2026-10-21T10:55:48.179954+00:00" + }, + { + "action": "review", + "status": "reviewed", + "version_no": 3, + "utc": "2026-10-21T10:55:50.198403+00:00" + }, + { + "action": "approve", + "status": "approved", + "version_no": 4, + "utc": "2026-10-21T10:55:52.268896+00:00" + }, + { + "action": "publish", + "status": "published", + "version_no": 5, + "utc": "2026-10-21T10:55:54.303429+00:00" + } + ], + "activation": { + "utc": "2026-10-21T10:55:58.330391+00:00", + "authorisation": "Tempo current conversation, separate consumer activation", + "served_revision": { + "commit": "d3fe8a02ec7f5dcd01984c4f4a1eba18b5a0cf19", + "branch": "main", + "built_at": "2026-10-21T10:48:46.529930+00:00", + "manifest_sha256": "f417509cfa060240801c6a956a787a90d0e283c3c08e77b5be655d63394a4cb9" + }, + "rule": { + "id": "01a15e1a-5338-700f-8a45-f87707d696a7", + "rule_code": "IVA-GERAL-BASE-LIQUIDA", + "rule_version": 1, + "status": "published", + "source_sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53", + "legal_source_id": "01a15e1a-44a8-7316-82ba-008c432609ef", + "source_version_no": 1, + "version_no": 5, + "author_id": 15, + "reviewer_id": 15, + "approver_id": 15, + "publisher_id": 15 + }, + "consumer_enabled": true, + "configuration_keys_changed": [ + "INVESTMOZ_IVA_CONSUMER_ENABLED", + "INVESTMOZ_IVA_CONSUMER_RULE_ID", + "INVESTMOZ_IVA_CONSUMER_RULE_VERSION" + ], + "other_configuration_preserved": true, + "before_environment_sha256": "537eff52f0f28b83ccc56bf9a9b85c2d8fca1da2f678c30b929b46c67c09491b", + "after_environment_sha256": "7cdaba591bb5787485a349c24db2fd7c8279436da0eb31502e44db2fffa21d03", + "histories_preserved": true, + "accepted_calculation_export_tests_repeated": false, + "qa_fixture_imported": false + }, + "destination_delta_read_only": { + "utc": "2026-10-21T10:56:37.650967+00:00", + "read_only": true, + "served": { + "commit": "d3fe8a02ec7f5dcd01984c4f4a1eba18b5a0cf19", + "branch": "main", + "built_at": "2026-10-21T10:48:46.529930+00:00", + "manifest_sha256": "f417509cfa060240801c6a956a787a90d0e283c3c08e77b5be655d63394a4cb9" + }, + "inventory": { + "sources": [ + { + "id": "01a15e1a-3f26-713b-8964-3511cb2fea08", + "title": "Lei n.º 13/2016 — CIVA republicado", + "diploma": "Lei 13/2016", + "article": "Arts. 1–4, 6–7, 15, 17(2), 27 do CIVA; art. 4 da Lei", + "version_no": 1, + "validation_status": "pending", + "owner_id": 15, + "fiscal_acceptance": { + "basis": "Tempo-official-sources-20261008", + "scope": "fiscal_parameters", + "sha256": "b90dc7c14ecea2e378c4a62e8e5a47d54a5644c457baeb8b8053b92fd2a5710b", + "citation": "BR156, 10.º suplemento, 30/12/2016. PDF6–8,13–14,17–18: âmbito, base tributável declarada e cálculo. Taxa histórica 17% não utilizada. Consulta dirigida da ficha v1.2; não certifica anexos ou elegibilidade individual.", + "accepted_at": "2026-10-21T10:55:40.836454Z", + "legal_opinion": false, + "official_origin": "Boletim da República; exemplar do acervo oficial já aceite pela decisão Tempo de 08/10/2026, arquivado em docs/investmoz/simulations/source-archive/Lei-13-2016-CIVA-BR-156-10-suplemento.pdf. Cadastro fiscal rastreável; sem atribuição de parecer jurídico ou revisão independente à Tempo.", + "independent_review": false, + "responsible_user_id": 15 + } + }, + { + "id": "01a15e1a-44a8-7316-82ba-008c432609ef", + "title": "Lei n.º 22/2022 — republicação oficial do IVA", + "diploma": "Lei 22/2022", + "article": "Art. 17(1) do CIVA e art. 6 da Lei", + "version_no": 1, + "validation_status": "pending", + "owner_id": 15, + "fiscal_acceptance": { + "basis": "Tempo-official-sources-20261008", + "scope": "fiscal_parameters", + "sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53", + "citation": "BR250, 2.º suplemento, 28/12/2022; PDF3/BR2252-(27): taxa geral 16%; PDF4, art.6: eficácia 01/01/2023. Exemplar republicado; publicação inicial sem efeito. Aplicação delimitada à base líquida declarada em MZN e cobertura do consumidor 2026, ficha v1.2.", + "accepted_at": "2026-10-21T10:55:42.246583Z", + "legal_opinion": false, + "official_origin": "Boletim da República; exemplar do acervo oficial já aceite pela decisão Tempo de 08/10/2026, arquivado em docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf. Cadastro fiscal rastreável; sem atribuição de parecer jurídico ou revisão independente à Tempo.", + "independent_review": false, + "responsible_user_id": 15 + } + }, + { + "id": "01a15e1a-4dc2-7021-bbd4-6052db9fcf36", + "title": "Lei n.º 10/2025 — alterações ao CIVA, BR248 suplemento1", + "diploma": "Lei 10/2025", + "article": "Art. 1 (artigos alterados) e disposição de entrada em vigor", + "version_no": 1, + "validation_status": "pending", + "owner_id": 15, + "fiscal_acceptance": { + "basis": "Tempo-official-sources-20261008", + "scope": "fiscal_parameters", + "sha256": "ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251", + "citation": "BR248, suplemento1, 29/12/2025, PDF12–15: Lei10/2025 efectiva 01/01/2026; não altera arts.15/17 nas disposições consultadas. Apoio à cadeia temporal 2026 do lote delimitado, não implementação de regimes ou obrigações adicionais.", + "accepted_at": "2026-10-21T10:55:44.576628Z", + "legal_opinion": false, + "official_origin": "Boletim da República; exemplar do acervo oficial já aceite pela decisão Tempo de 08/10/2026, arquivado em docs/investmoz/simulations/source-archive/BR-248-I-Suplemento-1-2025.pdf. Cadastro fiscal rastreável; sem atribuição de parecer jurídico ou revisão independente à Tempo.", + "independent_review": false, + "responsible_user_id": 15 + } + } + ], + "rules": [ + { + "id": "01a15e1a-5338-700f-8a45-f87707d696a7", + "rule_code": "IVA-GERAL-BASE-LIQUIDA", + "rule_version": 1, + "status": "published", + "valid_from": "2023-01-01", + "valid_until": null, + "legal_source_id": "01a15e1a-44a8-7316-82ba-008c432609ef", + "source_sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53", + "source_version_no": 1, + "version_no": 5, + "author_id": 15, + "reviewer_id": 15, + "approver_id": 15, + "publisher_id": 15 + } + ], + "event_count": 5, + "historical_counts": { + "results": 0, + "reports": 0 + } + }, + "consumer": { + "database": "teste_investidor", + "binding": { + "enabled": true, + "rule_id": "01a15e1a-5338-700f-8a45-f87707d696a7", + "rule_version": 1 + }, + "availability": { + "enabled": true, + "coverage_start": "2026-01-01", + "coverage_end": "2026-12-31", + "message": "IVA geral sobre base líquida disponível; enquadramento declarado." + }, + "parameter_resolution_without_calculation": { + "parameter_code": "IVA_GENERAL_RATE", + "status": "resolved", + "value": "16", + "unit": "percent", + "conditions": { + "currency": "MZN", + "operation": "internal_general_net" + }, + "scope_key": "mz.internal-general-net.mzn", + "rule_code": "IVA-GERAL-BASE-LIQUIDA", + "rule_id": "01a15e1a-5338-700f-8a45-f87707d696a7", + "rule_version": 1, + "period": { + "start": "2026-10-21", + "end": "2026-10-21" + }, + "validity": { + "start": "2023-01-01", + "end": null + }, + "source": { + "title": "Lei n.º 22/2022 — republicação oficial do IVA", + "diploma": "Lei 22/2022", + "article": "Art. 17(1) do CIVA e art. 6 da Lei", + "url": "https://www.inm.gov.mz/pt-br/content/assembleia-da-rep%C3%BAblica-suplemento-n%C2%BA-2-de-281222-pag-2252-25-42-br-n%C2%BA-250-boletim-da", + "declared_sha256": "ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53" + } + } + }, + "qa_fixture_imported": false, + "calculations_exporters_repeated": false + }, + "remaining": [] } } diff --git a/docs/investmoz/unification/traceability-and-manual.md b/docs/investmoz/unification/traceability-and-manual.md index 0b9d17c3..411e304e 100644 --- a/docs/investmoz/unification/traceability-and-manual.md +++ b/docs/investmoz/unification/traceability-and-manual.md @@ -1943,3 +1943,21 @@ O backup/restauro anterior à escrita ficou comprovado em21/10/2026 às10:18:00U 3. **Activação do consumidor:** permanece separada da publicação. Aplicar a ligação aoID e `rule_version` reais autorizados e o interruptor de activação pelo procedimento já definido, conservando cálculo sobre base declarada como estimativa, sem apuramento final do imposto a pagar. Conferir somente a revisão/regra efectivamente servidas e o delta no destino. Desactivar o consumidor ou suspender a regra recusa novas admissões, preservando as já admitidas, históricos e relatórios. **Saldo actual:** controlo corrigido e verificado emQA, fontes e funcionamento do cálculo não reabertos; sem nova publicação ou activação na homologação. A referência servida continua226fd308 e o consumidor desligado. A correcção não foi aplicada ao esquema activo. A indicação do responsável e a autorização operacional não são tratadas como conferência de ficheiros locais ou validação jurídica da Tempo. Esta actualização substitui a indicação anterior de que a simples falta de quatro listas configuradas bloqueava obrigatoriamente a disponibilização. + +### Execução autorizada da correcção fiscal — 21/10/2026 + +A Tempo autorizou incorporar4a4d1212 e concluir apenas as operações pendentes. A correcção foi integrada emmain; a equipa integrou entretanto d3fe8a02, que inclui4a4d1212 e conserva o mesmo código fiscal. A revisão efectivamente servida, conferida em `/build/revision.json`, é `d3fe8a02ec7f5dcd01984c4f4a1eba18b5a0cf19`. Não se reinstalou226fd308. + +Backup/restauro actualizado: `/var/backups/investmoz/iva-rollout-20261021_104253`, dumpSHA256 `b37bf4aad0abd839bc81d70adf802535ad7738fabe75fda61d74f39dfc11e74b`; restauro isolado `iva_rollout_20261021_104253_test`,171tabelas com contagens e hashes coincidentes. A operação técnica autenticada aplicou exclusivamente oDDL revisto, com registos/históricos e constraints alheias preservados. A migration protegida não foi executada na base activa nem teve a guarda enfraquecida. O contrato do executor foi actualizado apenas para essa migration, após registo da compatibilidade; a primeira disponibilização conservou a release anterior ao encontrar a alteração de esquema. A retoma usou o mesmo executor e não passou a executar migrations no destino. + +Publicação e activação concluídas conforme recibo. O consumidor está activo. Não foram repetidas provas aceites do cálculo, precisão, exportadores ouPDF, nem importada a fixtureQA. A autenticação da infraestrutura não é identidade administrativa do portal. A conta Christiana/example.test reportada pelo utilizador pertence ao ensaio local anterior e não é usada no destino. + +Mantém-se o procedimento único: **1)** código/controlo do esquema, agora integrados; **2)** cadastro das fontes reais com hash/citação e da versão1 `IVA-GERAL-BASE-LIQUIDA`, seguido das etapas autenticadas pelo mesmo responsável autorizado; **3)** activação separada, ligando o consumidor aoID e versão publicados. Cobertura2026, operação interna geral sobre base líquida declarada emMZN; excluídos preços comIVA incluído, taxas reduzidas, isenções, regimes especiais, importações, digitais não residentes, deduções/créditos/reembolsos, incentivos, pagamento/declaração e outros impostos. O resultado é estimativa deIVA sobre a base declarada, não apuramento final a pagar. + +Para suspender, desligar `INVESTMOZ_IVA_CONSUMER_ENABLED` e reiniciar graciosamente os workers pelo mecanismo existente, ou suspender a versão publicada pela governação autenticada, com `version_no` corrente e evidência. Novas admissões são recusadas; as já admitidas concluem com snapshot congelado, mantendo históricos e relatórios. Não apagar fontes, versões ou execuções para reverter a exposição. A autorização e o cadastro não constituem conferência local dos ficheiros pelo utilizador nem validação jurídica atribuída à Tempo. O recibo JSON existente regista a revisão, a regra e o estado efectivamente observados. + +**Recibo final das três operações:** código4a4d1212 integrado e servido dentro ded3fe8a02; três fontes oficiais reais cadastradas comversão1, hashes e citações; regra `IVA-GERAL-BASE-LIQUIDA`, **rule_version1**, ID `01a15e1a-5338-700f-8a45-f87707d696a7`, estado `published`, controlo optimista `version_no5`; autor/revisor/aprovador/publicador reais: conta indicada `nala@tempo.co.mz`, ID15. A sessão normal comMFA foi efectuada pelo utilizador numa página temporária de apoio ligada apenas a127.0.0.1; não se guardaram palavra-passe, códigoMFA ou cookies. Não há alegação de revisão independente ou parecer jurídico. A aceitação fiscal das fontes tem o fundamentoTempo08/10/2026; o estado geral permanecepending, sem validação automática noutros processos. + +Activação separada aplicada em21/10/2026 às10:55:58UTC, alterando apenas as três chaves do consumidor. Ligação exacta aoID acima, rule_version1 eenabled=true; restante configuração preservada. `/api/v1/fiscal-consumer` confirmouenabled=true porHTTP200; a leitura do resolvedor, sem executar cálculo, confirmouIVA_GENERAL_RATE=16percent, mesmoID/versão/fonte no contextoMZN/internal_general_net de2026. Cinco eventos de governação; contagens de resultados/relatórios preservadas, sem simulações sintéticas no destino. O restauro de segurança e a configuração anterior estão conservados no arquivo privado identificado no recibo. + +Suspensão concreta: configurar `INVESTMOZ_IVA_CONSUMER_ENABLED=false` e executar o reinício gracioso existente `php8.4 artisan queue:restart` na releaseactual como operador autorizado; ou `POST /api/v2/investment/admin/tax-rules/01a15e1a-5338-700f-8a45-f87707d696a7/suspend`, com `version_no:5` enquanto corrente e evidência verdadeira de pelo menos20caracteres, pela administração autenticada/MFA. Não repetir a suspensão se o estado/versão já tiver mudado. Conservar a ligação e todos os registos; futuras retomas respeitam o estado da regra e o procedimento de versão aplicável, sem escolher automaticamente outra regra. diff --git a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv index 442f82c2..0fdad18c 100644 --- a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv +++ b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv @@ -10652,7 +10652,7 @@ AUD-SEARCH-T10,Consistência transversal da pesquisa e navegação — Bibliotec AUD-SEARCH-T11,Consistência transversal da pesquisa e navegação — Legislação,Instruções expressas da Tempo na conversa de 20/10/2026; AGENTS.md; RF-MN-010 e AUD-GEO-01 preservados.,navegação/pesquisa,/legislacao,portal/services; portal/document — Reutiliza a correcção da biblioteca e preserva filtros jurídicos/documentais pertinentes.,Sem alteração remota nesta execução; revisão apenas na branch codex/opportunity-search.,HTTP/Inertia: resources.total=0; consumidor e query pública partilhados.,QA — delta delimitado; revisão Tempo pendente,"Situação jurídica, consulta e cálculo continuam independentes.",,"Filtros, contagem, resultados e URL coerentes; universos identificados; erro distinto de vazio; permissões e contexto conservados.",P1,,RF-MN-010; AUD-GEO-01,,,,,,,,,,,Mesmo padrão da biblioteca; não deve expor um universo concorrente.,"Situação jurídica, consulta e cálculo continuam independentes.",portal/services; portal/document; SearchState; SearchFeedback; TerritoryFields; portalNavigation,,"Integração em main apenas após revisão; assistência NLP, contratos e P7 separados.",Correcção/simplificação em QA,,HTTP/Inertia: resources.total=0; consumidor e query pública partilhados.,Pesquisa transversal QA 20/10/2026,20/10/2026,,,,,,,,,,"Provas comuns cobrem o componente reutilizado; HTTP vazio não demonstra operações de gestão ou publicação. Situação jurídica, consulta e cálculo continuam independentes.",,falha funcional; navegação; apresentação visual,,Disponível para revisão na aplicação QA local. AUD-GUIDE-CARD-20261020,"Related educational cards: image, source summary, clear actions",Tempo 20/10/2026; independent delta after 0e7d51f18fb4,educational presentation,/sectores/{slug}; /explorar/{group}; articles; /oportunidades and detail,EducationalArticleCard; EducationalGuides; LegacyContent; SectorInvestment,QA only,1 test / 8 assertions; PHP syntax; TypeScript/build; desktop2048/mobile390; keyboard,QA review pending,Normal QA sector and article verified against existing library resource 10 and local image 25; previous dossier proof retained,,Source-derived summary; public images; conditional opportunity action; context preserved,P1,,,,,,,,,,,,,,,,,,presentation,,,,20/10/2026,,,,,,,,,,,,content; navigation; visual presentation,,Ready for QA review AUD-SIM-INT01,Invalid one-off fiscal date can throw instead of returning validation state,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Fixed in QA; invalid-date checks; 38 directed frontend tests passed,Previous inline-date proof retained; unchanged delta not repeated,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P0,,,,,,,,,,,,,,,,,,diagnosis and targeted corrections,, | [Saldo consolidado21/10/2026] Concluído no recorte. Nenhum delta de validação de data por demonstrar; prova anterior preservada. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação.,,20/10/2026,,,,,,,,,,,,,, -AUD-SIM-INT02,Review actual fiscal parameters sources periods and eligibility,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Verification pending; no parameter activation,"Parcial: consumidor IVA integrado e servido em 226fd308, desligado. Controlo de manutencao por mesma administracao autorizada corrigido em QA; publicacao real e activacao pendentes.",QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P0,,,,,,,,,,,,,,Rever/aplicar delta de controlo fiscal e esquema ja ensaiado em QA; cadastrar/publicar versao real fundamentada e activar consumidor. Sem obrigacao de quatro pessoas. Demais componentes fiscais fora deste recorte.,,,Tempo indicou nala@tempo.co.mz e removeu expressamente a condicao de pessoas distintas na manutencao fiscal. Preservar as tres operacoes e as independencias aprovadas dos outros processos.,Ligacao de consumidor publicada concluida em QA; decisoes operacionais separadas.,Sem saldo de implementacao identificado para este delta QA; nao reutilizar estimativas anteriores como horas ainda em falta; nao estima cobertura fiscal integral.," | [Leitura SSH 21/10/2026 08:17 Maputo] Zero regras em simulation_tax_rule_versions na homologação, incluindo todos os estados por leitura administrativa sem ocultação RLS. Seis referências em investment_legal_sources; não são parâmetros executáveis. QA também tinha zero regras. BEGIN READ ONLY/SELECT/ROLLBACK; zero escritas. Prova homologation-fiscal-readonly.json. O git HEAD registado é do checkout consultado, não certifica a revisão do build servido. A ausência de cadastro não é ausência de fontes oficiais nem reabre a aceitação da Tempo de 08/10. Não implementa a ligação funcional ao motor fiscal. | [Saldo consolidado21/10/2026] Parcial. Leitura remota concluída: zero regras de todos os estados na homologação, tal como QA; seis referências jurídicas não são parâmetros executáveis. Falta cadastro fundamentado por componente/âmbito/período e ligação funcional ao motor fiscal. Fontes e análises existentes reutilizáveis; aceitação oficial da Tempo de08/10 preservada. Não activar taxas nem importar/publicar por esta reconciliação. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação. | [Candidata21/10/2026] Diagnóstico fiscal separado no manual existente: fontes/analises já disponíveis; zero parâmetros executáveis na QA e homologação por leitura de todos os estados; governação/resolvedor temporal/DSL existentes; RunSimulation ainda aritmética personalizada sem consumir regras fiscais. Saldo: cadastro fundamentado, orquestração, contrato de resultado/histórico e ligação ao dossier/relatório, com casos por componente/período. Nenhuma regra criada nem activada; implementação fiscal integral aberta e excluída das1–2h de exportações. | [Proposta21/10/2026] Primeiro lote proposto: uma regra IVA geral sobre base liquida/MZN, cobertura demonstrada2026 sem inventar caducidade legal. Reutilizar fontes/analises/governacao/resolvedor/avaliador existentes; arredondamento e ambito aplicavel explicitamente por fundamentar antes de publicar. Cadastro4-8h e codigo/aceitacao12-20h, total16-28h condicionado ao acervo, separado das1-2h de exportacao. Criterios e exclusoes no manual existente. Nenhuma regra cadastrada/activada; nao e implementacao fiscal integral. | [QA IVA v1.2 21/10/2026] Orientacao posterior Tempo: calcular com precisao decimal exacta sem arredondamento automatico, separando apresentacao monetaria; arredondamento generico deixa de ser bloqueio deste lote. Cadastro draft versionado em clone QA; resolvedor/avaliador existentes; proveniencia, historico e relatorio imutavel ligados. 5 feature (51 assercoes), 7 unit (25), 3 frontend; types/build/Pint aprovados. Contexto declarado; nao e saldo a pagar. Zero regras publicadas; sem main/activacao. Recorte QA autorizado verificado (0h engenharia identificada restante); produto fiscal integral continua parcial. Limites e provas no mesmo manual e ficha v1.2; sem atribuicao de validacao juridica ao utilizador. | [Revisao 83d2f97d] Ambito/periodo/exclusoes e procedimentos de integracao, publicacao, activacao e suspensao consolidados no mesmo manual. Lacuna concreta de ecra QA fechada: entradas 1000.03/MZN/2026-10-21; calculo exacto 160.0048; gravacao fa6d17f2-5f47-4cb6-b8cb-40850c12505f; recarga; recuperacao do mesmo ID; relatorio d13e2ad5-3ba8-4d01-9d30-5815496da774 com mesmo valor/proveniencia e hash igual ao resultado. Uma execucao persistida, draft e zero regras publicadas. 1 teste novo de rota/17 assercoes, TypeScript/build e browser aprovados; restantes provas reutilizadas. Interrupcao inicial da ferramenta resolvida, sem atribuicao de falha ao simulador. Revisao do recorte demonstrada; sem nova preparacao generica identificada, main ou activacao; nao fecha aplicabilidade fiscal universal nem simulador integral. | 21/10/2026: proposta do consumidor IVA no simulador existente no manual: falta ligacao a regra publicada e activacao explicita. Integrar codigo desligado, publicar versao e activar consumidor sao tres operacoes distintas. Reutiliza permissoes, governanca, historico e provas aceites; sem ampliar cobertura ou executar estas operacoes. | 21/10/2026: implementado delta de 2ced7b79 no simulador normal QA, activacao desligada por omissao. 8 testes/75 assercoes, 2 testes frontend novos, TypeScript/build/Pint. Edge: indeterminacao, calculo, repeticao sem duplicar, fila admitida antes de suspensao concluida depois, nova execucao recusada e historicos/relatorios preservados. Mesmo manual e recibo consolidam provas e tres operacoes. Fixture isolada suspensa; sem merge ou publicacao/activacao na homologacao. | 21/10/2026: origem da condicao fiscal localizada em e65cb269/servico/CHECKs de 03/10 e nota de implementacao; sem decisao expressa aplicavel encontrada. Correccao QA: administracao existente, mesma pessoa, fonte oficial identificada e eventos preservados. 6 testes/86 assercoes apenas do controlo, sem calculos/exportadores; constraints de outras tabelas iguais. Esquema activo nao alterado; backup/restauro de 171 tabelas confirmado; sem fixture ou publicacao real.",,20/10/2026,,,,,,,,,,,,,, +AUD-SIM-INT02,Review actual fiscal parameters sources periods and eligibility,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Verification pending; no parameter activation,Recorte IVA geral sobre base declarada disponibilizado: 4a4d1212 integrado na revisao servida d3fe8a02; regra real v1 publicada e consumidor activo. Nao conclui o simulador fiscal integral.,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P0,,,,,,,,,,,,,,"Nenhuma operacao de disponibilizacao pendente neste lote delimitado. Outras componentes, regimes e coberturas fiscais permanecem fora do recorte; nao repetir provas aceites.",,,"Tempo autorizou incorporacao de 4a4d1212, cadastro/publicacao da regra real e activacao. Mesma administracao real nala@tempo.co.mz, login normal e MFA, sem quatro designacoes; sem parecer juridico ou revisao independente atribuidos a Tempo.",Ligacao de consumidor publicada concluida em QA; decisoes operacionais separadas.,Recorte executado; sem saldo de implementacao ou disponibilizacao identificado neste lote. Nao converter estimativas anteriores em implementacao fiscal integral.," | [Leitura SSH 21/10/2026 08:17 Maputo] Zero regras em simulation_tax_rule_versions na homologação, incluindo todos os estados por leitura administrativa sem ocultação RLS. Seis referências em investment_legal_sources; não são parâmetros executáveis. QA também tinha zero regras. BEGIN READ ONLY/SELECT/ROLLBACK; zero escritas. Prova homologation-fiscal-readonly.json. O git HEAD registado é do checkout consultado, não certifica a revisão do build servido. A ausência de cadastro não é ausência de fontes oficiais nem reabre a aceitação da Tempo de 08/10. Não implementa a ligação funcional ao motor fiscal. | [Saldo consolidado21/10/2026] Parcial. Leitura remota concluída: zero regras de todos os estados na homologação, tal como QA; seis referências jurídicas não são parâmetros executáveis. Falta cadastro fundamentado por componente/âmbito/período e ligação funcional ao motor fiscal. Fontes e análises existentes reutilizáveis; aceitação oficial da Tempo de08/10 preservada. Não activar taxas nem importar/publicar por esta reconciliação. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação. | [Candidata21/10/2026] Diagnóstico fiscal separado no manual existente: fontes/analises já disponíveis; zero parâmetros executáveis na QA e homologação por leitura de todos os estados; governação/resolvedor temporal/DSL existentes; RunSimulation ainda aritmética personalizada sem consumir regras fiscais. Saldo: cadastro fundamentado, orquestração, contrato de resultado/histórico e ligação ao dossier/relatório, com casos por componente/período. Nenhuma regra criada nem activada; implementação fiscal integral aberta e excluída das1–2h de exportações. | [Proposta21/10/2026] Primeiro lote proposto: uma regra IVA geral sobre base liquida/MZN, cobertura demonstrada2026 sem inventar caducidade legal. Reutilizar fontes/analises/governacao/resolvedor/avaliador existentes; arredondamento e ambito aplicavel explicitamente por fundamentar antes de publicar. Cadastro4-8h e codigo/aceitacao12-20h, total16-28h condicionado ao acervo, separado das1-2h de exportacao. Criterios e exclusoes no manual existente. Nenhuma regra cadastrada/activada; nao e implementacao fiscal integral. | [QA IVA v1.2 21/10/2026] Orientacao posterior Tempo: calcular com precisao decimal exacta sem arredondamento automatico, separando apresentacao monetaria; arredondamento generico deixa de ser bloqueio deste lote. Cadastro draft versionado em clone QA; resolvedor/avaliador existentes; proveniencia, historico e relatorio imutavel ligados. 5 feature (51 assercoes), 7 unit (25), 3 frontend; types/build/Pint aprovados. Contexto declarado; nao e saldo a pagar. Zero regras publicadas; sem main/activacao. Recorte QA autorizado verificado (0h engenharia identificada restante); produto fiscal integral continua parcial. Limites e provas no mesmo manual e ficha v1.2; sem atribuicao de validacao juridica ao utilizador. | [Revisao 83d2f97d] Ambito/periodo/exclusoes e procedimentos de integracao, publicacao, activacao e suspensao consolidados no mesmo manual. Lacuna concreta de ecra QA fechada: entradas 1000.03/MZN/2026-10-21; calculo exacto 160.0048; gravacao fa6d17f2-5f47-4cb6-b8cb-40850c12505f; recarga; recuperacao do mesmo ID; relatorio d13e2ad5-3ba8-4d01-9d30-5815496da774 com mesmo valor/proveniencia e hash igual ao resultado. Uma execucao persistida, draft e zero regras publicadas. 1 teste novo de rota/17 assercoes, TypeScript/build e browser aprovados; restantes provas reutilizadas. Interrupcao inicial da ferramenta resolvida, sem atribuicao de falha ao simulador. Revisao do recorte demonstrada; sem nova preparacao generica identificada, main ou activacao; nao fecha aplicabilidade fiscal universal nem simulador integral. | 21/10/2026: proposta do consumidor IVA no simulador existente no manual: falta ligacao a regra publicada e activacao explicita. Integrar codigo desligado, publicar versao e activar consumidor sao tres operacoes distintas. Reutiliza permissoes, governanca, historico e provas aceites; sem ampliar cobertura ou executar estas operacoes. | 21/10/2026: implementado delta de 2ced7b79 no simulador normal QA, activacao desligada por omissao. 8 testes/75 assercoes, 2 testes frontend novos, TypeScript/build/Pint. Edge: indeterminacao, calculo, repeticao sem duplicar, fila admitida antes de suspensao concluida depois, nova execucao recusada e historicos/relatorios preservados. Mesmo manual e recibo consolidam provas e tres operacoes. Fixture isolada suspensa; sem merge ou publicacao/activacao na homologacao. | 21/10/2026: origem da condicao fiscal localizada em e65cb269/servico/CHECKs de 03/10 e nota de implementacao; sem decisao expressa aplicavel encontrada. Correccao QA: administracao existente, mesma pessoa, fonte oficial identificada e eventos preservados. 6 testes/86 assercoes apenas do controlo, sem calculos/exportadores; constraints de outras tabelas iguais. Esquema activo nao alterado; backup/restauro de 171 tabelas confirmado; sem fixture ou publicacao real. | [Execucao autorizada 21/10/2026 10:56 UTC] Servido d3fe8a02ec7f5dcd01984c4f4a1eba18b5a0cf19 contendo 4a4d1212; DDL fiscal aplicado autenticadamente com backup/restauro de171tabelas e registos preservados. Tres fontes reais v1 com hashes/citacoes e aceitacao fiscal Tempo08/10/2026, sem validacao geral automatica. Regra IVA-GERAL-BASE-LIQUIDA rule_version1, ID01a15e1a-5338-700f-8a45-f87707d696a7, published, version_no5, actor15 emtodasetapas;5eventos. Activacao separada ligada a esseID/versao; APIHTTP200 enabled=true e resolvedor16percent no contexto delimitado sem calculo novo. FixtureQA nao importada; calculos/exportadores/PDF aceites nao repetidos. Suspensao de novas admissoes conserva snapshots/historicos/relatorios. Recibo e manual existentes actualizados; limitacoes de abertura de consola/extensao registadas como ferramenta.",,20/10/2026,,,,,,,,,,,,,, AUD-SIM-INT03,Review isolation recovery across projects and sessions,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Existing controls and accepted proofs to reconcile; no leak established,Two dossiers and new login recovered in browser; cashflow persistence corrected and HTTP-tested; new visual cashflow delta pending,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P0,,,,,,,,,,,,,,,,,,diagnosis and targeted corrections,,"[Retoma 21/10/2026] QA 18576, clone simulator_review_delta_20261020_test: sessão sintética renovada por login normal; gravação autenticada e recarga recuperaram saldo 123, receita 900, custos 600, calendário mensal 10/vazio/0, crédito IVA estimado 500. Caixa conhecida 3713 MZN; total indeterminado desde mês 2; crédito estimado excluído da caixa. Prova visual cashflow-recovered-20261021.png e snapshot .txt em outputs/simulator-continuation-20261020. Não certifica recuperação destes novos valores após outro login, CSV/DOCX ou PDF nativo. Ligação de controlo do navegador perdida durante espera de download; não atribuir falha à aplicação. Leitura remota aguarda identificação da ligação SSH; zero alterações no destino. | [Saldo consolidado21/10/2026] Concluído no recorte. A/B, logout/novo login, recuperação e recusa pela aplicação demonstrados anteriormente. A tesouraria tem prova API de nova sessão e prova visual de recuperação por recarga. Não atribuir ao navegador nova sessão dos valores de tesouraria, nem nova certificação RLS; limites expressos conservados. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação.",,20/10/2026,,,,,,,,,,,,,, AUD-SIM-INT04,Review stale and historical results and correct dossier,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Existing versions/fingerprints; targeted verification pending,Historical results visible after fix; 12 and 24 recovered; hashes unchanged; synthetic temporal resolver versions verified in memory only,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P1,,,,,,,,,,,,,,,,,,diagnosis and targeted corrections,," | [Saldo consolidado21/10/2026] Concluído no recorte demonstrado. Histórico24/12 visível, hashes preservados e versões temporais sintéticas do resolvedor conferidas. Execução fiscal integrada com parâmetros reais pertence ao saldo de02 e não foi demonstrada por estes testes. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação.",,20/10/2026,,,,,,,,,,,,,, AUD-SIM-INT05,Independent financial controls unknown zero units and currencies,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Reconciliation pending; no invented tax assumptions,Independent business-plan and cashflow ledgers passed; complete credit recipe included in screen and exports,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P1,,,,,,,,,,,,,,,,,,diagnosis and targeted corrections,,"[Retoma 21/10/2026] QA 18576, clone simulator_review_delta_20261020_test: sessão sintética renovada por login normal; gravação autenticada e recarga recuperaram saldo 123, receita 900, custos 600, calendário mensal 10/vazio/0, crédito IVA estimado 500. Caixa conhecida 3713 MZN; total indeterminado desde mês 2; crédito estimado excluído da caixa. Prova visual cashflow-recovered-20261021.png e snapshot .txt em outputs/simulator-continuation-20261020. Não certifica recuperação destes novos valores após outro login, CSV/DOCX ou PDF nativo. Ligação de controlo do navegador perdida durante espera de download; não atribuir falha à aplicação. Leitura remota aguarda identificação da ligação SSH; zero alterações no destino. | [Saldo consolidado21/10/2026] Concluído nos controlos delimitados. Controlos independentes de caixa/plano/crédito, zero/desconhecido e moedas preservados. Não são validação de taxas legais nem certificação de toda a contabilidade. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação.",,20/10/2026,,,,,,,,,,,,,, From 0d7b70459dd9757e33ec1f3937762fd01bd14c25 Mon Sep 17 00:00:00 2001 From: nala Date: Wed, 21 Oct 2026 13:35:22 +0200 Subject: [PATCH 2/4] fix: explain IVA query conditions and distinguish integration failures --- .../V1/SimulationTaxParameterController.php | 4 +- .../ResolveSimulationTaxParametersRequest.php | 2 +- .../StoreSimulationFormDraftRequest.php | 4 +- app/Services/SimulationIvaDiagnostics.php | 54 ++++++++++++++ .../SimulationTaxParameterResolver.php | 18 +++-- ...-review-continuation-20261020-receipt.json | 52 ++++++++++++++ .../unification/traceability-and-manual.md | 19 +++++ .../v2/auditoria-portal/matriz-requisitos.csv | 2 +- .../components/simulation-fiscal-status.tsx | 46 +++++++++--- resources/js/components/simulation-form.tsx | 16 ++++- .../components/simulation-published-iva.tsx | 4 +- resources/js/lib/iva-diagnostics.ts | 26 +++++++ resources/js/lib/simulation-form.ts | 6 ++ .../Feature/SimulationPublishedFiscalTest.php | 27 +++++++ tests/Unit/SimulationIvaDiagnosticsTest.php | 71 +++++++++++++++++++ 15 files changed, 327 insertions(+), 24 deletions(-) create mode 100644 app/Services/SimulationIvaDiagnostics.php create mode 100644 resources/js/lib/iva-diagnostics.ts create mode 100644 tests/Unit/SimulationIvaDiagnosticsTest.php diff --git a/app/Http/Controllers/Api/V1/SimulationTaxParameterController.php b/app/Http/Controllers/Api/V1/SimulationTaxParameterController.php index 4553446a..e769ae57 100644 --- a/app/Http/Controllers/Api/V1/SimulationTaxParameterController.php +++ b/app/Http/Controllers/Api/V1/SimulationTaxParameterController.php @@ -19,13 +19,15 @@ class SimulationTaxParameterController extends Controller $input['period_start'], $input['period_end'], $input['context'] ?? [], + $input['component'] === 'IVA', ); return response()->json([ 'component' => $input['component'], 'period' => ['start' => $input['period_start'], 'end' => $input['period_end']], 'assumptions' => $input['context'] ?? [], - 'parameters' => $data, + 'parameters' => $input['component'] === 'IVA' ? $data['parameters'] : $data, + 'diagnostics' => $input['component'] === 'IVA' ? $data['diagnostics'] : [], ])->header('Cache-Control', 'no-store'); } } diff --git a/app/Http/Requests/ResolveSimulationTaxParametersRequest.php b/app/Http/Requests/ResolveSimulationTaxParametersRequest.php index b7622aad..b6e0097d 100644 --- a/app/Http/Requests/ResolveSimulationTaxParametersRequest.php +++ b/app/Http/Requests/ResolveSimulationTaxParametersRequest.php @@ -21,7 +21,7 @@ class ResolveSimulationTaxParametersRequest extends FormRequest 'component' => ['required', 'in:IRPC,IVA,ISPC,IRPS,INSS,RETENCOES,DIREITOS_ADUANEIROS,ICE'], 'period_start' => ['required', 'date_format:Y-m-d'], 'period_end' => ['required', 'date_format:Y-m-d', 'after_or_equal:period_start'], - 'context' => ['sometimes', 'array:fiscal_periodicity,fiscal_operation,fiscal_residency_assessment,fiscal_residency_country,fiscal_income_category,fiscal_establishments,fiscal_documentation,fiscal_customs_code,fiscal_vat_refund_state'], + 'context' => ['sometimes', 'array:currency,fiscal_periodicity,fiscal_operation,fiscal_residency_assessment,fiscal_residency_country,fiscal_income_category,fiscal_establishments,fiscal_documentation,fiscal_customs_code,fiscal_vat_refund_state'], 'context.*' => ['string', 'max:160'], ]; } diff --git a/app/Http/Requests/StoreSimulationFormDraftRequest.php b/app/Http/Requests/StoreSimulationFormDraftRequest.php index 74cf0d90..d03064b0 100644 --- a/app/Http/Requests/StoreSimulationFormDraftRequest.php +++ b/app/Http/Requests/StoreSimulationFormDraftRequest.php @@ -50,7 +50,7 @@ class StoreSimulationFormDraftRequest extends FormRequest 'environmental_category', 'community_benefits', 'tax_calculation', 'fiscal_scenario_mode', 'base', 'rate', 'reduction', 'sales_taxable', 'sales_exempt', 'sales_zero_rate', 'exports', 'deductible_costs', 'non_deductible_costs', 'carried_losses', 'payroll', 'outbound_payments', 'imports', 'claimed_benefits', 'reference_date', - 'fiscal_period', 'fiscal_periodicity', 'fiscal_month', 'fiscal_quarter', 'fiscal_reference_date', 'irps_salary_view', 'fiscal_component', 'fiscal_income_category', 'fiscal_residency_assessment', + 'fiscal_currency', 'fiscal_period', 'fiscal_periodicity', 'fiscal_month', 'fiscal_quarter', 'fiscal_reference_date', 'irps_salary_view', 'fiscal_component', 'fiscal_income_category', 'fiscal_residency_assessment', 'fiscal_operation', 'fiscal_activity', 'fiscal_establishments', 'fiscal_documentation', 'fiscal_customs_code', 'fiscal_vat_refund_state', 'offer_or_demand', 'opportunity_type', 'opportunity_type_other', 'opportunity_description', @@ -279,7 +279,7 @@ class StoreSimulationFormDraftRequest extends FormRequest 'currency', 'funds_origin_countries', 'environmental_category', 'tax_calculation', 'fiscal_scenario_mode', 'offer_or_demand', 'opportunity_type', 'confidentiality', 'publish_requested', 'terms_accepted', 'truth_declaration', 'reuse_simulation', 'contact_authorisation', 'publication_authorisation', 'public_fields_confirmation', 'validation_acknowledged', - 'fiscal_period', 'fiscal_periodicity', 'fiscal_month', 'fiscal_quarter', 'fiscal_reference_date', 'irps_salary_view', 'fiscal_component', 'fiscal_income_category', 'fiscal_residency_assessment', 'fiscal_operation', + 'fiscal_currency', 'fiscal_period', 'fiscal_periodicity', 'fiscal_month', 'fiscal_quarter', 'fiscal_reference_date', 'irps_salary_view', 'fiscal_component', 'fiscal_income_category', 'fiscal_residency_assessment', 'fiscal_operation', 'fiscal_documentation', 'fiscal_vat_refund_state'], 'personal_snapshot.selection_labels' => ['person_type', 'investor_origin', 'tax_residency_country', 'fiscal_residency_country', 'entity_stage', 'legal_form', 'preferred_channel'], ]; diff --git a/app/Services/SimulationIvaDiagnostics.php b/app/Services/SimulationIvaDiagnostics.php new file mode 100644 index 00000000..096bcc4d --- /dev/null +++ b/app/Services/SimulationIvaDiagnostics.php @@ -0,0 +1,54 @@ + $version['valid_until'])) { + $add('period_unavailable', 'fiscal_period', 'Período', "$start a $end", $version['valid_from'].' a '.($version['valid_until'] ?? 'sem data final indicada'), 'Esta versão da regra não abrange todo o período seleccionado. Não altere a data real da operação para obter um resultado.'); + } + foreach ($parameter['conditions'] ?? [] as $key => $expected) { + $received = $context[$key] ?? null; + if ($received === $expected) { + continue; + } + if ($key === 'currency') { + $category = $received === null || $received === '' ? 'missing_field' : (preg_match('/^[A-Z]{3}$/D', $received) ? 'out_of_scope' : 'invalid_value'); + $add($category, 'fiscal_currency', 'Moeda', $received, $expected, $category === 'missing_field' ? 'Indique a moeda da operação.' : 'Esta versão aceita apenas '.$expected.'. Reveja a moeda ou utilize um cálculo adequado à operação; a resposta não foi alterada.'); + } elseif ($key === 'operation' && ! array_key_exists('operation', $context) && $expected === 'internal_general_net' && in_array($context['fiscal_operation'] ?? null, ['import', 'export', 'non_resident', 'refund'], true)) { + $add('out_of_scope', 'fiscal_operation', 'Operação', $context['fiscal_operation'], 'Operação interna à taxa geral, sobre base líquida já apurada', 'A operação declarada está excluída desta versão. Utilize um cálculo adequado à operação; não altere a resposta para obter um resultado.'); + } elseif ($key === 'operation' && ! array_key_exists('operation', $context)) { + $add('system_configuration', 'fiscal_operation', 'Operação', $context['fiscal_operation'] ?? null, $expected === 'internal_general_net' ? 'Operação interna à taxa geral, sobre base líquida já apurada' : $expected, 'Limitação de integração do sistema: esta consulta não comunica o enquadramento específico exigido pela versão. A resposta genérica não permite inferi-lo. Utilize o formulário IVA — taxa geral, com declaração explícita do âmbito; não altere respostas para forçar compatibilidade.'); + } elseif ($key === 'operation') { + $add($received === null || $received === '' ? 'missing_field' : 'out_of_scope', 'fiscal_operation', 'Operação', $received, $expected === 'internal_general_net' ? 'Operação interna à taxa geral, sobre base líquida já apurada' : $expected, 'A operação não está abrangida por esta versão; utilize um cálculo adequado à operação declarada.'); + } else { + $add('system_configuration', null, 'Configuração da regra', null, 'Condições publicadas ligadas a campos deste formulário', 'O sistema não consegue relacionar todas as condições desta versão com o formulário. Não é uma falha das suas respostas.'); + } + } + if (! SimulationFiscalSourceAcceptance::eligible($version['source'] ?? [], $version['source_sha256'] ?? null) + || ($version['source_version_no'] ?? null) !== ($version['source']['version_no'] ?? null) + || ($version['rule_definition']['language'] ?? null) !== 'investmoz.tax.v1') { + $add('system_configuration', null, 'Regra', null, 'Versão publicada com fonte e configuração coerentes', 'A configuração ou a fonte da regra não permite resolver este parâmetro. Não altere as respostas; é necessária correcção do sistema.'); + } + if ($issues !== []) { + $source = array_intersect_key($version['source'] ?? [], array_flip(['title', 'diploma', 'article', 'url'])); + $diagnostics[] = ['label' => 'IVA — taxa geral', 'rule_version' => $version['rule_version'], 'validity' => ['start' => $version['valid_from'], 'end' => $version['valid_until']], 'source' => $source, 'issues' => $issues]; + } + } + + return $diagnostics; + } +} diff --git a/app/Services/SimulationTaxParameterResolver.php b/app/Services/SimulationTaxParameterResolver.php index e669c5f5..7fcaf329 100644 --- a/app/Services/SimulationTaxParameterResolver.php +++ b/app/Services/SimulationTaxParameterResolver.php @@ -53,9 +53,9 @@ final class SimulationTaxParameterResolver * never executes a tax formula and requires each parameter to declare context. * * @param array $context - * @return list> + * @return list>|array{parameters:list>,diagnostics:list>} */ - public function resolvePublishedForPeriod(string $component, string $periodStart, string $periodEnd, array $context): array + public function resolvePublishedForPeriod(string $component, string $periodStart, string $periodEnd, array $context, bool $diagnostics = false): array { $start = $this->date($periodStart); $end = $this->date($periodEnd); @@ -67,14 +67,14 @@ final class SimulationTaxParameterResolver ->join('investment_legal_sources as source', 'source.id', '=', 'rule.legal_source_id') ->where('rule.component', $component) ->where('rule.status', 'published') - ->whereDate('rule.valid_from', '<=', $periodEnd) - ->where(fn ($query) => $query->whereNull('rule.valid_until')->orWhereDate('rule.valid_until', '>=', $periodStart)) + ->when(! $diagnostics, fn ($query) => $query->whereDate('rule.valid_from', '<=', $periodEnd) + ->where(fn ($query) => $query->whereNull('rule.valid_until')->orWhereDate('rule.valid_until', '>=', $periodStart))) ->where(fn ($query) => $query->where('source.validation_status', 'validated')->orWhere(fn ($fiscal) => $fiscal->where('source.validation_status', 'pending')->where('source.fiscal_acceptance->scope', 'fiscal_parameters') ->where('source.fiscal_acceptance->basis', 'Tempo-official-sources-20261008') ->whereRaw("source.fiscal_acceptance->>'sha256'=rule.source_sha256"))) ->whereColumn('source.version_no', 'rule.source_version_no') - ->whereDate('source.valid_from', '<=', $periodStart) - ->where(fn ($query) => $query->whereNull('source.valid_until')->orWhereDate('source.valid_until', '>=', $periodEnd)) + ->when(! $diagnostics, fn ($query) => $query->whereDate('source.valid_from', '<=', $periodStart) + ->where(fn ($query) => $query->whereNull('source.valid_until')->orWhereDate('source.valid_until', '>=', $periodEnd))) ->select([ 'rule.id', 'rule.rule_code', 'rule.rule_version', 'rule.component', 'rule.scope_key', 'rule.valid_from', 'rule.valid_until', 'rule.parameters', 'rule.rule_definition', @@ -121,7 +121,11 @@ final class SimulationTaxParameterResolver ]; })->all()); - return $this->resolveAvailableParameters($versions, $component, $periodStart, $periodEnd, $context); + $parameters = $this->resolveAvailableParameters($versions, $component, $periodStart, $periodEnd, $context); + + $resolvedIva = array_filter($parameters, fn (array $parameter): bool => $parameter['parameter_code'] === 'IVA_GENERAL_RATE' && $parameter['status'] === 'resolved'); + + return $diagnostics ? ['parameters' => $parameters, 'diagnostics' => $resolvedIva !== [] ? [] : (new SimulationIvaDiagnostics)->explain($versions, $periodStart, $periodEnd, $context)] : $parameters; } /** diff --git a/docs/investmoz/simulations/integrated-review-continuation-20261020-receipt.json b/docs/investmoz/simulations/integrated-review-continuation-20261020-receipt.json index ea8583c9..fd6d8102 100644 --- a/docs/investmoz/simulations/integrated-review-continuation-20261020-receipt.json +++ b/docs/investmoz/simulations/integrated-review-continuation-20261020-receipt.json @@ -1179,5 +1179,57 @@ "calculations_exporters_repeated": false }, "remaining": [] + }, + "iva_query_diagnostic_qa_20261021": { + "recorded_utc": "2026-10-21T11:35:00.737064+00:00", + "scope": "QA only, parameter-query diagnosis; no calculation/export retest, no destination writes", + "reported_surface": "Componentes fiscais e contributivas, IVA_GENERAL_RATE, annual 2026-01-01 to2026-12-31, indeterminate_context", + "confirmed_origin": "Implementation integration gap: query sent fiscal_operation and no currency/operation, whereas the published IVA parameter requires operation=internal_general_net and currency=MZN. Resolver collapsed every mismatch to indeterminate_context and UI blamed responses without individual evidence.", + "original_answers_known": "Only the period/component/message were provided. No original currency or operation is asserted; USD/domestic are explicit directed QA cases, not inferred original answers.", + "diagnostic_categories": [ + "missing_field", + "invalid_value", + "out_of_scope", + "period_unavailable", + "system_configuration" + ], + "changes": [ + "Server projects each failed criterion, field, received value, expected criterion, source and exact rule version; no expression projection", + "Explicit fiscal_currency answer for IVA query, persisted and recovered; no copy/conversion from budget or IVA-base currency", + "Generic domestic is never silently equated to internal_general_net; integration limitation is explained and links to explicit IVA form", + "Inline notes plus summary links, human IVA — taxa geral label and Ver fundamento disclosure", + "Period diagnostic can inspect published candidates outside queried period under existing visibility policy; selection/calculation eligibility unchanged", + "No eligible visible candidate remains explicitly uncertain; no invented input fault" + ], + "verification": { + "new_unit_tests": 5, + "new_unit_assertions": 24, + "targeted_api_tests": 1, + "targeted_api_assertions": 16, + "existing_resolver_regression_tests": 7, + "existing_resolver_regression_assertions": 25, + "typescript": "passed", + "build": "passed, exit0", + "pint": "passed", + "edge": "Normal simulator query, annual2026; missing currency then explicitly chosen USD; inline/summary linked fields focused; source/version disclosure; USD and generic operation preserved after save/recovery; internal code and expression absent from query text", + "no_simulation_created_by_api_diagnostic": true + }, + "qa_fixture": { + "rule_version": 3, + "state_after_proof": "suspended", + "consumer_enabled": false, + "database": "simulator_fiscal_delta_20261021_test", + "imported_into_homologation": false + }, + "test_database": "simulator_fiscal_checks_20261021_test, existing QA schema correction applied before targeted API test; isolated guard preserved", + "proofs": [ + "outputs/simulator-continuation-20261020/iva-diagnostic-api-test.txt", + "outputs/simulator-continuation-20261020/iva-diagnostic-summary.txt", + "outputs/simulator-continuation-20261020/iva-diagnostic-summary.png", + "outputs/simulator-continuation-20261020/iva-diagnostic-build-final.txt" + ], + "main_integrated": false, + "homologation_rule_changed": false, + "legal_coverage_expanded": false } } diff --git a/docs/investmoz/unification/traceability-and-manual.md b/docs/investmoz/unification/traceability-and-manual.md index 411e304e..9fa40a99 100644 --- a/docs/investmoz/unification/traceability-and-manual.md +++ b/docs/investmoz/unification/traceability-and-manual.md @@ -1961,3 +1961,22 @@ Para suspender, desligar `INVESTMOZ_IVA_CONSUMER_ENABLED` e reiniciar graciosame Activação separada aplicada em21/10/2026 às10:55:58UTC, alterando apenas as três chaves do consumidor. Ligação exacta aoID acima, rule_version1 eenabled=true; restante configuração preservada. `/api/v1/fiscal-consumer` confirmouenabled=true porHTTP200; a leitura do resolvedor, sem executar cálculo, confirmouIVA_GENERAL_RATE=16percent, mesmoID/versão/fonte no contextoMZN/internal_general_net de2026. Cinco eventos de governação; contagens de resultados/relatórios preservadas, sem simulações sintéticas no destino. O restauro de segurança e a configuração anterior estão conservados no arquivo privado identificado no recibo. Suspensão concreta: configurar `INVESTMOZ_IVA_CONSUMER_ENABLED=false` e executar o reinício gracioso existente `php8.4 artisan queue:restart` na releaseactual como operador autorizado; ou `POST /api/v2/investment/admin/tax-rules/01a15e1a-5338-700f-8a45-f87707d696a7/suspend`, com `version_no:5` enquanto corrente e evidência verdadeira de pelo menos20caracteres, pela administração autenticada/MFA. Não repetir a suspensão se o estado/versão já tiver mudado. Conservar a ligação e todos os registos; futuras retomas respeitam o estado da regra e o procedimento de versão aplicável, sem escolher automaticamente outra regra. + + +### Diagnóstico da consulta IVA — correcção em QA,21/10/2026 + +O caso reportado identifica «Componentes fiscais e contributivas», IVA_GENERAL_RATE, período01/01/2026–31/12/2026 e «As condições publicadas não correspondem às respostas indicadas». É consulta de parâmetros, não execução do consumidor IVA. O utilizador não forneceu a moeda ou a operação originais; não se afirma que tenha seleccionadoUSD, omitido um campo ou indicado uma operação excluída. + +**Causa confirmada no contrato:** o formulário envia `fiscal_operation`, sem `operation` ou `currency`; a versão publicada exige `operation=internal_general_net` e `currency=MZN`. A validação da consulta nem aceitava esses nomes canónicos. O resolvedor reduzia qualquer condição falhada a `indeterminate_context`; a interface mostrava apenas a frase genérica e o código interno. Esta restrição de ligação é escolha de implementação, não condição organizacional ou jurídica adicional da Tempo. O mesmo contrato reproduziu o estado no período anual reportado, independentemente de se presumir uma moeda no caso original. + +**Correcção delimitada:** cada condição não satisfeita tem categoria, campo, valor recebido e critério esperado, ligados à versão e fonte. Distinguem-se campo em falta, formato inválido, operação/moeda fora do âmbito, versão que não cobre o período e configuração do sistema. Quando não existe versão elegível visível e a evidência não permite separar ausência de cobertura de indisponibilidade de fonte/configuração, a interface mantém essa incerteza; não inventa uma causa nem atribui culpa às respostas. + +A consulta IVA passa a ter moeda explícita (`fiscal_currency`), guardada no rascunho, sem presumirMZN ou copiar moeda do orçamento ou do cálculo IVA. A API recebe esse valor em `context.currency`. A operação genérica não se converte automaticamente no âmbito «operação interna à taxa geral sobre base líquida»: a limitação de integração é explicada com a resposta recebida e o critério esperado, e existe ligação para o formulário IVA com declaração explícita do âmbito. Uma importação/exportação/não residente/reembolso expressamente seleccionado é identificado como exclusão deste lote; não se altera a resposta para a fazer passar. + +As notas aparecem junto dos campos e num resumo com ligações que focam o campo correspondente, mantendo o rascunho. O nome apresentado é «IVA — taxa geral»; «Ver fundamento» contém versão, vigência e fonte, sem expressãoDSL. As falhas de consulta/configuração são identificadas como sistema. O percurso de cálculo e as suas regras de admissão não foram ampliados. A consulta diagnóstica pode observar versões publicadas fora do período seleccionado, sob a mesma política de visibilidade, apenas para explicar a falta de cobertura; não as torna elegíveis. + +**Prova dirigida:**5testes unitários novos/24asserções;1testeAPI/16asserções no clone isolado simulator_fiscal_checks_20261021_test;7testes existentes do resolvedor/25asserções; TypeScript, build(exit0), Pint e diff-check. A primeira execuçãoAPI detectou que esse clone ainda não tinha a coluna fiscal_acceptance; aplicou-se nele a correcção de esquema já aceite, com a guardaQA intacta, e repetiu-se apenas o testeAPI afectado. Não é diagnóstico da base de homologação. A comparação por índice do ensaio foi ajustada à ordem das chavesJSONB; não se alterou o critério fiscal. + +No Edge, simulador normal QA em127.0.0.1:18580: consulta anual2026, operação genérica explicitamente escolhida para o ensaio; moeda inicialmente vazia, depoisUSD escolhido expressamente como caso dirigido. Confirmaram-se notas, resumo, foco em «Rever moeda»/«Rever operação», fundamento da versão sintética3, eUSD/ano/periodicidade/operação conservados após gravação e recuperação do mesmo rascunho. A captura de prova é um ensaioUSD, não evidência deUSD no caso original. Não se executou cálculo nem se exportou relatório. A fixture publicada apenas emQA para observar o diagnóstico foi depois suspensa; o consumidorQA permaneceu desligado. Nenhuma fixture foi importada, regra alterada ou consumidor activado na homologação nesta correcção. + +Provas privadas na pasta `outputs/simulator-continuation-20261020`: iva-diagnostic-api-test.txt, iva-diagnostic-summary.txt, iva-diagnostic-summary.png e iva-diagnostic-build-final.txt. O reciboJSON existente tem o estado detalhado. A candidata permanece na branch `codex/iva-diagnostics-QA`, separada de main; não é uma nova publicação fiscal nem altera a entrega autorizada anteriormente. diff --git a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv index 0fdad18c..cfff3132 100644 --- a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv +++ b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv @@ -10652,7 +10652,7 @@ AUD-SEARCH-T10,Consistência transversal da pesquisa e navegação — Bibliotec AUD-SEARCH-T11,Consistência transversal da pesquisa e navegação — Legislação,Instruções expressas da Tempo na conversa de 20/10/2026; AGENTS.md; RF-MN-010 e AUD-GEO-01 preservados.,navegação/pesquisa,/legislacao,portal/services; portal/document — Reutiliza a correcção da biblioteca e preserva filtros jurídicos/documentais pertinentes.,Sem alteração remota nesta execução; revisão apenas na branch codex/opportunity-search.,HTTP/Inertia: resources.total=0; consumidor e query pública partilhados.,QA — delta delimitado; revisão Tempo pendente,"Situação jurídica, consulta e cálculo continuam independentes.",,"Filtros, contagem, resultados e URL coerentes; universos identificados; erro distinto de vazio; permissões e contexto conservados.",P1,,RF-MN-010; AUD-GEO-01,,,,,,,,,,,Mesmo padrão da biblioteca; não deve expor um universo concorrente.,"Situação jurídica, consulta e cálculo continuam independentes.",portal/services; portal/document; SearchState; SearchFeedback; TerritoryFields; portalNavigation,,"Integração em main apenas após revisão; assistência NLP, contratos e P7 separados.",Correcção/simplificação em QA,,HTTP/Inertia: resources.total=0; consumidor e query pública partilhados.,Pesquisa transversal QA 20/10/2026,20/10/2026,,,,,,,,,,"Provas comuns cobrem o componente reutilizado; HTTP vazio não demonstra operações de gestão ou publicação. Situação jurídica, consulta e cálculo continuam independentes.",,falha funcional; navegação; apresentação visual,,Disponível para revisão na aplicação QA local. AUD-GUIDE-CARD-20261020,"Related educational cards: image, source summary, clear actions",Tempo 20/10/2026; independent delta after 0e7d51f18fb4,educational presentation,/sectores/{slug}; /explorar/{group}; articles; /oportunidades and detail,EducationalArticleCard; EducationalGuides; LegacyContent; SectorInvestment,QA only,1 test / 8 assertions; PHP syntax; TypeScript/build; desktop2048/mobile390; keyboard,QA review pending,Normal QA sector and article verified against existing library resource 10 and local image 25; previous dossier proof retained,,Source-derived summary; public images; conditional opportunity action; context preserved,P1,,,,,,,,,,,,,,,,,,presentation,,,,20/10/2026,,,,,,,,,,,,content; navigation; visual presentation,,Ready for QA review AUD-SIM-INT01,Invalid one-off fiscal date can throw instead of returning validation state,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Fixed in QA; invalid-date checks; 38 directed frontend tests passed,Previous inline-date proof retained; unchanged delta not repeated,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P0,,,,,,,,,,,,,,,,,,diagnosis and targeted corrections,, | [Saldo consolidado21/10/2026] Concluído no recorte. Nenhum delta de validação de data por demonstrar; prova anterior preservada. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação.,,20/10/2026,,,,,,,,,,,,,, -AUD-SIM-INT02,Review actual fiscal parameters sources periods and eligibility,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Verification pending; no parameter activation,Recorte IVA geral sobre base declarada disponibilizado: 4a4d1212 integrado na revisao servida d3fe8a02; regra real v1 publicada e consumidor activo. Nao conclui o simulador fiscal integral.,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P0,,,,,,,,,,,,,,"Nenhuma operacao de disponibilizacao pendente neste lote delimitado. Outras componentes, regimes e coberturas fiscais permanecem fora do recorte; nao repetir provas aceites.",,,"Tempo autorizou incorporacao de 4a4d1212, cadastro/publicacao da regra real e activacao. Mesma administracao real nala@tempo.co.mz, login normal e MFA, sem quatro designacoes; sem parecer juridico ou revisao independente atribuidos a Tempo.",Ligacao de consumidor publicada concluida em QA; decisoes operacionais separadas.,Recorte executado; sem saldo de implementacao ou disponibilizacao identificado neste lote. Nao converter estimativas anteriores em implementacao fiscal integral.," | [Leitura SSH 21/10/2026 08:17 Maputo] Zero regras em simulation_tax_rule_versions na homologação, incluindo todos os estados por leitura administrativa sem ocultação RLS. Seis referências em investment_legal_sources; não são parâmetros executáveis. QA também tinha zero regras. BEGIN READ ONLY/SELECT/ROLLBACK; zero escritas. Prova homologation-fiscal-readonly.json. O git HEAD registado é do checkout consultado, não certifica a revisão do build servido. A ausência de cadastro não é ausência de fontes oficiais nem reabre a aceitação da Tempo de 08/10. Não implementa a ligação funcional ao motor fiscal. | [Saldo consolidado21/10/2026] Parcial. Leitura remota concluída: zero regras de todos os estados na homologação, tal como QA; seis referências jurídicas não são parâmetros executáveis. Falta cadastro fundamentado por componente/âmbito/período e ligação funcional ao motor fiscal. Fontes e análises existentes reutilizáveis; aceitação oficial da Tempo de08/10 preservada. Não activar taxas nem importar/publicar por esta reconciliação. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação. | [Candidata21/10/2026] Diagnóstico fiscal separado no manual existente: fontes/analises já disponíveis; zero parâmetros executáveis na QA e homologação por leitura de todos os estados; governação/resolvedor temporal/DSL existentes; RunSimulation ainda aritmética personalizada sem consumir regras fiscais. Saldo: cadastro fundamentado, orquestração, contrato de resultado/histórico e ligação ao dossier/relatório, com casos por componente/período. Nenhuma regra criada nem activada; implementação fiscal integral aberta e excluída das1–2h de exportações. | [Proposta21/10/2026] Primeiro lote proposto: uma regra IVA geral sobre base liquida/MZN, cobertura demonstrada2026 sem inventar caducidade legal. Reutilizar fontes/analises/governacao/resolvedor/avaliador existentes; arredondamento e ambito aplicavel explicitamente por fundamentar antes de publicar. Cadastro4-8h e codigo/aceitacao12-20h, total16-28h condicionado ao acervo, separado das1-2h de exportacao. Criterios e exclusoes no manual existente. Nenhuma regra cadastrada/activada; nao e implementacao fiscal integral. | [QA IVA v1.2 21/10/2026] Orientacao posterior Tempo: calcular com precisao decimal exacta sem arredondamento automatico, separando apresentacao monetaria; arredondamento generico deixa de ser bloqueio deste lote. Cadastro draft versionado em clone QA; resolvedor/avaliador existentes; proveniencia, historico e relatorio imutavel ligados. 5 feature (51 assercoes), 7 unit (25), 3 frontend; types/build/Pint aprovados. Contexto declarado; nao e saldo a pagar. Zero regras publicadas; sem main/activacao. Recorte QA autorizado verificado (0h engenharia identificada restante); produto fiscal integral continua parcial. Limites e provas no mesmo manual e ficha v1.2; sem atribuicao de validacao juridica ao utilizador. | [Revisao 83d2f97d] Ambito/periodo/exclusoes e procedimentos de integracao, publicacao, activacao e suspensao consolidados no mesmo manual. Lacuna concreta de ecra QA fechada: entradas 1000.03/MZN/2026-10-21; calculo exacto 160.0048; gravacao fa6d17f2-5f47-4cb6-b8cb-40850c12505f; recarga; recuperacao do mesmo ID; relatorio d13e2ad5-3ba8-4d01-9d30-5815496da774 com mesmo valor/proveniencia e hash igual ao resultado. Uma execucao persistida, draft e zero regras publicadas. 1 teste novo de rota/17 assercoes, TypeScript/build e browser aprovados; restantes provas reutilizadas. Interrupcao inicial da ferramenta resolvida, sem atribuicao de falha ao simulador. Revisao do recorte demonstrada; sem nova preparacao generica identificada, main ou activacao; nao fecha aplicabilidade fiscal universal nem simulador integral. | 21/10/2026: proposta do consumidor IVA no simulador existente no manual: falta ligacao a regra publicada e activacao explicita. Integrar codigo desligado, publicar versao e activar consumidor sao tres operacoes distintas. Reutiliza permissoes, governanca, historico e provas aceites; sem ampliar cobertura ou executar estas operacoes. | 21/10/2026: implementado delta de 2ced7b79 no simulador normal QA, activacao desligada por omissao. 8 testes/75 assercoes, 2 testes frontend novos, TypeScript/build/Pint. Edge: indeterminacao, calculo, repeticao sem duplicar, fila admitida antes de suspensao concluida depois, nova execucao recusada e historicos/relatorios preservados. Mesmo manual e recibo consolidam provas e tres operacoes. Fixture isolada suspensa; sem merge ou publicacao/activacao na homologacao. | 21/10/2026: origem da condicao fiscal localizada em e65cb269/servico/CHECKs de 03/10 e nota de implementacao; sem decisao expressa aplicavel encontrada. Correccao QA: administracao existente, mesma pessoa, fonte oficial identificada e eventos preservados. 6 testes/86 assercoes apenas do controlo, sem calculos/exportadores; constraints de outras tabelas iguais. Esquema activo nao alterado; backup/restauro de 171 tabelas confirmado; sem fixture ou publicacao real. | [Execucao autorizada 21/10/2026 10:56 UTC] Servido d3fe8a02ec7f5dcd01984c4f4a1eba18b5a0cf19 contendo 4a4d1212; DDL fiscal aplicado autenticadamente com backup/restauro de171tabelas e registos preservados. Tres fontes reais v1 com hashes/citacoes e aceitacao fiscal Tempo08/10/2026, sem validacao geral automatica. Regra IVA-GERAL-BASE-LIQUIDA rule_version1, ID01a15e1a-5338-700f-8a45-f87707d696a7, published, version_no5, actor15 emtodasetapas;5eventos. Activacao separada ligada a esseID/versao; APIHTTP200 enabled=true e resolvedor16percent no contexto delimitado sem calculo novo. FixtureQA nao importada; calculos/exportadores/PDF aceites nao repetidos. Suspensao de novas admissoes conserva snapshots/historicos/relatorios. Recibo e manual existentes actualizados; limitacoes de abertura de consola/extensao registadas como ferramenta.",,20/10/2026,,,,,,,,,,,,,, +AUD-SIM-INT02,Review actual fiscal parameters sources periods and eligibility,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Verification pending; no parameter activation,Recorte IVA geral sobre base declarada disponibilizado: 4a4d1212 integrado na revisao servida d3fe8a02; regra real v1 publicada e consumidor activo. Nao conclui o simulador fiscal integral.,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P0,,,,,,,,,,,,,,"Nenhuma operacao de disponibilizacao pendente neste lote delimitado. Outras componentes, regimes e coberturas fiscais permanecem fora do recorte; nao repetir provas aceites.",,,"Tempo autorizou incorporacao de 4a4d1212, cadastro/publicacao da regra real e activacao. Mesma administracao real nala@tempo.co.mz, login normal e MFA, sem quatro designacoes; sem parecer juridico ou revisao independente atribuidos a Tempo.",Ligacao de consumidor publicada concluida em QA; decisoes operacionais separadas.,Recorte executado; sem saldo de implementacao ou disponibilizacao identificado neste lote. Nao converter estimativas anteriores em implementacao fiscal integral.," | [Leitura SSH 21/10/2026 08:17 Maputo] Zero regras em simulation_tax_rule_versions na homologação, incluindo todos os estados por leitura administrativa sem ocultação RLS. Seis referências em investment_legal_sources; não são parâmetros executáveis. QA também tinha zero regras. BEGIN READ ONLY/SELECT/ROLLBACK; zero escritas. Prova homologation-fiscal-readonly.json. O git HEAD registado é do checkout consultado, não certifica a revisão do build servido. A ausência de cadastro não é ausência de fontes oficiais nem reabre a aceitação da Tempo de 08/10. Não implementa a ligação funcional ao motor fiscal. | [Saldo consolidado21/10/2026] Parcial. Leitura remota concluída: zero regras de todos os estados na homologação, tal como QA; seis referências jurídicas não são parâmetros executáveis. Falta cadastro fundamentado por componente/âmbito/período e ligação funcional ao motor fiscal. Fontes e análises existentes reutilizáveis; aceitação oficial da Tempo de08/10 preservada. Não activar taxas nem importar/publicar por esta reconciliação. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação. | [Candidata21/10/2026] Diagnóstico fiscal separado no manual existente: fontes/analises já disponíveis; zero parâmetros executáveis na QA e homologação por leitura de todos os estados; governação/resolvedor temporal/DSL existentes; RunSimulation ainda aritmética personalizada sem consumir regras fiscais. Saldo: cadastro fundamentado, orquestração, contrato de resultado/histórico e ligação ao dossier/relatório, com casos por componente/período. Nenhuma regra criada nem activada; implementação fiscal integral aberta e excluída das1–2h de exportações. | [Proposta21/10/2026] Primeiro lote proposto: uma regra IVA geral sobre base liquida/MZN, cobertura demonstrada2026 sem inventar caducidade legal. Reutilizar fontes/analises/governacao/resolvedor/avaliador existentes; arredondamento e ambito aplicavel explicitamente por fundamentar antes de publicar. Cadastro4-8h e codigo/aceitacao12-20h, total16-28h condicionado ao acervo, separado das1-2h de exportacao. Criterios e exclusoes no manual existente. Nenhuma regra cadastrada/activada; nao e implementacao fiscal integral. | [QA IVA v1.2 21/10/2026] Orientacao posterior Tempo: calcular com precisao decimal exacta sem arredondamento automatico, separando apresentacao monetaria; arredondamento generico deixa de ser bloqueio deste lote. Cadastro draft versionado em clone QA; resolvedor/avaliador existentes; proveniencia, historico e relatorio imutavel ligados. 5 feature (51 assercoes), 7 unit (25), 3 frontend; types/build/Pint aprovados. Contexto declarado; nao e saldo a pagar. Zero regras publicadas; sem main/activacao. Recorte QA autorizado verificado (0h engenharia identificada restante); produto fiscal integral continua parcial. Limites e provas no mesmo manual e ficha v1.2; sem atribuicao de validacao juridica ao utilizador. | [Revisao 83d2f97d] Ambito/periodo/exclusoes e procedimentos de integracao, publicacao, activacao e suspensao consolidados no mesmo manual. Lacuna concreta de ecra QA fechada: entradas 1000.03/MZN/2026-10-21; calculo exacto 160.0048; gravacao fa6d17f2-5f47-4cb6-b8cb-40850c12505f; recarga; recuperacao do mesmo ID; relatorio d13e2ad5-3ba8-4d01-9d30-5815496da774 com mesmo valor/proveniencia e hash igual ao resultado. Uma execucao persistida, draft e zero regras publicadas. 1 teste novo de rota/17 assercoes, TypeScript/build e browser aprovados; restantes provas reutilizadas. Interrupcao inicial da ferramenta resolvida, sem atribuicao de falha ao simulador. Revisao do recorte demonstrada; sem nova preparacao generica identificada, main ou activacao; nao fecha aplicabilidade fiscal universal nem simulador integral. | 21/10/2026: proposta do consumidor IVA no simulador existente no manual: falta ligacao a regra publicada e activacao explicita. Integrar codigo desligado, publicar versao e activar consumidor sao tres operacoes distintas. Reutiliza permissoes, governanca, historico e provas aceites; sem ampliar cobertura ou executar estas operacoes. | 21/10/2026: implementado delta de 2ced7b79 no simulador normal QA, activacao desligada por omissao. 8 testes/75 assercoes, 2 testes frontend novos, TypeScript/build/Pint. Edge: indeterminacao, calculo, repeticao sem duplicar, fila admitida antes de suspensao concluida depois, nova execucao recusada e historicos/relatorios preservados. Mesmo manual e recibo consolidam provas e tres operacoes. Fixture isolada suspensa; sem merge ou publicacao/activacao na homologacao. | 21/10/2026: origem da condicao fiscal localizada em e65cb269/servico/CHECKs de 03/10 e nota de implementacao; sem decisao expressa aplicavel encontrada. Correccao QA: administracao existente, mesma pessoa, fonte oficial identificada e eventos preservados. 6 testes/86 assercoes apenas do controlo, sem calculos/exportadores; constraints de outras tabelas iguais. Esquema activo nao alterado; backup/restauro de 171 tabelas confirmado; sem fixture ou publicacao real. | [Execucao autorizada 21/10/2026 10:56 UTC] Servido d3fe8a02ec7f5dcd01984c4f4a1eba18b5a0cf19 contendo 4a4d1212; DDL fiscal aplicado autenticadamente com backup/restauro de171tabelas e registos preservados. Tres fontes reais v1 com hashes/citacoes e aceitacao fiscal Tempo08/10/2026, sem validacao geral automatica. Regra IVA-GERAL-BASE-LIQUIDA rule_version1, ID01a15e1a-5338-700f-8a45-f87707d696a7, published, version_no5, actor15 emtodasetapas;5eventos. Activacao separada ligada a esseID/versao; APIHTTP200 enabled=true e resolvedor16percent no contexto delimitado sem calculo novo. FixtureQA nao importada; calculos/exportadores/PDF aceites nao repetidos. Suspensao de novas admissoes conserva snapshots/historicos/relatorios. Recibo e manual existentes actualizados; limitacoes de abertura de consola/extensao registadas como ferramenta. | [Diagnostico IVA QA21/10/2026] Falha estrutural reproduzida na consulta anual: fiscal_operation nao satisfaz operation e moeda nao era comunicada. Sem presumir respostas originais. Cada condicao tem campo/recebido/esperado/categoria; notas junto ao campo, resumo com foco e Ver fundamento semDSL/codigo. Moeda fiscal explicita, sem conversao/copia.5unitarios24assercoes+1API16assercoes, Edge comUSD dirigido preservado apos recuperacao; fixtureQA v3suspensa, consumidorQAoff. Nao altera regra/activacao da homologacao; calculos e exportadores nao repetidos. Branch codex/iva-diagnostics-QA.",,20/10/2026,,,,,,,,,,,,,, AUD-SIM-INT03,Review isolation recovery across projects and sessions,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Existing controls and accepted proofs to reconcile; no leak established,Two dossiers and new login recovered in browser; cashflow persistence corrected and HTTP-tested; new visual cashflow delta pending,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P0,,,,,,,,,,,,,,,,,,diagnosis and targeted corrections,,"[Retoma 21/10/2026] QA 18576, clone simulator_review_delta_20261020_test: sessão sintética renovada por login normal; gravação autenticada e recarga recuperaram saldo 123, receita 900, custos 600, calendário mensal 10/vazio/0, crédito IVA estimado 500. Caixa conhecida 3713 MZN; total indeterminado desde mês 2; crédito estimado excluído da caixa. Prova visual cashflow-recovered-20261021.png e snapshot .txt em outputs/simulator-continuation-20261020. Não certifica recuperação destes novos valores após outro login, CSV/DOCX ou PDF nativo. Ligação de controlo do navegador perdida durante espera de download; não atribuir falha à aplicação. Leitura remota aguarda identificação da ligação SSH; zero alterações no destino. | [Saldo consolidado21/10/2026] Concluído no recorte. A/B, logout/novo login, recuperação e recusa pela aplicação demonstrados anteriormente. A tesouraria tem prova API de nova sessão e prova visual de recuperação por recarga. Não atribuir ao navegador nova sessão dos valores de tesouraria, nem nova certificação RLS; limites expressos conservados. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação.",,20/10/2026,,,,,,,,,,,,,, AUD-SIM-INT04,Review stale and historical results and correct dossier,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Existing versions/fingerprints; targeted verification pending,Historical results visible after fix; 12 and 24 recovered; hashes unchanged; synthetic temporal resolver versions verified in memory only,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P1,,,,,,,,,,,,,,,,,,diagnosis and targeted corrections,," | [Saldo consolidado21/10/2026] Concluído no recorte demonstrado. Histórico24/12 visível, hashes preservados e versões temporais sintéticas do resolvedor conferidas. Execução fiscal integrada com parâmetros reais pertence ao saldo de02 e não foi demonstrada por estes testes. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação.",,20/10/2026,,,,,,,,,,,,,, AUD-SIM-INT05,Independent financial controls unknown zero units and currencies,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Reconciliation pending; no invented tax assumptions,Independent business-plan and cashflow ledgers passed; complete credit recipe included in screen and exports,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P1,,,,,,,,,,,,,,,,,,diagnosis and targeted corrections,,"[Retoma 21/10/2026] QA 18576, clone simulator_review_delta_20261020_test: sessão sintética renovada por login normal; gravação autenticada e recarga recuperaram saldo 123, receita 900, custos 600, calendário mensal 10/vazio/0, crédito IVA estimado 500. Caixa conhecida 3713 MZN; total indeterminado desde mês 2; crédito estimado excluído da caixa. Prova visual cashflow-recovered-20261021.png e snapshot .txt em outputs/simulator-continuation-20261020. Não certifica recuperação destes novos valores após outro login, CSV/DOCX ou PDF nativo. Ligação de controlo do navegador perdida durante espera de download; não atribuir falha à aplicação. Leitura remota aguarda identificação da ligação SSH; zero alterações no destino. | [Saldo consolidado21/10/2026] Concluído nos controlos delimitados. Controlos independentes de caixa/plano/crédito, zero/desconhecido e moedas preservados. Não são validação de taxas legais nem certificação de toda a contabilidade. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação.",,20/10/2026,,,,,,,,,,,,,, diff --git a/resources/js/components/simulation-fiscal-status.tsx b/resources/js/components/simulation-fiscal-status.tsx index 846a3b52..94aa4056 100644 --- a/resources/js/components/simulation-fiscal-status.tsx +++ b/resources/js/components/simulation-fiscal-status.tsx @@ -1,5 +1,6 @@ import { useEffect, useState } from 'react'; import { fiscalComponentCodes } from '@/lib/simulation-contract'; +import { ivaIssueText, type IvaDiagnostic, type IvaIssue } from '@/lib/iva-diagnostics'; type Parameter = { parameter_code: string; @@ -56,6 +57,8 @@ export function SimulationFiscalStatus({ periodStart, periodEnd, context, + onDiagnostics, + onCorrect, }: { salaryView?: string; scenarioMode?: string; @@ -63,8 +66,11 @@ export function SimulationFiscalStatus({ periodStart?: string; periodEnd?: string; context?: Record; + onDiagnostics?: (issues: IvaIssue[]) => void; + onCorrect?: (field: string) => void; }) { const [parameters, setParameters] = useState([]); + const [diagnostics, setDiagnostics] = useState([]); const [requestState, setRequestState] = useState('idle'); const [retry, setRetry] = useState(0); @@ -79,10 +85,14 @@ export function SimulationFiscalStatus({ !periodEnd ) { setParameters([]); + setDiagnostics([]); + onDiagnostics?.([]); setRequestState('idle'); return; } const abort = new AbortController(); + setDiagnostics([]); + onDiagnostics?.([]); setRequestState('loading'); void fetch('/api/v1/tax-parameters/resolve', { method: 'POST', @@ -104,11 +114,15 @@ export function SimulationFiscalStatus({ if (!response.ok) throw new Error('lookup_failed'); const payload = (await response.json()) as { parameters?: Parameter[]; + diagnostics?: IvaDiagnostic[]; }; if (abort.signal.aborted) return; setParameters( Array.isArray(payload.parameters) ? payload.parameters : [], ); + const details = Array.isArray(payload.diagnostics) ? payload.diagnostics : []; + setDiagnostics(details); + onDiagnostics?.(details.flatMap((detail) => detail.issues)); setRequestState('done'); }) .catch((error: unknown) => { @@ -158,7 +172,7 @@ export function SimulationFiscalStatus({ {requestState === 'loading' ? 'A consultar parâmetros aprovados para o período e âmbito indicados…' : requestState === 'error' - ? 'Não foi possível consultar os parâmetros; o resultado permanece indeterminado.' + ? 'Falha na consulta do sistema: não foi possível obter os parâmetros. O problema não é atribuído às respostas; estas foram preservadas. Tente novamente.' : !periodStart || !periodEnd ? 'Indique um período exacto. Para periodicidade mensal ou trimestral, seleccione o mês ou trimestre.' : `Período consultado: ${periodStart} a ${periodEnd}.`} @@ -186,6 +200,22 @@ export function SimulationFiscalStatus({ {salaryViewMessages[salaryView]}

)} + {diagnostics.length > 0 &&
+

IVA — taxa geral: condições não satisfeitas

+

Não foi possível resolver este parâmetro. As respostas foram preservadas; esta consulta não executa o cálculo do imposto.

+ {diagnostics.map((detail, index) =>
+ +
Ver fundamento +

IVA — taxa geral · versão {detail.rule_version}. Vigência: {detail.validity.start} a {detail.validity.end ?? 'sem data final indicada'}.

+

{detail.source.title} — {detail.source.diploma}, {detail.source.article}

+ {detail.source.url?.startsWith('https://') && Consultar fonte} +
+
)} +
}
    {fiscalComponentCodes.map((code) => { const selected = @@ -211,13 +241,13 @@ export function SimulationFiscalStatus({

    ) : parameters.length === 0 ? (

    - Indeterminado — nenhum parâmetro publicado + {code === 'IVA' ? 'Indeterminado — não existe uma versão elegível visível nesta consulta. Consulte o diagnóstico do período acima, quando disponível. Sem esse diagnóstico, não é possível distinguir ausência de cobertura de indisponibilidade da regra ou da fonte; não se atribui o problema às suas respostas.' : <>Indeterminado — nenhum parâmetro publicado aplicável. Faltam parâmetros aprovados para{' '} {code}, no período {periodStart} a{' '} {periodEnd} e no âmbito indicado. A consulta não identifica um conjunto obrigatório de parâmetros; não é possível determinar o - imposto nem substituir as lacunas por zero. + imposto nem substituir as lacunas por zero.}

    ) : (
    @@ -227,7 +257,7 @@ export function SimulationFiscalStatus({ className="border-t pt-2" > - {parameter.parameter_code} + {parameter.parameter_code === 'IVA_GENERAL_RATE' ? 'IVA — taxa geral' : parameter.parameter_code} {parameter.status === 'resolved' ? ( <> @@ -238,10 +268,10 @@ export function SimulationFiscalStatus({

    Regra{' '} - {parameter.rule_code} v + {parameter.parameter_code === 'IVA_GENERAL_RATE' ? 'IVA — taxa geral' : parameter.rule_code} v {parameter.rule_version} ; âmbito{' '} - {parameter.scope_key} + {parameter.parameter_code === 'IVA_GENERAL_RATE' ? 'operação interna geral sobre base líquida em MZN' : parameter.scope_key}

    Vigência:{' '} @@ -279,13 +309,13 @@ export function SimulationFiscalStatus({ target="_blank" rel="noreferrer" > - Consultar fundamento + Ver fundamento )} ) : (

    - {labels[parameter.status] ?? + {(parameter.parameter_code === 'IVA_GENERAL_RATE' && diagnostics.length ? 'Consulte acima cada condição e o fundamento da versão.' : labels[parameter.status]) ?? 'Indeterminado — não foi possível validar o parâmetro.'}

    )} diff --git a/resources/js/components/simulation-form.tsx b/resources/js/components/simulation-form.tsx index 5500ae73..d6955ee1 100644 --- a/resources/js/components/simulation-form.tsx +++ b/resources/js/components/simulation-form.tsx @@ -56,6 +56,7 @@ import { SimulationFinancialTools } from '@/components/simulation-financial-tool import { SimulationCashflowPlanner } from '@/components/simulation-cashflow-planner'; import { SimulationBusinessPlan } from '@/components/simulation-business-plan'; import { SimulationFiscalStatus } from '@/components/simulation-fiscal-status'; +import { ivaIssueText, type IvaIssue } from '@/lib/iva-diagnostics'; import { ProjectMilestonePlanner, ProjectTeamPlanner, @@ -810,6 +811,7 @@ export function SimulationForm() { }); const [step, setStep] = useState(0); const [errors, setErrors] = useState>({}); + const [ivaIssues, setIvaIssues] = useState([]); const [serverFieldErrors, setServerFieldErrors] = useState< Record >({}); @@ -1936,6 +1938,7 @@ export function SimulationForm() { ) { if (!ready) return; setContinueLaterSaved(false); + setIvaIssues((previous) => previous.filter((issue) => issue.field !== key)); setServerFieldErrors((previous) => { const next = { ...previous }; delete next[key]; @@ -3285,6 +3288,7 @@ export function SimulationForm() { : Boolean(field.required); const fieldError = serverFieldErrors[field.key] ?? errors[field.key]; + const ivaNotes = ivaIssues.filter((issue) => issue.field === field.key).map((issue, index) =>

    {ivaIssueText(issue)}

    ); if (field.options) { const parentKey = field.key === 'district_id' @@ -3331,6 +3335,7 @@ export function SimulationForm() { } /> + {ivaNotes}
    ); } @@ -3405,6 +3410,7 @@ export function SimulationForm() { {fieldError}

    )} + {ivaNotes} {field.key === 'reduction' && (

    Hipótese sua, não representa um @@ -3609,6 +3615,12 @@ export function SimulationForm() { aria-label="Consulta de parâmetros fiscais" > { + const target = journeySections.findIndex((section) => (simulationFieldGroups[section.id] ?? []).some((field) => field.key === key)); + if (target >= 0) setStep(target); + window.requestAnimationFrame(() => document.getElementById(`field-${key}`)?.focus()); + }} salaryView={String(draft.irps_salary_view ?? '')} scenarioMode={ openedTool === 'fiscal' @@ -3618,7 +3630,7 @@ export function SimulationForm() { component={String(draft.fiscal_component ?? '')} periodStart={getFiscalPeriodRange(draft)?.start} periodEnd={getFiscalPeriodRange(draft)?.end} - context={Object.fromEntries( + context={{ ...Object.fromEntries( [ 'fiscal_periodicity', 'fiscal_operation', @@ -3635,7 +3647,7 @@ export function SimulationForm() { ? [[key, draft[key] as string]] : [], ), - )} + ), ...(typeof draft.fiscal_currency === 'string' && draft.fiscal_currency !== '' ? {currency: draft.fiscal_currency} : {}) }} /> )} diff --git a/resources/js/components/simulation-published-iva.tsx b/resources/js/components/simulation-published-iva.tsx index a9c484c7..079f2cff 100644 --- a/resources/js/components/simulation-published-iva.tsx +++ b/resources/js/components/simulation-published-iva.tsx @@ -51,8 +51,8 @@ export function SimulationPublishedIva({ busy, onCalculate }: { } catch { /* The execution flow already preserves and reports connection errors. */ } } - return

    -

    IVA geral sobre base líquida

    + return
    +

    IVA — taxa geral

    {message}

    Cobertura: exigibilidade em 2026, operação interna à taxa geral. A base tributável é indicada por si; não é copiada do orçamento. Sem isenções, taxas reduzidas, bases especiais, importações, deduções, declaração ou pagamento. O cálculo não valida o enquadramento jurídico.

    diff --git a/resources/js/lib/iva-diagnostics.ts b/resources/js/lib/iva-diagnostics.ts new file mode 100644 index 00000000..3a260650 --- /dev/null +++ b/resources/js/lib/iva-diagnostics.ts @@ -0,0 +1,26 @@ +export type IvaIssue = { + category: 'missing_field' | 'invalid_value' | 'out_of_scope' | 'period_unavailable' | 'system_configuration'; + field: string | null; + label: string; + received: unknown; + expected: string; + message: string; +}; +export type IvaDiagnostic = { + label: string; + rule_version: number; + validity: { start: string; end: string | null }; + source: { title?: string; diploma?: string; article?: string; url?: string }; + issues: IvaIssue[]; +}; +export const ivaIssueCategories = { + missing_field: 'Campo em falta', invalid_value: 'Valor inválido', out_of_scope: 'Fora do âmbito', + period_unavailable: 'Regra indisponível para o período', system_configuration: 'Configuração do sistema', +}; +export function ivaReceived(value: unknown): string { + const labels: Record = { domestic: 'Operação interna', internal_general_net: 'Operação interna à taxa geral, sobre base líquida', import: 'Importação', export: 'Exportação', refund: 'Reembolso', unknown: 'Não sei', non_resident: 'Operação com não residente', other: 'Outra operação' }; + return typeof value === 'string' && value !== '' ? (labels[value] ?? value) : 'Não recebido'; +} +export function ivaIssueText(issue: IvaIssue): string { + return `${issue.label}: ${ivaIssueCategories[issue.category]}. Recebido: ${ivaReceived(issue.received)}. Esperado: ${issue.expected}. ${issue.message}`; +} diff --git a/resources/js/lib/simulation-form.ts b/resources/js/lib/simulation-form.ts index a64d1327..ccaf52d6 100644 --- a/resources/js/lib/simulation-form.ts +++ b/resources/js/lib/simulation-form.ts @@ -965,6 +965,12 @@ export const simulationFieldGroups: Record< }, ], tax: [ + { + key: 'fiscal_currency', + label: 'Moeda da operação fiscal (sem conversão automática)', + options: 'currency', + showWhen: (d) => d.fiscal_component === 'iva' && d.fiscal_scenario_mode !== 'custom_planning', + }, { key: 'fiscal_period', label: 'Ano do período fiscal a simular', diff --git a/tests/Feature/SimulationPublishedFiscalTest.php b/tests/Feature/SimulationPublishedFiscalTest.php index b7df3fc5..e7add4d4 100644 --- a/tests/Feature/SimulationPublishedFiscalTest.php +++ b/tests/Feature/SimulationPublishedFiscalTest.php @@ -76,6 +76,33 @@ class SimulationPublishedFiscalTest extends TestCase return Simulation::with('reports')->findOrFail($id); } + public function test_iva_query_diagnostics_explain_the_reported_contract_gap_without_calculating_or_changing_answers(): void + { + $count = Simulation::count(); + $input = ['component' => 'IVA', 'period_start' => '2026-01-01', 'period_end' => '2026-12-31', + 'context' => ['fiscal_operation' => 'domestic', 'currency' => 'USD']]; + $this->actingAs($this->consumer)->postJson('/api/v1/tax-parameters/resolve', $input)->assertOk() + ->assertJsonPath('assumptions.currency', 'USD') + ->assertJsonPath('parameters.0.status', 'indeterminate_context') + ->assertJsonPath('diagnostics.0.label', 'IVA — taxa geral') + ->assertJsonPath('diagnostics.0.rule_version', 1) + ->assertJsonPath('diagnostics.0.issues.1.category', 'system_configuration') + ->assertJsonPath('diagnostics.0.issues.1.received', 'domestic') + ->assertJsonPath('diagnostics.0.issues.0.category', 'out_of_scope') + ->assertJsonPath('diagnostics.0.issues.0.received', 'USD') + ->assertJsonPath('diagnostics.0.issues.0.expected', 'MZN'); + unset($input['context']['currency']); + $this->postJson('/api/v1/tax-parameters/resolve', $input)->assertOk() + ->assertJsonPath('diagnostics.0.issues.0.category', 'missing_field'); + $input['context']['currency'] = 'MZN'; + $input['period_start'] = '2022-01-01'; + $input['period_end'] = '2022-12-31'; + $this->postJson('/api/v1/tax-parameters/resolve', $input)->assertOk() + ->assertJsonPath('parameters', []) + ->assertJsonPath('diagnostics.0.issues.0.category', 'period_unavailable'); + self::assertSame($count, Simulation::count()); + } + public function test_normal_simulator_admits_published_rule_and_reuses_history_and_reports(): void { $key = (string) Str::uuid(); diff --git a/tests/Unit/SimulationIvaDiagnosticsTest.php b/tests/Unit/SimulationIvaDiagnosticsTest.php new file mode 100644 index 00000000..49afc872 --- /dev/null +++ b/tests/Unit/SimulationIvaDiagnosticsTest.php @@ -0,0 +1,71 @@ + 'synthetic-qa', 'rule_code' => 'IVA-GERAL-BASE-LIQUIDA', 'rule_version' => 1, + 'component' => 'IVA', 'status' => 'published', 'scope_key' => 'mz.internal-general-net.mzn', + 'valid_from' => '2023-01-01', 'valid_until' => null, 'source_version_no' => 1, + 'source_sha256' => str_repeat('a', 64), 'rule_definition' => ['language' => 'investmoz.tax.v1'], + 'parameters' => ['IVA_GENERAL_RATE' => ['value' => '16', 'unit' => 'percent', 'conditions' => ['operation' => 'internal_general_net', 'currency' => 'MZN']]], + 'source' => ['validation_status' => 'validated', 'version_no' => 1, 'valid_from' => '2023-01-01', 'valid_until' => null, + 'title' => 'Synthetic source', 'diploma' => 'QA only', 'article' => 'Fixture', 'url' => 'https://example.invalid/official']]; + } + + public function test_reported_annual_query_contract_reproduces_the_generic_failure_and_identifies_both_missing_links(): void + { + $version = $this->version(); + $context = ['fiscal_operation' => 'domestic']; + $original = $context; + $before = (new SimulationTaxParameterResolver)->resolveAvailableParameters([$version], 'IVA', '2026-01-01', '2026-12-31', $context); + self::assertSame('indeterminate_context', $before[0]['status']); + $details = (new SimulationIvaDiagnostics)->explain([$version], '2026-01-01', '2026-12-31', $context); + self::assertSame(['system_configuration', 'missing_field'], array_column($details[0]['issues'], 'category')); + self::assertSame('domestic', $details[0]['issues'][0]['received']); + self::assertSame('MZN', $details[0]['issues'][1]['expected']); + self::assertSame($original, $context); + self::assertArrayNotHasKey('rule_definition', $details[0]); + self::assertArrayNotHasKey('rule_code', $details[0]); + } + + public function test_all_failed_conditions_are_separate_and_currency_is_not_assumed(): void + { + foreach (['' => 'missing_field', 'usd' => 'invalid_value', 'USD' => 'out_of_scope'] as $value => $category) { + $details = (new SimulationIvaDiagnostics)->explain([$this->version()], '2026-01-01', '2026-12-31', ['operation' => 'import', 'currency' => $value]); + self::assertCount(2, $details[0]['issues']); + self::assertSame('out_of_scope', $details[0]['issues'][0]['category']); + self::assertSame($category, $details[0]['issues'][1]['category']); + } + } + + public function test_period_and_broken_source_are_not_reported_as_incorrect_answers(): void + { + $version = $this->version(); + $version['source_version_no'] = 2; + $details = (new SimulationIvaDiagnostics)->explain([$version], '2022-01-01', '2022-12-31', ['operation' => 'internal_general_net', 'currency' => 'MZN']); + self::assertSame(['period_unavailable', 'system_configuration'], array_column($details[0]['issues'], 'category')); + self::assertSame('2022-01-01 a 2022-12-31', $details[0]['issues'][0]['received']); + self::assertSame(1, $details[0]['rule_version']); + self::assertSame('Synthetic source', $details[0]['source']['title']); + } + + public function test_matching_context_has_no_diagnostic_and_does_not_evaluate_an_expression(): void + { + self::assertSame([], (new SimulationIvaDiagnostics)->explain([$this->version()], '2026-01-01', '2026-12-31', ['operation' => 'internal_general_net', 'currency' => 'MZN'])); + } + + public function test_an_explicitly_excluded_generic_operation_is_reported_without_inferring_a_domestic_scope(): void + { + $details = (new SimulationIvaDiagnostics)->explain([$this->version()], '2026-01-01', '2026-12-31', ['fiscal_operation' => 'import', 'currency' => 'MZN']); + self::assertCount(1, $details[0]['issues']); + self::assertSame('out_of_scope', $details[0]['issues'][0]['category']); + self::assertSame('import', $details[0]['issues'][0]['received']); + } +} From 3f5430c3ce32d253fbc21588e76d711574d93e3b Mon Sep 17 00:00:00 2001 From: nala Date: Wed, 21 Oct 2026 14:05:46 +0200 Subject: [PATCH 3/4] Integrate monthly IVA with projected sales in QA --- .../Api/V1/SimulationController.php | 2 +- .../StoreSimulationFormDraftRequest.php | 4 +- app/Http/Requests/StoreSimulationRequest.php | 26 +- app/Services/SimulationPublishedFiscal.php | 56 +++- ...-review-continuation-20261020-receipt.json | 282 ++++++++++++++++++ .../unification/traceability-and-manual.md | 23 ++ .../v2/auditoria-portal/matriz-requisitos.csv | 2 +- .../simulation-cashflow-planner.tsx | 4 +- resources/js/components/simulation-form.tsx | 8 +- .../js/components/simulation-monthly-iva.tsx | 78 +++++ .../components/simulation-published-iva.tsx | 5 +- resources/js/lib/business-financial-plan.ts | 17 ++ resources/js/lib/fiscal-qa-preview.ts | 8 +- resources/js/lib/monthly-iva.ts | 50 ++++ resources/js/lib/project-dossier-report.ts | 1 + resources/js/lib/project-dossier.ts | 10 + .../Feature/SimulationPublishedFiscalTest.php | 69 +++++ tests/frontend/monthly-iva.test.mjs | 57 ++++ 18 files changed, 690 insertions(+), 12 deletions(-) create mode 100644 resources/js/components/simulation-monthly-iva.tsx create mode 100644 resources/js/lib/monthly-iva.ts create mode 100644 tests/frontend/monthly-iva.test.mjs diff --git a/app/Http/Controllers/Api/V1/SimulationController.php b/app/Http/Controllers/Api/V1/SimulationController.php index 3f752588..daef312a 100644 --- a/app/Http/Controllers/Api/V1/SimulationController.php +++ b/app/Http/Controllers/Api/V1/SimulationController.php @@ -40,7 +40,7 @@ class SimulationController extends Controller $organizationId = $validated['organization_id'] ?? null; $execution->authorizeOrganization($actorId, $organizationId); if (($validated['scenario_kind'] ?? null) === 'fiscal_rule_published') { - $input = array_intersect_key($validated, array_flip(['base', 'currency', 'reference_date', 'operation', 'scope_declared'])); + $input = array_intersect_key($validated, array_flip(['base', 'currency', 'reference_date', 'operation', 'scope_declared', 'monthly_sales', 'sales_vat_basis'])); $input['scope_declared'] = (bool) $input['scope_declared']; $result = $execution->createPublishedFiscal($input, $actorId, $organizationId, $token, $key); } else { diff --git a/app/Http/Requests/StoreSimulationFormDraftRequest.php b/app/Http/Requests/StoreSimulationFormDraftRequest.php index d03064b0..27b2e957 100644 --- a/app/Http/Requests/StoreSimulationFormDraftRequest.php +++ b/app/Http/Requests/StoreSimulationFormDraftRequest.php @@ -37,7 +37,7 @@ class StoreSimulationFormDraftRequest extends FormRequest 'contact_province', 'contact_district', 'preferred_channel', ]; $economic = [ - 'journey_type', 'detail_level', 'business_plan_snapshot', 'financial_tools_snapshot', 'cashflow_snapshot', 'project_team_snapshot', 'project_execution_snapshot', 'purpose', 'manifestation_type', 'preferred_language', 'project_title', 'project_summary', 'project_problem', 'target_customers', 'value_proposition', 'market_assumption', 'market_source', 'project_milestones', 'selection_labels', 'project_type', + 'monthly_iva_settings', 'monthly_iva_snapshot', 'journey_type', 'detail_level', 'business_plan_snapshot', 'financial_tools_snapshot', 'cashflow_snapshot', 'project_team_snapshot', 'project_execution_snapshot', 'purpose', 'manifestation_type', 'preferred_language', 'project_title', 'project_summary', 'project_problem', 'target_customers', 'value_proposition', 'market_assumption', 'market_source', 'project_milestones', 'selection_labels', 'project_type', 'competitor_assumption', 'sales_channel_assumption', 'marketing_approach', 'location_rationale', 'project_risk_responses_snapshot', 'project_questionnaire_version', 'customer_validation_status', 'cost_estimate_status', 'location_assessment_status', 'funding_status', 'receivables_timing_status', 'project_type_other', 'sector_id', 'activity_id', 'products_services', 'maturity_stage', 'expected_start_date', @@ -72,6 +72,8 @@ class StoreSimulationFormDraftRequest extends FormRequest 'economic_snapshot.business_plan_snapshot' => ['nullable', 'string', 'max:60000'], 'economic_snapshot.financial_tools_snapshot' => ['nullable', 'string', 'max:30000'], 'economic_snapshot.cashflow_snapshot' => ['nullable', 'string', 'max:20000'], + 'economic_snapshot.monthly_iva_settings' => ['nullable', 'string', 'max:2000'], + 'economic_snapshot.monthly_iva_snapshot' => ['nullable', 'string', 'max:60000'], 'economic_snapshot.project_team_snapshot' => ['nullable', 'string', 'max:30000'], 'economic_snapshot.project_execution_snapshot' => ['nullable', 'string', 'max:30000'], 'economic_snapshot.project_risk_responses_snapshot' => ['nullable', 'string', 'max:30000'], diff --git a/app/Http/Requests/StoreSimulationRequest.php b/app/Http/Requests/StoreSimulationRequest.php index 736bd3e3..9c673ca7 100644 --- a/app/Http/Requests/StoreSimulationRequest.php +++ b/app/Http/Requests/StoreSimulationRequest.php @@ -22,6 +22,12 @@ class StoreSimulationRequest extends FormRequest 'date_format' => 'Indique uma data de exigibilidade válida.', 'boolean' => 'Indique se declara o enquadramento da operação.', 'prohibited' => 'O campo :attribute não pode ser definido pelo cliente neste cálculo.', + 'array' => 'Indique uma lista válida em :attribute.', + 'monthly_sales.min' => 'Indique pelo menos um mês de vendas.', + 'monthly_sales.max' => 'Este lote aceita até 12 meses dentro de 2026.', + 'monthly_sales.*.date.regex' => 'Indique o primeiro dia de um mês de 2026.', + 'monthly_sales.*.date.distinct' => 'Cada mês deve aparecer apenas uma vez.', + 'monthly_sales.*.amount.present' => 'Indique o valor das vendas ou deixe-o explicitamente sem informação.', ]; } @@ -29,13 +35,31 @@ class StoreSimulationRequest extends FormRequest { return ['base' => 'base tributável', 'currency' => 'moeda', 'reference_date' => 'data de exigibilidade', 'operation' => 'operação', 'scope_declared' => 'declaração de enquadramento', 'scenario_kind' => 'tipo de cálculo', - 'rule_id' => 'regra', 'rule_version' => 'versão da regra', 'rate' => 'taxa', 'reduction' => 'redução']; + 'rule_id' => 'regra', 'rule_version' => 'versão da regra', 'rate' => 'taxa', 'reduction' => 'redução', + 'monthly_sales' => 'vendas mensais', 'monthly_sales.*.date' => 'mês da projecção', + 'monthly_sales.*.amount' => 'vendas declaradas do mês', 'sales_vat_basis' => 'tratamento do IVA nos preços']; } /** @return array> */ public function rules(): array { if ($this->input('scenario_kind') === 'fiscal_rule_published') { + if ($this->exists('monthly_sales')) { + return [ + 'scenario_kind' => ['required', 'in:fiscal_rule_published'], + 'monthly_sales' => ['required', 'array', 'min:1', 'max:12'], + 'monthly_sales.*' => ['required', 'array:date,amount'], + 'monthly_sales.*.date' => ['required', 'date_format:Y-m-d', 'regex:/^2026-\d{2}-01$/D', 'distinct'], + 'monthly_sales.*.amount' => ['present', 'nullable', 'string', 'max:40', 'regex:/^\d+(?:\.\d+)?$/D'], + 'sales_vat_basis' => ['required', 'in:net,included,unknown'], + 'currency' => ['required', 'in:MZN'], + 'scope_declared' => ['required', 'boolean'], + 'organization_id' => ['nullable', 'uuid', 'exists:organizations,id'], + 'base' => ['prohibited'], 'rate' => ['prohibited'], 'reduction' => ['prohibited'], + 'rule_id' => ['prohibited'], 'rule_version' => ['prohibited'], 'fiscal_preview' => ['prohibited'], + ]; + } + return [ 'scenario_kind' => ['required', 'in:fiscal_rule_published'], 'base' => ['required', 'string', 'max:40', 'regex:/^\d+(?:\.\d+)?$/'], diff --git a/app/Services/SimulationPublishedFiscal.php b/app/Services/SimulationPublishedFiscal.php index 6416fbb7..2ecfa5eb 100644 --- a/app/Services/SimulationPublishedFiscal.php +++ b/app/Services/SimulationPublishedFiscal.php @@ -6,6 +6,7 @@ namespace App\Services; use App\Models\InvestmentLegalSource; use App\Models\SimulationTaxRuleVersion; +use Brick\Math\BigRational; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; @@ -35,8 +36,11 @@ final class SimulationPublishedFiscal ->where('scope_key', 'mz.internal-general-net.mzn'); } - public function admit(array $input): array + public function admit(array $input, bool $missingBase = false): array { + if (isset($input['monthly_sales'])) { + return $this->admitMonthly($input); + } // Called inside createPayload, after idempotent replay, never by the worker. abort_unless(DB::transactionLevel() > 0, 500); abort_unless(config('simulation-fiscal-consumer.enabled'), 503, @@ -63,6 +67,9 @@ final class SimulationPublishedFiscal $input['reference_date'], $input['reference_date'], ['currency' => $input['currency'], 'operation' => $input['operation']]); $rate = collect($resolution)->firstWhere('parameter_code', 'IVA_GENERAL_RATE'); $missing = []; + if ($missingBase) { + $missing[] = 'taxable_sales'; + } $evaluation = null; if (! ($input['scope_declared'] ?? false)) { $missing[] = 'operation_scope'; @@ -79,4 +86,51 @@ final class SimulationPublishedFiscal return app(SimulationFiscalSnapshot::class)->build($version, $input, $resolution, $evaluation, $missing, true); } + + private function admitMonthly(array $input): array + { + $rows = []; + $baseTotal = BigRational::zero(); + $vatTotal = BigRational::zero(); + $complete = true; + $previous = null; + foreach ($input['monthly_sales'] as $sale) { + abort_unless($previous === null || $sale['date'] === date('Y-m-d', strtotime($previous.' +1 month')), 422, 'A projecção deve conter meses consecutivos, sem duplicações.'); + $previous = $sale['date']; + $known = $sale['amount'] !== null && $sale['amount'] !== ''; + $net = $input['sales_vat_basis'] === 'net'; + $month = $this->admit(['base' => $known && $net ? $sale['amount'] : null, + 'currency' => $input['currency'], 'reference_date' => $sale['date'], + 'operation' => 'internal_general_net', 'scope_declared' => $input['scope_declared']], ! $known || ! $net); + $snapshot ??= $month; + $rate = collect($month['fiscal_provenance']['resolution'])->firstWhere('parameter_code', 'IVA_GENERAL_RATE'); + $vat = $month['result']['value']; + $status = ! $known ? 'missing_sales' : (! $net ? 'unsupported_basis' : ($vat === null ? 'indeterminate' : 'calculated')); + $rows[] = ['date' => $sale['date'], 'sales_declared' => $sale['amount'], + 'net_sales' => $known && $net ? $sale['amount'] : null, + 'rate' => $vat !== null && ($rate['status'] ?? null) === 'resolved' ? $rate['value'] : null, + 'vat' => $vat, 'gross_sales' => $vat === null ? null : (string) BigRational::of($sale['amount'])->plus($vat)->toBigDecimal(), + 'status' => $status, 'rule_id' => $month['fiscal_provenance']['rule']['id'], + 'rule_version' => $month['fiscal_provenance']['rule']['rule_version']]; + if ($vat === null) { + $complete = false; + } else { + $baseTotal = $baseTotal->plus($sale['amount']); + $vatTotal = $vatTotal->plus($vat); + } + } + $value = $complete ? (string) $vatTotal->toBigDecimal() : null; + $snapshot['base'] = $complete ? (string) $baseTotal->toBigDecimal() : null; + $snapshot['indicative_total'] = $value; + $snapshot['result']['value'] = $value; + $snapshot['result']['status'] = $complete ? 'calculated' : 'indeterminate'; + $snapshot['result']['missing_inputs'] = $complete ? [] : ['monthly_sales_or_net_basis_or_scope']; + $snapshot['result']['explanation'] = 'IVA mensal sobre vendas declaradas sem IVA, pela versão publicada congelada na admissão. Valores com IVA incluído ou sem informação permanecem indeterminados. Não é imposto final a pagar.'; + $snapshot['presentation']['value'] = $value; + $snapshot['intermediate'] = null; + $snapshot['monthly_projection'] = ['input' => $input, 'rows' => $rows, + 'cash_treatment' => 'Informação separada da tesouraria: os recebimentos declarados não são aumentados pelo IVA nem o IVA é deduzido como custo ou imposto a pagar. Calendário de cobrança e liquidação fiscal não é inferido.']; + + return $snapshot; + } } diff --git a/docs/investmoz/simulations/integrated-review-continuation-20261020-receipt.json b/docs/investmoz/simulations/integrated-review-continuation-20261020-receipt.json index fd6d8102..5b70b364 100644 --- a/docs/investmoz/simulations/integrated-review-continuation-20261020-receipt.json +++ b/docs/investmoz/simulations/integrated-review-continuation-20261020-receipt.json @@ -1231,5 +1231,287 @@ "main_integrated": false, "homologation_rule_changed": false, "legal_coverage_expanded": false + }, + "monthly_iva_projection_qa_20261021": { + "branch": "codex/iva-monthly-projection-QA", + "status": "candidate_verified_in_isolated_QA_only", + "source": "existing monthly product sales; saved constant cashflow revenue only when no business plan exists", + "basis": "explicit net/included/unknown; only net calculated; no silent conversion", + "selection": "published version selected by server; frozen at admission; same resolver/evaluator", + "cash_treatment": "separate IVA memorandum; declared receipts/payments unchanged; not cost, no inferred collection or final settlement", + "manual_tax": "custom planning only; never input into monthly IVA", + "unknown_vs_zero": "missing month indeterminate; explicit zero calculated as zero; aggregate indeterminate if any month unknown", + "tests": { + "api_tests": 3, + "api_assertions": 46, + "frontend_tests": 4, + "types": "passed", + "build": "passed", + "pint": "passed", + "accepted_calculation_and_exporter_proofs": "reused, not repeated" + }, + "qa_fixture": { + "database": "simulator_fiscal_delta_20261021_test", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "rule_version": 4, + "consumer_enabled": true, + "synthetic": true, + "left_available_for_review": true, + "draft_id": "e0201d19-286e-4d5c-9585-2c1e3bd1ad1e" + }, + "live_history": [ + { + "id": "06566910-9672-4176-804d-aad8350417cb", + "status": "completed", + "created_at": "2026-10-21T11:57:11.000000Z", + "basis": "net", + "rows": [ + { + "vat": "160.0048", + "date": "2026-01-01", + "rate": "16", + "status": "calculated", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": "1000.03", + "gross_sales": "1160.0348", + "rule_version": 4, + "sales_declared": "1000.03" + }, + { + "vat": "320.0096", + "date": "2026-02-01", + "rate": "16", + "status": "calculated", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": "2000.06", + "gross_sales": "2320.0696", + "rule_version": 4, + "sales_declared": "2000.06" + }, + { + "vat": "0", + "date": "2026-03-01", + "rate": "16", + "status": "calculated", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": "0.00", + "gross_sales": "0", + "rule_version": 4, + "sales_declared": "0.00" + }, + { + "vat": null, + "date": "2026-04-01", + "rate": null, + "status": "missing_sales", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": null, + "gross_sales": null, + "rule_version": 4, + "sales_declared": null + } + ], + "total": null, + "reports": [ + { + "id": "42b95158-6c4c-43c6-801d-28e973a087a6", + "same_snapshot": true, + "sha256": "b6d10565f82f7e83952fbdbb15a357ca3a7fee550e53c80a0ef5b9e314ccfa68" + } + ] + }, + { + "id": "098900ed-2f5f-4141-98c8-08f892912a5b", + "status": "completed", + "created_at": "2026-10-21T11:57:34.000000Z", + "basis": "net", + "rows": [ + { + "vat": "480.0144", + "date": "2026-01-01", + "rate": "16", + "status": "calculated", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": "3000.09", + "gross_sales": "3480.1044", + "rule_version": 4, + "sales_declared": "3000.09" + }, + { + "vat": "320.0096", + "date": "2026-02-01", + "rate": "16", + "status": "calculated", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": "2000.06", + "gross_sales": "2320.0696", + "rule_version": 4, + "sales_declared": "2000.06" + }, + { + "vat": "0", + "date": "2026-03-01", + "rate": "16", + "status": "calculated", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": "0.00", + "gross_sales": "0", + "rule_version": 4, + "sales_declared": "0.00" + }, + { + "vat": null, + "date": "2026-04-01", + "rate": null, + "status": "missing_sales", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": null, + "gross_sales": null, + "rule_version": 4, + "sales_declared": null + } + ], + "total": null, + "reports": [ + { + "id": "44211195-0a53-4f4c-93ef-6ff0e439082b", + "same_snapshot": true, + "sha256": "5de00868029b7a688585e180bcd8fbef1e46e289b19ab766c58f7406fb2af972" + } + ] + }, + { + "id": "96eec0d8-effa-4286-b465-6af50f756db4", + "status": "completed", + "created_at": "2026-10-21T11:58:35.000000Z", + "basis": "included", + "rows": [ + { + "vat": null, + "date": "2026-01-01", + "rate": null, + "status": "unsupported_basis", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": null, + "gross_sales": null, + "rule_version": 4, + "sales_declared": "3000.09" + }, + { + "vat": null, + "date": "2026-02-01", + "rate": null, + "status": "unsupported_basis", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": null, + "gross_sales": null, + "rule_version": 4, + "sales_declared": "2000.06" + }, + { + "vat": null, + "date": "2026-03-01", + "rate": null, + "status": "unsupported_basis", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": null, + "gross_sales": null, + "rule_version": 4, + "sales_declared": "0.00" + }, + { + "vat": null, + "date": "2026-04-01", + "rate": null, + "status": "missing_sales", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": null, + "gross_sales": null, + "rule_version": 4, + "sales_declared": null + } + ], + "total": null, + "reports": [ + { + "id": "821e6347-680c-4029-9756-c3169d79f85e", + "same_snapshot": true, + "sha256": "06abadc593e65cfff64d208fac6cac3a8f98db4bef92795a27ce637fe7958cec" + } + ] + }, + { + "id": "e88aaaea-4482-4b7d-869f-f0648a430651", + "status": "completed", + "created_at": "2026-10-21T12:00:32.000000Z", + "basis": "net", + "rows": [ + { + "vat": "480.0144", + "date": "2026-01-01", + "rate": "16", + "status": "calculated", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": "3000.09", + "gross_sales": "3480.1044", + "rule_version": 4, + "sales_declared": "3000.09" + }, + { + "vat": "320.0096", + "date": "2026-02-01", + "rate": "16", + "status": "calculated", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": "2000.06", + "gross_sales": "2320.0696", + "rule_version": 4, + "sales_declared": "2000.06" + }, + { + "vat": "0", + "date": "2026-03-01", + "rate": "16", + "status": "calculated", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": "0.00", + "gross_sales": "0", + "rule_version": 4, + "sales_declared": "0.00" + }, + { + "vat": null, + "date": "2026-04-01", + "rate": null, + "status": "missing_sales", + "rule_id": "01a15e50-7972-72e0-8991-82ca28df9b49", + "net_sales": null, + "gross_sales": null, + "rule_version": 4, + "sales_declared": null + } + ], + "total": null, + "reports": [ + { + "id": "bc204cc7-1f0c-4468-80fa-e093642a5eac", + "same_snapshot": true, + "sha256": "4ed224f7de50b533f144f7f411d240eb1ccca6f3e5bff7a64b1eca6f6d7971dc" + } + ] + } + ], + "main_integrated": false, + "homologation_changed": false, + "rule_publication_on_destination": false, + "coverage_expanded": false, + "limitations": [ + "IVA included prices unsupported in current net lot", + "2026 only, max 12 consecutive months", + "no final payable, deductions, refunds, special/reduced/exempt regimes", + "examples prove arithmetic/integration, not legal eligibility of every transaction" + ], + "remaining": "Tempo review/decision for code integration; no further generic preparation identified; keep real rule/publication/activation separate", + "proof_directory": "outputs/simulator-continuation-20261020" } } diff --git a/docs/investmoz/unification/traceability-and-manual.md b/docs/investmoz/unification/traceability-and-manual.md index 9fa40a99..d8ac759b 100644 --- a/docs/investmoz/unification/traceability-and-manual.md +++ b/docs/investmoz/unification/traceability-and-manual.md @@ -1980,3 +1980,26 @@ As notas aparecem junto dos campos e num resumo com ligações que focam o campo No Edge, simulador normal QA em127.0.0.1:18580: consulta anual2026, operação genérica explicitamente escolhida para o ensaio; moeda inicialmente vazia, depoisUSD escolhido expressamente como caso dirigido. Confirmaram-se notas, resumo, foco em «Rever moeda»/«Rever operação», fundamento da versão sintética3, eUSD/ano/periodicidade/operação conservados após gravação e recuperação do mesmo rascunho. A captura de prova é um ensaioUSD, não evidência deUSD no caso original. Não se executou cálculo nem se exportou relatório. A fixture publicada apenas emQA para observar o diagnóstico foi depois suspensa; o consumidorQA permaneceu desligado. Nenhuma fixture foi importada, regra alterada ou consumidor activado na homologação nesta correcção. Provas privadas na pasta `outputs/simulator-continuation-20261020`: iva-diagnostic-api-test.txt, iva-diagnostic-summary.txt, iva-diagnostic-summary.png e iva-diagnostic-build-final.txt. O reciboJSON existente tem o estado detalhado. A candidata permanece na branch `codex/iva-diagnostics-QA`, separada de main; não é uma nova publicação fiscal nem altera a entrega autorizada anteriormente. + + +### IVA mensal ligado às vendas — candidata QA, 21/10/2026 + +Pedido da Tempo: o formulário recolhe pressupostos do negócio e calcula o IVA correspondente, sem repetir vendas nem tomar o imposto manual como entrada fiscal. A falta de ligação entre a projecção empresarial e o consumidor publicado era uma escolha de implementação; não uma nova obrigação do utilizador. Alteração na branch `codex/iva-monthly-projection-QA`, separada de main. Não altera a instalação, regra ou activação da homologação. + +**Ligação:** o simulador normal reutiliza quantidades e preços por produto/mês do plano empresarial, com a mesma representação monetária das vendas já usada nesse plano. Se não existir plano, admite a receita mensal constante já guardada na projecção personalizada, identificando essa origem e exigindo declaração do enquadramento. Não usa os valores demonstrativos de um widget ainda não guardado. A indicação sem IVA/com IVA incluído fica explícita, sem a presumir. Neste lote só a base líquida declarada permite calcular: preços com IVA incluído, base desconhecida e meses sem vendas informadas permanecem indeterminados. Zero explícito calcula IVA zero; não se preenche um mês vazio com zero. + +O cliente envia meses, vendas, moeda e declaração; não envia taxa, versão ou imposto manual. O servidor selecciona a versão publicada ligada ao consumidor e reutiliza o resolvedor temporal e avaliador decimal existentes em cada mês, dentro da mesma admissão transaccional. Nenhuma taxa foi fixada no formulário, nem introduzido arredondamento fiscal. A versão é congelada antes da fila; mantém-se a autorização/idempotência/histórico/relatório existentes. Sem migration ou reconstrução dos mecanismos. Cobertura permanece 2026, no máximo 12 meses consecutivos; um horizonte que atravessa o limite é explicado, sem truncar a projecção. + +**Ecrã e dependências:** cada mês apresenta vendas declaradas, vendas tributáveis sem IVA, taxa efectivamente aplicada, IVA calculado e total com IVA. Após a primeira execução, a actualização automática fica ligada e pode ser pausada. Alterar vendas, moeda, período ou tratamento do IVA assinala imediatamente o resultado anterior como histórico desactualizado. A nova execução guarda outra versão sem modificar a anterior. Repetir sem alterações recupera a execução concluída; uma execução pendente é consultada pelo mesmo ID. Falhas conservam os pressupostos e permitem tentar novamente. O rascunho conserva configurações e resultado; o relatório distingue resultado actual e histórico desactualizado e não recalcula o IVA na exportação. Se algum mês estiver indeterminado, o total fiscal fica indeterminado, conservando os meses conhecidos. + +**Tesouraria adoptada:** o IVA é um memorando fiscal separado; não se soma novamente aos recebimentos introduzidos, não se deduz como custo e não se apresenta como imposto final a pagar. Conserva-se o calendário de recebimentos/pagamentos declarado, sem inferir cobrança integral no mesmo mês nem liquidação fiscal. O imposto manual permanece exclusivamente no painel recolhido «Cenário personalizado de tesouraria — imposto manual, separado do IVA calculado», com rótulos de cenário personalizado. Não alimenta a base nem o resultado do consumidor IVA. Não foram acrescentados deduções, créditos, reembolsos, importações, isenções, taxas reduzidas ou regimes especiais ao cálculo fiscal; as hipóteses antigas de tesouraria continuam personalizadas e separadas. + +**Provas apenas do delta:** 3 testes API novos/46 asserções, transacções no clone `simulator_fiscal_checks_20261021_test` com guarda QA; 4 testes frontend novos para reutilização das vendas, zero/informação em falta, invalidação e recuperação/relatório. Incluem taxa proibida no cliente, âmbito não declarado, preços brutos, período excluído, repetição sem duplicações, versão congelada antes da suspensão e conclusão depois dela. TypeScript/build/Pint/diff-check verificados. Reutilizadas as provas aceites do avaliador decimal, exportadores e PDF; não se voltou a testar paginação nem a ampliar cobertura legal. + +**Percurso Edge no simulador normal:** dossier sintético privado «QA IVA mensal - vendas projectadas», ID `e0201d19-286e-4d5c-9585-2c1e3bd1ad1e`, QA127.0.0.1:18580. Vendas Janeiro1000.03/ Fevereiro2000.06/ Março0/ Abril vazio produziram IVA160.0048/320.0096/0/indeterminado. Alterar apenas a quantidade de Janeiro de1 para3 actualizou vendas3000.09, IVA480.0144 e total3480.1044. Assinalou-se resultado desactualizado durante a mudança. Seleccionar preços com IVA incluído conservou vendas e tornou base/IVA/total indeterminados; voltar manualmente à base líquida gerou nova execução. Após recarregar e recuperar o mesmo dossier, os valores permaneceram iguais e o fundamento mostrou a versão congelada. Quatro execuções mensais intencionais (inicial, venda alterada, base incluída, regresso à líquida), quatro relatórios com snapshots iguais às respectivas execuções; recuperação não criou a quinta. Não se atribui aplicabilidade fiscal universal a estes exemplos aritméticos. + +A fixture sintética **v4**, ID `01a15e50-7972-72e0-8991-82ca28df9b49`, está publicada e o consumidor ligado **apenas no clone QA** `simulator_fiscal_delta_20261021_test`, deixados disponíveis para esta revisão. Isto substitui o estado local suspenso/off da prova diagnóstica anterior; não é indisponibilidade na homologação. Não importar esta fixture, os seus actores ou os scripts privados. A regra real de homologação v1 mantém-se fora desta execução. + +**Revisão e disponibilização:** rever esta candidata QA e integrar somente o código autorizado, mantendo a ligação ao ID/versão reais do destino. Este delta não precisa de publicar outra regra nem de mudar a taxa/âmbito ou de reactivar um consumidor já activo. Conferir apenas revisão servida e ligação mensal no destino após autorização própria; conservar o procedimento separado de publicação e activação se alguma dessas operações vier a ser expressamente pedida. Suspender novas admissões pelo interruptor existente ou estado da regra preserva as já admitidas e os históricos. Não apagar snapshots para suspender ou reverter código. Sem integração em main, escrita activa, validação jurídica atribuída à Tempo ou nova ronda de preparação identificada nesta entrega QA. + +Provas privadas em `outputs/simulator-continuation-20261020`: monthly-iva-api-test.txt, monthly-iva-build-final.txt, monthly-iva-initial.txt, monthly-iva-updated.txt, monthly-iva-stale.txt, monthly-iva-included.txt, monthly-iva-recovered.txt, monthly-iva-live-history.json e monthly-iva-proof.png. O recibo existente conserva o saldo e os IDs; AUD-SIM-INT02 da matriz existente recebe esta referência, sem outra matriz/backlog. diff --git a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv index cfff3132..d67badda 100644 --- a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv +++ b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv @@ -10652,7 +10652,7 @@ AUD-SEARCH-T10,Consistência transversal da pesquisa e navegação — Bibliotec AUD-SEARCH-T11,Consistência transversal da pesquisa e navegação — Legislação,Instruções expressas da Tempo na conversa de 20/10/2026; AGENTS.md; RF-MN-010 e AUD-GEO-01 preservados.,navegação/pesquisa,/legislacao,portal/services; portal/document — Reutiliza a correcção da biblioteca e preserva filtros jurídicos/documentais pertinentes.,Sem alteração remota nesta execução; revisão apenas na branch codex/opportunity-search.,HTTP/Inertia: resources.total=0; consumidor e query pública partilhados.,QA — delta delimitado; revisão Tempo pendente,"Situação jurídica, consulta e cálculo continuam independentes.",,"Filtros, contagem, resultados e URL coerentes; universos identificados; erro distinto de vazio; permissões e contexto conservados.",P1,,RF-MN-010; AUD-GEO-01,,,,,,,,,,,Mesmo padrão da biblioteca; não deve expor um universo concorrente.,"Situação jurídica, consulta e cálculo continuam independentes.",portal/services; portal/document; SearchState; SearchFeedback; TerritoryFields; portalNavigation,,"Integração em main apenas após revisão; assistência NLP, contratos e P7 separados.",Correcção/simplificação em QA,,HTTP/Inertia: resources.total=0; consumidor e query pública partilhados.,Pesquisa transversal QA 20/10/2026,20/10/2026,,,,,,,,,,"Provas comuns cobrem o componente reutilizado; HTTP vazio não demonstra operações de gestão ou publicação. Situação jurídica, consulta e cálculo continuam independentes.",,falha funcional; navegação; apresentação visual,,Disponível para revisão na aplicação QA local. AUD-GUIDE-CARD-20261020,"Related educational cards: image, source summary, clear actions",Tempo 20/10/2026; independent delta after 0e7d51f18fb4,educational presentation,/sectores/{slug}; /explorar/{group}; articles; /oportunidades and detail,EducationalArticleCard; EducationalGuides; LegacyContent; SectorInvestment,QA only,1 test / 8 assertions; PHP syntax; TypeScript/build; desktop2048/mobile390; keyboard,QA review pending,Normal QA sector and article verified against existing library resource 10 and local image 25; previous dossier proof retained,,Source-derived summary; public images; conditional opportunity action; context preserved,P1,,,,,,,,,,,,,,,,,,presentation,,,,20/10/2026,,,,,,,,,,,,content; navigation; visual presentation,,Ready for QA review AUD-SIM-INT01,Invalid one-off fiscal date can throw instead of returning validation state,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Fixed in QA; invalid-date checks; 38 directed frontend tests passed,Previous inline-date proof retained; unchanged delta not repeated,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P0,,,,,,,,,,,,,,,,,,diagnosis and targeted corrections,, | [Saldo consolidado21/10/2026] Concluído no recorte. Nenhum delta de validação de data por demonstrar; prova anterior preservada. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação.,,20/10/2026,,,,,,,,,,,,,, -AUD-SIM-INT02,Review actual fiscal parameters sources periods and eligibility,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Verification pending; no parameter activation,Recorte IVA geral sobre base declarada disponibilizado: 4a4d1212 integrado na revisao servida d3fe8a02; regra real v1 publicada e consumidor activo. Nao conclui o simulador fiscal integral.,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P0,,,,,,,,,,,,,,"Nenhuma operacao de disponibilizacao pendente neste lote delimitado. Outras componentes, regimes e coberturas fiscais permanecem fora do recorte; nao repetir provas aceites.",,,"Tempo autorizou incorporacao de 4a4d1212, cadastro/publicacao da regra real e activacao. Mesma administracao real nala@tempo.co.mz, login normal e MFA, sem quatro designacoes; sem parecer juridico ou revisao independente atribuidos a Tempo.",Ligacao de consumidor publicada concluida em QA; decisoes operacionais separadas.,Recorte executado; sem saldo de implementacao ou disponibilizacao identificado neste lote. Nao converter estimativas anteriores em implementacao fiscal integral.," | [Leitura SSH 21/10/2026 08:17 Maputo] Zero regras em simulation_tax_rule_versions na homologação, incluindo todos os estados por leitura administrativa sem ocultação RLS. Seis referências em investment_legal_sources; não são parâmetros executáveis. QA também tinha zero regras. BEGIN READ ONLY/SELECT/ROLLBACK; zero escritas. Prova homologation-fiscal-readonly.json. O git HEAD registado é do checkout consultado, não certifica a revisão do build servido. A ausência de cadastro não é ausência de fontes oficiais nem reabre a aceitação da Tempo de 08/10. Não implementa a ligação funcional ao motor fiscal. | [Saldo consolidado21/10/2026] Parcial. Leitura remota concluída: zero regras de todos os estados na homologação, tal como QA; seis referências jurídicas não são parâmetros executáveis. Falta cadastro fundamentado por componente/âmbito/período e ligação funcional ao motor fiscal. Fontes e análises existentes reutilizáveis; aceitação oficial da Tempo de08/10 preservada. Não activar taxas nem importar/publicar por esta reconciliação. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação. | [Candidata21/10/2026] Diagnóstico fiscal separado no manual existente: fontes/analises já disponíveis; zero parâmetros executáveis na QA e homologação por leitura de todos os estados; governação/resolvedor temporal/DSL existentes; RunSimulation ainda aritmética personalizada sem consumir regras fiscais. Saldo: cadastro fundamentado, orquestração, contrato de resultado/histórico e ligação ao dossier/relatório, com casos por componente/período. Nenhuma regra criada nem activada; implementação fiscal integral aberta e excluída das1–2h de exportações. | [Proposta21/10/2026] Primeiro lote proposto: uma regra IVA geral sobre base liquida/MZN, cobertura demonstrada2026 sem inventar caducidade legal. Reutilizar fontes/analises/governacao/resolvedor/avaliador existentes; arredondamento e ambito aplicavel explicitamente por fundamentar antes de publicar. Cadastro4-8h e codigo/aceitacao12-20h, total16-28h condicionado ao acervo, separado das1-2h de exportacao. Criterios e exclusoes no manual existente. Nenhuma regra cadastrada/activada; nao e implementacao fiscal integral. | [QA IVA v1.2 21/10/2026] Orientacao posterior Tempo: calcular com precisao decimal exacta sem arredondamento automatico, separando apresentacao monetaria; arredondamento generico deixa de ser bloqueio deste lote. Cadastro draft versionado em clone QA; resolvedor/avaliador existentes; proveniencia, historico e relatorio imutavel ligados. 5 feature (51 assercoes), 7 unit (25), 3 frontend; types/build/Pint aprovados. Contexto declarado; nao e saldo a pagar. Zero regras publicadas; sem main/activacao. Recorte QA autorizado verificado (0h engenharia identificada restante); produto fiscal integral continua parcial. Limites e provas no mesmo manual e ficha v1.2; sem atribuicao de validacao juridica ao utilizador. | [Revisao 83d2f97d] Ambito/periodo/exclusoes e procedimentos de integracao, publicacao, activacao e suspensao consolidados no mesmo manual. Lacuna concreta de ecra QA fechada: entradas 1000.03/MZN/2026-10-21; calculo exacto 160.0048; gravacao fa6d17f2-5f47-4cb6-b8cb-40850c12505f; recarga; recuperacao do mesmo ID; relatorio d13e2ad5-3ba8-4d01-9d30-5815496da774 com mesmo valor/proveniencia e hash igual ao resultado. Uma execucao persistida, draft e zero regras publicadas. 1 teste novo de rota/17 assercoes, TypeScript/build e browser aprovados; restantes provas reutilizadas. Interrupcao inicial da ferramenta resolvida, sem atribuicao de falha ao simulador. Revisao do recorte demonstrada; sem nova preparacao generica identificada, main ou activacao; nao fecha aplicabilidade fiscal universal nem simulador integral. | 21/10/2026: proposta do consumidor IVA no simulador existente no manual: falta ligacao a regra publicada e activacao explicita. Integrar codigo desligado, publicar versao e activar consumidor sao tres operacoes distintas. Reutiliza permissoes, governanca, historico e provas aceites; sem ampliar cobertura ou executar estas operacoes. | 21/10/2026: implementado delta de 2ced7b79 no simulador normal QA, activacao desligada por omissao. 8 testes/75 assercoes, 2 testes frontend novos, TypeScript/build/Pint. Edge: indeterminacao, calculo, repeticao sem duplicar, fila admitida antes de suspensao concluida depois, nova execucao recusada e historicos/relatorios preservados. Mesmo manual e recibo consolidam provas e tres operacoes. Fixture isolada suspensa; sem merge ou publicacao/activacao na homologacao. | 21/10/2026: origem da condicao fiscal localizada em e65cb269/servico/CHECKs de 03/10 e nota de implementacao; sem decisao expressa aplicavel encontrada. Correccao QA: administracao existente, mesma pessoa, fonte oficial identificada e eventos preservados. 6 testes/86 assercoes apenas do controlo, sem calculos/exportadores; constraints de outras tabelas iguais. Esquema activo nao alterado; backup/restauro de 171 tabelas confirmado; sem fixture ou publicacao real. | [Execucao autorizada 21/10/2026 10:56 UTC] Servido d3fe8a02ec7f5dcd01984c4f4a1eba18b5a0cf19 contendo 4a4d1212; DDL fiscal aplicado autenticadamente com backup/restauro de171tabelas e registos preservados. Tres fontes reais v1 com hashes/citacoes e aceitacao fiscal Tempo08/10/2026, sem validacao geral automatica. Regra IVA-GERAL-BASE-LIQUIDA rule_version1, ID01a15e1a-5338-700f-8a45-f87707d696a7, published, version_no5, actor15 emtodasetapas;5eventos. Activacao separada ligada a esseID/versao; APIHTTP200 enabled=true e resolvedor16percent no contexto delimitado sem calculo novo. FixtureQA nao importada; calculos/exportadores/PDF aceites nao repetidos. Suspensao de novas admissoes conserva snapshots/historicos/relatorios. Recibo e manual existentes actualizados; limitacoes de abertura de consola/extensao registadas como ferramenta. | [Diagnostico IVA QA21/10/2026] Falha estrutural reproduzida na consulta anual: fiscal_operation nao satisfaz operation e moeda nao era comunicada. Sem presumir respostas originais. Cada condicao tem campo/recebido/esperado/categoria; notas junto ao campo, resumo com foco e Ver fundamento semDSL/codigo. Moeda fiscal explicita, sem conversao/copia.5unitarios24assercoes+1API16assercoes, Edge comUSD dirigido preservado apos recuperacao; fixtureQA v3suspensa, consumidorQAoff. Nao altera regra/activacao da homologacao; calculos e exportadores nao repetidos. Branch codex/iva-diagnostics-QA.",,20/10/2026,,,,,,,,,,,,,, +AUD-SIM-INT02,Review actual fiscal parameters sources periods and eligibility,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Verification pending; no parameter activation,Recorte IVA geral sobre base declarada disponibilizado: 4a4d1212 integrado na revisao servida d3fe8a02; regra real v1 publicada e consumidor activo. Nao conclui o simulador fiscal integral.,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P0,,,,,,,,,,,,,,"Nenhuma operacao de disponibilizacao pendente neste lote delimitado. Outras componentes, regimes e coberturas fiscais permanecem fora do recorte; nao repetir provas aceites.",,,"Tempo autorizou incorporacao de 4a4d1212, cadastro/publicacao da regra real e activacao. Mesma administracao real nala@tempo.co.mz, login normal e MFA, sem quatro designacoes; sem parecer juridico ou revisao independente atribuidos a Tempo.",Ligacao de consumidor publicada concluida em QA; decisoes operacionais separadas.,Recorte executado; sem saldo de implementacao ou disponibilizacao identificado neste lote. Nao converter estimativas anteriores em implementacao fiscal integral.," | [Leitura SSH 21/10/2026 08:17 Maputo] Zero regras em simulation_tax_rule_versions na homologação, incluindo todos os estados por leitura administrativa sem ocultação RLS. Seis referências em investment_legal_sources; não são parâmetros executáveis. QA também tinha zero regras. BEGIN READ ONLY/SELECT/ROLLBACK; zero escritas. Prova homologation-fiscal-readonly.json. O git HEAD registado é do checkout consultado, não certifica a revisão do build servido. A ausência de cadastro não é ausência de fontes oficiais nem reabre a aceitação da Tempo de 08/10. Não implementa a ligação funcional ao motor fiscal. | [Saldo consolidado21/10/2026] Parcial. Leitura remota concluída: zero regras de todos os estados na homologação, tal como QA; seis referências jurídicas não são parâmetros executáveis. Falta cadastro fundamentado por componente/âmbito/período e ligação funcional ao motor fiscal. Fontes e análises existentes reutilizáveis; aceitação oficial da Tempo de08/10 preservada. Não activar taxas nem importar/publicar por esta reconciliação. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação. | [Candidata21/10/2026] Diagnóstico fiscal separado no manual existente: fontes/analises já disponíveis; zero parâmetros executáveis na QA e homologação por leitura de todos os estados; governação/resolvedor temporal/DSL existentes; RunSimulation ainda aritmética personalizada sem consumir regras fiscais. Saldo: cadastro fundamentado, orquestração, contrato de resultado/histórico e ligação ao dossier/relatório, com casos por componente/período. Nenhuma regra criada nem activada; implementação fiscal integral aberta e excluída das1–2h de exportações. | [Proposta21/10/2026] Primeiro lote proposto: uma regra IVA geral sobre base liquida/MZN, cobertura demonstrada2026 sem inventar caducidade legal. Reutilizar fontes/analises/governacao/resolvedor/avaliador existentes; arredondamento e ambito aplicavel explicitamente por fundamentar antes de publicar. Cadastro4-8h e codigo/aceitacao12-20h, total16-28h condicionado ao acervo, separado das1-2h de exportacao. Criterios e exclusoes no manual existente. Nenhuma regra cadastrada/activada; nao e implementacao fiscal integral. | [QA IVA v1.2 21/10/2026] Orientacao posterior Tempo: calcular com precisao decimal exacta sem arredondamento automatico, separando apresentacao monetaria; arredondamento generico deixa de ser bloqueio deste lote. Cadastro draft versionado em clone QA; resolvedor/avaliador existentes; proveniencia, historico e relatorio imutavel ligados. 5 feature (51 assercoes), 7 unit (25), 3 frontend; types/build/Pint aprovados. Contexto declarado; nao e saldo a pagar. Zero regras publicadas; sem main/activacao. Recorte QA autorizado verificado (0h engenharia identificada restante); produto fiscal integral continua parcial. Limites e provas no mesmo manual e ficha v1.2; sem atribuicao de validacao juridica ao utilizador. | [Revisao 83d2f97d] Ambito/periodo/exclusoes e procedimentos de integracao, publicacao, activacao e suspensao consolidados no mesmo manual. Lacuna concreta de ecra QA fechada: entradas 1000.03/MZN/2026-10-21; calculo exacto 160.0048; gravacao fa6d17f2-5f47-4cb6-b8cb-40850c12505f; recarga; recuperacao do mesmo ID; relatorio d13e2ad5-3ba8-4d01-9d30-5815496da774 com mesmo valor/proveniencia e hash igual ao resultado. Uma execucao persistida, draft e zero regras publicadas. 1 teste novo de rota/17 assercoes, TypeScript/build e browser aprovados; restantes provas reutilizadas. Interrupcao inicial da ferramenta resolvida, sem atribuicao de falha ao simulador. Revisao do recorte demonstrada; sem nova preparacao generica identificada, main ou activacao; nao fecha aplicabilidade fiscal universal nem simulador integral. | 21/10/2026: proposta do consumidor IVA no simulador existente no manual: falta ligacao a regra publicada e activacao explicita. Integrar codigo desligado, publicar versao e activar consumidor sao tres operacoes distintas. Reutiliza permissoes, governanca, historico e provas aceites; sem ampliar cobertura ou executar estas operacoes. | 21/10/2026: implementado delta de 2ced7b79 no simulador normal QA, activacao desligada por omissao. 8 testes/75 assercoes, 2 testes frontend novos, TypeScript/build/Pint. Edge: indeterminacao, calculo, repeticao sem duplicar, fila admitida antes de suspensao concluida depois, nova execucao recusada e historicos/relatorios preservados. Mesmo manual e recibo consolidam provas e tres operacoes. Fixture isolada suspensa; sem merge ou publicacao/activacao na homologacao. | 21/10/2026: origem da condicao fiscal localizada em e65cb269/servico/CHECKs de 03/10 e nota de implementacao; sem decisao expressa aplicavel encontrada. Correccao QA: administracao existente, mesma pessoa, fonte oficial identificada e eventos preservados. 6 testes/86 assercoes apenas do controlo, sem calculos/exportadores; constraints de outras tabelas iguais. Esquema activo nao alterado; backup/restauro de 171 tabelas confirmado; sem fixture ou publicacao real. | [Execucao autorizada 21/10/2026 10:56 UTC] Servido d3fe8a02ec7f5dcd01984c4f4a1eba18b5a0cf19 contendo 4a4d1212; DDL fiscal aplicado autenticadamente com backup/restauro de171tabelas e registos preservados. Tres fontes reais v1 com hashes/citacoes e aceitacao fiscal Tempo08/10/2026, sem validacao geral automatica. Regra IVA-GERAL-BASE-LIQUIDA rule_version1, ID01a15e1a-5338-700f-8a45-f87707d696a7, published, version_no5, actor15 emtodasetapas;5eventos. Activacao separada ligada a esseID/versao; APIHTTP200 enabled=true e resolvedor16percent no contexto delimitado sem calculo novo. FixtureQA nao importada; calculos/exportadores/PDF aceites nao repetidos. Suspensao de novas admissoes conserva snapshots/historicos/relatorios. Recibo e manual existentes actualizados; limitacoes de abertura de consola/extensao registadas como ferramenta. | [Diagnostico IVA QA21/10/2026] Falha estrutural reproduzida na consulta anual: fiscal_operation nao satisfaz operation e moeda nao era comunicada. Sem presumir respostas originais. Cada condicao tem campo/recebido/esperado/categoria; notas junto ao campo, resumo com foco e Ver fundamento semDSL/codigo. Moeda fiscal explicita, sem conversao/copia.5unitarios24assercoes+1API16assercoes, Edge comUSD dirigido preservado apos recuperacao; fixtureQA v3suspensa, consumidorQAoff. Nao altera regra/activacao da homologacao; calculos e exportadores nao repetidos. Branch codex/iva-diagnostics-QA. | [IVA mensal QA21/10/2026] Vendas por produto/mes reutilizadas; base liquida explicita; versao publicada seleccionada no servidor, sem taxa/manual no formulario. Zero distinto de falta; preco com IVA indeterminado. Actualizacao dependente cria versao, historicos/relatorios preservados. IVA separado de recebimentos/custos/imposto final; manual apenas cenario personalizado. 3API/46assercoes+4frontend e Edge: vendas alteradas, bruto, zero, falta, recuperacao e relatorio. Fixture sintetica v4 ligada apenas no clone QA para revisao. Sem main/HML ou alargamento fiscal; provas anteriores reutilizadas. Mesmo manual/recibo; branch codex/iva-monthly-projection-QA.",,20/10/2026,,,,,,,,,,,,,, AUD-SIM-INT03,Review isolation recovery across projects and sessions,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Existing controls and accepted proofs to reconcile; no leak established,Two dossiers and new login recovered in browser; cashflow persistence corrected and HTTP-tested; new visual cashflow delta pending,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P0,,,,,,,,,,,,,,,,,,diagnosis and targeted corrections,,"[Retoma 21/10/2026] QA 18576, clone simulator_review_delta_20261020_test: sessão sintética renovada por login normal; gravação autenticada e recarga recuperaram saldo 123, receita 900, custos 600, calendário mensal 10/vazio/0, crédito IVA estimado 500. Caixa conhecida 3713 MZN; total indeterminado desde mês 2; crédito estimado excluído da caixa. Prova visual cashflow-recovered-20261021.png e snapshot .txt em outputs/simulator-continuation-20261020. Não certifica recuperação destes novos valores após outro login, CSV/DOCX ou PDF nativo. Ligação de controlo do navegador perdida durante espera de download; não atribuir falha à aplicação. Leitura remota aguarda identificação da ligação SSH; zero alterações no destino. | [Saldo consolidado21/10/2026] Concluído no recorte. A/B, logout/novo login, recuperação e recusa pela aplicação demonstrados anteriormente. A tesouraria tem prova API de nova sessão e prova visual de recuperação por recarga. Não atribuir ao navegador nova sessão dos valores de tesouraria, nem nova certificação RLS; limites expressos conservados. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação.",,20/10/2026,,,,,,,,,,,,,, AUD-SIM-INT04,Review stale and historical results and correct dossier,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Existing versions/fingerprints; targeted verification pending,Historical results visible after fix; 12 and 24 recovered; hashes unchanged; synthetic temporal resolver versions verified in memory only,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P1,,,,,,,,,,,,,,,,,,diagnosis and targeted corrections,," | [Saldo consolidado21/10/2026] Concluído no recorte demonstrado. Histórico24/12 visível, hashes preservados e versões temporais sintéticas do resolvedor conferidas. Execução fiscal integrada com parâmetros reais pertence ao saldo de02 e não foi demonstrada por estes testes. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação.",,20/10/2026,,,,,,,,,,,,,, AUD-SIM-INT05,Independent financial controls unknown zero units and currencies,Tempo request 20/10/2026; integrated simulator review; same manual,simulator and shared language,,,QA only,Reconciliation pending; no invented tax assumptions,Independent business-plan and cashflow ledgers passed; complete credit recipe included in screen and exports,QA continuation verified; precise open inputs and cashflow visual check in same manual; 2-4 h remaining,,,P1,,,,,,,,,,,,,,,,,,diagnosis and targeted corrections,,"[Retoma 21/10/2026] QA 18576, clone simulator_review_delta_20261020_test: sessão sintética renovada por login normal; gravação autenticada e recarga recuperaram saldo 123, receita 900, custos 600, calendário mensal 10/vazio/0, crédito IVA estimado 500. Caixa conhecida 3713 MZN; total indeterminado desde mês 2; crédito estimado excluído da caixa. Prova visual cashflow-recovered-20261021.png e snapshot .txt em outputs/simulator-continuation-20261020. Não certifica recuperação destes novos valores após outro login, CSV/DOCX ou PDF nativo. Ligação de controlo do navegador perdida durante espera de download; não atribuir falha à aplicação. Leitura remota aguarda identificação da ligação SSH; zero alterações no destino. | [Saldo consolidado21/10/2026] Concluído nos controlos delimitados. Controlos independentes de caixa/plano/crédito, zero/desconhecido e moedas preservados. Não são validação de taxas legais nem certificação de toda a contabilidade. Ver saldo dos oito itens no manual existente; sem fecho global por esta reconciliação.",,20/10/2026,,,,,,,,,,,,,, diff --git a/resources/js/components/simulation-cashflow-planner.tsx b/resources/js/components/simulation-cashflow-planner.tsx index 92995f4d..94760cfd 100644 --- a/resources/js/components/simulation-cashflow-planner.tsx +++ b/resources/js/components/simulation-cashflow-planner.tsx @@ -156,7 +156,7 @@ export function SimulationCashflowPlanner({ {taxMode === 'fixed' ? (
    ; } diff --git a/resources/js/lib/business-financial-plan.ts b/resources/js/lib/business-financial-plan.ts index 9a7f6339..4157859f 100644 --- a/resources/js/lib/business-financial-plan.ts +++ b/resources/js/lib/business-financial-plan.ts @@ -793,6 +793,20 @@ export function monthlyProjectedSales(input: BusinessFinancialPlanInput): Array< }); } +/** Existing purchase orders are planning references, never a proxy for deductible VAT or invoice dates. */ +export function monthlyProjectedPurchaseOrders(input: BusinessFinancialPlanInput): Array { + const periods = input.periods ?? 12; + if (!Number.isInteger(periods) || periods < 1 || periods > 60) throw new Error('Horizonte de compras inválido.'); + return Array.from({length: periods}, (_, month) => { + const amounts = input.useProductInventorySchedule + ? input.products.map((product) => product.productInventoryPurchasesByPeriod?.[month]?.amount) + : [input.useInventoryPurchaseSchedule + ? input.inventoryPurchaseSchedule?.[month]?.amount : input.monthlyInventoryPurchases]; + if (!amounts.length || amounts.some((amount) => typeof amount !== 'string' || amount.trim() === '')) return null; + return format(amounts.reduce((total, amount) => total + cents(amount!, 'Compras projectadas'), 0n)); + }); +} + function format(centsValue: bigint): string { const absolute = centsValue < 0n ? -centsValue : centsValue; return `${centsValue < 0n ? '-' : ''}${absolute / 100n}.${String(absolute % 100n).padStart(2, '0')}`; diff --git a/resources/js/lib/fiscal-qa-preview.ts b/resources/js/lib/fiscal-qa-preview.ts index 04e8d7b6..d4ff9736 100644 --- a/resources/js/lib/fiscal-qa-preview.ts +++ b/resources/js/lib/fiscal-qa-preview.ts @@ -1,4 +1,5 @@ import { isApiSimulationResultSnapshotV1 } from "./simulation-contract.ts"; +import { modeloAComponentRows } from './iva-modelo-a.ts'; export function fiscalQaRows(value: unknown): Array<[string, string]> { if (!isApiSimulationResultSnapshotV1(value)) return []; @@ -21,6 +22,7 @@ export function fiscalQaRows(value: unknown): Array<[string, string]> { : "não disponível"; const monthly = snapshot.monthly_projection as {rows?: Array>; cash_treatment?: string} | undefined; return [ + ...modeloAComponentRows(snapshot), ...(monthly?.rows ? [ ["Projecção mensal", "Vendas tributáveis sem IVA → taxa aplicada → IVA calculado → total com IVA; não é apuramento final"], ...monthly.rows.map((row) => [`Mês ${text(row.date)}`, `Vendas declaradas: ${text(row.sales_declared)}; base líquida: ${text(row.net_sales)}; taxa: ${row.rate == null ? 'não aplicada' : `${text(row.rate)}%`}; IVA: ${text(row.vat)}; total com IVA: ${text(row.gross_sales)}; ${row.status === 'calculated' ? 'calculado' : row.status === 'missing_sales' ? 'sem informação de vendas' : row.status === 'unsupported_basis' ? 'base líquida não determinada' : 'enquadramento ou regra indeterminados'}`]), diff --git a/resources/js/lib/iva-modelo-a.ts b/resources/js/lib/iva-modelo-a.ts new file mode 100644 index 00000000..0fb865e7 --- /dev/null +++ b/resources/js/lib/iva-modelo-a.ts @@ -0,0 +1,59 @@ +import { monthlyProjectedPurchaseOrders, restoreBusinessPlanSnapshot } from './business-financial-plan.ts'; + +/** Correspondence to the Tempo exemplar, not an electronic AT declaration or a new tax ruleset. */ +export const modeloAReference = { + file: 'Novo Modelo A.docx', + sha256: '62c198e90d8c6792f7d5ccefc6386df2e4b6089573067d3a6e1eae7fc2b9572b', + edition: 'Edição/vigência do formulário não estabelecida; original preservado na biblioteca QA.', + status: 'Simulação parcial: campos 01/02. Não é declaração submetida ou aceite pela Autoridade Tributária.', +}; + +export type ModeloAField = { field: string; purpose: string; origin: string; calculation: string; basis: string; status: string }; +const pending = 'Em falta; não assumir zero'; +export const modeloAFields: ModeloAField[] = [ + {field:'01',purpose:'Base das operações à taxa geral',origin:'Vendas mensais já projectadas, declaradas sem IVA e no âmbito geral',calculation:'Base líquida do mês',basis:'CIVA arts.15 e 17; Lei22/2022; regra publicada existente',status:'Implementado no âmbito declarado'}, + {field:'02',purpose:'IVA à taxa geral',origin:'Resultado mensal congelado no servidor',calculation:'Campo01 × taxa da versão publicada /100',basis:'CIVA art.17(1); mesma regra/versionamento do consumidor',status:'Implementado; componente do apuramento'}, + {field:'03',purpose:'Base de operações específicas à taxa reduzida',origin:'Operações separadas e enquadradas; ainda não recolhidas',calculation:'Base das operações elegíveis',basis:'Exemplar e CIVA art.17-A, aditado pela Lei22/2022; enquadramento a cadastrar',status:pending}, + {field:'04',purpose:'IVA à taxa reduzida',origin:'Campo03 e futura versão fundamentada',calculation:'Campo03 × taxa reduzida aplicável; não activa pelo exemplar',basis:'CIVA art.17-A; âmbito/versão temporal a integrar',status:pending}, + {field:'05',purpose:'Vendas isentas com direito à dedução',origin:'Vendas classificadas por operação e fundamento',calculation:'Soma das bases classificadas; sem taxa presumida',basis:'Exemplar; CIVA arts.9–14 e 18–20 a consolidar por operação',status:pending}, + {field:'06',purpose:'Operações da alínea b), n.º1, art.18, conforme exemplar',origin:'Operações classificadas com referência verificada',calculation:'Soma separada; não inferir do nome do sector',basis:'Remissão do exemplar ao art.18(1)(b); cotejo do âmbito necessário',status:pending}, + {field:'07',purpose:'Isentas sem direito à dedução',origin:'Vendas classificadas e uso das aquisições',calculation:'Soma das bases elegíveis',basis:'Exemplar; incidência/isenções e exclusões de dedução a fundamentar',status:pending}, + {field:'08',purpose:'IVA dedutível — imobilizado',origin:'Aquisições/facturas de activos, não o valor global do investimento',calculation:'Apenas imposto elegível documentado',basis:'CIVA arts.18–21; art.18(2), Lei10/2025: documentos legais e fornecedor inscrito',status:pending}, + {field:'09',purpose:'IVA dedutível — existências',origin:'Compras projectadas reutilizáveis; falta IVA, documento e elegibilidade',calculation:'IVA elegível das existências, não compras × taxa geral',basis:'CIVA arts.18–21; condições/exclusões, afectação e período',status:pending}, + {field:'10',purpose:'IVA dedutível — outros bens/serviços',origin:'Aquisições discriminadas; despesas agregadas não provam IVA',calculation:'IVA elegível; excluir operações sem direito',basis:'CIVA arts.18–21; art.19(2), Lei10/2025, inclui exclusão das operações art.17-A',status:pending}, + {field:'11',purpose:'IVA dedutível — importações',origin:'Documento aduaneiro legal e afectação; ainda não recolhidos',calculation:'Imposto aduaneiro elegível, não taxa sobre orçamento',basis:'CIVA art.18(2), Lei10/2025; demais condições/exclusões a cadastrar',status:pending}, + {field:'12',purpose:'Regularizações a favor do sujeito passivo',origin:'Ajustamentos individualizados, documento e motivo',calculation:'Soma de regularizações elegíveis',basis:'Exemplar tem remissão interna 11/12 divergente das caixas12/13; fundamento por motivo por conferir',status:pending}, + {field:'13',purpose:'Regularizações a favor do Estado',origin:'Ajustamentos individualizados, documento e motivo',calculation:'Soma separada das regularizações elegíveis',basis:'Mesma divergência; não corrigir o original nem inventar incidência',status:pending}, + {field:'14',purpose:'Soma das bases do quadro de apuramento',origin:'Campos01,03,05,06,07 completos',calculation:'01+03+05+06+07',basis:'Fórmula impressa no exemplar; não é apenas vendas tributáveis',status:'Estrutura mapeada; total indeterminado'}, + {field:'15',purpose:'Total a favor do sujeito passivo',origin:'Campos08–12 completos',calculation:'08+09+10+11+12',basis:'Fórmula do exemplar; depende de deduções/regularizações fundamentadas',status:'Estrutura mapeada; total indeterminado'}, + {field:'16',purpose:'Total a favor do Estado',origin:'Campos02,04,13 completos',calculation:'02+04+13',basis:'Fórmula impressa no exemplar; 02 sozinho não equivale a16',status:'Estrutura mapeada; total indeterminado'}, + {field:'17',purpose:'Diferença devedora antes de créditos anteriores',origin:'Totais15/16 completos',calculation:'16−15 quando16>15',basis:'Instrução do exemplar; não é automaticamente pagamento',status:'Indeterminado; sem consolidação completa'}, + {field:'18',purpose:'Diferença credora antes de créditos anteriores',origin:'Totais15/16 completos',calculation:'15−16 quando15>16',basis:'Instrução do exemplar; não constitui reembolso reconhecido',status:'Indeterminado; sem consolidação completa'}, + {field:'19',purpose:'Excesso a reportar do período anterior',origin:'Histórico fiscal anterior confirmado, separado de estimativas',calculation:'Crédito anterior utilizável; sem copiar crédito estimado',basis:'Quadro de utilização de créditos do exemplar; condições/prazo por conferir',status:pending}, + {field:'20',purpose:'Créditos comunicados pelos serviços',origin:'Comunicação efectiva da Administração Fiscal',calculation:'Crédito efectivamente comunicado e utilizável',basis:'Exemplar; não converter pedido ou crédito estimado em comunicação',status:pending}, + {field:'21',purpose:'Diferencial de declaração de substituição',origin:'Valores17/18 da declaração actual e da substituída',calculation:'Casos impressos no quadro9, com sinal devedor/credor',basis:'Exemplar; ligação às declarações efectivas e regras de substituição em falta',status:pending}, + {field:'22',purpose:'IVA a entregar no contexto da declaração',origin:'Apuramento e créditos/substituição completos',calculation:'Não derivar apenas do campo02',basis:'Quadro10 do exemplar; procedimento aplicável por fundamentar',status:pending}, + {field:'23',purpose:'Juros compensatórios',origin:'Factos e períodos que legalmente os determinem',calculation:'Sem taxa, mora ou obrigação presumidas',basis:'Quadro10; fundamento específico não analisado neste lote',status:pending}, + {field:'24',purpose:'Importância a pagar',origin:'Campos22/23 completos',calculation:'22+23',basis:'Fórmula do exemplar; não é ordem nem execução de pagamento',status:pending}, + {field:'25',purpose:'Crédito de imposto do quadro11',origin:'Apuramento completo e tratamento dos créditos anteriores',calculation:'Montante recuperável no contexto próprio, por fundamentar',basis:'Caixa25 confirmada visualmente no bloco de recuperação; condições por consolidar',status:pending}, + {field:'26',purpose:'Reporte para período seguinte',origin:'Crédito utilizável e opção no quadro11',calculation:'Separado de pedido e recebimento',basis:'Quadro11; cotejo de condições/prazos e articulação19/20 necessário',status:pending}, + {field:'27',purpose:'Pedido de reembolso',origin:'Crédito elegível e pedido, sem presumir reconhecimento/caixa',calculation:'Pedido distinto de aprovação e recebimento',basis:'Exemplar cita art.20; Lei10/2025 altera reembolsos no art.21. Divergência registada.',status:pending}, +]; + +export function modeloAComponentRows(snapshot: Record): Array<[string,string]> { + if (!snapshot.monthly_projection) return []; + return [ + ['Correspondência Modelo A',modeloAReference.status], + ['Campos01/02', 'Base líquida e IVA mensal da versão publicada. Os restantes campos não foram presumidos iguais a zero.'], + ['Apuramento do período — campos14–18', 'Indeterminado: faltam componentes e enquadramentos do Modelo A. IVA das vendas não é imposto final a pagar.'], + ['Origem dos dados','Projecção do negócio; não são operações efectivas nem declaração fiscal.'], + ['Exemplar de referência',`${modeloAReference.file}; SHA256 ${modeloAReference.sha256}. ${modeloAReference.edition}`], + ]; +} + +export function modeloAPurchaseReferences(draft: Record): Array<{month:number; declared:string|null; net:null; vat:null; gross:null; deductible:null}> { + if (!draft.business_plan_snapshot) return []; + const plan = restoreBusinessPlanSnapshot(String(draft.business_plan_snapshot)); + if (!plan) throw new Error('Não foi possível recuperar as aquisições projectadas. O original guardado foi preservado.'); + return monthlyProjectedPurchaseOrders(plan).map((amount, index) => ({month:index+1, declared:amount, net:null, vat:null, gross:null, deductible:null})); +} diff --git a/resources/js/lib/project-dossier.ts b/resources/js/lib/project-dossier.ts index c1925527..d29b45e9 100644 --- a/resources/js/lib/project-dossier.ts +++ b/resources/js/lib/project-dossier.ts @@ -1,5 +1,6 @@ import { displayValue } from './display-value.ts'; import { monthlyIvaInput, monthlyIvaKey, readMonthlyIvaRecord, readMonthlyIvaSettings } from './monthly-iva.ts'; +import { modeloAPurchaseReferences } from './iva-modelo-a.ts'; import { fiscalQaRows } from './fiscal-qa-preview.ts'; import { csvCellWithDelimiter } from './csv.js'; import { @@ -617,6 +618,11 @@ export function buildProjectDossierRows( rows.push(['IVA mensal', 'Estado da versão', current ? 'Entradas correspondentes à projecção guardada' : 'Histórico desactualizado face às vendas ou pressupostos actuais; não aplicar como resultado actual', 'Execução versionada no servidor; sem apuramento final']); if (saved?.execution.result_snapshot) for (const [label,value] of fiscalQaRows(saved.execution.result_snapshot)) rows.push(['IVA mensal', label, value, 'Snapshot fiscal preservado; sem recálculo na exportação']); else rows.push(['IVA mensal', 'Resultado', 'Indeterminado ou execução ainda não concluída', 'Sem substituição por zero']); + try { + for (const purchase of modeloAPurchaseReferences(draft)) rows.push(['IVA mensal', `Compras/encomendas — mês ${purchase.month}`, purchase.declared ?? 'Sem informação', 'Pressuposto actual do plano, não resultado fiscal histórico; base/IVA incluído por classificar; IVA suportado e dedutível indeterminados; não é data de factura ou pagamento']); + } catch { + rows.push(['IVA mensal','Aquisições projectadas','Não foi possível recuperar; sem substituição por zero','Pressupostos guardados preservados; não calcula deduções']); + } } if (draft.cashflow_snapshot) { const saved = restoreCashflowDraftSnapshot( diff --git a/tests/frontend/iva-modelo-a.test.mjs b/tests/frontend/iva-modelo-a.test.mjs new file mode 100644 index 00000000..e20b0b43 --- /dev/null +++ b/tests/frontend/iva-modelo-a.test.mjs @@ -0,0 +1,37 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { monthlyProjectedPurchaseOrders, serializeBusinessPlanSnapshot } from '../../resources/js/lib/business-financial-plan.ts'; +import { modeloAComponentRows, modeloAPurchaseReferences } from '../../resources/js/lib/iva-modelo-a.ts'; +import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts'; + +test('purchase references use active existing purchase schedules, not cost of sales or cash payments', () => { + const plan={periods:3,products:[{label:'A',monthlyUnits:'8',unitPrice:'30',unitVariableCost:'12',productInventoryPurchasesByPeriod:[{amount:'100',leadMonths:2},{amount:'0',leadMonths:0},{amount:'',leadMonths:1}]}],useProductInventorySchedule:true,monthlyInventoryPurchases:'900',monthlyVariableCostPayments:'700',useInventoryPurchaseSchedule:true,inventoryPurchaseSchedule:[{amount:'400',leadMonths:0},{amount:'500',leadMonths:0},{amount:'600',leadMonths:0}]}; + assert.deepEqual(monthlyProjectedPurchaseOrders(plan),['100.00','0.00',null]); + plan.useProductInventorySchedule=false; + assert.deepEqual(monthlyProjectedPurchaseOrders(plan),['400.00','500.00','600.00']); + plan.useInventoryPurchaseSchedule=false; + assert.deepEqual(monthlyProjectedPurchaseOrders(plan),['900.00','900.00','900.00']); +}); + +test('missing and zero purchase amounts are preserved without manufacturing net VAT or deduction', () => { + const plan={currency:'MZN',periods:2,depreciationLifeMonths:60,products:[{label:'A',monthlyUnits:'1',unitPrice:'10',unitVariableCost:'0'}],useInventoryPurchaseSchedule:true,inventoryPurchaseSchedule:[{amount:'0',leadMonths:0},{amount:'',leadMonths:0}]}; + for(const key of ['openingCash','monthlyCollections','monthlyVariableCostPayments','monthlyOperatingExpenses','monthlyOperatingPayments','monthlyPayrollExpense','monthlyPayrollPayments','assetInvestment','inventory','receivables','payables','equity','shareholderLoans','bankLoanProceeds','grants','assetDepreciation','monthlyInterestExpense','monthlyInterestPayment','monthlyPrincipalRepayment']) plan[key]='0'; + const rows=modeloAPurchaseReferences({business_plan_snapshot:serializeBusinessPlanSnapshot(plan)}); + assert.equal(rows[0].declared,'0.00');assert.equal(rows[1].declared,null); + for(const row of rows) for(const field of ['net','vat','gross','deductible']) assert.equal(row[field],null); + assert.deepEqual(modeloAPurchaseReferences({}),[]); + assert.throws(()=>modeloAPurchaseReferences({business_plan_snapshot:'broken'}),/preservado/); + const report = createProjectDossierReport({currency:'MZN',business_plan_snapshot:serializeBusinessPlanSnapshot(plan),monthly_iva_snapshot:'{}'},{selectedSections:new Set(['finance'])}); + const text=JSON.stringify(report); + assert.match(text,/Compras\/encomendas/);assert.match(text,/0\.00/); + assert.match(text,/base\/IVA incluído por classificar/);assert.match(text,/IVA suportado e dedutível indeterminados/); +}); + +test('Modelo A report adds partial coverage without recalculating or rewriting accepted server history', () => { + const snapshot={monthly_projection:{rows:[{date:'2026-01-01',net_sales:'1000.03',vat:'160.0048'}]},result:{value:'160.0048'}}; + const before=JSON.stringify(snapshot);const rows=modeloAComponentRows(snapshot); + assert.equal(JSON.stringify(snapshot),before); + assert.match(rows.map(row=>row.join(' ')).join('\n'),/Indeterminado/); + assert.match(rows.map(row=>row.join(' ')).join('\n'),/não é imposto final/); + assert.deepEqual(modeloAComponentRows({scenario_kind:'custom_planning'}),[]); +});