Update: lib/services/database_helper.dart

This commit is contained in:
Hadi Mottale 2025-07-08 12:38:16 +03:30
parent 25ad603299
commit 00d56530a0
1 changed files with 101 additions and 25 deletions

View File

@ -3,56 +3,122 @@ import 'package:path/path.dart';
import '../models/product.dart';
class DatabaseHelper {
static final DatabaseHelper _instance = DatabaseHelper._internal();
static Database? _database;
factory DatabaseHelper() {
return _instance;
}
DatabaseHelper._internal();
static const String tableName = 'products';
static const int _databaseVersion = 2; // Increased database version for schema migration
Future<Database> get database async {
if (_database != null) {
return _database!;
}
if (_database != null) return _database!;
_database = await _initDatabase();
return _database!;
}
Future<Database> _initDatabase() async {
String documentsDirectory = await getDatabasesPath();
String path = join(documentsDirectory, 'product_database.db');
sqfliteFfiInit();
var databaseFactory = databaseFactoryFfi;
return await openDatabase(path, version: 1, onCreate: _onCreate);
String databasesPath = await databaseFactory.getDatabasesPath();
String path = join(databasesPath, 'product_database.db');
return await databaseFactory.openDatabase(
path,
options: OpenDatabaseOptions(
version: _databaseVersion,
onCreate: _onCreate,
onUpgrade: _onUpgrade, // Add onUpgrade for schema migration
),
);
}
Future<void> _onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE products(
CREATE TABLE $tableName(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
code TEXT NOT NULL,
quantity INTEGER NOT NULL,
description TEXT,
imageUrl TEXT,
serialNumber TEXT,
model TEXT,
tags TEXT,
price REAL NOT NULL,
description TEXT
costPrice REAL,
taxRate REAL,
discount REAL,
profitMargin REAL,
quantity INTEGER NOT NULL,
unitOfMeasure TEXT,
location TEXT,
minimumStock INTEGER,
supplier TEXT,
entryDate TEXT,
manufactureDate TEXT,
expirationDate TEXT,
status TEXT,
category TEXT,
brand TEXT,
createdBy TEXT,
createdAt TEXT,
lastModifiedBy TEXT,
lastModifiedAt TEXT
)
''');
}
// Handle database schema upgrades
Future<void> _onUpgrade(Database db, int oldVersion, int newVersion) async {
if (oldVersion < 2) {
// Add new columns if upgrading from version 1 to 2
// This is a simplified migration. For real apps, check if columns exist before adding.
await db.execute('ALTER TABLE $tableName ADD COLUMN description TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN imageUrl TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN serialNumber TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN model TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN tags TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN costPrice REAL;');
await db.execute('ALTER TABLE $tableName ADD COLUMN taxRate REAL;');
await db.execute('ALTER TABLE $tableName ADD COLUMN discount REAL;');
await db.execute('ALTER TABLE $tableName ADD COLUMN profitMargin REAL;');
await db.execute('ALTER TABLE $tableName ADD COLUMN unitOfMeasure TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN location TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN minimumStock INTEGER;');
await db.execute('ALTER TABLE $tableName ADD COLUMN supplier TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN entryDate TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN manufactureDate TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN expirationDate TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN status TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN category TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN brand TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN createdBy TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN createdAt TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN lastModifiedBy TEXT;');
await db.execute('ALTER TABLE $tableName ADD COLUMN lastModifiedAt TEXT;');
}
// Add more upgrade paths for future versions if needed
}
Future<int> insertProduct(Product product) async {
final db = await database;
final now = DateTime.now().toIso8601String();
// Ensure createdAt and lastModifiedAt are set for new products
final productMap = product.toMap();
productMap['createdAt'] = now;
productMap['lastModifiedAt'] = now;
// You might want to get createdBy from a user session
// productMap['createdBy'] = 'current_user_id';
// productMap['lastModifiedBy'] = 'current_user_id';
return await db.insert(
'products',
product.toMap(),
tableName,
productMap,
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<List<Product>> getProducts() async {
final db = await database;
final List<Map<String, dynamic>> maps = await db.query('products');
final List<Map<String, dynamic>> maps = await db.query(tableName);
return List.generate(maps.length, (i) {
return Product.fromMap(maps[i]);
});
@ -60,9 +126,15 @@ class DatabaseHelper {
Future<int> updateProduct(Product product) async {
final db = await database;
final now = DateTime.now().toIso8601String();
final productMap = product.toMap();
productMap['lastModifiedAt'] = now;
// You might want to get lastModifiedBy from a user session
// productMap['lastModifiedBy'] = 'current_user_id';
return await db.update(
'products',
product.toMap(),
tableName,
productMap,
where: 'id = ?',
whereArgs: [product.id],
);
@ -70,6 +142,10 @@ class DatabaseHelper {
Future<int> deleteProduct(int id) async {
final db = await database;
return await db.delete('products', where: 'id = ?', whereArgs: [id]);
return await db.delete(
tableName,
where: 'id = ?',
whereArgs: [id],
);
}
}