Skip to content

Commit c5653a0

Browse files
Merge pull request #14541 from woocommerce/issue/WOOMOB-887-cache-carrier-packages-data
[Shipping Labels] Cache carrier packages data
2 parents cd0480a + 33ce680 commit c5653a0

File tree

18 files changed

+4657
-339
lines changed

18 files changed

+4657
-339
lines changed

RELEASE-NOTES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
- [WEAR] Updated UserAgent of API requests to use `http.agent` System Property to fix performance issues related to WebView usage on app launch [https://github.com/woocommerce/woocommerce-android/pull/14431]
1717
- [***] POS: A new settings to customize the POS [https://github.com/woocommerce/woocommerce-android/pull/14527]
1818
- [*] [Login] Improved the detection of WooCommerce API version during login flow [https://github.com/woocommerce/woocommerce-android/pull/14524]
19+
- [*] Shipping Labels: Adds caching to the "Select a Package" screen [https://github.com/woocommerce/woocommerce-android/pull/14541]
1920
- [*] Add more filter options to orders filters sales channel [https://github.com/woocommerce/woocommerce-android/pull/14546]
2021
- [*] Automatically populate the weight field in the create shipment flow [https://github.com/woocommerce/woocommerce-android/pull/14525]
2122
- [*] [Shipping Labels] Fixed displaying incorrect hazardous material option for purchased labels [https://github.com/woocommerce/woocommerce-android/pull/14571]

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/wooshippinglabels/packages/WooShippingLabelPackageCreationViewModel.kt

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import com.woocommerce.android.analytics.AnalyticsTracker.Companion.VALUE_STARTE
1313
import com.woocommerce.android.analytics.AnalyticsTrackerWrapper
1414
import com.woocommerce.android.tools.SelectedSite
1515
import com.woocommerce.android.ui.orders.wooshippinglabels.models.StoreOptionsModel
16-
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.datasource.FetchPackagesFromStore
16+
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.datasource.FetchShippingPackages
17+
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.datasource.ObserveShippingPackages
1718
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.datasource.WooShippingLabelPackageRepository
1819
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.networking.CustomPackageCreationRequestData
1920
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.ui.Carrier
@@ -27,7 +28,9 @@ import com.woocommerce.android.viewmodel.ScopedViewModel
2728
import com.woocommerce.android.viewmodel.getStateFlow
2829
import com.woocommerce.android.viewmodel.navArgs
2930
import dagger.hilt.android.lifecycle.HiltViewModel
30-
import kotlinx.coroutines.Job
31+
import kotlinx.coroutines.flow.SharingStarted
32+
import kotlinx.coroutines.flow.collectLatest
33+
import kotlinx.coroutines.flow.shareIn
3134
import kotlinx.coroutines.flow.update
3235
import kotlinx.coroutines.launch
3336
import kotlinx.parcelize.Parcelize
@@ -39,12 +42,15 @@ class WooShippingLabelPackageCreationViewModel @Inject constructor(
3942
savedState: SavedStateHandle,
4043
private val selectedSite: SelectedSite,
4144
private val resourceProvider: ResourceProvider,
42-
private val fetchPackages: FetchPackagesFromStore,
45+
observeShippingPackages: ObserveShippingPackages,
46+
private val fetchShippingPackages: FetchShippingPackages,
4347
private val updateSavedCarrierPackages: UpdateSavedCarrierPackages,
4448
private val packageRepository: WooShippingLabelPackageRepository,
4549
private val tracker: AnalyticsTrackerWrapper,
4650
) : ScopedViewModel(savedState) {
4751
private val navArgs: WooShippingLabelPackageCreationFragmentArgs by savedState.navArgs()
52+
private val shippingPackagesFlow = observeShippingPackages()
53+
.shareIn(viewModelScope, started = SharingStarted.Lazily, replay = 1)
4854

4955
private val _viewState = savedState.getStateFlow(
5056
scope = viewModelScope,
@@ -72,20 +78,16 @@ class WooShippingLabelPackageCreationViewModel @Inject constructor(
7278
)
7379

7480
init {
75-
loadData()
76-
}
77-
78-
private fun loadData(): Job {
79-
return launch {
80-
tracker.track(AnalyticsEvent.WCS_PACKAGE_SELECTION_STEP, mapOf(KEY_STATE to VALUE_STARTED))
81-
fetchPackages().let { response ->
82-
_viewState.update { viewState -> viewState.copy(packagesState = response) }
83-
if (response is PackagesState.Data) {
81+
tracker.track(AnalyticsEvent.WCS_PACKAGE_SELECTION_STEP, mapOf(KEY_STATE to VALUE_STARTED))
82+
launch {
83+
shippingPackagesFlow.collectLatest { packages ->
84+
_viewState.update { viewState -> viewState.copy(packagesState = packages) }
85+
if (packages is PackagesState.Data) {
8486
tracker.track(AnalyticsEvent.WCS_PACKAGE_SELECTION_STEP, mapOf(KEY_STATE to "loading_success"))
85-
} else if (response is PackagesState.Error) {
87+
} else if (packages is PackagesState.Error) {
8688
tracker.track(
8789
AnalyticsEvent.WCS_PACKAGE_SELECTION_STEP,
88-
mapOf(KEY_STATE to "loading_failed", KEY_ERROR to response.error)
90+
mapOf(KEY_STATE to "loading_failed", KEY_ERROR to packages.error)
8991
)
9092
}
9193
}
@@ -148,7 +150,7 @@ class WooShippingLabelPackageCreationViewModel @Inject constructor(
148150
fun onRetryClick() {
149151
triggerEvent(ShowLoadingDialog(true))
150152
launch {
151-
loadData().join()
153+
fetchShippingPackages()
152154
triggerEvent(ShowLoadingDialog(false))
153155
}
154156
}
@@ -333,7 +335,7 @@ class WooShippingLabelPackageCreationViewModel @Inject constructor(
333335

334336
return response.takeIf { it.isError.not() }
335337
?.model?.firstOrNull()
336-
?.let { PackageData.fromPackageDAO(it) }
338+
?.let { PackageData.fromPackageEntity(it) }
337339
?.let { Result.success(it) }
338340
?: Result.failure(Throwable(response.error.type.toString()))
339341
}

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/wooshippinglabels/packages/datasource/FetchPackagesFromStore.kt

Lines changed: 0 additions & 67 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.woocommerce.android.ui.orders.wooshippinglabels.packages.datasource
2+
3+
import com.woocommerce.android.tools.SelectedSite
4+
import org.wordpress.android.fluxc.persistence.entity.WooShippingPackagesEntity
5+
import javax.inject.Inject
6+
7+
class FetchShippingPackages @Inject constructor(
8+
private val packageRepository: WooShippingLabelPackageRepository,
9+
private val selectedSite: SelectedSite
10+
) {
11+
suspend operator fun invoke(): Result<WooShippingPackagesEntity> {
12+
val response = packageRepository.fetchShippingPackages(selectedSite.get())
13+
val result = response.model
14+
return if (response.isError || result == null) {
15+
val message = response.error?.type?.name ?: "Unknown error"
16+
Result.failure(Exception(message))
17+
} else {
18+
Result.success(result)
19+
}
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package com.woocommerce.android.ui.orders.wooshippinglabels.packages.datasource
2+
3+
import com.woocommerce.android.tools.SelectedSite
4+
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.WooShippingLabelPackageCreationViewModel.PackagesState
5+
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.ui.Carrier
6+
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.ui.CarrierPackageGroup
7+
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.ui.PackageData
8+
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.ui.StoreOptionsForPackages
9+
import kotlinx.coroutines.ExperimentalCoroutinesApi
10+
import kotlinx.coroutines.flow.Flow
11+
import kotlinx.coroutines.flow.transformLatest
12+
import kotlinx.coroutines.flow.withIndex
13+
import org.wordpress.android.fluxc.persistence.entity.WooShippingPackagesEntity
14+
import org.wordpress.android.fluxc.persistence.entity.WooShippingPackagesEntity.CarrierPackageGroups
15+
import org.wordpress.android.fluxc.persistence.entity.WooShippingPackagesEntity.StoreOptions
16+
import javax.inject.Inject
17+
18+
class ObserveShippingPackages @Inject constructor(
19+
private val selectedSite: SelectedSite,
20+
private val packageRepository: WooShippingLabelPackageRepository,
21+
private val fetchShippingPackages: FetchShippingPackages
22+
) {
23+
@OptIn(ExperimentalCoroutinesApi::class)
24+
operator fun invoke(): Flow<PackagesState> = packageRepository.observeShippingPackages(selectedSite.get())
25+
.withIndex()
26+
.transformLatest { (index, entity) ->
27+
val isFirst = index == 0
28+
when {
29+
isFirst && entity == null -> {
30+
val result = fetchShippingPackages()
31+
if (result.isFailure) {
32+
emit(PackagesState.Error(result.exceptionOrNull()?.message ?: "Unknown error"))
33+
}
34+
}
35+
36+
entity == null -> emit(PackagesState.Error())
37+
else -> {
38+
emit(entity.toPackagesState())
39+
if (isFirst) {
40+
fetchShippingPackages()
41+
}
42+
}
43+
}
44+
}
45+
46+
private fun StoreOptions.toStoreOptionsForPackages() = StoreOptionsForPackages(
47+
currencySymbol = currencySymbol ?: StoreOptionsForPackages.DEFAULT.currencySymbol,
48+
dimensionUnit = dimensionUnit ?: StoreOptionsForPackages.DEFAULT.dimensionUnit,
49+
weightUnit = weightUnit ?: StoreOptionsForPackages.DEFAULT.weightUnit,
50+
originCountry = originCountry ?: StoreOptionsForPackages.DEFAULT.originCountry
51+
)
52+
53+
private fun WooShippingPackagesEntity.filterCarrierData(): Map<Carrier, List<CarrierPackageGroup>> =
54+
buildMap {
55+
carrierPackageGroups.parseCarrierData(WooShippingPackagesEntity.CarrierType.USPS)
56+
.takeIf { it.isNotEmpty() }
57+
?.let { packageGroups -> put(Carrier.USPS, packageGroups) }
58+
59+
carrierPackageGroups.parseCarrierData(WooShippingPackagesEntity.CarrierType.DHL)
60+
.takeIf { it.isNotEmpty() }
61+
?.let { packageGroups -> put(Carrier.DHL, packageGroups) }
62+
63+
carrierPackageGroups.parseCarrierData(WooShippingPackagesEntity.CarrierType.UPS)
64+
.takeIf { it.isNotEmpty() }
65+
?.let { packageGroups -> put(Carrier.UPS, packageGroups) }
66+
}
67+
68+
private fun List<CarrierPackageGroups>.parseCarrierData(
69+
carrierType: WooShippingPackagesEntity.CarrierType
70+
) = find { it.carrierType == carrierType }?.let {
71+
it.packageGroups?.mapNotNull { group ->
72+
group.description?.let { description ->
73+
CarrierPackageGroup(
74+
groupName = description,
75+
packages = group.packages?.map { packageItem ->
76+
PackageData.fromPackageEntity(packageItem)
77+
}.orEmpty()
78+
)
79+
}
80+
}
81+
} ?: emptyList()
82+
83+
private fun WooShippingPackagesEntity.toPackagesState() = PackagesState.Data(
84+
storeOptions = storeOptions.toStoreOptionsForPackages(),
85+
savedPackages = savedPackages.map { PackageData.fromPackageEntity(it) },
86+
carrierPackages = filterCarrierData()
87+
)
88+
}

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/wooshippinglabels/packages/datasource/PackageDAOs.kt

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)