diff --git a/lib/app/app_bootstrap.dart b/lib/app/app_bootstrap.dart index 9c7ec40..bd35c09 100644 --- a/lib/app/app_bootstrap.dart +++ b/lib/app/app_bootstrap.dart @@ -3,6 +3,7 @@ import 'package:provider/provider.dart'; import '../database/app_database.dart'; import '../services/default_product_seeder.dart'; +import '../services/export_service.dart'; import '../viewmodels/bar_screen_view_model.dart'; import '../viewmodels/product_list_view_model.dart'; @@ -28,6 +29,8 @@ class _AppBootstrapState extends State { context.read().ensureLoaded(); context.read().ensureLoaded(); + + DefaultExportService(database: database).uploadToServer(); }); } diff --git a/lib/services/export_service.dart b/lib/services/export_service.dart new file mode 100644 index 0000000..551d68f --- /dev/null +++ b/lib/services/export_service.dart @@ -0,0 +1,124 @@ +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, + }); +} \ No newline at end of file diff --git a/lib/utils/app_config.dart b/lib/utils/app_config.dart index 739cd66..4e881b4 100644 --- a/lib/utils/app_config.dart +++ b/lib/utils/app_config.dart @@ -1 +1,2 @@ -const kUpdateServerUrl = 'https://updater.brammie15.dev'; \ No newline at end of file +const kUpdateServerUrl = 'https://updater.brammie15.dev'; +const kExportServerUrl = 'https://your-server.com/api/backup'; \ No newline at end of file