refactor providers e basi per spedizioni
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
class ProviderLocationModel extends Equatable {
|
||||
final String? id;
|
||||
final String providerId;
|
||||
final String companyId;
|
||||
final String name; // Es: "Laboratorio Centrale"
|
||||
final String address;
|
||||
final String city;
|
||||
final String zipCode;
|
||||
final String province;
|
||||
final String? contactPerson;
|
||||
final bool isMain;
|
||||
|
||||
const ProviderLocationModel({
|
||||
this.id,
|
||||
required this.providerId,
|
||||
required this.companyId,
|
||||
required this.name,
|
||||
required this.address,
|
||||
required this.city,
|
||||
required this.zipCode,
|
||||
required this.province,
|
||||
this.contactPerson,
|
||||
this.isMain = false,
|
||||
});
|
||||
|
||||
factory ProviderLocationModel.empty() {
|
||||
return const ProviderLocationModel(
|
||||
providerId: '',
|
||||
companyId: '',
|
||||
name: '',
|
||||
address: '',
|
||||
city: '',
|
||||
zipCode: '',
|
||||
province: '',
|
||||
);
|
||||
}
|
||||
|
||||
ProviderLocationModel copyWith({
|
||||
String? id,
|
||||
String? providerId,
|
||||
String? companyId,
|
||||
String? name,
|
||||
String? address,
|
||||
String? city,
|
||||
String? zipCode,
|
||||
String? province,
|
||||
String? contactPerson,
|
||||
bool? isMain,
|
||||
}) {
|
||||
return ProviderLocationModel(
|
||||
id: id ?? this.id,
|
||||
providerId: providerId ?? this.providerId,
|
||||
companyId: companyId ?? this.companyId,
|
||||
name: name ?? this.name,
|
||||
address: address ?? this.address,
|
||||
city: city ?? this.city,
|
||||
zipCode: zipCode ?? this.zipCode,
|
||||
province: province ?? this.province,
|
||||
contactPerson: contactPerson ?? this.contactPerson,
|
||||
isMain: isMain ?? this.isMain,
|
||||
);
|
||||
}
|
||||
|
||||
factory ProviderLocationModel.fromMap(Map<String, dynamic> map) {
|
||||
return ProviderLocationModel(
|
||||
id: map['id'] as String,
|
||||
providerId: map['provider_id'] as String,
|
||||
companyId: map['company_id'] as String,
|
||||
name: map['name'] as String,
|
||||
address: map['address'] as String,
|
||||
city: map['city'] as String,
|
||||
zipCode: map['zip_code'] as String,
|
||||
province: map['province'] as String,
|
||||
contactPerson: map['contact_person'] as String?,
|
||||
isMain: map['is_main'] as bool? ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
if (id != null) 'id': id,
|
||||
'provider_id': providerId,
|
||||
'company_id': companyId,
|
||||
'name': name,
|
||||
'address': address,
|
||||
'city': city,
|
||||
'zip_code': zipCode,
|
||||
'province': province,
|
||||
'contact_person': contactPerson,
|
||||
'is_main': isMain,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
id,
|
||||
providerId,
|
||||
companyId,
|
||||
name,
|
||||
address,
|
||||
city,
|
||||
zipCode,
|
||||
province,
|
||||
contactPerson,
|
||||
isMain,
|
||||
];
|
||||
}
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
28
lib/features/master_data/providers/models/provider_role.dart
Normal file
28
lib/features/master_data/providers/models/provider_role.dart
Normal file
@@ -0,0 +1,28 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
enum ProviderRole {
|
||||
landline('Fisso', Colors.blue),
|
||||
mobile('Mobile', Colors.green),
|
||||
energy('Energia', Colors.orange),
|
||||
insurance('Assicurazioni', Colors.purple),
|
||||
financing('Finanziamenti', Colors.teal),
|
||||
entertainment('Intrattenimento', Colors.red),
|
||||
telepass('Telepass', Colors.amber),
|
||||
repairCenter('Centro Riparazioni', Colors.cyan),
|
||||
partsSupplier('Fornitore Ricambi', Colors.indigo),
|
||||
merchandiseSupplier('Fornitore Merce', Colors.brown);
|
||||
|
||||
final String displayValue;
|
||||
final Color color; // <-- Il nostro tocco magico
|
||||
|
||||
const ProviderRole(this.displayValue, this.color);
|
||||
|
||||
static ProviderRole? fromString(String? value) {
|
||||
if (value == null) return null;
|
||||
try {
|
||||
return ProviderRole.values.firstWhere((e) => e.name == value);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user