ultimatepos/app/Modules/Maintenance/Http/Controllers/Api/V1/EquipmentPartController.php

142 lines
6.0 KiB
PHP

<?php
namespace App\Modules\Maintenance\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use App\Modules\Maintenance\Models\Equipment;
use App\Modules\Maintenance\Models\EquipmentPart;
use App\Modules\Maintenance\Traits\ResolvesBusiness;
use Illuminate\Http\Request;
class EquipmentPartController extends Controller
{
use ResolvesBusiness;
private function partRules(bool $partial = false): array
{
$sometimes = $partial ? 'sometimes' : 'nullable';
return [
'parent_id' => [$sometimes, 'exists:maintenance_equipment_parts,id'],
'spare_part_id' => ['nullable', 'exists:maintenance_spare_parts,id'],
'part_catalog_id' => ['nullable', 'exists:maintenance_part_catalogs,id'],
'part_name' => [$partial ? 'sometimes' : 'required_without:spare_part_id', 'nullable', 'string', 'max:255'],
'part_code' => ['nullable', 'string', 'max:100'],
'quantity' => ['nullable', 'numeric', 'min:0'],
'unit' => ['nullable', 'string', 'max:50'],
'part_type' => ['sometimes', 'string', 'in:mechanical,electronic,consumable,hydraulic,pneumatic'],
'is_consumable' => ['sometimes', 'boolean'],
'is_critical' => ['sometimes', 'boolean'],
'responsibility' => ['sometimes', 'string', 'in:ours,vendor,shared'],
'responsibility_party_name' => ['nullable', 'string', 'max:255'],
'warranty_status' => ['sometimes', 'string', 'in:none,active,expired'],
'warranty_provider' => ['nullable', 'string', 'max:255'],
'warranty_expires_at' => ['nullable', 'date'],
'installed_by' => ['sometimes', 'string', 'in:ours,vendor,third_party'],
'installer_name' => ['nullable', 'string', 'max:255'],
'expected_replacement_date' => ['nullable', 'date'],
'replacement_interval_days' => ['nullable', 'integer', 'min:0'],
'last_replaced_at' => ['nullable', 'date'],
'replacement_quality_grade' => ['nullable', 'string', 'max:50'],
'damage_action' => ['nullable', 'string', 'in:replace,service,both'],
'damage_service_list' => ['nullable', 'array'],
'multi_year_service_plan' => ['nullable', 'array'],
'health_percentage' => ['nullable', 'numeric', 'min:0', 'max:100'],
'notes' => ['nullable', 'string'],
];
}
public function index(Request $request, Equipment $equipment)
{
if (! $this->ensureBusinessOwnership($request, $equipment->business_id)) {
return $this->jsonError('دسترسی ندارید.', 403);
}
$parts = EquipmentPart::where('equipment_id', $equipment->id)
->with(['sparePart:id,part_number,name,quantity,unit', 'partCatalog:id,catalog_code,name', 'children'])
->orderBy('part_name')
->get();
$tree = $this->buildTree($parts);
return $this->jsonSuccess(['items' => $parts, 'tree' => $tree]);
}
public function store(Request $request, Equipment $equipment)
{
if (! $this->ensureBusinessOwnership($request, $equipment->business_id)) {
return $this->jsonError('دسترسی ندارید.', 403);
}
$data = $request->validate($this->partRules());
if (! empty($data['spare_part_id'])) {
$spare = \App\Modules\Maintenance\Models\SparePart::find($data['spare_part_id']);
if ($spare) {
$data['part_name'] = $data['part_name'] ?? $spare->name;
$data['part_code'] = $data['part_code'] ?? $spare->part_number;
$data['unit'] = $data['unit'] ?? $spare->unit;
}
}
if (! empty($data['part_catalog_id'])) {
$catalog = \App\Modules\Maintenance\Models\PartCatalog::find($data['part_catalog_id']);
if ($catalog) {
$data['part_name'] = $data['part_name'] ?? $catalog->name;
$data['part_code'] = $data['part_code'] ?? $catalog->catalog_code;
$data['part_type'] = $data['part_type'] ?? $catalog->part_type;
$data['is_consumable'] = $data['is_consumable'] ?? $catalog->is_consumable;
}
}
$part = EquipmentPart::create(array_merge($data, [
'business_id' => $equipment->business_id,
'equipment_id' => $equipment->id,
'quantity' => $data['quantity'] ?? 1,
]));
return $this->jsonSuccess($part->load(['sparePart', 'partCatalog']), 'قطعه به تجهیز اضافه شد.', 201);
}
public function update(Request $request, Equipment $equipment, EquipmentPart $part)
{
if (! $this->ensureBusinessOwnership($request, $equipment->business_id) || $part->equipment_id !== $equipment->id) {
return $this->jsonError('دسترسی ندارید.', 403);
}
$data = $request->validate($this->partRules(true));
$part->update($data);
return $this->jsonSuccess($part->fresh()->load(['sparePart', 'partCatalog']), 'قطعه به‌روزرسانی شد.');
}
public function destroy(Request $request, Equipment $equipment, EquipmentPart $part)
{
if (! $this->ensureBusinessOwnership($request, $equipment->business_id) || $part->equipment_id !== $equipment->id) {
return $this->jsonError('دسترسی ندارید.', 403);
}
$part->delete();
return $this->jsonSuccess(null, 'قطعه حذف شد.');
}
private function buildTree($parts, ?int $parentId = null): array
{
$branch = [];
foreach ($parts as $part) {
if ($part->parent_id === $parentId) {
$branch[] = [
'id' => $part->id,
'part_name' => $part->part_name,
'part_code' => $part->part_code,
'health_percentage' => $part->health_percentage,
'children' => $this->buildTree($parts, $part->id),
];
}
}
return $branch;
}
}