sells store

This commit is contained in:
Gracia Hotmauli
2025-05-21 00:26:00 +07:00
parent 4e4faf25be
commit 4f65b845d6
23 changed files with 2212 additions and 978 deletions

View File

@ -109,7 +109,6 @@ class DetailStoreProductActivity : AppCompatActivity() {
// Setup Pre-Order visibility
binding.switchIsPreOrder.setOnCheckedChangeListener { _, isChecked ->
binding.layoutDurasi.visibility = if (isChecked) View.VISIBLE else View.GONE
validateForm()
}
validateForm()
@ -176,7 +175,10 @@ class DetailStoreProductActivity : AppCompatActivity() {
binding.edtStokProduk.setText(product?.stock.toString())
binding.edtMinOrder.setText(product?.minOrder.toString())
binding.edtBeratProduk.setText(product?.weight.toString())
binding.switchIsPreOrder.isChecked = product?.isPreOrder ?: false
binding.switchIsPreOrder.isChecked = product?.isPreOrder == false
// binding.switchIsWholesale.isChecked = product?.isWholesale == false
// binding.edtMinPesanGrosir.setText(product?.minOrderWholesale.toString())
// binding.edtHargaGrosir.setText(product?.priceWholesale.toString())
binding.switchIsActive.isChecked = product?.status == "active"
binding.spinnerKondisiProduk.setSelection(if (product?.condition == "Baru") 0 else 1)
@ -267,6 +269,9 @@ class DetailStoreProductActivity : AppCompatActivity() {
val weight = binding.edtBeratProduk.text.toString().toInt()
val isPreOrder = binding.switchIsPreOrder.isChecked
val duration = if (isPreOrder) binding.edtDurasi.text.toString().toInt() else 0
val isWholesale = binding.switchIsWholesale.isChecked
val minOrderWholesale = binding.edtMinPesanGrosir.text.toString().toInt()
val priceWholesale = binding.edtHargaGrosir.text.toString().toInt()
val status = if (binding.switchIsActive.isChecked) "active" else "inactive"
val condition = binding.spinnerKondisiProduk.selectedItem.toString()
val categoryId = categoryList.getOrNull(binding.spinnerKategoriProduk.selectedItemPosition)?.id ?: 0

View File

@ -3,6 +3,7 @@ package com.alya.ecommerce_serang.ui.profile.mystore.sells
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import androidx.fragment.app.commit
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
import com.alya.ecommerce_serang.data.repository.SellsRepository
@ -33,9 +34,9 @@ class SellsActivity : AppCompatActivity() {
setupHeader()
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container_sells, SellsFragment())
.commit()
supportFragmentManager.commit {
replace(R.id.fragment_container_sells, SellsFragment())
}
}
}

View File

@ -1,5 +1,6 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells
import android.content.Intent
import android.util.Log
import android.view.LayoutInflater
import android.view.View
@ -10,8 +11,11 @@ import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
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.gson.Gson
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
@ -35,17 +39,8 @@ class SellsAdapter(
notifyDataSetChanged()
}
fun findResource(status: String): Int {
return when (status) {
"pending" -> R.layout.item_sells_order
"paid" -> R.layout.item_sells_payment
"processed" -> R.layout.item_sells_shipment
else -> R.layout.item_sells_payment
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SellsViewHolder {
val view = LayoutInflater.from(parent.context).inflate(findResource(fragmentStatus), parent, false)
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sells, parent, false)
return SellsViewHolder(view)
}
@ -56,21 +51,23 @@ class SellsAdapter(
override fun getItemCount(): Int = sells.size
inner class SellsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val tvSellsTitle: TextView = itemView.findViewById(R.id.tv_sells_title)
private val tvSellsNumber: TextView = itemView.findViewById(R.id.tv_sells_number)
private val tvSellsDueDesc: TextView = itemView.findViewById(R.id.tv_sells_due_desc)
private val tvSellsDue: TextView = itemView.findViewById(R.id.tv_sells_due)
private val tvSellsLocation: TextView = itemView.findViewById(R.id.tv_sells_location)
private val tvSellsCustomer: TextView = itemView.findViewById(R.id.tv_sells_customer)
private val ivSellsProduct: ImageView = itemView.findViewById(R.id.iv_sells_product)
private val tvSellsProductName: TextView = itemView.findViewById(R.id.tv_sells_product_name)
private val tvSellsProductQty: TextView = itemView.findViewById(R.id.tv_sells_product_qty)
private val tvSellsProductPrice: TextView = itemView.findViewById(R.id.tv_sells_product_price)
private val tvSeeMore: TextView = itemView.findViewById(R.id.tv_see_more)
private val tvSellsQty: TextView = itemView.findViewById(R.id.tv_sells_qty)
private val tvSellsPrice: TextView = itemView.findViewById(R.id.tv_sells_price)
private val btnEditOrder: Button = itemView.findViewById(R.id.btn_edit_order)
private val btnConfirmOrder: Button = itemView.findViewById(R.id.btn_confirm_order)
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)
@ -111,51 +108,103 @@ class SellsAdapter(
Log.d("SellsAdapter", "Adjusting display for status: $status")
when (status) {
"pending" -> {
tvSellsDue.text = formatDueDate(sells.updatedAt.toString(), 3)
btnEditOrder.setOnClickListener {
TODO("Go to DetailOrderActivity")
}
btnConfirmOrder.setOnClickListener {
viewModel.updateOrderStatus(sells.orderId, "unpaid")
}
"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(sells.updatedAt.toString(), 1)
}
"paid" -> {
tvSellsDue.text = formatDueDate(sells.updatedAt.toString(), 1)
layoutOrders.visibility = View.GONE
layoutPayments.visibility = View.VISIBLE
layoutShipments.visibility = View.GONE
tvSellsDue.text = formatDueDate(sells.updatedAt.toString(), 2)
btnConfirmPayment.setOnClickListener {
TODO("Go to DetailPaymentActivity")
val context = itemView.context
val intent = Intent(context, DetailPaymentActivity::class.java)
intent.putExtra("sells_data", Gson().toJson(sells))
context.startActivity(intent)
}
}
"processed" -> {
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(sells.updatedAt.toString(), 2)
btnConfirmShipment.setOnClickListener {
TODO("Go to DetailShipmentActivity")
val context = itemView.context
val intent = Intent(context, DetailShipmentActivity::class.java)
intent.putExtra("sells_data", Gson().toJson(sells))
context.startActivity(intent)
}
}
"shipped" -> {
layoutOrders.visibility = View.GONE
layoutPayments.visibility = View.VISIBLE
layoutShipments.visibility = View.GONE
tvSellsTitle.text = "Pesanan Telah Dikirim"
tvSellsDueDesc.text = "Dikirimkan pada"
tvSellsDue.text = formatDueDate(sells.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(sells.updatedAt.toString(), 0)
tvSellsDue.background = itemView.context.getDrawable(R.drawable.bg_product_inactive)
btnConfirmPayment.visibility = View.GONE
}
"completed" -> {
layoutOrders.visibility = View.GONE
layoutPayments.visibility = View.VISIBLE
layoutShipments.visibility = View.GONE
tvSellsTitle.text = "Pesanan Selesai"
tvSellsDueDesc.text = "Selesai pada"
tvSellsDue.text = formatDueDate(sells.updatedAt.toString(), 0)
tvSellsDue.background = itemView.context.getDrawable(R.drawable.bg_product_inactive)
btnConfirmPayment.visibility = View.GONE
}
"canceled" -> {
layoutOrders.visibility = View.GONE
layoutPayments.visibility = View.VISIBLE
layoutShipments.visibility = View.GONE
tvSellsTitle.text = "Pesanan Dibatalkan"
tvSellsDueDesc.text = "Dibatalkan pada"
tvSellsDue.text = formatDueDate(sells.updatedAt.toString(), 0)
tvSellsDue.background = itemView.context.getDrawable(R.drawable.bg_product_inactive)
btnConfirmPayment.visibility = View.GONE

View File

@ -35,14 +35,13 @@ class SellsFragment : Fragment() {
val tabs = listOf(
"Semua Pesanan",
"Perlu Tagihan",
"Pesanan Masuk",
"Konfirmasi Pembayaran",
"Perlu Dikirim",
"Dikirim",
"Selesai",
"Pembatalan",
"Klaim Pembayaran",
"Pengiriman Gagal"
"Klaim Pembayaran"
)
TabLayoutMediator(binding.tabLayoutSells, binding.viewPagerSells) { tab, position ->

View File

@ -0,0 +1,48 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.alya.ecommerce_serang.R
import com.alya.ecommerce_serang.data.api.response.store.orders.OrderItemsItem
import com.bumptech.glide.Glide
class SellsProductAdapter(
private val items: List<OrderItemsItem?>
) : RecyclerView.Adapter<SellsProductAdapter.ProductViewHolder>() {
inner class ProductViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val ivProduct: ImageView = view.findViewById(R.id.iv_order_product)
val tvName: TextView = view.findViewById(R.id.tv_order_product_name)
val tvQty: TextView = view.findViewById(R.id.tv_order_product_qty)
val tvPrice: TextView = view.findViewById(R.id.tv_order_product_price)
val tvTotal: TextView = view.findViewById(R.id.tv_order_product_total_price)
fun bind(item: OrderItemsItem) {
tvName.text = item.productName
tvQty.text = "${item.quantity} x "
tvPrice.text = "Rp${item.price}"
val total = (item.quantity ?: 1) * (item.price ?: 0)
tvTotal.text = "Rp$total"
Glide.with(ivProduct.context)
.load(item.productImage)
.placeholder(R.drawable.placeholder_image)
.into(ivProduct)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_sells_product, parent, false)
return ProductViewHolder(view)
}
override fun getItemCount(): Int = items.size
override fun onBindViewHolder(holder: ProductViewHolder, position: Int) {
items[position]?.let { holder.bind(it) }
}
}

View File

@ -9,14 +9,13 @@ class SellsViewPagerAdapter(fragmentActivity: FragmentActivity)
private val sellsStatuses = listOf(
"all", // Semua Pesanan
"pending", // Perlu Tagihan
"unpaid", // Pesanan Masuk
"processed", // Konfirmasi Pembayaran
"paid", // Perlu Dikirim
"shipped", // Dikirim
"delivered", // Dikirim
"completed", // Selesai
"canceled", // Dibatalkan
TODO("Klaim Pembayaran dan Pengajuan Komplain belum ada statusnya")
"payment_onhold"
)
override fun getItemCount(): Int = sellsStatuses.size

View File

@ -1,21 +1,65 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.payment
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.alya.ecommerce_serang.R
import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.data.api.response.store.orders.OrdersItem
import com.alya.ecommerce_serang.databinding.ActivityDetailPaymentBinding
import com.alya.ecommerce_serang.ui.profile.mystore.sells.SellsProductAdapter
import com.google.gson.Gson
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.TimeZone
class DetailPaymentActivity : AppCompatActivity() {
private lateinit var binding: ActivityDetailPaymentBinding
private lateinit var sells: OrdersItem
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_detail_payment)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
binding = ActivityDetailPaymentBinding.inflate(layoutInflater)
setContentView(binding.root)
val orderJson = intent.getStringExtra("sells_data")
sells = Gson().fromJson(orderJson, OrdersItem::class.java)
bindOrderDetails()
setupRecyclerView()
}
private fun bindOrderDetails() = with(binding) {
tvOrderNumber.text = sells.orderId.toString()
tvOrderCustomer.text = sells.username
tvOrderDate.text = formatDate(sells.createdAt)
tvOrderDue.text = formatDate(sells.updatedAt)
tvOrderTotalProduct.text = "(${sells.orderItems?.size ?: 0} Barang)"
tvOrderSubtotal.text = "Rp${sells.totalAmount}"
tvOrderPrice.text = "Rp${sells.totalAmount}"
tvOrderShipPrice.text = "Rp${sells.shipmentPrice}"
tvOrderRecipient.text = sells.username
// tvOrderRecipientNum.text = sells.phone
tvOrderRecipientAddress.text = sells.street
}
private fun setupRecyclerView() {
binding.rvProductItems.apply {
layoutManager = LinearLayoutManager(this@DetailPaymentActivity)
adapter = SellsProductAdapter(sells.orderItems ?: emptyList())
}
}
private fun formatDate(dateStr: String?): 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("dd MMM yyyy, HH:mm", Locale("id", "ID"))
val date = inputFormat.parse(dateStr ?: "")
outputFormat.format(date!!)
} catch (e: Exception) {
"-"
}
}
}

View File

@ -1,21 +1,65 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.shipment
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.alya.ecommerce_serang.R
import androidx.recyclerview.widget.LinearLayoutManager
import com.alya.ecommerce_serang.data.api.response.store.orders.OrdersItem
import com.alya.ecommerce_serang.databinding.ActivityDetailShipmentBinding
import com.alya.ecommerce_serang.ui.profile.mystore.sells.SellsProductAdapter
import com.google.gson.Gson
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.TimeZone
class DetailShipmentActivity : AppCompatActivity() {
private lateinit var binding: ActivityDetailShipmentBinding
private lateinit var sells: OrdersItem
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_detail_shipment)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
binding = ActivityDetailShipmentBinding.inflate(layoutInflater)
setContentView(binding.root)
val orderJson = intent.getStringExtra("order_data")
sells = Gson().fromJson(orderJson, OrdersItem::class.java)
bindOrderDetails()
setupRecyclerView()
}
private fun bindOrderDetails() = with(binding) {
tvOrderNumber.text = sells.orderId.toString()
tvOrderCustomer.text = sells.username
tvOrderDate.text = formatDate(sells.createdAt)
tvOrderDue.text = formatDate(sells.updatedAt)
tvOrderTotalProduct.text = "(${sells.orderItems?.size ?: 0} Barang)"
tvOrderSubtotal.text = "Rp${sells.totalAmount}"
tvOrderPrice.text = "Rp${sells.totalAmount}"
tvOrderShipPrice.text = "Rp${sells.shipmentPrice}"
tvOrderRecipient.text = sells.username
// tvOrderRecipientNum.text = sells.phone
tvOrderRecipientAddress.text = sells.street
}
private fun setupRecyclerView() {
binding.rvProductItems.apply {
layoutManager = LinearLayoutManager(this@DetailShipmentActivity)
adapter = SellsProductAdapter(sells.orderItems ?: emptyList())
}
}
private fun formatDate(dateStr: String?): 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("dd MMM yyyy, HH:mm", Locale("id", "ID"))
val date = inputFormat.parse(dateStr ?: "")
outputFormat.format(date!!)
} catch (e: Exception) {
"-"
}
}
}

View File

@ -1,4 +1,4 @@
package com.alya.ecommerce_serang.ui.profile.mystore.sells.order
package com.alya.ecommerce_serang.ui.profile.mystore.sells.shipment
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
@ -7,11 +7,11 @@ import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.alya.ecommerce_serang.R
class DetailOrderActivity : AppCompatActivity() {
class ShipmentConfirmationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_detail_order)
setContentView(R.layout.activity_shipment_confirmation)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)