This commit is contained in:
2026-05-15 19:18:03 +02:00
parent f4a8314978
commit b5ccb0428d
9 changed files with 620 additions and 294 deletions

View File

@@ -0,0 +1,157 @@
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:get_it/get_it.dart';
part 'ticket_shipping_state.dart';
class TicketShippingCubit extends Cubit<TicketShippingState> {
final TicketsShipmentRepository _repository =
GetIt.I<TicketsShipmentRepository>();
TicketShippingCubit({required List<String> ticketIds})
: super(
TicketShippingState(
// Inizializziamo il modello direttamente nello stato!
document: ShipmentDocumentModel(
companyId: GetIt.I.get<SessionCubit>().state.company!.id!,
ticketIds: ticketIds,
providerId: '', // Sarà riempito alla selezione
destinationLocationId: '', // Sarà riempito alla selezione
docNumber: '',
docDate: DateTime.now(),
),
),
);
Future<void> 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),
),
);
}
void toggleAutoNumber(bool value) {
emit(state.copyWith(isAutoNumber: value));
if (value) {
final nextNumber = "DDT-${DateTime.now().year}-001";
emit(
state.copyWith(
document: state.document.copyWith(docNumber: nextNumber),
),
);
} else {
emit(state.copyWith(document: state.document.copyWith(docNumber: '')));
}
}
// 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<void> confirmShipment({required String 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.document.docNumber.trim().isEmpty) {
emit(
state.copyWith(
status: TicketShippingStatus.failure,
errorMessage: 'Inserisci il numero DDT.',
),
);
return;
}
emit(state.copyWith(status: TicketShippingStatus.loading));
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(),
),
);
}
}
}

View File

@@ -0,0 +1,51 @@
part of 'ticket_shipping_cubit.dart';
enum TicketShippingStatus { initial, loading, success, failure }
class TicketShippingState extends Equatable {
final TicketShippingStatus status;
final ShipmentDocumentModel document; // Il nostro eroe!
// Dati di supporto per la UI
final List<ProviderModel> availableProviders;
final List<ProviderLocationModel> availableLocations;
final bool isAutoNumber;
final String? errorMessage;
const TicketShippingState({
this.status = TicketShippingStatus.initial,
required this.document,
this.availableProviders = const [],
this.availableLocations = const [],
this.isAutoNumber = false,
this.errorMessage,
});
TicketShippingState copyWith({
TicketShippingStatus? status,
ShipmentDocumentModel? document,
List<ProviderModel>? availableProviders,
List<ProviderLocationModel>? availableLocations,
bool? isAutoNumber,
String? errorMessage,
}) {
return TicketShippingState(
status: status ?? this.status,
document: document ?? this.document,
availableProviders: availableProviders ?? this.availableProviders,
availableLocations: availableLocations ?? this.availableLocations,
isAutoNumber: isAutoNumber ?? this.isAutoNumber,
errorMessage: errorMessage ?? this.errorMessage,
);
}
@override
List<Object?> get props => [
status,
document,
availableProviders,
availableLocations,
isAutoNumber,
errorMessage,
];
}