schema([ Forms\Components\Section::make('Información del Producto') ->schema([ Forms\Components\Select::make('producto_id') ->label('Producto') ->relationship('producto', 'nombre') ->searchable() ->preload() ->required() ->reactive() ->afterStateUpdated(function ($set, $get, $state) { if ($state) { $producto = Producto::find($state); if ($producto && $producto->variants()->exists()) { $set('tiene_variantes', true); $set('variante_id', null); // Limpiar selección anterior $set('stock_disponible_info', null); // Mostrar información sobre las variantes $cantidadVariantes = $producto->variants()->count(); $set('info_variantes', "Este producto tiene {$cantidadVariantes} variante(s). Debe seleccionar una variante específica para la transferencia."); } else { $set('tiene_variantes', false); $set('variante_id', null); $set('info_variantes', null); // Mostrar stock disponible del producto $stockTotal = $producto->getStockEfectivo(); $set('stock_disponible_info', "Stock total del producto: {$stockTotal} unidades"); } } else { $set('tiene_variantes', false); $set('variante_id', null); $set('info_variantes', null); $set('stock_disponible_info', null); } }), Forms\Components\Placeholder::make('info_variantes') ->label('Información del Producto') ->content(fn ($get) => $get('info_variantes') ?? '') ->visible(fn ($get) => $get('tiene_variantes')), Forms\Components\Placeholder::make('stock_disponible_info') ->label('Stock Disponible') ->content(fn ($get) => $get('stock_disponible_info') ?? '') ->visible(fn ($get) => !$get('tiene_variantes') && $get('stock_disponible_info')), Forms\Components\Select::make('variante_id') ->label('Seleccionar Variante') ->options(function ($get) { $productoId = $get('producto_id'); if ($productoId) { return ProductVariant::where('producto_id', $productoId) ->with(['color', 'size']) ->get() ->mapWithKeys(function ($variante) { $colorName = $variante->color->name ?? ''; $sizeName = $variante->size->name ?? ''; $stockEfectivo = $variante->getStockEfectivo(); $displayName = "{$variante->sku} - {$colorName} {$sizeName} (Stock: {$stockEfectivo})"; return [$variante->id => $displayName]; }); } return []; }) ->searchable() ->required(fn ($get) => $get('tiene_variantes')) ->visible(fn ($get) => $get('tiene_variantes')) ->reactive() ->afterStateUpdated(function ($set, $get, $state) { if ($state) { $variante = ProductVariant::find($state); if ($variante) { $stockTotal = $variante->getStockEfectivo(); $set('stock_variante_info', "Stock total de esta variante: {$stockTotal} unidades"); } } else { $set('stock_variante_info', null); } }) ->helperText('Seleccione la variante específica que desea transferir'), Forms\Components\Placeholder::make('stock_variante_info') ->label('Stock de la Variante') ->content(fn ($get) => $get('stock_variante_info') ?? '') ->visible(fn ($get) => $get('tiene_variantes') && $get('variante_id') && $get('stock_variante_info')), ]) ->columns(2), Forms\Components\Section::make('Detalles de la Transferencia') ->schema([ Forms\Components\Select::make('bodega_origen_id') ->label('Bodega Origen') ->options(function ($get) { $productoId = $get('producto_id'); $varianteId = $get('variante_id'); if ($varianteId) { // Si hay variante seleccionada, mostrar solo bodegas con stock de esa variante $variante = ProductVariant::find($varianteId); if ($variante) { return $variante->bodegas() ->where('variante_bodega.stock', '>', 0) ->get() ->mapWithKeys(function ($bodega) { return [$bodega->id => "{$bodega->nombre} (Stock: {$bodega->pivot->stock})"]; }); } } elseif ($productoId) { // Si hay producto sin variantes, mostrar bodegas con stock del producto $producto = Producto::find($productoId); if ($producto && !$producto->variants()->exists()) { return $producto->bodegas() ->where('producto_bodega.stock', '>', 0) ->get() ->mapWithKeys(function ($bodega) { return [$bodega->id => "{$bodega->nombre} (Stock: {$bodega->pivot->stock})"]; }); } } // Fallback: mostrar todas las bodegas return Bodega::pluck('nombre', 'id'); }) ->searchable() ->required() ->reactive() ->afterStateUpdated(function ($set, $get, $state) { $set('stock_origen_disponible', null); if ($state) { $productoId = $get('producto_id'); $varianteId = $get('variante_id'); if ($varianteId) { $variante = ProductVariant::find($varianteId); $stock = $variante->bodegas() ->where('bodega_id', $state) ->first()?->pivot?->stock ?? 0; } elseif ($productoId) { $producto = Producto::find($productoId); $stock = $producto->bodegas() ->where('bodega_id', $state) ->first()?->pivot?->stock ?? 0; } else { $stock = 0; } $bodegaNombre = Bodega::find($state)?->nombre ?? ''; $set('stock_origen_disponible', "Stock disponible en {$bodegaNombre}: {$stock} unidades"); $set('max_cantidad', $stock); } }) ->helperText('Solo se muestran bodegas con stock disponible'), Forms\Components\Placeholder::make('stock_origen_disponible') ->label('Stock en Bodega Origen') ->content(fn ($get) => $get('stock_origen_disponible') ?? '') ->visible(fn ($get) => $get('stock_origen_disponible')), Forms\Components\Select::make('bodega_destino_id') ->label('Bodega Destino') ->relationship('bodegaDestino', 'nombre') ->searchable() ->required() ->different('bodega_origen_id'), Forms\Components\TextInput::make('cantidad') ->label('Cantidad a Transferir') ->numeric() ->required() ->minValue(1) ->maxValue(fn ($get) => $get('max_cantidad') ?? 999999) ->helperText(fn ($get) => $get('max_cantidad') ? "Máximo disponible: {$get('max_cantidad')} unidades" : '' ), Forms\Components\Textarea::make('motivo') ->label('Motivo de la Transferencia') ->placeholder('Ej: Reposición de sucursal, reorganización de inventario...') ->rows(3) ->columnSpanFull(), ]) ->columns(2), Forms\Components\Hidden::make('usuario_id') ->default(Auth::id()), Forms\Components\Hidden::make('fecha_transferencia') ->default(now()), Forms\Components\Hidden::make('tiene_variantes') ->default(false), Forms\Components\Hidden::make('max_cantidad') ->default(0), Forms\Components\Hidden::make('info_variantes'), Forms\Components\Hidden::make('stock_disponible_info'), Forms\Components\Hidden::make('stock_variante_info'), Forms\Components\Hidden::make('stock_origen_disponible'), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('producto.nombre') ->label('Producto') ->searchable() ->sortable() ->wrap(), Tables\Columns\TextColumn::make('variante_info') ->label('Variante') ->getStateUsing(function ($record) { if ($record->variante_id) { $variante = ProductVariant::find($record->variante_id); if ($variante) { $colorName = $variante->color->name ?? ''; $sizeName = $variante->size->name ?? ''; return "{$variante->sku} - {$colorName} {$sizeName}"; } } return 'Producto general'; }) ->badge() ->color(fn ($state) => $state === 'Producto general' ? 'info' : 'warning') ->searchable(query: function (Builder $query, string $search): Builder { return $query->whereHas('producto.variants', function ($q) use ($search) { $q->where('sku', 'like', "%{$search}%"); }); }), Tables\Columns\TextColumn::make('bodegaOrigen.nombre') ->label('Bodega Origen') ->badge() ->color('danger') ->sortable(), Tables\Columns\TextColumn::make('bodegaDestino.nombre') ->label('Bodega Destino') ->badge() ->color('success') ->sortable(), Tables\Columns\TextColumn::make('cantidad') ->label('Cantidad') ->numeric() ->sortable() ->badge() ->color('primary'), Tables\Columns\TextColumn::make('motivo') ->label('Motivo') ->limit(30) ->tooltip(function ($record) { return $record->motivo; }) ->wrap(), Tables\Columns\TextColumn::make('usuario.name') ->label('Usuario') ->sortable() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('fecha_transferencia') ->label('Fecha') ->dateTime('d/m/Y H:i') ->sortable() ->badge() ->color('gray'), Tables\Columns\TextColumn::make('created_at') ->label('Creado') ->dateTime('d/m/Y H:i') ->sortable() ->toggleable(isToggledHiddenByDefault: true), ]) ->filters([ SelectFilter::make('bodega_origen_id') ->label('Bodega Origen') ->relationship('bodegaOrigen', 'nombre'), SelectFilter::make('bodega_destino_id') ->label('Bodega Destino') ->relationship('bodegaDestino', 'nombre'), SelectFilter::make('producto_id') ->label('Producto') ->relationship('producto', 'nombre') ->searchable(), Tables\Filters\Filter::make('con_variantes') ->label('Solo Variantes') ->query(fn (Builder $query): Builder => $query->whereNotNull('variante_id')), Tables\Filters\Filter::make('sin_variantes') ->label('Solo Productos Generales') ->query(fn (Builder $query): Builder => $query->whereNull('variante_id')), ]) ->actions([ Tables\Actions\EditAction::make(), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), ]), ]); } public static function getRelations(): array { return [ // ]; } public static function getPages(): array { return [ 'index' => Pages\ListTransferenciaBodegas::route('/'), 'create' => Pages\CreateTransferenciaBodega::route('/create'), 'edit' => Pages\EditTransferenciaBodega::route('/{record}/edit'), ]; } }