Implement ReceiptActivity dengan printer

This commit is contained in:
riz081 2025-06-30 21:43:06 +07:00
parent a52f56e154
commit b2442ada48

View File

@ -1,9 +1,12 @@
package com.example.bdkipoc;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
@ -13,7 +16,13 @@ import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.cardview.widget.CardView;
import com.sunmi.peripheral.printer.InnerResultCallback;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
@ -29,32 +38,6 @@ import java.util.Map;
import com.example.bdkipoc.cetakulang.ReprintActivity;
public class ReceiptActivity extends AppCompatActivity {
// Views
private LinearLayout backNavigation;
private ImageView backArrow;
private TextView toolbarTitle;
// Receipt details
private TextView merchantName;
private TextView merchantLocation;
private TextView midText;
private TextView tidText;
private TextView transactionNumber;
private TextView transactionDate;
private TextView paymentMethod;
private TextView cardType;
private TextView transactionTotal;
private TextView taxPercentage;
private TextView serviceFee;
private TextView finalTotal;
// Action buttons
private LinearLayout printButton;
private LinearLayout emailButton;
private Button finishButton;
// ENHANCED: Mapping dari technical issuer ke display name
private static final Map<String, String> ISSUER_DISPLAY_MAP = new HashMap<String, String>() {{
put("airpay shopee", "ShopeePay");
put("shopeepay", "ShopeePay");
@ -76,6 +59,61 @@ public class ReceiptActivity extends AppCompatActivity {
put("qris", "QRIS");
}};
// Views
private LinearLayout backNavigation;
private ImageView backArrow;
private TextView toolbarTitle;
private CardView receiptCard;
// Receipt details
private TextView merchantName;
private TextView merchantLocation;
private TextView midText;
private TextView tidText;
private TextView transactionNumber;
private TextView transactionDate;
private TextView paymentMethod;
private TextView cardType;
private TextView transactionTotal;
private TextView taxPercentage;
private TextView serviceFee;
private TextView finalTotal;
// Action buttons
private LinearLayout printButton;
private LinearLayout emailButton;
private Button finishButton;
// Printer callback
private final InnerResultCallback printCallback = new InnerResultCallback() {
@Override
public void onRunResult(boolean isSuccess) throws RemoteException {
runOnUiThread(() -> {
if (isSuccess) {
showToast("Struk berhasil dicetak");
} else {
showToast("Gagal mencetak struk");
}
});
}
@Override
public void onReturnString(String result) throws RemoteException {
Log.d("ReceiptActivity", "Print result: " + result);
}
@Override
public void onRaiseException(int code, String msg) throws RemoteException {
runOnUiThread(() -> showToast("Printer error: " + msg));
Log.e("ReceiptActivity", "Printer exception: " + code + " - " + msg);
}
@Override
public void onPrintResult(int code, String msg) throws RemoteException {
Log.d("ReceiptActivity", "Print result code: " + code + ", msg: " + msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -90,26 +128,15 @@ public class ReceiptActivity extends AppCompatActivity {
loadTransactionData();
}
private void setStatusBarColor() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.parseColor("#E31937")); // Red color
// Make status bar icons white (for dark red background)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
View decorView = window.getDecorView();
decorView.setSystemUiVisibility(0); // Clear light status bar flag
}
}
}
private void initializeViews() {
// Navigation
backNavigation = findViewById(R.id.back_navigation);
backArrow = findViewById(R.id.backArrow);
toolbarTitle = findViewById(R.id.toolbarTitle);
// Receipt card view that will be printed
receiptCard = findViewById(R.id.receipt_card);
// Receipt details
merchantName = findViewById(R.id.merchant_name);
merchantLocation = findViewById(R.id.merchant_location);
@ -130,6 +157,129 @@ public class ReceiptActivity extends AppCompatActivity {
finishButton = findViewById(R.id.finish_button);
}
private void handlePrintReceipt() {
try {
// Check if printer service is available
if (MyApplication.app.sunmiPrinterService == null) {
showToast("Printer tidak tersedia");
return;
}
// Get all the data from the views
String merchantNameText = merchantName.getText().toString();
String merchantLocationText = merchantLocation.getText().toString();
String midTextValue = midText.getText().toString();
String tidTextValue = tidText.getText().toString();
String transactionNumberText = transactionNumber.getText().toString();
String transactionDateText = transactionDate.getText().toString();
String paymentMethodText = paymentMethod.getText().toString();
String cardTypeText = cardType.getText().toString();
String transactionTotalText = transactionTotal.getText().toString();
String taxPercentageText = taxPercentage.getText().toString();
String serviceFeeText = serviceFee.getText().toString();
String finalTotalText = finalTotal.getText().toString();
showToast("Mencetak struk...");
try {
// Start printing
MyApplication.app.sunmiPrinterService.enterPrinterBuffer(true);
// Set alignment to center
MyApplication.app.sunmiPrinterService.setAlignment(1, null);
// Print header
MyApplication.app.sunmiPrinterService.printText("# Payvora PRO\n\n", null);
// Set alignment to left
MyApplication.app.sunmiPrinterService.setAlignment(0, null);
// Print merchant info
MyApplication.app.sunmiPrinterService.printText(merchantNameText + "\n", null);
MyApplication.app.sunmiPrinterService.printText(merchantLocationText + "\n\n", null);
// Print MID/TID
MyApplication.app.sunmiPrinterService.printText(midTextValue + " | " + tidTextValue + "\n\n", null);
// Print transaction details
MyApplication.app.sunmiPrinterService.printText("Nomor transaksi " + transactionNumberText + "\n", null);
MyApplication.app.sunmiPrinterService.printText("Tanggal transaksi " + transactionDateText + "\n", null);
MyApplication.app.sunmiPrinterService.printText("Metode pembayaran " + paymentMethodText + "\n", null);
MyApplication.app.sunmiPrinterService.printText("Jenis Kartu " + cardTypeText + "\n\n", null);
// Print amounts
MyApplication.app.sunmiPrinterService.printText("Total transaksi " + transactionTotalText + "\n", null);
MyApplication.app.sunmiPrinterService.printText("Pajak (%) " + taxPercentageText + "\n", null);
MyApplication.app.sunmiPrinterService.printText("Biaya Layanan " + serviceFeeText + "\n\n", null);
// Print total in bold
MyApplication.app.sunmiPrinterService.printText("**TOTAL** **" + finalTotalText + "**\n", null);
// Add some line feeds
MyApplication.app.sunmiPrinterService.lineWrap(4, null);
// Exit buffer mode
MyApplication.app.sunmiPrinterService.exitPrinterBuffer(true);
} catch (RemoteException e) {
e.printStackTrace();
showToast("Error printer: " + e.getMessage());
}
} catch (Exception e) {
Log.e("ReceiptActivity", "Print error", e);
showToast("Error saat mencetak: " + e.getMessage());
}
}
private void setStatusBarColor() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.parseColor("#E31937")); // Red color
// Make status bar icons white (for dark red background)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
View decorView = window.getDecorView();
decorView.setSystemUiVisibility(0); // Clear light status bar flag
}
}
}
/** Create Bitmap from View */
private Bitmap createBitmapFromView(View view) {
try {
// Enable drawing cache
view.setDrawingCacheEnabled(true);
view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
// Measure and layout the view to ensure it has correct dimensions
view.measure(
View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
// Create bitmap
Bitmap bitmap = Bitmap.createBitmap(
view.getWidth(),
view.getHeight(),
Bitmap.Config.ARGB_8888
);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
} catch (Exception e) {
Log.e("ReceiptActivity", "Error creating bitmap", e);
return null;
} finally {
view.setDrawingCacheEnabled(false);
}
}
private void setupClickListeners() {
// Back navigation - Goes back to previous activity
backNavigation.setOnClickListener(v -> handleBackNavigation());
@ -279,20 +429,17 @@ public class ReceiptActivity extends AppCompatActivity {
return getCurrentDateTime();
}
/**
* Format date specifically for EMV transactions
*/
private String formatDateForEmvTransaction(String dateString) {
try {
// EMV transactions might use different date formats
String[] inputFormats = {
"dd MMMM yyyy HH:mm",
"yyyy-MM-dd HH:mm:ss",
"yyyy-MM-dd'T'HH:mm:ss'Z'",
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
"dd/MM/yyyy HH:mm"
};
SimpleDateFormat outputFormat = new SimpleDateFormat("dd MMMM yyyy HH:mm", new Locale("id", "ID"));
SimpleDateFormat outputFormat = new SimpleDateFormat("dd/MM/yy HH:mm:ss", new Locale("id", "ID"));
for (String format : inputFormats) {
try {
@ -319,11 +466,16 @@ public class ReceiptActivity extends AppCompatActivity {
private String formatDateFromCreatedAt(String createdAt) {
try {
// Input format from database: "yyyy-MM-dd HH:mm:ss"
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
// Input format from database: "yyyy-MM-dd HH:mm:ss" atau "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
SimpleDateFormat inputFormat;
if (createdAt.contains("T")) {
inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
} else {
inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
}
// Output format for receipt: "dd/MM/yyyy HH:mm"
SimpleDateFormat outputFormat = new SimpleDateFormat("dd MMMM yyyy HH:mm", new Locale("id", "ID"));
// Output format for receipt: "dd/MM/yy HH:mm:ss"
SimpleDateFormat outputFormat = new SimpleDateFormat("dd/MM/yy HH:mm:ss", new Locale("id", "ID"));
Date date = inputFormat.parse(createdAt);
String formatted = outputFormat.format(date);
@ -333,7 +485,7 @@ public class ReceiptActivity extends AppCompatActivity {
} catch (Exception e) {
Log.e("ReceiptActivity", "Error formatting date: " + createdAt, e);
// Fallback: try alternative formats or return as-is
// Fallback: return original string if parsing fails
return createdAt;
}
}
@ -1224,12 +1376,6 @@ public class ReceiptActivity extends AppCompatActivity {
return sdf.format(new Date());
}
private void handlePrintReceipt() {
// Handle print receipt action
// In real app, this would integrate with printer
showToast("Mencetak struk...");
}
private void handleEmailReceipt() {
// Handle email receipt action
// In real app, this would open email intent