renamed services folder to operations

This commit is contained in:
2026-05-01 09:41:48 +02:00
parent a562606613
commit 87b4661d33
29 changed files with 56 additions and 56 deletions

View File

@@ -0,0 +1,72 @@
import 'package:equatable/equatable.dart';
enum EnergyType { luce, gas } // Mappa il tuo public.energy_type
class EnergyServiceModel extends Equatable {
final String? id;
final DateTime? createdAt;
final EnergyType type;
final DateTime expiration;
final String providerId;
final String? serviceId;
const EnergyServiceModel({
this.id,
this.createdAt,
required this.type,
required this.expiration,
required this.providerId,
this.serviceId,
});
EnergyServiceModel copyWith({
String? id,
DateTime? createdAt,
EnergyType? type,
DateTime? expiration,
String? providerId,
String? serviceId,
}) {
return EnergyServiceModel(
id: id ?? this.id,
createdAt: createdAt ?? this.createdAt,
type: type ?? this.type,
expiration: expiration ?? this.expiration,
providerId: providerId ?? this.providerId,
serviceId: serviceId ?? this.serviceId,
);
}
@override
List<Object?> get props => [
id,
createdAt,
type,
expiration,
providerId,
serviceId,
];
factory EnergyServiceModel.fromMap(Map<String, dynamic> map) {
return EnergyServiceModel(
id: map['id'],
createdAt: map['created_at'] != null
? DateTime.parse(map['created_at'])
: null,
type: map['type'] == 'gas' ? EnergyType.gas : EnergyType.luce,
expiration: DateTime.parse(map['expiration']),
providerId: map['provider_id'],
serviceId: map['service_id'],
);
}
Map<String, dynamic> toMap() {
return {
if (id != null) 'id': id,
'type': type.name, // .name trasforma l'enum in 'luce' o 'gas'
'expiration': expiration.toIso8601String(),
'provider_id': providerId,
'service_id': serviceId,
};
}
}

View File

@@ -0,0 +1,77 @@
import 'package:equatable/equatable.dart';
class EntertainmentServiceModel extends Equatable {
final String? id;
final DateTime? createdAt;
final String type; // es. Sky, DAZN, ecc.
final bool constrained; // Vincolato?
final DateTime constrainExpiration;
final String? serviceId;
final String? providerId;
const EntertainmentServiceModel({
this.id,
this.createdAt,
required this.type,
required this.constrained,
required this.constrainExpiration,
this.serviceId,
this.providerId,
});
EntertainmentServiceModel copyWith({
String? id,
DateTime? createdAt,
String? type,
bool? constrained,
DateTime? constrainExpiration,
String? serviceId,
String? providerId,
}) {
return EntertainmentServiceModel(
id: id ?? this.id,
createdAt: createdAt ?? this.createdAt,
type: type ?? this.type,
constrained: constrained ?? this.constrained,
constrainExpiration: constrainExpiration ?? this.constrainExpiration,
serviceId: serviceId ?? this.serviceId,
providerId: providerId ?? this.providerId,
);
}
@override
List<Object?> get props => [
id,
createdAt,
type,
constrained,
constrainExpiration,
serviceId,
providerId,
];
factory EntertainmentServiceModel.fromMap(Map<String, dynamic> map) {
return EntertainmentServiceModel(
id: map['id'],
createdAt: map['created_at'] != null
? DateTime.parse(map['created_at'])
: null,
type: map['type'],
constrained: map['constrained'] ?? false,
constrainExpiration: DateTime.parse(map['constrain_expiration']),
serviceId: map['service_id'],
providerId: map['provider_id'],
);
}
Map<String, dynamic> toMap() {
return {
if (id != null) 'id': id,
'type': type,
'constrained': constrained,
'constrain_expiration': constrainExpiration.toIso8601String(),
'service_id': serviceId,
'provider_id': providerId,
};
}
}

View File

@@ -0,0 +1,63 @@
import 'package:equatable/equatable.dart';
class FinServiceModel extends Equatable {
final String? id;
final DateTime? createdAt;
final DateTime expiration;
final String? serviceId;
final String? modelId; // FK verso model (es. iPhone, Samsung, ecc.)
final String? providerId;
const FinServiceModel({
this.id,
this.createdAt,
required this.expiration,
this.serviceId,
this.modelId,
this.providerId,
});
FinServiceModel copyWith({
String? id,
DateTime? createdAt,
DateTime? expiration,
String? serviceId,
String? modelId,
String? providerId,
}) {
return FinServiceModel(
id: id ?? this.id,
createdAt: createdAt ?? this.createdAt,
expiration: expiration ?? this.expiration,
serviceId: serviceId ?? this.serviceId,
modelId: modelId ?? this.modelId,
providerId: providerId ?? this.providerId,
);
}
@override
List<Object?> get props => [id, createdAt, expiration, serviceId, modelId];
factory FinServiceModel.fromMap(Map<String, dynamic> map) {
return FinServiceModel(
id: map['id'],
createdAt: map['created_at'] != null
? DateTime.parse(map['created_at'])
: null,
expiration: DateTime.parse(map['expiration']),
serviceId: map['service_id'],
modelId: map['model_id'],
providerId: map['provider_id'],
);
}
Map<String, dynamic> toMap() {
return {
if (id != null) 'id': id,
'expiration': expiration.toIso8601String(),
'service_id': serviceId,
'model_id': modelId,
'provider_id': providerId,
};
}
}

View File

@@ -0,0 +1,100 @@
import 'dart:typed_data';
import 'package:equatable/equatable.dart';
class ServiceFileModel extends Equatable {
final String? id;
final DateTime? createdAt;
final String name;
final String extension;
final String storagePath;
final String serviceId;
final int fileSize;
final Uint8List? localBytes;
const ServiceFileModel({
this.id,
this.createdAt,
required this.name,
required this.extension,
required this.storagePath,
required this.serviceId,
required this.fileSize,
this.localBytes,
});
bool get isLocal => localBytes != null;
// Trasforma i byte in qualcosa di leggibile (KB, MB, GB)
String get sizeFormatted {
if (fileSize <= 0) return "0 B";
const suffixes = ["B", "KB", "MB", "GB", "TB"];
var i = (fileSize.toString().length - 1) ~/ 3;
if (i >= suffixes.length) i = suffixes.length - 1;
double num = fileSize / (1 << (i * 10));
return "${num.toStringAsFixed(i == 0 ? 0 : 1)} ${suffixes[i]}";
}
bool get isPdf => extension.toLowerCase().replaceAll('.', '') == 'pdf';
ServiceFileModel copyWith({
String? id,
DateTime? createdAt,
String? name,
String? extension,
String? storagePath,
String? serviceId,
int? fileSize,
Uint8List? localBytes,
}) {
return ServiceFileModel(
id: id ?? this.id,
createdAt: createdAt ?? this.createdAt,
name: name ?? this.name,
extension: extension ?? this.extension,
storagePath: storagePath ?? this.storagePath,
serviceId: serviceId ?? this.serviceId,
fileSize: fileSize ?? this.fileSize,
localBytes: localBytes ?? this.localBytes,
);
}
factory ServiceFileModel.fromMap(Map<String, dynamic> map) {
return ServiceFileModel(
id: map['id'] as String,
createdAt: map['created_at'] != null
? DateTime.parse(map['created_at'])
: null,
name: map['name'] ?? '',
extension: map['extension'] ?? '',
storagePath: map['storage_path'] ?? '',
serviceId: map['service_id']?.toString() ?? '',
fileSize: map['file_size'] is int
? map['file_size']
: int.tryParse(map['file_size']?.toString() ?? '0') ?? 0,
);
}
Map<String, dynamic> toMap() {
return {
if (id != null) 'id': id,
'name': name,
'extension': extension,
'storage_path': storagePath,
'service_id': serviceId,
'file_size': fileSize,
};
}
@override
List<Object?> get props => [
id,
createdAt,
name,
extension,
storagePath,
serviceId,
fileSize,
localBytes,
];
}

View File

@@ -0,0 +1,200 @@
import 'package:equatable/equatable.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/features/operations/models/energy_service_model.dart';
import 'package:flux/features/operations/models/entertainment_service_model.dart';
import 'package:flux/features/operations/models/fin_service_model.dart';
import 'package:flux/features/operations/models/service_file_model.dart'; // <-- Aggiunto Import
class ServiceModel extends Equatable {
final String? id;
final DateTime? createdAt;
final String storeId;
final String? employeeId;
final String? customerId;
final String number;
final bool isBozza;
final String note;
final bool resultOk;
final String? customerDisplayName;
final String companyId;
// Telefonia
final int al;
final int mnp;
final int nip;
final int unica;
final int telepass;
// Moduli (Liste)
final List<EnergyServiceModel> energyServices;
final List<FinServiceModel> finServices;
final List<EntertainmentServiceModel> entertainmentServices;
// ALLEGATI (Aggiunto)
final List<ServiceFileModel> files;
const ServiceModel({
this.id,
this.createdAt,
required this.storeId,
this.employeeId,
this.customerId,
required this.number,
this.isBozza = true,
this.note = '',
this.resultOk = true,
this.al = 0,
this.mnp = 0,
this.nip = 0,
this.unica = 0,
this.telepass = 0,
this.energyServices = const [],
this.finServices = const [],
this.entertainmentServices = const [],
this.files = const [], // <-- Aggiunto default vuoto
this.customerDisplayName,
required this.companyId,
});
ServiceModel copyWith({
String? id,
DateTime? createdAt,
String? storeId,
String? employeeId,
String? customerId,
String? number,
bool? isBozza,
String? note,
bool? resultOk,
int? al,
int? mnp,
int? nip,
int? unica,
int? telepass,
List<EnergyServiceModel>? energyServices,
List<FinServiceModel>? finServices,
List<EntertainmentServiceModel>? entertainmentServices,
List<ServiceFileModel>? files, // <-- Aggiunto
String? customerDisplayName,
String? companyId,
}) {
return ServiceModel(
id: id ?? this.id,
createdAt: createdAt ?? this.createdAt,
storeId: storeId ?? this.storeId,
employeeId: employeeId ?? this.employeeId,
customerId: customerId ?? this.customerId,
number: number ?? this.number,
isBozza: isBozza ?? this.isBozza,
note: note ?? this.note,
resultOk: resultOk ?? this.resultOk,
al: al ?? this.al,
mnp: mnp ?? this.mnp,
nip: nip ?? this.nip,
unica: unica ?? this.unica,
telepass: telepass ?? this.telepass,
energyServices: energyServices ?? this.energyServices,
finServices: finServices ?? this.finServices,
entertainmentServices:
entertainmentServices ?? this.entertainmentServices,
files: files ?? this.files, // <-- Aggiunto
customerDisplayName: customerDisplayName ?? this.customerDisplayName,
companyId: companyId ?? this.companyId,
);
}
@override
List<Object?> get props => [
id,
createdAt,
storeId,
employeeId,
customerId,
number,
isBozza,
note,
resultOk,
al,
mnp,
nip,
unica,
telepass,
energyServices,
finServices,
entertainmentServices,
files, // <-- Aggiunto
customerDisplayName,
companyId,
];
factory ServiceModel.fromMap(Map<String, dynamic> map) {
return ServiceModel(
id: map['id'].toString(),
createdAt: map['created_at'] != null
? DateTime.parse(map['created_at'])
: DateTime.now(),
storeId: map['store_id'] ?? '',
employeeId: map['employee_id']?.toString(),
customerId: map['customer_id']?.toString(),
number: map['number']?.toString() ?? '',
isBozza: map['bozza'] ?? true,
note: map['note'] ?? '',
resultOk: map['result_ok'] ?? true,
al: map['al'] ?? 0,
mnp: map['mnp'] ?? 0,
nip: map['nip'] ?? 0,
unica: map['unica'] ?? 0,
telepass: map['telepass'] ?? 0,
// Estrazione sicura liste collegate
energyServices:
(map['energy_service'] as List?)
?.map((x) => EnergyServiceModel.fromMap(x))
.toList() ??
const [],
finServices:
(map['fin_service'] as List?)
?.map((x) => FinServiceModel.fromMap(x))
.toList() ??
const [],
entertainmentServices:
(map['entertainment_service'] as List?)
?.map((x) => EntertainmentServiceModel.fromMap(x))
.toList() ??
const [],
// I FILE! (Assicurati che la foreign key su Supabase usi esattamente questo nome)
files:
(map['service_file'] as List?)
?.map((x) => ServiceFileModel.fromMap(x))
.toList() ??
const [],
// Display name del cliente con fallback
customerDisplayName: map['customer'] != null
? "${map['customer']['nome'] ?? ''}".myFormat()
: "Cliente non assegnato",
companyId: map['company_id'] as String,
);
}
Map<String, dynamic> toMap() {
return {
if (id != null) 'id': id,
'store_id': storeId,
'employee_id': employeeId,
'customer_id': customerId,
'number': number,
'bozza': isBozza,
'note': note,
'result_ok': resultOk,
'al': al,
'mnp': mnp,
'nip': nip,
'unica': unica,
'telepass': telepass,
'company_id': companyId,
// Le liste non le mettiamo qui perché vanno in tabelle diverse!
};
}
}