manual edit cleaning and fix AI code

master
a2nr 2025-09-07 22:29:09 +07:00
parent b88c301d7d
commit b3cb5e3e05
5 changed files with 115 additions and 114 deletions

View File

@ -13,19 +13,16 @@ class EscPosPrintService {
static Future<List<int>> generateEscPosBytes({ static Future<List<int>> generateEscPosBytes({
required List<ReceiptItem> items, required List<ReceiptItem> items,
required DateTime transactionDate, required DateTime transactionDate,
required String cashierId,
required String transactionId,
}) async { }) async {
print('Memulai generateEscPosBytes...'); print('Memulai generateEscPosBytes...');
print('Jumlah item: ${items.length}'); print('Jumlah item: ${items.length}');
print('Tanggal transaksi: $transactionDate'); print('Tanggal transaksi: $transactionDate');
print('ID kasir: $cashierId');
print('ID transaksi: $transactionId');
// Load store info from shared preferences // Load store info from shared preferences
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
final storeName = prefs.getString('store_name') ?? 'TOKO SEMBAKO MURAH'; final storeName = prefs.getString('store_name') ?? 'TOKO SEMBAKO MURAH';
final storeAddress = prefs.getString('store_address') ?? 'Jl. Merdeka No. 123'; final storeAddress =
prefs.getString('store_address') ?? 'Jl. Merdeka No. 123';
final adminName = prefs.getString('admin_name') ?? 'Budi Santoso'; final adminName = prefs.getString('admin_name') ?? 'Budi Santoso';
final adminPhone = prefs.getString('admin_phone') ?? '08123456789'; final adminPhone = prefs.getString('admin_phone') ?? '08123456789';
@ -97,18 +94,6 @@ class EscPosPrintService {
bytes += generator.feed(1); bytes += generator.feed(1);
// Garis pemisah
bytes += generator.text('================================',
styles: PosStyles(align: PosAlign.center));
// Informasi transaksi
bytes += generator.text('Kasir: $cashierId',
styles: PosStyles(bold: true));
bytes += generator.text('ID Transaksi: $transactionId',
styles: PosStyles());
bytes += generator.feed(1);
// Garis pemisah // Garis pemisah
bytes += generator.text('================================', bytes += generator.text('================================',
styles: PosStyles(align: PosAlign.center)); styles: PosStyles(align: PosAlign.center));
@ -132,7 +117,8 @@ class EscPosPrintService {
for (int i = 0; i < items.length; i++) { for (int i = 0; i < items.length; i++) {
try { try {
var item = items[i]; var item = items[i];
print('Item $i: ${item.description}, qty: ${item.quantity}, price: ${item.price}, total: ${item.total}'); print(
'Item $i: ${item.description}, qty: ${item.quantity}, price: ${item.price}, total: ${item.total}');
// Untuk item dengan detail kuantitas dan harga // Untuk item dengan detail kuantitas dan harga
bytes += generator.row([ bytes += generator.row([
@ -147,7 +133,10 @@ class EscPosPrintService {
PosColumn( PosColumn(
text: '${item.quantity} x ${formatRupiah(item.price)}', text: '${item.quantity} x ${formatRupiah(item.price)}',
width: 7, width: 7,
styles: PosStyles(align: PosAlign.left, height: PosTextSize.size1, width: PosTextSize.size1), styles: PosStyles(
align: PosAlign.left,
height: PosTextSize.size1,
width: PosTextSize.size1),
), ),
PosColumn( PosColumn(
text: formatRupiah(item.total), text: formatRupiah(item.total),
@ -203,12 +192,14 @@ class EscPosPrintService {
'Harap periksa kembali struk belanja Anda sebelum meninggalkan toko.'; 'Harap periksa kembali struk belanja Anda sebelum meninggalkan toko.';
} catch (e) { } catch (e) {
print('Error saat memuat disclaimer: $e'); print('Error saat memuat disclaimer: $e');
customDisclaimer = 'Barang yang sudah dibeli tidak dapat dikembalikan/ditukar.'; customDisclaimer =
'Barang yang sudah dibeli tidak dapat dikembalikan/ditukar.';
} }
String customThankYou; String customThankYou;
try { try {
customThankYou = prefs.getString('thank_you_text') ?? '*** TERIMA KASIH ***'; customThankYou =
prefs.getString('thank_you_text') ?? '*** TERIMA KASIH ***';
} catch (e) { } catch (e) {
print('Error saat memuat thank you text: $e'); print('Error saat memuat thank you text: $e');
customThankYou = '*** TERIMA KASIH ***'; customThankYou = '*** TERIMA KASIH ***';
@ -248,8 +239,8 @@ class EscPosPrintService {
} }
for (final line in wrappedDisclaimer) { for (final line in wrappedDisclaimer) {
bytes += generator.text(line, bytes +=
styles: PosStyles(align: PosAlign.center)); generator.text(line, styles: PosStyles(align: PosAlign.center));
} }
} catch (e) { } catch (e) {
print('Error saat memproses disclaimer: $e'); print('Error saat memproses disclaimer: $e');
@ -269,8 +260,8 @@ class EscPosPrintService {
bytes += generator.feed(1); bytes += generator.feed(1);
final pantunLines = customPantun.split('\n'); final pantunLines = customPantun.split('\n');
for (final line in pantunLines) { for (final line in pantunLines) {
bytes += generator.text(line, bytes +=
styles: PosStyles(align: PosAlign.center)); generator.text(line, styles: PosStyles(align: PosAlign.center));
} }
} catch (e) { } catch (e) {
print('Error saat menambahkan pantun: $e'); print('Error saat menambahkan pantun: $e');
@ -299,30 +290,21 @@ class EscPosPrintService {
required BuildContext context, required BuildContext context,
required dynamic bluetoothService, // Kita akan sesuaikan tipe ini nanti required dynamic bluetoothService, // Kita akan sesuaikan tipe ini nanti
}) async { }) async {
// Definisikan cashierId dan transactionId di sini karena tidak berubah
final String cashierId = 'KSR001';
final String transactionId = 'TXN202508200001';
print('=== FUNGSI printToThermalPrinter DIPANGGIL ==='); print('=== FUNGSI printToThermalPrinter DIPANGGIL ===');
print('Memulai proses pencetakan struk...'); print('Memulai proses pencetakan struk...');
print('Jumlah item: ${items.length}'); print('Jumlah item: ${items.length}');
print('Tanggal transaksi: ${transactionDate}'); print('Tanggal transaksi: ${transactionDate}');
print('ID kasir: $cashierId');
print('ID transaksi: $transactionId');
try { try {
print('Menghasilkan byte array ESC/POS menggunakan flutter_esc_pos_utils...'); print(
'Menghasilkan byte array ESC/POS menggunakan flutter_esc_pos_utils...');
print('Jumlah item: ${items.length}'); print('Jumlah item: ${items.length}');
print('Tanggal transaksi: ${transactionDate}'); print('Tanggal transaksi: ${transactionDate}');
print('ID kasir: $cashierId');
print('ID transaksi: $transactionId');
// Generate struk dalam format byte array menggunakan EscPosPrintService // Generate struk dalam format byte array menggunakan EscPosPrintService
final bytes = await generateEscPosBytes( final bytes = await generateEscPosBytes(
items: items, items: items,
transactionDate: transactionDate, transactionDate: transactionDate,
cashierId: cashierId,
transactionId: transactionId,
); );
print('Byte array ESC/POS berhasil dihasilkan'); print('Byte array ESC/POS berhasil dihasilkan');
@ -330,7 +312,8 @@ class EscPosPrintService {
// Tampilkan byte array untuk debugging (dalam format hex) // Tampilkan byte array untuk debugging (dalam format hex)
print('Isi byte array (hex):'); print('Isi byte array (hex):');
if (bytes.length <= 1000) { // Batasi tampilan untuk mencegah output terlalu panjang if (bytes.length <= 1000) {
// Batasi tampilan untuk mencegah output terlalu panjang
print(bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join(' ')); print(bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join(' '));
} else { } else {
print('Terlalu banyak byte untuk ditampilkan (${bytes.length} bytes)'); print('Terlalu banyak byte untuk ditampilkan (${bytes.length} bytes)');
@ -355,7 +338,8 @@ class EscPosPrintService {
throw SocketException('Koneksi ke printer terputus: ${e.message}'); throw SocketException('Koneksi ke printer terputus: ${e.message}');
} on PlatformException catch (e) { } on PlatformException catch (e) {
print('Platform error saat mengirim perintah cetak ke printer: $e'); print('Platform error saat mengirim perintah cetak ke printer: $e');
throw PlatformException(code: e.code, message: 'Error printer: ${e.message}'); throw PlatformException(
code: e.code, message: 'Error printer: ${e.message}');
} catch (printError) { } catch (printError) {
print('Error saat mengirim perintah cetak ke printer: $printError'); print('Error saat mengirim perintah cetak ke printer: $printError');
throw Exception('Gagal mengirim perintah cetak: $printError'); throw Exception('Gagal mengirim perintah cetak: $printError');

View File

@ -15,8 +15,9 @@ class FireflyApiService {
required String accessToken, required String accessToken,
String? type, String? type,
}) async { }) async {
final uri = final uri = type != null
type != null ? Uri.parse('$baseUrl/api/v1/accounts?type=$type') : Uri.parse('$baseUrl/api/v1/accounts'); ? Uri.parse('$baseUrl/api/v1/accounts?type=$type')
: Uri.parse('$baseUrl/api/v1/accounts');
final response = await http.get( final response = await http.get(
uri, uri,
@ -29,7 +30,8 @@ class FireflyApiService {
if (response.statusCode == 200) { if (response.statusCode == 200) {
final dynamic responseBody = json.decode(response.body); final dynamic responseBody = json.decode(response.body);
if (responseBody is Map<String, dynamic> && responseBody.containsKey('data')) { if (responseBody is Map<String, dynamic> &&
responseBody.containsKey('data')) {
final List accountsJson = responseBody['data'] as List; final List accountsJson = responseBody['data'] as List;
final List<FireflyAccount> accounts = accountsJson final List<FireflyAccount> accounts = accountsJson
@ -94,7 +96,6 @@ class FireflyApiService {
if (responseBody is Map<String, dynamic> && if (responseBody is Map<String, dynamic> &&
responseBody.containsKey('data')) { responseBody.containsKey('data')) {
final dynamic data = responseBody['data']; final dynamic data = responseBody['data'];
// Handle case where data is a single object with an 'id' field // Handle case where data is a single object with an 'id' field
@ -173,7 +174,7 @@ class FireflyApiService {
/// Menguji koneksi ke Firefly III. /// Menguji koneksi ke Firefly III.
static Future<bool> testConnection({required String baseUrl}) async { static Future<bool> testConnection({required String baseUrl}) async {
try { try {
final response = await http.get(Uri.parse('$baseUrl/api/v1/about')); final response = await http.get(Uri.parse(baseUrl));
return response.statusCode == 200; return response.statusCode == 200;
} catch (e) { } catch (e) {
return false; return false;
@ -181,7 +182,8 @@ class FireflyApiService {
} }
/// Menguji autentikasi dengan token. /// Menguji autentikasi dengan token.
static Future<bool> testAuthentication({required String baseUrl, required String accessToken}) async { static Future<bool> testAuthentication(
{required String baseUrl, required String accessToken}) async {
try { try {
final response = await http.get( final response = await http.get(
Uri.parse('$baseUrl/api/v1/about/user'), Uri.parse('$baseUrl/api/v1/about/user'),
@ -196,3 +198,4 @@ class FireflyApiService {
} }
} }
} }

View File

@ -37,7 +37,8 @@ class PrintService {
// Detail tanggal dan ID transaksi // Detail tanggal dan ID transaksi
list.add(LineText( list.add(LineText(
type: LineText.TYPE_TEXT, type: LineText.TYPE_TEXT,
content: 'Tanggal: ${DateFormat('dd/MM/yyyy HH:mm').format(transaction.timestamp)}', content:
'Tanggal: ${DateFormat('dd/MM/yyyy HH:mm').format(transaction.timestamp)}',
align: LineText.ALIGN_LEFT)); align: LineText.ALIGN_LEFT));
list.add(LineText( list.add(LineText(
@ -62,7 +63,8 @@ class PrintService {
final itemTotal = item.price * item.quantity; final itemTotal = item.price * item.quantity;
list.add(LineText( list.add(LineText(
type: LineText.TYPE_TEXT, type: LineText.TYPE_TEXT,
content: 'Rp ${CurrencyFormat.formatRupiahWithoutSymbol(itemTotal)}', content:
'Rp ${CurrencyFormat.formatRupiahWithoutSymbol(itemTotal)}',
align: LineText.ALIGN_RIGHT, align: LineText.ALIGN_RIGHT,
linefeed: 1)); linefeed: 1));
} }
@ -82,7 +84,8 @@ class PrintService {
list.add(LineText( list.add(LineText(
type: LineText.TYPE_TEXT, type: LineText.TYPE_TEXT,
content: 'Rp ${CurrencyFormat.formatRupiahWithoutSymbol(transaction.total)}', content:
'Rp ${CurrencyFormat.formatRupiahWithoutSymbol(transaction.total)}',
weight: 2, weight: 2,
align: LineText.ALIGN_RIGHT, align: LineText.ALIGN_RIGHT,
linefeed: 1)); linefeed: 1));
@ -139,3 +142,4 @@ class PrintService {
} }
} }
} }

View File

@ -28,9 +28,10 @@ class _ReceiptItemListState extends State<ReceiptItemList> {
return Column( return Column(
children: [ children: [
// Baris tabel keterangan // Baris tabel keterangan
Row( const Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
SizedBox(width: 5),
Expanded( Expanded(
flex: 4, flex: 4,
child: Text( child: Text(
@ -79,6 +80,7 @@ class _ReceiptItemListState extends State<ReceiptItemList> {
textAlign: TextAlign.right, textAlign: TextAlign.right,
), ),
), ),
SizedBox(width: 5),
], ],
), ),
// Garis pembatas // Garis pembatas
@ -124,3 +126,4 @@ class _ReceiptItemListState extends State<ReceiptItemList> {
); );
} }
} }

View File

@ -46,15 +46,13 @@ class ReceiptSpeedDial extends StatelessWidget {
: () { : () {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(
content: Text( content:
'Pilih akun sumber dan tujuan terlebih dahulu'), Text('Pilih akun sumber dan tujuan terlebih dahulu'),
duration: Duration(seconds: 2), duration: Duration(seconds: 2),
), ),
); );
}, },
backgroundColor: hasItems && backgroundColor: hasItems && hasSourceAccount && hasDestinationAccount
hasSourceAccount &&
hasDestinationAccount
? Colors.blue ? Colors.blue
: Colors.grey, : Colors.grey,
), ),
@ -72,7 +70,8 @@ class ReceiptSpeedDial extends StatelessWidget {
), ),
SpeedDialChild( SpeedDialChild(
child: bluetoothService.isPrinting child: bluetoothService.isPrinting
? const CircularProgressIndicator(color: Colors.white, strokeWidth: 2) ? const CircularProgressIndicator(
color: Colors.white, strokeWidth: 2)
: const Icon(Icons.receipt), : const Icon(Icons.receipt),
label: 'Cetak Struk', label: 'Cetak Struk',
onTap: bluetoothService.isPrinting onTap: bluetoothService.isPrinting
@ -91,43 +90,50 @@ class ReceiptSpeedDial extends StatelessWidget {
if (bluetoothService.connectedDevice != null) { if (bluetoothService.connectedDevice != null) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(
content: Text('Mencoba menyambungkan ke printer...')), content:
Text('Mencoba menyambungkan ke printer...')),
); );
try { try {
bool connectResult = await bluetoothService.connectToDevice(bluetoothService.connectedDevice!); bool connectResult =
await bluetoothService.connectToDevice(
bluetoothService.connectedDevice!);
if (!connectResult) { if (!connectResult) {
throw Exception('Gagal menyambungkan ke printer'); throw Exception('Gagal menyambungkan ke printer');
} }
// Tunggu sebentar untuk memastikan koneksi stabil // Tunggu sebentar untuk memastikan koneksi stabil
await Future.delayed(const Duration(milliseconds: 500)); await Future.delayed(
const Duration(milliseconds: 500));
// Periksa koneksi lagi // Periksa koneksi lagi
final isConnectedAfterConnect = await onCheckConnection(); final isConnectedAfterConnect =
await onCheckConnection();
if (isConnectedAfterConnect) { if (isConnectedAfterConnect) {
await onPrint(); await onPrint();
} else { } else {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(
content: Text('Gagal menyambungkan ke printer')), content:
Text('Gagal menyambungkan ke printer')),
); );
} }
} catch (e) { } catch (e) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text('Gagal menyambungkan ke printer: $e')), content:
Text('Gagal menyambungkan ke printer: $e')),
); );
} }
} else { } else {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(
content: Text('Hubungkan printer terlebih dahulu')), content:
Text('Hubungkan printer terlebih dahulu')),
); );
} }
} }
} catch (e) { } catch (e) {
// Tangani error secara umum // Tangani error secara umum
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(content: Text('Terjadi kesalahan: $e')),
content: Text('Terjadi kesalahan: $e')),
); );
} finally { } finally {
// Pastikan printing status selalu diakhiri // Pastikan printing status selalu diakhiri
@ -140,3 +146,4 @@ class ReceiptSpeedDial extends StatelessWidget {
); );
} }
} }