ultimatepos/Modules/Maintenance/Http/Controllers/MaterialListController.php

233 lines
8.8 KiB
PHP

<?php
namespace Modules\Maintenance\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\Maintenance\Http\Controllers\Concerns\AuthorizesMaintenance;
use Modules\Maintenance\Models\MaterialLine;
use Modules\Maintenance\Models\MaterialList;
use Modules\Maintenance\Services\MaterialListService;
use Modules\Maintenance\Services\MaterialPurchaseSuggestionService;
use Modules\Maintenance\Services\MaterialStockService;
use Modules\Maintenance\Utils\MaintenanceUtil;
class MaterialListController extends Controller
{
use AuthorizesMaintenance;
public function __construct(
protected MaintenanceUtil $maintenanceUtil,
protected MaterialListService $materialService,
protected MaterialStockService $stockService,
protected MaterialPurchaseSuggestionService $suggestionService
) {}
public function panel(Request $request, string $sourceType, int $sourceId)
{
$this->authorizeMaintenanceAccess('maintenance.materials.view');
$business = $this->maintenanceUtil->getBusiness();
$list = $this->materialService->getOrCreateList($business, $sourceType, $sourceId, auth()->user());
$panelData = $this->materialService->getPanelData($business, $sourceType, $sourceId, auth()->user());
return view('maintenance::materials.panel', array_merge($panelData, [
'spare_parts' => $this->maintenanceUtil->getSparePartsDropdown($business->id),
'can_manage' => auth()->user()->can('maintenance.materials.manage'),
'can_procure' => auth()->user()->can('maintenance.materials.procure'),
]));
}
public function updateDestination(Request $request, string $sourceType, int $sourceId)
{
$this->authorizeMaintenanceAccess('maintenance.materials.manage');
$business = $this->maintenanceUtil->getBusiness();
$list = $this->materialService->getOrCreateList($business, $sourceType, $sourceId);
$data = $request->validate([
'destination_location_id' => 'nullable|integer|exists:business_locations,id',
]);
$this->materialService->updateDestination($list, $data['destination_location_id'] ?? null);
return $this->maintenanceUtil->jsonOrRedirect($request, true, __('maintenance::lang.mat_destination_updated'));
}
public function storeLine(Request $request, string $sourceType, int $sourceId)
{
$this->authorizeMaintenanceAccess('maintenance.materials.manage');
$business = $this->maintenanceUtil->getBusiness();
$list = $this->materialService->getOrCreateList($business, $sourceType, $sourceId);
$data = $request->validate([
'spare_part_id' => 'nullable|exists:maintenance_spare_parts,id',
'part_name' => 'nullable|string|max:255',
'line_type' => 'nullable|in:supply,repair',
'quantity_required' => 'required|numeric|min:0.001',
'notes' => 'nullable|string',
]);
try {
$this->materialService->addLine($list, $data);
} catch (\InvalidArgumentException $e) {
return $this->maintenanceUtil->jsonOrRedirect($request, false, $e->getMessage());
}
return $this->maintenanceUtil->jsonOrRedirect($request, true, __('maintenance::lang.mat_line_added'));
}
public function destroyLine(Request $request, int $lineId)
{
$this->authorizeMaintenanceAccess('maintenance.materials.manage');
$business_id = $this->maintenanceUtil->getBusinessId();
$line = MaterialLine::where('business_id', $business_id)->findOrFail($lineId);
try {
$this->materialService->deleteLine($line);
} catch (\InvalidArgumentException $e) {
return $this->maintenanceUtil->jsonOrRedirect($request, false, $e->getMessage());
}
return $this->maintenanceUtil->jsonOrRedirect($request, true, __('maintenance::lang.mat_line_deleted'));
}
public function importBom(Request $request, string $sourceType, int $sourceId)
{
$this->authorizeMaintenanceAccess('maintenance.materials.manage');
$business = $this->maintenanceUtil->getBusiness();
$list = $this->materialService->getOrCreateList($business, $sourceType, $sourceId);
$equipmentId = $request->input('equipment_id')
?: $this->materialService->resolveEquipmentId($sourceType, $sourceId, $business->id);
if (! $equipmentId) {
return $this->maintenanceUtil->jsonOrRedirect($request, false, __('maintenance::lang.mat_no_equipment'));
}
$count = $this->materialService->importFromEquipmentBom($list, (int) $equipmentId);
return $this->maintenanceUtil->jsonOrRedirect(
$request,
true,
__('maintenance::lang.mat_bom_imported', ['count' => $count])
);
}
public function requestTransfer(Request $request, int $lineId)
{
$this->authorizeMaintenanceAccess('maintenance.materials.procure');
$business = $this->maintenanceUtil->getBusiness();
$line = MaterialLine::where('business_id', $business->id)->with('materialList')->findOrFail($lineId);
$data = $request->validate([
'source_location_id' => 'required|integer|exists:business_locations,id',
'quantity' => 'required|numeric|min:0.001',
]);
try {
$procurement = $this->materialService->requestTransfer(
$line->materialList,
$line,
(int) $data['source_location_id'],
(float) $data['quantity'],
auth()->user()
);
} catch (\InvalidArgumentException $e) {
return $this->maintenanceUtil->jsonOrRedirect($request, false, $e->getMessage());
}
$ref = $procurement->meta['ref_no'] ?? '';
return $this->maintenanceUtil->jsonOrRedirect(
$request,
true,
__('maintenance::lang.mat_transfer_created', ['ref' => $ref])
);
}
public function createPurchaseRequisition(Request $request, string $sourceType, int $sourceId)
{
$this->authorizeMaintenanceAccess('maintenance.materials.procure');
$business = $this->maintenanceUtil->getBusiness();
$list = $this->materialService->getOrCreateList($business, $sourceType, $sourceId);
$data = $request->validate([
'lines' => 'required|array|min:1',
'lines.*.line_id' => 'required|integer',
'lines.*.supplier_id' => 'nullable|integer',
'lines.*.quantity' => 'nullable|numeric|min:0.001',
]);
try {
$transaction = $this->materialService->createPurchaseRequisition(
$list,
$data['lines'],
auth()->user()
);
} catch (\InvalidArgumentException $e) {
return $this->maintenanceUtil->jsonOrRedirect($request, false, $e->getMessage());
}
return $this->maintenanceUtil->jsonOrRedirect(
$request,
true,
__('maintenance::lang.mat_requisition_created', ['ref' => $transaction->ref_no])
);
}
public function createPurchaseOrders(Request $request, string $sourceType, int $sourceId)
{
$this->authorizeMaintenanceAccess('maintenance.materials.procure');
$business = $this->maintenanceUtil->getBusiness();
$list = $this->materialService->getOrCreateList($business, $sourceType, $sourceId);
$data = $request->validate([
'lines' => 'required|array|min:1',
'lines.*.line_id' => 'required|integer',
'lines.*.supplier_id' => 'required|integer',
'lines.*.quantity' => 'nullable|numeric|min:0.001',
]);
try {
$orders = $this->materialService->createPurchaseOrders(
$list,
$data['lines'],
auth()->user()
);
} catch (\InvalidArgumentException $e) {
return $this->maintenanceUtil->jsonOrRedirect($request, false, $e->getMessage());
}
$refs = $orders->pluck('ref_no')->implode(', ');
return $this->maintenanceUtil->jsonOrRedirect(
$request,
true,
__('maintenance::lang.mat_po_created', ['refs' => $refs])
);
}
public function supplierSuggestions(int $lineId)
{
$this->authorizeMaintenanceAccess('maintenance.materials.view');
$business_id = $this->maintenanceUtil->getBusinessId();
$line = MaterialLine::where('business_id', $business_id)->findOrFail($lineId);
if (! $line->variation_id) {
return response()->json(['success' => true, 'data' => []]);
}
$suggestions = $this->suggestionService->suggestSuppliers($business_id, (int) $line->variation_id);
return response()->json(['success' => true, 'data' => $suggestions]);
}
}