149 lines
4.3 KiB
Dart
149 lines
4.3 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:drift/drift.dart';
|
|
import 'package:sentry_flutter/sentry_flutter.dart';
|
|
import 'package:uuid/uuid.dart';
|
|
import 'package:path/path.dart' as path;
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
|
import '../database/app_database.dart';
|
|
|
|
class DefaultProductSeeder {
|
|
final AppDatabase database;
|
|
|
|
DefaultProductSeeder({required this.database});
|
|
|
|
static const _defaultProducts = [
|
|
('Jupiler', 280, 80, 'Bier'),
|
|
('Stella Artois', 300, 60, 'Bier'),
|
|
('Leffe Blonde', 380, 30, 'Bier'),
|
|
('Duvel', 420, 25, 'Bier'),
|
|
('Hoegaarden', 350, 35, 'Bier'),
|
|
('Witte Wijn', 380, 50, 'Wijn'),
|
|
('Rode Wijn', 400, 45, 'Wijn'),
|
|
('Rosé', 350, 40, 'Wijn'),
|
|
('Cola', 250, 100, 'Frisdrank'),
|
|
('Cola Zero', 250, 80, 'Frisdrank'),
|
|
('Spa Bruis', 200, 70, 'Frisdrank'),
|
|
('Spa Plat', 200, 70, 'Frisdrank'),
|
|
('Ice Tea', 280, 60, 'Frisdrank'),
|
|
('Limonade', 250, 50, 'Frisdrank'),
|
|
('Chips', 220, 40, 'Snacks'),
|
|
('Koffie', 280, 200, 'Coffee'),
|
|
('Thee', 250, 150, 'Coffee'),
|
|
];
|
|
|
|
Future<void> seedIfEmpty() async {
|
|
try {
|
|
final count = await _getProductCount();
|
|
if (count > 0) return;
|
|
|
|
final imagesDir = await _ensureImagesDir();
|
|
|
|
await database.transaction(() async {
|
|
final uuid = const Uuid();
|
|
|
|
for (final (name, priceInCents, stock, category) in _defaultProducts) {
|
|
String? imagePath;
|
|
|
|
if (imagesDir != null) {
|
|
imagePath = await _copyBundledImage(name, imagesDir);
|
|
}
|
|
|
|
await database.into(database.products).insert(
|
|
ProductsCompanion.insert(
|
|
id: uuid.v4(),
|
|
name: name,
|
|
category: category,
|
|
stockQuantity: stock,
|
|
lowStockThreshold: 10,
|
|
priceInCents: priceInCents,
|
|
imagePath: Value(imagePath),
|
|
),
|
|
);
|
|
}
|
|
});
|
|
} catch (e, stack) {
|
|
debugPrint('DefaultProductSeeder: seedIfEmpty error: $e');
|
|
Sentry.captureException(e, stackTrace: stack);
|
|
}
|
|
}
|
|
|
|
Future<int> _getProductCount() async {
|
|
final countExpr = database.products.id.count();
|
|
final query = database.selectOnly(database.products)
|
|
..addColumns([countExpr]);
|
|
final row = await query.getSingle();
|
|
return row.read(countExpr) ?? 0;
|
|
}
|
|
|
|
Future<Directory?> _ensureImagesDir() async {
|
|
try {
|
|
final appDir = await getApplicationSupportDirectory();
|
|
final imagesDir = Directory(path.join(appDir.path, 'product_images'));
|
|
|
|
if (!imagesDir.existsSync()) {
|
|
await imagesDir.create(recursive: true);
|
|
}
|
|
|
|
return imagesDir;
|
|
} catch (e) {
|
|
debugPrint('DefaultProductSeeder: could not create images dir: $e');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
Future<String?> _copyBundledImage(String productName, Directory imagesDir) async {
|
|
final slug = _toSlug(productName);
|
|
|
|
for (final ext in ['png', 'jpg', 'webp']) {
|
|
final assetKey = 'assets/products/$slug.$ext';
|
|
|
|
try {
|
|
final bytes = await rootBundle.load(assetKey);
|
|
final fileName = '${DateTime.now().millisecondsSinceEpoch}_$slug.$ext';
|
|
final destPath = path.join(imagesDir.path, fileName);
|
|
final destFile = File(destPath);
|
|
|
|
await destFile.writeAsBytes(bytes.buffer.asUint8List(
|
|
bytes.offsetInBytes,
|
|
bytes.lengthInBytes,
|
|
));
|
|
|
|
return destPath;
|
|
} catch (_) {
|
|
// Asset not found for this extension, try next
|
|
}
|
|
}
|
|
|
|
debugPrint('DefaultProductSeeder: no bundled image found for "$productName" '
|
|
'(looked for assets/products/$slug.{png,jpg,webp})');
|
|
return null;
|
|
}
|
|
|
|
String _toSlug(String name) {
|
|
return name
|
|
.toLowerCase()
|
|
.replaceAll(' ', '_')
|
|
.replaceAll("'", '')
|
|
.replaceAll('é', 'e')
|
|
.replaceAll('è', 'e')
|
|
.replaceAll('ê', 'e')
|
|
.replaceAll('ë', 'e')
|
|
.replaceAll('â', 'a')
|
|
.replaceAll('à', 'a')
|
|
.replaceAll('ä', 'a')
|
|
.replaceAll('û', 'u')
|
|
.replaceAll('ù', 'u')
|
|
.replaceAll('ü', 'u')
|
|
.replaceAll('ô', 'o')
|
|
.replaceAll('ö', 'o')
|
|
.replaceAll('ï', 'i')
|
|
.replaceAll('î', 'i')
|
|
.replaceAll('ç', 'c')
|
|
.replaceAll('œ', 'oe');
|
|
}
|
|
}
|