Additional Changes
This commit is contained in:
@@ -13,26 +13,61 @@ use Modules\MaterialLogistics\Models\MaterialRequisition;
|
||||
use Modules\MasterData\Models\MaterialGroup;
|
||||
use Modules\MaterialLogistics\Services\DocumentNumberService;
|
||||
use Modules\ProjectManagement\Models\Project;
|
||||
use Modules\ProjectManagement\Services\ProjectWorkflowService;
|
||||
|
||||
class MaterialRequisitionController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$requisitions = MaterialRequisition::with([
|
||||
$query = MaterialRequisition::with([
|
||||
'requester:id,ulid,name',
|
||||
'approver:id,ulid,name',
|
||||
'items:id,material_requisition_id,quantity,unit_cost' // Need items for frontend line total
|
||||
])
|
||||
->latest()
|
||||
->paginate(20);
|
||||
'project:id,ulid,name,code',
|
||||
'items:id,material_requisition_id,quantity,unit_cost'
|
||||
]);
|
||||
|
||||
if ($request->filled('project_ulid')) {
|
||||
$project = Project::where('ulid', $request->project_ulid)->first();
|
||||
if ($project) {
|
||||
$query->where('project_id', $project->id);
|
||||
}
|
||||
}
|
||||
|
||||
$requisitions = $query->latest()->paginate(20);
|
||||
|
||||
return Inertia::render('MaterialLogistics::Requisitions/Index', [
|
||||
'requisitions' => $requisitions,
|
||||
'projects' => Project::active()->where('current_wizard_step', '>=', 8)->select('id', 'ulid', 'name', 'code', 'client_name', 'location', 'start_date', 'target_end_date', 'status', 'contract_value')->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
public function create(Request $request)
|
||||
{
|
||||
$selectedProject = null;
|
||||
$prefilledItems = [];
|
||||
|
||||
if ($request->filled('project_ulid')) {
|
||||
$selectedProject = Project::where('ulid', $request->project_ulid)
|
||||
->with('materialsEstimates.material:id,ulid,name,unit,unit_cost')
|
||||
->firstOrFail();
|
||||
|
||||
$workflowService = new ProjectWorkflowService();
|
||||
if (!$workflowService->canCreateRequisition($selectedProject)) {
|
||||
return redirect()->back()->with('error', 'Cannot create material requisition: Project is not in scheduled/procuring state or task resources are missing.');
|
||||
}
|
||||
|
||||
// Auto-populate from project materials estimation
|
||||
foreach ($selectedProject->materialsEstimates as $estimate) {
|
||||
$prefilledItems[] = [
|
||||
'material_ulid' => $estimate->material->ulid,
|
||||
'material_name' => $estimate->material->name,
|
||||
'unit' => $estimate->material->unit,
|
||||
'quantity' => (float) $estimate->estimated_qty,
|
||||
'unit_cost' => (float) $estimate->unit_cost,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$materials = Material::select('id', 'ulid', 'name', 'unit', 'unit_cost', 'sku', 'category', 'status')
|
||||
->where('status', 'active')
|
||||
->orderBy('category')
|
||||
@@ -62,12 +97,16 @@ class MaterialRequisitionController extends Controller
|
||||
return Inertia::render('MaterialLogistics::Requisitions/Form', [
|
||||
'materials' => $materials,
|
||||
'materialGroups' => $materialGroups,
|
||||
'projects' => Project::active()->where('current_wizard_step', '>=', 8)->select('id', 'ulid', 'name', 'code', 'client_name', 'location', 'start_date', 'target_end_date', 'status', 'contract_value')->get(),
|
||||
'selectedProject' => $selectedProject,
|
||||
'prefilledItems' => $prefilledItems,
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'project_ulid' => 'required|string|exists:projects,ulid',
|
||||
'notes' => 'nullable|string|max:1000',
|
||||
'items' => 'required|array|min:1',
|
||||
'items.*.material_ulid' => 'required|string',
|
||||
@@ -75,10 +114,30 @@ class MaterialRequisitionController extends Controller
|
||||
'items.*.unit_cost' => 'required|numeric|min:0',
|
||||
]);
|
||||
|
||||
$project = Project::where('ulid', $validated['project_ulid'])->firstOrFail();
|
||||
if ($project->current_wizard_step < 8) {
|
||||
return redirect()->back()->with('error', 'Cannot create material requisition: Project estimation is not approved.');
|
||||
}
|
||||
|
||||
$workflowService = new ProjectWorkflowService();
|
||||
if (!$workflowService->canCreateRequisition($project)) {
|
||||
return redirect()->back()->with('error', 'Cannot create material requisition: Project is not in scheduled/procuring state.');
|
||||
}
|
||||
|
||||
// Validate that all items are in the project's materials estimates
|
||||
$estimatedMaterialIds = $project->materialsEstimates()->pluck('material_id')->toArray();
|
||||
foreach ($validated['items'] as $item) {
|
||||
$material = Material::where('ulid', $item['material_ulid'])->firstOrFail();
|
||||
if (!in_array($material->id, $estimatedMaterialIds)) {
|
||||
return redirect()->back()->with('error', "Cannot create material requisition: Material '{$material->name}' is not in the project's approved estimation.");
|
||||
}
|
||||
}
|
||||
|
||||
$docService = new DocumentNumberService();
|
||||
|
||||
$mr = DB::transaction(function () use ($validated, $docService) {
|
||||
$mr = DB::transaction(function () use ($validated, $project, $docService) {
|
||||
$mr = MaterialRequisition::create([
|
||||
'project_id' => $project->id,
|
||||
'document_number' => $docService->nextMrNumber(),
|
||||
'status' => 'draft',
|
||||
'requested_by' => auth()->id(),
|
||||
@@ -106,7 +165,7 @@ class MaterialRequisitionController extends Controller
|
||||
return redirect()->back()->with('error', 'Only draft requisitions can be edited.');
|
||||
}
|
||||
|
||||
$requisition->load('items.material:id,ulid,name,unit,unit_cost');
|
||||
$requisition->load('items.material:id,ulid,name,unit,unit_cost', 'project:id,ulid,name,code');
|
||||
|
||||
$materials = Material::select('id', 'ulid', 'name', 'sku', 'category', 'unit', 'unit_cost', 'status')
|
||||
->where('status', 'active')
|
||||
@@ -138,6 +197,7 @@ class MaterialRequisitionController extends Controller
|
||||
'requisition' => $requisition,
|
||||
'materials' => $materials,
|
||||
'materialGroups' => $materialGroups,
|
||||
'projects' => Project::active()->where('current_wizard_step', '>=', 8)->select('id', 'ulid', 'name', 'code', 'client_name', 'location', 'start_date', 'target_end_date', 'status', 'contract_value')->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -148,6 +208,7 @@ class MaterialRequisitionController extends Controller
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'project_ulid' => 'required|string|exists:projects,ulid',
|
||||
'notes' => 'nullable|string|max:1000',
|
||||
'items' => 'required|array|min:1',
|
||||
'items.*.material_ulid' => 'required|string',
|
||||
@@ -155,8 +216,28 @@ class MaterialRequisitionController extends Controller
|
||||
'items.*.unit_cost' => 'required|numeric|min:0',
|
||||
]);
|
||||
|
||||
DB::transaction(function () use ($validated, $requisition) {
|
||||
$project = Project::where('ulid', $validated['project_ulid'])->firstOrFail();
|
||||
if ($project->current_wizard_step < 8) {
|
||||
return redirect()->back()->with('error', 'Cannot update material requisition: Project estimation is not approved.');
|
||||
}
|
||||
|
||||
$workflowService = new ProjectWorkflowService();
|
||||
if (!$workflowService->canCreateRequisition($project)) {
|
||||
return redirect()->back()->with('error', 'Cannot update material requisition: Project is not in scheduled/procuring state.');
|
||||
}
|
||||
|
||||
// Validate that all items are in the project's materials estimates
|
||||
$estimatedMaterialIds = $project->materialsEstimates()->pluck('material_id')->toArray();
|
||||
foreach ($validated['items'] as $item) {
|
||||
$material = Material::where('ulid', $item['material_ulid'])->firstOrFail();
|
||||
if (!in_array($material->id, $estimatedMaterialIds)) {
|
||||
return redirect()->back()->with('error', "Cannot update material requisition: Material '{$material->name}' is not in the project's approved estimation.");
|
||||
}
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($validated, $project, $requisition) {
|
||||
$requisition->update([
|
||||
'project_id' => $project->id,
|
||||
'notes' => $validated['notes'] ?? null,
|
||||
]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user