Implement ReceiptActivity dengan printer
This commit is contained in:
parent
a52f56e154
commit
b2442ada48
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user