77 lines
5.8 KiB
PHP
77 lines
5.8 KiB
PHP
<?php
|
|
|
|
use App\Enums\PurchasingRole;
|
|
use App\Models\ProposalEvaluation;
|
|
use App\Models\Supplier;
|
|
use App\Models\User;
|
|
use App\Services\DocumentaryQualificationWorkflow;
|
|
use App\Services\FormalAdmission;
|
|
use App\Services\FormalRecommendation;
|
|
use App\Services\ProposalOpeningWorkflow;
|
|
|
|
require_once __DIR__.'/QualificationFixture.php';
|
|
|
|
/** Genuine three-quotation basis; underlying fixture refuses non-isolated databases. */
|
|
function recommendationFixture(int $quorum = 2): array
|
|
{
|
|
$f = qualificationFixture();
|
|
$tenantId = $f['tenant']->id;
|
|
$departmentId = $f['r']->department_id;
|
|
$admin = User::factory()->create(['tenant_id' => $tenantId, 'purchasing_role' => PurchasingRole::Admin]);
|
|
$buyer = User::factory()->create(['tenant_id' => $tenantId, 'department_id' => $departmentId, 'purchasing_role' => PurchasingRole::Procurement]);
|
|
$head = User::factory()->create(['tenant_id' => $tenantId, 'department_id' => $departmentId, 'purchasing_role' => PurchasingRole::DepartmentHead]);
|
|
$reviewer = User::factory()->create(['tenant_id' => $tenantId, 'purchasing_role' => PurchasingRole::Finance]);
|
|
$otherReviewer = User::factory()->create(['tenant_id' => $tenantId, 'purchasing_role' => PurchasingRole::Finance]);
|
|
auth()->guard()->setUser($buyer);
|
|
$f['r']->update(['approval_snapshot' => ['first_limit_minor' => 2500000, 'second_limit_minor' => 15000000, 'approval_includes_tax' => true, 'rules_provisional' => true]]);
|
|
$f['r']->steps()->create(['tenant_id' => $tenantId, 'position' => 1, 'role' => 'department_head', 'decision' => 'approved', 'approver_id' => $head->id, 'decided_at' => now()]);
|
|
$supplier = Supplier::query()->findOrFail($f['quote']->supplier_id);
|
|
$quotes = [$f['quote']];
|
|
for ($i = 1; $i <= 2; $i++) {
|
|
$otherSupplier = $supplier->replicate();
|
|
$otherSupplier->fill(['nuit' => '12345678'.$i, 'name' => 'Fornecedor fictício '.$i])->save();
|
|
$quote = $f['quote']->replicate();
|
|
$quote->fill(['supplier_id' => $otherSupplier->id, 'reference' => 'PROP-FICTICIA-'.$i])->save();
|
|
$quotes[] = $quote;
|
|
}
|
|
$item = $f['r']->items()->firstOrFail();
|
|
foreach ($quotes as $index => $quote) {
|
|
$amount = 10000 * ($index + 1);
|
|
$quote->update(['created_by' => $buyer->id, 'subtotal_minor' => $amount, 'total_minor' => $amount]);
|
|
$quote->items()->create(['tenant_id' => $tenantId, 'requisition_item_id' => $item->id, 'description' => $item->description, 'quantity' => '1.000', 'unit_price_minor' => $amount, 'tax_rate' => '0', 'subtotal_minor' => $amount, 'tax_minor' => 0, 'total_minor' => $amount]);
|
|
foreach ([$buyer, $f['analyst']] as $evaluator) {
|
|
ProposalEvaluation::query()->create(['tenant_id' => $tenantId, 'quotation_id' => $quote->id, 'evaluator_id' => $evaluator->id, 'quality' => '8', 'history' => '5', 'payment' => '8', 'no_conflict' => true, 'comment' => 'Avaliação exclusivamente fictícia']);
|
|
}
|
|
}
|
|
$opening = app(ProposalOpeningWorkflow::class);
|
|
$documentary = app(DocumentaryQualificationWorkflow::class);
|
|
$set = $documentary->define($buyer, $f['r'], [...$f['definition'], 'basis_hash' => $opening->basis($opening->proposals($f['r']))]);
|
|
$answers = $f['assessment']['answers'];
|
|
$answers[1] = ['criterion_id' => 2, 'result' => 'met', 'evidence' => 'Documento fictício', 'reason' => 'Conformidade exclusivamente fictícia'];
|
|
foreach ($quotes as $quote) {
|
|
auth()->guard()->setUser($f['analyst']);
|
|
$documentary->assess($f['analyst'], $set, [...$f['assessment'], 'quotation_id' => $quote->id, 'answers' => $answers]);
|
|
}
|
|
$admission = app(FormalAdmission::class);
|
|
auth()->guard()->setUser($admin);
|
|
$admissionPolicy = $admission->policy($admin, ['previous_id' => 0, 'enabled' => true, 'roles' => ['finance'], 'required_count' => 1, 'reason' => 'Política de admissão exclusivamente fictícia']);
|
|
auth()->guard()->setUser($buyer);
|
|
$admissionAdoption = $admission->adopt($buyer, $f['r'], $admissionPolicy->id, 0, 'Adopção de admissão exclusivamente fictícia');
|
|
foreach ($quotes as $quote) {
|
|
auth()->guard()->setUser($buyer);
|
|
$decision = $admission->propose($buyer, $f['r'], ['quotation_id' => $quote->id, 'previous_id' => 0, 'basis_hash' => $admission->basis($f['r'], $quote->id)['hash'], 'outcome' => 'admit', 'reason' => 'Proposta de admissão exclusivamente fictícia']);
|
|
auth()->guard()->setUser($f['analyst']);
|
|
$admission->review($f['analyst'], $decision, 'approved', 'Conferência de admissão exclusivamente fictícia');
|
|
}
|
|
$workflow = app(FormalRecommendation::class);
|
|
$policyData = ['previous_id' => 0, 'enabled' => true, 'roles' => ['finance', 'department_head'], 'required_count' => $quorum, 'reason' => 'Política de recomendação exclusivamente fictícia'];
|
|
auth()->guard()->setUser($admin);
|
|
$policy = $workflow->policy($admin, $policyData);
|
|
auth()->guard()->setUser($buyer);
|
|
$adoption = $workflow->adopt($buyer, $f['r'], $policy->id, 0, 'Adopção de recomendação exclusivamente fictícia');
|
|
$proposal = ['previous_id' => 0, 'quotation_id' => $quotes[0]->id, 'basis_hash' => $workflow->basis($f['r'])['hash'], 'reason' => 'Recomendação exclusivamente fictícia'];
|
|
$selection = ['quotation_id' => $quotes[0]->id, 'justification' => 'Proposta de maior pontuação com recomendação.', 'delivery_date' => today()->addWeek()->format('Y-m-d'), 'delivery_location' => 'Armazém fictício'];
|
|
|
|
return [...$f, 'quotes' => $quotes, 'set' => $set, 'admin' => $admin, 'buyer' => $buyer, 'head' => $head, 'reviewer' => $reviewer, 'other_reviewer' => $otherReviewer, 'admission_policy' => $admissionPolicy, 'admission_adoption' => $admissionAdoption, 'policy' => $policy, 'policy_data' => $policyData, 'adoption' => $adoption, 'proposal' => $proposal, 'selection' => $selection];
|
|
}
|