124 lines
3.5 KiB
Dart
124 lines
3.5 KiB
Dart
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<void> uploadToServer();
|
|
}
|
|
|
|
class DefaultExportService implements ExportService {
|
|
final AppDatabase database;
|
|
|
|
DefaultExportService({required this.database});
|
|
|
|
@override
|
|
Future<void> 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<List<_ClosedTabExport>> _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<String, dynamic> _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,
|
|
});
|
|
} |