feat: add default mock data
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
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'),
|
||||
('Chimay Blue', 500, 20, 'Bier'),
|
||||
('Witte Wijn', 380, 50, 'Wijn'),
|
||||
('Rode Wijn', 400, 45, 'Wijn'),
|
||||
('Rosé', 350, 40, 'Wijn'),
|
||||
('Cava', 650, 15, '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'),
|
||||
('Nootjes', 280, 35, 'Snacks'),
|
||||
('Kroketten', 350, 30, 'Snacks'),
|
||||
('Bitterballen', 320, 30, 'Snacks'),
|
||||
('Koffie', 280, 200, 'Coffee'),
|
||||
('Espresso', 250, 200, 'Coffee'),
|
||||
('Latte Macchiato', 350, 150, 'Coffee'),
|
||||
('Warme Chocomelk', 320, 100, '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');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user