Additional Changes
Some checks failed
Tests / PHP 8.3 (push) Has been cancelled
Tests / PHP 8.4 (push) Has been cancelled
Tests / PHP 8.5 (push) Has been cancelled

This commit is contained in:
2026-06-02 22:04:03 +08:00
parent e6a9a80c32
commit 64d4b331a8
151 changed files with 15070 additions and 945 deletions

View File

@@ -12,6 +12,7 @@ use Modules\MaterialLogistics\Models\InventoryBatch;
use Modules\MaterialLogistics\Models\ProjectInventory;
use Modules\MaterialLogistics\Models\Warehouse;
use Modules\MaterialLogistics\Models\WarehouseStock;
use Modules\MaterialLogistics\Models\PurchaseOrder;
use Modules\MaterialLogistics\Services\WarehouseService;
use Modules\ProjectManagement\Models\Project;
use Modules\ProjectManagement\Models\Task;
@@ -154,12 +155,45 @@ class MaterialController extends Controller
]);
}
// --- Fetch materials filtered by operation parameters (e.g. PO for dispatch) ---
public function getMaterialsForOperation(Request $request)
{
$request->validate([
'purchase_order_ulid' => 'nullable|string',
'warehouse_ulid' => 'nullable|string',
'project_ulid' => 'nullable|string',
'type' => 'required|in:dispatch,return,adjust',
]);
$query = Material::select('id', 'ulid', 'name', 'sku', 'unit', 'unit_cost')
->with(['warehouseStocks', 'projectInventories']);
if ($request->type === 'dispatch') {
if ($request->filled('purchase_order_ulid')) {
$po = PurchaseOrder::where('ulid', $request->purchase_order_ulid)->first();
if ($po) {
$materialIds = $po->items()->pluck('material_id');
$query->whereIn('id', $materialIds);
} else {
$query->whereRaw('1 = 0');
}
} else {
$query->whereRaw('1 = 0');
}
}
$materials = $query->get();
return response()->json($materials);
}
// --- Dispatch from Warehouse to Project ---
public function dispatchFromWarehouse(Request $request)
{
$validated = $request->validate([
'warehouse_ulid' => 'required|string',
'project_ulid' => 'required|string',
'purchase_order_ulid' => 'required|string|exists:purchase_orders,ulid',
'handler_id' => 'required|integer|exists:users,id',
'notes' => 'nullable|string|max:500',
'items' => 'required|array|min:1',
@@ -170,11 +204,23 @@ class MaterialController extends Controller
$warehouse = Warehouse::where('ulid', $validated['warehouse_ulid'])->firstOrFail();
$project = Project::where('ulid', $validated['project_ulid'])->firstOrFail();
$po = PurchaseOrder::where('ulid', $validated['purchase_order_ulid'])->firstOrFail();
if ($po->project_id !== $project->id || $po->target_warehouse_id !== $warehouse->id) {
return back()->with('error', 'The selected Purchase Order is not associated with this project and warehouse.');
}
$poMaterialIds = $po->items()->pluck('material_id')->toArray();
DB::beginTransaction();
try {
foreach ($validated['items'] as $item) {
$material = Material::where('ulid', $item['material_ulid'])->firstOrFail();
if (!in_array($material->id, $poMaterialIds)) {
throw new \InvalidArgumentException("Material {$material->name} is not listed in the selected Purchase Order.");
}
$batchId = null;
if (! empty($item['inventory_batch_ulid'])) {