Implement ReceiptActivity dengan printer
This commit is contained in:
parent
a52f56e154
commit
b2442ada48
@ -1,9 +1,12 @@
|
|||||||
package com.example.bdkipoc;
|
package com.example.bdkipoc;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.RemoteException;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -13,7 +16,13 @@ import android.widget.Button;
|
|||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.cardview.widget.CardView;
|
||||||
|
|
||||||
|
import com.sunmi.peripheral.printer.InnerResultCallback;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -29,32 +38,6 @@ import java.util.Map;
|
|||||||
import com.example.bdkipoc.cetakulang.ReprintActivity;
|
import com.example.bdkipoc.cetakulang.ReprintActivity;
|
||||||
|
|
||||||
public class ReceiptActivity extends AppCompatActivity {
|
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>() {{
|
private static final Map<String, String> ISSUER_DISPLAY_MAP = new HashMap<String, String>() {{
|
||||||
put("airpay shopee", "ShopeePay");
|
put("airpay shopee", "ShopeePay");
|
||||||
put("shopeepay", "ShopeePay");
|
put("shopeepay", "ShopeePay");
|
||||||
@ -76,6 +59,61 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
put("qris", "QRIS");
|
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
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@ -90,26 +128,15 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
loadTransactionData();
|
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() {
|
private void initializeViews() {
|
||||||
// Navigation
|
// Navigation
|
||||||
backNavigation = findViewById(R.id.back_navigation);
|
backNavigation = findViewById(R.id.back_navigation);
|
||||||
backArrow = findViewById(R.id.backArrow);
|
backArrow = findViewById(R.id.backArrow);
|
||||||
toolbarTitle = findViewById(R.id.toolbarTitle);
|
toolbarTitle = findViewById(R.id.toolbarTitle);
|
||||||
|
|
||||||
|
// Receipt card view that will be printed
|
||||||
|
receiptCard = findViewById(R.id.receipt_card);
|
||||||
|
|
||||||
// Receipt details
|
// Receipt details
|
||||||
merchantName = findViewById(R.id.merchant_name);
|
merchantName = findViewById(R.id.merchant_name);
|
||||||
merchantLocation = findViewById(R.id.merchant_location);
|
merchantLocation = findViewById(R.id.merchant_location);
|
||||||
@ -130,6 +157,129 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
finishButton = findViewById(R.id.finish_button);
|
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() {
|
private void setupClickListeners() {
|
||||||
// Back navigation - Goes back to previous activity
|
// Back navigation - Goes back to previous activity
|
||||||
backNavigation.setOnClickListener(v -> handleBackNavigation());
|
backNavigation.setOnClickListener(v -> handleBackNavigation());
|
||||||
@ -279,20 +429,17 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
return getCurrentDateTime();
|
return getCurrentDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Format date specifically for EMV transactions
|
|
||||||
*/
|
|
||||||
private String formatDateForEmvTransaction(String dateString) {
|
private String formatDateForEmvTransaction(String dateString) {
|
||||||
try {
|
try {
|
||||||
// EMV transactions might use different date formats
|
// EMV transactions might use different date formats
|
||||||
String[] inputFormats = {
|
String[] inputFormats = {
|
||||||
"dd MMMM yyyy HH:mm",
|
"dd MMMM yyyy HH:mm",
|
||||||
"yyyy-MM-dd HH:mm:ss",
|
"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"
|
"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) {
|
for (String format : inputFormats) {
|
||||||
try {
|
try {
|
||||||
@ -319,11 +466,16 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
private String formatDateFromCreatedAt(String createdAt) {
|
private String formatDateFromCreatedAt(String createdAt) {
|
||||||
try {
|
try {
|
||||||
// Input format from database: "yyyy-MM-dd HH:mm:ss"
|
// Input format from database: "yyyy-MM-dd HH:mm:ss" atau "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
|
||||||
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
|
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"
|
// Output format for receipt: "dd/MM/yy HH:mm:ss"
|
||||||
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"));
|
||||||
|
|
||||||
Date date = inputFormat.parse(createdAt);
|
Date date = inputFormat.parse(createdAt);
|
||||||
String formatted = outputFormat.format(date);
|
String formatted = outputFormat.format(date);
|
||||||
@ -333,7 +485,7 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("ReceiptActivity", "Error formatting date: " + createdAt, 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;
|
return createdAt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1224,12 +1376,6 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
return sdf.format(new Date());
|
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() {
|
private void handleEmailReceipt() {
|
||||||
// Handle email receipt action
|
// Handle email receipt action
|
||||||
// In real app, this would open email intent
|
// In real app, this would open email intent
|
||||||
|
Loading…
x
Reference in New Issue
Block a user