commit21
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\QuotationController;
|
||||
use App\Http\Controllers\SupplierController;
|
||||
use App\Http\Requests\SaveSupplierRequest;
|
||||
use App\Models\Quotation;
|
||||
use App\Models\Requisition;
|
||||
use App\Models\Supplier;
|
||||
use App\Services\RequisitionWorkflow;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/** Shared driver of native product commands, only called by guarded local pilot scripts. */
|
||||
function pilotMarketScenario($app, array $proposal, array $next, Closure $actor, Closure $check): array
|
||||
{
|
||||
$preparer = $actor('prepare');
|
||||
$check($preparer->id === $next['preparer_id'], 'Preparador diferente da proposta.');
|
||||
$purchase = Requisition::query()->findOrFail($next['purchase_id']);
|
||||
$check($purchase->status === 'approved' && $purchase->number === $next['purchase_number'] && $purchase->items()->sole()->quantity === '2.000' && $purchase->total_minor === 2320, 'Compra diferente da proposta.');
|
||||
$check(Quotation::query()->where('requisition_id', $purchase->id)->count() === 0, 'Já existem propostas: não duplicar.');
|
||||
$existing = Supplier::query()->findOrFail($next['existing_eligible_supplier_id']);
|
||||
$check($existing->eligible(), 'O fornecedor existente deixou de estar elegível.');
|
||||
$protected = ['users', 'organization_access', 'organization_profiles', 'organization_memberships', 'purchase_orders', 'stock_movements', 'requisitions', 'requisition_items', 'budget_entries', 'purchase_awards'];
|
||||
$fingerprint = fn () => collect($protected)->mapWithKeys(fn ($table) => [$table => hash('sha256', json_encode(DB::table($table)->orderBy('id')->get(), JSON_THROW_ON_ERROR))])->all();
|
||||
$baseline = $fingerprint();
|
||||
$suppliersBefore = DB::table('suppliers')->orderBy('id')->get()->toArray();
|
||||
$supplierIds = ['existing' => $existing->id];
|
||||
$workflow = app(RequisitionWorkflow::class);
|
||||
foreach ($next['new_synthetic_suppliers'] as $index => $values) {
|
||||
$preparer = $actor('prepare');
|
||||
$form = SaveSupplierRequest::create($proposal['environment'].'/fornecedores', 'POST', [...$next['synthetic_supplier_fields'], ...$values]);
|
||||
$form->setContainer($app)->setRedirector($app['redirect']);
|
||||
$form->setUserResolver(fn () => $preparer);
|
||||
$form->validateResolved();
|
||||
app(SupplierController::class)->store($form, $workflow);
|
||||
$supplier = Supplier::query()->where('nuit', $values['nuit'])->sole();
|
||||
$reviewer = $actor('review');
|
||||
$check($reviewer->id === $next['supplier_reviewer_id'] && $supplier->created_by !== $reviewer->id, 'Conferência sem independência.');
|
||||
$review = Request::create($proposal['environment'].'/fornecedores/'.$supplier->id.'/validar', 'POST', ['version' => $supplier->version, 'status' => 'active',
|
||||
'comment' => 'Activação exclusivamente sintética para o piloto local; não representa validação comercial real.']);
|
||||
$review->setUserResolver(fn () => $reviewer);
|
||||
app(SupplierController::class)->review($review, $supplier, $workflow);
|
||||
$supplierIds[$index === 0 ? 'alternative_a' : 'alternative_b'] = $supplier->id;
|
||||
}
|
||||
$preparer = $actor('prepare');
|
||||
foreach ($next['quotations'] as $quote) {
|
||||
$input = Request::create($proposal['environment'].'/requisicoes/'.$purchase->id.'/cotacoes', 'POST', ['supplier_id' => $supplierIds[$quote['supplier']],
|
||||
'reference' => $quote['reference'], 'delivery_days' => $quote['delivery_days'], 'valid_until' => $next['quotation_valid_until'], 'payment_terms' => $next['payment_terms'],
|
||||
'no_conflict' => true, 'items' => [['requisition_item_id' => $purchase->items()->sole()->id, 'unit_price' => $quote['unit_price']]]]);
|
||||
$input->setUserResolver(fn () => $preparer);
|
||||
app(QuotationController::class)->store($input, $purchase, $workflow);
|
||||
$saved = Quotation::query()->where('requisition_id', $purchase->id)->where('reference', $quote['reference'])->sole();
|
||||
$check($saved->total_minor === $quote['expected_total_minor'], 'Totais diferentes da proposta sintética.');
|
||||
}
|
||||
$check($fingerprint() === $baseline && Quotation::query()->where('requisition_id', $purchase->id)->count() === 3, 'A consulta alterou dados fora do âmbito.');
|
||||
$check(DB::table('suppliers')->whereNotIn('id', [$supplierIds['alternative_a'], $supplierIds['alternative_b']])->orderBy('id')->get()->toArray() == $suppliersBefore, 'Cadastro anterior alterado.');
|
||||
$check(Quotation::query()->where('requisition_id', $purchase->id)->withCount('evaluations')->get()->sum('evaluations_count') === 0, 'Não avaliar automaticamente.');
|
||||
|
||||
return ['supplier_ids' => $supplierIds, 'quotation_ids' => Quotation::query()->where('requisition_id', $purchase->id)->orderBy('id')->pluck('id')->all(), 'protected_tables' => $protected];
|
||||
}
|
||||
Reference in New Issue
Block a user