* @version 1.0.0 */ class InventorySerialController extends Controller { /** * Listar seriales de un producto */ public function index(Inventory $inventory, Request $request) { $query = $inventory->serials(); if ($request->has('status')) { $query->where('status', $request->status); } if ($request->has('q')) { $query->where('serial_number', 'like', "%{$request->q}%"); } $serials = $query->orderBy('created_at', 'desc') ->paginate(config('app.pagination')); return ApiResponse::OK->response([ 'serials' => $serials, 'inventory' => $inventory->load('category'), ]); } /** * Mostrar un serial específico */ public function show(Inventory $inventory, InventorySerial $serial) { // Verificar que el serial pertenece al inventario if ($serial->inventory_id !== $inventory->id) { return ApiResponse::NOT_FOUND->response([ 'message' => 'Serial no encontrado para este inventario' ]); } return ApiResponse::OK->response([ 'serial' => $serial->load('saleDetail'), 'inventory' => $inventory->load('category'), ]); } /** * Crear un nuevo serial */ public function store(Inventory $inventory, Request $request) { $request->validate([ 'serial_number' => ['required', 'string', 'unique:inventory_serials,serial_number'], 'notes' => ['nullable', 'string'], ]); $serial = InventorySerial::create([ 'inventory_id' => $inventory->id, 'serial_number' => $request->serial_number, 'status' => 'disponible', 'notes' => $request->notes, ]); // Sincronizar stock $inventory->syncStock(); return ApiResponse::CREATED->response([ 'serial' => $serial, 'inventory' => $inventory->fresh(), ]); } /** * Actualizar un serial */ public function update(Inventory $inventory, InventorySerial $serial, Request $request) { // Verificar que el serial pertenece al inventario if ($serial->inventory_id !== $inventory->id) { return ApiResponse::NOT_FOUND->response([ 'message' => 'Serial no encontrado para este inventario' ]); } $request->validate([ 'serial_number' => ['sometimes', 'string', 'unique:inventory_serials,serial_number,' . $serial->id], 'status' => ['sometimes', 'in:disponible,vendido,dañado,reservado'], 'notes' => ['nullable', 'string'], ]); $serial->update($request->only(['serial_number', 'status', 'notes'])); // Sincronizar stock del inventario $inventory->syncStock(); return ApiResponse::OK->response([ 'serial' => $serial->fresh(), 'inventory' => $inventory->fresh(), ]); } /** * Eliminar un serial */ public function destroy(Inventory $inventory, InventorySerial $serial) { // Verificar que el serial pertenece al inventario if ($serial->inventory_id !== $inventory->id) { return ApiResponse::NOT_FOUND->response([ 'message' => 'Serial no encontrado para este inventario' ]); } $serial->delete(); // Sincronizar stock $inventory->syncStock(); return ApiResponse::OK->response([ 'message' => 'Serial eliminado exitosamente', 'inventory' => $inventory->fresh(), ]); } /** * Importar múltiples seriales */ public function bulkStore(Inventory $inventory, Request $request) { $request->validate([ 'serial_numbers' => ['required', 'array', 'min:1'], 'serial_numbers.*' => ['required', 'string', 'unique:inventory_serials,serial_number'], ]); $created = []; foreach ($request->serial_numbers as $serialNumber) { $serial = InventorySerial::create([ 'inventory_id' => $inventory->id, 'serial_number' => $serialNumber, 'status' => 'disponible', ]); $created[] = $serial; } // Sincronizar stock $inventory->syncStock(); return ApiResponse::CREATED->response([ 'serials' => $created, 'count' => count($created), 'inventory' => $inventory->fresh(), ]); } }