Compare commits

..

No commits in common. "8022fa6b322a82e6fc8ba9ef6d6e40c1910e4bcb" and "7586df207e98b4b3473731ff24c1f65a91c2388b" have entirely different histories.

11 changed files with 49 additions and 401 deletions

View File

@ -23,7 +23,7 @@ if (flutterVersionName == null) {
}
android {
namespace "com.appscale.pos"
namespace "com.example.enaklo_pos"
compileSdkVersion 35
ndkVersion flutter.ndkVersion
@ -42,7 +42,7 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.appscale.pos"
applicationId "com.example.enaklo_pos"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 21

View File

@ -1,4 +1,4 @@
package com.appscale.pos
package com.example.enaklo_pos
import io.flutter.embedding.android.FlutterActivity

View File

@ -3,7 +3,6 @@ import 'dart:developer';
import 'package:enaklo_pos/core/extensions/string_ext.dart';
import 'package:enaklo_pos/core/utils/printer_service.dart';
import 'package:enaklo_pos/data/dataoutputs/print_dataoutputs.dart';
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
import 'package:enaklo_pos/data/models/response/order_response_model.dart';
import 'package:enaklo_pos/presentation/home/models/product_quantity.dart';
@ -21,11 +20,17 @@ Future<void> onPrint(
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(
productQuantity,
productQuantity
.where((e) => e.product.printerType == "checker")
.toList(),
order.tableNumber ?? "",
order.orderNumber ?? "",
'kasir',
@ -48,7 +53,9 @@ Future<void> onPrint(
if (kitchenPrinter != null) {
try {
final printValue = await PrintDataoutputs.instance.printKitchen(
productQuantity,
productQuantity
.where((e) => e.product.printerType == "kitchen")
.toList(),
order.tableNumber!,
order.orderNumber ?? "",
'kasir',
@ -70,7 +77,7 @@ Future<void> onPrint(
if (barPrinter != null) {
try {
final printValue = await PrintDataoutputs.instance.printBar(
productQuantity,
productQuantity.where((e) => e.product.printerType == "bar").toList(),
order.tableNumber ?? "",
order.orderNumber ?? "",
'kasir',
@ -87,37 +94,3 @@ Future<void> onPrint(
}
}
}
Future<void> onPrintRecipt(
context, {
required Order order,
required String paymentMethod,
required int nominalBayar,
required int kembalian,
required int taxPercentage,
}) async {
final receiptPrinter =
await ProductLocalDatasource.instance.getPrinterByCode('receipt');
final authData = await AuthLocalDataSource().getAuthData();
if (receiptPrinter != null) {
try {
final printValue = await PrintDataoutputs.instance.printOrderV4(
order,
authData.user?.name ?? "",
paymentMethod,
nominalBayar,
kembalian,
taxPercentage,
receiptPrinter.paper.toIntegerFromText,
);
await PrinterService()
.printWithPrinter(receiptPrinter, printValue, context);
} catch (e) {
log("Error printing receipt order: $e");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error printing receipt order: $e')),
);
}
}
}

View File

@ -1,6 +1,5 @@
import 'dart:math';
import 'package:enaklo_pos/data/models/response/order_response_model.dart';
import 'package:esc_pos_utils_plus/esc_pos_utils_plus.dart';
import 'package:flutter/services.dart';
import 'package:enaklo_pos/core/extensions/int_ext.dart';
@ -740,263 +739,6 @@ class PrintDataoutputs {
return bytes;
}
Future<List<int>> printOrderV4(
Order order,
String chashierName,
String paymentMethod,
int nominalBayar,
int kembalian,
int taxPercentage,
int paper,
) async {
List<int> bytes = [];
final profile = await CapabilityProfile.load();
final generator =
Generator(paper == 58 ? PaperSize.mm58 : PaperSize.mm80, profile);
bytes += generator.reset();
bytes += generator.text('Guapatlu Khas Bakmi Jambi',
styles: const PosStyles(
bold: true,
align: PosAlign.center,
height: PosTextSize.size1,
width: PosTextSize.size1,
));
bytes += generator.text('Gading Boulevard w2, No 25, Jakarta',
styles: const PosStyles(bold: false, align: PosAlign.center));
bytes += generator.text('085-77777-3839',
styles: const PosStyles(bold: false, align: PosAlign.center));
bytes += generator.text(
paper == 80
? '------------------------------------------------'
: '--------------------------------',
styles: const PosStyles(bold: false, align: PosAlign.center));
bytes += generator.row([
PosColumn(
text: DateFormat('dd MMM yyyy').format(DateTime.now()),
width: 6,
styles: const PosStyles(align: PosAlign.left),
),
PosColumn(
text: DateFormat('HH:mm').format(DateTime.now()),
width: 6,
styles: const PosStyles(align: PosAlign.right),
),
]);
bytes += generator.row([
PosColumn(
text: 'Receipt Number',
width: 6,
styles: const PosStyles(align: PosAlign.left),
),
PosColumn(
text: 'JF-${DateFormat('yyyyMMddhhmm').format(DateTime.now())}',
width: 6,
styles: const PosStyles(align: PosAlign.right),
),
]);
bytes += generator.row([
PosColumn(
text: 'Order ID',
width: 6,
styles: const PosStyles(align: PosAlign.left),
),
PosColumn(
text: Random().nextInt(100000).toString(),
width: 6,
styles: const PosStyles(align: PosAlign.right),
),
]);
bytes += generator.row([
PosColumn(
text: 'Bill Name',
width: 6,
styles: const PosStyles(align: PosAlign.left),
),
PosColumn(
text: order.metadata?['customer_name'] ?? '',
width: 6,
styles: const PosStyles(align: PosAlign.right),
),
]);
bytes += generator.row([
PosColumn(
text: 'Collected By',
width: 6,
styles: const PosStyles(align: PosAlign.left),
),
PosColumn(
text: chashierName,
width: 6,
styles: const PosStyles(align: PosAlign.right),
),
]);
bytes += generator.row([
PosColumn(
text: 'Pembayaran',
width: 8,
styles: const PosStyles(align: PosAlign.left),
),
PosColumn(
text: paymentMethod,
width: 4,
styles: const PosStyles(align: PosAlign.right),
),
]);
bytes += generator.text(
paper == 80
? '------------------------------------------------'
: '--------------------------------',
styles: const PosStyles(bold: false, align: PosAlign.center));
bytes += generator.text('Dine In',
styles: const PosStyles(bold: true, align: PosAlign.center));
bytes += generator.text(
paper == 80
? '------------------------------------------------'
: '--------------------------------',
styles: const PosStyles(bold: false, align: PosAlign.center));
for (final product in (order.orderItems ?? <OrderItem>[])) {
bytes += generator.row([
PosColumn(
text: '${product.quantity} x ${product.productName}',
width: 8,
styles: const PosStyles(bold: true, align: PosAlign.left),
),
PosColumn(
text: (product.totalPrice ?? 0).currencyFormatRpV2,
width: 4,
styles: const PosStyles(bold: true, align: PosAlign.right),
),
]);
}
bytes += generator.text(
paper == 80
? '------------------------------------------------'
: '--------------------------------',
styles: const PosStyles(bold: false, align: PosAlign.center));
bytes += generator.row([
PosColumn(
text: 'Subtotal ${order.orderItems?.length ?? "0"} Product',
width: 6,
styles: const PosStyles(align: PosAlign.left),
),
PosColumn(
text: (order.subtotal ?? 0).currencyFormatRpV2,
width: 6,
styles: const PosStyles(align: PosAlign.right),
),
]);
bytes += generator.row([
PosColumn(
text: 'Discount',
width: 6,
styles: const PosStyles(align: PosAlign.left),
),
PosColumn(
text: (order.discountAmount ?? 0).currencyFormatRpV2,
width: 6,
styles: const PosStyles(align: PosAlign.right),
),
]);
// Only show tax if it's greater than 0
if ((order.taxAmount ?? 0) > 0) {
bytes += generator.row([
PosColumn(
text: 'Tax PB1 ($taxPercentage%)',
width: 6,
styles: const PosStyles(align: PosAlign.left),
),
PosColumn(
text: (order.taxAmount ?? 0).currencyFormatRpV2,
width: 6,
styles: const PosStyles(align: PosAlign.right),
),
]);
}
// Only show service charge if it's greater than 0
// if (serviceCharge > 0) {
// bytes += generator.row([
// PosColumn(
// text: 'Service Charge($serviceChargePercentage%)',
// width: 6,
// styles: const PosStyles(align: PosAlign.left),
// ),
// PosColumn(
// text: serviceCharge.currencyFormatRpV2,
// width: 6,
// styles: const PosStyles(align: PosAlign.right),
// ),
// ]);
// }
bytes += generator.text(
paper == 80
? '------------------------------------------------'
: '--------------------------------',
styles: const PosStyles(bold: false, align: PosAlign.center));
bytes += generator.row([
PosColumn(
text: 'Total',
width: 6,
styles: const PosStyles(bold: true, align: PosAlign.left),
),
PosColumn(
text: '${order.totalAmount ?? ""}'.currencyFormatRpV2,
width: 6,
styles: const PosStyles(bold: true, align: PosAlign.right),
),
]);
bytes += generator.row([
PosColumn(
text: 'Dibayar',
width: 6,
styles: const PosStyles(align: PosAlign.left),
),
PosColumn(
text: nominalBayar.currencyFormatRpV2,
width: 6,
styles: const PosStyles(align: PosAlign.right),
),
]);
bytes += generator.row([
PosColumn(
text: 'Kembali',
width: 6,
styles: const PosStyles(align: PosAlign.left),
),
PosColumn(
text: kembalian.currencyFormatRpV2,
width: 6,
styles: const PosStyles(align: PosAlign.right),
),
]);
bytes += generator.text(
paper == 80
? '------------------------------------------------'
: '--------------------------------',
styles: const PosStyles(bold: false, align: PosAlign.center));
// bytes += generator.text('Notes',
// styles: const PosStyles(bold: false, align: PosAlign.center));
// bytes += generator.text('Pass Wifi: fic14jilid2',
// styles: const PosStyles(bold: false, align: PosAlign.center));
// //terima kasih
// bytes += generator.text('Terima Kasih',
// styles: const PosStyles(bold: true, align: PosAlign.center));
paper == 80 ? bytes += generator.feed(3) : bytes += generator.feed(1);
bytes += generator.cut();
return bytes;
}
Future<List<int>> printQRIS(
int totalPrice, Uint8List imageQris, int paper) async {
List<int> bytes = [];

View File

@ -220,8 +220,7 @@ class OrderRemoteDatasource {
return const Left('Gagal membuat pesanan');
}
} on DioException catch (e) {
final errorMessage =
e.response?.data['message'] ?? 'Terjadi kesalahan, coba lagi nanti.';
final errorMessage = e.response?.data['message'] ?? 'Kesalahan jaringan';
log("đź’Ą Dio error: ${e.message}");
log("đź’Ą Dio response: ${e.response?.data}");
return Left(errorMessage);
@ -255,8 +254,7 @@ class OrderRemoteDatasource {
return const Left('Gagal membuat pembayaran');
}
} on DioException catch (e) {
final errorMessage =
e.response?.data['message'] ?? 'Terjadi kesalahan, coba lagi nanti.';
final errorMessage = e.response?.data['message'] ?? 'Kesalahan jaringan';
log("đź’Ą Dio error: ${e.message}");
log("đź’Ą Dio response: ${e.response?.data}");
return Left(errorMessage);
@ -386,8 +384,7 @@ class OrderRemoteDatasource {
return const Left('Gagal membuat pesanan');
}
} on DioException catch (e) {
final errorMessage =
e.response?.data['message'] ?? 'Terjadi kesalahan, coba lagi nanti.';
final errorMessage = e.response?.data['message'] ?? 'Kesalahan jaringan';
log("đź’Ą Dio error: ${e.message}");
log("đź’Ą Dio response: ${e.response?.data}");
return Left(errorMessage);
@ -427,8 +424,7 @@ class OrderRemoteDatasource {
return const Left('Gagal menambahkan pesanan pesanan');
}
} on DioException catch (e) {
final errorMessage =
e.response?.data['message'] ?? 'Terjadi kesalahan, coba lagi nanti.';
final errorMessage = e.response?.data['message'] ?? 'Kesalahan jaringan';
log("đź’Ą Dio error: ${e.message}");
log("đź’Ą Dio response: ${e.response?.data}");
return Left(errorMessage);
@ -480,8 +476,7 @@ class OrderRemoteDatasource {
return const Left('Gagal refund');
}
} on DioException catch (e) {
final errorMessage =
e.response?.data['message'] ?? 'Terjadi kesalahan, coba lagi nanti.';
final errorMessage = e.response?.data['message'] ?? 'Kesalahan jaringan';
log("đź’Ą Dio error: ${e.message}");
log("đź’Ą Dio response: ${e.response?.data}");
return Left(errorMessage);
@ -529,8 +524,7 @@ class OrderRemoteDatasource {
return const Left('Gagal refund');
}
} on DioException catch (e) {
final errorMessage =
e.response?.data['message'] ?? 'Terjadi kesalahan, coba lagi nanti.';
final errorMessage = e.response?.data['message'] ?? 'Kesalahan jaringan';
log("đź’Ą Dio error: ${e.message}");
log("đź’Ą Dio response: ${e.response?.data}");
return Left(errorMessage);

View File

@ -69,16 +69,6 @@ class _OutletDialogState extends State<OutletDialog> {
),
),
SpaceHeight(24),
BlocListener<UserUpdateOutletBloc, UserUpdateOutletState>(
listener: (context, state) {
state.maybeWhen(
orElse: () {},
success: () {
context.pop();
},
);
},
child:
BlocBuilder<UserUpdateOutletBloc, UserUpdateOutletState>(
builder: (context, state) {
return state.maybeWhen(
@ -98,7 +88,6 @@ class _OutletDialogState extends State<OutletDialog> {
);
},
),
),
],
),
);

View File

@ -51,7 +51,7 @@ class VariantDialog extends StatelessWidget {
Text(
(variant.priceModifier ?? 0).currencyFormatRpV2,
style: TextStyle(
color: AppColors.black,
color: AppColors.grey,
),
),
],

View File

@ -961,23 +961,6 @@ class _ConfirmPaymentPageState extends State<ConfirmPaymentPage> {
) =>
products,
);
int tax = state.maybeWhen(
orElse: () => 0,
loaded: (
products,
discountModel,
discount,
discountAmount,
tax,
serviceCharge,
totalQuantity,
totalPrice,
draftName,
orderType,
deliveryType,
) =>
tax,
);
return Container(
padding: EdgeInsets.all(16),
@ -1035,11 +1018,6 @@ class _ConfirmPaymentPageState extends State<ConfirmPaymentPage> {
.pushReplacement(SuccessOrderPage(
productQuantity: items,
order: data,
paymentMethod:
selectedPaymentMethod?.name ?? "",
nominalBayar: totalPriceController
.text.toIntegerFromText,
taxPercentage: tax,
));
},
error: (message) => AppFlushbar.showError(

View File

@ -127,6 +127,7 @@ class _HomePageState extends State<HomePage> {
orElse: () {},
loading: () {},
success: () {
context.pop();
Future.delayed(Duration(milliseconds: 300), () {
AppFlushbar.showSuccess(context, 'Outlet berhasil diubah');
context

View File

@ -23,7 +23,6 @@ class ProductCard extends StatelessWidget {
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
if (data.isActive == true) {
if (data.variants!.isEmpty) {
context.read<CheckoutBloc>().add(
CheckoutEvent.addItem(data, null),
@ -34,7 +33,6 @@ class ProductCard extends StatelessWidget {
builder: (context) => VariantDialog(product: data),
);
}
}
},
child: Container(
decoration: BoxDecoration(
@ -163,14 +161,6 @@ class ProductCard extends StatelessWidget {
);
},
),
if (data.isActive == false)
Container(
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
color: AppColors.grey.withOpacity(0.5),
),
),
],
),
),

View File

@ -11,18 +11,8 @@ import 'package:flutter/material.dart';
class SuccessOrderPage extends StatefulWidget {
final List<ProductQuantity> productQuantity;
final Order order;
final String paymentMethod;
final int nominalBayar;
final int taxPercentage;
const SuccessOrderPage({
super.key,
required this.order,
required this.productQuantity,
required this.paymentMethod,
required this.nominalBayar,
required this.taxPercentage,
});
const SuccessOrderPage(
{super.key, required this.order, required this.productQuantity});
@override
State<SuccessOrderPage> createState() => _SuccessOrderPageState();
@ -1001,15 +991,6 @@ class _SuccessOrderPageState extends State<SuccessOrderPage>
child: InkWell(
borderRadius: BorderRadius.circular(16),
onTap: () async {
onPrintRecipt(
context,
order: widget.order,
paymentMethod: widget.paymentMethod,
nominalBayar: widget.nominalBayar,
kembalian: widget.nominalBayar -
(widget.order.totalAmount ?? 0),
taxPercentage: widget.taxPercentage,
);
onPrint(
context,
productQuantity: widget.productQuantity,