fix: reformat code / code improvements

This commit is contained in:
2026-07-30 01:46:01 +02:00
parent a732e2d07f
commit 498ad68e1c
15 changed files with 85 additions and 169 deletions
+3 -10
View File
@@ -1,4 +1,5 @@
import 'tab_item.dart'; import 'tab_item.dart';
import '../utils/collection_utils.dart';
class BarTab { class BarTab {
final String id; final String id;
@@ -40,7 +41,7 @@ class BarTab {
status == other.status && status == other.status &&
openedAt == other.openedAt && openedAt == other.openedAt &&
closedAt == other.closedAt && closedAt == other.closedAt &&
_listEquals(items, other.items); listEquals(items, other.items);
@override @override
int get hashCode => Object.hash( int get hashCode => Object.hash(
@@ -53,12 +54,4 @@ class BarTab {
); );
} }
bool _listEquals<T>(List<T>? a, List<T>? b) { // _listEquals moved to utils/collection_utils.dart
if (identical(a, b)) return true;
if (a == null || b == null) return a == b;
if (a.length != b.length) return false;
for (int i = 0; i < a.length; i++) {
if (a[i] != b[i]) return false;
}
return true;
}
+8 -20
View File
@@ -1,16 +1,18 @@
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'closed_tab_item.dart'; import 'closed_tab_item.dart';
import 'payment_method.dart';
import '../utils/collection_utils.dart';
class ClosedTab { class ClosedTab {
final String id; final String id;
final String originalTabId; final String originalTabId;
final String customerName; final String customerName;
final DateTime closedAt; final DateTime closedAt;
final String paymentMethod; final PaymentMethod paymentMethod;
final List<ClosedTabItem> items;
ClosedTab({ final List<ClosedTabItem> items;
const ClosedTab({
required this.id, required this.id,
required this.originalTabId, required this.originalTabId,
required this.customerName, required this.customerName,
@@ -27,13 +29,7 @@ class ClosedTab {
String get formattedTotal => String get formattedTotal =>
NumberFormat.simpleCurrency().format(totalInCents / 100); NumberFormat.simpleCurrency().format(totalInCents / 100);
String get formattedPaymentMethod { String get formattedPaymentMethod => paymentMethod.label;
return switch (paymentMethod) {
'cash' => 'Cash',
'payconiq' => 'Payconiq',
_ => 'Cash',
};
}
@override @override
bool operator ==(Object other) => bool operator ==(Object other) =>
@@ -44,7 +40,7 @@ class ClosedTab {
customerName == other.customerName && customerName == other.customerName &&
closedAt == other.closedAt && closedAt == other.closedAt &&
paymentMethod == other.paymentMethod && paymentMethod == other.paymentMethod &&
_listEquals(items, other.items); listEquals(items, other.items);
@override @override
int get hashCode => Object.hash( int get hashCode => Object.hash(
@@ -57,12 +53,4 @@ class ClosedTab {
); );
} }
bool _listEquals<T>(List<T>? a, List<T>? b) { // _listEquals moved to utils/collection_utils.dart
if (identical(a, b)) return true;
if (a == null || b == null) return a == b;
if (a.length != b.length) return false;
for (int i = 0; i < a.length; i++) {
if (a[i] != b[i]) return false;
}
return true;
}
+15
View File
@@ -0,0 +1,15 @@
enum PaymentMethod {
cash('cash', 'Cash', 'Cash payment'),
payconiq('payconiq', 'Payconiq', 'Payconiq QR payment');
final String value;
final String label;
final String description;
const PaymentMethod(this.value, this.label, this.description);
static PaymentMethod fromValue(String value) => PaymentMethod.values.firstWhere(
(e) => e.value == value,
orElse: () => PaymentMethod.cash,
);
}
+5 -4
View File
@@ -5,6 +5,7 @@ import '../database/app_database.dart';
import '../models/bar_tab.dart'; import '../models/bar_tab.dart';
import '../models/closed_tab.dart'; import '../models/closed_tab.dart';
import '../models/closed_tab_item.dart'; import '../models/closed_tab_item.dart';
import '../models/payment_method.dart';
import '../models/product.dart'; import '../models/product.dart';
import '../models/tab_item.dart'; import '../models/tab_item.dart';
@@ -29,7 +30,7 @@ abstract class BarTabService {
/// Archives the tab's current items into history and clears them. /// Archives the tab's current items into history and clears them.
/// The tab itself stays open under the same customer name. /// The tab itself stays open under the same customer name.
Future<void> closeTab(String tabId, {String paymentMethod = 'cash'}); Future<void> closeTab(String tabId, {PaymentMethod paymentMethod = PaymentMethod.cash});
Future<List<ClosedTab>> getClosedTabs(); Future<List<ClosedTab>> getClosedTabs();
@@ -234,7 +235,7 @@ class DriftBarTabService implements BarTabService {
} }
@override @override
Future<void> closeTab(String tabId, {String paymentMethod = 'cash'}) async { Future<void> closeTab(String tabId, {PaymentMethod paymentMethod = PaymentMethod.cash}) async {
await database.transaction(() async { await database.transaction(() async {
final tabQuery = database.select(database.barTabs) final tabQuery = database.select(database.barTabs)
..where((tab) => tab.id.equals(tabId)); ..where((tab) => tab.id.equals(tabId));
@@ -261,7 +262,7 @@ class DriftBarTabService implements BarTabService {
originalTabId: tabId, originalTabId: tabId,
customerName: tabRow.customerName, customerName: tabRow.customerName,
closedAt: DateTime.now(), closedAt: DateTime.now(),
paymentMethod: Value(paymentMethod), paymentMethod: Value(paymentMethod.value),
), ),
); );
@@ -326,7 +327,7 @@ class DriftBarTabService implements BarTabService {
originalTabId: row.originalTabId, originalTabId: row.originalTabId,
customerName: row.customerName, customerName: row.customerName,
closedAt: row.closedAt, closedAt: row.closedAt,
paymentMethod: row.paymentMethod, paymentMethod: PaymentMethod.fromValue(row.paymentMethod),
items: itemRows.map<ClosedTabItem>(_mapClosedItemRow).toList(), items: itemRows.map<ClosedTabItem>(_mapClosedItemRow).toList(),
), ),
); );
-97
View File
@@ -83,101 +83,4 @@ class AppUpdateUtil {
return UpdateInfo.fromJson(data); return UpdateInfo.fromJson(data);
} }
// /// Downloads the APK
// Future<File> downloadApk(
// UpdateInfo update, {
//
// Function(double progress)? onProgress,
// }) async {
// final url = update.download.startsWith("http")
// ? update.download
// : "$serverUrl${update.download}";
//
// final request = http.Request("GET", Uri.parse(url));
//
// final response = await request.send();
//
// if (response.statusCode != 200) {
// throw Exception("APK download failed");
// }
//
// final total = response.contentLength ?? 0;
//
// int received = 0;
//
// final directory = await getTemporaryDirectory();
//
// final file = File("${directory.path}/update.apk");
//
// final sink = file.openWrite();
//
// await for (final chunk in response.stream) {
// sink.add(chunk);
//
// received += chunk.length;
//
// if (total > 0 && onProgress != null) {
// onProgress(received / total);
// }
// }
//
// await sink.close();
//
// return file;
// }
//
// /// Verifies APK checksum
// Future<bool> verifySha256(File file, String expectedHash) async {
// final bytes = await file.readAsBytes();
//
// final digest = sha256.convert(bytes);
//
// return digest.toString().toLowerCase() == expectedHash.toLowerCase();
// }
//
// /// Opens Android APK installer
// Future<void> installApk(File file) async {
// final result =
// await OpenFilex.open(
// file.path,
// );
//
// if(result.type == ResultType.done) {
// debugPrint("APK installer opened successfully");
// }
//
//
// if (result.type != ResultType.done) {
// throw Exception(
// "Could not open APK installer",
// );
// }
// }
//
// /// Full update flow
// ///
// /// Returns:
// /// - null if no update exists
// /// - UpdateInfo if update is available
// ///
// Future<UpdateInfo?> update({Function(double progress)? onProgress}) async {
// final info = await checkForUpdate();
//
// if (info == null) {
// return null;
// }
//
// final apk = await downloadApk(info, onProgress: onProgress);
//
// final valid = await verifySha256(apk, info.sha256);
//
// if (!valid) {
// throw Exception("APK checksum mismatch");
// }
//
// await installApk(apk);
//
// return info;
// }
} }
+9
View File
@@ -0,0 +1,9 @@
bool listEquals<T>(List<T>? a, List<T>? b) {
if (identical(a, b)) return true;
if (a == null || b == null) return a == b;
if (a.length != b.length) return false;
for (int i = 0; i < a.length; i++) {
if (a[i] != b[i]) return false;
}
return true;
}
+7 -4
View File
@@ -1,5 +1,6 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import '../models/payment_method.dart';
import '../models/bar_tab.dart'; import '../models/bar_tab.dart';
import '../models/product.dart'; import '../models/product.dart';
import '../models/tab_item.dart'; import '../models/tab_item.dart';
@@ -33,7 +34,8 @@ class BarScreenViewModel extends ChangeNotifier {
try { try {
return _tabs.firstWhere((tab) => tab.id == _selectedTabId); return _tabs.firstWhere((tab) => tab.id == _selectedTabId);
} catch (_) { } catch (e) {
debugPrint('BarScreenViewModel: error finding selected tab: $e');
return null; return null;
} }
} }
@@ -58,7 +60,8 @@ class BarScreenViewModel extends ChangeNotifier {
!_tabs.any((tab) => tab.id == _selectedTabId)) { !_tabs.any((tab) => tab.id == _selectedTabId)) {
_selectedTabId = _tabs.isEmpty ? null : _tabs.first.id; _selectedTabId = _tabs.isEmpty ? null : _tabs.first.id;
} }
} catch (_) { } catch (e) {
debugPrint('BarScreenViewModel: load error: $e');
_errorMessage = 'Could not load bar screen.'; _errorMessage = 'Could not load bar screen.';
} finally { } finally {
_hasLoaded = true; _hasLoaded = true;
@@ -115,7 +118,7 @@ class BarScreenViewModel extends ChangeNotifier {
await _reloadTabs(); await _reloadTabs();
} }
Future<void> closeSelectedTab({String paymentMethod = 'cash'}) async { Future<void> closeSelectedTab({PaymentMethod paymentMethod = PaymentMethod.cash}) async {
final tab = selectedTab; final tab = selectedTab;
if (tab == null) return; if (tab == null) return;
@@ -125,7 +128,7 @@ class BarScreenViewModel extends ChangeNotifier {
await _reloadTabs(); await _reloadTabs();
} }
Future<void> closeTab(String tabId, {String paymentMethod = 'cash'}) async { Future<void> closeTab(String tabId, {PaymentMethod paymentMethod = PaymentMethod.cash}) async {
await barTabService.closeTab(tabId, paymentMethod: paymentMethod); await barTabService.closeTab(tabId, paymentMethod: paymentMethod);
await _reloadTabs(); await _reloadTabs();
+3 -2
View File
@@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart';
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:kooltab2/database/app_database.dart'; import 'package:kooltab2/database/app_database.dart';
import 'package:kooltab2/services/bar_tab_service.dart'; import 'package:kooltab2/services/bar_tab_service.dart';
import 'package:kooltab2/models/payment_method.dart';
import 'package:kooltab2/services/pin_lock_service.dart'; import 'package:kooltab2/services/pin_lock_service.dart';
import 'package:kooltab2/services/product_service.dart'; import 'package:kooltab2/services/product_service.dart';
import 'package:kooltab2/services/settings_service.dart'; import 'package:kooltab2/services/settings_service.dart';
@@ -275,7 +276,7 @@ class DevMenuViewModel extends ChangeNotifier {
'Sam', 'Tina', 'Umar', 'Vera', 'Wes', 'Xena', 'Sam', 'Tina', 'Umar', 'Vera', 'Wes', 'Xena',
'Yves', 'Zara', 'Yves', 'Zara',
]; ];
const paymentMethods = ['cash', 'payconiq']; const paymentMethods = [PaymentMethod.cash, PaymentMethod.payconiq];
await database.transaction(() async { await database.transaction(() async {
for (var i = 0; i < count; i++) { for (var i = 0; i < count; i++) {
@@ -297,7 +298,7 @@ class DevMenuViewModel extends ChangeNotifier {
originalTabId: uuid.v4(), originalTabId: uuid.v4(),
customerName: customer, customerName: customer,
closedAt: closedAt, closedAt: closedAt,
paymentMethod: Value(paymentMethods[(i * 3) % paymentMethods.length]), paymentMethod: Value(paymentMethods[(i * 3) % paymentMethods.length].value),
), ),
); );
+4 -2
View File
@@ -73,7 +73,8 @@ class HistoryViewModel extends ChangeNotifier {
_totalCount = results[1] as int; _totalCount = results[1] as int;
_customerNames = results[2] as List<String>; _customerNames = results[2] as List<String>;
_offset = _closedTabs.length; _offset = _closedTabs.length;
} catch (_) { } catch (e) {
debugPrint('HistoryViewModel: load error: $e');
_errorMessage = 'Could not load tab history.'; _errorMessage = 'Could not load tab history.';
} finally { } finally {
_hasLoaded = true; _hasLoaded = true;
@@ -92,7 +93,8 @@ class HistoryViewModel extends ChangeNotifier {
final more = await _fetchPage(offset: _offset); final more = await _fetchPage(offset: _offset);
_closedTabs = [..._closedTabs, ...more]; _closedTabs = [..._closedTabs, ...more];
_offset = _closedTabs.length; _offset = _closedTabs.length;
} catch (_) { } catch (e) {
debugPrint('HistoryViewModel: loadMore error: $e');
_errorMessage = 'Could not load more tabs.'; _errorMessage = 'Could not load more tabs.';
} finally { } finally {
_isLoadingMore = false; _isLoadingMore = false;
+6 -3
View File
@@ -56,7 +56,8 @@ class PinLockViewModel extends ChangeNotifier {
final settings = await svc.getSettings(); final settings = await svc.getSettings();
_pinRequired = settings.pinRequired; _pinRequired = settings.pinRequired;
} }
} catch (_) { } catch (e) {
debugPrint('PinLockViewModel: load error: $e');
_errorMessage = 'Could not check PIN status.'; _errorMessage = 'Could not check PIN status.';
} finally { } finally {
_hasLoaded = true; _hasLoaded = true;
@@ -85,7 +86,8 @@ class PinLockViewModel extends ChangeNotifier {
notifyListeners(); notifyListeners();
return true; return true;
} catch (_) { } catch (e) {
debugPrint('PinLockViewModel: setPin error: $e');
_errorMessage = 'Could not save PIN.'; _errorMessage = 'Could not save PIN.';
notifyListeners(); notifyListeners();
return false; return false;
@@ -108,7 +110,8 @@ class PinLockViewModel extends ChangeNotifier {
_errorMessage = 'Incorrect PIN.'; _errorMessage = 'Incorrect PIN.';
notifyListeners(); notifyListeners();
return false; return false;
} catch (_) { } catch (e) {
debugPrint('PinLockViewModel: verify error: $e');
_errorMessage = 'Could not verify PIN.'; _errorMessage = 'Could not verify PIN.';
notifyListeners(); notifyListeners();
return false; return false;
+2 -15
View File
@@ -48,27 +48,14 @@ class ProductListViewModel extends ChangeNotifier {
try { try {
await inventory.load(); await inventory.load();
} catch (_) { } catch (e) {
debugPrint('ProductListViewModel: load error: $e');
_errorMessage = 'Could not load products.'; _errorMessage = 'Could not load products.';
} finally { } finally {
_hasLoaded = true; _hasLoaded = true;
_isLoading = false; _isLoading = false;
notifyListeners(); notifyListeners();
} }
// try {
// _products = await productService.getProducts();
//
// debugPrint(
// _products.map((p) => '${p.name}: ${p.stockQuantity}').join('\n'),
// );
// } catch (_) {
// _errorMessage = 'Could not load products.';
// } finally {
// _hasLoaded = true;
// _isLoading = false;
// notifyListeners();
// }
} }
Future<void> addProduct({ Future<void> addProduct({
+4 -2
View File
@@ -44,7 +44,8 @@ class SettingsViewModel extends ChangeNotifier {
try { try {
_settings = await settingsService.getSettings(); _settings = await settingsService.getSettings();
} catch (_) { } catch (e) {
debugPrint('SettingsViewModel: load error: $e');
_errorMessage = 'Could not load settings.'; _errorMessage = 'Could not load settings.';
} finally { } finally {
_hasLoaded = true; _hasLoaded = true;
@@ -118,7 +119,8 @@ class SettingsViewModel extends ChangeNotifier {
try { try {
await settingsService.saveSettings(updated); await settingsService.saveSettings(updated);
} catch (_) { } catch (e) {
debugPrint('SettingsViewModel: save error: $e');
_settings = previous; _settings = previous;
_errorMessage = 'Could not save settings.'; _errorMessage = 'Could not save settings.';
notifyListeners(); notifyListeners();
+7
View File
@@ -125,7 +125,14 @@ class _BarScreenViewState extends State<BarScreenView> {
return; return;
} }
try {
await viewModel.addProductToSelectedTab(product); await viewModel.addProductToSelectedTab(product);
} catch (e) {
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('$e')),
);
}
}, },
), ),
), ),
+7 -6
View File
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../models/payment_method.dart';
import '../../viewmodels/bar_screen_view_model.dart'; import '../../viewmodels/bar_screen_view_model.dart';
import '../widgets/slide_confirm.dart'; import '../widgets/slide_confirm.dart';
@@ -11,7 +12,7 @@ Future<void> confirmCloseTab(BuildContext context) async {
if (tab == null) return; if (tab == null) return;
String paymentMethod = 'cash'; PaymentMethod paymentMethod = PaymentMethod.cash;
final confirmed = await showDialog<bool>( final confirmed = await showDialog<bool>(
context: context, context: context,
@@ -66,8 +67,8 @@ Future<void> confirmCloseTab(BuildContext context) async {
} }
class _PaymentPicker extends StatelessWidget { class _PaymentPicker extends StatelessWidget {
final String selected; final PaymentMethod selected;
final ValueChanged<String> onChanged; final ValueChanged<PaymentMethod> onChanged;
const _PaymentPicker({ const _PaymentPicker({
required this.selected, required this.selected,
@@ -75,8 +76,8 @@ class _PaymentPicker extends StatelessWidget {
}); });
static const _options = [ static const _options = [
('cash', 'Cash'), (PaymentMethod.cash, 'Cash'),
('payconiq', 'Payconiq'), (PaymentMethod.payconiq, 'Payconiq'),
]; ];
@override @override
@@ -96,7 +97,7 @@ class _PaymentPicker extends StatelessWidget {
label: Row( label: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
if (value == 'cash') if (value == PaymentMethod.cash)
const Icon( const Icon(
Icons.attach_money, Icons.attach_money,
size: 16, size: 16,
+4 -3
View File
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:kooltab2/models/closed_tab.dart'; import 'package:kooltab2/models/closed_tab.dart';
import 'package:kooltab2/models/closed_tab_item.dart'; import 'package:kooltab2/models/closed_tab_item.dart';
import 'package:kooltab2/models/payment_method.dart';
class ClosedTabCard extends StatefulWidget { class ClosedTabCard extends StatefulWidget {
final ClosedTab closedTab; final ClosedTab closedTab;
@@ -15,10 +16,10 @@ class ClosedTabCard extends StatefulWidget {
class _ClosedTabCardState extends State<ClosedTabCard> { class _ClosedTabCardState extends State<ClosedTabCard> {
bool _expanded = false; bool _expanded = false;
IconData _paymentIcon(String method) { IconData _paymentIcon(PaymentMethod method) {
return switch (method) { return switch (method) {
'payconiq' => Icons.qr_code_rounded, PaymentMethod.payconiq => Icons.qr_code_rounded,
_ => Icons.money_rounded, PaymentMethod.cash => Icons.money_rounded,
}; };
} }