feat: syn product
This commit is contained in:
@@ -46,7 +46,7 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
PaymentMethod? selectedPaymentMethod;
|
||||
int totalPriceFinal = 0;
|
||||
int discountAmountFinal = 0;
|
||||
|
||||
|
||||
// Helper method to handle post-payment cleanup
|
||||
Future<void> _handlePostPaymentCleanup() async {
|
||||
if (widget.table != null && widget.draftOrder?.id != null) {
|
||||
@@ -60,21 +60,22 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
startTime: DateTime.now().toIso8601String(),
|
||||
position: widget.table!.position,
|
||||
);
|
||||
|
||||
|
||||
// Update table status
|
||||
await ProductLocalDatasource.instance.updateStatusTable(newTable);
|
||||
|
||||
|
||||
// Remove draft order
|
||||
await ProductLocalDatasource.instance.removeDraftOrderById(widget.draftOrder!.id!);
|
||||
|
||||
await ProductLocalDatasource.instance
|
||||
.removeDraftOrderById(widget.draftOrder!.id!);
|
||||
|
||||
// Refresh table status
|
||||
context.read<GetTableStatusBloc>().add(
|
||||
GetTableStatusEvent.getTablesStatus('all'),
|
||||
);
|
||||
|
||||
GetTableStatusEvent.getTablesStatus('all'),
|
||||
);
|
||||
|
||||
log("Table ${widget.table!.tableName} freed up and draft order removed");
|
||||
}
|
||||
|
||||
|
||||
// Safely navigate back - pop multiple times to get to table management
|
||||
// Pop the success dialog first, then the payment page
|
||||
if (Navigator.of(context).canPop()) {
|
||||
@@ -84,6 +85,7 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
context
|
||||
@@ -93,7 +95,7 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
.read<PaymentMethodsBloc>()
|
||||
.add(PaymentMethodsEvent.fetchPaymentMethods());
|
||||
super.initState();
|
||||
|
||||
|
||||
// Set a default payment method in case API fails
|
||||
selectedPaymentMethod = PaymentMethod(
|
||||
id: 1,
|
||||
@@ -135,7 +137,8 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text('Kembali'),
|
||||
content: const Text('Apakah Anda yakin ingin kembali? Order akan tetap tersimpan.'),
|
||||
content: const Text(
|
||||
'Apakah Anda yakin ingin kembali? Order akan tetap tersimpan.'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
@@ -146,7 +149,8 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(); // Close dialog
|
||||
Navigator.of(context).pop(); // Go back to previous page
|
||||
Navigator.of(context)
|
||||
.pop(); // Go back to previous page
|
||||
},
|
||||
child: const Text('Ya'),
|
||||
),
|
||||
@@ -157,7 +161,8 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
},
|
||||
child: const Text(
|
||||
'Kembali',
|
||||
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
|
||||
style: TextStyle(
|
||||
color: Colors.white, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -251,7 +256,8 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
serviceCharge,
|
||||
totalQuantity,
|
||||
totalPrice,
|
||||
draftName, orderType) {
|
||||
draftName,
|
||||
orderType) {
|
||||
if (products.isEmpty) {
|
||||
return const Center(
|
||||
child: Text('No Items'),
|
||||
@@ -294,13 +300,13 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
serviceCharge,
|
||||
totalQuantity,
|
||||
totalPrice,
|
||||
draftName, orderType) =>
|
||||
draftName,
|
||||
orderType) =>
|
||||
products.fold(
|
||||
0,
|
||||
(previousValue, element) =>
|
||||
previousValue +
|
||||
(element.product.price!
|
||||
.toIntegerFromText *
|
||||
(element.product.price! *
|
||||
element.quantity),
|
||||
));
|
||||
return Text(
|
||||
@@ -374,7 +380,8 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
serviceCharge,
|
||||
totalQuantity,
|
||||
totalPrice,
|
||||
draftName, orderType) =>
|
||||
draftName,
|
||||
orderType) =>
|
||||
tax,
|
||||
);
|
||||
final price = state.maybeWhen(
|
||||
@@ -387,13 +394,13 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
serviceCharge,
|
||||
totalQuantity,
|
||||
totalPrice,
|
||||
draftName, orderType) =>
|
||||
draftName,
|
||||
orderType) =>
|
||||
products.fold(
|
||||
0,
|
||||
(previousValue, element) =>
|
||||
previousValue +
|
||||
(element.product.price!
|
||||
.toIntegerFromText *
|
||||
(element.product.price! *
|
||||
element.quantity),
|
||||
),
|
||||
);
|
||||
@@ -408,7 +415,8 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
serviceCharge,
|
||||
totalQuantity,
|
||||
totalPrice,
|
||||
draftName, orderType) {
|
||||
draftName,
|
||||
orderType) {
|
||||
return discountAmount;
|
||||
});
|
||||
|
||||
@@ -446,7 +454,8 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
serviceCharge,
|
||||
totalQuantity,
|
||||
totalPrice,
|
||||
draftName, orderType) =>
|
||||
draftName,
|
||||
orderType) =>
|
||||
tax,
|
||||
);
|
||||
final price = state.maybeWhen(
|
||||
@@ -459,13 +468,13 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
serviceCharge,
|
||||
totalQuantity,
|
||||
totalPrice,
|
||||
draftName, orderType) =>
|
||||
draftName,
|
||||
orderType) =>
|
||||
products.fold(
|
||||
0,
|
||||
(previousValue, element) =>
|
||||
previousValue +
|
||||
(element.product.price!
|
||||
.toIntegerFromText *
|
||||
(element.product.price! *
|
||||
element.quantity),
|
||||
),
|
||||
);
|
||||
@@ -480,7 +489,8 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
serviceCharge,
|
||||
totalQuantity,
|
||||
totalPrice,
|
||||
draftName, orderType) {
|
||||
draftName,
|
||||
orderType) {
|
||||
return discountAmount;
|
||||
});
|
||||
|
||||
@@ -494,7 +504,8 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
serviceCharge,
|
||||
totalQuantity,
|
||||
totalPrice,
|
||||
draftName, orderType) =>
|
||||
draftName,
|
||||
orderType) =>
|
||||
serviceCharge,
|
||||
);
|
||||
|
||||
@@ -536,13 +547,13 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
serviceCharge,
|
||||
totalQuantity,
|
||||
totalPrice,
|
||||
draftName, orderType) =>
|
||||
draftName,
|
||||
orderType) =>
|
||||
products.fold(
|
||||
0,
|
||||
(previousValue, element) =>
|
||||
previousValue +
|
||||
(element.product.price!
|
||||
.toIntegerFromText *
|
||||
(element.product.price! *
|
||||
element.quantity),
|
||||
),
|
||||
);
|
||||
@@ -557,7 +568,8 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
serviceCharge,
|
||||
totalQuantity,
|
||||
totalPrice,
|
||||
draftName, orderType) {
|
||||
draftName,
|
||||
orderType) {
|
||||
return discountAmount;
|
||||
});
|
||||
|
||||
@@ -571,7 +583,8 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
serviceCharge,
|
||||
totalQuantity,
|
||||
totalPrice,
|
||||
draftName, orderType) =>
|
||||
draftName,
|
||||
orderType) =>
|
||||
serviceCharge,
|
||||
);
|
||||
|
||||
@@ -585,7 +598,8 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
serviceCharge,
|
||||
totalQuantity,
|
||||
totalPrice,
|
||||
draftName, orderType) =>
|
||||
draftName,
|
||||
orderType) =>
|
||||
tax,
|
||||
);
|
||||
|
||||
@@ -666,7 +680,8 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
serviceCharge,
|
||||
totalQuantity,
|
||||
totalPrice,
|
||||
draftName, orderType) {
|
||||
draftName,
|
||||
orderType) {
|
||||
customerController.text = draftName;
|
||||
return TextFormField(
|
||||
readOnly: true,
|
||||
@@ -699,7 +714,8 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
),
|
||||
),
|
||||
const SpaceHeight(12.0),
|
||||
BlocBuilder<PaymentMethodsBloc, PaymentMethodsState>(
|
||||
BlocBuilder<PaymentMethodsBloc,
|
||||
PaymentMethodsState>(
|
||||
builder: (context, state) {
|
||||
return state.maybeWhen(
|
||||
orElse: () => const Center(
|
||||
@@ -717,14 +733,16 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
error: (message) => Column(
|
||||
children: [
|
||||
Center(
|
||||
child: Text('Error loading payment methods: $message'),
|
||||
child: Text(
|
||||
'Error loading payment methods: $message'),
|
||||
),
|
||||
const SpaceHeight(16.0),
|
||||
Button.filled(
|
||||
onPressed: () {
|
||||
context
|
||||
.read<PaymentMethodsBloc>()
|
||||
.add(PaymentMethodsEvent.fetchPaymentMethods());
|
||||
.add(PaymentMethodsEvent
|
||||
.fetchPaymentMethods());
|
||||
},
|
||||
label: 'Retry',
|
||||
),
|
||||
@@ -739,32 +757,39 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
return Column(
|
||||
children: [
|
||||
const Center(
|
||||
child: Text('No payment methods available'),
|
||||
child: Text(
|
||||
'No payment methods available'),
|
||||
),
|
||||
const SpaceHeight(16.0),
|
||||
Button.filled(
|
||||
onPressed: () {
|
||||
context
|
||||
.read<PaymentMethodsBloc>()
|
||||
.add(PaymentMethodsEvent.fetchPaymentMethods());
|
||||
.add(PaymentMethodsEvent
|
||||
.fetchPaymentMethods());
|
||||
},
|
||||
label: 'Retry',
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Set default selected payment method if none selected or if current selection is not in the list
|
||||
if (selectedPaymentMethod == null ||
|
||||
!paymentMethods.any((method) => method.id == selectedPaymentMethod?.id)) {
|
||||
selectedPaymentMethod = paymentMethods.first;
|
||||
if (selectedPaymentMethod == null ||
|
||||
!paymentMethods.any((method) =>
|
||||
method.id ==
|
||||
selectedPaymentMethod?.id)) {
|
||||
selectedPaymentMethod =
|
||||
paymentMethods.first;
|
||||
}
|
||||
|
||||
|
||||
return Wrap(
|
||||
spacing: 12.0,
|
||||
runSpacing: 8.0,
|
||||
children: paymentMethods.map((method) {
|
||||
final isSelected = selectedPaymentMethod?.id == method.id;
|
||||
final isSelected =
|
||||
selectedPaymentMethod?.id ==
|
||||
method.id;
|
||||
return Container(
|
||||
constraints: const BoxConstraints(
|
||||
minWidth: 120.0,
|
||||
@@ -775,31 +800,44 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
color: AppColors.primary,
|
||||
width: 2.0,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
8.0),
|
||||
)
|
||||
: null,
|
||||
child: Tooltip(
|
||||
message: method.description ?? 'No description available',
|
||||
message: method.description ??
|
||||
'No description available',
|
||||
child: isSelected
|
||||
? Button.filled(
|
||||
width: double.infinity,
|
||||
height: 50.0,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
selectedPaymentMethod = method;
|
||||
selectedPaymentMethod =
|
||||
method;
|
||||
});
|
||||
},
|
||||
label: method.name?.isNotEmpty == true ? method.name! : 'Unknown',
|
||||
label: method.name
|
||||
?.isNotEmpty ==
|
||||
true
|
||||
? method.name!
|
||||
: 'Unknown',
|
||||
)
|
||||
: Button.outlined(
|
||||
width: double.infinity,
|
||||
height: 50.0,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
selectedPaymentMethod = method;
|
||||
selectedPaymentMethod =
|
||||
method;
|
||||
});
|
||||
},
|
||||
label: method.name?.isNotEmpty == true ? method.name! : 'Unknown',
|
||||
label: method.name
|
||||
?.isNotEmpty ==
|
||||
true
|
||||
? method.name!
|
||||
: 'Unknown',
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -881,30 +919,41 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
builder: (context) => AlertDialog(
|
||||
title: Row(
|
||||
children: [
|
||||
Icon(Icons.warning, color: AppColors.red),
|
||||
Icon(Icons.warning,
|
||||
color: AppColors.red),
|
||||
SizedBox(width: 8),
|
||||
Text('Batalkan Pesanan?'),
|
||||
Text('Batalkan Pesanan?'),
|
||||
],
|
||||
),
|
||||
content: Text(
|
||||
'Apakah anda yakin ingin membatalkan pesanan untuk meja ${widget.table?.tableName ?? "ini"}?\n\nPesanan akan dihapus secara permanen.'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text('Tidak',
|
||||
style: TextStyle(color: AppColors.primary)),
|
||||
onPressed: () =>
|
||||
Navigator.pop(context),
|
||||
child: Text('Tidak',
|
||||
style: TextStyle(
|
||||
color:
|
||||
AppColors.primary)),
|
||||
),
|
||||
BlocListener<StatusTableBloc, StatusTableState>(
|
||||
BlocListener<StatusTableBloc,
|
||||
StatusTableState>(
|
||||
listener: (context, state) {
|
||||
state.maybeWhen(
|
||||
orElse: () {},
|
||||
success: () {
|
||||
Navigator.pop(context); // Close void dialog
|
||||
Navigator.pop(context); // Close payment page
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
Navigator.pop(
|
||||
context); // Close void dialog
|
||||
Navigator.pop(
|
||||
context); // Close payment page
|
||||
ScaffoldMessenger.of(
|
||||
context)
|
||||
.showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Pesanan berhasil dibatalkan'),
|
||||
backgroundColor: AppColors.primary,
|
||||
content: Text(
|
||||
'Pesanan berhasil dibatalkan'),
|
||||
backgroundColor:
|
||||
AppColors.primary,
|
||||
),
|
||||
);
|
||||
},
|
||||
@@ -912,34 +961,47 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
},
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColors.red,
|
||||
backgroundColor:
|
||||
AppColors.red,
|
||||
),
|
||||
onPressed: () {
|
||||
// Void the order
|
||||
if (widget.table != null) {
|
||||
final newTable = TableModel(
|
||||
id: widget.table!.id,
|
||||
tableName: widget.table!.tableName,
|
||||
tableName: widget
|
||||
.table!.tableName,
|
||||
status: 'available',
|
||||
orderId: 0,
|
||||
paymentAmount: 0,
|
||||
startTime: DateTime.now().toIso8601String(),
|
||||
position: widget.table!.position,
|
||||
startTime: DateTime.now()
|
||||
.toIso8601String(),
|
||||
position: widget
|
||||
.table!.position,
|
||||
);
|
||||
context.read<StatusTableBloc>().add(
|
||||
StatusTableEvent.statusTabel(newTable),
|
||||
context
|
||||
.read<StatusTableBloc>()
|
||||
.add(
|
||||
StatusTableEvent
|
||||
.statusTabel(
|
||||
newTable),
|
||||
);
|
||||
}
|
||||
// Remove draft order from local storage
|
||||
if (widget.draftOrder?.id != null) {
|
||||
ProductLocalDatasource.instance
|
||||
.removeDraftOrderById(widget.draftOrder!.id!);
|
||||
if (widget.draftOrder?.id !=
|
||||
null) {
|
||||
ProductLocalDatasource
|
||||
.instance
|
||||
.removeDraftOrderById(
|
||||
widget.draftOrder!
|
||||
.id!);
|
||||
}
|
||||
log("Voided order from payment page");
|
||||
},
|
||||
child: const Text(
|
||||
"Ya, Batalkan",
|
||||
style: TextStyle(color: Colors.white),
|
||||
style: TextStyle(
|
||||
color: Colors.white),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1011,8 +1073,7 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
0,
|
||||
(previousValue, element) =>
|
||||
previousValue +
|
||||
(element.product.price!
|
||||
.toIntegerFromText *
|
||||
(element.product.price! *
|
||||
element.quantity),
|
||||
),
|
||||
);
|
||||
@@ -1080,22 +1141,29 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
child: Button.filled(
|
||||
onPressed: () async {
|
||||
if (selectedPaymentMethod == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Please select a payment method'),
|
||||
content: Text(
|
||||
'Please select a payment method'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final paymentMethodName = selectedPaymentMethod?.name?.toLowerCase() ?? '';
|
||||
|
||||
final paymentMethodName =
|
||||
selectedPaymentMethod?.name
|
||||
?.toLowerCase() ??
|
||||
'';
|
||||
log("Selected payment method: ${selectedPaymentMethod?.name} (normalized: $paymentMethodName)");
|
||||
|
||||
if (paymentMethodName == 'cash' ||
|
||||
|
||||
if (paymentMethodName == 'cash' ||
|
||||
paymentMethodName == 'tunai' ||
|
||||
paymentMethodName == 'uang tunai' ||
|
||||
paymentMethodName == 'cash payment') {
|
||||
paymentMethodName ==
|
||||
'uang tunai' ||
|
||||
paymentMethodName ==
|
||||
'cash payment') {
|
||||
context.read<OrderBloc>().add(
|
||||
OrderEvent.order(
|
||||
items,
|
||||
@@ -1109,7 +1177,9 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
widget.table?.id ?? 0,
|
||||
'completed',
|
||||
'paid',
|
||||
selectedPaymentMethod?.name ?? 'Cash',
|
||||
selectedPaymentMethod
|
||||
?.name ??
|
||||
'Cash',
|
||||
totalPriceFinal,
|
||||
orderType));
|
||||
|
||||
@@ -1149,7 +1219,9 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
widget.table?.id ?? 0,
|
||||
'completed',
|
||||
'paid',
|
||||
selectedPaymentMethod?.name ?? 'Unknown Payment Method',
|
||||
selectedPaymentMethod
|
||||
?.name ??
|
||||
'Unknown Payment Method',
|
||||
totalPriceFinal,
|
||||
orderType));
|
||||
|
||||
@@ -1173,7 +1245,7 @@ class _PaymentTablePageState extends State<PaymentTablePage> {
|
||||
customerController.text,
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
// Handle post-payment cleanup
|
||||
await _handlePostPaymentCleanup();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user