Files
flux/lib/features/services/data/services_repository.dart
Mark M2 Macbook 5229571fa1 service (#2)
Reviewed-on: http://catelliub.zapto.org:3000/brontomark/flux/pulls/2
Co-authored-by: Mark M2 Macbook <marco@catelli.it>
Co-committed-by: Mark M2 Macbook <marco@catelli.it>
2026-04-16 11:50:29 +02:00

119 lines
3.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import '../models/service_model.dart';
class ServicesRepository {
final _supabase = Supabase.instance.client;
// --- RECUPERO PAGINATO CON FILTRI E JOIN ---
Future<List<ServiceModel>> fetchServices({
required String companyId,
required int offset,
int limit = 50,
String? searchTerm,
DateTimeRange? dateRange,
}) async {
try {
// Nota: 'customer(name, surname)' serve per il display name nella card
var query = _supabase
.from('service')
.select('''
*,
customer(name, surname),
energy_service(*),
fin_service(*),
entertainment_service(*)
''')
.eq('company_id', companyId);
// Filtro Range Date
if (dateRange != null) {
query = query
.gte('created_at', dateRange.start.toIso8601String())
.lte('created_at', dateRange.end.toIso8601String());
}
if (searchTerm != null && searchTerm.isNotEmpty) {
// Filtra sui campi della tabella principale O su quelli della tabella joinata
query = query.or(
'number.ilike.%$searchTerm%,note.ilike.%$searchTerm%,customer.name.ilike.%$searchTerm%,customer.surname.ilike.%$searchTerm%',
);
}
final response = await query
.order('created_at', ascending: false)
.range(offset, offset + limit - 1);
return (response as List)
.map((map) => ServiceModel.fromMap(map))
.toList();
} catch (e) {
throw Exception('Errore nel caricamento servizi: $e');
}
}
// --- SALVATAGGIO COMPLETO (PRIMA PADRE, POI FIGLI) ---
Future<void> saveFullService(ServiceModel service) async {
try {
// 1. Inseriamo il record principale
// Se service.id è null, Supabase fa INSERT. Se c'è, fa UPDATE (grazie all'upsert o gestione manuale)
final serviceData = await _supabase
.from('service')
.upsert(service.toMap())
.select()
.single();
final String newId = serviceData['id'];
// 2. Pulizia vecchi record figli (necessaria se è una MODIFICA)
// Se stiamo modificando, cancelliamo i vecchi per reinserire i nuovi (più semplice)
if (service.id != null) {
await _supabase.from('energy_service').delete().eq('service_id', newId);
await _supabase.from('fin_service').delete().eq('service_id', newId);
await _supabase
.from('entertainment_service')
.delete()
.eq('service_id', newId);
}
// 3. Inserimento EnergyServices
if (service.energyServices.isNotEmpty) {
final List<Map<String, dynamic>> toInsert = [];
for (var item in service.energyServices) {
toInsert.add(item.copyWith(serviceId: newId).toMap());
}
await _supabase.from('energy_service').insert(toInsert);
}
// 4. Inserimento FinServices
if (service.finServices.isNotEmpty) {
final List<Map<String, dynamic>> toInsert = [];
for (var item in service.finServices) {
toInsert.add(item.copyWith(serviceId: newId).toMap());
}
await _supabase.from('fin_service').insert(toInsert);
}
// 5. Inserimento EntertainmentServices
if (service.entertainmentServices.isNotEmpty) {
final List<Map<String, dynamic>> toInsert = [];
for (var item in service.entertainmentServices) {
toInsert.add(item.copyWith(serviceId: newId).toMap());
}
await _supabase.from('entertainment_service').insert(toInsert);
}
} catch (e) {
throw Exception('Errore durante il salvataggio: $e');
}
}
// --- ELIMINAZIONE ---
Future<void> deleteService(String id) async {
try {
await _supabase.from('service').delete().eq('id', id);
} catch (e) {
throw Exception('Errore durante l\'eliminazione: $e');
}
}
}