From ccfd3a09eb396fc2ceafb96d167f1175008f15d4 Mon Sep 17 00:00:00 2001 From: riz081 Date: Mon, 11 Aug 2025 07:55:58 +0700 Subject: [PATCH] settlement --- app/src/main/AndroidManifest.xml | 5 + .../settlement/SettlementActivity.java | 16 +- .../settlement/SettlementDetailActivity.java | 438 ++++++++++++++++++ .../res/layout/activity_settlement_detail.xml | 395 ++++++++++++++++ .../res/layout/item_settlement_detail.xml | 87 ++++ 5 files changed, 939 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/example/bdkipoc/settlement/SettlementDetailActivity.java create mode 100644 app/src/main/res/layout/activity_settlement_detail.xml create mode 100644 app/src/main/res/layout/item_settlement_detail.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d1ad159..55ce4dc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -91,6 +91,11 @@ + + + settlementList; - private LinearLayout backNavigation; // Changed from ImageView btnBack + private LinearLayout backNavigation; + private Button btnContinue; @Override protected void onCreate(Bundle savedInstanceState) { @@ -126,7 +129,8 @@ public class SettlementActivity extends AppCompatActivity { tvTotalAmount = findViewById(R.id.tv_total_amount); tvTotalTransactions = findViewById(R.id.tv_total_transactions); recyclerView = findViewById(R.id.recycler_view); - backNavigation = findViewById(R.id.back_navigation); // Updated to use back_navigation from appbar + backNavigation = findViewById(R.id.back_navigation); + btnContinue = findViewById(R.id.btn_continue); settlementList = new ArrayList<>(); } @@ -145,6 +149,14 @@ public class SettlementActivity extends AppCompatActivity { finish(); } }); + + btnContinue.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(SettlementActivity.this, SettlementDetailActivity.class); + startActivity(intent); + } + }); } private void loadSampleData() { diff --git a/app/src/main/java/com/example/bdkipoc/settlement/SettlementDetailActivity.java b/app/src/main/java/com/example/bdkipoc/settlement/SettlementDetailActivity.java new file mode 100644 index 0000000..cfae3e7 --- /dev/null +++ b/app/src/main/java/com/example/bdkipoc/settlement/SettlementDetailActivity.java @@ -0,0 +1,438 @@ +package com.example.bdkipoc.settlement; + +import android.os.AsyncTask; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; +import android.content.Intent; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import com.example.bdkipoc.BuildConfig; +import com.example.bdkipoc.R; + +public class SettlementDetailActivity extends AppCompatActivity { + + private TextView tvStoreName, tvStoreLocation, tvMid, tvTid; + private TextView tvSettlementDate, tvSettlementTime; + private TextView tvTotalMasuk, tvTotalKeluar, tvBiayaAdmin, tvGrandTotal; + private RecyclerView recyclerView; + private SettlementDetailAdapter adapter; + private List settlementDetailList; + private LinearLayout backNavigation; + private Button btnSendSettlement; + + // Summary totals + private long totalMasuk = 0; + private long totalKeluar = 0; + private long biayaAdmin = 15000; // Default admin fee + private long grandTotal = 0; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_settlement_detail); + + initViews(); + setupRecyclerView(); + fetchApiData(); // Fetch from API instead of loading sample data + setupClickListeners(); + updateDateTime(); + } + + private void fetchApiData() { + // Get current date in yyyy-MM-dd format (same as SettlementActivity) + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); + String currentDate = sdf.format(new Date()); + + // Build API URL with current date and credentials from BuildConfig + String apiUrl = BuildConfig.BACKEND_BASE_URL + "/transactions/performa-chanel-pembayaran" + + "?from_date=" + currentDate + + "&to_date=" + currentDate + + "&location_id=0&merchant_id=0"; + + // Execute network call in background thread + new ApiTask().execute(apiUrl); + } + + private void processApiData(JSONArray dataArray) { + try { + settlementDetailList.clear(); + + long totalAmount = 0; + int totalTransactions = 0; + + // Process each channel from API data + for (int i = 0; i < dataArray.length(); i++) { + JSONObject item = dataArray.getJSONObject(i); + + String channelCode = item.getString("channel_code"); + int transactions = item.getInt("total_transactions"); + long maxAmount = item.getLong("max_transastions"); + + // Use channel code with formatting + String displayName = formatChannelName(channelCode); + + settlementDetailList.add(new SettlementDetailItem( + displayName, + maxAmount, + transactions + )); + + totalAmount += maxAmount; + totalTransactions += transactions; + } + + // Calculate totals based on API data + calculateTotalsFromApiData(totalAmount, totalTransactions); + + // Update UI on main thread + runOnUiThread(new Runnable() { + @Override + public void run() { + adapter.notifyDataSetChanged(); + updateSummary(); + } + }); + + } catch (JSONException e) { + e.printStackTrace(); + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(SettlementDetailActivity.this, "Error parsing data", Toast.LENGTH_SHORT).show(); + loadSampleData(); // Fallback to sample data + } + }); + } + } + + private void calculateTotalsFromApiData(long totalAmount, int totalTransactions) { + // Calculate totals based on actual API data + // You can adjust this logic based on your business requirements + + // For example, split transactions into incoming/outgoing based on transaction type + // This is a simplified calculation - adjust according to your actual data structure + totalKeluar = totalAmount; // All transactions as outgoing for now + totalMasuk = (long) (totalAmount * 0.3); // 30% as incoming (adjust as needed) + biayaAdmin = 15000; // Fixed admin fee + + // Calculate grand total + grandTotal = totalKeluar - totalMasuk - biayaAdmin; + if (grandTotal < 0) { + grandTotal = totalAmount - biayaAdmin; // Fallback calculation + } + } + + private String formatChannelName(String channelCode) { + // Format channel code to be more readable (same as SettlementActivity) + switch (channelCode) { + case "GO-PAY": + return "GoPay"; + case "SHOPEEPAY": + return "ShopeePay"; + case "LINKAJA": + return "LinkAja"; + case "MASTERCARD": + return "Mastercard"; + case "VISA": + return "Visa"; + case "QRIS": + return "QRIS"; + case "DANA": + return "Dana"; + case "OVO": + return "OVO"; + case "DEBIT": + return "Kartu Debit"; + case "GPN": + return "GPN"; + case "OTHER": + return "Lainnya"; + case "CREDIT": + return "Kartu Kredit"; + case "TRANSFER": + return "Transfer"; + case "E_MONEY": + return "Uang Elektronik"; + case "CASH_DEPOSIT": + return "Setoran Tunai"; + case "BILL_PAYMENT": + return "Pembayaran Tagihan"; + case "CASH_WITHDRAWAL": + return "Penarikan Tunai"; + case "TOP_UP": + return "Top-up Saldo"; + case "REFUND": + return "Refund (void)"; + default: + // Capitalize first letter and make rest lowercase + return channelCode.substring(0, 1).toUpperCase() + + channelCode.substring(1).toLowerCase(); + } + } + + private void initViews() { + // Store info + tvStoreName = findViewById(R.id.tv_store_name); + tvStoreLocation = findViewById(R.id.tv_store_location); + tvMid = findViewById(R.id.tv_mid); + tvTid = findViewById(R.id.tv_tid); + + // Date and time + tvSettlementDate = findViewById(R.id.tv_settlement_date); + tvSettlementTime = findViewById(R.id.tv_settlement_time); + + // Summary totals + tvTotalMasuk = findViewById(R.id.tv_total_masuk); + tvTotalKeluar = findViewById(R.id.tv_total_keluar); + tvBiayaAdmin = findViewById(R.id.tv_biaya_admin); + tvGrandTotal = findViewById(R.id.tv_grand_total); + + // RecyclerView and navigation + recyclerView = findViewById(R.id.recycler_settlement_details); + backNavigation = findViewById(R.id.back_navigation); + btnSendSettlement = findViewById(R.id.btn_send_settlement); + + settlementDetailList = new ArrayList<>(); + } + + private void setupRecyclerView() { + adapter = new SettlementDetailAdapter(settlementDetailList); + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + recyclerView.setAdapter(adapter); + } + + private void loadSampleData() { + // Sample data as fallback (same structure as API data would provide) + settlementDetailList.clear(); + + settlementDetailList.add(new SettlementDetailItem("Kartu Kredit", 200000, 14)); + settlementDetailList.add(new SettlementDetailItem("Kartu Debit", 200000, 14)); + settlementDetailList.add(new SettlementDetailItem("QRIS", 200000, 14)); + settlementDetailList.add(new SettlementDetailItem("Transfer", 200000, 14)); + settlementDetailList.add(new SettlementDetailItem("Uang Elektronik", 200000, 14)); + settlementDetailList.add(new SettlementDetailItem("Setoran Tunai", 200000, 14)); + settlementDetailList.add(new SettlementDetailItem("Pembayaran Tagihan", 200000, 14)); + settlementDetailList.add(new SettlementDetailItem("Penarikan Tunai", 200000, 14)); + settlementDetailList.add(new SettlementDetailItem("Top-up Saldo", 200000, 14)); + settlementDetailList.add(new SettlementDetailItem("Refund (void)", 200000, 14)); + + // Calculate sample totals + totalMasuk = 1800000; + totalKeluar = 5800000; + biayaAdmin = 15000; + grandTotal = 3506500; + + adapter.notifyDataSetChanged(); + updateSummary(); + } + + private void updateSummary() { + tvTotalMasuk.setText("Rp " + formatCurrency(totalMasuk)); + tvTotalKeluar.setText("Rp " + formatCurrency(totalKeluar)); + tvBiayaAdmin.setText("Rp " + formatCurrency(biayaAdmin)); + tvGrandTotal.setText(formatCurrency(grandTotal)); + } + + private void updateDateTime() { + // Set current date and time + SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", new Locale("id", "ID")); + SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss", Locale.getDefault()); + + Date now = new Date(); + tvSettlementDate.setText(dateFormat.format(now)); + tvSettlementTime.setText(timeFormat.format(now)); + + // Set store info (these could come from SharedPreferences or API) + tvStoreName.setText("TOKO KLONTONG PAK EKO"); + tvStoreLocation.setText("Ciputat Baru, Tangsel"); + tvMid.setText("12345678901"); + tvTid.setText("12345678901"); + } + + private void setupClickListeners() { + backNavigation.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + btnSendSettlement.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + sendSettlement(); + } + }); + } + + private void sendSettlement() { + // Show loading or confirmation dialog + Toast.makeText(this, "Mengirim settlement...", Toast.LENGTH_SHORT).show(); + + // TODO: Implement actual settlement sending logic + // This could involve API call to send settlement data + + // For now, just show success message + Toast.makeText(this, "Settlement berhasil dikirim!", Toast.LENGTH_LONG).show(); + + // Optionally close the activity or navigate back + finish(); + } + + private String formatCurrency(long amount) { + NumberFormat formatter = NumberFormat.getNumberInstance(new Locale("id", "ID")); + return formatter.format(amount); + } + + // AsyncTask for API call (same as SettlementActivity) + private class ApiTask extends AsyncTask { + @Override + protected String doInBackground(String... urls) { + try { + URL url = new URL(urls[0]); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + + // Add authorization header if needed + // connection.setRequestProperty("Authorization", BuildConfig.MIDTRANS_SANDBOX_AUTH); + + int responseCode = connection.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + StringBuilder response = new StringBuilder(); + String line; + + while ((line = reader.readLine()) != null) { + response.append(line); + } + reader.close(); + return response.toString(); + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(String result) { + if (result != null) { + try { + JSONObject jsonResponse = new JSONObject(result); + if (jsonResponse.getInt("status") == 200) { + JSONArray dataArray = jsonResponse.getJSONArray("data"); + processApiData(dataArray); + } else { + Toast.makeText(SettlementDetailActivity.this, "API Error", Toast.LENGTH_SHORT).show(); + loadSampleData(); + } + } catch (JSONException e) { + e.printStackTrace(); + Toast.makeText(SettlementDetailActivity.this, "JSON Parse Error", Toast.LENGTH_SHORT).show(); + loadSampleData(); + } + } else { + Toast.makeText(SettlementDetailActivity.this, "Network Error", Toast.LENGTH_SHORT).show(); + loadSampleData(); + } + } + } +} + +// SettlementDetailItem class +class SettlementDetailItem { + private String paymentMethod; + private long totalNominal; + private int jumlahTransaksi; + + public SettlementDetailItem(String paymentMethod, long totalNominal, int jumlahTransaksi) { + this.paymentMethod = paymentMethod; + this.totalNominal = totalNominal; + this.jumlahTransaksi = jumlahTransaksi; + } + + // Getters + public String getPaymentMethod() { return paymentMethod; } + public long getTotalNominal() { return totalNominal; } + public int getJumlahTransaksi() { return jumlahTransaksi; } + + // Setters + public void setPaymentMethod(String paymentMethod) { this.paymentMethod = paymentMethod; } + public void setTotalNominal(long totalNominal) { this.totalNominal = totalNominal; } + public void setJumlahTransaksi(int jumlahTransaksi) { this.jumlahTransaksi = jumlahTransaksi; } +} + +// SettlementDetailAdapter class +class SettlementDetailAdapter extends RecyclerView.Adapter { + + private List settlementDetailList; + + public SettlementDetailAdapter(List settlementDetailList) { + this.settlementDetailList = settlementDetailList; + } + + @NonNull + @Override + public SettlementDetailViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_settlement_detail, parent, false); + return new SettlementDetailViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull SettlementDetailViewHolder holder, int position) { + SettlementDetailItem item = settlementDetailList.get(position); + + holder.tvPaymentMethod.setText(item.getPaymentMethod()); + holder.tvTotalNominal.setText(formatCurrency(item.getTotalNominal())); + holder.tvJumlahTransaksi.setText(String.valueOf(item.getJumlahTransaksi())); + } + + @Override + public int getItemCount() { + return settlementDetailList.size(); + } + + private String formatCurrency(long amount) { + NumberFormat formatter = NumberFormat.getNumberInstance(new Locale("id", "ID")); + return formatter.format(amount); + } + + static class SettlementDetailViewHolder extends RecyclerView.ViewHolder { + TextView tvPaymentMethod; + TextView tvTotalNominal; + TextView tvJumlahTransaksi; + + public SettlementDetailViewHolder(@NonNull View itemView) { + super(itemView); + tvPaymentMethod = itemView.findViewById(R.id.tv_payment_method); + tvTotalNominal = itemView.findViewById(R.id.tv_total_nominal); + tvJumlahTransaksi = itemView.findViewById(R.id.tv_jumlah_transaksi); + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_settlement_detail.xml b/app/src/main/res/layout/activity_settlement_detail.xml new file mode 100644 index 0000000..f6ada87 --- /dev/null +++ b/app/src/main/res/layout/activity_settlement_detail.xml @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +