import 'package:equatable/equatable.dart'; import 'package:flux/core/enums_and_consts/consts.dart'; import 'package:flux/core/utils/extensions.dart'; import 'package:flux/features/attachments/models/attachment_model.dart'; import 'package:flux/features/customers/models/customer_model.dart'; enum OperationStatus { success('success', 'OK'), waitingForAction('waiting_for_action', 'In attesa di azione'), waitingForSupport('waiting_for_support', 'In attesa di supporto'), failure('failure', 'KO'), draft('draft', 'Bozza'); static OperationStatus fromString(String value) { final normalizedValue = value.replaceAll('_', '').toLowerCase(); return OperationStatus.values.firstWhere( (e) => e.name.toLowerCase() == normalizedValue, ); } final String supabaseName; final String displayName; const OperationStatus(this.supabaseName, this.displayName); } class OperationModel extends Equatable { final String? id; final DateTime? createdAt; final String type; final String? subtype; final String? providerId; final String? providerDisplayName; final String? modelId; final String? modelDisplayName; final String? description; final DateTime? expirationDate; final String note; final bool showInDashboard; final String batchUuid; final String companyId; final String storeId; final String? storeDisplayName; final int quantity; final String? staffId; final String? staffDisplayName; final String? lastCampaignId; final OperationStatus status; final String? customerId; final CustomerModel? customer; final String reference; final bool isBusiness; // ALLEGATI (Aggiunto) final List attachments; const OperationModel({ this.id, this.createdAt, this.type = '', this.subtype, this.providerId, this.providerDisplayName, this.modelId, this.modelDisplayName, this.description, this.expirationDate, this.note = '', this.showInDashboard = true, this.batchUuid = '', required this.companyId, this.storeId = '', this.storeDisplayName, this.quantity = 1, this.staffId, this.staffDisplayName, this.lastCampaignId, this.status = OperationStatus.draft, this.customerId, this.customer, this.reference = '', this.attachments = const [], this.isBusiness = false, }); OperationModel copyWith({ String? id, DateTime? createdAt, String? type, String? subtype, String? providerId, String? providerDisplayName, String? modelId, String? modelDisplayName, String? description, DateTime? expirationDate, String? note, bool? showInDashboard, String? batchUuid, String? companyId, String? storeId, String? storeDisplayName, int? quantity, String? staffId, String? staffDisplayName, String? lastCampaignId, OperationStatus? status, String? customerId, CustomerModel? customer, String? reference, List? attachments, bool? isBusiness, }) => OperationModel( id: id ?? this.id, createdAt: createdAt ?? this.createdAt, type: type ?? this.type, subtype: subtype ?? this.subtype, providerId: providerId ?? this.providerId, providerDisplayName: providerDisplayName ?? this.providerDisplayName, modelId: modelId ?? this.modelId, modelDisplayName: modelDisplayName ?? this.modelDisplayName, description: description ?? this.description, expirationDate: expirationDate ?? this.expirationDate, note: note ?? this.note, showInDashboard: showInDashboard ?? this.showInDashboard, batchUuid: batchUuid ?? this.batchUuid, companyId: companyId ?? this.companyId, storeId: storeId ?? this.storeId, storeDisplayName: storeDisplayName ?? this.storeDisplayName, quantity: quantity ?? this.quantity, staffId: staffId ?? this.staffId, staffDisplayName: staffDisplayName ?? this.staffDisplayName, lastCampaignId: lastCampaignId ?? this.lastCampaignId, status: status ?? this.status, customerId: customerId ?? this.customerId, customer: customer ?? this.customer, reference: reference ?? this.reference, attachments: attachments ?? this.attachments, isBusiness: isBusiness ?? this.isBusiness, ); @override List get props => [ id, createdAt, type, subtype, providerId, providerDisplayName, modelId, modelDisplayName, description, expirationDate, note, showInDashboard, batchUuid, companyId, storeId, storeDisplayName, quantity, staffId, staffDisplayName, lastCampaignId, status, customerId, customer, reference, attachments, isBusiness, ]; factory OperationModel.empty() { return OperationModel(id: null, createdAt: null, companyId: ''); } factory OperationModel.fromMap(Map map) { return OperationModel( id: map['id'] as String?, createdAt: map['created_at'] != null ? DateTime.parse(map['created_at']) : null, type: map['type'] as String? ?? '', subtype: map['sub_type'] as String?, // I campi relazionali nullabili restano rigorosamente null! providerId: map['provider_id'] as String?, // MAGIA ANTI-CRASH: Usiamo ?['chiave'] per non far esplodere i join vuoti providerDisplayName: (map[Tables.providers]?['name'] as String?) ?.myFormat(), modelId: map['model_id'] as String?, modelDisplayName: (map[Tables.models]?['name_with_brand'] as String?) ?.myFormat(), description: map['description'] as String?, expirationDate: map['expiration_date'] != null ? DateTime.parse(map['expiration_date']) : null, note: map['note'] as String? ?? '', showInDashboard: map['show_in_dashboard'] as bool? ?? true, batchUuid: map['batch_uuid'] as String? ?? '', companyId: map['company_id'] as String, storeId: map['store_id'] as String? ?? '', // Questo รจ non-nullable nella tua classe storeDisplayName: (map[Tables.stores]?['name'] as String?)?.myFormat(), quantity: map['quantity'] is int ? map['quantity'] : int.tryParse(map['quantity']?.toString() ?? '1') ?? 1, staffId: map['staff_id'] as String?, staffDisplayName: (map[Tables.staffMembers]?['name'] as String?) ?.myFormat(), lastCampaignId: map['last_campaign_id'] as String?, status: OperationStatus.fromString(map['status'] ?? 'draft'), customerId: map['customer_id'] as String?, customer: map[Tables.customers] != null ? CustomerModel.fromMap(map[Tables.customers] as Map) : null, attachments: (map[Tables.attachments] as List?) ?.map((x) => AttachmentModel.fromMap(x)) .toList() ?? const [], reference: map['reference'] as String? ?? '', isBusiness: map['is_business'] as bool? ?? false, ); } Map toMap() { return { if (id != null) 'id': id, 'type': type, 'sub_type': subtype, 'provider_id': providerId, 'model_id': modelId, 'description': description, if (expirationDate != null) 'expiration_date': expirationDate!.toIso8601String(), 'note': note, 'show_in_dashboard': showInDashboard, 'batch_uuid': batchUuid, 'company_id': companyId, 'store_id': storeId, 'quantity': quantity, if (staffId != null) 'staff_id': staffId, if (lastCampaignId != null) 'last_campaign_id': lastCampaignId, 'status': status.supabaseName, if (customerId != null) 'customer_id': customerId, 'reference': reference, 'is_business': isBusiness, }; } }