import 'package:cashumit/models/receipt_item.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:intl/intl.dart'; /// Class untuk menghasilkan struk dalam format teks untuk printer thermal class StrukTextGenerator { /// Fungsi untuk mengatur teks ke tengah static String centerText(String text, int width, [String padChar = ' ']) { if (text.length >= width) return text; int padLeft = (width - text.length) ~/ 2; int padRight = width - text.length - padLeft; return padChar * padLeft + text + padChar * padRight; } /// Fungsi untuk membuat garis pemisah static String createSeparator(int width, String char) { return char * width; } /// Menghasilkan struk dalam format teks berdasarkan data transaksi static Future generateStrukText({ required List items, required DateTime transactionDate, required String cashierId, required String transactionId, }) async { print('Memulai generateStrukText...'); print('Jumlah item: ${items.length}'); print('Tanggal transaksi: $transactionDate'); print('ID kasir: $cashierId'); print('ID transaksi: $transactionId'); // Load store info from shared preferences final prefs = await SharedPreferences.getInstance(); final storeName = prefs.getString('store_name') ?? 'TOKO SEMBAKO MURAH'; final storeAddress = prefs.getString('store_address') ?? 'Jl. Merdeka No. 123'; final adminName = prefs.getString('admin_name') ?? 'Budi Santoso'; final adminPhone = prefs.getString('admin_phone') ?? '08123456789'; print('Nama toko: $storeName'); print('Alamat toko: $storeAddress'); print('Nama admin: $adminName'); print('Telepon admin: $adminPhone'); // Format tanggal final dateFormatter = DateFormat('dd/MM/yyyy'); final formattedDate = dateFormatter.format(transactionDate); print('Tanggal yang diformat: $formattedDate'); // Format angka ke rupiah String formatRupiah(double amount) { final formatter = NumberFormat("#,##0", "id_ID"); return "Rp ${formatter.format(amount)}"; } // Bangun struk dalam format teks final buffer = StringBuffer(); // Header toko - menggunakan lebar 32 karakter untuk kompatibilitas printer termal buffer.writeln(centerText(storeName, 32)); buffer.writeln(centerText(storeAddress, 32)); buffer.writeln(centerText('Admin: $adminName', 32)); buffer.writeln(centerText('Telp: $adminPhone', 32)); buffer.writeln(centerText(' $formattedDate ', 32)); buffer.writeln(createSeparator(32, '=')); // Header tabel - disesuaikan lebar kolom untuk printer termal buffer.writeln('ITEM QTY HARGA TOTAL'); buffer.writeln(createSeparator(32, '-')); // Item list print('Memulai iterasi item...'); for (int i = 0; i < items.length; i++) { var item = items[i]; print('Item $i: ${item.description}, qty: ${item.quantity}, price: ${item.price}, total: ${item.total}'); // Nama item (potong jika terlalu panjang) - maks 12 karakter String itemName = item.description.length > 12 ? '${item.description.substring(0, 9)}...' : item.description.padRight(12); // Quantity (3 karakter) String qty = item.quantity.toString().padRight(3); // Harga (7 karakter) String price = formatRupiah(item.price).padLeft(7); // Total (7 karakter) String total = formatRupiah(item.total).padLeft(7); buffer.writeln('$itemName $qty $price $total'); } print('Selesai iterasi item'); // Garis pemisah sebelum total buffer.writeln(createSeparator(32, '-')); // Total final totalAmount = items.fold(0.0, (sum, item) => sum + item.total); print('Total amount: $totalAmount'); buffer.writeln('TOTAL: ${formatRupiah(totalAmount)}'.padLeft(32)); // Garis pemisah setelah total buffer.writeln(createSeparator(32, '=')); // Memuat teks kustom dari shared preferences final customDisclaimer = prefs.getString('store_disclaimer_text') ?? 'Barang yang sudah dibeli tidak dapat dikembalikan/ditukar. ' 'Harap periksa kembali struk belanja Anda sebelum meninggalkan toko.'; final customThankYou = prefs.getString('thank_you_text') ?? '*** TERIMA KASIH ***'; final customPantun = prefs.getString('pantun_text') ?? 'Belanja di toko kami, hemat dan nyaman,\n' 'Dengan penuh semangat, kami siap melayani,\n' 'Harapan kami, Anda selalu puas,\n' 'Sampai jumpa lagi, selamat tinggal.'; // Menambahkan disclaimer buffer.writeln(''); // Memecah disclaimer menjadi beberapa baris jika terlalu panjang final disclaimerLines = customDisclaimer.split(' '); final List wrappedDisclaimer = []; String currentLine = ''; for (final word in disclaimerLines) { if ((currentLine + word).length > 32) { wrappedDisclaimer.add(currentLine.trim()); currentLine = word + ' '; } else { currentLine += word + ' '; } } if (currentLine.trim().isNotEmpty) { wrappedDisclaimer.add(currentLine.trim()); } for (final line in wrappedDisclaimer) { buffer.writeln(centerText(line, 32)); } // Menambahkan ucapan terima kasih buffer.writeln(''); buffer.writeln(centerText(customThankYou, 32)); // Menambahkan pantun buffer.writeln(''); final pantunLines = customPantun.split('\n'); for (final line in pantunLines) { buffer.writeln(centerText(line, 32)); } // Spasi di akhir buffer.writeln(''); buffer.writeln(''); final result = buffer.toString(); print('Teks struk yang dihasilkan:'); print(result); return result; } }