sells update

This commit is contained in:
Gracia Hotmauli
2025-06-02 17:04:23 +07:00
parent 0d2edb7ea2
commit a3c3a9d499
6 changed files with 1061 additions and 368 deletions

View File

@ -5,14 +5,17 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.alya.ecommerce_serang.BuildConfig.BASE_URL
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.response.store.orders.OrdersItem
import com.alya.ecommerce_serang.ui.profile.mystore.sells.payment.DetailPaymentActivity
import com.alya.ecommerce_serang.ui.profile.mystore.sells.shipment.DetailShipmentActivity
import com.alya.ecommerce_serang.utils.viewmodel.SellsViewModel
import com.bumptech.glide.Glide
import com.google.android.material.button.MaterialButton
import com.google.gson.Gson
import java.text.SimpleDateFormat
@ -60,59 +63,72 @@ class SellsAdapter(
override fun getItemCount(): Int = sells.size
inner class SellsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val tvStoreName: TextView = itemView.findViewById(R.id.tvUserName)
private val rvOrderItems: RecyclerView = itemView.findViewById(R.id.rvSellsItems)
private val tvShowMore: TextView = itemView.findViewById(R.id.tvShowMores)
private val tvTotalAmount: TextView = itemView.findViewById(R.id.tvTotalAmounts)
private val tvItemCountLabel: TextView = itemView.findViewById(R.id.tv_count_total_items)
private val layoutOrders: View = itemView.findViewById(R.id.layout_orders)
private val layoutPayments: View = itemView.findViewById(R.id.layout_payments)
private val layoutShipments: View = itemView.findViewById(R.id.layout_shipments)
private var tvSellsTitle: TextView = itemView.findViewById(R.id.tv_payment_title)
private var tvSellsNumber: TextView = itemView.findViewById(R.id.tv_payment_number)
private var tvSellsDueDesc: TextView = itemView.findViewById(R.id.tv_payment_due_desc)
private var tvSellsDue: TextView = itemView.findViewById(R.id.tv_payment_due)
private var tvSellsLocation: TextView = itemView.findViewById(R.id.tv_payment_location)
private var tvSellsCustomer: TextView = itemView.findViewById(R.id.tv_payment_customer)
private var ivSellsProduct: ImageView = itemView.findViewById(R.id.iv_payment_product)
private var tvSellsProductName: TextView = itemView.findViewById(R.id.tv_payment_product_name)
private var tvSellsProductQty: TextView = itemView.findViewById(R.id.tv_payment_product_qty)
private var tvSellsProductPrice: TextView = itemView.findViewById(R.id.tv_payment_product_price)
private var tvSeeMore: TextView = itemView.findViewById(R.id.tv_see_more_payment)
private var tvSellsQty: TextView = itemView.findViewById(R.id.tv_payment_qty)
private var tvSellsPrice: TextView = itemView.findViewById(R.id.tv_payment_price)
private val btnConfirmPayment: Button = itemView.findViewById(R.id.btn_confirm_payment)
private val btnConfirmShipment: Button = itemView.findViewById(R.id.btn_confirm_shipment)
fun bind(order: OrdersItem) {
Log.d("SellsAdapter", "=== ViewHolder.bind() called ===")
Log.d("SellsAdapter", "Binding order: ${order.orderId} with status: ${order.status}")
// Show customer/buyer name (seller's perspective)
tvStoreName.text = order.username ?: "Unknown Customer"
Log.d("SellsAdapter", "Customer name set: ${order.username}")
val actualStatus = if (fragmentStatus == "all") order.status ?: "" else fragmentStatus
adjustDisplay(actualStatus, order)
// Set total amount
tvTotalAmount.text = "Rp${order.totalAmount}"
Log.d("SellsAdapter", "Total amount set: ${order.totalAmount}")
tvSellsNumber.text = "No. Pesanan: ${order.orderId}"
tvSellsLocation.text = order.subdistrict
tvSellsCustomer.text = order.username
// Set item count
val itemCount = order.orderItems?.size ?: 0
tvItemCountLabel.text = itemView.context.getString(R.string.item_count_prod, itemCount)
Log.d("SellsAdapter", "Item count set: $itemCount")
val product = order.orderItems?.firstOrNull()
tvSellsProductName.text = product?.productName
tvSellsProductQty.text = "x${product?.quantity}"
tvSellsProductPrice.text = formatPrice(product?.price.toString())
// Set up the order items RecyclerView
val productAdapter = SellsProductAdapter()
rvOrderItems.apply {
layoutManager = LinearLayoutManager(itemView.context)
adapter = productAdapter
val fullImageUrl = when (val img = product?.productImage) {
is String -> {
if (img.startsWith("/")) BASE_URL + img.substring(1) else img
}
else -> R.drawable.placeholder_image
}
Log.d("SellsAdapter", "Product RecyclerView configured")
// Load product image using Glide
Glide.with(itemView.context)
.load(fullImageUrl)
.placeholder(R.drawable.placeholder_image)
.error(R.drawable.placeholder_image)
.into(ivSellsProduct)
// Display only the first product and show "View more" for the rest
order.orderItems?.let { items ->
if (items.isNotEmpty()) {
productAdapter.submitList(items.take(1))
Log.d("SellsAdapter", "Product list submitted: ${items.size} items")
// Show or hide the "View more" text based on number of items
if (items.size > 1) {
val itemString = items.size - 1
tvShowMore.visibility = View.VISIBLE
tvShowMore.text = itemView.context.getString(R.string.show_more_product, itemString)
Log.d("SellsAdapter", "Show more visible: $itemString more items")
tvSeeMore.visibility = View.VISIBLE
tvSeeMore.text = itemView.context.getString(R.string.show_more_product, itemString)
} else {
tvShowMore.visibility = View.GONE
Log.d("SellsAdapter", "Show more hidden: only 1 item")
tvSeeMore.visibility = View.GONE
}
} else {
tvShowMore.visibility = View.GONE
tvSeeMore.visibility = View.GONE
Log.w("SellsAdapter", "Order has no items!")
}
} ?: run {
tvShowMore.visibility = View.GONE
tvSeeMore.visibility = View.GONE
Log.w("SellsAdapter", "Order items is null!")
}
@ -121,192 +137,169 @@ class SellsAdapter(
onOrderClickListener(order)
}
val actualStatus = if (fragmentStatus == "all") order.status ?: "" else fragmentStatus
Log.d("SellsAdapter", "Adjusting UI for status: '$actualStatus' (fragmentStatus: '$fragmentStatus')")
adjustButtonsAndText(actualStatus, order)
Log.d("SellsAdapter", "=== ViewHolder.bind() completed ===")
}
private fun adjustButtonsAndText(status: String, order: OrdersItem) {
Log.d("SellsAdapter", "Adjusting buttons for status: $status")
// Get references to buttons and status views
val btnLeft = itemView.findViewById<MaterialButton>(R.id.btn_left)
val btnRight = itemView.findViewById<MaterialButton>(R.id.btn_right)
val statusOrder = itemView.findViewById<TextView>(R.id.tvOrderStatus)
val deadlineLabel = itemView.findViewById<TextView>(R.id.tvDeadlineLabel)
val deadlineDate = itemView.findViewById<TextView>(R.id.tvDeadlineDate)
private fun adjustDisplay(status: String, order: OrdersItem) {
Log.d("SellsAdapter", "Adjusting display for status: $status")
// Reset visibility
btnLeft.visibility = View.GONE
btnRight.visibility = View.GONE
statusOrder.visibility = View.GONE
deadlineLabel.visibility = View.GONE
deadlineDate.visibility = View.GONE
layoutOrders.visibility = View.GONE
layoutPayments.visibility = View.VISIBLE
layoutShipments.visibility = View.GONE
when (status) {
"pending" -> {
statusOrder.apply {
visibility = View.VISIBLE
text = "Menunggu Tagihan"
}
deadlineLabel.apply {
visibility = View.VISIBLE
text = "Batas waktu konfirmasi:"
}
deadlineDate.apply {
visibility = View.VISIBLE
text = formatDate(order.createdAt ?: "")
}
btnLeft.apply {
visibility = View.VISIBLE
text = "Tolak Pesanan"
setOnClickListener {
// Handle reject order
viewModel.updateOrderStatus(order.orderId, "canceled")
viewModel.refreshOrders()
}
}
btnRight.apply {
visibility = View.VISIBLE
text = "Terima Pesanan"
setOnClickListener {
// Handle accept order
viewModel.updateOrderStatus(order.orderId, "unpaid")
viewModel.refreshOrders()
}
}
}
"unpaid" -> {
statusOrder.apply {
visibility = View.VISIBLE
text = "Konfirmasi Bayar"
}
deadlineLabel.apply {
visibility = View.VISIBLE
text = "Batas pembayaran:"
}
deadlineDate.apply {
visibility = View.VISIBLE
text = formatDatePay(order.updatedAt ?: "")
}
btnLeft.apply {
visibility = View.VISIBLE
text = "Batalkan"
setOnClickListener {
viewModel.updateOrderStatus(order.orderId, "canceled")
viewModel.refreshOrders()
"pending", "unpaid" -> {
layoutOrders.visibility = View.VISIBLE
layoutPayments.visibility = View.GONE
layoutShipments.visibility = View.GONE
tvSellsTitle = itemView.findViewById(R.id.tv_order_title)
tvSellsNumber = itemView.findViewById(R.id.tv_order_number)
tvSellsDue = itemView.findViewById(R.id.tv_order_due)
tvSellsCustomer = itemView.findViewById(R.id.tv_order_customer)
tvSellsProductName = itemView.findViewById(R.id.tv_order_product_name)
tvSellsProductQty = itemView.findViewById(R.id.tv_order_product_qty)
tvSellsProductPrice = itemView.findViewById(R.id.tv_order_product_price)
tvSeeMore = itemView.findViewById(R.id.tv_see_more_order)
tvSellsQty = itemView.findViewById(R.id.tv_order_qty)
tvSellsPrice = itemView.findViewById(R.id.tv_order_price)
tvSellsDue.text = formatDueDate(order.updatedAt.toString(), 1)
val product = order.orderItems?.firstOrNull()
tvSellsProductName.text = product?.productName
tvSellsProductQty.text = "x${product?.quantity}"
tvSellsProductPrice.text = formatPrice(product?.price.toString())
val fullImageUrl = when (val img = product?.productImage) {
is String -> {
if (img.startsWith("/")) BASE_URL + img.substring(1) else img
}
else -> R.drawable.placeholder_image
}
// Load product image using Glide
Glide.with(itemView.context)
.load(fullImageUrl)
.placeholder(R.drawable.placeholder_image)
.error(R.drawable.placeholder_image)
.into(ivSellsProduct)
tvSellsQty.text = "${order.orderItems?.size} produk"
tvSellsPrice.text = formatPrice(order.totalAmount.toString())
}
"paid" -> {
statusOrder.apply {
visibility = View.VISIBLE
text = "Sudah Dibayar"
}
deadlineLabel.apply {
visibility = View.VISIBLE
text = "Konfirmasi pembayaran sebelum:"
}
deadlineDate.apply {
visibility = View.VISIBLE
text = formatDatePay(order.updatedAt ?: "")
}
btnRight.apply {
visibility = View.VISIBLE
text = "Konfirmasi Pembayaran"
setOnClickListener {
val context = itemView.context
val intent = Intent(context, DetailPaymentActivity::class.java)
intent.putExtra("sells_data", Gson().toJson(order))
context.startActivity(intent)
}
layoutOrders.visibility = View.GONE
layoutPayments.visibility = View.VISIBLE
layoutShipments.visibility = View.GONE
tvSellsDue.text = formatDueDate(order.updatedAt.toString(), 2)
btnConfirmPayment.setOnClickListener {
val context = itemView.context
val intent = Intent(context, DetailPaymentActivity::class.java)
intent.putExtra("sells_data", Gson().toJson(order))
context.startActivity(intent)
viewModel.refreshOrders()
}
tvSellsTitle.text = "Pesanan Telah Dibayar"
tvSellsDueDesc.text = "Konfirmasi pembayaran sebelum:"
tvSellsDue.text = formatDueDate(order.updatedAt.toString(), 2)
}
"processed" -> {
statusOrder.apply {
visibility = View.VISIBLE
text = "Diproses"
}
deadlineLabel.apply {
visibility = View.VISIBLE
text = "Kirim sebelum:"
}
deadlineDate.apply {
visibility = View.VISIBLE
text = formatDatePay(order.updatedAt ?: "")
}
btnRight.apply {
visibility = View.VISIBLE
text = "Kirim Pesanan"
setOnClickListener {
val context = itemView.context
val intent = Intent(context, DetailShipmentActivity::class.java)
intent.putExtra("sells_data", Gson().toJson(order))
context.startActivity(intent)
}
layoutOrders.visibility = View.GONE
layoutPayments.visibility = View.GONE
layoutShipments.visibility = View.VISIBLE
tvSellsTitle = itemView.findViewById(R.id.tv_shipment_title)
tvSellsNumber = itemView.findViewById(R.id.tv_shipment_number)
tvSellsDue = itemView.findViewById(R.id.tv_shipment_due)
tvSellsLocation = itemView.findViewById(R.id.tv_shipment_location)
tvSellsCustomer = itemView.findViewById(R.id.tv_shipment_customer)
tvSellsProductName = itemView.findViewById(R.id.tv_shipment_product_name)
tvSellsProductQty = itemView.findViewById(R.id.tv_shipment_product_qty)
tvSeeMore = itemView.findViewById(R.id.tv_see_more_shipment)
tvSellsDue.text = formatDueDate(order.updatedAt.toString(), 2)
btnConfirmShipment.setOnClickListener {
val context = itemView.context
val intent = Intent(context, DetailShipmentActivity::class.java)
intent.putExtra("sells_data", Gson().toJson(order))
context.startActivity(intent)
}
tvSellsTitle.text = "Pesanan Perlu Dikirim"
tvSellsNumber.text = "No. Pesanan: ${order.orderId}"
tvSellsLocation.text = order.subdistrict
tvSellsCustomer.text = order.username
tvSellsDue.text = formatDueDate(order.updatedAt.toString(), 2)
}
"shipped" -> {
statusOrder.apply {
visibility = View.VISIBLE
text = "Dikirim"
}
deadlineLabel.apply {
visibility = View.VISIBLE
text = "Dikirimkan pada:"
}
deadlineDate.apply {
visibility = View.VISIBLE
text = formatDate(order.updatedAt ?: "")
}
layoutOrders.visibility = View.GONE
layoutPayments.visibility = View.VISIBLE
layoutShipments.visibility = View.GONE
tvSellsTitle.text = "Pesanan Telah Dikirim"
tvSellsDueDesc.text = "Dikirimkan pada"
tvSellsDue.text = formatDueDate(order.updatedAt.toString(), 0)
tvSellsDue.background = itemView.context.getDrawable(R.drawable.bg_product_inactive)
btnConfirmPayment.visibility = View.GONE
}
"delivered" -> {
layoutOrders.visibility = View.GONE
layoutPayments.visibility = View.VISIBLE
layoutShipments.visibility = View.GONE
tvSellsTitle.text = "Pesanan Telah Dikirim"
tvSellsDueDesc.text = "Dikirimkan pada"
tvSellsDue.text = formatDueDate(order.updatedAt.toString(), 0)
tvSellsDue.background = itemView.context.getDrawable(R.drawable.bg_product_inactive)
btnConfirmPayment.visibility = View.GONE
}
"completed" -> {
statusOrder.apply {
visibility = View.VISIBLE
text = "Selesai"
}
deadlineLabel.apply {
visibility = View.VISIBLE
text = "Selesai pada:"
}
deadlineDate.apply {
visibility = View.VISIBLE
text = formatDate(order.updatedAt ?: "")
}
layoutOrders.visibility = View.GONE
layoutPayments.visibility = View.VISIBLE
layoutShipments.visibility = View.GONE
tvSellsTitle.text = "Pesanan Selesai"
tvSellsDueDesc.text = "Selesai pada"
tvSellsDue.text = formatDueDate(order.updatedAt.toString(), 0)
tvSellsDue.background = itemView.context.getDrawable(R.drawable.bg_product_inactive)
btnConfirmPayment.visibility = View.GONE
}
"canceled" -> {
statusOrder.apply {
visibility = View.VISIBLE
text = "Dibatalkan"
}
deadlineLabel.apply {
visibility = View.VISIBLE
text = "Dibatalkan pada:"
}
deadlineDate.apply {
visibility = View.VISIBLE
text = formatDate(order.cancelDate ?: "")
}
layoutOrders.visibility = View.GONE
layoutPayments.visibility = View.VISIBLE
layoutShipments.visibility = View.GONE
tvSellsTitle.text = "Pesanan Dibatalkan"
tvSellsDueDesc.text = "Dibatalkan pada"
tvSellsDue.text = formatDueDate(order.updatedAt.toString(), 0)
tvSellsDue.background = itemView.context.getDrawable(R.drawable.bg_product_inactive)
btnConfirmPayment.visibility = View.GONE
}
}
}
private fun formatDate(dateString: String): String {
private fun formatDueDate(dateString: String, dueDay: Int): String {
return try {
val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
inputFormat.timeZone = TimeZone.getTimeZone("UTC")
val outputFormat = SimpleDateFormat("HH:mm dd MMMM yyyy", Locale("id", "ID"))
val outputFormat = SimpleDateFormat("dd MMM; HH.mm", Locale("id", "ID"))
val date = inputFormat.parse(dateString)
date?.let {
val calendar = Calendar.getInstance()
calendar.time = it
calendar.set(Calendar.HOUR_OF_DAY, 23)
calendar.set(Calendar.MINUTE, 59)
calendar.add(Calendar.DATE, dueDay)
outputFormat.format(calendar.time)
} ?: dateString
@ -316,27 +309,10 @@ class SellsAdapter(
}
}
private fun formatDatePay(dateString: String): String {
return try {
// Parse the ISO 8601 date
val isoDateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
isoDateFormat.timeZone = TimeZone.getTimeZone("UTC")
val createdDate = isoDateFormat.parse(dateString)
// Add 24 hours to get due date
val calendar = Calendar.getInstance()
calendar.time = createdDate
calendar.add(Calendar.HOUR, 24)
// Format due date for display
val dueDateFormat = SimpleDateFormat("dd MMM yyyy", Locale.getDefault())
dueDateFormat.format(calendar.time)
} catch (e: Exception) {
Log.e("DateFormatting", "Error formatting date: ${e.message}")
dateString
}
private fun formatPrice(price: String): String {
val priceDouble = price.toDoubleOrNull() ?: 0.0
val formattedPrice = String.format(Locale("id", "ID"), "Rp%,.0f", priceDouble)
return formattedPrice
}
}
}

View File

@ -42,14 +42,14 @@ class SellsFragment : Fragment() {
// Connect TabLayout with ViewPager2
TabLayoutMediator(binding.tabLayoutSells, binding.viewPagerSells) { tab, position ->
tab.text = when (position) {
0 -> getString(R.string.all_orders) // "Semua Pesanan"
1 -> getString(R.string.pending_orders) // "Menunggu Tagihan"
2 -> getString(R.string.unpaid_orders) // "Konfirmasi Bayar"
3 -> getString(R.string.paid_orders) // "Diproses"
4 -> getString(R.string.processed_orders) // "Sudah Dibayar"
5 -> getString(R.string.shipped_orders) // "Dikirim"
6 -> getString(R.string.completed_orders) // "Selesai"
7 -> getString(R.string.canceled_orders) // "Dibatalkan"
0 -> getString(R.string.all_sells)
1 -> getString(R.string.unpaid_sells)
2 -> getString(R.string.paid_sells)
3 -> getString(R.string.processed_sells)
4 -> getString(R.string.shipped_sells)
5 -> getString(R.string.delivered_sells)
6 -> getString(R.string.completed_sells)
7 -> getString(R.string.canceled_sells)
else -> "Tab $position"
}
}.attach()

View File

@ -33,12 +33,10 @@ class SellsListFragment : Fragment() {
}
}
private lateinit var sellsAdapter: SellsAdapter
private var status: String = "all"
companion object {
private const val TAG = "SellsListFragment"
private const val ARG_STATUS = "status"
fun newInstance(status: String): SellsListFragment {
@ -123,7 +121,7 @@ class SellsListFragment : Fragment() {
Log.d(TAG, "✅ Data is available: ${result.data.size} items")
binding.tvEmptyState.visibility = View.GONE
binding.rvSells.visibility = View.VISIBLE
// Log first few items for debugging
result.data.take(3).forEachIndexed { index, order ->
Log.d(TAG, "Order ${index + 1}: ID=${order.orderId}, Status=${order.status}, Customer=${order.username}")
}

View File

@ -10,14 +10,14 @@ class SellsViewPagerAdapter(
// Define all possible sells statuses - keeping your original list
private val sellsStatuses = listOf(
"all", // Position 0: "Semua Pesanan"
"pending", // Position 1: "Menunggu Tagihan"
"unpaid", // Position 2: "Konfirmasi Bayar"
"paid", // Position 3: "Diproses"
"processed", // Position 4: "Sudah Dibayar"
"shipped", // Position 5: "Dikirim"
"completed", // Position 6: "Selesai"
"canceled" // Position 7: "Dibatalkan"
"all",
"unpaid",
"paid",
"processed",
"shipped",
"delivered",
"completed",
"canceled"
)
override fun getItemCount(): Int = sellsStatuses.size

File diff suppressed because it is too large Load Diff

View File

@ -66,17 +66,26 @@
<string name="dl_date_wait">23:59 15 April 2025</string>
<string name="no_available_orders">Tidak ada order</string>
<string name="item_count_prod">%d produk</string>
<string name="show_more_product">%d produk lainnya</string>
<!-- status order-->
<string name="show_more_product">Lihat %d produk lainnya</string>
<!-- status order -->
<string name="all_orders">Semua Pesanan </string>
<string name="pending_orders">Menunggu Tagihan</string>
<string name="unpaid_orders">Konfrimasi Bayar</string>
<string name="unpaid_orders">Perlu Dibayar</string>
<string name="processed_orders">Diproses</string>
<string name="paid_orders">Sudah Dibayar</string>
<string name="delivered_orders">Pesanan Sampai</string>
<string name="completed_orders">Selesai</string>
<string name="shipped_orders">Dikirim</string>
<string name="canceled_orders">Dibatalkan</string>
<!-- status penjualan -->
<string name="all_sells">Semua Penjualan</string>
<string name="unpaid_sells">Belum Dibayar</string>
<string name="paid_sells">Konfirmasi Pembayaran</string>
<string name="processed_sells">Perlu Dikirim</string>
<string name="shipped_sells">Dikirim</string>
<string name="delivered_sells">Pengiriman Sampai</string>
<string name="completed_sells">Selesai</string>
<string name="canceled_sells">Dibatalkan</string>
<!-- deadline label -->
<string name="dl_pending">Batas Tagihan</string>
<string name="dl_unpaid">Batas Pembayaran</string>