import 'package:equatable/equatable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flux/core/blocs/session/session_cubit.dart'; import 'package:flux/features/documents/data/tickets_shipment_repository.dart'; import 'package:flux/features/documents/models/shipment_document_model.dart'; import 'package:flux/features/master_data/providers/models/provider_location_model.dart'; import 'package:flux/features/master_data/providers/models/provider_model.dart'; import 'package:flux/features/settings/document_sequence/data/document_sequence_repository.dart'; import 'package:flux/features/settings/document_sequence/models/document_sequence_model.dart'; import 'package:flux/features/tickets/models/ticket_model.dart'; import 'package:get_it/get_it.dart'; part 'ticket_shipping_state.dart'; class TicketShippingCubit extends Cubit { final TicketsShipmentRepository _repository = GetIt.I(); final DocumentSequenceRepository _sequenceRepository = GetIt.I(); TicketShippingCubit({required List ticketIds}) : super( TicketShippingState( // Inizializziamo il modello direttamente nello stato! document: ShipmentDocumentModel( companyId: GetIt.I.get().state.company!.id!, ticketIds: ticketIds, providerId: '', // Sarà riempito alla selezione destinationLocationId: '', // Sarà riempito alla selezione docNumber: '', docDate: DateTime.now(), ), ), ); Future loadRepairCenters() async { emit(state.copyWith(status: TicketShippingStatus.loading)); try { final repairCenters = await _repository.fetchRepairCenters(); emit( state.copyWith( status: TicketShippingStatus.initial, availableProviders: repairCenters, ), ); } catch (e) { emit( state.copyWith( status: TicketShippingStatus.failure, errorMessage: e.toString(), ), ); } } void selectProvider(String providerId) { final ProviderModel provider = state.availableProviders.firstWhere( (p) => p.id == providerId, ); final locations = provider.locations ?? []; String destinationId = ''; if (locations.length == 1) { destinationId = locations.first.id ?? ''; } else if (locations.any((l) => l.isMain)) { destinationId = locations.firstWhere((l) => l.isMain).id ?? ''; } emit( state.copyWith( availableLocations: locations, document: state.document.copyWith( providerId: providerId, destinationLocationId: destinationId, ), ), ); } void selectLocation(String locationId) { emit( state.copyWith( document: state.document.copyWith(destinationLocationId: locationId), ), ); } Future toggleAutoNumber(bool value) async { // Aggiorniamo subito l'UI per mostrare che lo switch si è acceso emit(state.copyWith(isAutoNumber: value)); } // Metodo unico e pulito per aggiornare i campi testuali/numerici del documento void updateDocument({ String? docNumber, DateTime? docDate, int? packageCount, double? weight, String? shippingReason, String? notes, }) { emit( state.copyWith( document: state.document.copyWith( docNumber: docNumber, docDate: docDate, packageCount: packageCount, weight: weight, shippingReason: shippingReason, notes: notes, ), ), ); } Future confirmShipment({required TicketStatus newTicketStatus}) async { if (state.document.providerId.isEmpty || state.document.destinationLocationId.isEmpty) { emit( state.copyWith( status: TicketShippingStatus.failure, errorMessage: 'Seleziona laboratorio e sede.', ), ); return; } if (!state.isAutoNumber && state.document.docNumber.trim().isEmpty) { emit( state.copyWith( status: TicketShippingStatus.failure, errorMessage: 'Inserisci il numero DDT.', ), ); return; } emit(state.copyWith(status: TicketShippingStatus.loading)); if (state.isAutoNumber) { try { final nextNumber = await _sequenceRepository.getNextDocumentNumber( DocumentType.shipment.name, ); updateDocument(docNumber: nextNumber); } catch (e) { emit(state.copyWith(isAutoNumber: false, errorMessage: e.toString())); return; } } try { await _repository.createShipmentDocument( document: state.document, newTicketStatus: newTicketStatus, ); emit(state.copyWith(status: TicketShippingStatus.success)); } catch (e) { emit( state.copyWith( status: TicketShippingStatus.failure, errorMessage: e.toString(), ), ); } } }