fear: rev 2
This commit is contained in:
parent
3624f75bea
commit
6599e6fe7c
@ -35,18 +35,25 @@ Future<void> onPrint(
|
|||||||
// Checker printer
|
// Checker printer
|
||||||
if (checkerPrinter != null) {
|
if (checkerPrinter != null) {
|
||||||
try {
|
try {
|
||||||
|
final productByPrinter = productQuantity
|
||||||
|
.where((item) => item.product.printerType == 'checker')
|
||||||
|
.toList();
|
||||||
|
|
||||||
final printValue = await PrintDataoutputs.instance.printChecker(
|
final printValue = await PrintDataoutputs.instance.printChecker(
|
||||||
productQuantity,
|
productByPrinter,
|
||||||
order.tableNumber ?? "",
|
order.tableNumber ?? "",
|
||||||
order.orderNumber ?? "",
|
order.orderNumber ?? "",
|
||||||
authData.user?.name ?? "",
|
authData.user?.name ?? "",
|
||||||
|
order.metadata?['customer_name'] ?? "",
|
||||||
checkerPrinter.paper.toIntegerFromText,
|
checkerPrinter.paper.toIntegerFromText,
|
||||||
order.orderType ?? "",
|
order.orderType ?? "",
|
||||||
);
|
);
|
||||||
|
|
||||||
await PrinterService()
|
if (productByPrinter.isNotEmpty) {
|
||||||
// ignore: use_build_context_synchronously
|
await PrinterService()
|
||||||
.printWithPrinter(checkerPrinter, printValue, context);
|
// ignore: use_build_context_synchronously
|
||||||
|
.printWithPrinter(checkerPrinter, printValue, context);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("Error printing checker: $e");
|
log("Error printing checker: $e");
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
@ -58,17 +65,23 @@ Future<void> onPrint(
|
|||||||
// Kitchen printer
|
// Kitchen printer
|
||||||
if (kitchenPrinter != null) {
|
if (kitchenPrinter != null) {
|
||||||
try {
|
try {
|
||||||
|
final productByPrinter = productQuantity
|
||||||
|
.where((item) => item.product.printerType == 'kitchen')
|
||||||
|
.toList();
|
||||||
final printValue = await PrintDataoutputs.instance.printKitchen(
|
final printValue = await PrintDataoutputs.instance.printKitchen(
|
||||||
productQuantity,
|
productByPrinter,
|
||||||
order.tableNumber!,
|
order.tableNumber!,
|
||||||
order.orderNumber ?? "",
|
order.orderNumber ?? "",
|
||||||
authData.user?.name ?? "",
|
authData.user?.name ?? "",
|
||||||
|
order.metadata?['customer_name'] ?? "",
|
||||||
kitchenPrinter.paper.toIntegerFromText,
|
kitchenPrinter.paper.toIntegerFromText,
|
||||||
order.orderType ?? "",
|
order.orderType ?? "",
|
||||||
);
|
);
|
||||||
|
|
||||||
await PrinterService()
|
if (productByPrinter.isNotEmpty) {
|
||||||
.printWithPrinter(kitchenPrinter, printValue, context);
|
await PrinterService()
|
||||||
|
.printWithPrinter(kitchenPrinter, printValue, context);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("Error printing kitchen order: $e");
|
log("Error printing kitchen order: $e");
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
@ -80,17 +93,24 @@ Future<void> onPrint(
|
|||||||
// Bar printer
|
// Bar printer
|
||||||
if (barPrinter != null) {
|
if (barPrinter != null) {
|
||||||
try {
|
try {
|
||||||
|
final productByPrinter = productQuantity
|
||||||
|
.where((item) => item.product.printerType == 'bar')
|
||||||
|
.toList();
|
||||||
|
|
||||||
final printValue = await PrintDataoutputs.instance.printBar(
|
final printValue = await PrintDataoutputs.instance.printBar(
|
||||||
productQuantity,
|
productByPrinter,
|
||||||
order.tableNumber ?? "",
|
order.tableNumber ?? "",
|
||||||
order.orderNumber ?? "",
|
order.orderNumber ?? "",
|
||||||
authData.user?.name ?? "",
|
authData.user?.name ?? "",
|
||||||
|
order.metadata?['customer_name'] ?? "",
|
||||||
barPrinter.paper.toIntegerFromText,
|
barPrinter.paper.toIntegerFromText,
|
||||||
order.orderType ?? "",
|
order.orderType ?? "",
|
||||||
);
|
);
|
||||||
|
|
||||||
await PrinterService()
|
if (productByPrinter.isNotEmpty) {
|
||||||
.printWithPrinter(barPrinter, printValue, context);
|
await PrinterService()
|
||||||
|
.printWithPrinter(barPrinter, printValue, context);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("Error printing bar order: $e");
|
log("Error printing bar order: $e");
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
|||||||
@ -1275,6 +1275,7 @@ class PrintDataoutputs {
|
|||||||
String tableName,
|
String tableName,
|
||||||
String draftName,
|
String draftName,
|
||||||
String cashierName,
|
String cashierName,
|
||||||
|
String customerName,
|
||||||
int paper,
|
int paper,
|
||||||
String orderType) async {
|
String orderType) async {
|
||||||
List<int> bytes = [];
|
List<int> bytes = [];
|
||||||
@ -1330,9 +1331,6 @@ class PrintDataoutputs {
|
|||||||
styles: const PosStyles(align: PosAlign.right),
|
styles: const PosStyles(align: PosAlign.right),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
// bytes += generator.text(
|
|
||||||
// 'Receipt: JF-${DateFormat('yyyyMMddhhmm').format(DateTime.now())}',
|
|
||||||
// styles: const PosStyles(bold: false, align: PosAlign.left));
|
|
||||||
//cashier name
|
//cashier name
|
||||||
bytes += generator.row([
|
bytes += generator.row([
|
||||||
PosColumn(
|
PosColumn(
|
||||||
@ -1352,7 +1350,7 @@ class PrintDataoutputs {
|
|||||||
//column 2
|
//column 2
|
||||||
bytes += generator.row([
|
bytes += generator.row([
|
||||||
PosColumn(
|
PosColumn(
|
||||||
text: 'Customer - $draftName',
|
text: '$customerName - $draftName',
|
||||||
width: 6,
|
width: 6,
|
||||||
styles: const PosStyles(align: PosAlign.left),
|
styles: const PosStyles(align: PosAlign.left),
|
||||||
),
|
),
|
||||||
@ -1410,6 +1408,7 @@ class PrintDataoutputs {
|
|||||||
String tableNumber,
|
String tableNumber,
|
||||||
String draftName,
|
String draftName,
|
||||||
String cashierName,
|
String cashierName,
|
||||||
|
String customerName,
|
||||||
int paper,
|
int paper,
|
||||||
String orderType) async {
|
String orderType) async {
|
||||||
List<int> bytes = [];
|
List<int> bytes = [];
|
||||||
@ -1462,14 +1461,26 @@ class PrintDataoutputs {
|
|||||||
styles: const PosStyles(align: PosAlign.left),
|
styles: const PosStyles(align: PosAlign.left),
|
||||||
),
|
),
|
||||||
PosColumn(
|
PosColumn(
|
||||||
text: 'JF-${DateFormat('yyyyMMddhhmm').format(DateTime.now())}',
|
text: DateFormat('yyyyMMddhhmm').format(DateTime.now()),
|
||||||
width: 6,
|
width: 6,
|
||||||
styles: const PosStyles(align: PosAlign.right),
|
styles: const PosStyles(align: PosAlign.right),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
bytes += generator.row([
|
bytes += generator.row([
|
||||||
PosColumn(
|
PosColumn(
|
||||||
text: 'Customer - $draftName',
|
text: 'Cashier',
|
||||||
|
width: 6,
|
||||||
|
styles: const PosStyles(align: PosAlign.left),
|
||||||
|
),
|
||||||
|
PosColumn(
|
||||||
|
text: cashierName,
|
||||||
|
width: 6,
|
||||||
|
styles: const PosStyles(align: PosAlign.right),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
bytes += generator.row([
|
||||||
|
PosColumn(
|
||||||
|
text: '$customerName - $draftName',
|
||||||
width: 6,
|
width: 6,
|
||||||
styles: const PosStyles(align: PosAlign.left),
|
styles: const PosStyles(align: PosAlign.left),
|
||||||
),
|
),
|
||||||
@ -1524,8 +1535,15 @@ class PrintDataoutputs {
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<int>> printBar(List<ProductQuantity> products, String tableNumber,
|
Future<List<int>> printBar(
|
||||||
String draftName, String cashierName, int paper, String orderType) async {
|
List<ProductQuantity> products,
|
||||||
|
String tableNumber,
|
||||||
|
String draftName,
|
||||||
|
String cashierName,
|
||||||
|
String customerName,
|
||||||
|
int paper,
|
||||||
|
String orderType,
|
||||||
|
) async {
|
||||||
List<int> bytes = [];
|
List<int> bytes = [];
|
||||||
|
|
||||||
final profile = await CapabilityProfile.load();
|
final profile = await CapabilityProfile.load();
|
||||||
@ -1576,14 +1594,26 @@ class PrintDataoutputs {
|
|||||||
styles: const PosStyles(align: PosAlign.left),
|
styles: const PosStyles(align: PosAlign.left),
|
||||||
),
|
),
|
||||||
PosColumn(
|
PosColumn(
|
||||||
text: 'JF-${DateFormat('yyyyMMddhhmm').format(DateTime.now())}',
|
text: DateFormat('yyyyMMddhhmm').format(DateTime.now()),
|
||||||
width: 6,
|
width: 6,
|
||||||
styles: const PosStyles(align: PosAlign.right),
|
styles: const PosStyles(align: PosAlign.right),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
bytes += generator.row([
|
bytes += generator.row([
|
||||||
PosColumn(
|
PosColumn(
|
||||||
text: 'Customer - $draftName',
|
text: 'Cashier',
|
||||||
|
width: 6,
|
||||||
|
styles: const PosStyles(align: PosAlign.left),
|
||||||
|
),
|
||||||
|
PosColumn(
|
||||||
|
text: cashierName,
|
||||||
|
width: 6,
|
||||||
|
styles: const PosStyles(align: PosAlign.right),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
bytes += generator.row([
|
||||||
|
PosColumn(
|
||||||
|
text: '$customerName - $draftName',
|
||||||
width: 6,
|
width: 6,
|
||||||
styles: const PosStyles(align: PosAlign.left),
|
styles: const PosStyles(align: PosAlign.left),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import 'package:intl/intl.dart';
|
|||||||
|
|
||||||
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
|
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
|
||||||
import 'package:enaklo_pos/presentation/home/bloc/qris/qris_bloc.dart';
|
import 'package:enaklo_pos/presentation/home/bloc/qris/qris_bloc.dart';
|
||||||
import 'package:enaklo_pos/presentation/home/widgets/success_payment_dialog.dart';
|
// import 'package:enaklo_pos/presentation/home/widgets/success_payment_dialog.dart';
|
||||||
import 'package:widgets_to_image/widgets_to_image.dart';
|
import 'package:widgets_to_image/widgets_to_image.dart';
|
||||||
import 'package:enaklo_pos/core/utils/printer_service.dart';
|
import 'package:enaklo_pos/core/utils/printer_service.dart';
|
||||||
|
|
||||||
@ -124,36 +124,36 @@ class _PaymentQrisDialogState extends State<PaymentQrisDialog> {
|
|||||||
));
|
));
|
||||||
});
|
});
|
||||||
}, success: (message) async {
|
}, success: (message) async {
|
||||||
context.read<OrderBloc>().add(OrderEvent.order(
|
// context.read<OrderBloc>().add(OrderEvent.order(
|
||||||
widget.items,
|
// widget.items,
|
||||||
widget.discount,
|
// widget.discount,
|
||||||
widget.discountAmount,
|
// widget.discountAmount,
|
||||||
widget.tax,
|
// widget.tax,
|
||||||
widget.serviceCharge,
|
// widget.serviceCharge,
|
||||||
widget.paymentAmount,
|
// widget.paymentAmount,
|
||||||
widget.customerName,
|
// widget.customerName,
|
||||||
widget.tableNumber,
|
// widget.tableNumber,
|
||||||
'completed',
|
// 'completed',
|
||||||
'paid',
|
// 'paid',
|
||||||
'Qris',
|
// 'Qris',
|
||||||
widget.price,
|
// widget.price,
|
||||||
OrderType.dineIn));
|
// OrderType.dineIn));
|
||||||
await showDialog(
|
// await showDialog(
|
||||||
context: context,
|
// context: context,
|
||||||
barrierDismissible: false,
|
// barrierDismissible: false,
|
||||||
builder: (context) => SuccessPaymentDialog(
|
// builder: (context) => SuccessPaymentDialog(
|
||||||
isTablePaymentPage: widget.isTablePaymentPage,
|
// isTablePaymentPage: widget.isTablePaymentPage,
|
||||||
data: widget.items,
|
// data: widget.items,
|
||||||
totalQty: widget.totalQty,
|
// totalQty: widget.totalQty,
|
||||||
totalPrice: widget.price,
|
// totalPrice: widget.price,
|
||||||
totalTax: widget.tax,
|
// totalTax: widget.tax,
|
||||||
totalDiscount: widget.discountAmount,
|
// totalDiscount: widget.discountAmount,
|
||||||
subTotal: widget.subTotal,
|
// subTotal: widget.subTotal,
|
||||||
normalPrice: widget.price,
|
// normalPrice: widget.price,
|
||||||
totalService: widget.serviceCharge,
|
// totalService: widget.serviceCharge,
|
||||||
draftName: widget.customerName,
|
// draftName: widget.customerName,
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: BlocBuilder<QrisBloc, QrisState>(
|
child: BlocBuilder<QrisBloc, QrisState>(
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import 'package:enaklo_pos/presentation/home/bloc/order/order_bloc.dart';
|
|||||||
import 'package:enaklo_pos/presentation/home/bloc/payment_methods/payment_methods_bloc.dart';
|
import 'package:enaklo_pos/presentation/home/bloc/payment_methods/payment_methods_bloc.dart';
|
||||||
import 'package:enaklo_pos/presentation/home/models/product_quantity.dart';
|
import 'package:enaklo_pos/presentation/home/models/product_quantity.dart';
|
||||||
import 'package:enaklo_pos/presentation/home/models/order_type.dart';
|
import 'package:enaklo_pos/presentation/home/models/order_type.dart';
|
||||||
import 'package:enaklo_pos/presentation/home/widgets/save_order_dialog.dart';
|
// import 'package:enaklo_pos/presentation/home/widgets/save_order_dialog.dart';
|
||||||
import 'package:enaklo_pos/data/models/response/payment_methods_response_model.dart';
|
import 'package:enaklo_pos/data/models/response/payment_methods_response_model.dart';
|
||||||
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
|
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
|
||||||
|
|
||||||
@ -214,8 +214,24 @@ class _HomePageState extends State<HomePage> {
|
|||||||
final filteredProducts =
|
final filteredProducts =
|
||||||
_filterProducts(products);
|
_filterProducts(products);
|
||||||
if (filteredProducts.isEmpty) {
|
if (filteredProducts.isEmpty) {
|
||||||
return const Center(
|
return Center(
|
||||||
child: Text('No Items Found'),
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text('No Items Found'),
|
||||||
|
SpaceHeight(20),
|
||||||
|
Button.filled(
|
||||||
|
width: 120,
|
||||||
|
onPressed: () {
|
||||||
|
context
|
||||||
|
.read<
|
||||||
|
ProductLoaderBloc>()
|
||||||
|
.add(const ProductLoaderEvent
|
||||||
|
.getProduct());
|
||||||
|
},
|
||||||
|
label: 'Retry',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return GridView.builder(
|
return GridView.builder(
|
||||||
|
|||||||
@ -1,211 +0,0 @@
|
|||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:enaklo_pos/core/extensions/string_ext.dart';
|
|
||||||
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
|
|
||||||
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
|
|
||||||
import 'package:enaklo_pos/data/dataoutputs/print_dataoutputs.dart';
|
|
||||||
import 'package:enaklo_pos/data/models/response/table_model.dart';
|
|
||||||
import 'package:enaklo_pos/presentation/home/models/product_quantity.dart';
|
|
||||||
|
|
||||||
import '../../../core/assets/assets.gen.dart';
|
|
||||||
import '../../../core/components/buttons.dart';
|
|
||||||
import '../../../core/components/spaces.dart';
|
|
||||||
import '../../table/blocs/get_table/get_table_bloc.dart';
|
|
||||||
import '../bloc/checkout/checkout_bloc.dart';
|
|
||||||
import '../models/order_type.dart';
|
|
||||||
import 'package:enaklo_pos/core/utils/printer_service.dart';
|
|
||||||
|
|
||||||
class SaveOrderDialog extends StatefulWidget {
|
|
||||||
const SaveOrderDialog({
|
|
||||||
super.key,
|
|
||||||
required this.data,
|
|
||||||
required this.totalQty,
|
|
||||||
required this.totalPrice,
|
|
||||||
required this.totalTax,
|
|
||||||
required this.totalDiscount,
|
|
||||||
required this.subTotal,
|
|
||||||
required this.normalPrice,
|
|
||||||
required this.table,
|
|
||||||
required this.draftName,
|
|
||||||
});
|
|
||||||
final List<ProductQuantity> data;
|
|
||||||
final int totalQty;
|
|
||||||
final int totalPrice;
|
|
||||||
final int totalTax;
|
|
||||||
final int totalDiscount;
|
|
||||||
final int subTotal;
|
|
||||||
final int normalPrice;
|
|
||||||
final TableModel table;
|
|
||||||
final String draftName;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<SaveOrderDialog> createState() => _SaveOrderDialogState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SaveOrderDialogState extends State<SaveOrderDialog> {
|
|
||||||
// List<ProductQuantity> data = [];
|
|
||||||
// int totalQty = 0;
|
|
||||||
// int totalPrice = 0;
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return AlertDialog(
|
|
||||||
content: SingleChildScrollView(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Center(child: Assets.icons.success.svg()),
|
|
||||||
const SpaceHeight(16.0),
|
|
||||||
const Center(
|
|
||||||
child: Text(
|
|
||||||
'Order Berhasil Disimpan',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SpaceHeight(20.0),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Flexible(
|
|
||||||
child: Button.outlined(
|
|
||||||
onPressed: () {
|
|
||||||
context
|
|
||||||
.read<CheckoutBloc>()
|
|
||||||
.add(const CheckoutEvent.started([]));
|
|
||||||
context
|
|
||||||
.read<GetTableBloc>()
|
|
||||||
.add(const GetTableEvent.getTables());
|
|
||||||
context.popToRoot();
|
|
||||||
},
|
|
||||||
label: 'Kembali',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SpaceWidth(8.0),
|
|
||||||
Flexible(
|
|
||||||
child: BlocBuilder<CheckoutBloc, CheckoutState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
final orderType = state.maybeWhen(
|
|
||||||
orElse: () => OrderType.dineIn,
|
|
||||||
loaded: (
|
|
||||||
items,
|
|
||||||
discountModel,
|
|
||||||
discount,
|
|
||||||
discountAmount,
|
|
||||||
tax,
|
|
||||||
serviceCharge,
|
|
||||||
totalQuantity,
|
|
||||||
totalPrice,
|
|
||||||
draftName,
|
|
||||||
orderType,
|
|
||||||
deliveryType,
|
|
||||||
) =>
|
|
||||||
orderType,
|
|
||||||
);
|
|
||||||
|
|
||||||
return Button.filled(
|
|
||||||
onPressed: () async {
|
|
||||||
final checkerPrinter = await ProductLocalDatasource
|
|
||||||
.instance
|
|
||||||
.getPrinterByCode('checker');
|
|
||||||
final kitchenPrinter = await ProductLocalDatasource
|
|
||||||
.instance
|
|
||||||
.getPrinterByCode('kitchen');
|
|
||||||
final barPrinter = await ProductLocalDatasource
|
|
||||||
.instance
|
|
||||||
.getPrinterByCode('bar');
|
|
||||||
|
|
||||||
log("Checker printer: ${checkerPrinter?.toMap()}");
|
|
||||||
log("Kitchen printer: ${kitchenPrinter?.toMap()}");
|
|
||||||
log("Bar printer: ${barPrinter?.toMap()}");
|
|
||||||
|
|
||||||
// Checker printer
|
|
||||||
if (checkerPrinter != null) {
|
|
||||||
try {
|
|
||||||
final printValue = await PrintDataoutputs.instance
|
|
||||||
.printChecker(
|
|
||||||
widget.data,
|
|
||||||
widget.table.tableName!,
|
|
||||||
widget.draftName,
|
|
||||||
'kasir',
|
|
||||||
checkerPrinter.paper.toIntegerFromText,
|
|
||||||
orderType.value);
|
|
||||||
|
|
||||||
await PrinterService().printWithPrinter(
|
|
||||||
checkerPrinter, printValue, context);
|
|
||||||
} catch (e) {
|
|
||||||
log("Error printing checker: $e");
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(
|
|
||||||
content:
|
|
||||||
Text('Error printing checker: $e')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kitchen printer
|
|
||||||
if (kitchenPrinter != null) {
|
|
||||||
try {
|
|
||||||
final printValue =
|
|
||||||
await PrintDataoutputs.instance.printKitchen(
|
|
||||||
widget.data,
|
|
||||||
widget.table.tableName!,
|
|
||||||
widget.draftName,
|
|
||||||
'kasir',
|
|
||||||
kitchenPrinter.paper.toIntegerFromText,
|
|
||||||
orderType.value,
|
|
||||||
);
|
|
||||||
|
|
||||||
await PrinterService().printWithPrinter(
|
|
||||||
kitchenPrinter, printValue, context);
|
|
||||||
} catch (e) {
|
|
||||||
log("Error printing kitchen order: $e");
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(
|
|
||||||
content: Text(
|
|
||||||
'Error printing kitchen order: $e')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bar printer
|
|
||||||
if (barPrinter != null) {
|
|
||||||
try {
|
|
||||||
final printValue =
|
|
||||||
await PrintDataoutputs.instance.printBar(
|
|
||||||
widget.data,
|
|
||||||
widget.table.tableName!,
|
|
||||||
widget.draftName,
|
|
||||||
'kasir',
|
|
||||||
barPrinter.paper.toIntegerFromText,
|
|
||||||
orderType.value,
|
|
||||||
);
|
|
||||||
|
|
||||||
await PrinterService().printWithPrinter(
|
|
||||||
barPrinter, printValue, context);
|
|
||||||
} catch (e) {
|
|
||||||
log("Error printing bar order: $e");
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(
|
|
||||||
content:
|
|
||||||
Text('Error printing bar order: $e')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
label: 'Print Checker',
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,349 +0,0 @@
|
|||||||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
|
||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
|
|
||||||
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
|
|
||||||
import 'package:enaklo_pos/core/extensions/int_ext.dart';
|
|
||||||
import 'package:enaklo_pos/core/extensions/string_ext.dart';
|
|
||||||
import 'package:enaklo_pos/data/dataoutputs/print_dataoutputs.dart';
|
|
||||||
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
|
|
||||||
import 'package:enaklo_pos/presentation/home/models/product_quantity.dart';
|
|
||||||
import 'package:enaklo_pos/presentation/home/models/order_type.dart';
|
|
||||||
import 'package:enaklo_pos/core/utils/printer_service.dart';
|
|
||||||
import 'package:enaklo_pos/data/datasources/settings_local_datasource.dart';
|
|
||||||
|
|
||||||
import '../../../core/assets/assets.gen.dart';
|
|
||||||
import '../../../core/components/buttons.dart';
|
|
||||||
import '../../../core/components/spaces.dart';
|
|
||||||
import '../../table/blocs/get_table/get_table_bloc.dart';
|
|
||||||
import '../bloc/checkout/checkout_bloc.dart';
|
|
||||||
import '../bloc/order/order_bloc.dart';
|
|
||||||
|
|
||||||
class SuccessPaymentDialog extends StatefulWidget {
|
|
||||||
const SuccessPaymentDialog({
|
|
||||||
Key? key,
|
|
||||||
required this.data,
|
|
||||||
required this.totalQty,
|
|
||||||
required this.totalPrice,
|
|
||||||
required this.totalTax,
|
|
||||||
required this.totalDiscount,
|
|
||||||
required this.subTotal,
|
|
||||||
required this.normalPrice,
|
|
||||||
required this.totalService,
|
|
||||||
required this.draftName,
|
|
||||||
this.isTablePaymentPage = false,
|
|
||||||
}) : super(key: key);
|
|
||||||
final List<ProductQuantity> data;
|
|
||||||
final int totalQty;
|
|
||||||
final int totalPrice;
|
|
||||||
final int totalTax;
|
|
||||||
final int totalDiscount;
|
|
||||||
final int subTotal;
|
|
||||||
final int normalPrice;
|
|
||||||
final int totalService;
|
|
||||||
final String draftName;
|
|
||||||
final bool? isTablePaymentPage;
|
|
||||||
@override
|
|
||||||
State<SuccessPaymentDialog> createState() => _SuccessPaymentDialogState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SuccessPaymentDialogState extends State<SuccessPaymentDialog> {
|
|
||||||
// List<ProductQuantity> data = [];
|
|
||||||
// int totalQty = 0;
|
|
||||||
// int totalPrice = 0;
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return AlertDialog(
|
|
||||||
content: SingleChildScrollView(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Center(child: Assets.icons.success.svg()),
|
|
||||||
const SpaceHeight(16.0),
|
|
||||||
const Center(
|
|
||||||
child: Text(
|
|
||||||
'Pembayaran telah sukses dilakukan',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SpaceHeight(20.0),
|
|
||||||
const Text('METODE BAYAR'),
|
|
||||||
const SpaceHeight(5.0),
|
|
||||||
BlocBuilder<OrderBloc, OrderState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
final paymentMethod = state.maybeWhen(
|
|
||||||
orElse: () => 'Cash',
|
|
||||||
loaded: (model, orderId) => model.paymentMethod,
|
|
||||||
);
|
|
||||||
return Text(
|
|
||||||
paymentMethod,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SpaceHeight(10.0),
|
|
||||||
const Divider(),
|
|
||||||
const SpaceHeight(8.0),
|
|
||||||
const Text('TOTAL TAGIHAN'),
|
|
||||||
const SpaceHeight(5.0),
|
|
||||||
BlocBuilder<OrderBloc, OrderState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
state.maybeWhen(
|
|
||||||
orElse: () => 0,
|
|
||||||
loaded: (model, orderId) => model.total,
|
|
||||||
);
|
|
||||||
return Text(
|
|
||||||
widget.totalPrice.currencyFormatRp,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SpaceHeight(10.0),
|
|
||||||
const Divider(),
|
|
||||||
const SpaceHeight(8.0),
|
|
||||||
const Text('NOMINAL BAYAR'),
|
|
||||||
const SpaceHeight(5.0),
|
|
||||||
BlocBuilder<OrderBloc, OrderState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
final paymentAmount = state.maybeWhen(
|
|
||||||
orElse: () => 0,
|
|
||||||
loaded: (model, orderId) => model.paymentAmount,
|
|
||||||
);
|
|
||||||
return Text(
|
|
||||||
paymentAmount.ceil().currencyFormatRp,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
const SpaceHeight(8.0),
|
|
||||||
const Text('KEMBALIAN'),
|
|
||||||
const SpaceHeight(5.0),
|
|
||||||
BlocBuilder<OrderBloc, OrderState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
final paymentAmount = state.maybeWhen(
|
|
||||||
orElse: () => 0,
|
|
||||||
loaded: (model, orderId) => model.paymentAmount,
|
|
||||||
);
|
|
||||||
final total = state.maybeWhen(
|
|
||||||
orElse: () => 0,
|
|
||||||
loaded: (model, orderId) => model.total,
|
|
||||||
);
|
|
||||||
final diff = paymentAmount - total;
|
|
||||||
log("DIFF: $diff paymentAmount: $paymentAmount total: $total");
|
|
||||||
return Text(
|
|
||||||
diff.ceil().currencyFormatRp,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SpaceHeight(10.0),
|
|
||||||
const Divider(),
|
|
||||||
const SpaceHeight(8.0),
|
|
||||||
const Text('WAKTU PEMBAYARAN'),
|
|
||||||
const SpaceHeight(5.0),
|
|
||||||
Text(
|
|
||||||
DateFormat('dd MMMM yyyy, HH:mm').format(DateTime.now()),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SpaceHeight(20.0),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Flexible(
|
|
||||||
child: Button.outlined(
|
|
||||||
onPressed: () {
|
|
||||||
// For table payment page, just close the dialog
|
|
||||||
// The cleanup and navigation is handled by the payment page
|
|
||||||
if (widget.isTablePaymentPage == true) {
|
|
||||||
Navigator.of(context).pop(); // Close dialog only
|
|
||||||
} else {
|
|
||||||
// For regular payment flow, reset and go to root
|
|
||||||
context
|
|
||||||
.read<CheckoutBloc>()
|
|
||||||
.add(const CheckoutEvent.started([]));
|
|
||||||
context
|
|
||||||
.read<GetTableBloc>()
|
|
||||||
.add(const GetTableEvent.getTables());
|
|
||||||
context.popToRoot();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
label: 'Kembali',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SpaceWidth(8.0),
|
|
||||||
Flexible(
|
|
||||||
child: BlocBuilder<OrderBloc, OrderState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
final paymentAmount = state.maybeWhen(
|
|
||||||
orElse: () => 0,
|
|
||||||
loaded: (model, orderId) => model.paymentAmount,
|
|
||||||
);
|
|
||||||
|
|
||||||
final kembalian = paymentAmount - widget.totalPrice;
|
|
||||||
return BlocBuilder<CheckoutBloc, CheckoutState>(
|
|
||||||
builder: (context, checkoutState) {
|
|
||||||
final orderType = checkoutState.maybeWhen(
|
|
||||||
orElse: () => OrderType.dineIn,
|
|
||||||
loaded: (
|
|
||||||
items,
|
|
||||||
discountModel,
|
|
||||||
discount,
|
|
||||||
discountAmount,
|
|
||||||
tax,
|
|
||||||
serviceCharge,
|
|
||||||
totalQuantity,
|
|
||||||
totalPrice,
|
|
||||||
draftName,
|
|
||||||
orderType,
|
|
||||||
deliveryType,
|
|
||||||
) =>
|
|
||||||
orderType,
|
|
||||||
);
|
|
||||||
|
|
||||||
return Button.filled(
|
|
||||||
onPressed: () async {
|
|
||||||
final receiptPrinter =
|
|
||||||
await ProductLocalDatasource.instance
|
|
||||||
.getPrinterByCode('receipt');
|
|
||||||
final kitchenPrinter =
|
|
||||||
await ProductLocalDatasource.instance
|
|
||||||
.getPrinterByCode('kitchen');
|
|
||||||
final barPrinter = await ProductLocalDatasource
|
|
||||||
.instance
|
|
||||||
.getPrinterByCode('bar');
|
|
||||||
|
|
||||||
// Receipt Printer
|
|
||||||
if (receiptPrinter != null) {
|
|
||||||
try {
|
|
||||||
final settingsLocalDatasource =
|
|
||||||
SettingsLocalDatasource();
|
|
||||||
final taxModel =
|
|
||||||
await settingsLocalDatasource.getTax();
|
|
||||||
final serviceChargeValue =
|
|
||||||
await settingsLocalDatasource
|
|
||||||
.getServiceCharge();
|
|
||||||
|
|
||||||
// Get the actual payment method from OrderBloc
|
|
||||||
final paymentMethod = state.maybeWhen(
|
|
||||||
orElse: () => 'Cash',
|
|
||||||
loaded: (model, orderId) =>
|
|
||||||
model.paymentMethod,
|
|
||||||
);
|
|
||||||
|
|
||||||
final printValue = await PrintDataoutputs
|
|
||||||
.instance
|
|
||||||
.printOrderV3(
|
|
||||||
widget.data,
|
|
||||||
widget.totalQty,
|
|
||||||
widget.totalPrice,
|
|
||||||
paymentMethod,
|
|
||||||
paymentAmount,
|
|
||||||
kembalian,
|
|
||||||
widget.subTotal,
|
|
||||||
widget.totalDiscount,
|
|
||||||
widget.totalTax,
|
|
||||||
widget.totalService,
|
|
||||||
'kasir',
|
|
||||||
widget.draftName,
|
|
||||||
receiptPrinter.paper.toIntegerFromText,
|
|
||||||
taxPercentage: taxModel.value,
|
|
||||||
serviceChargePercentage: serviceChargeValue,
|
|
||||||
);
|
|
||||||
|
|
||||||
await PrinterService().printWithPrinter(
|
|
||||||
receiptPrinter, printValue, context);
|
|
||||||
} catch (e) {
|
|
||||||
log("Error printing receipt: $e");
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(
|
|
||||||
content:
|
|
||||||
Text('Error printing receipt: $e')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kitchen Printer
|
|
||||||
if (kitchenPrinter != null &&
|
|
||||||
widget.isTablePaymentPage == false) {
|
|
||||||
try {
|
|
||||||
final printValue = await PrintDataoutputs
|
|
||||||
.instance
|
|
||||||
.printKitchen(
|
|
||||||
widget.data,
|
|
||||||
'',
|
|
||||||
widget.draftName,
|
|
||||||
'kasir',
|
|
||||||
kitchenPrinter.paper.toIntegerFromText,
|
|
||||||
orderType.value,
|
|
||||||
);
|
|
||||||
|
|
||||||
await PrinterService().printWithPrinter(
|
|
||||||
kitchenPrinter, printValue, context);
|
|
||||||
} catch (e) {
|
|
||||||
log("Error printing kitchen order: $e");
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(
|
|
||||||
content: Text(
|
|
||||||
'Error printing kitchen order: $e')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bar printer
|
|
||||||
if (barPrinter != null &&
|
|
||||||
widget.isTablePaymentPage == false) {
|
|
||||||
try {
|
|
||||||
final printValue =
|
|
||||||
await PrintDataoutputs.instance.printBar(
|
|
||||||
widget.data,
|
|
||||||
'',
|
|
||||||
widget.draftName,
|
|
||||||
'kasir',
|
|
||||||
barPrinter.paper.toIntegerFromText,
|
|
||||||
orderType.value,
|
|
||||||
);
|
|
||||||
|
|
||||||
await PrinterService().printWithPrinter(
|
|
||||||
barPrinter, printValue, context);
|
|
||||||
} catch (e) {
|
|
||||||
log("Error printing bar order: $e");
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(
|
|
||||||
content: Text(
|
|
||||||
'Error printing bar order: $e')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
label: 'Print',
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -160,48 +160,53 @@ class _BarPrinterPageState extends State<BarPrinterPage> {
|
|||||||
SpaceHeight(16),
|
SpaceHeight(16),
|
||||||
// button test print
|
// button test print
|
||||||
Button.outlined(
|
Button.outlined(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (addressController!.text.isNotEmpty && printNameController!.text.isNotEmpty) {
|
if (addressController!.text.isNotEmpty &&
|
||||||
try {
|
printNameController!.text.isNotEmpty) {
|
||||||
// Create a test print model
|
try {
|
||||||
final testPrinter = PrintModel(
|
// Create a test print model
|
||||||
code: 'bar',
|
final testPrinter = PrintModel(
|
||||||
name: printNameController!.text,
|
code: 'bar',
|
||||||
address: addressController!.text,
|
name: printNameController!.text,
|
||||||
paper: paper,
|
address: addressController!.text,
|
||||||
type: selectedPrinter,
|
paper: paper,
|
||||||
);
|
type: selectedPrinter,
|
||||||
|
);
|
||||||
|
|
||||||
// Generate test print data
|
// Generate test print data
|
||||||
final testPrintData = await PrintDataoutputs.instance.printBar(
|
final testPrintData =
|
||||||
[], // Empty product list for test
|
await PrintDataoutputs.instance.printBar(
|
||||||
'Test Table',
|
[], // Empty product list for test
|
||||||
'Test Order',
|
'Test Table',
|
||||||
'Test Cashier',
|
'Test Order',
|
||||||
int.parse(paper),
|
'Test Cashier',
|
||||||
'DINE IN',
|
'Test Customer',
|
||||||
);
|
int.parse(paper),
|
||||||
|
'DINE IN',
|
||||||
|
);
|
||||||
|
|
||||||
// Print test
|
// Print test
|
||||||
await PrinterService().printWithPrinter(
|
await PrinterService().printWithPrinter(
|
||||||
testPrinter,
|
testPrinter,
|
||||||
testPrintData,
|
testPrintData,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("Error test printing: $e");
|
log("Error test printing: $e");
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text('Error test printing: $e')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('Error test printing: $e')),
|
SnackBar(
|
||||||
|
content: Text(
|
||||||
|
'Please fill in printer details first')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
label: 'Test Print'),
|
||||||
SnackBar(content: Text('Please fill in printer details first')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
label: 'Test Print'
|
|
||||||
),
|
|
||||||
SpaceHeight(8),
|
SpaceHeight(8),
|
||||||
// button save
|
// button save
|
||||||
data == null
|
data == null
|
||||||
|
|||||||
@ -162,48 +162,54 @@ class _CheckerPrinterPageState extends State<CheckerPrinterPage> {
|
|||||||
SpaceHeight(16),
|
SpaceHeight(16),
|
||||||
// button test print
|
// button test print
|
||||||
Button.outlined(
|
Button.outlined(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (addressController!.text.isNotEmpty && printNameController!.text.isNotEmpty) {
|
if (addressController!.text.isNotEmpty &&
|
||||||
try {
|
printNameController!.text.isNotEmpty) {
|
||||||
// Create a test print model
|
try {
|
||||||
final testPrinter = PrintModel(
|
// Create a test print model
|
||||||
code: 'checker',
|
final testPrinter = PrintModel(
|
||||||
name: printNameController!.text,
|
code: 'checker',
|
||||||
address: addressController!.text,
|
name: printNameController!.text,
|
||||||
paper: paper,
|
address: addressController!.text,
|
||||||
type: selectedPrinter,
|
paper: paper,
|
||||||
);
|
type: selectedPrinter,
|
||||||
|
);
|
||||||
|
|
||||||
// Generate test print data
|
// Generate test print data
|
||||||
final testPrintData = await PrintDataoutputs.instance.printChecker(
|
final testPrintData = await PrintDataoutputs
|
||||||
[], // Empty product list for test
|
.instance
|
||||||
'Test Table',
|
.printChecker(
|
||||||
'Test Order',
|
[], // Empty product list for test
|
||||||
'Test Cashier',
|
'Test Table',
|
||||||
int.parse(paper),
|
'Test Order',
|
||||||
'DINE IN',
|
'Test Cashier',
|
||||||
);
|
'Test Customer',
|
||||||
|
int.parse(paper),
|
||||||
|
'DINE IN',
|
||||||
|
);
|
||||||
|
|
||||||
// Print test
|
// Print test
|
||||||
await PrinterService().printWithPrinter(
|
await PrinterService().printWithPrinter(
|
||||||
testPrinter,
|
testPrinter,
|
||||||
testPrintData,
|
testPrintData,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("Error test printing: $e");
|
log("Error test printing: $e");
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text('Error test printing: $e')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('Error test printing: $e')),
|
SnackBar(
|
||||||
|
content: Text(
|
||||||
|
'Please fill in printer details first')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
label: 'Test Print'),
|
||||||
SnackBar(content: Text('Please fill in printer details first')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
label: 'Test Print'
|
|
||||||
),
|
|
||||||
SpaceHeight(8),
|
SpaceHeight(8),
|
||||||
// button save
|
// button save
|
||||||
data == null
|
data == null
|
||||||
|
|||||||
@ -160,48 +160,54 @@ class _KitchenPrinterPageState extends State<KitchenPrinterPage> {
|
|||||||
SpaceHeight(16),
|
SpaceHeight(16),
|
||||||
// button test print
|
// button test print
|
||||||
Button.outlined(
|
Button.outlined(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (addressController!.text.isNotEmpty && printNameController!.text.isNotEmpty) {
|
if (addressController!.text.isNotEmpty &&
|
||||||
try {
|
printNameController!.text.isNotEmpty) {
|
||||||
// Create a test print model
|
try {
|
||||||
final testPrinter = PrintModel(
|
// Create a test print model
|
||||||
code: 'kitchen',
|
final testPrinter = PrintModel(
|
||||||
name: printNameController!.text,
|
code: 'kitchen',
|
||||||
address: addressController!.text,
|
name: printNameController!.text,
|
||||||
paper: paper,
|
address: addressController!.text,
|
||||||
type: selectedPrinter,
|
paper: paper,
|
||||||
);
|
type: selectedPrinter,
|
||||||
|
);
|
||||||
|
|
||||||
// Generate test print data
|
// Generate test print data
|
||||||
final testPrintData = await PrintDataoutputs.instance.printKitchen(
|
final testPrintData = await PrintDataoutputs
|
||||||
[], // Empty product list for test
|
.instance
|
||||||
'Test Table',
|
.printKitchen(
|
||||||
'Test Order',
|
[], // Empty product list for test
|
||||||
'Test Cashier',
|
'Test Table',
|
||||||
int.parse(paper),
|
'Test Order',
|
||||||
'DINE IN',
|
'Test Cashier',
|
||||||
);
|
'Test Customer',
|
||||||
|
int.parse(paper),
|
||||||
|
'DINE IN',
|
||||||
|
);
|
||||||
|
|
||||||
// Print test
|
// Print test
|
||||||
await PrinterService().printWithPrinter(
|
await PrinterService().printWithPrinter(
|
||||||
testPrinter,
|
testPrinter,
|
||||||
testPrintData,
|
testPrintData,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("Error test printing: $e");
|
log("Error test printing: $e");
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text('Error test printing: $e')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('Error test printing: $e')),
|
SnackBar(
|
||||||
|
content: Text(
|
||||||
|
'Please fill in printer details first')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
label: 'Test Print'),
|
||||||
SnackBar(content: Text('Please fill in printer details first')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
label: 'Test Print'
|
|
||||||
),
|
|
||||||
SpaceHeight(8),
|
SpaceHeight(8),
|
||||||
// button save
|
// button save
|
||||||
data == null
|
data == null
|
||||||
|
|||||||
@ -204,180 +204,186 @@ class _SuccessOrderPageState extends State<SuccessOrderPage>
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// Success Header with Glassmorphism Effect
|
// Success Header with Glassmorphism Effect
|
||||||
Container(
|
|
||||||
width: double.infinity,
|
|
||||||
padding: const EdgeInsets.all(32.0),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
begin: Alignment.topLeft,
|
|
||||||
end: Alignment.bottomRight,
|
|
||||||
colors: [
|
|
||||||
AppColors.primary.withOpacity(0.1),
|
|
||||||
AppColors.primary.withOpacity(0.05),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
borderRadius: const BorderRadius.vertical(
|
|
||||||
top: Radius.circular(24),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
// Animated Success Icon with Floating Effect
|
|
||||||
AnimatedBuilder(
|
|
||||||
animation: _floatingAnimation,
|
|
||||||
builder: (context, child) {
|
|
||||||
return Transform.translate(
|
|
||||||
offset: Offset(0, _floatingAnimation.value),
|
|
||||||
child: ScaleTransition(
|
|
||||||
scale: _successIconAnimation,
|
|
||||||
child: Container(
|
|
||||||
padding: const EdgeInsets.all(20.0),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
begin: Alignment.topLeft,
|
|
||||||
end: Alignment.bottomRight,
|
|
||||||
colors: [
|
|
||||||
AppColors.primary,
|
|
||||||
AppColors.primary.withOpacity(0.8),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColors.primary.withOpacity(0.3),
|
|
||||||
blurRadius: 20,
|
|
||||||
offset: const Offset(0, 10),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: const Icon(
|
|
||||||
Icons.check_rounded,
|
|
||||||
size: 48,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
|
|
||||||
// Success Title with Shimmer Effect
|
|
||||||
FadeTransition(
|
|
||||||
opacity: _fadeInAnimation,
|
|
||||||
child: ShaderMask(
|
|
||||||
shaderCallback: (bounds) {
|
|
||||||
return LinearGradient(
|
|
||||||
begin: Alignment.centerLeft,
|
|
||||||
end: Alignment.centerRight,
|
|
||||||
colors: const [
|
|
||||||
AppColors.primary,
|
|
||||||
Colors.amber,
|
|
||||||
AppColors.primary,
|
|
||||||
],
|
|
||||||
stops: [
|
|
||||||
_shimmerAnimation.value - 1,
|
|
||||||
_shimmerAnimation.value,
|
|
||||||
_shimmerAnimation.value + 1,
|
|
||||||
],
|
|
||||||
).createShader(bounds);
|
|
||||||
},
|
|
||||||
child: const Text(
|
|
||||||
'Pesanan Berhasil!',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 26,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
|
|
||||||
FadeTransition(
|
|
||||||
opacity: _fadeInAnimation,
|
|
||||||
child: Container(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 16,
|
|
||||||
vertical: 8,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white.withOpacity(0.2),
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
),
|
|
||||||
child: const Text(
|
|
||||||
'Pesanan telah diterima dan sedang diproses',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: AppColors.primary,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Order Information Section
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: SingleChildScrollView(
|
||||||
padding: const EdgeInsets.all(24.0),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
_buildSectionTitle('Informasi Pesanan'),
|
Container(
|
||||||
const SizedBox(height: 24),
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.all(32.0),
|
||||||
// Customer Card with Gradient Background
|
decoration: BoxDecoration(
|
||||||
_buildInfoCard(
|
gradient: LinearGradient(
|
||||||
icon: Icons.person_outline_rounded,
|
begin: Alignment.topLeft,
|
||||||
title: 'Nama Pelanggan',
|
end: Alignment.bottomRight,
|
||||||
value: widget.order.metadata?['customer_name'] ?? "-",
|
colors: [
|
||||||
gradient: [
|
AppColors.primary.withOpacity(0.1),
|
||||||
Colors.blue.withOpacity(0.1),
|
AppColors.primary.withOpacity(0.05),
|
||||||
Colors.purple.withOpacity(0.1),
|
],
|
||||||
],
|
),
|
||||||
),
|
borderRadius: const BorderRadius.vertical(
|
||||||
|
top: Radius.circular(24),
|
||||||
const SizedBox(height: 16),
|
),
|
||||||
|
),
|
||||||
// Order Details Grid
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
_buildInfoRow(
|
// Animated Success Icon with Floating Effect
|
||||||
icon: Icons.receipt_long_outlined,
|
AnimatedBuilder(
|
||||||
label: 'No. Pesanan',
|
animation: _floatingAnimation,
|
||||||
value: widget.order.orderNumber ?? "-",
|
builder: (context, child) {
|
||||||
delay: 0.3,
|
return Transform.translate(
|
||||||
|
offset: Offset(0, _floatingAnimation.value),
|
||||||
|
child: ScaleTransition(
|
||||||
|
scale: _successIconAnimation,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(20.0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
colors: [
|
||||||
|
AppColors.primary,
|
||||||
|
AppColors.primary.withOpacity(0.8),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColors.primary
|
||||||
|
.withOpacity(0.3),
|
||||||
|
blurRadius: 20,
|
||||||
|
offset: const Offset(0, 10),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: const Icon(
|
||||||
|
Icons.check_rounded,
|
||||||
|
size: 48,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
|
||||||
_buildInfoRow(
|
const SizedBox(height: 24),
|
||||||
icon: Icons.table_restaurant_outlined,
|
|
||||||
label: 'No. Meja',
|
// Success Title with Shimmer Effect
|
||||||
value: widget.order.tableNumber ?? "-",
|
FadeTransition(
|
||||||
delay: 0.4,
|
opacity: _fadeInAnimation,
|
||||||
|
child: ShaderMask(
|
||||||
|
shaderCallback: (bounds) {
|
||||||
|
return LinearGradient(
|
||||||
|
begin: Alignment.centerLeft,
|
||||||
|
end: Alignment.centerRight,
|
||||||
|
colors: const [
|
||||||
|
AppColors.primary,
|
||||||
|
Colors.amber,
|
||||||
|
AppColors.primary,
|
||||||
|
],
|
||||||
|
stops: [
|
||||||
|
_shimmerAnimation.value - 1,
|
||||||
|
_shimmerAnimation.value,
|
||||||
|
_shimmerAnimation.value + 1,
|
||||||
|
],
|
||||||
|
).createShader(bounds);
|
||||||
|
},
|
||||||
|
child: const Text(
|
||||||
|
'Pesanan Berhasil!',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 26,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
_buildInfoRow(
|
|
||||||
icon: Icons.access_time_rounded,
|
FadeTransition(
|
||||||
label: 'Waktu',
|
opacity: _fadeInAnimation,
|
||||||
value: (widget.order.createdAt ?? DateTime.now())
|
child: Container(
|
||||||
.toFormattedDate3(),
|
padding: const EdgeInsets.symmetric(
|
||||||
delay: 0.5,
|
horizontal: 16,
|
||||||
|
vertical: 8,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white.withOpacity(0.2),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
child: const Text(
|
||||||
|
'Pesanan telah diterima dan sedang diproses',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: AppColors.primary,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
],
|
||||||
_buildInfoRow(
|
),
|
||||||
icon: Icons.check_circle_outline,
|
),
|
||||||
label: 'Status Pembayaran',
|
// Order Information Section
|
||||||
value: 'Lunas',
|
Padding(
|
||||||
delay: 0.6,
|
padding: const EdgeInsets.all(24.0),
|
||||||
valueColor: Colors.green,
|
child: Column(
|
||||||
showBadge: true,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
_buildSectionTitle('Informasi Pesanan'),
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
|
// Customer Card with Gradient Background
|
||||||
|
_buildInfoCard(
|
||||||
|
icon: Icons.person_outline_rounded,
|
||||||
|
title: 'Nama Pelanggan',
|
||||||
|
value:
|
||||||
|
widget.order.metadata?['customer_name'] ?? "-",
|
||||||
|
gradient: [
|
||||||
|
Colors.blue.withOpacity(0.1),
|
||||||
|
Colors.purple.withOpacity(0.1),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Order Details Grid
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
_buildInfoRow(
|
||||||
|
icon: Icons.receipt_long_outlined,
|
||||||
|
label: 'No. Pesanan',
|
||||||
|
value: widget.order.orderNumber ?? "-",
|
||||||
|
delay: 0.3,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildInfoRow(
|
||||||
|
icon: Icons.wallet_outlined,
|
||||||
|
label: 'Metode Pembayaran',
|
||||||
|
value: widget.paymentMethod ?? "-",
|
||||||
|
delay: 0.3,
|
||||||
|
),
|
||||||
|
if (widget.order.tableNumber != "") ...[
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildInfoRow(
|
||||||
|
icon: Icons.table_restaurant_outlined,
|
||||||
|
label: 'No. Meja',
|
||||||
|
value: widget.order.tableNumber ?? "-",
|
||||||
|
delay: 0.4,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildInfoRow(
|
||||||
|
icon: Icons.access_time_rounded,
|
||||||
|
label: 'Waktu',
|
||||||
|
value:
|
||||||
|
(widget.order.createdAt ?? DateTime.now())
|
||||||
|
.toFormattedDate3(),
|
||||||
|
delay: 0.5,
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -108,141 +108,146 @@ class _SuccessPaymentPageState extends State<SuccessPaymentPage> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// Success Header
|
// Success Header
|
||||||
Container(
|
|
||||||
width: double.infinity,
|
|
||||||
padding: const EdgeInsets.all(32.0),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
begin: Alignment.topLeft,
|
|
||||||
end: Alignment.bottomRight,
|
|
||||||
colors: [
|
|
||||||
AppColors.primary.withOpacity(0.1),
|
|
||||||
AppColors.primary.withOpacity(0.05),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
borderRadius: const BorderRadius.vertical(
|
|
||||||
top: Radius.circular(24),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
// Success Icon
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.all(20.0),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
begin: Alignment.topLeft,
|
|
||||||
end: Alignment.bottomRight,
|
|
||||||
colors: [
|
|
||||||
AppColors.primary,
|
|
||||||
AppColors.primary.withOpacity(0.8),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColors.primary.withOpacity(0.3),
|
|
||||||
blurRadius: 20,
|
|
||||||
offset: const Offset(0, 10),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: const Icon(
|
|
||||||
Icons.check_rounded,
|
|
||||||
size: 48,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
|
|
||||||
// Success Title
|
|
||||||
const Text(
|
|
||||||
'Pesanan Berhasil!',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 26,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: AppColors.primary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 16,
|
|
||||||
vertical: 8,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white.withOpacity(0.2),
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
),
|
|
||||||
child: const Text(
|
|
||||||
'Pesanan telah diterima dan sedang diproses',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: AppColors.primary,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Order Information Section
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: SingleChildScrollView(
|
||||||
padding: const EdgeInsets.all(24.0),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
_buildSectionTitle('Informasi Pesanan'),
|
Container(
|
||||||
const SizedBox(height: 24),
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.all(32.0),
|
||||||
// Customer Card
|
decoration: BoxDecoration(
|
||||||
_buildInfoCard(
|
gradient: LinearGradient(
|
||||||
icon: Icons.person_outline_rounded,
|
begin: Alignment.topLeft,
|
||||||
title: 'Nama Pelanggan',
|
end: Alignment.bottomRight,
|
||||||
value: order.metadata?['customer_name'] ?? "-",
|
colors: [
|
||||||
gradient: [
|
AppColors.primary.withOpacity(0.1),
|
||||||
Colors.blue.withOpacity(0.1),
|
AppColors.primary.withOpacity(0.05),
|
||||||
Colors.purple.withOpacity(0.1),
|
],
|
||||||
],
|
),
|
||||||
),
|
borderRadius: const BorderRadius.vertical(
|
||||||
|
top: Radius.circular(24),
|
||||||
const SizedBox(height: 16),
|
),
|
||||||
|
),
|
||||||
// Order Details
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
_buildInfoRow(
|
// Success Icon
|
||||||
icon: Icons.receipt_long_outlined,
|
Container(
|
||||||
label: 'No. Pesanan',
|
padding: const EdgeInsets.all(20.0),
|
||||||
value: order.orderNumber ?? "-",
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
colors: [
|
||||||
|
AppColors.primary,
|
||||||
|
AppColors.primary.withOpacity(0.8),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColors.primary.withOpacity(0.3),
|
||||||
|
blurRadius: 20,
|
||||||
|
offset: const Offset(0, 10),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: const Icon(
|
||||||
|
Icons.check_rounded,
|
||||||
|
size: 48,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
|
||||||
_buildInfoRow(
|
const SizedBox(height: 24),
|
||||||
icon: Icons.table_restaurant_outlined,
|
|
||||||
label: 'No. Meja',
|
// Success Title
|
||||||
value: order.tableNumber ?? "-",
|
const Text(
|
||||||
|
'Pesanan Berhasil!',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 26,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: AppColors.primary,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
_buildInfoRow(
|
|
||||||
icon: Icons.access_time_rounded,
|
Container(
|
||||||
label: 'Waktu',
|
padding: const EdgeInsets.symmetric(
|
||||||
value: (order.createdAt ?? DateTime.now())
|
horizontal: 16,
|
||||||
.toFormattedDate3(),
|
vertical: 8,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white.withOpacity(0.2),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
child: const Text(
|
||||||
|
'Pesanan telah diterima dan sedang diproses',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: AppColors.primary,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
],
|
||||||
_buildInfoRow(
|
),
|
||||||
icon: Icons.check_circle_outline,
|
),
|
||||||
label: 'Status Pembayaran',
|
// Order Information Section
|
||||||
value: 'Lunas',
|
Padding(
|
||||||
valueColor: Colors.green,
|
padding: const EdgeInsets.all(24.0),
|
||||||
showBadge: true,
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
_buildSectionTitle('Informasi Pesanan'),
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
|
// Customer Card
|
||||||
|
_buildInfoCard(
|
||||||
|
icon: Icons.person_outline_rounded,
|
||||||
|
title: 'Nama Pelanggan',
|
||||||
|
value: order.metadata?['customer_name'] ?? "-",
|
||||||
|
gradient: [
|
||||||
|
Colors.blue.withOpacity(0.1),
|
||||||
|
Colors.purple.withOpacity(0.1),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Order Details
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
_buildInfoRow(
|
||||||
|
icon: Icons.receipt_long_outlined,
|
||||||
|
label: 'No. Pesanan',
|
||||||
|
value: order.orderNumber ?? "-",
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildInfoRow(
|
||||||
|
icon: Icons.receipt_long_outlined,
|
||||||
|
label: 'Metode Pembayaran',
|
||||||
|
value: widget.paymentMethod,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildInfoRow(
|
||||||
|
icon: Icons.access_time_rounded,
|
||||||
|
label: 'Waktu',
|
||||||
|
value: (order.createdAt ?? DateTime.now())
|
||||||
|
.toFormattedDate3(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildInfoRow(
|
||||||
|
icon: Icons.check_circle_outline,
|
||||||
|
label: 'Status Pembayaran',
|
||||||
|
value: 'Lunas',
|
||||||
|
valueColor: Colors.green,
|
||||||
|
showBadge: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -79,6 +79,12 @@ class _TablePageState extends State<TablePage> {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text("Layout Meja"),
|
title: const Text("Layout Meja"),
|
||||||
actions: [
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.refresh),
|
||||||
|
onPressed: () {
|
||||||
|
context.read<GetTableBloc>().add(const GetTableEvent.getTables());
|
||||||
|
},
|
||||||
|
),
|
||||||
BlocListener<CreateTableBloc, CreateTableState>(
|
BlocListener<CreateTableBloc, CreateTableState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
state.maybeWhen(
|
state.maybeWhen(
|
||||||
|
|||||||
@ -16,7 +16,7 @@ import 'package:enaklo_pos/presentation/home/bloc/status_table/status_table_bloc
|
|||||||
import 'package:enaklo_pos/presentation/home/pages/home_page.dart';
|
import 'package:enaklo_pos/presentation/home/pages/home_page.dart';
|
||||||
import 'package:enaklo_pos/presentation/table/blocs/get_table/get_table_bloc.dart';
|
import 'package:enaklo_pos/presentation/table/blocs/get_table/get_table_bloc.dart';
|
||||||
import 'package:enaklo_pos/presentation/table/models/draft_order_model.dart';
|
import 'package:enaklo_pos/presentation/table/models/draft_order_model.dart';
|
||||||
import 'package:enaklo_pos/presentation/table/pages/payment_table_page.dart';
|
import 'package:enaklo_pos/presentation/table/pages/payment_table_page.dart.old';
|
||||||
|
|
||||||
class CardTableWidget extends StatefulWidget {
|
class CardTableWidget extends StatefulWidget {
|
||||||
final TableModel table;
|
final TableModel table;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user