third commit
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
@@ -16,7 +14,7 @@ class AppDatabase {
|
||||
static final AppDatabase instance = AppDatabase._();
|
||||
|
||||
static const String _fileName = 'nearle_pos.db';
|
||||
static const int _version = 1;
|
||||
static const int _version = 3;
|
||||
|
||||
Database? _db;
|
||||
|
||||
@@ -37,7 +35,21 @@ class AppDatabase {
|
||||
Future<void> open({String? overridePath}) async {
|
||||
if (_db != null) return;
|
||||
|
||||
if (!kIsWeb && (Platform.isWindows || Platform.isLinux || Platform.isMacOS)) {
|
||||
if (kIsWeb) {
|
||||
// sqflite has no web implementation. Fail loudly here rather than
|
||||
// letting databaseFactory throw something unreadable further down.
|
||||
throw UnsupportedError(
|
||||
'Nearle POS stores bills in SQLite, which has no web implementation. '
|
||||
'Run the app on macOS, Windows, Linux or an Android tablet.',
|
||||
);
|
||||
}
|
||||
|
||||
const desktop = {
|
||||
TargetPlatform.windows,
|
||||
TargetPlatform.linux,
|
||||
TargetPlatform.macOS,
|
||||
};
|
||||
if (desktop.contains(defaultTargetPlatform)) {
|
||||
sqfliteFfiInit();
|
||||
databaseFactory = databaseFactoryFfi;
|
||||
}
|
||||
@@ -52,7 +64,12 @@ class AppDatabase {
|
||||
onConfigure: (db) => db.execute('PRAGMA foreign_keys = ON'),
|
||||
onCreate: (db, version) async => _createSchema(db),
|
||||
onUpgrade: (db, from, to) async {
|
||||
// Single version so far; migrations land here as the schema grows.
|
||||
if (from < 2) await db.execute(_createDayArchive);
|
||||
if (from < 3) {
|
||||
await db.execute(
|
||||
'ALTER TABLE ${Tables.products} ADD COLUMN hsn_code TEXT',
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -84,6 +101,7 @@ class AppDatabase {
|
||||
for (final t in const [
|
||||
Tables.orderItems,
|
||||
Tables.orders,
|
||||
Tables.dayArchive,
|
||||
Tables.products,
|
||||
Tables.customers,
|
||||
Tables.parkedBills,
|
||||
@@ -111,6 +129,7 @@ class AppDatabase {
|
||||
image_url TEXT,
|
||||
unit TEXT NOT NULL DEFAULT 'piece',
|
||||
gst_rate REAL NOT NULL DEFAULT 0.18,
|
||||
hsn_code TEXT,
|
||||
brand TEXT,
|
||||
is_active INTEGER NOT NULL DEFAULT 1,
|
||||
updated_at INTEGER NOT NULL
|
||||
@@ -232,6 +251,9 @@ class AppDatabase {
|
||||
)
|
||||
''');
|
||||
|
||||
// ------------------------------------------------------------- archive
|
||||
await db.execute(_createDayArchive);
|
||||
|
||||
// ----------------------------------------------------------------- meta
|
||||
await db.execute('''
|
||||
CREATE TABLE ${Tables.meta} (
|
||||
@@ -242,9 +264,34 @@ class AppDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
/// Running totals per business day.
|
||||
///
|
||||
/// Synced orders are deleted from the terminal, so their figures are folded in
|
||||
/// here first — otherwise "Bills Today" would collapse to zero the moment a
|
||||
/// mid-shift sync ran.
|
||||
const String _createDayArchive = '''
|
||||
CREATE TABLE day_archive (
|
||||
business_date TEXT PRIMARY KEY,
|
||||
bill_count INTEGER NOT NULL DEFAULT 0,
|
||||
item_count REAL NOT NULL DEFAULT 0,
|
||||
gross_sales REAL NOT NULL DEFAULT 0,
|
||||
tax_collected REAL NOT NULL DEFAULT 0,
|
||||
discount_given REAL NOT NULL DEFAULT 0,
|
||||
round_off REAL NOT NULL DEFAULT 0,
|
||||
points_issued INTEGER NOT NULL DEFAULT 0,
|
||||
points_redeemed INTEGER NOT NULL DEFAULT 0,
|
||||
payments_json TEXT NOT NULL DEFAULT '{}',
|
||||
first_bill_at INTEGER,
|
||||
last_bill_at INTEGER,
|
||||
synced_bills INTEGER NOT NULL DEFAULT 0
|
||||
)
|
||||
''';
|
||||
|
||||
class Tables {
|
||||
const Tables._();
|
||||
|
||||
static const String dayArchive = 'day_archive';
|
||||
|
||||
static const String products = 'products';
|
||||
static const String customers = 'customers';
|
||||
static const String orders = 'orders';
|
||||
@@ -260,4 +307,11 @@ class MetaKeys {
|
||||
static const String lastImportAt = 'last_import_at';
|
||||
static const String catalogueRevision = 'catalogue_revision';
|
||||
static const String invoiceSequence = 'invoice_sequence';
|
||||
|
||||
/// Printer chosen in Settings. Stored as the printer's `url`, which is what
|
||||
/// `Printing.directPrintPdf` needs to target it without a dialog.
|
||||
static const String printerUrl = 'printer_url';
|
||||
static const String printerName = 'printer_name';
|
||||
static const String autoPrint = 'auto_print';
|
||||
static const String openDrawer = 'open_cash_drawer';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user