import 'dart:convert'; import 'package:drift/drift.dart'; import 'package:http/http.dart' as http; import '../database/app_database.dart'; import '../utils/app_config.dart'; abstract class ExportService { Future uploadToServer(); } class DefaultExportService implements ExportService { final AppDatabase database; DefaultExportService({required this.database}); @override Future uploadToServer() async { try { final closedTabs = await _getAllClosedTabs(); final exportData = _buildExportPayload(closedTabs); final response = await http.post( Uri.parse(kExportServerUrl), headers: {'Content-Type': 'application/json'}, body: jsonEncode(exportData), ); if (response.statusCode != 200 && response.statusCode != 201) { // Silently fail - this is a non-critical background operation } } catch (_) { // Silently fail - this is a non-critical background operation } } Future> _getAllClosedTabs() async { final tabQuery = database.select(database.closedTabs) ..orderBy([(tab) => OrderingTerm.desc(tab.closedAt)]); final tabRows = await tabQuery.get(); final result = <_ClosedTabExport>[]; for (final tabRow in tabRows) { final itemsQuery = database.select(database.closedTabItems) ..where((item) => item.closedTabId.equals(tabRow.id)); final itemRows = await itemsQuery.get(); result.add(_ClosedTabExport( id: tabRow.id, originalTabId: tabRow.originalTabId, customerName: tabRow.customerName, closedAt: tabRow.closedAt.toIso8601String(), paymentMethod: tabRow.paymentMethod, items: itemRows.map((row) => _ClosedTabItemExport( productId: row.productId, productName: row.productName, quantity: row.quantity, unitPriceInCents: row.unitPriceInCents, )).toList(), )); } return result; } Map _buildExportPayload(List<_ClosedTabExport> tabs) { return { 'exportedAt': DateTime.now().toIso8601String(), 'appVersion': '1.0.7', 'closedTabs': tabs.map((tab) => { 'id': tab.id, 'originalTabId': tab.originalTabId, 'customerName': tab.customerName, 'closedAt': tab.closedAt, 'paymentMethod': tab.paymentMethod, 'items': tab.items.map((item) => { 'productId': item.productId, 'productName': item.productName, 'quantity': item.quantity, 'unitPriceInCents': item.unitPriceInCents, 'lineTotalInCents': item.quantity * item.unitPriceInCents, }).toList(), 'itemCount': tab.items.fold(0, (sum, item) => sum + item.quantity), 'totalInCents': tab.items.fold(0, (sum, item) => sum + item.quantity * item.unitPriceInCents), }).toList(), }; } } class _ClosedTabItemExport { final String productId; final String productName; final int quantity; final int unitPriceInCents; _ClosedTabItemExport({ required this.productId, required this.productName, required this.quantity, required this.unitPriceInCents, }); } class _ClosedTabExport { final String id; final String originalTabId; final String customerName; final String closedAt; final String paymentMethod; final List<_ClosedTabItemExport> items; _ClosedTabExport({ required this.id, required this.originalTabId, required this.customerName, required this.closedAt, required this.paymentMethod, required this.items, }); }