refactor providers e basi per spedizioni

This commit is contained in:
2026-05-15 10:12:05 +02:00
parent ad35f641b3
commit f19f19a279
21 changed files with 1542 additions and 830 deletions

View File

@@ -1,134 +1,169 @@
import 'package:equatable/equatable.dart';
import 'package:flux/features/master_data/store/models/store_model.dart';
import 'provider_location_model.dart';
import 'provider_role.dart';
class ProviderModel extends Equatable {
final String? id;
final String name;
final bool landline;
final bool mobile;
final bool energy;
final bool insurance;
final bool entertainment;
final bool financing;
final bool telepass;
final bool other;
final bool isActive;
final String companyId;
final List<StoreModel> associatedStores;
final String name; // Nome "commerciale" per riconoscerlo velocemente
final bool isActive;
// Dati fiscali e legali
final String? businessName; // Ragione Sociale
final String? vatNumber; // P.IVA
final String? fiscalCode; // C.F.
final String? sdiCode; // Codice Univoco (SDI)
final String? emailPec;
final String? legalAddress;
final String? legalCity;
final String? legalZip;
final String? legalProvince;
// Ruoli e Sedi (Relazioni)
final List<ProviderRole> roles;
final List<ProviderLocationModel>? locations;
const ProviderModel({
this.id,
required this.name,
required this.landline,
required this.mobile,
required this.energy,
required this.insurance,
required this.entertainment,
required this.financing,
required this.telepass,
required this.other,
required this.isActive,
required this.companyId,
this.associatedStores = const [],
required this.name,
this.isActive = true,
this.businessName,
this.vatNumber,
this.fiscalCode,
this.sdiCode,
this.emailPec,
this.legalAddress,
this.legalCity,
this.legalZip,
this.legalProvince,
this.roles = const [],
this.locations,
});
factory ProviderModel.empty({required String companyId}) {
return ProviderModel(
companyId: companyId,
name: '',
isActive: true,
roles: const [],
);
}
ProviderModel copyWith({
String? id,
String? companyId,
String? name,
bool? isActive,
String? businessName,
String? vatNumber,
String? fiscalCode,
String? sdiCode,
String? emailPec,
String? legalAddress,
String? legalCity,
String? legalZip,
String? legalProvince,
List<ProviderRole>? roles,
List<ProviderLocationModel>? locations,
}) {
return ProviderModel(
id: id ?? this.id,
companyId: companyId ?? this.companyId,
name: name ?? this.name,
isActive: isActive ?? this.isActive,
businessName: businessName ?? this.businessName,
vatNumber: vatNumber ?? this.vatNumber,
fiscalCode: fiscalCode ?? this.fiscalCode,
sdiCode: sdiCode ?? this.sdiCode,
emailPec: emailPec ?? this.emailPec,
legalAddress: legalAddress ?? this.legalAddress,
legalCity: legalCity ?? this.legalCity,
legalZip: legalZip ?? this.legalZip,
legalProvince: legalProvince ?? this.legalProvince,
roles: roles ?? this.roles,
locations: locations ?? this.locations,
);
}
factory ProviderModel.fromMap(Map<String, dynamic> map) {
// Estraiamo la lista dalla pivot e poi prendiamo l'oggetto 'store' annidato
final pivotList = map['associated_stores'] as List?;
List<StoreModel> stores = [];
if (pivotList != null) {
stores = pivotList
.where((item) => item['store'] != null) // Sicurezza
// Parsing sicuro dell'array testuale di Supabase per trasformarlo in Enum
List<ProviderRole> parsedRoles = [];
if (map['roles'] != null) {
final List<dynamic> rawRoles = map['roles'];
for (var r in rawRoles) {
final role = ProviderRole.fromString(r as String);
if (role != null) parsedRoles.add(role);
}
}
// Parsing della JOIN per le locations, se presenti nella query
List<ProviderLocationModel>? parsedLocations;
if (map['provider_locations'] != null) {
parsedLocations = (map['provider_locations'] as List<dynamic>)
.map(
(item) => StoreModel.fromMap(item['store'] as Map<String, dynamic>),
(item) =>
ProviderLocationModel.fromMap(item as Map<String, dynamic>),
)
.toList();
}
return ProviderModel(
id: map['id'],
name: map['name'],
landline: map['landline'] ?? false,
mobile: map['mobile'] ?? false,
energy: map['energy'] ?? false,
insurance: map['insurance'] ?? false,
entertainment: map['entertainment'] ?? false,
financing: map['financing'] ?? false,
telepass: map['telepass'] ?? false,
other: map['other'] ?? false,
isActive: map['is_active'] ?? true,
companyId: map['company_id'],
associatedStores: stores,
id: map['id'] as String,
companyId: map['company_id'] as String,
name: map['name'] as String,
isActive: map['is_active'] as bool? ?? true,
businessName: map['business_name'] as String?,
vatNumber: map['vat_number'] as String?,
fiscalCode: map['fiscal_code'] as String?,
sdiCode: map['sdi_code'] as String?,
emailPec: map['email_pec'] as String?,
legalAddress: map['legal_address'] as String?,
legalCity: map['legal_city'] as String?,
legalZip: map['legal_zip'] as String?,
legalProvince: map['legal_province'] as String?,
roles: parsedRoles,
locations: parsedLocations,
);
}
Map<String, dynamic> toMap() {
final map = {
'name': name,
'landline': landline,
'mobile': mobile,
'energy': energy,
'insurance': insurance,
'entertainment': entertainment,
'financing': financing,
'telepass': telepass,
'other': other,
'is_active': isActive,
return {
if (id != null) 'id': id,
'company_id': companyId,
'name': name,
'is_active': isActive,
'business_name': businessName,
'vat_number': vatNumber,
'fiscal_code': fiscalCode,
'sdi_code': sdiCode,
'email_pec': emailPec,
'legal_address': legalAddress,
'legal_city': legalCity,
'legal_zip': legalZip,
'legal_province': legalProvince,
// Trasformiamo gli Enum di nuovo in stringhe per Supabase
'roles': roles.map((e) => e.name).toList(),
};
// AGGIUNGIAMO L'ID SOLO SE NON È NULLO
// Senza questo, l'upsert non sa dove andare a parare
if (id != null) {
map['id'] = id!;
}
return map;
}
@override
List<Object?> get props => [
id,
name,
landline,
mobile,
energy,
insurance,
entertainment,
financing,
telepass,
other,
isActive,
companyId,
associatedStores,
name,
isActive,
businessName,
vatNumber,
fiscalCode,
sdiCode,
emailPec,
legalAddress,
legalCity,
legalZip,
legalProvince,
roles,
locations,
];
ProviderModel copyWith({
String? id,
String? name,
bool? landline,
bool? mobile,
bool? energy,
bool? insurance,
bool? entertainment,
bool? financing,
bool? telepass,
bool? other,
bool? isActive,
String? companyId,
List<StoreModel>? associatedStores,
}) {
return ProviderModel(
id: id ?? this.id,
name: name ?? this.name,
landline: landline ?? this.landline,
mobile: mobile ?? this.mobile,
energy: energy ?? this.energy,
insurance: insurance ?? this.insurance,
entertainment: entertainment ?? this.entertainment,
financing: financing ?? this.financing,
telepass: telepass ?? this.telepass,
other: other ?? this.other,
isActive: isActive ?? this.isActive,
companyId: companyId ?? this.companyId,
associatedStores: associatedStores ?? this.associatedStores,
);
}
}