This commit is contained in:
2026-05-06 19:25:17 +02:00
parent d15d7e458b
commit 040db4ad79
8 changed files with 60 additions and 53 deletions

View File

@@ -34,7 +34,7 @@ class TicketFormCubit extends Cubit<TicketFormState> {
createdById: currentUser?.id,
createdByName: currentUser?.name,
// Impostiamo lo stato iniziale
status: TicketStatus.open,
ticketStatus: TicketStatus.open,
ticketType: TicketType.repair, // Default
);
@@ -98,7 +98,7 @@ class TicketFormCubit extends Cubit<TicketFormState> {
state.copyWith(
ticket: state.ticket.copyWith(
ticketType: ticketType ?? state.ticket.ticketType,
status: status ?? state.ticket.status,
ticketStatus: status ?? state.ticket.ticketStatus,
request: request ?? state.ticket.request,
targetSn: targetSn ?? state.ticket.targetSn,
alternativePhoneNumber:
@@ -143,7 +143,7 @@ class TicketFormCubit extends Cubit<TicketFormState> {
createdById: ticketToSave
.createdById, // Manteniamo quello selezionato nella tendina!
createdByName: ticketToSave.createdByName,
status: TicketStatus.open,
ticketStatus: TicketStatus.open,
ticketType: TicketType.repair,
),
),

View File

@@ -27,7 +27,8 @@ class TicketRepository {
.select('''
*,
customer (*),
staff_member (*),
created_by:staff_member!ticket_staff_id_fkey (*),
assigned_to:staff_member!ticket_assigned_to_id_fkey (*),
target_model:model!ticket_model_id_1_fkey (*),
source_model:model!ticket_model_id_2_fkey (*)
''')
@@ -83,7 +84,8 @@ class TicketRepository {
.select('''
*,
customer (*),
staff_member (*),
created_by:staff_member!ticket_staff_id_fkey (*),
assigned_to:staff_member!ticket_assigned_to_id_fkey (*),
target_model:model!ticket_model_id_1_fkey (*),
source_model:model!ticket_model_id_2_fkey (*)
''')
@@ -144,8 +146,8 @@ class TicketRepository {
// 2. Filtriamo in memoria!
final urgentTickets = allStoreTickets.where((ticket) {
// Escludiamo quelli già chiusi o consegnati
if (ticket.status == TicketStatus.closed ||
ticket.status == TicketStatus.ready) {
if (ticket.ticketStatus == TicketStatus.closed ||
ticket.ticketStatus == TicketStatus.ready) {
return false;
}
@@ -178,7 +180,8 @@ class TicketRepository {
customer (*),
target_model:model!ticket_model_id_1_fkey (*),
source_model:model!ticket_model_id_2_fkey (*),
staff:staff_member!ticket_staff_id_fkey (*)
created_by:staff_member!ticket_staff_id_fkey (*),
assigned_to:staff_member!ticket_assigned_to_id_fkey (*),
''')
.eq('id', ticketId)
.single();

View File

@@ -35,8 +35,7 @@ enum TicketStatus {
final String displayValue;
const TicketStatus(this.value, this.displayValue);
static TicketStatus? fromString(String? val) {
if (val == null) return null;
static TicketStatus fromString(String? val) {
return TicketStatus.values.firstWhere(
(e) => e.value == val,
orElse: () => TicketStatus.open,
@@ -103,9 +102,9 @@ class TicketModel extends Equatable {
final String? alternativePhoneNumber;
final bool hasCourtesyDevice;
final TicketType ticketType;
final TicketStatus? status;
final TicketStatus ticketStatus;
final DateTime? estimatedDeliveryAt;
final TicketResult? result;
final TicketResult? ticketResult;
final String? resolutionNotes;
final String? legacyId;
final String? customerName;
@@ -139,9 +138,9 @@ class TicketModel extends Equatable {
this.alternativePhoneNumber,
this.hasCourtesyDevice = false,
required this.ticketType,
this.status,
this.ticketStatus = TicketStatus.closed,
this.estimatedDeliveryAt,
this.result,
this.ticketResult,
this.resolutionNotes,
this.legacyId,
this.customerName,
@@ -160,7 +159,7 @@ class TicketModel extends Equatable {
companyId: companyId ?? '',
storeId: storeId,
ticketType: TicketType.repair, // Valore di default
status: TicketStatus.open,
ticketStatus: TicketStatus.open,
customerPrice: 0.0,
internalCost: 0.0,
hasCourtesyDevice: false,
@@ -190,9 +189,9 @@ class TicketModel extends Equatable {
String? alternativePhoneNumber,
bool? hasCourtesyDevice,
TicketType? ticketType,
TicketStatus? status,
TicketStatus? ticketStatus,
DateTime? estimatedDeliveryAt,
TicketResult? result,
TicketResult? ticketResult,
String? resolutionNotes,
String? legacyId,
String? customerName,
@@ -227,9 +226,9 @@ class TicketModel extends Equatable {
alternativePhoneNumber ?? this.alternativePhoneNumber,
hasCourtesyDevice: hasCourtesyDevice ?? this.hasCourtesyDevice,
ticketType: ticketType ?? this.ticketType,
status: status ?? this.status,
ticketStatus: ticketStatus ?? this.ticketStatus,
estimatedDeliveryAt: estimatedDeliveryAt ?? this.estimatedDeliveryAt,
result: result ?? this.result,
ticketResult: ticketResult ?? this.ticketResult,
resolutionNotes: resolutionNotes ?? this.resolutionNotes,
legacyId: legacyId ?? this.legacyId,
customerName: customerName ?? this.customerName,
@@ -274,11 +273,11 @@ class TicketModel extends Equatable {
alternativePhoneNumber: map['alternative_phone_number'] as String?,
hasCourtesyDevice: map['has_courtesy_device'] as bool? ?? false,
ticketType: TicketType.fromString(map['ticket_type'] as String),
status: TicketStatus.fromString(map['status'] as String?),
ticketStatus: TicketStatus.fromString(map['ticket_status'] as String),
estimatedDeliveryAt: map['estimated_delivery_at'] != null
? DateTime.parse(map['estimated_delivery_at']).toLocal()
: null,
result: TicketResult.fromString(map['result'] as String?),
ticketResult: TicketResult.fromString(map['ticket_result'] as String?),
resolutionNotes: map['resolution_notes'] as String?,
legacyId: map['legacy_id'] as String?,
customerName: (map['customer']?['name'] as String?).myFormat(),
@@ -318,10 +317,10 @@ class TicketModel extends Equatable {
'alternative_phone_number': alternativePhoneNumber,
'has_courtesy_device': hasCourtesyDevice,
'ticket_type': ticketType.value,
if (status != null) 'status': status!.value,
'ticket_status': ticketStatus.value,
if (estimatedDeliveryAt != null)
'estimated_delivery_at': estimatedDeliveryAt!.toUtc().toIso8601String(),
if (result != null) 'result': result!.value,
if (ticketResult != null) 'ticket_result': ticketResult!.value,
'resolution_notes': resolutionNotes,
'legacy_id': legacyId,
'included_accessories': includedAccessories,
@@ -351,9 +350,9 @@ class TicketModel extends Equatable {
alternativePhoneNumber,
hasCourtesyDevice,
ticketType,
status,
ticketStatus,
estimatedDeliveryAt,
result,
ticketResult,
resolutionNotes,
legacyId,
includedAccessories,

View File

@@ -5,7 +5,8 @@ import 'package:flux/features/tickets/blocs/ticket_form_state.dart';
import 'package:flux/features/tickets/models/ticket_model.dart';
import 'package:flux/core/widgets/shared_forms/shared_customer_section.dart';
import 'package:flux/core/widgets/shared_forms/shared_model_section.dart';
import 'package:flux/core/widgets/shared_forms/shared_staff_section.dart'; // Il tuo widget agnostico dello staff
import 'package:flux/core/widgets/shared_forms/shared_staff_section.dart';
import 'package:flux/features/tickets/models/ticket_status_extension.dart'; // Il tuo widget agnostico dello staff
class TicketFormScreen extends StatefulWidget {
final TicketModel? existingTicket;
@@ -53,20 +54,26 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
// Sincronizza i controller con lo stato iniziale senza sovrascrivere se l'utente sta digitando
void _syncTextControllers(TicketModel model) {
if (_altPhoneCtrl.text.isEmpty)
if (_altPhoneCtrl.text.isEmpty) {
_altPhoneCtrl.text = model.alternativePhoneNumber ?? '';
}
if (_serialCtrl.text.isEmpty) _serialCtrl.text = model.targetSn ?? '';
if (_requestCtrl.text.isEmpty) _requestCtrl.text = model.request ?? '';
if (_accessoriesCtrl.text.isEmpty)
if (_requestCtrl.text.isEmpty) _requestCtrl.text = model.request;
if (_accessoriesCtrl.text.isEmpty) {
_accessoriesCtrl.text = model.includedAccessories ?? '';
if (_publicNotesCtrl.text.isEmpty)
}
if (_publicNotesCtrl.text.isEmpty) {
_publicNotesCtrl.text = model.publicNotes ?? '';
if (_internalNotesCtrl.text.isEmpty)
}
if (_internalNotesCtrl.text.isEmpty) {
_internalNotesCtrl.text = model.internalNotes ?? '';
if (_priceCtrl.text.isEmpty && model.customerPrice > 0)
}
if (_priceCtrl.text.isEmpty && model.customerPrice > 0) {
_priceCtrl.text = model.customerPrice.toString();
if (_costCtrl.text.isEmpty && model.internalCost > 0)
}
if (_costCtrl.text.isEmpty && model.internalCost > 0) {
_costCtrl.text = model.internalCost.toString();
}
_isInitialized = true;
}
@@ -143,10 +150,10 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
padding: const EdgeInsets.only(right: 16.0),
child: Chip(
label: Text(
ticket.status.name.toUpperCase(),
ticket.ticketStatus!.name.toUpperCase(),
style: const TextStyle(color: Colors.white, fontSize: 10),
),
backgroundColor: ticket.status.color,
backgroundColor: ticket.ticketStatus.color,
),
),
],
@@ -174,7 +181,7 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
staffName: ticket.createdByName,
onStaffSelected: (staff) =>
context.read<TicketFormCubit>().updateCreator(
staffId: staff.id,
staffId: staff.id!,
staffName: staff.name,
),
),
@@ -254,7 +261,7 @@ class _TicketFormScreenState extends State<TicketFormScreen> {
const SizedBox(width: 16),
Expanded(
child: DropdownButtonFormField<TicketStatus>(
value: ticket.status,
value: ticket.ticketStatus,
decoration: const InputDecoration(
labelText: 'Stato Attuale',
),

View File

@@ -192,8 +192,8 @@ class _TicketCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
final statusColor = ticket.status?.color ?? Colors.grey;
final statusIcon = ticket.status?.icon ?? Icons.help_outline;
final statusColor = ticket.ticketStatus.color;
final statusIcon = ticket.ticketStatus.icon;
return Card(
margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
@@ -244,7 +244,7 @@ class _TicketCard extends StatelessWidget {
Icon(statusIcon, size: 14, color: statusColor),
const SizedBox(width: 4),
Text(
ticket.status?.displayValue ?? 'N/D',
ticket.ticketStatus.displayValue,
style: TextStyle(
fontSize: 12,
color: statusColor,