327 lines
8.5 KiB
Dart
327 lines
8.5 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:kooltab2/database/app_database.dart';
|
|
import 'package:kooltab2/services/bar_tab_service.dart';
|
|
import 'package:kooltab2/services/pin_lock_service.dart';
|
|
import 'package:kooltab2/services/product_service.dart';
|
|
import 'package:kooltab2/services/settings_service.dart';
|
|
import 'package:uuid/uuid.dart';
|
|
|
|
class DevMenuViewModel extends ChangeNotifier {
|
|
final AppDatabase database;
|
|
final ProductService productService;
|
|
final BarTabService barTabService;
|
|
final SettingsService settingsService;
|
|
final PinLockService pinLockService;
|
|
|
|
bool _isLoading = false;
|
|
String? _lastAction;
|
|
|
|
bool get isLoading => _isLoading;
|
|
String? get lastAction => _lastAction;
|
|
|
|
DevMenuViewModel({
|
|
required this.database,
|
|
required this.productService,
|
|
required this.barTabService,
|
|
required this.settingsService,
|
|
required this.pinLockService,
|
|
});
|
|
|
|
Future<void> clearOpenTabs() async {
|
|
_isLoading = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
await database.transaction(() async {
|
|
await database.delete(database.tabItems).go();
|
|
await database.delete(database.barTabs).go();
|
|
});
|
|
_lastAction = 'Cleared all open tabs';
|
|
} finally {
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> clearClosedTabHistory() async {
|
|
_isLoading = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
await database.transaction(() async {
|
|
await database.delete(database.closedTabItems).go();
|
|
await database.delete(database.closedTabs).go();
|
|
});
|
|
_lastAction = 'Cleared closed tab history';
|
|
} finally {
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> clearAllProducts() async {
|
|
_isLoading = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
await database.transaction(() async {
|
|
await database.delete(database.tabItems).go();
|
|
await database.delete(database.products).go();
|
|
});
|
|
_lastAction = 'Cleared all products';
|
|
} finally {
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> resetAllStock() async {
|
|
_isLoading = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
final products = await productService.getProducts();
|
|
for (final product in products) {
|
|
await productService.updateProduct(
|
|
product.copyWith(stockQuantity: 100),
|
|
);
|
|
}
|
|
_lastAction = 'Reset stock for ${products.length} products';
|
|
} finally {
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> seedDemoData() async {
|
|
_isLoading = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
final uuid = const Uuid();
|
|
|
|
final categories = ['Beer', 'Wine', 'Soft Drinks', 'Snacks'];
|
|
final demoProducts = [
|
|
('Heineken', 350, 50),
|
|
('Stella Artois', 380, 40),
|
|
('Leffe Blonde', 420, 30),
|
|
('Duvel', 450, 25),
|
|
('Hoegaarden', 380, 35),
|
|
('Chimay Blue', 550, 20),
|
|
('White Wine', 450, 60),
|
|
('Red Wine', 450, 55),
|
|
('Rosé', 400, 45),
|
|
('Champagne', 850, 15),
|
|
('Cola', 250, 100),
|
|
('Lemonade', 250, 90),
|
|
('Sparkling Water', 200, 80),
|
|
('Orange Juice', 300, 70),
|
|
('Chips', 250, 40),
|
|
('Nuts', 300, 35),
|
|
('Chocolate Bar', 200, 50),
|
|
('Ice Cream', 350, 25),
|
|
];
|
|
|
|
for (var i = 0; i < demoProducts.length; i++) {
|
|
final (name, priceInCents, stock) = demoProducts[i];
|
|
final category = categories[i ~/ 5];
|
|
|
|
await database.into(database.products).insert(
|
|
ProductsCompanion.insert(
|
|
id: uuid.v4(),
|
|
name: name,
|
|
category: category,
|
|
stockQuantity: stock,
|
|
lowStockThreshold: 10,
|
|
priceInCents: priceInCents,
|
|
),
|
|
);
|
|
}
|
|
|
|
_lastAction = 'Seeded ${demoProducts.length} demo products';
|
|
} finally {
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> resetPin() async {
|
|
_isLoading = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
await pinLockService.clearPin();
|
|
_lastAction = 'PIN reset (no PIN required)';
|
|
} finally {
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> createTestTab() async {
|
|
_isLoading = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
final products = await productService.getProducts();
|
|
if (products.isEmpty) {
|
|
_lastAction = 'No products to add to test tab';
|
|
return;
|
|
}
|
|
|
|
final tab = await barTabService.createTab(customerName: 'Test Customer');
|
|
final randomProducts = products.take(3).toList();
|
|
|
|
for (final product in randomProducts) {
|
|
await barTabService.addProductToTab(
|
|
tabId: tab.id,
|
|
product: product,
|
|
);
|
|
}
|
|
|
|
_lastAction = 'Created test tab with ${randomProducts.length} items';
|
|
} finally {
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> addTestProducts({int count = 100}) async {
|
|
_isLoading = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
final uuid = const Uuid();
|
|
|
|
for (var i = 0; i < count; i++) {
|
|
await database.into(database.products).insert(
|
|
ProductsCompanion.insert(
|
|
id: uuid.v4(),
|
|
name: 'Test Product $i',
|
|
category: 'Test Category ${i % 5}',
|
|
stockQuantity: 50 + (i % 50),
|
|
lowStockThreshold: 5,
|
|
priceInCents: 100 + (i * 10),
|
|
),
|
|
);
|
|
}
|
|
|
|
_lastAction = 'Added $count test products';
|
|
} finally {
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> simulateLowStock() async {
|
|
_isLoading = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
final products = await productService.getProducts();
|
|
for (final product in products) {
|
|
await productService.updateProduct(
|
|
product.copyWith(stockQuantity: 3, lowStockThreshold: 10),
|
|
);
|
|
}
|
|
_lastAction = 'Simulated low stock for ${products.length} products';
|
|
} finally {
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> clearImageCache() async {
|
|
_isLoading = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
_lastAction = 'Image cache cleared (no-op in debug mode)';
|
|
} finally {
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> reloadProductImages() async {
|
|
_isLoading = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
_lastAction = 'Product images reloaded';
|
|
} finally {
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> generateMockOrders({int count = 100}) async {
|
|
_isLoading = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
final products = await productService.getProducts();
|
|
if (products.isEmpty) {
|
|
_lastAction = 'No products available — seed demo data first';
|
|
return;
|
|
}
|
|
|
|
final uuid = const Uuid();
|
|
final customerNames = [
|
|
'Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank',
|
|
'Grace', 'Hank', 'Ivy', 'Jack', 'Kate', 'Leo',
|
|
'Mia', 'Noah', 'Olivia', 'Pete', 'Quinn', 'Rose',
|
|
'Sam', 'Tina', 'Umar', 'Vera', 'Wes', 'Xena',
|
|
'Yves', 'Zara',
|
|
];
|
|
|
|
await database.transaction(() async {
|
|
for (var i = 0; i < count; i++) {
|
|
final customer = customerNames[i % customerNames.length];
|
|
final closedTabId = uuid.v4();
|
|
final itemCount = 1 + (i % 5);
|
|
|
|
final closedAt = DateTime.now().subtract(
|
|
Duration(
|
|
days: i % 90,
|
|
hours: i % 24,
|
|
minutes: i % 60,
|
|
),
|
|
);
|
|
|
|
await database.into(database.closedTabs).insert(
|
|
ClosedTabsCompanion.insert(
|
|
id: closedTabId,
|
|
originalTabId: uuid.v4(),
|
|
customerName: customer,
|
|
closedAt: closedAt,
|
|
),
|
|
);
|
|
|
|
for (var j = 0; j < itemCount; j++) {
|
|
final product = products[(i + j) % products.length];
|
|
final quantity = 1 + ((i * 7 + j * 13) % 6);
|
|
|
|
await database.into(database.closedTabItems).insert(
|
|
ClosedTabItemsCompanion.insert(
|
|
id: uuid.v4(),
|
|
closedTabId: closedTabId,
|
|
productId: product.id,
|
|
productName: product.name,
|
|
quantity: quantity,
|
|
unitPriceInCents: product.priceInCents,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
});
|
|
|
|
_lastAction = 'Generated $count mock orders across '
|
|
'${customerNames.length} customers';
|
|
} finally {
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
}
|