first(); } /** * Actualizar almacén */ public function updateWarehouse(Warehouse $warehouse, array $data): Warehouse { return DB::transaction(function () use ($warehouse, $data) { // Si se marca como principal, desactivar otros principales if (isset($data['is_main']) && $data['is_main']) { Warehouse::where('id', '!=', $warehouse->id) ->where('is_main', true) ->update(['is_main' => false]); } // No permitir desactivar el último almacén principal if (isset($data['is_main']) && !$data['is_main'] && $warehouse->is_main) { if (Warehouse::main()->count() === 1) { throw new \Exception('No se puede desactivar el único almacén principal. Asigna otro almacén como principal primero.'); } } $warehouse->update($data); return $warehouse->fresh(); }); } /** * Activar/Desactivar almacén */ public function toggleActive(Warehouse $warehouse): Warehouse { // No permitir desactivar el almacén principal if ($warehouse->is_main && $warehouse->is_active) { throw new \Exception('No se puede desactivar el almacén principal.'); } $warehouse->update(['is_active' => !$warehouse->is_active]); return $warehouse->fresh(); } /** * Obtener stock de un almacén */ public function getWarehouseStock(Warehouse $warehouse) { return $warehouse->inventories() ->with(['category', 'price']) ->select('inventories.*') ->get() ->map(function ($inventory) use ($warehouse) { $pivot = $inventory->warehouses() ->where('warehouse_id', $warehouse->id) ->first(); return [ 'inventory_id' => $inventory->id, 'name' => $inventory->name, 'sku' => $inventory->sku, 'category' => $inventory->category?->name, 'stock' => $pivot?->pivot->stock ?? 0, 'min_stock' => $pivot?->pivot->min_stock, 'max_stock' => $pivot?->pivot->max_stock, 'cost' => $inventory->price?->cost, 'retail_price' => $inventory->price?->retail_price, ]; }); } /** * Validar que existe almacén principal */ public function ensureMainWarehouse(): void { if (!Warehouse::main()->exists()) { throw new \Exception('No existe un almacén principal configurado.'); } } }