vat_wms/app/Http/Controllers/Api/StockBatchController.php
2025-06-02 07:36:24 +02:00

275 lines
8.6 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\OriginCountry;
use App\Models\StockBatch;
use App\Models\StockEntry;
use App\Models\StockPosition;
use App\Models\PhysicalItem;
use App\Models\StockSection;
use App\Models\Supplier;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class StockBatchController extends Controller
{
/**
* Display a paginated listing of stock entries.
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function index(Request $request)
{
$query = StockBatch::query()
->with(['user', 'supplier', 'stockEntries.statusHistory.status', 'files']);
// Apply filters if provided
if ($request->has('search')) {
$search = $request->search;
$query->whereHas('physicalItem', function($q) use ($search) {
$q->where('name', 'like', "%{$search}%");
});
}
// Sort
$sortField = $request->input('sort_field', 'updated_at');
$sortDirection = $request->input('sort_direction', 'desc');
$query->orderBy($sortField, $sortDirection);
// Paginate
$perPage = $request->input('per_page', 10);
$page = $request->input('page', 1);
$entries = $query->paginate($perPage, ['*'], 'page', $page);
return response()->json([
'data' => $entries->items(),
'meta' => [
'total' => $entries->total(),
'per_page' => $entries->perPage(),
'current_page' => $entries->currentPage(),
'last_page' => $entries->lastPage(),
],
]);
}
/**
* Store a newly created stock batch, with multiple files.
*/
public function addData(Request $request)
{
try {
$validator = Validator::make($request->all(), [
'supplier_id' => 'nullable|integer',
'tracking_number' => 'nullable|string',
'arrival_date' => 'nullable|date',
'files.*' => 'file',
'file_types' => 'array',
'file_types.*' => 'in:invoice,label,other',
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 422);
}
// create the batch
$batch = StockBatch::create([
'user_id' => auth()->id() ?? 1,
'supplier_id' => $request->input('supplier_id'),
'tracking_number' => $request->input('tracking_number'),
'arrival_date' => $request->input('arrival_date'),
]);
// attach each uploaded file
if ($request->hasFile('files')) {
foreach ($request->file('files') as $i => $upload) {
$batch->files()->create([
'filename' => $upload->getClientOriginalName(),
'file_data' => file_get_contents($upload->getRealPath()),
'file_type' => $request->input("file_types.{$i}", 'other'),
'user_id' => auth()->id() ?? 1,
]);
}
}
return response()->json([
'message' => 'Stock batch created successfully',
'data' => $batch->load(['supplier', 'user', 'files', 'stockEntries']),
], 201);
}
catch (\Exception $e) {
return response()->json(['errors' => $e->getMessage()], 500);
}
}
/**
* Display the specified stock batch, with its files & entries.
*/
public function show($id)
{
$batch = StockBatch::with(['user','supplier','files','stockEntries'])
->findOrFail($id);
return response()->json(['data' => $batch]);
}
/**
* Update the specified stock batch and optionally add new files.
*/
public function updateData(Request $request, $id)
{
$validator = Validator::make($request->all(), [
'supplier_id' => 'nullable|integer|exists:supplier,id',
'tracking_number' => 'nullable|integer',
'arrival_date' => 'nullable|date',
'files.*' => 'file',
'file_types' => 'array',
'file_types.*' => 'in:invoice,label,other',
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 422);
}
$batch = StockBatch::findOrFail($id);
$batch->update($request->only(['supplier_id','tracking_number','arrival_date']) + [
'updated_at' => now(),
]);
// if there are new files, attach them
if ($request->hasFile('files')) {
foreach ($request->file('files') as $i => $upload) {
$batch->files()->create([
'filename' => $upload->getClientOriginalName(),
'file_data' => file_get_contents($upload->getRealPath()),
'file_type' => $request->input("file_types.{$i}", 'other'),
'user_id' => auth()->id() ?? 1,
]);
}
}
return response()->json([
'message' => 'Stock batch updated successfully',
'data' => $batch->fresh(['supplier','user','files','stockEntries']),
]);
}
/**
* Remove the specified stock batch (and its files).
*/
public function destroy($id)
{
$batch = StockBatch::with('files')->findOrFail($id);
// delete related files first if you need to clean up storage
foreach ($batch->files as $file) {
$file->delete();
}
$batch->delete();
return response()->json([
'message' => 'Stock batch deleted successfully',
]);
}
/**
* Get options for dropdown lists.
*
* @return \Illuminate\Http\JsonResponse
*/
public function getOptions()
{
$stockPositions = StockSection::doesntHave('entries')
->with('position.shelf.rack.line.room')
->get()
->map(function (StockSection $section) {
$pos = $section->position;
$shelf = $pos->shelf;
$rack = $shelf->rack;
$line = $rack->line;
$room = $line->room;
return [
'id' => $section->section_id,
'name' => sprintf(
'%s-%s-%s-%s-%s-%s',
$room->room_symbol,
$line->line_symbol,
$rack->rack_symbol,
$shelf->shelf_symbol,
$pos->position_symbol,
$section->section_symbol
),
];
});
// Get suppliers from warehouse DB
$suppliers = Supplier::select('id', 'name')->get();
// Get physical items from warehouse DB
$countriesOrigin = OriginCountry::select('id', 'code as name')->get();
return response()->json([
'stockPositions' => $stockPositions,
'suppliers' => $suppliers,
'countriesOrigin' => $countriesOrigin,
]);
}
/**
* Get options for dropdown lists.
*
* @return \Illuminate\Http\JsonResponse
*/
public function getItems(Request $request)
{
// Get physical items from warehouse DB
$physicalItems = PhysicalItem::select('id', 'name')
->where('name', 'like', '%' . $request->input('item_name', '') . '%')
->get();
return response()->json([
'physicalItems' => $physicalItems,
]);
}
/**
* Get options for dropdown lists.
*
* @return \Illuminate\Http\JsonResponse
*/
public function getEntries(Request $request, $id)
{
// Get physical items from warehouse DB
$stockEntries = StockEntry::with(['physicalItem', 'supplier', 'sections', 'statusHistory'])->where('stock_batch_id', $id)->get();
return response()->json([
"data" => $stockEntries
]);
}
public function addEntries(Request $request, $id)
{
// Get physical items from warehouse DB
$stockEntries = StockEntry::whereIn('id', $request->get('ids'))->get();
foreach ($stockEntries as $entry) {
$entry->update([
'stock_batch_id' => $id,
'on_the_way' => false,
]);
}
return response()->json([
'message' => 'Batch entries updated successfully',
'data' => $entry->fresh(),
]);
}
}