refactor shipping attachments and changed shipment to shipping for coherence
This commit is contained in:
@@ -4,17 +4,27 @@ import 'package:flux/features/attachments/models/attachment_model.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
import 'package:flux/features/attachments/blocs/attachments_bloc.dart';
|
||||
|
||||
enum Bucket {
|
||||
documents('documents'),
|
||||
companyDocuments('company_documents');
|
||||
|
||||
final String value;
|
||||
const Bucket(this.value);
|
||||
}
|
||||
|
||||
class AttachmentsRepository {
|
||||
final _supabase = Supabase.instance.client;
|
||||
static const String _bucketName = 'documents';
|
||||
static const String _tableName =
|
||||
'attachment'; // Cambia col vero nome della tua tabella se diverso!
|
||||
|
||||
/// Scarica i byte di un file direttamente da Supabase Storage
|
||||
Future<Uint8List> downloadAttachmentBytes(String storagePath) async {
|
||||
Future<Uint8List> downloadAttachmentBytes({
|
||||
required String storagePath,
|
||||
required Bucket bucket,
|
||||
}) async {
|
||||
try {
|
||||
final Uint8List bytes = await _supabase.storage
|
||||
.from(_bucketName)
|
||||
.from(bucket.value)
|
||||
.download(storagePath);
|
||||
return bytes;
|
||||
} catch (e) {
|
||||
@@ -31,6 +41,8 @@ class AttachmentsRepository {
|
||||
return 'ticket_id';
|
||||
case AttachmentParentType.customer:
|
||||
return 'customer_id';
|
||||
case AttachmentParentType.shippingDocument:
|
||||
return 'shipping_document_id';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,41 +67,70 @@ class AttachmentsRepository {
|
||||
Future<void> uploadAndRegisterFile({
|
||||
required String parentId,
|
||||
required AttachmentParentType parentType,
|
||||
required PlatformFile pickedFile,
|
||||
required String companyId,
|
||||
required Bucket bucket,
|
||||
PlatformFile? pickedFile, // Ora è opzionale
|
||||
Uint8List? rawBytes, // Alternativa: bytes grezzi
|
||||
String? rawFileName, // Alternativa: nome del file
|
||||
}) async {
|
||||
// 🛡️ L'ASSERT NINJA: O c'è il pickedFile, o ci sono i byte e il nome.
|
||||
// L'assert funziona solo in debug, ma è perfetto per beccare subito errori di chiamata!
|
||||
assert(
|
||||
pickedFile != null || (rawBytes != null && rawFileName != null),
|
||||
'Devi passare o un PlatformFile, oppure rawBytes e rawFileName!',
|
||||
);
|
||||
|
||||
try {
|
||||
if (pickedFile.bytes == null) {
|
||||
throw Exception(
|
||||
"I bytes del file sono vuoti! Ricarica la pagina senza cache.",
|
||||
);
|
||||
// 1. Normalizziamo i dati in base a cosa ci è stato passato
|
||||
final Uint8List finalBytes;
|
||||
final String finalFileName;
|
||||
final int finalFileSize;
|
||||
|
||||
if (pickedFile != null) {
|
||||
if (pickedFile.bytes == null) {
|
||||
throw Exception(
|
||||
"I bytes del file sono vuoti! Ricarica la pagina senza cache.",
|
||||
);
|
||||
}
|
||||
finalBytes = pickedFile.bytes!;
|
||||
finalFileName = pickedFile.name;
|
||||
finalFileSize = pickedFile.size;
|
||||
} else {
|
||||
// Se pickedFile è null, grazie all'assert sappiamo che questi non lo sono
|
||||
finalBytes = rawBytes!;
|
||||
finalFileName = rawFileName!;
|
||||
finalFileSize = finalBytes.length; // Calcoliamo la size dai byte reali
|
||||
}
|
||||
|
||||
final extension = pickedFile.extension ?? pickedFile.name.split('.').last;
|
||||
final cleanName = pickedFile.name
|
||||
// 2. Estraiamo l'estensione e puliamo il nome
|
||||
final extension = finalFileName.contains('.')
|
||||
? finalFileName.split('.').last
|
||||
: ''; // Fallback se il file non ha estensione
|
||||
|
||||
final cleanName = finalFileName
|
||||
.replaceAll(RegExp(r'[^\w\s\.-]'), '')
|
||||
.replaceAll(' ', '_');
|
||||
|
||||
// Creiamo un path ordinato: idAzienda/tipoEntita/idEntita/timestamp_nomefile
|
||||
// 3. Creiamo un path ordinato: idAzienda/tipoEntita/idEntita/timestamp_nomefile
|
||||
final timestamp = DateTime.now().millisecondsSinceEpoch;
|
||||
final storagePath =
|
||||
'$companyId/${parentType.name}/$parentId/${timestamp}_$cleanName';
|
||||
|
||||
// 1. Upload su Supabase Storage
|
||||
// 4. Upload su Supabase Storage
|
||||
await _supabase.storage
|
||||
.from(_bucketName)
|
||||
.from(bucket.value)
|
||||
.uploadBinary(
|
||||
storagePath,
|
||||
pickedFile.bytes!,
|
||||
finalBytes,
|
||||
fileOptions: FileOptions(contentType: _guessContentType(extension)),
|
||||
);
|
||||
|
||||
// 2. Creiamo la mappa per il DB dinamicamente
|
||||
// 5. Creiamo la mappa per il DB dinamicamente
|
||||
final Map<String, dynamic> insertData = {
|
||||
'company_id': companyId,
|
||||
'name': pickedFile.name.replaceAll('.$extension', ''),
|
||||
'name': finalFileName.replaceAll('.$extension', ''),
|
||||
'extension': extension,
|
||||
'file_size': pickedFile.size,
|
||||
'file_size': finalFileSize,
|
||||
'storage_path': storagePath,
|
||||
};
|
||||
|
||||
@@ -97,7 +138,7 @@ class AttachmentsRepository {
|
||||
final columnName = _getColumnNameForParent(parentType);
|
||||
insertData[columnName] = parentId;
|
||||
|
||||
// 3. Salviamo su Postgres
|
||||
// 6. Salviamo su Postgres
|
||||
await _supabase.from(_tableName).insert(insertData);
|
||||
} catch (e) {
|
||||
throw Exception("Errore caricamento: $e");
|
||||
@@ -108,6 +149,7 @@ class AttachmentsRepository {
|
||||
Future<void> deleteFiles({
|
||||
required List<AttachmentModel> files,
|
||||
required AttachmentParentType currentContextType,
|
||||
required Bucket bucket,
|
||||
}) async {
|
||||
if (files.isEmpty) return;
|
||||
|
||||
@@ -120,6 +162,7 @@ class AttachmentsRepository {
|
||||
AttachmentParentType.operation: file.operationId,
|
||||
AttachmentParentType.ticket: file.ticketId,
|
||||
AttachmentParentType.customer: file.customerId,
|
||||
AttachmentParentType.shippingDocument: file.shippingDocumentId,
|
||||
};
|
||||
|
||||
// 2. Simuliamo la rimozione del collegamento per il contesto attuale
|
||||
@@ -142,7 +185,7 @@ class AttachmentsRepository {
|
||||
await _supabase.from(_tableName).delete().eq('id', file.id!);
|
||||
|
||||
if (file.storagePath != null) {
|
||||
await _supabase.storage.from(_bucketName).remove([
|
||||
await _supabase.storage.from(bucket.value).remove([
|
||||
file.storagePath!,
|
||||
]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user