Complete G2B social QA and prepare joint L1 delivery with compatible rollback
This commit is contained in:
@@ -5106,5 +5106,88 @@
|
||||
"path": "tests/frontend/fixtures/iva-services.json",
|
||||
"sha256": "8b215b97f4044d259a6f6d0075738591eccb4a1abd1b06cd4f819d5d83c430d2"
|
||||
}
|
||||
},
|
||||
"iva_l1_g2_social_joint_delivery_qa_20261024": {
|
||||
"status": "G2B_QA_and_joint_delivery_prepared;notinstalled;L1open",
|
||||
"candidate": null,
|
||||
"preserved": [
|
||||
"675cf38f/0e644b55",
|
||||
"5030116e/89ab2883",
|
||||
"689e7cbe/8719e916",
|
||||
"544068e8/d89912e5",
|
||||
"reference/stabilization-20261024"
|
||||
],
|
||||
"G2B_mapping": {
|
||||
"AUD-SIM-L1-P009": [
|
||||
"social_assistance_public",
|
||||
"social_assistance_nonprofit"
|
||||
],
|
||||
"AUD-SIM-L1-P011": [
|
||||
"social_care_public",
|
||||
"social_care_nonprofit"
|
||||
],
|
||||
"AUD-SIM-L1-P012": [
|
||||
"activity_facilities_public",
|
||||
"activity_facilities_nonprofit"
|
||||
]
|
||||
},
|
||||
"counts": {
|
||||
"original_IDs": 133,
|
||||
"QA_covered_branches": 12,
|
||||
"functional_pending": 120,
|
||||
"documentary_pending": 1,
|
||||
"new_branches": 3,
|
||||
"new_treatments": 6,
|
||||
"joint_new_group_treatments": 15,
|
||||
"joint_conditional_treatments_including_initial10": 25
|
||||
},
|
||||
"P010_refinement": "9(2)(b)saysseguranca,notsegurancasocial;labelcorrected,stillpending,sameID",
|
||||
"proofs": {
|
||||
"new_frontend_tests": 2,
|
||||
"new_API_tests": 1,
|
||||
"API_assertions": 15,
|
||||
"database": "simulator_fiscal_delta_20261021_test:55441",
|
||||
"rollback": true,
|
||||
"UI": "Public/nonprofitdifferentconditions;missingpricecondition->indeterminate;restored->600MZN;UI/API/recoveredreport311/Manica/2026-03/revision3",
|
||||
"prior_books_309_310_unchanged": true,
|
||||
"accepted_tests_repeated": false,
|
||||
"accepted_Word_PDF_regenerated": false,
|
||||
"types": "passed",
|
||||
"build": "passed",
|
||||
"readonly_reversal_QA": "Patchapplies;L1inputs/calculationdisabled;storedresultanddetailsremain;normalcandidateunmodified",
|
||||
"UI_reload": "Revision3/Manica/311/2026-03/600MZN maintained;normalcomponenteditable;readonlypatchonlyinQAvariant"
|
||||
},
|
||||
"delivery_manifest": "docs\\investmoz\\simulations\\l1-joint-delivery-20261024.json",
|
||||
"runtime_paths": [
|
||||
"resources/js/components/simulation-monthly-iva.tsx",
|
||||
"resources/js/components/simulation-operations.tsx",
|
||||
"resources/js/lib/fiscal-rational.ts",
|
||||
"resources/js/lib/iva-acquisitions.ts",
|
||||
"resources/js/lib/iva-operations.ts",
|
||||
"resources/js/lib/project-dossier.ts"
|
||||
],
|
||||
"schema_or_permission_changes": false,
|
||||
"active_changes": false,
|
||||
"published_rule_activation": false,
|
||||
"main_pushed": false,
|
||||
"homologation_delivery": false,
|
||||
"remaining_dependency": "P001specificinstruction05/06doesnotblockindependentgroups",
|
||||
"artifacts": {
|
||||
"calculated.json": "c317830b9a9c335709a2af672b2af0d36cb9d64ac59648d5df3c7ab05a4aa77d",
|
||||
"ui-calculated.json": "9151c045c9344e2b36a9b9b200abb823e855cadb4140384f7d32518c312d66d4",
|
||||
"recovered.json": "bedc32fff1dccef46199c675fb4ebb23181b0615b3e758391587242ba7b92f96",
|
||||
"frontend-tests.txt": "63457000642f7e8a1d4bd511ce6848fb4b7a4510cf7829c984a3aa7c0d1b9b62",
|
||||
"api-tests.txt": "30e1a37bfa8a79aceca4be216713994eadfc2f84cc1cdb9ad1d18379a8058290",
|
||||
"api-tests.xml": "1c2fa8c615ffca04ff838b82131102ada60f24469b92b065346cfb10ae00d531",
|
||||
"social-model.json": "5883bf3d063eebd73732302d4df3b4bdd111b0922fb85f1fbc60afe0644ce57f",
|
||||
"social-report.html": "1febdfc2794924ac3e6f6c7aef8acc4fb21c487f258d7462d6cc9a9e14d5ccc1",
|
||||
"types.txt": "5346ac8a6566c1c38cb0bbda6a029579df58cd78af78e2c4845d9c82b5d1d76c",
|
||||
"build.txt": "4f0952cd1a66a3d991796f138e6de6a69867b4d0ccc212c895322068384c3cbf",
|
||||
"checks.json": "f366fb2d17bd44e91ee7642dd28e935d71f574652e62868f612a83de257eacea",
|
||||
"rollback-proof.json": "2918f7b4d3436cdf44d0605fdd88d389a30567f6a876b4223e680f7c50c05bfc",
|
||||
"qa-rollback.png": "fde7ad60608a3572e0537f61a6947b1c1513d535ab522c7db3f7a5666e49ac56",
|
||||
"qa-recovered.png": "5bd4748824137cda2c1465ce13a302df85f5a4fe3e4572a4f7ecc19ea075a310",
|
||||
"qa-result.png": "3f88f884925258230ec91942f94ee0cacba3e9472c250a70cdce8b1bb41682ba"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
{
|
||||
"status": "prepared_QA_not_installed",
|
||||
"candidate": null,
|
||||
"base_remote_main": "1655f57e698fef4099c2886069a79cd1c920f792",
|
||||
"fetch": "completed;noforce;localmainnotused",
|
||||
"bundle": null,
|
||||
"coverage": {
|
||||
"initial_QA": "544068e8/d89912e5:10conditionaltreatments",
|
||||
"rational_QA": "689e7cbe/8719e916;exactincluded5%andreaders",
|
||||
"G1": "5030116e/89ab2883:4branches/4treatments",
|
||||
"G2A": "675cf38f/0e644b55:5branches/5treatments",
|
||||
"G2B": {
|
||||
"AUD-SIM-L1-P009": [
|
||||
"social_assistance_public",
|
||||
"social_assistance_nonprofit"
|
||||
],
|
||||
"AUD-SIM-L1-P011": [
|
||||
"social_care_public",
|
||||
"social_care_nonprofit"
|
||||
],
|
||||
"AUD-SIM-L1-P012": [
|
||||
"activity_facilities_public",
|
||||
"activity_facilities_nonprofit"
|
||||
]
|
||||
},
|
||||
"conditional_treatments_total": 25,
|
||||
"indeterminate_options": 2,
|
||||
"QA_covered_inventory_IDs": [
|
||||
"AUD-SIM-L1-P003",
|
||||
"AUD-SIM-L1-P004",
|
||||
"AUD-SIM-L1-P005",
|
||||
"AUD-SIM-L1-P006",
|
||||
"AUD-SIM-L1-P007",
|
||||
"AUD-SIM-L1-P009",
|
||||
"AUD-SIM-L1-P011",
|
||||
"AUD-SIM-L1-P012",
|
||||
"AUD-SIM-L1-P017",
|
||||
"AUD-SIM-L1-P018",
|
||||
"AUD-SIM-L1-P029",
|
||||
"AUD-SIM-L1-P030"
|
||||
],
|
||||
"pending_functional_IDs": [
|
||||
"AUD-SIM-L1-P002",
|
||||
"AUD-SIM-L1-P008",
|
||||
"AUD-SIM-L1-P010",
|
||||
"AUD-SIM-L1-P013",
|
||||
"AUD-SIM-L1-P014",
|
||||
"AUD-SIM-L1-P015",
|
||||
"AUD-SIM-L1-P016",
|
||||
"AUD-SIM-L1-P019",
|
||||
"AUD-SIM-L1-P020",
|
||||
"AUD-SIM-L1-P021",
|
||||
"AUD-SIM-L1-P022",
|
||||
"AUD-SIM-L1-P023",
|
||||
"AUD-SIM-L1-P024",
|
||||
"AUD-SIM-L1-P025",
|
||||
"AUD-SIM-L1-P026",
|
||||
"AUD-SIM-L1-P027",
|
||||
"AUD-SIM-L1-P028",
|
||||
"AUD-SIM-L1-P031",
|
||||
"AUD-SIM-L1-P032",
|
||||
"AUD-SIM-L1-P033",
|
||||
"AUD-SIM-L1-P034",
|
||||
"AUD-SIM-L1-P035",
|
||||
"AUD-SIM-L1-P036",
|
||||
"AUD-SIM-L1-P037",
|
||||
"AUD-SIM-L1-P038",
|
||||
"AUD-SIM-L1-P039",
|
||||
"AUD-SIM-L1-P040",
|
||||
"AUD-SIM-L1-P041",
|
||||
"AUD-SIM-L1-P042",
|
||||
"AUD-SIM-L1-P043",
|
||||
"AUD-SIM-L1-P044",
|
||||
"AUD-SIM-L1-P045",
|
||||
"AUD-SIM-L1-P046",
|
||||
"AUD-SIM-L1-P047",
|
||||
"AUD-SIM-L1-P048",
|
||||
"AUD-SIM-L1-P049",
|
||||
"AUD-SIM-L1-P050",
|
||||
"AUD-SIM-L1-P051",
|
||||
"AUD-SIM-L1-P052",
|
||||
"AUD-SIM-L1-P053",
|
||||
"AUD-SIM-L1-P054",
|
||||
"AUD-SIM-L1-P055",
|
||||
"AUD-SIM-L1-P056",
|
||||
"AUD-SIM-L1-P057",
|
||||
"AUD-SIM-L1-P058",
|
||||
"AUD-SIM-L1-P059",
|
||||
"AUD-SIM-L1-P060",
|
||||
"AUD-SIM-L1-P061",
|
||||
"AUD-SIM-L1-P062",
|
||||
"AUD-SIM-L1-P063",
|
||||
"AUD-SIM-L1-P064",
|
||||
"AUD-SIM-L1-P065",
|
||||
"AUD-SIM-L1-P066",
|
||||
"AUD-SIM-L1-P067",
|
||||
"AUD-SIM-L1-P068",
|
||||
"AUD-SIM-L1-P069",
|
||||
"AUD-SIM-L1-P070",
|
||||
"AUD-SIM-L1-P071",
|
||||
"AUD-SIM-L1-P072",
|
||||
"AUD-SIM-L1-P073",
|
||||
"AUD-SIM-L1-P074",
|
||||
"AUD-SIM-L1-P075",
|
||||
"AUD-SIM-L1-P076",
|
||||
"AUD-SIM-L1-P077",
|
||||
"AUD-SIM-L1-P078",
|
||||
"AUD-SIM-L1-P079",
|
||||
"AUD-SIM-L1-P080",
|
||||
"AUD-SIM-L1-P081",
|
||||
"AUD-SIM-L1-P082",
|
||||
"AUD-SIM-L1-P083",
|
||||
"AUD-SIM-L1-P084",
|
||||
"AUD-SIM-L1-P085",
|
||||
"AUD-SIM-L1-P086",
|
||||
"AUD-SIM-L1-P087",
|
||||
"AUD-SIM-L1-P088",
|
||||
"AUD-SIM-L1-P089",
|
||||
"AUD-SIM-L1-P090",
|
||||
"AUD-SIM-L1-P091",
|
||||
"AUD-SIM-L1-P092",
|
||||
"AUD-SIM-L1-P093",
|
||||
"AUD-SIM-L1-P094",
|
||||
"AUD-SIM-L1-P095",
|
||||
"AUD-SIM-L1-P096",
|
||||
"AUD-SIM-L1-P097",
|
||||
"AUD-SIM-L1-P098",
|
||||
"AUD-SIM-L1-P099",
|
||||
"AUD-SIM-L1-P100",
|
||||
"AUD-SIM-L1-P101",
|
||||
"AUD-SIM-L1-P102",
|
||||
"AUD-SIM-L1-P103",
|
||||
"AUD-SIM-L1-P104",
|
||||
"AUD-SIM-L1-P105",
|
||||
"AUD-SIM-L1-P106",
|
||||
"AUD-SIM-L1-P107",
|
||||
"AUD-SIM-L1-P108",
|
||||
"AUD-SIM-L1-P109",
|
||||
"AUD-SIM-L1-P110",
|
||||
"AUD-SIM-L1-P111",
|
||||
"AUD-SIM-L1-P112",
|
||||
"AUD-SIM-L1-P113",
|
||||
"AUD-SIM-L1-P114",
|
||||
"AUD-SIM-L1-P115",
|
||||
"AUD-SIM-L1-P116",
|
||||
"AUD-SIM-L1-P117",
|
||||
"AUD-SIM-L1-P118",
|
||||
"AUD-SIM-L1-P119",
|
||||
"AUD-SIM-L1-P120",
|
||||
"AUD-SIM-L1-P121",
|
||||
"AUD-SIM-L1-P122",
|
||||
"AUD-SIM-L1-P123",
|
||||
"AUD-SIM-L1-P124",
|
||||
"AUD-SIM-L1-P125",
|
||||
"AUD-SIM-L1-P126",
|
||||
"AUD-SIM-L1-P127",
|
||||
"AUD-SIM-L1-P128",
|
||||
"AUD-SIM-L1-P129",
|
||||
"AUD-SIM-L1-P130",
|
||||
"AUD-SIM-L1-P131",
|
||||
"AUD-SIM-L1-P132",
|
||||
"AUD-SIM-L1-P133"
|
||||
],
|
||||
"pending_documentary_IDs": [
|
||||
"AUD-SIM-L1-P001"
|
||||
]
|
||||
},
|
||||
"runtime_delta": [
|
||||
{
|
||||
"path": "resources/js/components/simulation-monthly-iva.tsx",
|
||||
"sha256_LF": "27e9f7b0a6cd011d6278d5bf507c8df0a290432006d795e9f7bf03b05fc6b350"
|
||||
},
|
||||
{
|
||||
"path": "resources/js/components/simulation-operations.tsx",
|
||||
"sha256_LF": "ae8fafbff339c4b52bae11ad479caf0fb451e5543e59bfbf15becf9aab4c5d27"
|
||||
},
|
||||
{
|
||||
"path": "resources/js/lib/fiscal-rational.ts",
|
||||
"sha256_LF": "91234efa465a8660f71a56e48d280a602c56ecf2ccce9cf7a8d91db513a3ffd3"
|
||||
},
|
||||
{
|
||||
"path": "resources/js/lib/iva-acquisitions.ts",
|
||||
"sha256_LF": "846dbd2d2dbdd54ffcddae8623eeaa2ae4f7686c6e2db05590ffa893d3ffbfb0"
|
||||
},
|
||||
{
|
||||
"path": "resources/js/lib/iva-operations.ts",
|
||||
"sha256_LF": "fb41bf3d6cf14ee65bf242f5a2504f9d4758c8d87bb4c4e9eda4822f74aa4d7f"
|
||||
},
|
||||
{
|
||||
"path": "resources/js/lib/project-dossier.ts",
|
||||
"sha256_LF": "5a6ea8a8c7261fa1d24cca56e92617cd66f72bd027dbafec22d051e686e927d7"
|
||||
}
|
||||
],
|
||||
"schema_routes_permissions_dependencies_changed": false,
|
||||
"database_imports_migrations_seeds": [],
|
||||
"server_fiscal_rule_activation": false,
|
||||
"activation": {
|
||||
"method": "ExistingGitFF/merge+build+webhook;no new mandatory flag",
|
||||
"preflight": [
|
||||
"Re-fetchorigin/main;reconcileconcurrentchangeswithoutforce",
|
||||
"Confirmactualservedrevisionandvalidbackup/restoreresultthroughauthenticatedexistingprocess",
|
||||
"Usecompiledassets;excludeoutputs/syntheticdata/publichot/secrets",
|
||||
"No globalmigration,seed,taxpublication or datareplacement"
|
||||
],
|
||||
"installed_delta_only": [
|
||||
"servedrevisionandmanifesthash",
|
||||
"simulatorusesnewasset",
|
||||
"newoptions/readerscontextvisible;existingdraftrecoverable",
|
||||
"prioracceptedproofsreused;nosyntheticwritesinactive"
|
||||
]
|
||||
},
|
||||
"reversal": {
|
||||
"preferred": "ForwardGitcompatibilitycontainmentcommitusingpreparedreadonlypatch,notDBrestore;revertcontainmentcommitafterfix",
|
||||
"patch": {
|
||||
"patch": "docs\\investmoz\\simulations\\l1-joint-readonly-rollback-20261024.patch",
|
||||
"patch_sha256": "d25a81f025ffeeb5869161404eb23b9762d87e07b4a820c14b63d29359d0db0e",
|
||||
"component_before_sha256": "37676ccb4302e5fdf5dceb58291809f120ea204c2a8c6a59ede9585f8753aa73",
|
||||
"git_apply_check": true,
|
||||
"live_component_changed": false,
|
||||
"purpose": "Operational compatibility rollback: suspend edits/calculations in L1 panel only;keep catalogue,readers,history,API,otherforms and reports;no DBrestore or broad path disable"
|
||||
},
|
||||
"QA_UI": "L1inputs/calculationdisabled;details/result600MZN/revision3/readers/reportsremain;otherforms/APIpermissionsunchanged",
|
||||
"limitations": "UIoperationalcontainment,notAPIauthorizationchange;fullrollbackto1655wouldhidenewL1readersandisnotpreferred"
|
||||
},
|
||||
"destination_precheck": {
|
||||
"public_revision_url": "https://teste-investidor.tempo.co.mz/build/revision.json",
|
||||
"result": "HTTP403",
|
||||
"served_revision_verified_this_pass": false,
|
||||
"protected_installer_or_current_backup_verified": false
|
||||
},
|
||||
"excluded": [
|
||||
"P001mapping",
|
||||
"120unimplementedbranches",
|
||||
"newtaxes",
|
||||
"IRPC/IRPS",
|
||||
"statistics/AI",
|
||||
"syntheticQArecordsandruntimefiles"
|
||||
],
|
||||
"delivery_performed": false
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
--- a/resources/js/components/simulation-operations.tsx
|
||||
+++ b/resources/js/components/simulation-operations.tsx
|
||||
@@ -9,6 +9,8 @@
|
||||
const save=(next:SalesBook)=>onChange('modelo_a_snapshot',saveSalesBook(draft,next));
|
||||
const change=(id:string,patch:Partial<SalesOperation>)=>run(()=>save({...book,rows:book.rows.map(r=>r.id===id?{...r,...patch}:r)}));
|
||||
return <section aria-label="Operações IVA por oportunidade" className="space-y-3 rounded border p-3">
|
||||
+ <p role="status">Novos cálculos de operações IVA temporariamente suspensos. Resultados guardados e relatórios permanecem disponíveis.</p>
|
||||
+ <fieldset disabled>
|
||||
<h4 className="font-semibold">Operações de IVA — enquadramento das vendas</h4>
|
||||
<p>Oportunidade {String(draft.context_opportunity||'entrada geral')}; moeda original {book.currency||'por indicar'}. Cobertura2026/MZN. Reutilize as vendas e complete apenas o enquadramento. Este bloco classifica as operações; não substitui nem soma novamente a execução mensal geral acima.</p>
|
||||
<p>Uma empresa pode ter operações com tratamentos diferentes. Os valores são projecções sob pressupostos declarados, sem certificar facturas, reconhecer créditos ou submeter uma declaração à AT.</p>
|
||||
@@ -36,6 +38,7 @@
|
||||
{book.periods.map(p=><label className="block" key={p.period}><input type="checkbox" checked={p.complete} onChange={e=>run(()=>save({...book,periods:book.periods.map(v=>v.period===p.period?{...v,complete:e.target.checked}:v)}))}/> {p.period}: incluí todas as operações deste período; lista vazia significa ausência expressamente confirmada.</label>)}
|
||||
<p>Limites: outras isenções/bases especiais e correspondência do campo06 permanecem por delimitar. IVA incluído a5% conserva a fracção exacta e apresenta um decimal a6casas; a aproximação de apresentação não constitui regra declarativa. O desconhecido nunca é assumido como zero.</p>
|
||||
<button type="button" disabled={!book.periods.length} className="rounded bg-emerald-800 p-2 text-white disabled:opacity-50" onClick={()=>run(()=>save(recordSales(draft,book)))}>Calcular e guardar operações IVA</button>
|
||||
+ </fieldset>
|
||||
{book.result&&<><p role="status">{salesCurrent(draft,book)?'Resultado correspondente às entradas.':'Resultado histórico conservado; reveja as alterações antes de recalcular.'}</p><dl>{salesReportRows(draft).map(([,label,value,origin],index)=><div className="break-inside-avoid border-t py-2" key={index}><dt className="font-semibold">{label}</dt><dd>{value}<small className="block">{origin}</small></dd></div>)}</dl></>}
|
||||
</section>;
|
||||
}
|
||||
@@ -1,5 +1,48 @@
|
||||
# Rastreabilidade, utilização e formação
|
||||
|
||||
## 24/10/2026 — G2B social em QA e entrega conjunta L1 preparada
|
||||
|
||||
**G2B executável/demonstrado em QA; entrega conjunta preparada, não instalada. L1 continua aberto.** Preservados G1 (`5030116e`/`89ab2883`), G2A (`675cf38f`/`0e644b55`), precisão racional (`689e7cbe`) e provas aceites. Não se repetiram os ensaios de G1/G2A nem se regeneraram os Word/PDF das fracções. O conjunto concluído não depende do fecho dos restantes ramos ou da correspondência de P001.
|
||||
|
||||
### G2B — três ramos, seis tratamentos por tipo de entidade
|
||||
|
||||
IDs com prefixo `AUD-SIM-L1-`:
|
||||
|
||||
| Ramo | Tratamento público | Tratamento sem finalidade lucrativa |
|
||||
| --- | --- | --- |
|
||||
| P009 — assistência social/bens estreitamente conexos | `social_assistance_public` | `social_assistance_nonprofit` |
|
||||
| P011 — actividade habitual de equipamentos sociais e bens/serviços conexos | `social_care_public` | `social_care_nonprofit` |
|
||||
| P012 — uso de instalações para prática artística/desportiva/recreativa/educação física | `activity_facilities_public` | `activity_facilities_nonprofit` |
|
||||
|
||||
**Fonte/período:** CIVA republicado Lei13/2016, art.9(2)(a),(c),(d), PDF9/p.1426(267); art.19(1), PDF15/p.1426(273). Lei22/2022 art.1, art.10(1–2), PDF2/p.2252(26): definição de entidade pública e quatro condições cumulativas do organismo sem finalidade lucrativa. Reutilizado o cotejo das alterações2017/2020/2022/2025 já documentado; não houve nova validação de credibilidade da fonte. Âmbito técnico2026/MZN, operações internas; campo07 condicionado, sem dedução automática de compras ou apuramento integral.
|
||||
|
||||
Entidade pública: órgão/instituição da Administração Pública com funções administrativas do Estado nos termos legais. Organismo sem finalidade lucrativa: cumulativamente, não disponibiliza lucros nem interesse dos gerentes nos resultados; escrituração de todas as actividades disponível aos serviços fiscais; preços homologados ou, quando não sujeitos a homologação, inferiores aos comerciais análogos; ausência de concorrência directa com sujeitos passivos. Os controlos de uma entidade pública não exigem as quatro condições próprias do outro tipo. É a definição do artigo10, não um novo aprovador ou requisito organizacional criado pelo Codex.
|
||||
|
||||
Acrescem as condições da operação: assistência social e bens estreitamente conexos com fins/objecto reconhecidos; equipamento social enumerado, pertencente à entidade, na actividade habitual, com reconhecimento quando exigido; instalação explorada pela própria entidade e serviço a quem pratica a actividade, sem isenção automática de bilhetes para espectadores, rendas ou revenda. A escolha não decorre apenas do sector ou da designação «associação». A falta de uma condição/fundamento produz indeterminação; não zero nem isenção presumida. Os dados específicos são pedidos nos controlos já existentes, reutilizando contexto, moeda original, período, preço/representação e documentação válida do dossier.
|
||||
|
||||
**Refinamento documental P010:** o texto de9(2)(b), na mesma página, diz «ligadas à segurança», prestadas por entidades públicas. A rotulagem anterior «segurança social» foi corrigida na matriz; não se presume que a alínea seja um regime de segurança social. P010 continua pendente, com o mesmo ID e sem cálculo novo. Este refinamento não condiciona as alíneas(a)/(c)/(d).
|
||||
|
||||
Provas novas: dois testes frontend para seis tratamentos, todas as condições ausentes individualmente, fundamento ausente, preço líquido/incluído, contexto e relatório; um teste API privada/15asserções com guarda `simulator_fiscal_delta_20261021_test:55441` e rollback. Componente real em QA18629: condições públicas e não lucrativas distintas; retirada a condição de preços do organismo não lucrativo→indeterminação; reposta→seis linhas de100MZN/campo07=600MZN/IVA0, oportunidade311/Manica/2026-03, revisão3. Interface→API→recuperação idêntica→relatório HTML existente. Os livros aceites309/G2A e310/G1 permanecem iguais e legíveis, sem recálculo. Tipos/compilação conferidos apenas para o delta.
|
||||
|
||||
**Saldo exacto:**133IDs=**12ramos demonstrados em QA +120funcionais pendentes +P001documental**. Ramos cobertos: P003–P007, P009, P011–P012, P017–P018, P029–P030. Pendentes funcionais: P002, P008, P010, P013–P016, P019–P028, P031–P133. G2 mantém32ramos:8cobertos/24pendentes. G1/G2A/G2B somam15tratamentos para12ramos; com os dez tratamentos iniciais já aceites fora deste saldo, o conjunto oferece25tratamentos determinados sob condições, mais duas opções explicitamente indeterminadas. Não se confundem ramos, tratamentos, grupos ou pendência documental.
|
||||
|
||||
### Entrega conjunta — cobertura e dependências concretas
|
||||
|
||||
Manifesto executável/reconciliável: [l1-joint-delivery-20261024.json](../simulations/l1-joint-delivery-20261024.json). Inclui o motor L1 inicial, precisão racional e leitores/relatórios necessários, G1, G2A e G2B. Não é possível transportar só as opções novas sem as dependências L1 que ainda não estão na referência remota. Nenhum outro imposto, regime não demonstrado, tratamento de P001, alteração de fontes publicadas, migração, seeder, importação ou mudança de permissões integra a entrega. As fontes/cálculos publicados no servidor não são activados por este pacote.
|
||||
|
||||
A referência `origin/main` foi actualizada por `git fetch origin`, terminando em `1655f57e698fef4099c2886069a79cd1c920f792`. O `main` local é anterior e não foi usado como base de reposição. A diferença funcional desde o destino Git limita-se a seis ficheiros JS/TS: painel mensal, operações, fracções, aquisições, operações e consolidação do dossier. Mantêm-se S1–S3, aquisições08–10/totais condicionados14–18, estabilização276d833a, complementos, âncoras/mapas e alterações concorrentes herdadas. A pré-visualização Git deve confirmar ancestralidade/integração antes da publicação; qualquer avanço remoto exige reconciliação do delta, nunca force-push ou substituição do trabalho concorrente.
|
||||
|
||||
**Activação preparada:** confirmar revisão servida e backup/restauro válidos do destino no processo existente; actualizar novamente `origin/main`; integrar a candidata/conjunto por fast-forward quando possível ou merge reconciliado; build normal por `npm ci`/`npm run build` e webhook existente. Excluir outputs, basesQA, dados sintéticos, `public/hot`, segredos e dependências locais do artefacto activo. Não há migration/seed/regra fiscal de servidor a executar nem novo sinalizador obrigatório. O painel passa a disponibilizar as opções compiladas no percurso já existente; a condição de cada operação continua explícita. Após instalação conferir só revisão servida/manifesto/asset do simulador e o delta de visibilidade/contexto/leitura, reutilizando os ensaios aceites. Não criar pedidos sintéticos no activo.
|
||||
|
||||
A leitura prévia de `https://teste-investidor.tempo.co.mz/build/revision.json` nesta passagem devolveu **HTTP403**. Portanto, não se afirma uma nova conferência da revisão efectivamente servida, de backup activo ou do instalador protegido. A referência1655f57e é a referência Git remota e a última entrega comunicada. O controlo autenticado já existente permite conferir o destino no momento da instalação; não é dependência fiscal nem bloqueio de P001. Nesta passagem não houve push para main, instalação ou escrita no activo.
|
||||
|
||||
**Reversão preparada e ensaiada em QA:** [patch de consulta L1](../simulations/l1-joint-readonly-rollback-20261024.patch), verificado por `git apply --check` e pelo componente real em QA. Mantém catálogo, leitores, snapshots/histórico, relatórios, API e restantes formulários; suspende apenas edição/cálculo no painel L1 através de um fieldset desactivado com explicação visível. A consulta dos detalhes e o resultado de600MZN continuam disponíveis. É uma contenção operacional da interface, não uma alteração das permissões da API nem uma regra de negócio. Não está aplicada à candidata normal.
|
||||
|
||||
Em incidente: criar correcção Git sobre a revisão instalada, aplicar o patch sem ignorar conflitos, compilar/disponibilizar pelo mesmo processo e verificar apenas suspensão L1+consulta/relatório+demais percursos preservados. Corrigida a causa, reverter apenas esse commit de contenção e disponibilizar novamente. Não restaurar a base nem apagar snapshots para uma reversão de código. Voltar integralmente à revisão1655f57e ocultaria os tratamentos/leitores L1 e não é a reversão preferencial; se exigido por emergência, identificar essa redução e conservar base/originais/histórico para recuperação compatível. O bundle Git preparado transporta a história do conjunto desde a base remota; o recibo fixa candidata, hashes e resultado da pré-visualização. Ainda não é entrega na homologação.
|
||||
|
||||
Estatísticas/IA e os restantes lotes permanecem no plano acordado. Não se reabre o concluído para exigir uma nova ronda genérica de aceitação.
|
||||
|
||||
|
||||
## 24/10/2026 — reconciliação dos IDs L1 e incremento G2A de saúde
|
||||
|
||||
**Incremento executável em QA, candidata `675cf38f`; L1 aberto; homologação inalterada.** Preservados `5030116e`/registo `89ab2883`, G1 e a apresentação das fracções Word/PDF, aceites pela Tempo com base no relatório. Não se repetiram esses ensaios nem se regeneraram os respectivos ficheiros. As entregas podem reunir conjuntos coerentes/utilizáveis; o fecho de todos os ramos não é condição técnica ou organizacional para entregar um conjunto. Esta passagem prepara QA, sem realizar integração/disponibilização.
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -10,9 +10,18 @@ const source2022 = 'Lei22/2022, BR250, 2.º suplemento, PDF1–4 (2252(25)–(28
|
||||
const source2016 = 'CIVA republicado Lei13/2016, BR156, 10.º suplemento, PDF9–15 (1426(267)–(273))';
|
||||
const source2025 = 'Lei10/2025, BR248, suplemento1, PDF14–15 (2180(14)–(15)); arts.1/2/3/5; efeitos01/01/2026';
|
||||
const healthGoodsSource = 'CIVA republicado Lei13/2016, PDF9, p.1426(267), art.9(1)(b–f); PDF15, p.1426(273), art.19(1); Lei22/2022 art.1, PDF1, p.2252(25), mantém9(1)(b–f). Âmbito técnico2026/MZN';
|
||||
const internalHealthOperation = 'Operação interna localizada em Moçambique; não é importação nem operação localizada no estrangeiro';
|
||||
const internalOperation = 'Operação interna localizada em Moçambique; não é importação nem operação localizada no estrangeiro';
|
||||
export const modeloA06Correspondence = 'Exemplar recebido:06 é base de operações isentas, com remissão18(1)(b); nessa lei18(1)(b) trata IVA de importações, enquanto19(1)(b) enumera operações com direito. O mesmo exemplar já tem05 para vendas isentas com direito. O formulário antigo da AT usa03 para a remissão e06 para existências. Não há correspondência unívoca nem instrução aplicável que separe05/06 no acervo conferido: não atribuir06 automaticamente a operações no estrangeiro ou importar instruções antigas por número.';
|
||||
export type OperationTreatment = {id:string; label:string; field:string|null; rate:number|null; article:string; source:string; conditions:string[]};
|
||||
const nonprofitConditions = [
|
||||
'Não distribui nem disponibiliza lucros; os corpos gerentes não têm interesse directo ou indirecto nos resultados, por si ou interposta pessoa',
|
||||
'Escrituração abrange todas as actividades e está à disposição dos serviços fiscais para comprovação',
|
||||
'Preços homologados pela autoridade competente ou, quando não susceptíveis de homologação, inferiores aos de operações análogas das empresas comerciais sujeitas a imposto',
|
||||
'Não entra em concorrência directa com sujeitos passivos do imposto',
|
||||
];
|
||||
function socialTreatment(id:string,label:string,article:string,conditions:string[],nonprofit:boolean):OperationTreatment {
|
||||
return {id,label,field:'07',rate:0,article:`CIVA arts.9(2)(${article}),10(${nonprofit?'2':'1'}),19(1)`,source:'CIVA republicado Lei13/2016, PDF9, p.1426(267), art.9(2)(a/c/d); PDF15, p.1426(273),19(1); Lei22/2022 art.1, PDF2, p.2252(26),10(1–2). Âmbito técnico2026/MZN',conditions:[internalOperation,...(nonprofit?nonprofitConditions:['Entidade pública: órgão ou instituição da Administração Pública que desempenha funções administrativas do Estado, nos termos da legislação aplicável']),...conditions]};
|
||||
}
|
||||
export const operationTreatments:OperationTreatment[] = [
|
||||
{id:'general',label:'Operação interna geral',field:'01',rate:16,article:'CIVA arts.1,6,15(1),17(1–2); art.34 (Lei10/2025)',source:`${source2016}; ${source2022}; ${source2025}`,conditions:['Operação localizada e tributável em Moçambique, no regime normal','Contraprestação completa; sem base especial do art.15(2), isenção ou taxa reduzida']},
|
||||
{id:'private_health',label:'Serviços médicos e sanitários privados',field:'03',rate:5,article:'CIVA arts.15(10),17-A(a)',source:source2022,conditions:['Serviço médico/sanitário ou operação estreitamente conexa','Prestador hospitalar privado, clínica, dispensário ou similar']},
|
||||
@@ -28,11 +37,19 @@ export const operationTreatments:OperationTreatment[] = [
|
||||
{id:'insurance_stamp',label:'Seguro/resseguro ou mediação conexa sujeitos a Selo',field:'07',rate:0,article:'CIVA art.9(6), redacção Lei22/2022; art.19(1)',source:`${source2022}; ${source2016}`,conditions:['Seguro/resseguro ou serviço conexo efectuado por corrector ou outro mediador de seguros','Sujeição a Imposto do Selo identificada para esta operação']},
|
||||
{id:'public_waste',label:'Remoção de lixo pública ou por entidade contratada',field:'07',rate:0,article:'CIVA art.9(12)(b), redacção Lei22/2022; art.19(1)',source:`${source2022}; ${source2016}`,conditions:['Prestação de serviço de remoção de lixo, não qualquer serviço de limpeza','Efectuada por entidade pública ou por entidade por ela contratada, com relação identificada']},
|
||||
{id:'public_funeral',label:'Serviços funerários/cremação públicos e bens acessórios',field:'07',rate:0,article:'CIVA art.9(12)(c), redacção Lei22/2022; art.19(1)',source:`${source2022}; ${source2016}`,conditions:['Serviço funerário/cremação ou transmissão de bem acessório a esse serviço','Efectuado por entidade pública; não aplicar automaticamente a funerária privada']},
|
||||
{id:'health_assistive',label:'Bens de compensação da deficiência, próteses e braille',field:'07',rate:0,article:'CIVA arts.9(1)(b),19(1)',source:healthGoodsSource,conditions:[internalHealthOperation,'Bem identificado na enumeração: cadeira de rodas/veículo semelhante, aparelho/máquina/impressora braille, prótese ou material de compensação','Destino documentado conforme a categoria: deficiência, substituição de membro/órgão, fractura, pessoa invisual ou correcção da audição; não qualquer equipamento médico']},
|
||||
{id:'human_materials',label:'Órgãos, sangue e leite humanos',field:'07',rate:0,article:'CIVA arts.9(1)(c),19(1)',source:healthGoodsSource,conditions:[internalHealthOperation,'Transmissão de órgãos, sangue ou leite de origem humana, identificada; não produto de origem animal nem serviço autónomo']},
|
||||
{id:'patient_transport',label:'Transporte de doentes/feridos por organismo autorizado',field:'07',rate:0,article:'CIVA arts.9(1)(d),19(1)',source:healthGoodsSource,conditions:[internalHealthOperation,'Transporte de doente ou ferido em ambulância ou outro veículo apropriado','Organismo que efectua o transporte devidamente autorizado, com autorização identificada; não basta o destino hospitalar']},
|
||||
{id:'mosquito_nets',label:'Transmissão de redes mosquiteiras',field:'07',rate:0,article:'CIVA arts.9(1)(e),19(1)',source:healthGoodsSource,conditions:[internalHealthOperation,'Bem identificado como rede mosquiteira; não extensão automática a outros produtos de prevenção']},
|
||||
{id:'medicines',label:'Medicamentos e artigos terapêuticos/profilácticos elegíveis',field:'07',rate:0,article:'CIVA arts.9(1)(f),19(1)',source:healthGoodsSource,conditions:[internalHealthOperation,'Medicamento/especialidade farmacêutica ou produto farmacêutico exclusivamente terapêutico/profiláctico; ou pasta, gaze, algodão hidrófilo, tira/penso adesivo ou análogo','Finalidade elegível identificada: terapêutica/profiláctica nos produtos farmacêuticos; higiénica, medicinal ou cirúrgica nos artigos enumerados, mesmo impregnados/revestidos; não qualquer produto vendido por farmácia']},
|
||||
{id:'health_assistive',label:'Bens de compensação da deficiência, próteses e braille',field:'07',rate:0,article:'CIVA arts.9(1)(b),19(1)',source:healthGoodsSource,conditions:[internalOperation,'Bem identificado na enumeração: cadeira de rodas/veículo semelhante, aparelho/máquina/impressora braille, prótese ou material de compensação','Destino documentado conforme a categoria: deficiência, substituição de membro/órgão, fractura, pessoa invisual ou correcção da audição; não qualquer equipamento médico']},
|
||||
{id:'human_materials',label:'Órgãos, sangue e leite humanos',field:'07',rate:0,article:'CIVA arts.9(1)(c),19(1)',source:healthGoodsSource,conditions:[internalOperation,'Transmissão de órgãos, sangue ou leite de origem humana, identificada; não produto de origem animal nem serviço autónomo']},
|
||||
{id:'patient_transport',label:'Transporte de doentes/feridos por organismo autorizado',field:'07',rate:0,article:'CIVA arts.9(1)(d),19(1)',source:healthGoodsSource,conditions:[internalOperation,'Transporte de doente ou ferido em ambulância ou outro veículo apropriado','Organismo que efectua o transporte devidamente autorizado, com autorização identificada; não basta o destino hospitalar']},
|
||||
{id:'mosquito_nets',label:'Transmissão de redes mosquiteiras',field:'07',rate:0,article:'CIVA arts.9(1)(e),19(1)',source:healthGoodsSource,conditions:[internalOperation,'Bem identificado como rede mosquiteira; não extensão automática a outros produtos de prevenção']},
|
||||
{id:'medicines',label:'Medicamentos e artigos terapêuticos/profilácticos elegíveis',field:'07',rate:0,article:'CIVA arts.9(1)(f),19(1)',source:healthGoodsSource,conditions:[internalOperation,'Medicamento/especialidade farmacêutica ou produto farmacêutico exclusivamente terapêutico/profiláctico; ou pasta, gaze, algodão hidrófilo, tira/penso adesivo ou análogo','Finalidade elegível identificada: terapêutica/profiláctica nos produtos farmacêuticos; higiénica, medicinal ou cirúrgica nos artigos enumerados, mesmo impregnados/revestidos; não qualquer produto vendido por farmácia']},
|
||||
...([false,true] as const).flatMap(nonprofit=>{
|
||||
const suffix=nonprofit?'nonprofit':'public',entity=nonprofit?'organismo sem finalidade lucrativa':'entidade pública';
|
||||
return [
|
||||
socialTreatment(`social_assistance_${suffix}`,`Assistência social — ${entity}`,'a',['Prestação de assistência social ou transmissão de bens estreitamente conexa, identificada','Fins e objecto da entidade reconhecidos pelas autoridades competentes, com fundamento identificado'],nonprofit),
|
||||
socialTreatment(`social_care_${suffix}`,`Equipamentos sociais/creches/lares — ${entity}`,'c',['Prestação ou bem estreitamente conexo no exercício da actividade habitual de creche, jardim de infância, centro de tempos livres, lar ou outro equipamento social enumerado no art.9(2)(c)','Equipamento pertencente à entidade e fins/objecto reconhecidos pelas autoridades competentes; não qualquer alojamento ou empresa de cuidados'],nonprofit),
|
||||
socialTreatment(`activity_facilities_${suffix}`,`Prática artística/desportiva/recreativa — ${entity}`,'d',['Serviço efectuado pela própria entidade que explora o estabelecimento ou instalação','Instalação destinada à prática artística, desportiva, recreativa ou de educação física e serviço prestado a quem a pratica; não isenção automática de bilhetes para espectadores'],nonprofit),
|
||||
];
|
||||
}),
|
||||
{id:'foreign_operation',label:'Operação no estrangeiro — analisar territorialidade',field:null,rate:null,article:'CIVA art.6: localização por natureza da operação; art.19(1)(b)(ii) não determina sozinho a caixa06 do formulário',source:source2016,conditions:[]},
|
||||
{id:'other',label:'Outra operação / enquadramento ainda desconhecido',field:null,rate:null,article:'Fundamento específico ainda necessário; não presumir taxa ou isenção',source:'Sem fonte operacional determinada para esta linha',conditions:[]},
|
||||
];
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Tests\TestCase;
|
||||
|
||||
final class IvaSocialDraftTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
public function test_social_context_preserves_both_accepted_opportunities(): void
|
||||
{
|
||||
$target = DB::selectOne('select current_database() as name,inet_server_port() as port');
|
||||
$this->assertSame('simulator_fiscal_delta_20261021_test', $target->name);
|
||||
$this->assertSame(55441, (int) $target->port);
|
||||
config(['investor-path.enabled' => true, 'suitecrm.enabled' => false]);
|
||||
$this->actingAs(User::factory()->create(['email_verified_at' => now()]));
|
||||
$draft = json_decode(file_get_contents(getenv('IVA_G2B_INPUT') ?: base_path('outputs/iva-l1-g2-social-20261024/calculated.json')), true, flags: JSON_THROW_ON_ERROR);
|
||||
$id = $this->postJson('/api/v1/simulation-drafts', ['personal_snapshot' => [], 'economic_snapshot' => $draft], ['Idempotency-Key' => (string) Str::uuid()])->assertCreated()->json('data.id');
|
||||
$recovered = $this->getJson('/api/v1/simulation-drafts/'.$id)->assertOk()->json('data.economic_snapshot');
|
||||
$this->assertSame($draft['modelo_a_snapshot'], $recovered['modelo_a_snapshot']);
|
||||
$book = json_decode($recovered['modelo_a_snapshot'], true)['salesOperations']['opportunity:311'];
|
||||
$this->assertCount(6, $book['result']['rows']);
|
||||
$this->assertSame('600.00', $book['result']['periods'][0]['fields']['07']);
|
||||
$this->assertSame(json_decode($draft['modelo_a_snapshot'], true)['salesOperations']['opportunity:310'], json_decode($recovered['modelo_a_snapshot'], true)['salesOperations']['opportunity:310']);
|
||||
$this->assertSame(json_decode($draft['modelo_a_snapshot'], true)['salesOperations']['opportunity:309'], json_decode($recovered['modelo_a_snapshot'], true)['salesOperations']['opportunity:309']);
|
||||
foreach ($book['result']['rows'] as $row) $this->assertSame('0.00', $row['vat']);
|
||||
if (getenv('IVA_G2B_RECOVERED')) file_put_contents(getenv('IVA_G2B_RECOVERED'), json_encode($recovered, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,28 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import fs from 'node:fs';
|
||||
import {operationTreatments,newSalesOperation,evaluateSalesOperation,recordSales,saveSalesBook,salesBook,salesCurrent} from '../../resources/js/lib/iva-operations.ts';
|
||||
import {createProjectDossierReport} from '../../resources/js/lib/project-dossier-report.ts';
|
||||
const ids=['social_assistance_public','social_assistance_nonprofit','social_care_public','social_care_nonprofit','activity_facilities_public','activity_facilities_nonprofit'];
|
||||
function seed(){return JSON.parse(fs.readFileSync(new URL('./fixtures/iva-health-goods.json',import.meta.url),'utf8'));}
|
||||
function fixture(){const draft=seed();draft.context_opportunity='opportunity:311';draft.project_title='SYNTHETIC QA — G2B social';
|
||||
let book={currency:'MZN',rows:ids.map((id,i)=>({...newSalesOperation(`g2b-${i}`,'2026-03','MZN'),description:`SYNTHETIC QA ${id}`,establishment:'SYNTHETIC QA equipamento Manica',amount:'100',basis:i%2?'included':'net',treatment:id,confirmed:operationTreatments.find(t=>t.id===id).conditions.map((_,n)=>n),evidence:'SYNTHETIC QA — natureza, entidade, reconhecimento e condições cumulativas pressupostos documentados; sem certificação'})),periods:[{period:'2026-03',complete:true}]};book=recordSales(draft,book);draft.modelo_a_snapshot=saveSalesBook(draft,book);return {draft,book};}
|
||||
test('G2B three branches have six entity-specific treatments and cumulative nonprofit conditions',()=>{
|
||||
const {book}=fixture();for(const row of book.rows){const rule=operationTreatments.find(t=>t.id===row.treatment),r=evaluateSalesOperation(row,'MZN');assert.equal(r.field,'07');assert.equal(r.net,'100.00');assert.equal(r.vat,'0.00');assert.equal(r.gross,'100.00');assert.match(r.article,/10\(/);
|
||||
assert.equal(rule.conditions.length,row.treatment.endsWith('_nonprofit')?7:4);
|
||||
for(const missing of row.confirmed)assert.equal(evaluateSalesOperation({...row,confirmed:row.confirmed.filter(n=>n!==missing)},'MZN').vat,null);
|
||||
assert.equal(evaluateSalesOperation({...row,evidence:''},'MZN').vat,null);
|
||||
}
|
||||
assert.equal(book.result.periods[0].fields['07'],'600.00');
|
||||
});
|
||||
test('new social context round-trips and reports only its operations, preserving both accepted books without recalculation',()=>{
|
||||
const {draft,book}=fixture(),original=seed();const old=JSON.parse(original.modelo_a_snapshot).salesOperations;
|
||||
const recovered=JSON.parse(JSON.stringify(draft)),store=JSON.parse(recovered.modelo_a_snapshot).salesOperations;
|
||||
for(const id of ['opportunity:309','opportunity:310']){assert.deepEqual(store[id],old[id]);assert.equal(salesCurrent({...recovered,context_opportunity:id},store[id]),true);}
|
||||
assert.equal(salesCurrent(recovered,salesBook(recovered)),true);
|
||||
const model=JSON.stringify(createProjectDossierReport(recovered,{selectedSections:new Set(['finance'])}));
|
||||
for(const token of [...ids,'600.00','opportunity:311','Manica','2026-03','MZN'])assert.ok(model.includes(token),token);
|
||||
for(const token of ['financial_stamp','patient_transport'])assert.equal(model.includes(token),false);
|
||||
assert.equal(book.result.rows.length,6);assert.equal(draft.currency,original.currency);assert.deepEqual(draft.selection_labels,original.selection_labels);
|
||||
});
|
||||
if(process.env.IVA_G2B_OUT)fs.writeFileSync(process.env.IVA_G2B_OUT,JSON.stringify(fixture().draft,null,2));
|
||||
Reference in New Issue
Block a user