show($actor, $ruleId); abort_unless($rule->status === 'draft' && $rule->rule_code === 'IVA-GERAL-BASE-LIQUIDA', 422, 'Seleccione o rascunho do primeiro lote fiscal.'); abort_if(collect($rule->rule_definition['nodes'] ?? [])->contains(fn (array $node): bool => ($node['op'] ?? null) === 'round'), 422, 'Este percurso preserva o valor exacto e não aplica arredondamento automático.'); $source = InvestmentLegalSource::findOrFail($rule->legal_source_id); $version = $rule->attributesToArray(); $version['source'] = $source->attributesToArray(); $date = $input['reference_date']; $context = ['operation' => $input['operation'], 'currency' => $input['currency']]; $missing = []; $resolution = []; $evaluation = null; if ($date < '2026-01-01' || $date > '2026-12-31') { $missing[] = 'demonstrated_coverage'; } else { $resolution = app(SimulationTaxParameterResolver::class)->resolveDraftForQa([$version], 'IVA', $date, $date, $context); $rate = collect($resolution)->firstWhere('parameter_code', 'IVA_GENERAL_RATE'); if (($rate['status'] ?? null) !== 'resolved' || ($rate['unit'] ?? null) !== 'percent') { $missing[] = 'eligible_parameter'; } else { $evaluation = app(SimulationTaxRuleExpression::class)->evaluate($rule->rule_definition, ['base_tributavel' => $input['base']], ['iva_general_rate' => $rate['value']]); } } $exact = ($evaluation['status'] ?? null) === 'determinate' ? (string) BigRational::of($evaluation['result'])->toBigDecimal() : null; if ($exact === null && $missing === []) { $missing = $evaluation['missing'] ?? ['eligible_parameter']; } $snapshot = [ 'contract_version' => 1, 'scenario_kind' => 'fiscal_rule_qa_preview', 'base' => $input['base'], 'currency' => $input['currency'], 'indicative_total' => $exact, 'legal_interpretation' => false, 'formula_version' => 'investmoz.tax.v1', 'context' => [ 'reference_date' => $date, 'currency' => $input['currency'], 'currency_fraction_digits' => 2, 'scenario_id' => null, 'scenario_version' => 1, 'engine_version' => 'fiscal-draft-preview-v1', 'ruleset_version' => $rule->rule_code.':'.$rule->rule_version, ], 'result' => [ 'status' => $exact === null ? 'indeterminate' : 'calculated', 'value' => $exact, 'unit' => 'MZN', 'explanation' => $exact === null ? 'IVA indeterminado: o contexto, a fonte ou o período não permitem resolver o parâmetro deste lote QA.' : 'IVA calculado com precisão decimal exacta, sem arredondamento. Ensaio QA de regra em rascunho; enquadramento declarado, não validado. Não é saldo de declaração nem valor a pagar.', 'missing_inputs' => $missing, 'source_ids' => [(string) $source->id], ], 'presentation' => ['value' => $exact, 'currency' => $input['currency'], 'rounding_applied' => false, 'purpose' => 'operation_tax_not_payment'], // Exact rational steps supplement the decimal result; no float conversion. 'intermediate' => $evaluation, 'fiscal_provenance' => [ 'mode' => 'qa_draft_only', 'scope_status' => 'user_declared', 'context' => $context, 'rounding_policy' => $rule->rounding_policy, 'resolution' => $resolution, 'rule' => $version, 'source_acceptance' => 'Fonte oficial aceite pela decisão Tempo de 08/10/2026; não constitui aprovação jurídica desta operação ou publicação da regra.', ], ]; return app(SimulationExecution::class)->createFiscalQaPreview($snapshot, $actor->id, $key); }); } }