docs(iva): prepare joint travel event delivery preserving fiscal continuity
tests / ci (push) Canceled after 0s

This commit is contained in:
2026-10-25 01:48:26 +02:00
parent 1a5f72209e
commit a48e974979
3 changed files with 235 additions and 1 deletions
@@ -0,0 +1,212 @@
{
"status": "ready_after_fresh_authenticated_preflight_and_verified_backup_restore",
"candidate": "1a5f72209e4cb1ec38543f9465c59b8159dec15d",
"accepted_candidates": [
"1a5f7220"
],
"base_installed": "df43aeb1e583e65af854ac71f46ddaa1f49b0b7c",
"coverage_complete_branches": {
"AUD-SIM-L1-P129": [
"third_party_package",
"mixed_means_special_part",
"own_means_general",
"other_name_general",
"retailer_simple_general",
"retailer_new_package",
"foreign_establishment_outside"
],
"AUD-SIM-L1-P133": [
"travel_integral_first",
"travel_start_first",
"same_day_order_not_inferred",
"partial_8c",
"partial_then_full_no_double_count",
"invoice_before_special_event",
"travel_not_started",
"suspensive_exit_14_a_b_c_d",
"regime_still_held"
]
},
"branch_count_complete": 2,
"coverage_label": "P129/P133 no âmbito demonstrado: margem e eventos, sem calcular IVA devido ou dedução; sem apuramento fiscal integral.",
"meaning": {
"P129": "Natureza e âmbito do regime38/39; meios próprios/terceiros e retalhista; margem global por operador/período do registo simulado, custos directos e exclusões41(3), excesso anterior/seguinte e base positiva com divisor1.16 arredondada à unidade. Sem IVA devido, dedução43d/campo11, regularização44 ou factura/modelo oficial emitidos.",
"P133": "Cessação efectiva de regime7(8), distinta de mudança de armazém/transferência; viagens7(9)/RIVA40 pelo primeiro entre integral e início/primeiro serviço, sem subtrair dia nem inferir ordem intradiária. Exigibilidade8 por factura/recebimento separada, incluindo sinal e saldo integral sem dupla soma. Sem montante de imposto, desembaraço, direito ou ICE apurados."
},
"examples": {
"travel_rows": 10,
"global_periods": 5,
"special_event_rows": 12
},
"fiscal_continuity": {
"parent_requirement": "AUD-SIM-INT02",
"matrix": "docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv",
"manual": "docs/investmoz/unification/traceability-and-manual.md",
"implemented": "P129 margem/base global do período; P133 eventos/exigibilidade, sem calcular IVA devido ou dedução.",
"remaining": "Apuramento/liquidação fiscal restantes continuam ligados ao requisito integrado AUD-SIM-INT02; deduções, regularizações e restituições nos seus âmbitos/lotes próprios, incluindo L2/L3. A entrega P129/P133 não encerra esses trabalhos.",
"traceability": "Conserva base, moeda, operador, operação, período, datas, documentos/fontes e versões para utilização fiscal posterior; nenhuma regra/cálculo fiscal é activado por disponibilização."
},
"limitations_balance": {
"digital": "Formalidades P121/P130: modelos da declaração/mapa de retenções e procedimentos de entrega/pagamento ainda não automatizados; cobertura digital integral não declarada. Mantém-se o limite da entrega df43aeb1.",
"travel": "Cálculo limitado à base da margem do registo simulado declarado, não apuramento integral da organização. Não calcula IVA devido/dedução42/43d, não executa regularização44, não emite factura45 ou modelo oficial46(2).",
"P104": "Conversão condicionada preservada; falta regra aplicável à escolha da taxa/data.",
"P084_P085": "Rascunhos e simulação condicionada preservados; ModeloI.1 não demonstra ligação a14(3) nem benefício concedido.",
"P001": "Pendência documental limitada aos campos05/06.",
"scope": "L1 aberto; bebidas L2/L3; Estatísticas/IA adiadas."
},
"UI_delta_from_QA": "Esclarecimento textual da continuidade do trabalho fiscal, pedido pela Tempo; sem alteração de regra ou cálculo.",
"runtime_delta": [
{
"path": "resources/js/lib/iva-travel.ts",
"sha256_LF": "253efc133fd968cbec0e0f04530d8757eb5dbf686cc2baa34a92a0efe71ee2fd"
},
{
"path": "resources/js/lib/iva-travel-events.ts",
"sha256_LF": "862c2c7c584a10e51626b215b5e23cceda9ed29859180c009be41113e30d30e9"
},
{
"path": "resources/js/components/simulation-travel.tsx",
"sha256_LF": "3fc4aec2678ba8d39635affe2d1c8e1d0b8684be7532de1a45b12463789905a6"
},
{
"path": "resources/js/components/simulation-travel-events.tsx",
"sha256_LF": "0d12f7ace5d5c1488756675aab075f957d3833e059e58963cf69e5b1ea315bda"
},
{
"path": "resources/js/components/simulation-monthly-iva.tsx",
"sha256_LF": "ed7b32c1838eebf33fbb31366dc313bcc6fe718b3ffca9a990f495fa7a0d253a"
},
{
"path": "resources/js/lib/project-dossier.ts",
"sha256_LF": "a63f9ee361b175718ce405a888b8fca4f1525980a3f14bcea53770f49df2aaa0"
}
],
"compiled_delta_markers_expected": [
"travel-period-margin/1",
"travel-suspensive-events/1",
"travelOperations",
"travelSpecialEvents",
"grossReceipts",
"directCosts",
"excludedCosts",
"priorExcess",
"carryForward",
"baseDivisorRate",
"priorOverride",
"travel_special",
"suspensive_exit",
"fullPaymentState",
"fullPaymentDate",
"startState",
"regimeStatus",
"cessationConfirmed",
"eventTiming",
"Continuidade do trabalho fiscal:",
"sem calcular IVA devido ou dedução",
"não ficam concluídas por esta entrega",
"Cobertura digital deste incremento:",
"Não representa cobertura digital integral"
],
"counts_before": {
"delivered": 123,
"QA": 2,
"functional_pending": 7,
"documentary": 1,
"total": 133
},
"counts_current": {
"delivered": 123,
"QA": 2,
"functional_pending": 7,
"documentary": 1,
"total": 133
},
"counts_after_delivery": {
"delivered": 125,
"QA": 0,
"functional_pending": 7,
"documentary": 1,
"total": 133
},
"QA_proofs_reused": [
"iva-l1-travel-events-qa-20261025.json"
],
"authorization": "Tempo pede entrega conjunta P129/P133 pela via Git existente, preservando alterações concorrentes e verificando apenas delta instalado; manter limitação de IVA devido/dedução ligada ao trabalho fiscal restante.",
"preservation": "123 fechos, dados, acessos, relações e histórico preservados; P104/P084/P085 parciais e formalidades digitais não automatizadas mantidos.",
"P104_closure": false,
"limits": {
"digital": "Formalidades P121/P130: modelos da declaração/mapa de retenções e procedimentos de entrega/pagamento ainda não automatizados; cobertura digital integral não declarada. Mantém-se o limite da entrega df43aeb1.",
"travel": "Cálculo limitado à base da margem do registo simulado declarado, não apuramento integral da organização. Não calcula IVA devido/dedução42/43d, não executa regularização44, não emite factura45 ou modelo oficial46(2).",
"P104": "Conversão condicionada preservada; falta regra aplicável à escolha da taxa/data.",
"P084_P085": "Rascunhos e simulação condicionada preservados; ModeloI.1 não demonstra ligação a14(3) nem benefício concedido.",
"P001": "Pendência documental limitada aos campos05/06.",
"scope": "L1 aberto; bebidas L2/L3; Estatísticas/IA adiadas."
},
"source": "RIVA Decreto7/2008,38–46,acervoBR16-I16/04/2008PDF6–8/p104–106 (6/7 conferidas visualmente,46(2) texto extraídoPDF8). CIVA Lei13/2016,4(5)/5(2),PDF7/p1426(265);7(8)/(9)/8,PDF9/p1426(267);14(1),PDF13/p1426(271),páginas visualmente conferidas. CIVA17(1),Lei22/2022PDF3,16% usado no divisor da base;Lei10/2025não altera4/7/8/17. Não confundir regime fiscal com licenciamento turístico.",
"containment": "l1-travel-events-readonly-rollback-20261025.patch, conferida sem aplicar; suspende novas versões P129/P133 e conserva leitores/histórico/outros ramos.",
"authenticated_preflight": {
"installed": {
"status": "installed",
"commit": "df43aeb1e583e65af854ac71f46ddaa1f49b0b7c",
"release": "/var/www/investmoz-homologacao/releases/df43aeb1e583e65af854ac71f46ddaa1f49b0b7c-657a60cb",
"previous_release": "/var/www/investmoz-homologacao/releases/e8b5ae43add95be3a7fd437e4488befce76c0a97-7ad802df",
"database_migrations": 0,
"content_imports": 0
},
"current_link": "/var/www/investmoz-homologacao/releases/df43aeb1e583e65af854ac71f46ddaa1f49b0b7c-657a60cb",
"release_revision": {
"commit": "df43aeb1e583e65af854ac71f46ddaa1f49b0b7c",
"branch": "main",
"built_at": "2026-10-24T23:29:21.431835+00:00",
"manifest_sha256": "42fcfc7d2fa7e7adae795927245582d1d140dd2a4fdc77164056b33de94f21e1"
},
"service": "ExecMainStatus=0\nActiveState=inactive\nSubState=dead\n",
"configuration_keys": [
"repository",
"branch",
"target_url",
"legacy_root",
"state_root",
"release_root",
"current_link",
"shared_assets",
"php",
"schema_contract",
"ci_environment",
"postgis_image",
"test_database",
"qa_port",
"retention",
"webhook_secret_file"
],
"safe_paths": {
"repository": "nala/Investidor-V2",
"release_root": "/var/www/investmoz-homologacao/releases",
"postgis_image": "postgis/postgis@sha256:01a6a70e41e6c4467c8f55f6063555ed72db2d6662cd0d571040d42eadaeb6f6"
},
"pipeline_sha256": "adec1c17654f3a8658b83b134f1e75f95391b235738552721906c3236e388604"
},
"backup_restore": {
"backup": {
"stage": "/var/backups/investmoz-l1-travel-events-delivery-20261025/backup",
"target": {
"database": "teste_investidor",
"port": 5432
},
"tables": 174,
"files_verified": 369,
"dump_sha256": "c1f4d332b1157a0676e7407f65d9fecf21acd21f172904619fb964010f1091d3",
"files_sha256": "a794dd0f469aaad13e9c12f43355bcf268f4e86b0122dec9ca4b48217996e01c",
"restore_verified": false
},
"restore": {
"restore_verified": true,
"tables_verified": 174,
"container_network": "none",
"database": "l1_travel_events_restore_20261025",
"port": 55441,
"source_dump_sha256": "c1f4d332b1157a0676e7407f65d9fecf21acd21f172904619fb964010f1091d3",
"active_database_writes": 0
}
}
}
@@ -0,0 +1,22 @@
--- a/resources/js/lib/iva-travel.ts
+++ b/resources/js/lib/iva-travel.ts
@@ -87,7 +87,7 @@
}
function key(draft:Record<string,unknown>,book:TravelBook):string{return JSON.stringify({version:travelVersion,scope:acquisitionScope(draft),location:draft.selection_labels??{},currency:draft.currency,rows:book.rows,periods:book.periods});}
export function travelCurrent(draft:Record<string,unknown>,book:TravelBook):boolean{return!!book.result&&book.result.sourceKey===key(draft,book);}
-export function recordTravel(draft:Record<string,unknown>,book:TravelBook):TravelBook{
+export function recordTravel(draft:Record<string,unknown>,book:TravelBook):TravelBook{throw new Error('Novas versões P129 temporariamente suspensas; dados, histórico e relatórios conservados.');
const costIds=book.rows.flatMap(r=>r.costs.map(c=>c.id));
if(!book.rows.length||new Set(book.rows.map(r=>r.id)).size!==book.rows.length||new Set(book.rows.map(r=>r.operatorRef+'|'+r.period+'|'+r.operationRef)).size!==book.rows.length||new Set(costIds).size!==costIds.length||new Set(book.periods.map(p=>p.id)).size!==book.periods.length||new Set(book.periods.map(p=>p.operatorRef+'|'+p.period)).size!==book.periods.length)throw new Error('Identidades de operações/custos/períodos devem ser distintas; evite dupla soma, originais conservados.');
const rows=book.rows.map(row=>evaluateTravel(row,draft.currency));const result:TravelCalculation={version:travelVersion,revision:(book.result?.revision??0)+1,calculatedAt:new Date().toISOString(),opportunity:acquisitionScope(draft),sourceKey:key(draft,book),source:travelSource,inputs:structuredClone(book.rows),periodInputs:structuredClone(book.periods),rows,periods:evaluateTravelPeriods(book,rows)};
--- a/resources/js/lib/iva-travel-events.ts
+++ b/resources/js/lib/iva-travel-events.ts
@@ -88,7 +88,7 @@
}
function key(draft:Record<string,unknown>,book:TravelEventBook):string{return JSON.stringify({version:travelEventVersion,scope:acquisitionScope(draft),location:draft.selection_labels??{},rows:book.rows,dependencies:book.rows.map(row=>row.treatment==='travel_special'?travelEventSources(draft).find(s=>s.id===row.travelRowId):null)});}
export function travelEventCurrent(draft:Record<string,unknown>,book:TravelEventBook):boolean{try{return!!book.result&&book.result.sourceKey===key(draft,book);}catch{return false;}}
-export function recordTravelEvents(draft:Record<string,unknown>,book:TravelEventBook):TravelEventBook{
+export function recordTravelEvents(draft:Record<string,unknown>,book:TravelEventBook):TravelEventBook{throw new Error('Novas versões P133 temporariamente suspensas; dados, histórico e relatórios conservados.');
if(!book.rows.length||new Set(book.rows.map(r=>r.id)).size!==book.rows.length)throw new Error('Identifique eventos distintos; originais conservados.');
const result:TravelEventCalculation={version:travelEventVersion,revision:(book.result?.revision??0)+1,calculatedAt:new Date().toISOString(),opportunity:acquisitionScope(draft),sourceKey:key(draft,book),source:travelEventSource,inputs:structuredClone(book.rows),rows:book.rows.map(row=>evaluateTravelEvent(draft,row))};
const next={...book,result,history:[...(book.history??[]),...(book.result?[book.result]:[])]};saveTravelEventBook(draft,next);return next;
@@ -7,7 +7,7 @@ export function SimulationTravel({draft,onChange}:{draft:Record<string,unknown>;
const period=(id:string,patch:Partial<TravelPeriod>)=>save({...book,periods:book.periods.map(p=>p.id===id?{...p,...patch}:p)});
const cost=(row:TravelRow,id:string,patch:Partial<TravelCost>)=>change(row.id,{costs:row.costs.map(c=>c.id===id?{...c,...patch}:c)});
return<details className="space-y-3 rounded border p-3"><summary>Agências de viagens — pacote, meios utilizados e margem do período</summary>
<p>Preço único, actuação em nome próprio e meios de terceiros determinam o percurso específico. Meios próprios, intermediação e revenda simples conservam o regime geral aplicável. Reutilize documentos e referências; não é necessário criar certificados ou aprovadores.</p><p>A margem é global por operador e período do registo simulado, com âmbito completo declarado. Não somar margem por pacote nem misturar dados efectivos e projectados. A base não é IVA devido nem dedução. Facturação oficial, regularização e apuramento integral continuam fora deste cálculo.</p><p>{travelSource}</p>{error&&<p role="alert">{error}</p>}
<p>Preço único, actuação em nome próprio e meios de terceiros determinam o percurso específico. Meios próprios, intermediação e revenda simples conservam o regime geral aplicável. Reutilize documentos e referências; não é necessário criar certificados ou aprovadores.</p><p>A margem é global por operador e período do registo simulado, com âmbito completo declarado. Não somar margem por pacote nem misturar dados efectivos e projectados. A base não é IVA devido nem dedução. Facturação oficial, regularização e apuramento integral continuam fora deste cálculo.</p><p><strong>Continuidade do trabalho fiscal:</strong> este incremento trata margem e eventos, sem calcular IVA devido ou dedução. A base e os eventos conservam as referências para o apuramento e liquidação restantes; deduções e regularizações seguem os seus percursos próprios e não ficam concluídas por esta entrega.</p><p>{travelSource}</p>{error&&<p role="alert">{error}</p>}
<button type="button" onClick={()=>save({...book,rows:[...book.rows,newTravel(crypto.randomUUID(),String(draft.currency??''))]})}>Acrescentar operação de viagem</button>
{book.rows.map(row=><details key={row.id} className="rounded border p-3"><summary>{row.description||'Viagem por identificar'} — {row.period||'período do registo por indicar'}</summary><div className="grid gap-3 md:grid-cols-2">
{([['description','Viagem ou conjunto de serviços'],['operatorRef','Operador: referência da agência/organizador'],['operationRef','Referência da operação / pressuposto'],['period','Período do registo de contraprestação e custos'],['documentRef','Documento existente / referência da previsão'],['documentDate','Data do documento / prevista'],['scope','Âmbito: pacote, parcela, período e condições'],['evidence','Factos / pressupostos expressos'],['agencyRef','Sede/estabelecimento a partir do qual presta e referência'],['currency','Moeda original do registo']] as const).map(([field,label])=><label key={field}>{label}<input type={field==='period'?'month':field==='documentDate'?'date':'text'} value={row[field]} onChange={e=>change(row.id,{[field]:e.target.value})}/></label>)}