refactot ticket model + cubit

This commit is contained in:
2026-05-06 12:20:26 +02:00
parent 1e9e6947b3
commit bdde092976
3 changed files with 236 additions and 14 deletions

View File

@@ -0,0 +1,169 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/features/customers/models/customer_model.dart';
import 'package:flux/features/tickets/models/ticket_model.dart';
import 'package:flux/features/tickets/data/ticket_repository.dart';
import 'package:get_it/get_it.dart';
import 'ticket_form_state.dart';
class TicketFormCubit extends Cubit<TicketFormState> {
final TicketRepository _repository = GetIt.I.get<TicketRepository>();
final SessionCubit _sessionCubit = GetIt.I.get<SessionCubit>();
TicketFormCubit()
: super(
// Inizializziamo con un ticket vuoto di default
TicketFormState(
ticket: TicketModel.empty(
companyId: GetIt.I.get<SessionCubit>().state.company!.id!,
),
),
);
/// 1. INIZIALIZZAZIONE (Se stiamo modificando un ticket esistente)
void initForm(TicketModel? existingTicket) {
if (existingTicket != null) {
emit(
state.copyWith(ticket: existingTicket, status: TicketFormStatus.ready),
);
} else {
// È un nuovo ticket! Inseriamo i default base (Azienda, Negozio, Creatore)
final currentUser = _sessionCubit.state.currentStaffMember;
final currentStore = _sessionCubit.state.currentStore;
final companyId = _sessionCubit.state.company?.id ?? '';
final newTicket =
TicketModel.empty(
companyId: _sessionCubit.state.company!.id!,
).copyWith(
companyId: companyId,
storeId: currentStore?.id,
staffId: currentUser?.id,
createdById: currentUser?.name,
// Impostiamo lo stato iniziale
status: TicketStatus.open,
ticketType: TicketType.repair, // Default
);
emit(state.copyWith(ticket: newTicket, status: TicketFormStatus.ready));
}
}
/// 2. AGGIORNAMENTO CLIENTE (Usato dal nostro SharedCustomerSection!)
void updateCustomer(CustomerModel customer) {
emit(
state.copyWith(
ticket: state.ticket.copyWith(
customerId: customer.id,
customerName: customer.name,
alternativePhoneNumber: customer.phoneNumber, // Comodo come fallback!
),
),
);
}
/// 3. AGGIORNAMENTO MODELLO (Usato dal nostro SharedModelSection!)
void updateModel({required String modelId, required String modelName}) {
emit(
state.copyWith(
ticket: state.ticket.copyWith(
targetModelId: modelId,
targetModelName: modelName,
),
),
);
}
void updateCreator({required String staffId, required String staffName}) {
emit(
state.copyWith(
ticket: state.ticket.copyWith(staffId: staffId, createdById: staffName),
),
);
}
/// 4. AGGIORNAMENTO GENERICO DEI CAMPI
void updateFields({
TicketType? ticketType,
TicketStatus? status,
String? request,
String? targetSn,
String? alternativePhoneNumber,
bool? hasCourtesyDevice,
String? includedAccessories,
String? publicNotes,
String? internalNotes,
double? customerPrice,
double? internalCost,
String? assignedToId,
String? assignedToName,
}) {
emit(
state.copyWith(
ticket: state.ticket.copyWith(
ticketType: ticketType ?? state.ticket.ticketType,
status: status ?? state.ticket.status,
request: request ?? state.ticket.request,
targetSn: targetSn ?? state.ticket.targetSn,
alternativePhoneNumber:
alternativePhoneNumber ?? state.ticket.alternativePhoneNumber,
hasCourtesyDevice:
hasCourtesyDevice ?? state.ticket.hasCourtesyDevice,
includedAccessories:
includedAccessories ?? state.ticket.includedAccessories,
publicNotes: publicNotes ?? state.ticket.publicNotes,
internalNotes: internalNotes ?? state.ticket.internalNotes,
customerPrice: customerPrice ?? state.ticket.customerPrice,
internalCost: internalCost ?? state.ticket.internalCost,
assignedToId: assignedToId ?? state.ticket.assignedToId,
assignedToName: assignedToName ?? state.ticket.assignedToName,
),
),
);
}
/// 5. SALVATAGGIO
Future<void> saveTicket({required bool keepAdding}) async {
emit(state.copyWith(status: TicketFormStatus.saving));
try {
final ticketToSave = state.ticket;
// Validazione base
if (ticketToSave.customerId == null || ticketToSave.customerId!.isEmpty) {
throw Exception("Seleziona un cliente prima di salvare.");
}
final savedTicket = await _repository.saveTicket(ticketToSave);
if (keepAdding) {
emit(
state.copyWith(
status: TicketFormStatus.successAndAddAnother,
// Svuotiamo il form per il prossimo, mantenendo Store e Creatore ATTUALI
ticket: TicketModel.empty().copyWith(
companyId: savedTicket.companyId,
storeId: savedTicket.storeId,
createdById: ticketToSave
.createdById, // Manteniamo quello selezionato nella tendina!
createdByName: ticketToSave.createdByName,
status: TicketStatus.open,
ticketType: TicketType.repair,
),
),
);
} else {
emit(
state.copyWith(status: TicketFormStatus.success, ticket: savedTicket),
);
}
} catch (e) {
emit(
state.copyWith(
status: TicketFormStatus.failure,
errorMessage: e.toString(),
),
);
}
}
}

View File

@@ -0,0 +1,40 @@
import 'package:equatable/equatable.dart';
import 'package:flux/features/tickets/models/ticket_model.dart';
// Adatta gli import al tuo progetto!
enum TicketFormStatus {
initial,
ready,
loading,
saving,
success,
successAndAddAnother,
failure,
}
class TicketFormState extends Equatable {
final TicketModel ticket;
final TicketFormStatus status;
final String? errorMessage;
const TicketFormState({
required this.ticket,
this.status = TicketFormStatus.initial,
this.errorMessage,
});
@override
List<Object?> get props => [ticket, status, errorMessage];
TicketFormState copyWith({
TicketModel? ticket,
TicketFormStatus? status,
String? errorMessage,
}) {
return TicketFormState(
ticket: ticket ?? this.ticket,
status: status ?? this.status,
errorMessage: errorMessage,
);
}
}