@@ -3,9 +3,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flux/core/blocs/session/session_cubit.dart';
|
||||
import 'package:flux/core/utils/extensions.dart';
|
||||
import 'package:flux/features/attachments/models/attachment_model.dart';
|
||||
import 'package:flux/features/customers/data/customer_repository.dart';
|
||||
import 'package:flux/features/customers/models/customer_file_model.dart';
|
||||
import 'package:flux/features/operations/models/operation_file_model.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
import '../models/operation_model.dart';
|
||||
@@ -13,7 +10,6 @@ import '../models/operation_model.dart';
|
||||
class OperationsRepository {
|
||||
final _supabase = Supabase.instance.client;
|
||||
final companyId = GetIt.I.get<SessionCubit>().state.company!.id;
|
||||
final CustomerRepository _customerRepository = GetIt.I<CustomerRepository>();
|
||||
|
||||
// --- RECUPERO SINGOLO SERVIZIO CON JOIN COMPLETO ---
|
||||
Future<OperationModel> fetchOperationById(String id) async {
|
||||
@@ -23,7 +19,11 @@ class OperationsRepository {
|
||||
.select('''
|
||||
*,
|
||||
customer(name),
|
||||
staff_member(name)
|
||||
store(name),
|
||||
staff_member(name),
|
||||
provider(name),
|
||||
model(name_with_brand),
|
||||
attachments(*)
|
||||
''')
|
||||
.eq('id', id)
|
||||
.single();
|
||||
@@ -48,6 +48,9 @@ class OperationsRepository {
|
||||
.select('''
|
||||
*,
|
||||
customer(name),
|
||||
store(name),
|
||||
provider(name),
|
||||
model(name_with_brand),
|
||||
staff_member(name),
|
||||
attachments(*)
|
||||
''')
|
||||
@@ -107,49 +110,6 @@ class OperationsRepository {
|
||||
|
||||
final String newId = operationData['id'];
|
||||
|
||||
// 4. UPLOAD DEI FILE LOCALI (Nuovi)
|
||||
// Filtriamo solo i file che non hanno ancora un ID (quindi sono locali)
|
||||
final localFilesToUpload = operation.attachments
|
||||
.where((f) => f.id == null)
|
||||
.toList();
|
||||
|
||||
if (localFilesToUpload.isNotEmpty) {
|
||||
final List<Future> uploadTasks = [];
|
||||
|
||||
for (var file in localFilesToUpload) {
|
||||
final storagePath =
|
||||
'$companyId/operations/$newId/${DateTime.now().millisecondsSinceEpoch}_${file.name}.${file.extension}';
|
||||
final String mimeType = file.extension.toLowerCase() == 'pdf'
|
||||
? 'application/pdf'
|
||||
: 'image/${file.extension}';
|
||||
|
||||
final fileToSave = file.copyWith(
|
||||
operationId: newId,
|
||||
storagePath: storagePath,
|
||||
);
|
||||
|
||||
// Creiamo una funzione asincrona per caricare file e scrivere nel DB
|
||||
Future<void> uploadAndLink() async {
|
||||
// A. Upload nel Bucket Storage (usiamo i bytes così funziona anche su Web!)
|
||||
await _supabase.storage
|
||||
.from('documents')
|
||||
.uploadBinary(
|
||||
storagePath,
|
||||
fileToSave.localBytes!,
|
||||
fileOptions: FileOptions(contentType: mimeType, upsert: true),
|
||||
);
|
||||
|
||||
// B. Inserimento riga nel DB relazionale
|
||||
await _supabase.from('attachment').insert(fileToSave.toMap());
|
||||
}
|
||||
|
||||
uploadTasks.add(uploadAndLink());
|
||||
}
|
||||
|
||||
// Eseguiamo tutti gli upload in parallelo per la massima velocità
|
||||
await Future.wait(uploadTasks);
|
||||
}
|
||||
|
||||
// 5. GRAN FINALE: RECUPERO DEL MODELLO COMPLETO E AGGIORNATO
|
||||
// Interroghiamo Supabase per farci restituire la pratica con TUTTI gli ID generati
|
||||
// (inclusi quelli della tabella operation_file appena inseriti)
|
||||
@@ -158,6 +118,9 @@ class OperationsRepository {
|
||||
.select('''
|
||||
*,
|
||||
staff_member(name),
|
||||
store(name),
|
||||
provider(name),
|
||||
model(name_with_brand),
|
||||
customer(name),
|
||||
attachments(*)
|
||||
''')
|
||||
@@ -278,7 +241,7 @@ class OperationsRepository {
|
||||
}
|
||||
|
||||
Future<void> copyFileToCustomer({
|
||||
required OperationFileModel file,
|
||||
required AttachmentModel file,
|
||||
required String customerId,
|
||||
}) async {
|
||||
await _supabase
|
||||
@@ -290,16 +253,28 @@ class OperationsRepository {
|
||||
Future<void> deleteOperationFiles(List<AttachmentModel> files) async {
|
||||
if (files.isEmpty) return;
|
||||
// 1. Prepariamo le liste di ID e di Percorsi
|
||||
final List<String> idsToDelete = files.map((f) => f.id!).toList();
|
||||
final List<String> storagePaths = files.map((f) => f.storagePath).toList();
|
||||
|
||||
final List<String> idsToDelete = [];
|
||||
final List<String> idsToEdit = [];
|
||||
final List<String> storagePathsToDelete = [];
|
||||
for (var file in files) {
|
||||
if (file.customerId == null) {
|
||||
idsToDelete.add(file.id!);
|
||||
storagePathsToDelete.add(file.storagePath);
|
||||
} else {
|
||||
idsToEdit.add(file.id!);
|
||||
}
|
||||
}
|
||||
try {
|
||||
await _supabase
|
||||
.from('attachment')
|
||||
.update({'operation_id': null})
|
||||
.inFilter('id', idsToDelete);
|
||||
|
||||
await _supabase.storage.from('documents').remove(storagePaths);
|
||||
if (idsToDelete.isNotEmpty) {
|
||||
await _supabase.from('attachment').delete().inFilter('id', idsToDelete);
|
||||
await _supabase.storage.from('documents').remove(storagePathsToDelete);
|
||||
}
|
||||
if (idsToEdit.isNotEmpty) {
|
||||
await _supabase
|
||||
.from('attachment')
|
||||
.update({'operation_id': null})
|
||||
.inFilter('id', idsToEdit);
|
||||
}
|
||||
} on PostgrestException catch (e) {
|
||||
throw 'Errore database: ${e.message}';
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user