ultimatepos/Modules/IndustrialEngineering/Http/Controllers/EngineeringChangeOrderController.php

159 lines
6.3 KiB
PHP

<?php
namespace Modules\IndustrialEngineering\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\IndustrialEngineering\Http\Controllers\Concerns\AuthorizesIndustrialEngineering;
use Modules\IndustrialEngineering\Http\Controllers\Concerns\ResolvesIeCodes;
use Modules\IndustrialEngineering\Models\Bom;
use Modules\IndustrialEngineering\Models\EngineeringChangeOrder;
use Modules\IndustrialEngineering\Models\LineRevision;
use Modules\IndustrialEngineering\Services\CodeGeneratorService;
use Yajra\DataTables\Facades\DataTables;
class EngineeringChangeOrderController extends Controller
{
use AuthorizesIndustrialEngineering;
use ResolvesIeCodes;
public function __construct(protected CodeGeneratorService $codeGenerator)
{
}
public function index(Request $request)
{
$this->authorizeIe('ie.revisions.view');
$businessId = $this->businessId();
if ($request->ajax()) {
$query = EngineeringChangeOrder::forBusiness($businessId)
->with(['lineRevision', 'requestedBy'])
->latest('id');
return DataTables::of($query)
->addColumn('code', fn ($row) => $row->effectiveCode())
->addColumn('revision', fn ($row) => $row->lineRevision?->name ?? '—')
->addColumn('change_type_label', fn ($row) => __('industrialengineering::lang.eco_type_'.$row->change_type))
->addColumn('status_label', fn ($row) => __('industrialengineering::lang.eco_status_'.$row->status))
->addColumn('action', fn ($row) => '<a href="'.action([self::class, 'show'], $row->id).'" class="btn btn-xs btn-primary"><i class="fa fa-eye"></i></a>')
->rawColumns(['action'])
->make(true);
}
return view('industrialengineering::engineering_changes.index');
}
public function create()
{
$this->authorizeIe('ie.revisions.create');
$businessId = $this->businessId();
return view('industrialengineering::engineering_changes.create', [
'suggestedCode' => $this->suggestCode('eco'),
'revisions' => LineRevision::forBusiness($businessId)->with('lineTemplate')->orderBy('name')->get(),
'changeTypes' => $this->changeTypes(),
'priorities' => $this->priorities(),
]);
}
public function store(Request $request)
{
$this->authorizeIe('ie.revisions.create');
$businessId = $this->businessId();
$data = $request->validate([
'eco_number' => 'nullable|string|max:100',
'title' => 'required|string|max:255',
'line_revision_id' => 'nullable|exists:ie_line_revisions,id',
'bom_id' => 'nullable|exists:ie_boms,id',
'change_type' => 'required|string|max:50',
'priority' => 'nullable|string|max:20',
'impact_cost_delta' => 'nullable|numeric',
'impact_quality' => 'nullable|string',
'impact_schedule_days' => 'nullable|integer',
'description' => 'nullable|string',
]);
$codes = $this->codeGenerator->resolveCode('eco', $businessId, $data['eco_number'] ?? null, new EngineeringChangeOrder(), 'eco_number');
$eco = EngineeringChangeOrder::create(array_merge($data, $codes, [
'business_id' => $businessId,
'auto_code' => $this->codeGenerator->suggest('eco', $businessId),
'status' => 'draft',
'requested_by' => auth()->id(),
]));
return redirect()->action([self::class, 'show'], $eco->id)
->with('status', ['success' => true, 'msg' => __('industrialengineering::lang.eco_created')]);
}
public function show($id)
{
$this->authorizeIe('ie.revisions.view');
$eco = EngineeringChangeOrder::forBusiness($this->businessId())
->with(['lineRevision.lineTemplate', 'bom', 'requestedBy', 'approvedBy'])
->findOrFail($id);
return view('industrialengineering::engineering_changes.show', [
'eco' => $eco,
'changeTypes' => $this->changeTypes(),
'statuses' => $this->statuses(),
]);
}
public function updateStatus(Request $request, $id)
{
$this->authorizeIe('ie.revisions.create');
$eco = EngineeringChangeOrder::forBusiness($this->businessId())->findOrFail($id);
$data = $request->validate([
'status' => 'required|in:draft,review,approved,implemented,rejected',
'implementation_notes' => 'nullable|string',
]);
if ($data['status'] === 'approved' && ! $eco->approved_by) {
$eco->approved_by = auth()->id();
$eco->effective_at = now();
}
$eco->fill($data)->save();
return back()->with('status', ['success' => true, 'msg' => __('industrialengineering::lang.eco_status_updated')]);
}
protected function changeTypes(): array
{
return [
'design' => __('industrialengineering::lang.eco_type_design'),
'process' => __('industrialengineering::lang.eco_type_process'),
'cost' => __('industrialengineering::lang.eco_type_cost'),
'quality' => __('industrialengineering::lang.eco_type_quality'),
'safety' => __('industrialengineering::lang.eco_type_safety'),
'regulatory' => __('industrialengineering::lang.eco_type_regulatory'),
'reverse_engineering' => __('industrialengineering::lang.eco_type_reverse_engineering'),
];
}
protected function priorities(): array
{
return [
'low' => __('industrialengineering::lang.priority_low'),
'medium' => __('industrialengineering::lang.priority_medium'),
'high' => __('industrialengineering::lang.priority_high'),
'critical' => __('industrialengineering::lang.priority_critical'),
];
}
protected function statuses(): array
{
return [
'draft' => __('industrialengineering::lang.eco_status_draft'),
'review' => __('industrialengineering::lang.eco_status_review'),
'approved' => __('industrialengineering::lang.eco_status_approved'),
'implemented' => __('industrialengineering::lang.eco_status_implemented'),
'rejected' => __('industrialengineering::lang.eco_status_rejected'),
];
}
}