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,
|
val street: String,
|
||||||
|
|
||||||
@field:SerializedName("cancel_date")
|
@field:SerializedName("cancel_date")
|
||||||
val cancelDate: String? = null,
|
val cancelDate: String,
|
||||||
|
|
||||||
@field:SerializedName("longitude")
|
@field:SerializedName("longitude")
|
||||||
val longitude: String,
|
val longitude: String,
|
||||||
@ -42,7 +42,7 @@ data class OrdersItem(
|
|||||||
val autoCompletedAt: String? = null,
|
val autoCompletedAt: String? = null,
|
||||||
|
|
||||||
@field:SerializedName("is_store_location")
|
@field:SerializedName("is_store_location")
|
||||||
val isStoreLocation: Boolean? = null,
|
val isStoreLocation: Boolean? = false,
|
||||||
|
|
||||||
@field:SerializedName("voucher_name")
|
@field:SerializedName("voucher_name")
|
||||||
val voucherName: String? = null,
|
val voucherName: String? = null,
|
||||||
@ -81,7 +81,7 @@ data class OrdersItem(
|
|||||||
val paymentInfoId: Int? = null,
|
val paymentInfoId: Int? = null,
|
||||||
|
|
||||||
@field:SerializedName("detail")
|
@field:SerializedName("detail")
|
||||||
val detail: String,
|
val detail: String? = null,
|
||||||
|
|
||||||
@field:SerializedName("postal_code")
|
@field:SerializedName("postal_code")
|
||||||
val postalCode: String,
|
val postalCode: String,
|
||||||
@ -90,5 +90,7 @@ data class OrdersItem(
|
|||||||
val orderId: Int,
|
val orderId: Int,
|
||||||
|
|
||||||
@field:SerializedName("city_id")
|
@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.OrderRepository
|
||||||
import com.alya.ecommerce_serang.data.repository.Result
|
import com.alya.ecommerce_serang.data.repository.Result
|
||||||
import com.alya.ecommerce_serang.ui.order.address.ViewState
|
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 kotlinx.coroutines.launch
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
class HistoryViewModel(private val repository: OrderRepository) : ViewModel() {
|
class HistoryViewModel(private val repository: OrderRepository) : ViewModel() {
|
||||||
|
|
||||||
@ -57,28 +62,80 @@ class HistoryViewModel(private val repository: OrderRepository) : ViewModel() {
|
|||||||
fun getOrderList(status: String) {
|
fun getOrderList(status: String) {
|
||||||
_orders.value = ViewState.Loading
|
_orders.value = ViewState.Loading
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
_orders.value = ViewState.Loading
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
when (val result = repository.getOrderList(status)) {
|
if (status == "all") {
|
||||||
is Result.Success -> {
|
// Get all orders by combining all statuses
|
||||||
_orders.value = ViewState.Success(result.data.orders)
|
getAllOrdersCombined()
|
||||||
Log.d("HistoryViewModel", "Orders loaded successfully: ${result.data.orders.size} items")
|
} else {
|
||||||
}
|
// Get orders for specific status
|
||||||
is Result.Error -> {
|
when (val result = repository.getOrderList(status)) {
|
||||||
_orders.value = ViewState.Error(result.exception.message ?: "Unknown error occurred")
|
is Result.Success -> {
|
||||||
Log.e("HistoryViewModel", "Error loading orders", result.exception)
|
_orders.value = ViewState.Success(result.data.orders)
|
||||||
}
|
Log.d(TAG, "Orders loaded successfully: ${result.data.orders.size} items")
|
||||||
is Result.Loading -> {
|
}
|
||||||
null
|
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) {
|
} catch (e: Exception) {
|
||||||
_orders.value = ViewState.Error("An unexpected error occurred: ${e.message}")
|
_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) {
|
fun confirmOrderCompleted(orderId: Int, status: String) {
|
||||||
Log.d(TAG, "Confirming order completed: orderId=$orderId, status=$status")
|
Log.d(TAG, "Confirming order completed: orderId=$orderId, status=$status")
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
@ -119,8 +119,8 @@ class OrderHistoryAdapter(
|
|||||||
onOrderClickListener(order)
|
onOrderClickListener(order)
|
||||||
}
|
}
|
||||||
|
|
||||||
//adjust each fragment
|
val actualStatus = if (fragmentStatus == "all") order.displayStatus ?: "" else fragmentStatus
|
||||||
adjustButtonsAndText(fragmentStatus, order)
|
adjustButtonsAndText(actualStatus, order)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +253,7 @@ class OrderHistoryAdapter(
|
|||||||
"completed" -> {
|
"completed" -> {
|
||||||
statusOrder.apply {
|
statusOrder.apply {
|
||||||
visibility = View.VISIBLE
|
visibility = View.VISIBLE
|
||||||
text = itemView.context.getString(R.string.shipped_orders)
|
text = itemView.context.getString(R.string.completed_orders)
|
||||||
}
|
}
|
||||||
deadlineLabel.apply {
|
deadlineLabel.apply {
|
||||||
visibility = View.VISIBLE
|
visibility = View.VISIBLE
|
||||||
@ -268,12 +268,26 @@ class OrderHistoryAdapter(
|
|||||||
// Handle click event
|
// Handle click event
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
deadlineDate.apply {
|
||||||
|
visibility = View.VISIBLE
|
||||||
|
text = formatDate(order.updatedAt)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"canceled" -> {
|
"canceled" -> {
|
||||||
statusOrder.apply {
|
statusOrder.apply {
|
||||||
visibility = View.VISIBLE
|
visibility = View.VISIBLE
|
||||||
text = itemView.context.getString(R.string.canceled_orders)
|
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 val binding get() = _binding!!
|
||||||
private lateinit var sessionManager: SessionManager
|
private lateinit var sessionManager: SessionManager
|
||||||
|
|
||||||
|
|
||||||
private val viewModel: HistoryViewModel by viewModels {
|
private val viewModel: HistoryViewModel by viewModels {
|
||||||
BaseViewModelFactory {
|
BaseViewModelFactory {
|
||||||
val apiService = ApiConfig.getApiService(sessionManager)
|
val apiService = ApiConfig.getApiService(sessionManager)
|
||||||
@ -80,10 +79,9 @@ class OrderListFragment : Fragment() {
|
|||||||
private fun setupRecyclerView() {
|
private fun setupRecyclerView() {
|
||||||
orderAdapter = OrderHistoryAdapter(
|
orderAdapter = OrderHistoryAdapter(
|
||||||
onOrderClickListener = { order ->
|
onOrderClickListener = { order ->
|
||||||
// Handle order click
|
|
||||||
navigateToOrderDetail(order)
|
navigateToOrderDetail(order)
|
||||||
},
|
},
|
||||||
viewModel = viewModel // Pass the ViewModel to the adapter
|
viewModel = viewModel
|
||||||
)
|
)
|
||||||
|
|
||||||
orderAdapter.setFragmentStatus(status)
|
orderAdapter.setFragmentStatus(status)
|
||||||
@ -95,6 +93,7 @@ class OrderListFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun observeOrderList() {
|
private fun observeOrderList() {
|
||||||
|
// Now we only need to observe one LiveData for all cases
|
||||||
viewModel.orders.observe(viewLifecycleOwner) { result ->
|
viewModel.orders.observe(viewLifecycleOwner) { result ->
|
||||||
when (result) {
|
when (result) {
|
||||||
is ViewState.Success -> {
|
is ViewState.Success -> {
|
||||||
@ -115,13 +114,14 @@ class OrderListFragment : Fragment() {
|
|||||||
Toast.makeText(requireContext(), result.message, Toast.LENGTH_SHORT).show()
|
Toast.makeText(requireContext(), result.message, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
is ViewState.Loading -> {
|
is ViewState.Loading -> {
|
||||||
null
|
binding.progressBar.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadOrders() {
|
private fun loadOrders() {
|
||||||
|
// Simple - just call getOrderList for any status including "all"
|
||||||
viewModel.getOrderList(status)
|
viewModel.getOrderList(status)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,15 +130,15 @@ class OrderListFragment : Fragment() {
|
|||||||
) { result ->
|
) { result ->
|
||||||
if (result.resultCode == Activity.RESULT_OK) {
|
if (result.resultCode == Activity.RESULT_OK) {
|
||||||
// Refresh order list when returning with OK result
|
// Refresh order list when returning with OK result
|
||||||
viewModel.getOrderList(status)
|
loadOrders()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun navigateToOrderDetail(order: OrdersItem) {
|
private fun navigateToOrderDetail(order: OrdersItem) {
|
||||||
val intent = Intent(requireContext(), DetailOrderStatusActivity::class.java).apply {
|
val intent = Intent(requireContext(), DetailOrderStatusActivity::class.java).apply {
|
||||||
putExtra("ORDER_ID", order.orderId)
|
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)
|
detailOrderLauncher.launch(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,11 +147,11 @@ class OrderListFragment : Fragment() {
|
|||||||
_binding = null
|
_binding = null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeOrderCompletionStatus(){
|
private fun observeOrderCompletionStatus() {
|
||||||
viewModel.orderCompletionStatus.observe(viewLifecycleOwner){ result ->
|
viewModel.orderCompletionStatus.observe(viewLifecycleOwner) { result ->
|
||||||
when(result){
|
when (result) {
|
||||||
is Result.Loading -> {
|
is Result.Loading -> {
|
||||||
|
// Handle loading state if needed
|
||||||
}
|
}
|
||||||
is Result.Success -> {
|
is Result.Success -> {
|
||||||
Toast.makeText(requireContext(), "Order completed successfully!", Toast.LENGTH_SHORT).show()
|
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_delivered">Semua Pesanan </string>
|
||||||
<string name="dl_completed">Semua Pesanan </string>
|
<string name="dl_completed">Semua Pesanan </string>
|
||||||
<string name="dl_shipped">Tanggal Pesanan Sampai</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="sent_evidence">Kirim Bukti Pembayaran </string>
|
||||||
<string name="canceled_order_btn">Batalkan Pesanan </string>
|
<string name="canceled_order_btn">Batalkan Pesanan </string>
|
||||||
|
Reference in New Issue
Block a user