diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrdersItem.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrdersItem.kt index 5d16279..439b949 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrdersItem.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrdersItem.kt @@ -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 ) diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt b/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt index e162141..0f4f587 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt @@ -511,4 +511,5 @@ class OrderRepository(private val apiService: ApiService) { } } + } \ No newline at end of file diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryViewModel.kt index 9c36c28..c2df487 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/HistoryViewModel.kt @@ -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 { - 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") - } - is Result.Error -> { - _orders.value = ViewState.Error(result.exception.message ?: "Unknown error occurred") - Log.e("HistoryViewModel", "Error loading orders", result.exception) - } - is Result.Loading -> { - null + 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(TAG, "Orders loaded successfully: ${result.data.orders.size} items") + } + is Result.Error -> { + _orders.value = ViewState.Error(result.exception.message ?: "Unknown error occurred") + Log.e(TAG, "Error loading orders", result.exception) + } + is Result.Loading -> { + // 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() + + // 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() + } + is Result.Loading -> emptyList() + } + } + } + + // 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 { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderHistoryAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderHistoryAdapter.kt index 5432f78..a67a2d7 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderHistoryAdapter.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderHistoryAdapter.kt @@ -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) + } } } } diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderListFragment.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderListFragment.kt index fcc9837..5e43898 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderListFragment.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/history/OrderListFragment.kt @@ -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() { } } } - } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 43c932d..1623228 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -85,7 +85,7 @@ Semua Pesanan Semua Pesanan Tanggal Pesanan Sampai - Semua Pesanan + Tanggal Pesanan Dibatalkan Kirim Bukti Pembayaran Batalkan Pesanan