schema([ Section::make('Datos de la Orden') ->schema([ Select::make('producto_id') ->label('Producto (opcional)') ->relationship('producto', 'nombre') ->searchable() ->preload() ->nullable() ->reactive() ->afterStateUpdated(function ($state, $set) { if ($state) { $prod = \App\Models\Producto::find($state); if ($prod) { $set('prenda_modelo', $prod->nombre); } } }) ->helperText('Si seleccionas un producto, se completará automáticamente el campo Prenda / Modelo.'), TextInput::make('prenda_modelo') ->label('Prenda / Modelo') ->required() ->maxLength(255), TextInput::make('cantidad_total') ->numeric() ->required() ->minValue(1), Select::make('tela_id') ->label('Tela asociada') ->options(fn () => \App\Models\Tela::where('metros_disponibles', '>', 0)->pluck('codigo', 'id')->toArray()) ->searchable() ->preload() ->reactive() ->afterStateUpdated(function ($state, $set, $get) { if ($state) { $tela = \App\Models\Tela::find($state); $available = $tela ? (float) $tela->metros_disponibles : 0; if (! $get('metros_requeridos') || $get('metros_requeridos') > $available) { $set('metros_requeridos', $available); } } else { $set('metros_requeridos', 0); } }) ->nullable(), TextInput::make('metros_requeridos') ->label('Metros requeridos') ->numeric() ->required() ->minValue(0) ->reactive() ->helperText(fn ($get) => $get('tela_id') ? 'Saldo disponible: ' . (\App\Models\Tela::find($get('tela_id'))->metros_disponibles ?? 0) . ' m' : 'Selecciona una tela') ->default(0), DatePicker::make('fecha_inicio') ->required() ->default(now()), DatePicker::make('fecha_entrega_estimada') ->required(), FileUpload::make('imagenes') ->label('Imágenes') ->image() ->multiple() ->directory('ordenes') ->enableReordering() ->columnSpanFull() ->helperText('Sube imágenes relacionadas con la orden.'), ]) ->columns(2), Section::make('Proceso') ->schema([ View::make('filament.orden_produccion.timeline') ->columnSpanFull(), ]) ->columnSpanFull(), ]); } public static function table(Table $table): Table { return $table ->columns([ TextColumn::make('numero_orden') ->label('OP') ->sortable(), TextColumn::make('prenda_modelo') ->searchable(), TextColumn::make('cantidad_total') ->label('Cantidad'), TextColumn::make('prensillas_count') ->label('Prensillas') ->counts('prensillas') ->sortable(), TextColumn::make('ojales_count') ->label('Ojales') ->counts('ojales') ->sortable(), TextColumn::make('realizado') ->label('Realizado') ->sortable(), TextColumn::make('faltantes') ->label('Faltan') ->sortable(), TextColumn::make('tela.codigo') ->label('Tela') ->toggleable(), BadgeColumn::make('estado_display') ->label('Estado') ->colors([ 'warning' => 'en_corte', 'info' => 'en_confeccion', 'primary' => 'en_tintoreria', 'secondary' => 'en_acabados', 'success' => 'finalizada', ]) ->formatStateUsing(fn($state) => match ($state) { 'en_corte' => 'En corte', 'en_confeccion' => 'En confección', 'en_tintoreria' => 'En tintorería', 'en_acabados' => 'En acabados', 'finalizada' => 'Finalizada', }), TextColumn::make('fecha_entrega_estimada') ->date(), ]) ->defaultSort('created_at', 'desc') ->filters([ // ]) ->actions([ Tables\Actions\EditAction::make(), Tables\Actions\Action::make('finalizar') ->label('Finalizar') ->icon('heroicon-o-check') ->color('success') ->requiresConfirmation() ->visible(fn($record) => $record->estado !== 'finalizada') ->action(function ($record) { try { // Forzar finalización $record->manualFinalize(); \Filament\Notifications\Notification::make() ->success() ->title('Orden finalizada') ->body('La orden se marcó como finalizada manualmente.') ->send(); } catch (\Throwable $e) { \Filament\Notifications\Notification::make() ->danger() ->title('Error') ->body($e->getMessage()) ->send(); } }), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), // Tables\Actions\Action::make('avanzar') // ->label('Avanzar estado') // ->icon('heroicon-o-arrow-right') // ->requiresConfirmation() // ->visible(fn($record) => $record->estado !== 'finalizada') // ->action(fn($record) => $record->avanzarEstado()), ]), ]); } public static function getRelations(): array { return [ RelationManagers\TrasladosRelationManager::class, RelationManagers\PrensillasRelationManager::class, RelationManagers\OjalesRelationManager::class, ]; } public static function getPages(): array { return [ 'index' => Pages\ListOrdenProduccions::route('/'), 'create' => Pages\CreateOrdenProduccion::route('/create'), 'edit' => Pages\EditOrdenProduccion::route('/{record}/edit'), ]; } }