52 lines
2.8 KiB
PHP
52 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\InvestmentLegalSource;
|
|
use App\Models\User;
|
|
use App\Services\SimulationTaxParameterResolver;
|
|
use App\Services\SimulationTaxRuleExpression;
|
|
use App\Services\SimulationTaxRuleGovernance;
|
|
use App\Support\CheckedFile;
|
|
use App\Support\IsolatedQaDatabase;
|
|
use Illuminate\Console\Command;
|
|
|
|
/** Explicit registration: never run during migration, deployment or document import. */
|
|
class RegisterFiscalQaDraft extends Command
|
|
{
|
|
protected $signature = 'fiscal:qa-register-iva {actor : Existing QA editor ID} {source : Existing accepted legal source UUID}';
|
|
|
|
protected $description = 'Cadastrar apenas o rascunho IVA do primeiro lote numa base QA isolada, sem publicação';
|
|
|
|
public function handle(SimulationTaxRuleGovernance $governance): int
|
|
{
|
|
abort_unless(IsolatedQaDatabase::allowsSchemaChanges(), 403, 'O cadastro deste lote só é permitido na base QA isolada.');
|
|
$actor = User::findOrFail($this->argument('actor'));
|
|
$source = InvestmentLegalSource::findOrFail($this->argument('source'));
|
|
abort_unless($source->validation_status === 'validated' && $source->diploma === 'Lei 22/2022'
|
|
&& $source->article === 'Artigo 17(1)', 422, 'Seleccione a referência aceite da taxa geral, Lei 22/2022, artigo 17(1).');
|
|
$payload = json_decode(CheckedFile::read(database_path('qa/iva-general-net-v1.json')), true, flags: JSON_THROW_ON_ERROR);
|
|
$actualHash = CheckedFile::sha256(base_path('docs/investmoz/simulations/source-archive/Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf'));
|
|
abort_unless(hash_equals($payload['source_sha256'], $actualHash), 422, 'O exemplar não corresponde ao hash da ficha.');
|
|
$payload['legal_source_id'] = (string) $source->id;
|
|
app(SimulationTaxRuleExpression::class)->validate($payload['rule_definition']);
|
|
app(SimulationTaxParameterResolver::class)->validateParameters($payload['parameters']);
|
|
$existing = $governance->listing($actor, ['rule_code' => $payload['rule_code']])->getCollection()
|
|
->firstWhere('rule_version', 1);
|
|
if ($existing) {
|
|
foreach ($payload as $field => $value) {
|
|
$stored = $existing->attributesToArray()[$field] ?? null;
|
|
abort_unless($stored == $value, 409, 'O cadastro existente difere desta ficha; não será sobrescrito.');
|
|
}
|
|
abort_unless($existing->status === 'draft', 409, 'A versão existente já não é um rascunho.');
|
|
$this->line(json_encode(['id' => $existing->id, 'status' => 'draft', 'reused' => true], JSON_THROW_ON_ERROR));
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
$rule = $governance->create($actor, $payload);
|
|
$this->line(json_encode(['id' => $rule->id, 'status' => $rule->status, 'reused' => false], JSON_THROW_ON_ERROR));
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
}
|