- customer_master_screen.dart: const 使用と SnackBarAction の修正 - employee_master_screen.dart: DropdownButtonFormField のパラメータ追加 - database_helper.dart: jsonEncode メソッドの修正、isDeleted フィールドのチェック - main.dart: ScaffoldMessenger と Navigator のルートジェネレータ実装
139 lines
No EOL
3.6 KiB
Dart
139 lines
No EOL
3.6 KiB
Dart
// Version: 1.0.0
|
|
import 'package:sqflite/sqflite.dart';
|
|
import 'package:path/path.dart';
|
|
import 'dart:convert';
|
|
import '../models/customer.dart';
|
|
|
|
class DatabaseHelper {
|
|
static final DatabaseHelper instance = DatabaseHelper._init();
|
|
static Database? _database;
|
|
|
|
DatabaseHelper._init();
|
|
|
|
Future<Database> get database async {
|
|
if (_database != null) return _database!;
|
|
_database = await _initDB('customer_assist.db');
|
|
return _database!;
|
|
}
|
|
|
|
Future<Database> _initDB(String filePath) async {
|
|
final dbPath = await getDatabasesPath();
|
|
final path = join(dbPath, filePath);
|
|
|
|
return await openDatabase(
|
|
path,
|
|
version: 1,
|
|
onCreate: _createDB,
|
|
);
|
|
}
|
|
|
|
Future<void> _createDB(Database db, int version) async {
|
|
const idType = 'INTEGER PRIMARY KEY AUTOINCREMENT';
|
|
const textType = 'TEXT NOT NULL';
|
|
const intType = 'INTEGER';
|
|
|
|
await db.execute('''
|
|
CREATE TABLE customers (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
customer_code TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
phone_number TEXT NOT NULL,
|
|
email TEXT NOT NULL,
|
|
address TEXT NOT NULL,
|
|
sales_person_id INTEGER,
|
|
tax_rate INTEGER DEFAULT 8, // Default 10%
|
|
discount_rate INTEGER DEFAULT 0, // Default 0%
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
)
|
|
''');
|
|
|
|
await db.execute('''
|
|
CREATE TABLE customer_snapshots (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
customer_id INTEGER NOT NULL,
|
|
data_json TEXT NOT NULL,
|
|
created_at TEXT NOT NULL
|
|
)
|
|
''');
|
|
}
|
|
|
|
Future<int> insert(Customer customer) async {
|
|
final db = await instance.database;
|
|
return await db.insert('customers', customer.toMap());
|
|
}
|
|
|
|
Future<List<Customer>> getCustomers() async {
|
|
final db = await instance.database;
|
|
final List<Map<String, dynamic>> maps = await db.query('customers');
|
|
|
|
return (maps as List)
|
|
.map((json) => Customer.fromMap(json))
|
|
.where((c) => c.isDeleted == 0)
|
|
.toList();
|
|
}
|
|
|
|
Future<Customer?> getCustomer(int id) async {
|
|
final db = await instance.database;
|
|
final maps = await db.query(
|
|
'customers',
|
|
where: 'id = ?',
|
|
whereArgs: [id],
|
|
);
|
|
|
|
if (maps.isEmpty) return null;
|
|
return Customer.fromMap(maps.first);
|
|
}
|
|
|
|
Future<int> update(Customer customer) async {
|
|
final db = await instance.database;
|
|
return await db.update(
|
|
'customers',
|
|
customer.toMap(),
|
|
where: 'id = ?',
|
|
whereArgs: [customer.id],
|
|
);
|
|
}
|
|
|
|
Future<int> delete(int id) async {
|
|
final db = await instance.database;
|
|
return await db.update(
|
|
'customers',
|
|
{'is_deleted': 1}, // Soft delete
|
|
where: 'id = ?',
|
|
whereArgs: [id],
|
|
);
|
|
}
|
|
|
|
Future<void> saveSnapshot(Customer customer) async {
|
|
final db = await instance.database;
|
|
final id = customer.id;
|
|
final now = DateTime.now().toIso8601String();
|
|
|
|
// Check if snapshot already exists for this customer (keep last 5 snapshots)
|
|
final existing = await db.query(
|
|
'customer_snapshots',
|
|
where: 'customer_id = ?',
|
|
whereArgs: [id],
|
|
limit: 6,
|
|
);
|
|
|
|
if (existing.length > 5) {
|
|
// Delete oldest snapshot
|
|
final oldestId = existing.first['id'] as int;
|
|
await db.delete('customer_snapshots', where: 'id = ?', whereArgs: [oldestId]);
|
|
}
|
|
|
|
// Insert new snapshot
|
|
await db.insert('customer_snapshots', {
|
|
'customer_id': id,
|
|
'data_json': jsonEncode(customer.toMap()),
|
|
'created_at': now,
|
|
});
|
|
}
|
|
|
|
Future<void> close() async {
|
|
final db = await instance.database;
|
|
db.close();
|
|
}
|
|
} |