feat: add payment method
This commit is contained in:
+10
-1
@@ -34,7 +34,7 @@ class _KoolTabAppState extends State<KoolTabApp> {
|
|||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
routerConfig: widget.router,
|
routerConfig: widget.router,
|
||||||
theme: lightTheme,
|
theme: lightTheme,
|
||||||
darkTheme: darkTheme,
|
darkTheme: _themeFor(settings.themeMode),
|
||||||
themeMode: _mapThemeMode(settings.themeMode, context),
|
themeMode: _mapThemeMode(settings.themeMode, context),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -45,8 +45,17 @@ class _KoolTabAppState extends State<KoolTabApp> {
|
|||||||
return switch (mode) {
|
return switch (mode) {
|
||||||
AppThemeMode.dark => ThemeMode.dark,
|
AppThemeMode.dark => ThemeMode.dark,
|
||||||
AppThemeMode.light => ThemeMode.light,
|
AppThemeMode.light => ThemeMode.light,
|
||||||
|
AppThemeMode.ugly => ThemeMode.dark,
|
||||||
AppThemeMode.system =>
|
AppThemeMode.system =>
|
||||||
hasLoaded ? ThemeMode.system : ThemeMode.dark,
|
hasLoaded ? ThemeMode.system : ThemeMode.dark,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ThemeData _themeFor(AppThemeMode mode) {
|
||||||
|
return switch (mode) {
|
||||||
|
AppThemeMode.ugly => uglyTheme,
|
||||||
|
_ => darkTheme,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -73,6 +73,8 @@ class ClosedTabs extends Table {
|
|||||||
|
|
||||||
DateTimeColumn get closedAt => dateTime()();
|
DateTimeColumn get closedAt => dateTime()();
|
||||||
|
|
||||||
|
TextColumn get paymentMethod => text().withDefault(const Constant('cash'))();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Set<Column> get primaryKey => {id};
|
Set<Column> get primaryKey => {id};
|
||||||
}
|
}
|
||||||
@@ -126,7 +128,7 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
AppDatabase([QueryExecutor? executor]) : super(executor ?? _openConnection());
|
AppDatabase([QueryExecutor? executor]) : super(executor ?? _openConnection());
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 5;
|
int get schemaVersion => 6;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MigrationStrategy get migration {
|
MigrationStrategy get migration {
|
||||||
@@ -152,6 +154,10 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
if (from < 5) {
|
if (from < 5) {
|
||||||
await migrator.createTable(appSettingsTable);
|
await migrator.createTable(appSettingsTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (from < 6) {
|
||||||
|
await migrator.addColumn(closedTabs, closedTabs.paymentMethod);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1417,12 +1417,25 @@ class $ClosedTabsTable extends ClosedTabs
|
|||||||
type: DriftSqlType.dateTime,
|
type: DriftSqlType.dateTime,
|
||||||
requiredDuringInsert: true,
|
requiredDuringInsert: true,
|
||||||
);
|
);
|
||||||
|
static const VerificationMeta _paymentMethodMeta = const VerificationMeta(
|
||||||
|
'paymentMethod',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> paymentMethod = GeneratedColumn<String>(
|
||||||
|
'payment_method',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultValue: const Constant('cash'),
|
||||||
|
);
|
||||||
@override
|
@override
|
||||||
List<GeneratedColumn> get $columns => [
|
List<GeneratedColumn> get $columns => [
|
||||||
id,
|
id,
|
||||||
originalTabId,
|
originalTabId,
|
||||||
customerName,
|
customerName,
|
||||||
closedAt,
|
closedAt,
|
||||||
|
paymentMethod,
|
||||||
];
|
];
|
||||||
@override
|
@override
|
||||||
String get aliasedName => _alias ?? actualTableName;
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
@@ -1471,6 +1484,15 @@ class $ClosedTabsTable extends ClosedTabs
|
|||||||
} else if (isInserting) {
|
} else if (isInserting) {
|
||||||
context.missing(_closedAtMeta);
|
context.missing(_closedAtMeta);
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('payment_method')) {
|
||||||
|
context.handle(
|
||||||
|
_paymentMethodMeta,
|
||||||
|
paymentMethod.isAcceptableOrUnknown(
|
||||||
|
data['payment_method']!,
|
||||||
|
_paymentMethodMeta,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1496,6 +1518,10 @@ class $ClosedTabsTable extends ClosedTabs
|
|||||||
DriftSqlType.dateTime,
|
DriftSqlType.dateTime,
|
||||||
data['${effectivePrefix}closed_at'],
|
data['${effectivePrefix}closed_at'],
|
||||||
)!,
|
)!,
|
||||||
|
paymentMethod: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}payment_method'],
|
||||||
|
)!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1510,11 +1536,13 @@ class ClosedTabsRow extends DataClass implements Insertable<ClosedTabsRow> {
|
|||||||
final String originalTabId;
|
final String originalTabId;
|
||||||
final String customerName;
|
final String customerName;
|
||||||
final DateTime closedAt;
|
final DateTime closedAt;
|
||||||
|
final String paymentMethod;
|
||||||
const ClosedTabsRow({
|
const ClosedTabsRow({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.originalTabId,
|
required this.originalTabId,
|
||||||
required this.customerName,
|
required this.customerName,
|
||||||
required this.closedAt,
|
required this.closedAt,
|
||||||
|
required this.paymentMethod,
|
||||||
});
|
});
|
||||||
@override
|
@override
|
||||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
@@ -1523,6 +1551,7 @@ class ClosedTabsRow extends DataClass implements Insertable<ClosedTabsRow> {
|
|||||||
map['original_tab_id'] = Variable<String>(originalTabId);
|
map['original_tab_id'] = Variable<String>(originalTabId);
|
||||||
map['customer_name'] = Variable<String>(customerName);
|
map['customer_name'] = Variable<String>(customerName);
|
||||||
map['closed_at'] = Variable<DateTime>(closedAt);
|
map['closed_at'] = Variable<DateTime>(closedAt);
|
||||||
|
map['payment_method'] = Variable<String>(paymentMethod);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1532,6 +1561,7 @@ class ClosedTabsRow extends DataClass implements Insertable<ClosedTabsRow> {
|
|||||||
originalTabId: Value(originalTabId),
|
originalTabId: Value(originalTabId),
|
||||||
customerName: Value(customerName),
|
customerName: Value(customerName),
|
||||||
closedAt: Value(closedAt),
|
closedAt: Value(closedAt),
|
||||||
|
paymentMethod: Value(paymentMethod),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1545,6 +1575,7 @@ class ClosedTabsRow extends DataClass implements Insertable<ClosedTabsRow> {
|
|||||||
originalTabId: serializer.fromJson<String>(json['originalTabId']),
|
originalTabId: serializer.fromJson<String>(json['originalTabId']),
|
||||||
customerName: serializer.fromJson<String>(json['customerName']),
|
customerName: serializer.fromJson<String>(json['customerName']),
|
||||||
closedAt: serializer.fromJson<DateTime>(json['closedAt']),
|
closedAt: serializer.fromJson<DateTime>(json['closedAt']),
|
||||||
|
paymentMethod: serializer.fromJson<String>(json['paymentMethod']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@override
|
@override
|
||||||
@@ -1555,6 +1586,7 @@ class ClosedTabsRow extends DataClass implements Insertable<ClosedTabsRow> {
|
|||||||
'originalTabId': serializer.toJson<String>(originalTabId),
|
'originalTabId': serializer.toJson<String>(originalTabId),
|
||||||
'customerName': serializer.toJson<String>(customerName),
|
'customerName': serializer.toJson<String>(customerName),
|
||||||
'closedAt': serializer.toJson<DateTime>(closedAt),
|
'closedAt': serializer.toJson<DateTime>(closedAt),
|
||||||
|
'paymentMethod': serializer.toJson<String>(paymentMethod),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1563,11 +1595,13 @@ class ClosedTabsRow extends DataClass implements Insertable<ClosedTabsRow> {
|
|||||||
String? originalTabId,
|
String? originalTabId,
|
||||||
String? customerName,
|
String? customerName,
|
||||||
DateTime? closedAt,
|
DateTime? closedAt,
|
||||||
|
String? paymentMethod,
|
||||||
}) => ClosedTabsRow(
|
}) => ClosedTabsRow(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
originalTabId: originalTabId ?? this.originalTabId,
|
originalTabId: originalTabId ?? this.originalTabId,
|
||||||
customerName: customerName ?? this.customerName,
|
customerName: customerName ?? this.customerName,
|
||||||
closedAt: closedAt ?? this.closedAt,
|
closedAt: closedAt ?? this.closedAt,
|
||||||
|
paymentMethod: paymentMethod ?? this.paymentMethod,
|
||||||
);
|
);
|
||||||
ClosedTabsRow copyWithCompanion(ClosedTabsCompanion data) {
|
ClosedTabsRow copyWithCompanion(ClosedTabsCompanion data) {
|
||||||
return ClosedTabsRow(
|
return ClosedTabsRow(
|
||||||
@@ -1579,6 +1613,9 @@ class ClosedTabsRow extends DataClass implements Insertable<ClosedTabsRow> {
|
|||||||
? data.customerName.value
|
? data.customerName.value
|
||||||
: this.customerName,
|
: this.customerName,
|
||||||
closedAt: data.closedAt.present ? data.closedAt.value : this.closedAt,
|
closedAt: data.closedAt.present ? data.closedAt.value : this.closedAt,
|
||||||
|
paymentMethod: data.paymentMethod.present
|
||||||
|
? data.paymentMethod.value
|
||||||
|
: this.paymentMethod,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1588,13 +1625,15 @@ class ClosedTabsRow extends DataClass implements Insertable<ClosedTabsRow> {
|
|||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('originalTabId: $originalTabId, ')
|
..write('originalTabId: $originalTabId, ')
|
||||||
..write('customerName: $customerName, ')
|
..write('customerName: $customerName, ')
|
||||||
..write('closedAt: $closedAt')
|
..write('closedAt: $closedAt, ')
|
||||||
|
..write('paymentMethod: $paymentMethod')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(id, originalTabId, customerName, closedAt);
|
int get hashCode =>
|
||||||
|
Object.hash(id, originalTabId, customerName, closedAt, paymentMethod);
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
identical(this, other) ||
|
identical(this, other) ||
|
||||||
@@ -1602,7 +1641,8 @@ class ClosedTabsRow extends DataClass implements Insertable<ClosedTabsRow> {
|
|||||||
other.id == this.id &&
|
other.id == this.id &&
|
||||||
other.originalTabId == this.originalTabId &&
|
other.originalTabId == this.originalTabId &&
|
||||||
other.customerName == this.customerName &&
|
other.customerName == this.customerName &&
|
||||||
other.closedAt == this.closedAt);
|
other.closedAt == this.closedAt &&
|
||||||
|
other.paymentMethod == this.paymentMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClosedTabsCompanion extends UpdateCompanion<ClosedTabsRow> {
|
class ClosedTabsCompanion extends UpdateCompanion<ClosedTabsRow> {
|
||||||
@@ -1610,12 +1650,14 @@ class ClosedTabsCompanion extends UpdateCompanion<ClosedTabsRow> {
|
|||||||
final Value<String> originalTabId;
|
final Value<String> originalTabId;
|
||||||
final Value<String> customerName;
|
final Value<String> customerName;
|
||||||
final Value<DateTime> closedAt;
|
final Value<DateTime> closedAt;
|
||||||
|
final Value<String> paymentMethod;
|
||||||
final Value<int> rowid;
|
final Value<int> rowid;
|
||||||
const ClosedTabsCompanion({
|
const ClosedTabsCompanion({
|
||||||
this.id = const Value.absent(),
|
this.id = const Value.absent(),
|
||||||
this.originalTabId = const Value.absent(),
|
this.originalTabId = const Value.absent(),
|
||||||
this.customerName = const Value.absent(),
|
this.customerName = const Value.absent(),
|
||||||
this.closedAt = const Value.absent(),
|
this.closedAt = const Value.absent(),
|
||||||
|
this.paymentMethod = const Value.absent(),
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
});
|
});
|
||||||
ClosedTabsCompanion.insert({
|
ClosedTabsCompanion.insert({
|
||||||
@@ -1623,6 +1665,7 @@ class ClosedTabsCompanion extends UpdateCompanion<ClosedTabsRow> {
|
|||||||
required String originalTabId,
|
required String originalTabId,
|
||||||
required String customerName,
|
required String customerName,
|
||||||
required DateTime closedAt,
|
required DateTime closedAt,
|
||||||
|
this.paymentMethod = const Value.absent(),
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
}) : id = Value(id),
|
}) : id = Value(id),
|
||||||
originalTabId = Value(originalTabId),
|
originalTabId = Value(originalTabId),
|
||||||
@@ -1633,6 +1676,7 @@ class ClosedTabsCompanion extends UpdateCompanion<ClosedTabsRow> {
|
|||||||
Expression<String>? originalTabId,
|
Expression<String>? originalTabId,
|
||||||
Expression<String>? customerName,
|
Expression<String>? customerName,
|
||||||
Expression<DateTime>? closedAt,
|
Expression<DateTime>? closedAt,
|
||||||
|
Expression<String>? paymentMethod,
|
||||||
Expression<int>? rowid,
|
Expression<int>? rowid,
|
||||||
}) {
|
}) {
|
||||||
return RawValuesInsertable({
|
return RawValuesInsertable({
|
||||||
@@ -1640,6 +1684,7 @@ class ClosedTabsCompanion extends UpdateCompanion<ClosedTabsRow> {
|
|||||||
if (originalTabId != null) 'original_tab_id': originalTabId,
|
if (originalTabId != null) 'original_tab_id': originalTabId,
|
||||||
if (customerName != null) 'customer_name': customerName,
|
if (customerName != null) 'customer_name': customerName,
|
||||||
if (closedAt != null) 'closed_at': closedAt,
|
if (closedAt != null) 'closed_at': closedAt,
|
||||||
|
if (paymentMethod != null) 'payment_method': paymentMethod,
|
||||||
if (rowid != null) 'rowid': rowid,
|
if (rowid != null) 'rowid': rowid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1649,6 +1694,7 @@ class ClosedTabsCompanion extends UpdateCompanion<ClosedTabsRow> {
|
|||||||
Value<String>? originalTabId,
|
Value<String>? originalTabId,
|
||||||
Value<String>? customerName,
|
Value<String>? customerName,
|
||||||
Value<DateTime>? closedAt,
|
Value<DateTime>? closedAt,
|
||||||
|
Value<String>? paymentMethod,
|
||||||
Value<int>? rowid,
|
Value<int>? rowid,
|
||||||
}) {
|
}) {
|
||||||
return ClosedTabsCompanion(
|
return ClosedTabsCompanion(
|
||||||
@@ -1656,6 +1702,7 @@ class ClosedTabsCompanion extends UpdateCompanion<ClosedTabsRow> {
|
|||||||
originalTabId: originalTabId ?? this.originalTabId,
|
originalTabId: originalTabId ?? this.originalTabId,
|
||||||
customerName: customerName ?? this.customerName,
|
customerName: customerName ?? this.customerName,
|
||||||
closedAt: closedAt ?? this.closedAt,
|
closedAt: closedAt ?? this.closedAt,
|
||||||
|
paymentMethod: paymentMethod ?? this.paymentMethod,
|
||||||
rowid: rowid ?? this.rowid,
|
rowid: rowid ?? this.rowid,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1675,6 +1722,9 @@ class ClosedTabsCompanion extends UpdateCompanion<ClosedTabsRow> {
|
|||||||
if (closedAt.present) {
|
if (closedAt.present) {
|
||||||
map['closed_at'] = Variable<DateTime>(closedAt.value);
|
map['closed_at'] = Variable<DateTime>(closedAt.value);
|
||||||
}
|
}
|
||||||
|
if (paymentMethod.present) {
|
||||||
|
map['payment_method'] = Variable<String>(paymentMethod.value);
|
||||||
|
}
|
||||||
if (rowid.present) {
|
if (rowid.present) {
|
||||||
map['rowid'] = Variable<int>(rowid.value);
|
map['rowid'] = Variable<int>(rowid.value);
|
||||||
}
|
}
|
||||||
@@ -1688,6 +1738,7 @@ class ClosedTabsCompanion extends UpdateCompanion<ClosedTabsRow> {
|
|||||||
..write('originalTabId: $originalTabId, ')
|
..write('originalTabId: $originalTabId, ')
|
||||||
..write('customerName: $customerName, ')
|
..write('customerName: $customerName, ')
|
||||||
..write('closedAt: $closedAt, ')
|
..write('closedAt: $closedAt, ')
|
||||||
|
..write('paymentMethod: $paymentMethod, ')
|
||||||
..write('rowid: $rowid')
|
..write('rowid: $rowid')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
@@ -3536,6 +3587,7 @@ typedef $$ClosedTabsTableCreateCompanionBuilder =
|
|||||||
required String originalTabId,
|
required String originalTabId,
|
||||||
required String customerName,
|
required String customerName,
|
||||||
required DateTime closedAt,
|
required DateTime closedAt,
|
||||||
|
Value<String> paymentMethod,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
typedef $$ClosedTabsTableUpdateCompanionBuilder =
|
typedef $$ClosedTabsTableUpdateCompanionBuilder =
|
||||||
@@ -3544,6 +3596,7 @@ typedef $$ClosedTabsTableUpdateCompanionBuilder =
|
|||||||
Value<String> originalTabId,
|
Value<String> originalTabId,
|
||||||
Value<String> customerName,
|
Value<String> customerName,
|
||||||
Value<DateTime> closedAt,
|
Value<DateTime> closedAt,
|
||||||
|
Value<String> paymentMethod,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -3575,6 +3628,11 @@ class $$ClosedTabsTableFilterComposer
|
|||||||
column: $table.closedAt,
|
column: $table.closedAt,
|
||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnFilters<String> get paymentMethod => $composableBuilder(
|
||||||
|
column: $table.paymentMethod,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class $$ClosedTabsTableOrderingComposer
|
class $$ClosedTabsTableOrderingComposer
|
||||||
@@ -3605,6 +3663,11 @@ class $$ClosedTabsTableOrderingComposer
|
|||||||
column: $table.closedAt,
|
column: $table.closedAt,
|
||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<String> get paymentMethod => $composableBuilder(
|
||||||
|
column: $table.paymentMethod,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class $$ClosedTabsTableAnnotationComposer
|
class $$ClosedTabsTableAnnotationComposer
|
||||||
@@ -3631,6 +3694,11 @@ class $$ClosedTabsTableAnnotationComposer
|
|||||||
|
|
||||||
GeneratedColumn<DateTime> get closedAt =>
|
GeneratedColumn<DateTime> get closedAt =>
|
||||||
$composableBuilder(column: $table.closedAt, builder: (column) => column);
|
$composableBuilder(column: $table.closedAt, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get paymentMethod => $composableBuilder(
|
||||||
|
column: $table.paymentMethod,
|
||||||
|
builder: (column) => column,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class $$ClosedTabsTableTableManager
|
class $$ClosedTabsTableTableManager
|
||||||
@@ -3668,12 +3736,14 @@ class $$ClosedTabsTableTableManager
|
|||||||
Value<String> originalTabId = const Value.absent(),
|
Value<String> originalTabId = const Value.absent(),
|
||||||
Value<String> customerName = const Value.absent(),
|
Value<String> customerName = const Value.absent(),
|
||||||
Value<DateTime> closedAt = const Value.absent(),
|
Value<DateTime> closedAt = const Value.absent(),
|
||||||
|
Value<String> paymentMethod = const Value.absent(),
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) => ClosedTabsCompanion(
|
}) => ClosedTabsCompanion(
|
||||||
id: id,
|
id: id,
|
||||||
originalTabId: originalTabId,
|
originalTabId: originalTabId,
|
||||||
customerName: customerName,
|
customerName: customerName,
|
||||||
closedAt: closedAt,
|
closedAt: closedAt,
|
||||||
|
paymentMethod: paymentMethod,
|
||||||
rowid: rowid,
|
rowid: rowid,
|
||||||
),
|
),
|
||||||
createCompanionCallback:
|
createCompanionCallback:
|
||||||
@@ -3682,12 +3752,14 @@ class $$ClosedTabsTableTableManager
|
|||||||
required String originalTabId,
|
required String originalTabId,
|
||||||
required String customerName,
|
required String customerName,
|
||||||
required DateTime closedAt,
|
required DateTime closedAt,
|
||||||
|
Value<String> paymentMethod = const Value.absent(),
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) => ClosedTabsCompanion.insert(
|
}) => ClosedTabsCompanion.insert(
|
||||||
id: id,
|
id: id,
|
||||||
originalTabId: originalTabId,
|
originalTabId: originalTabId,
|
||||||
customerName: customerName,
|
customerName: customerName,
|
||||||
closedAt: closedAt,
|
closedAt: closedAt,
|
||||||
|
paymentMethod: paymentMethod,
|
||||||
rowid: rowid,
|
rowid: rowid,
|
||||||
),
|
),
|
||||||
withReferenceMapper: (p0) => p0
|
withReferenceMapper: (p0) => p0
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ class ClosedTab {
|
|||||||
final String originalTabId;
|
final String originalTabId;
|
||||||
final String customerName;
|
final String customerName;
|
||||||
final DateTime closedAt;
|
final DateTime closedAt;
|
||||||
|
final String paymentMethod;
|
||||||
final List<ClosedTabItem> items;
|
final List<ClosedTabItem> items;
|
||||||
|
|
||||||
ClosedTab({
|
ClosedTab({
|
||||||
@@ -14,6 +15,7 @@ class ClosedTab {
|
|||||||
required this.originalTabId,
|
required this.originalTabId,
|
||||||
required this.customerName,
|
required this.customerName,
|
||||||
required this.closedAt,
|
required this.closedAt,
|
||||||
|
required this.paymentMethod,
|
||||||
required this.items,
|
required this.items,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -25,6 +27,14 @@ class ClosedTab {
|
|||||||
String get formattedTotal =>
|
String get formattedTotal =>
|
||||||
NumberFormat.simpleCurrency().format(totalInCents / 100);
|
NumberFormat.simpleCurrency().format(totalInCents / 100);
|
||||||
|
|
||||||
|
String get formattedPaymentMethod {
|
||||||
|
return switch (paymentMethod) {
|
||||||
|
'cash' => 'Cash',
|
||||||
|
'payconiq' => 'Payconiq',
|
||||||
|
_ => 'Cash',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
identical(this, other) ||
|
identical(this, other) ||
|
||||||
@@ -33,6 +43,7 @@ class ClosedTab {
|
|||||||
originalTabId == other.originalTabId &&
|
originalTabId == other.originalTabId &&
|
||||||
customerName == other.customerName &&
|
customerName == other.customerName &&
|
||||||
closedAt == other.closedAt &&
|
closedAt == other.closedAt &&
|
||||||
|
paymentMethod == other.paymentMethod &&
|
||||||
_listEquals(items, other.items);
|
_listEquals(items, other.items);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -41,6 +52,7 @@ class ClosedTab {
|
|||||||
originalTabId,
|
originalTabId,
|
||||||
customerName,
|
customerName,
|
||||||
closedAt,
|
closedAt,
|
||||||
|
paymentMethod,
|
||||||
Object.hashAll(items),
|
Object.hashAll(items),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -53,4 +65,4 @@ bool _listEquals<T>(List<T>? a, List<T>? b) {
|
|||||||
if (a[i] != b[i]) return false;
|
if (a[i] != b[i]) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
enum AppThemeMode { system, light, dark }
|
enum AppThemeMode { system, light, dark, ugly }
|
||||||
|
|
||||||
class AppSettings {
|
class AppSettings {
|
||||||
final bool pinRequired;
|
final bool pinRequired;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ abstract class BarTabService {
|
|||||||
|
|
||||||
/// Archives the tab's current items into history and clears them.
|
/// Archives the tab's current items into history and clears them.
|
||||||
/// The tab itself stays open under the same customer name.
|
/// The tab itself stays open under the same customer name.
|
||||||
Future<void> closeTab(String tabId);
|
Future<void> closeTab(String tabId, {String paymentMethod = 'cash'});
|
||||||
|
|
||||||
Future<List<ClosedTab>> getClosedTabs();
|
Future<List<ClosedTab>> getClosedTabs();
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ class DriftBarTabService implements BarTabService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> closeTab(String tabId) async {
|
Future<void> closeTab(String tabId, {String paymentMethod = 'cash'}) async {
|
||||||
await database.transaction(() async {
|
await database.transaction(() async {
|
||||||
final tabQuery = database.select(database.barTabs)
|
final tabQuery = database.select(database.barTabs)
|
||||||
..where((tab) => tab.id.equals(tabId));
|
..where((tab) => tab.id.equals(tabId));
|
||||||
@@ -261,6 +261,7 @@ class DriftBarTabService implements BarTabService {
|
|||||||
originalTabId: tabId,
|
originalTabId: tabId,
|
||||||
customerName: tabRow.customerName,
|
customerName: tabRow.customerName,
|
||||||
closedAt: DateTime.now(),
|
closedAt: DateTime.now(),
|
||||||
|
paymentMethod: Value(paymentMethod),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -325,6 +326,7 @@ class DriftBarTabService implements BarTabService {
|
|||||||
originalTabId: row.originalTabId,
|
originalTabId: row.originalTabId,
|
||||||
customerName: row.customerName,
|
customerName: row.customerName,
|
||||||
closedAt: row.closedAt,
|
closedAt: row.closedAt,
|
||||||
|
paymentMethod: row.paymentMethod,
|
||||||
items: itemRows.map<ClosedTabItem>(_mapClosedItemRow).toList(),
|
items: itemRows.map<ClosedTabItem>(_mapClosedItemRow).toList(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
+319
@@ -727,3 +727,322 @@ final ThemeData lightTheme = ThemeData(
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Ugly theme — intentionally repulsive
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const _uglyFg = Color(0xFFFFF700);
|
||||||
|
const _uglyBg = Color(0xFF00FFFF);
|
||||||
|
const _uglySurface = Color(0xFFFF00FF);
|
||||||
|
const _uglyPrimary = Color(0xFFCCFF00);
|
||||||
|
const _uglySecondary = Color(0xFFFF1493);
|
||||||
|
const _uglyError = Color(0xFFFF6600);
|
||||||
|
|
||||||
|
final ThemeData uglyTheme = ThemeData(
|
||||||
|
useMaterial3: true,
|
||||||
|
brightness: Brightness.light,
|
||||||
|
|
||||||
|
colorScheme: const ColorScheme.light(
|
||||||
|
primary: _uglyPrimary,
|
||||||
|
secondary: _uglySecondary,
|
||||||
|
surface: _uglySurface,
|
||||||
|
error: _uglyError,
|
||||||
|
onPrimary: Color(0xFF0000FF),
|
||||||
|
onSecondary: _uglyFg,
|
||||||
|
onSurface: _uglyFg,
|
||||||
|
onError: Color(0xFF000000),
|
||||||
|
onSurfaceVariant: Color(0xFFFF0000),
|
||||||
|
),
|
||||||
|
|
||||||
|
scaffoldBackgroundColor: _uglyBg,
|
||||||
|
canvasColor: _uglyBg,
|
||||||
|
|
||||||
|
appBarTheme: const AppBarTheme(
|
||||||
|
elevation: 8,
|
||||||
|
shadowColor: Color(0xFFFF0000),
|
||||||
|
centerTitle: true,
|
||||||
|
backgroundColor: _uglySecondary,
|
||||||
|
foregroundColor: _uglyFg,
|
||||||
|
surfaceTintColor: _uglyError,
|
||||||
|
titleTextStyle: TextStyle(
|
||||||
|
fontSize: 30,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
letterSpacing: 4,
|
||||||
|
color: _uglyFg,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
iconTheme: IconThemeData(color: _uglyBg, size: 30),
|
||||||
|
actionsIconTheme: IconThemeData(color: _uglyFg, size: 30),
|
||||||
|
toolbarHeight: 80,
|
||||||
|
),
|
||||||
|
|
||||||
|
iconButtonTheme: IconButtonThemeData(
|
||||||
|
style: IconButton.styleFrom(
|
||||||
|
backgroundColor: _uglyError,
|
||||||
|
foregroundColor: Colors.black,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(0),
|
||||||
|
topRight: Radius.circular(20),
|
||||||
|
bottomLeft: Radius.circular(20),
|
||||||
|
bottomRight: Radius.circular(0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
side: const BorderSide(color: _uglyPrimary, width: 3),
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
cardTheme: CardThemeData(
|
||||||
|
color: _uglySurface,
|
||||||
|
elevation: 8,
|
||||||
|
shadowColor: _uglyPrimary,
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 0, vertical: 18),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(4),
|
||||||
|
topRight: Radius.circular(30),
|
||||||
|
bottomLeft: Radius.circular(30),
|
||||||
|
bottomRight: Radius.circular(4),
|
||||||
|
),
|
||||||
|
side: const BorderSide(color: _uglySecondary, width: 4),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
filledButtonTheme: FilledButtonThemeData(
|
||||||
|
style: FilledButton.styleFrom(
|
||||||
|
elevation: 4,
|
||||||
|
backgroundColor: _uglyPrimary,
|
||||||
|
foregroundColor: const Color(0xFF0000FF),
|
||||||
|
shadowColor: _uglyError,
|
||||||
|
disabledBackgroundColor: _uglyBg,
|
||||||
|
disabledForegroundColor: _uglyError,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 22),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
side: const BorderSide(color: _uglySecondary, width: 3),
|
||||||
|
),
|
||||||
|
textStyle: const TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
letterSpacing: 3,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
elevation: 6,
|
||||||
|
backgroundColor: _uglyError,
|
||||||
|
foregroundColor: _uglyBg,
|
||||||
|
shadowColor: _uglyPrimary,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 20),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(24),
|
||||||
|
side: const BorderSide(color: _uglyFg, width: 4),
|
||||||
|
),
|
||||||
|
textStyle: const TextStyle(
|
||||||
|
fontSize: 17,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
outlinedButtonTheme: OutlinedButtonThemeData(
|
||||||
|
style: OutlinedButton.styleFrom(
|
||||||
|
foregroundColor: _uglyFg,
|
||||||
|
side: const BorderSide(color: _uglySecondary, width: 5),
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 18),
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0)),
|
||||||
|
textStyle: const TextStyle(
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
textButtonTheme: TextButtonThemeData(
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
foregroundColor: _uglyError,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 14),
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||||
|
textStyle: const TextStyle(fontWeight: FontWeight.w900, fontSize: 16),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
inputDecorationTheme: const InputDecorationTheme(
|
||||||
|
filled: true,
|
||||||
|
fillColor: Color(0xFFAAFFAA),
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
color: Color(0xFFFF0000),
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
fontStyle: FontStyle.italic,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 24, vertical: 20),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(16),
|
||||||
|
bottomRight: Radius.circular(16),
|
||||||
|
),
|
||||||
|
borderSide: BorderSide(color: _uglySecondary, width: 4),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(16),
|
||||||
|
bottomRight: Radius.circular(16),
|
||||||
|
),
|
||||||
|
borderSide: BorderSide(color: _uglyError, width: 4),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(16),
|
||||||
|
bottomRight: Radius.circular(16),
|
||||||
|
),
|
||||||
|
borderSide: BorderSide(color: _uglyPrimary, width: 6),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
dialogTheme: DialogThemeData(
|
||||||
|
backgroundColor: _uglySurface,
|
||||||
|
elevation: 16,
|
||||||
|
shadowColor: _uglyFg,
|
||||||
|
surfaceTintColor: _uglyError,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(0),
|
||||||
|
side: const BorderSide(color: _uglyPrimary, width: 5),
|
||||||
|
),
|
||||||
|
titleTextStyle: const TextStyle(
|
||||||
|
color: _uglyFg,
|
||||||
|
fontSize: 26,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
contentTextStyle: const TextStyle(
|
||||||
|
color: _uglyBg,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.8,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
floatingActionButtonTheme: const FloatingActionButtonThemeData(
|
||||||
|
backgroundColor: _uglySecondary,
|
||||||
|
foregroundColor: _uglyFg,
|
||||||
|
elevation: 8,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(30),
|
||||||
|
bottomRight: Radius.circular(30),
|
||||||
|
),
|
||||||
|
side: BorderSide(color: _uglyPrimary, width: 4),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
listTileTheme: ListTileThemeData(
|
||||||
|
tileColor: _uglyFg,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(0),
|
||||||
|
side: const BorderSide(color: _uglySecondary, width: 3),
|
||||||
|
),
|
||||||
|
iconColor: _uglyBg,
|
||||||
|
textColor: _uglySurface,
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 16),
|
||||||
|
),
|
||||||
|
|
||||||
|
snackBarTheme: SnackBarThemeData(
|
||||||
|
backgroundColor: _uglyPrimary,
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
elevation: 8,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(0),
|
||||||
|
side: const BorderSide(color: _uglySecondary, width: 4),
|
||||||
|
),
|
||||||
|
contentTextStyle: const TextStyle(
|
||||||
|
color: Color(0xFF0000FF),
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
dividerTheme: const DividerThemeData(
|
||||||
|
color: _uglySecondary,
|
||||||
|
thickness: 5,
|
||||||
|
space: 8,
|
||||||
|
),
|
||||||
|
|
||||||
|
chipTheme: const ChipThemeData(
|
||||||
|
backgroundColor: _uglyError,
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: _uglyFg,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
fontSize: 14,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topRight: Radius.circular(20),
|
||||||
|
bottomLeft: Radius.circular(20),
|
||||||
|
),
|
||||||
|
side: BorderSide(color: _uglyPrimary, width: 3),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
textTheme: const TextTheme(
|
||||||
|
displayLarge: TextStyle(
|
||||||
|
color: _uglyFg,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
fontSize: 52,
|
||||||
|
letterSpacing: 5,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
headlineMedium: TextStyle(
|
||||||
|
color: _uglyPrimary,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
fontSize: 34,
|
||||||
|
letterSpacing: 3,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
titleLarge: TextStyle(
|
||||||
|
color: _uglyFg,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
fontSize: 26,
|
||||||
|
letterSpacing: 2,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
titleMedium: TextStyle(
|
||||||
|
color: _uglyPrimary,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
fontSize: 20,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
bodyLarge: TextStyle(
|
||||||
|
color: _uglyFg,
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.8,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
bodyMedium: TextStyle(
|
||||||
|
color: _uglyBg,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
fontSize: 14,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
bodySmall: TextStyle(
|
||||||
|
color: _uglyError,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
fontSize: 12,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
labelLarge: TextStyle(
|
||||||
|
color: _uglySecondary,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
fontSize: 16,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|||||||
@@ -115,18 +115,18 @@ class BarScreenViewModel extends ChangeNotifier {
|
|||||||
await _reloadTabs();
|
await _reloadTabs();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> closeSelectedTab() async {
|
Future<void> closeSelectedTab({String paymentMethod = 'cash'}) async {
|
||||||
final tab = selectedTab;
|
final tab = selectedTab;
|
||||||
|
|
||||||
if (tab == null) return;
|
if (tab == null) return;
|
||||||
|
|
||||||
await barTabService.closeTab(tab.id);
|
await barTabService.closeTab(tab.id, paymentMethod: paymentMethod);
|
||||||
|
|
||||||
await _reloadTabs();
|
await _reloadTabs();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> closeTab(String tabId) async {
|
Future<void> closeTab(String tabId, {String paymentMethod = 'cash'}) async {
|
||||||
await barTabService.closeTab(tabId);
|
await barTabService.closeTab(tabId, paymentMethod: paymentMethod);
|
||||||
|
|
||||||
await _reloadTabs();
|
await _reloadTabs();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
import 'package:kooltab2/database/app_database.dart';
|
import 'package:kooltab2/database/app_database.dart';
|
||||||
import 'package:kooltab2/services/bar_tab_service.dart';
|
import 'package:kooltab2/services/bar_tab_service.dart';
|
||||||
import 'package:kooltab2/services/pin_lock_service.dart';
|
import 'package:kooltab2/services/pin_lock_service.dart';
|
||||||
@@ -274,6 +275,7 @@ class DevMenuViewModel extends ChangeNotifier {
|
|||||||
'Sam', 'Tina', 'Umar', 'Vera', 'Wes', 'Xena',
|
'Sam', 'Tina', 'Umar', 'Vera', 'Wes', 'Xena',
|
||||||
'Yves', 'Zara',
|
'Yves', 'Zara',
|
||||||
];
|
];
|
||||||
|
const paymentMethods = ['cash', 'payconiq'];
|
||||||
|
|
||||||
await database.transaction(() async {
|
await database.transaction(() async {
|
||||||
for (var i = 0; i < count; i++) {
|
for (var i = 0; i < count; i++) {
|
||||||
@@ -295,6 +297,7 @@ class DevMenuViewModel extends ChangeNotifier {
|
|||||||
originalTabId: uuid.v4(),
|
originalTabId: uuid.v4(),
|
||||||
customerName: customer,
|
customerName: customer,
|
||||||
closedAt: closedAt,
|
closedAt: closedAt,
|
||||||
|
paymentMethod: Value(paymentMethods[(i * 3) % paymentMethods.length]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import 'package:kooltab2/viewmodels/bar_screen_view_model.dart';
|
|
||||||
import 'package:kooltab2/views/widgets/slide_confirm.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../../viewmodels/bar_screen_view_model.dart';
|
||||||
|
import '../widgets/slide_confirm.dart';
|
||||||
|
|
||||||
Future<void> confirmCloseTab(BuildContext context) async {
|
Future<void> confirmCloseTab(BuildContext context) async {
|
||||||
final viewModel = context.read<BarScreenViewModel>();
|
final viewModel = context.read<BarScreenViewModel>();
|
||||||
@@ -9,39 +11,111 @@ Future<void> confirmCloseTab(BuildContext context) async {
|
|||||||
|
|
||||||
if (tab == null) return;
|
if (tab == null) return;
|
||||||
|
|
||||||
|
String paymentMethod = 'cash';
|
||||||
|
|
||||||
final confirmed = await showDialog<bool>(
|
final confirmed = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (dialogContext) {
|
builder: (dialogContext) {
|
||||||
return AlertDialog(
|
return StatefulBuilder(
|
||||||
title: Text('Close ${tab.customerName}ʼs tab?'),
|
builder: (context, setDialogState) {
|
||||||
content: SizedBox(
|
return AlertDialog(
|
||||||
width: 360,
|
title: Text('Close ${tab.customerName}ʼs tab?'),
|
||||||
child: Column(
|
content: SizedBox(
|
||||||
mainAxisSize: MainAxisSize.min,
|
width: 360,
|
||||||
children: [
|
child: Column(
|
||||||
Text('Current total: ${tab.formattedTotal}'),
|
mainAxisSize: MainAxisSize.min,
|
||||||
const SizedBox(height: 20),
|
children: [
|
||||||
|
Text('Current total: ${tab.formattedTotal}'),
|
||||||
SlideConfirm(
|
const SizedBox(height: 20),
|
||||||
onConfirmed: () {
|
Text(
|
||||||
Navigator.of(dialogContext).pop(true);
|
'Payment method',
|
||||||
},
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_PaymentPicker(
|
||||||
|
selected: paymentMethod,
|
||||||
|
onChanged: (value) {
|
||||||
|
setDialogState(() => paymentMethod = value);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
SlideConfirm(
|
||||||
|
onConfirmed: () {
|
||||||
|
Navigator.of(dialogContext).pop(true);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actionsPadding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(dialogContext).pop(false),
|
||||||
|
child: const Text('Cancel'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
);
|
||||||
),
|
},
|
||||||
actionsPadding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.of(dialogContext).pop(false),
|
|
||||||
child: const Text('Cancel'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (confirmed != true) return;
|
if (confirmed != true) return;
|
||||||
|
|
||||||
await viewModel.closeSelectedTab();
|
await viewModel.closeSelectedTab(paymentMethod: paymentMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _PaymentPicker extends StatelessWidget {
|
||||||
|
final String selected;
|
||||||
|
final ValueChanged<String> onChanged;
|
||||||
|
|
||||||
|
const _PaymentPicker({
|
||||||
|
required this.selected,
|
||||||
|
required this.onChanged,
|
||||||
|
});
|
||||||
|
|
||||||
|
static const _options = [
|
||||||
|
('cash', 'Cash'),
|
||||||
|
('payconiq', 'Payconiq'),
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: _options.map((option) {
|
||||||
|
final (value, label) = option;
|
||||||
|
final isSelected = selected == value;
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 6),
|
||||||
|
child: ChoiceChip(
|
||||||
|
showCheckmark: false,
|
||||||
|
selected: isSelected,
|
||||||
|
onSelected: (_) => onChanged(value),
|
||||||
|
label: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
if (value == 'cash')
|
||||||
|
const Icon(
|
||||||
|
Icons.attach_money,
|
||||||
|
size: 16,
|
||||||
|
color: Colors.lightGreen,
|
||||||
|
)
|
||||||
|
else
|
||||||
|
SvgPicture.asset(
|
||||||
|
'assets/icons/payconic.svg',
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
colorFilter: ColorFilter.mode(Colors.pinkAccent, BlendMode.srcIn),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
Text(label),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -219,6 +219,7 @@ class _SettingsScreenViewState extends State<SettingsScreenView> {
|
|||||||
AppThemeMode.system => 'System',
|
AppThemeMode.system => 'System',
|
||||||
AppThemeMode.light => 'Light',
|
AppThemeMode.light => 'Light',
|
||||||
AppThemeMode.dark => 'Dark',
|
AppThemeMode.dark => 'Dark',
|
||||||
|
AppThemeMode.ugly => 'Ugly',
|
||||||
},
|
},
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final selected = await showModalBottomSheet<AppThemeMode>(
|
final selected = await showModalBottomSheet<AppThemeMode>(
|
||||||
@@ -234,6 +235,7 @@ class _SettingsScreenViewState extends State<SettingsScreenView> {
|
|||||||
AppThemeMode.system => 'System',
|
AppThemeMode.system => 'System',
|
||||||
AppThemeMode.light => 'Light',
|
AppThemeMode.light => 'Light',
|
||||||
AppThemeMode.dark => 'Dark',
|
AppThemeMode.dark => 'Dark',
|
||||||
|
AppThemeMode.ugly => 'Ugly',
|
||||||
}),
|
}),
|
||||||
onChanged: (value) =>
|
onChanged: (value) =>
|
||||||
Navigator.pop(context, value),
|
Navigator.pop(context, value),
|
||||||
|
|||||||
@@ -15,6 +15,13 @@ class ClosedTabCard extends StatefulWidget {
|
|||||||
class _ClosedTabCardState extends State<ClosedTabCard> {
|
class _ClosedTabCardState extends State<ClosedTabCard> {
|
||||||
bool _expanded = false;
|
bool _expanded = false;
|
||||||
|
|
||||||
|
IconData _paymentIcon(String method) {
|
||||||
|
return switch (method) {
|
||||||
|
'payconiq' => Icons.qr_code_rounded,
|
||||||
|
_ => Icons.money_rounded,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final closedTab = widget.closedTab;
|
final closedTab = widget.closedTab;
|
||||||
@@ -49,15 +56,51 @@ class _ClosedTabCardState extends State<ClosedTabCard> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Row(
|
||||||
closedTab.customerName,
|
children: [
|
||||||
maxLines: 1,
|
Expanded(
|
||||||
overflow: TextOverflow.ellipsis,
|
child: Text(
|
||||||
style: TextStyle(
|
closedTab.customerName,
|
||||||
fontSize: 16,
|
maxLines: 1,
|
||||||
fontWeight: FontWeight.w800,
|
overflow: TextOverflow.ellipsis,
|
||||||
color: scheme.onSurface,
|
style: TextStyle(
|
||||||
),
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w800,
|
||||||
|
color: scheme.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 8,
|
||||||
|
vertical: 3,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: scheme.primary.withValues(alpha: 0.1),
|
||||||
|
borderRadius: BorderRadius.circular(999),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
_paymentIcon(closedTab.paymentMethod),
|
||||||
|
size: 13,
|
||||||
|
color: scheme.primary,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
closedTab.formattedPaymentMethod,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 11,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: scheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 2),
|
||||||
Text(
|
Text(
|
||||||
@@ -163,4 +206,4 @@ class _ClosedTabItemRow extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -358,6 +358,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.3"
|
version: "4.0.3"
|
||||||
|
flutter_svg:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_svg
|
||||||
|
sha256: "35882981abcbfb8c15b286f0cd690ff25bac12d95eff3e25ee207f37d4c42e7f"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.0"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -680,6 +688,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.9.1"
|
||||||
|
path_parsing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_parsing
|
||||||
|
sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
path_provider:
|
path_provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -728,6 +744,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.3.0"
|
||||||
|
petitparser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: petitparser
|
||||||
|
sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.2"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -925,6 +949,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.5.3"
|
version: "4.5.3"
|
||||||
|
vector_graphics:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vector_graphics
|
||||||
|
sha256: "2306c03da2ba81724afeb589c351ebbc0aa7d86005925be8f8735856dbe5e42d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.2"
|
||||||
|
vector_graphics_codec:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vector_graphics_codec
|
||||||
|
sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.13"
|
||||||
|
vector_graphics_compiler:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vector_graphics_compiler
|
||||||
|
sha256: "4dca4feb77dc3ec7f6e27e49c53241eb8217f55e4f9b12599a27f8903bca5682"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.0"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -989,6 +1037,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
|
xml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xml
|
||||||
|
sha256: "67f0aff7be013d107995e9b75bf4e7f2c3ef2dfdb2c8e68024bba0a7fd5756a4"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.1"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ dependencies:
|
|||||||
package_info_plus: ^10.1.0
|
package_info_plus: ^10.1.0
|
||||||
open_filex: ^4.7.0
|
open_filex: ^4.7.0
|
||||||
ota_update: ^7.1.0
|
ota_update: ^7.1.0
|
||||||
|
flutter_svg: ^2.3.0
|
||||||
# permission_handler: ^12.0.3
|
# permission_handler: ^12.0.3
|
||||||
|
|
||||||
|
|
||||||
@@ -83,6 +84,9 @@ flutter:
|
|||||||
# - images/a_dot_burr.jpeg
|
# - images/a_dot_burr.jpeg
|
||||||
# - images/a_dot_ham.jpeg
|
# - images/a_dot_ham.jpeg
|
||||||
|
|
||||||
|
assets:
|
||||||
|
- assets/icons/payconic.svg
|
||||||
|
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
# https://flutter.dev/to/resolution-aware-images
|
# https://flutter.dev/to/resolution-aware-images
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user