mirror of
https://github.com/shaulascr/ecommerce_serang.git
synced 2025-08-10 09:22:21 +00:00
add all order tab
This commit is contained in:
@ -27,7 +27,7 @@ data class OrdersItem(
|
||||
val street: String,
|
||||
|
||||
@field:SerializedName("cancel_date")
|
||||
val cancelDate: String? = null,
|
||||
val cancelDate: String,
|
||||
|
||||
@field:SerializedName("longitude")
|
||||
val longitude: String,
|
||||
@ -42,7 +42,7 @@ data class OrdersItem(
|
||||
val autoCompletedAt: String? = null,
|
||||
|
||||
@field:SerializedName("is_store_location")
|
||||
val isStoreLocation: Boolean? = null,
|
||||
val isStoreLocation: Boolean? = false,
|
||||
|
||||
@field:SerializedName("voucher_name")
|
||||
val voucherName: String? = null,
|
||||
@ -81,7 +81,7 @@ data class OrdersItem(
|
||||
val paymentInfoId: Int? = null,
|
||||
|
||||
@field:SerializedName("detail")
|
||||
val detail: String,
|
||||
val detail: String? = null,
|
||||
|
||||
@field:SerializedName("postal_code")
|
||||
val postalCode: String,
|
||||
@ -90,5 +90,7 @@ data class OrdersItem(
|
||||
val orderId: Int,
|
||||
|
||||
@field:SerializedName("city_id")
|
||||
val cityId: Int
|
||||
val cityId: Int,
|
||||
|
||||
var displayStatus: String? = null
|
||||
)
|
||||
|
@ -511,4 +511,5 @@ class OrderRepository(private val apiService: ApiService) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -15,8 +15,13 @@ import com.alya.ecommerce_serang.data.api.response.order.CompletedOrderResponse
|
||||
import com.alya.ecommerce_serang.data.repository.OrderRepository
|
||||
import com.alya.ecommerce_serang.data.repository.Result
|
||||
import com.alya.ecommerce_serang.ui.order.address.ViewState
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
class HistoryViewModel(private val repository: OrderRepository) : ViewModel() {
|
||||
|
||||
@ -57,28 +62,80 @@ class HistoryViewModel(private val repository: OrderRepository) : ViewModel() {
|
||||
fun getOrderList(status: String) {
|
||||
_orders.value = ViewState.Loading
|
||||
viewModelScope.launch {
|
||||
_orders.value = ViewState.Loading
|
||||
|
||||
try {
|
||||
if (status == "all") {
|
||||
// Get all orders by combining all statuses
|
||||
getAllOrdersCombined()
|
||||
} else {
|
||||
// Get orders for specific status
|
||||
when (val result = repository.getOrderList(status)) {
|
||||
is Result.Success -> {
|
||||
_orders.value = ViewState.Success(result.data.orders)
|
||||
Log.d("HistoryViewModel", "Orders loaded successfully: ${result.data.orders.size} items")
|
||||
Log.d(TAG, "Orders loaded successfully: ${result.data.orders.size} items")
|
||||
}
|
||||
is Result.Error -> {
|
||||
_orders.value = ViewState.Error(result.exception.message ?: "Unknown error occurred")
|
||||
Log.e("HistoryViewModel", "Error loading orders", result.exception)
|
||||
Log.e(TAG, "Error loading orders", result.exception)
|
||||
}
|
||||
is Result.Loading -> {
|
||||
null
|
||||
// Keep loading state
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
_orders.value = ViewState.Error("An unexpected error occurred: ${e.message}")
|
||||
Log.e("HistoryViewModel", "Exception in getOrderList", e)
|
||||
Log.e(TAG, "Exception in getOrderList", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getAllOrdersCombined() {
|
||||
try {
|
||||
val allStatuses = listOf("pending", "unpaid", "processed", "shipped", "completed", "canceled")
|
||||
val allOrders = mutableListOf<OrdersItem>()
|
||||
|
||||
// Use coroutineScope to allow launching async blocks
|
||||
coroutineScope {
|
||||
val deferreds = allStatuses.map { status ->
|
||||
async {
|
||||
when (val result = repository.getOrderList(status)) {
|
||||
is Result.Success -> {
|
||||
// Tag each order with the status it was fetched from
|
||||
result.data.orders.onEach { it.displayStatus = status }
|
||||
}
|
||||
is Result.Error -> {
|
||||
Log.e(TAG, "Error loading orders for status $status", result.exception)
|
||||
emptyList<OrdersItem>()
|
||||
}
|
||||
is Result.Loading -> emptyList<OrdersItem>()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Await all results and combine
|
||||
deferreds.awaitAll().forEach { orders ->
|
||||
allOrders.addAll(orders)
|
||||
}
|
||||
}
|
||||
|
||||
// Sort orders
|
||||
val sortedOrders = allOrders.sortedByDescending { order ->
|
||||
try {
|
||||
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault()).parse(order.createdAt)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
_orders.value = ViewState.Success(sortedOrders)
|
||||
Log.d(TAG, "All orders loaded successfully: ${sortedOrders.size} items")
|
||||
|
||||
} catch (e: Exception) {
|
||||
_orders.value = ViewState.Error("An unexpected error occurred: ${e.message}")
|
||||
Log.e(TAG, "Exception in getAllOrdersCombined", e)
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmOrderCompleted(orderId: Int, status: String) {
|
||||
Log.d(TAG, "Confirming order completed: orderId=$orderId, status=$status")
|
||||
viewModelScope.launch {
|
||||
|
@ -119,8 +119,8 @@ class OrderHistoryAdapter(
|
||||
onOrderClickListener(order)
|
||||
}
|
||||
|
||||
//adjust each fragment
|
||||
adjustButtonsAndText(fragmentStatus, order)
|
||||
val actualStatus = if (fragmentStatus == "all") order.displayStatus ?: "" else fragmentStatus
|
||||
adjustButtonsAndText(actualStatus, order)
|
||||
|
||||
}
|
||||
|
||||
@ -253,7 +253,7 @@ class OrderHistoryAdapter(
|
||||
"completed" -> {
|
||||
statusOrder.apply {
|
||||
visibility = View.VISIBLE
|
||||
text = itemView.context.getString(R.string.shipped_orders)
|
||||
text = itemView.context.getString(R.string.completed_orders)
|
||||
}
|
||||
deadlineLabel.apply {
|
||||
visibility = View.VISIBLE
|
||||
@ -268,12 +268,26 @@ class OrderHistoryAdapter(
|
||||
// Handle click event
|
||||
}
|
||||
}
|
||||
deadlineDate.apply {
|
||||
visibility = View.VISIBLE
|
||||
text = formatDate(order.updatedAt)
|
||||
}
|
||||
}
|
||||
"canceled" -> {
|
||||
statusOrder.apply {
|
||||
visibility = View.VISIBLE
|
||||
text = itemView.context.getString(R.string.canceled_orders)
|
||||
}
|
||||
|
||||
deadlineLabel.apply {
|
||||
visibility = View.VISIBLE
|
||||
text = itemView.context.getString(R.string.dl_canceled)
|
||||
}
|
||||
|
||||
deadlineDate.apply {
|
||||
visibility = View.VISIBLE
|
||||
text = formatDate(order.cancelDate)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ class OrderListFragment : Fragment() {
|
||||
private val binding get() = _binding!!
|
||||
private lateinit var sessionManager: SessionManager
|
||||
|
||||
|
||||
private val viewModel: HistoryViewModel by viewModels {
|
||||
BaseViewModelFactory {
|
||||
val apiService = ApiConfig.getApiService(sessionManager)
|
||||
@ -80,10 +79,9 @@ class OrderListFragment : Fragment() {
|
||||
private fun setupRecyclerView() {
|
||||
orderAdapter = OrderHistoryAdapter(
|
||||
onOrderClickListener = { order ->
|
||||
// Handle order click
|
||||
navigateToOrderDetail(order)
|
||||
},
|
||||
viewModel = viewModel // Pass the ViewModel to the adapter
|
||||
viewModel = viewModel
|
||||
)
|
||||
|
||||
orderAdapter.setFragmentStatus(status)
|
||||
@ -95,6 +93,7 @@ class OrderListFragment : Fragment() {
|
||||
}
|
||||
|
||||
private fun observeOrderList() {
|
||||
// Now we only need to observe one LiveData for all cases
|
||||
viewModel.orders.observe(viewLifecycleOwner) { result ->
|
||||
when (result) {
|
||||
is ViewState.Success -> {
|
||||
@ -115,13 +114,14 @@ class OrderListFragment : Fragment() {
|
||||
Toast.makeText(requireContext(), result.message, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
is ViewState.Loading -> {
|
||||
null
|
||||
binding.progressBar.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadOrders() {
|
||||
// Simple - just call getOrderList for any status including "all"
|
||||
viewModel.getOrderList(status)
|
||||
}
|
||||
|
||||
@ -130,15 +130,15 @@ class OrderListFragment : Fragment() {
|
||||
) { result ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
// Refresh order list when returning with OK result
|
||||
viewModel.getOrderList(status)
|
||||
loadOrders()
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateToOrderDetail(order: OrdersItem) {
|
||||
val intent = Intent(requireContext(), DetailOrderStatusActivity::class.java).apply {
|
||||
putExtra("ORDER_ID", order.orderId)
|
||||
putExtra("ORDER_STATUS", status) // Pass the current status
|
||||
}
|
||||
val actualStatus = if (status == "all") order.displayStatus ?: "" else status
|
||||
putExtra("ORDER_STATUS", actualStatus) }
|
||||
detailOrderLauncher.launch(intent)
|
||||
}
|
||||
|
||||
@ -147,11 +147,11 @@ class OrderListFragment : Fragment() {
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private fun observeOrderCompletionStatus(){
|
||||
viewModel.orderCompletionStatus.observe(viewLifecycleOwner){ result ->
|
||||
when(result){
|
||||
private fun observeOrderCompletionStatus() {
|
||||
viewModel.orderCompletionStatus.observe(viewLifecycleOwner) { result ->
|
||||
when (result) {
|
||||
is Result.Loading -> {
|
||||
|
||||
// Handle loading state if needed
|
||||
}
|
||||
is Result.Success -> {
|
||||
Toast.makeText(requireContext(), "Order completed successfully!", Toast.LENGTH_SHORT).show()
|
||||
@ -163,5 +163,4 @@ class OrderListFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -85,7 +85,7 @@
|
||||
<string name="dl_delivered">Semua Pesanan </string>
|
||||
<string name="dl_completed">Semua Pesanan </string>
|
||||
<string name="dl_shipped">Tanggal Pesanan Sampai</string>
|
||||
<string name="dl_canceled">Semua Pesanan </string>
|
||||
<string name="dl_canceled">Tanggal Pesanan Dibatalkan </string>
|
||||
|
||||
<string name="sent_evidence">Kirim Bukti Pembayaran </string>
|
||||
<string name="canceled_order_btn">Batalkan Pesanan </string>
|
||||
|
Reference in New Issue
Block a user