Consolida recepcoes, stock, equipamentos e identidade SGC

This commit is contained in:
2026-10-28 13:54:53 +02:00
parent eb1c8b8074
commit 75ffdb395c
76 changed files with 6933 additions and 152 deletions
+11 -2
View File
@@ -27,9 +27,10 @@ class RequisitionWorkflow
$items = [];
$subtotal = 0;
$tax = 0;
/** @var list<array{description: string, category: string, purchase_type: string, quantity: string, unit: string, unit_price: string, tax_rate: string}> $lines */
/** @var list<array{description: string, category: string, purchase_type: string, quantity: string, unit: string, unit_price: string, tax_rate: string, equipment_id?: int, spare_part_id?: int, production_area?: string, downtime_started_at?: string|null}> $lines */
$lines = $data['items'];
foreach ($lines as $line) {
app(EquipmentWorkflow::class)->line($line, (int) $user->department_id, $data['priority']);
$price = BigDecimal::of($line['unit_price'])->multipliedBy(100)->toScale(0)->toInt();
$lineSubtotal = BigDecimal::of($line['quantity'])->multipliedBy($price)->toScale(0, RoundingMode::HalfUp)->toInt();
$lineTax = BigDecimal::of($lineSubtotal)->multipliedBy($line['tax_rate'])->dividedBy(100, 0, RoundingMode::HalfUp)->toInt();
@@ -37,6 +38,7 @@ class RequisitionWorkflow
'tenant_id' => $user->tenant_id,
'description' => $line['description'], 'category' => $line['category'],
'purchase_type' => $line['purchase_type'], 'quantity' => $line['quantity'], 'unit' => $line['unit'],
'equipment_id' => $line['equipment_id'] ?? null, 'spare_part_id' => $line['spare_part_id'] ?? null, 'production_area' => $line['production_area'] ?? null, 'downtime_started_at' => $line['downtime_started_at'] ?? null,
'unit_price_minor' => $price, 'tax_rate' => $line['tax_rate'],
'subtotal_minor' => $lineSubtotal, 'tax_minor' => $lineTax, 'total_minor' => $lineSubtotal + $lineTax,
];
@@ -71,6 +73,10 @@ class RequisitionWorkflow
$requisition = Requisition::query()->lockForUpdate()->findOrFail($requisition->id);
abort_unless($requisition->requester_id === $user->id && $requisition->status === 'draft', 403);
app(ConflictGuard::class)->assertParticipation($user, $requisition);
foreach ($requisition->items()->get() as $item) {
app(EquipmentWorkflow::class)->line($item->toArray(), $requisition->department_id, $requisition->priority);
}
app(EquipmentWorkflow::class)->assertTechnical($requisition);
if ($requisition->needed_by < today()) {
throw ValidationException::withMessages(['submission' => 'Actualize a data de entrega antes de submeter.']);
}
@@ -80,7 +86,7 @@ class RequisitionWorkflow
if ($amount > $tenant->first_limit_minor) {
$roles[] = 'procurement';
}
if ($amount > $tenant->second_limit_minor) {
if ($amount > $tenant->second_limit_minor || $requisition->items()->where('purchase_type', 'equipment')->exists()) {
$roles[] = 'finance';
}
foreach ($roles as $position => $role) {
@@ -99,6 +105,9 @@ class RequisitionWorkflow
$requisition = Requisition::query()->lockForUpdate()->findOrFail($requisition->id);
$requisition->load('steps');
abort_unless($requisition->canDecide($user), 403);
if ($decision === 'approved') {
app(EquipmentWorkflow::class)->assertTechnical($requisition);
}
$step = $requisition->steps->firstWhere('decision', 'pending');
abort_if($step === null, 409);
$step->update(['decision' => $decision, 'approver_id' => $user->id, 'comment' => $comment, 'decided_at' => now()]);