Skip to content

Commit

Permalink
Merge pull request #13071 from woocommerce/issue/add-package-creation…
Browse files Browse the repository at this point in the history
…-support

[Shipping Labels Revamp] Add Custom package creation support
  • Loading branch information
ThomazFB authored Dec 6, 2024
2 parents 373b263 + e77b101 commit 9731223
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,19 @@ fun WooShippingLabelsPackageCreationScreenPreview() {
),
createCustomPackageScreen = {
WooShippingCustomPackageCreationScreen(
packageName = "Custom Package Name",
packageType = "Envelope",
packageLength = "10",
packageWidth = "10",
packageHeight = "10",
isAddPackageEnabled = true,
isSaveAsTemplateChecked = true,
onAddPackageClick = {},
onPackageTypeClick = {},
onLengthChange = {},
onWidthChange = {},
onHeightChange = {},
onPackageNameChange = {},
onSavePackageChanged = { }
)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import com.woocommerce.android.R
import com.woocommerce.android.tools.SelectedSite
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.datasource.FetchPredefinedPackagesFromStore
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.datasource.WooShippingLabelPackageRepository
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.networking.CustomPackageCreationRequestData
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.ui.Carrier
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.ui.CarrierPackageGroup
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.ui.CarrierPackageSelection
Expand All @@ -20,13 +23,16 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
import org.wordpress.android.fluxc.model.SiteModel
import javax.inject.Inject

@HiltViewModel
class WooShippingLabelPackageCreationViewModel @Inject constructor(
savedState: SavedStateHandle,
private val selectedSite: SelectedSite,
private val resourceProvider: ResourceProvider,
private val fetchPredefinedPackages: FetchPredefinedPackagesFromStore
private val fetchPredefinedPackages: FetchPredefinedPackagesFromStore,
private val packageRepository: WooShippingLabelPackageRepository
) : ScopedViewModel(savedState) {

private val _viewState = savedState.getStateFlow(
Expand Down Expand Up @@ -97,9 +103,13 @@ class WooShippingLabelPackageCreationViewModel @Inject constructor(
?.let { triggerEvent(PackageSelected(it)) }
}

fun onAddCustomPackageClick() {
_viewState.value.customPackageCreationData
.toPackageData()
fun onAddCustomPackageClick(savePackageAsTemplate: Boolean) {
val customPackage = _viewState.value.customPackageCreationData
selectedSite.getOrNull()
?.takeIf { savePackageAsTemplate }
?.let { customPackage.submitToStore(it) }

customPackage.toPackageData()
.let { triggerEvent(PackageSelected(it)) }
}

Expand Down Expand Up @@ -135,6 +145,13 @@ class WooShippingLabelPackageCreationViewModel @Inject constructor(
}
}

fun onPackageNameChange(name: String) {
_viewState.update {
val newPackageData = it.customPackageCreationData.copy(name = name)
it.copy(customPackageCreationData = newPackageData)
}
}

fun onSavePackageChanged(checked: Boolean) {
_viewState.update {
val newPackageData = it.customPackageCreationData.copy(saveAsTemplate = checked)
Expand Down Expand Up @@ -163,6 +180,24 @@ class WooShippingLabelPackageCreationViewModel @Inject constructor(
?.let { set(it, updatedPackage) }
}

private fun CustomPackageCreationData.submitToStore(site: SiteModel) {
launch {
packageRepository.createCustomPackage(
site = site,
requestData = this@submitToStore.let {
CustomPackageCreationRequestData(
name = it.name,
isLetter = it.type == PackageType.ENVELOPE,
innerDimensions = it.dimensions,
boxWeight = 0.0,
isUserDefined = true,
maxWeight = 0.0
)
}.let { listOf(it) }
)
}
}

@Parcelize
data class ViewState(
val pageTabs: List<PageTab> = emptyList(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.woocommerce.android.ui.orders.wooshippinglabels.packages.datasource.C
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.datasource.CarrierType.USPS
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.networking.CarrierPackageGroupDTO
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.networking.CarrierPredefinedPackagesDTO
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.networking.CustomPackageCreationResponse
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.networking.CustomPackageDTO
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.networking.PackageResponse
import javax.inject.Inject
Expand All @@ -18,6 +19,17 @@ class WooShippingLabelPackageMapper @Inject constructor() {
)
}

operator fun invoke(resopnse: CustomPackageCreationResponse): List<PackageDAO> {
return resopnse.custom?.map {
PackageDAO(
id = it.id.orEmpty(),
name = it.name.orEmpty(),
dimensions = it.dimensions.orEmpty(),
isLetter = it.isLetter ?: false
)
} ?: emptyList()
}

private fun mapSavedPackages(savedResponse: List<CustomPackageDTO>): List<PackageDAO> {
return savedResponse.map {
PackageDAO(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.woocommerce.android.ui.orders.wooshippinglabels.packages.datasource

import com.woocommerce.android.tools.SelectedSite
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.networking.CustomPackageCreationRequestData
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.networking.WooShippingLabelPackageRestClient
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooResult
Expand All @@ -21,4 +22,14 @@ class WooShippingLabelPackageRepository @Inject constructor(
?.let { WooResult(it) }
?: WooResult(error)
}

suspend fun createCustomPackage(
site: SiteModel = selectedSite.get(),
requestData: List<CustomPackageCreationRequestData>
) = with(packageRestClient.postNewCustomPackage(site, requestData)) {
result.takeIf { isError.not() }
?.let { packageMapper(it) }
?.let { WooResult(it) }
?: WooResult(error)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@ package com.woocommerce.android.ui.orders.wooshippinglabels.packages.networking

import com.google.gson.annotations.SerializedName

class CustomPackageCreationResponse {
val custom: List<CustomPackageDTO>? = null
}

data class CustomPackageCreationRequestData(
val name: String? = null,
@SerializedName("is_letter") val isLetter: Boolean? = null,
@SerializedName("inner_dimensions") val innerDimensions: String? = null,
@SerializedName("box_weight") val boxWeight: Double? = null,
@SerializedName("is_user_defined") val isUserDefined: Boolean? = null,
@SerializedName("max_weight") val maxWeight: Double? = null
)

class PackageResponse {
val storeOptions: PackageStoreOptionsDTO? = null
val packages: PackagesInfoDTO? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,26 @@ class WooShippingLabelPackageRestClient @Inject constructor(
suspend fun fetchShippingLabelPackages(
site: SiteModel
): WooPayload<PackageResponse> {
val url = "/wcshipping/v1/packages"

return wooNetwork.executeGetGsonRequest(
site = site,
path = url,
path = URL,
clazz = PackageResponse::class.java,
).toWooPayload()
}

suspend fun postNewCustomPackage(
site: SiteModel,
requestData: List<CustomPackageCreationRequestData>
): WooPayload<CustomPackageCreationResponse> {
return wooNetwork.executePostGsonRequest(
site = site,
path = URL,
body = mapOf("custom" to requestData),
clazz = CustomPackageCreationResponse::class.java,
).toWooPayload()
}

companion object {
private const val URL = "/wcshipping/v1/packages"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.woocommerce.android.ui.orders.wooshippinglabels.packages.ui

import android.os.Parcelable
import com.woocommerce.android.R
import com.woocommerce.android.extensions.isNotNullOrEmpty
import com.woocommerce.android.ui.orders.wooshippinglabels.packages.WooShippingLabelPackageCreationViewModel.PackageType
import kotlinx.parcelize.Parcelize

Expand Down Expand Up @@ -38,10 +39,21 @@ data class CustomPackageCreationData(
val length: String,
val width: String,
val height: String,
val saveAsTemplate: Boolean
val saveAsTemplate: Boolean,
val name: String? = null
) : Parcelable {
val isValid: Boolean
get() = height.isNotEmpty() && length.isNotEmpty() && width.isNotEmpty()
get() = height.isNotEmpty() && length.isNotEmpty() && width.isNotEmpty() && isTemplateConfigured

val dimensions: String
get() = "$length x $width x $height"

private val isTemplateConfigured: Boolean
get() {
if (saveAsTemplate.not()) return true

return name.isNotNullOrEmpty()
}

fun toPackageData(dimensionUnit: String = "cm") = PackageData(
name = "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.Checkbox
import androidx.compose.material.CheckboxDefaults
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
Expand All @@ -35,32 +37,38 @@ fun WooShippingCustomPackageCreationScreen(viewModel: WooShippingLabelPackageCre

WooShippingCustomPackageCreationScreen(
packageType = packageType,
packageName = viewState?.customPackageCreationData?.name.orEmpty(),
packageHeight = viewState?.customPackageCreationData?.height.orEmpty(),
packageLength = viewState?.customPackageCreationData?.length.orEmpty(),
packageWidth = viewState?.customPackageCreationData?.width.orEmpty(),
isAddPackageEnabled = viewState?.customPackageCreationData?.isValid ?: false,
isSaveAsTemplateChecked = viewState?.customPackageCreationData?.saveAsTemplate ?: false,
onAddPackageClick = viewModel::onAddCustomPackageClick,
onPackageTypeClick = viewModel::onPackageTypeSpinnerClick,
onLengthChange = viewModel::onLengthChange,
onWidthChange = viewModel::onWidthChange,
onHeightChange = viewModel::onHeightChange,
onPackageNameChange = viewModel::onPackageNameChange,
onSavePackageChanged = viewModel::onSavePackageChanged
)
}

@Composable
fun WooShippingCustomPackageCreationScreen(
modifier: Modifier = Modifier,
packageName: String,
packageType: String,
packageLength: String,
packageWidth: String,
packageHeight: String,
isAddPackageEnabled: Boolean,
onAddPackageClick: () -> Unit,
isSaveAsTemplateChecked: Boolean,
onAddPackageClick: (saveAsTemplate: Boolean) -> Unit,
onPackageTypeClick: () -> Unit,
onLengthChange: (String) -> Unit,
onWidthChange: (String) -> Unit,
onHeightChange: (String) -> Unit,
onPackageNameChange: (String) -> Unit,
onSavePackageChanged: (Boolean) -> Unit
) {
Column(
Expand Down Expand Up @@ -120,13 +128,32 @@ fun WooShippingCustomPackageCreationScreen(
text = stringResource(id = R.string.woo_shipping_labels_package_creation_save_package_option),
modifier = modifier.align(Alignment.CenterVertically)
)
Checkbox(checked = false, onCheckedChange = onSavePackageChanged)
Checkbox(
checked = isSaveAsTemplateChecked,
onCheckedChange = onSavePackageChanged,
colors = CheckboxDefaults.colors(
checkedColor = MaterialTheme.colors.primary,
uncheckedColor = MaterialTheme.colors.onSurface
),
)
}
if (isSaveAsTemplateChecked) {
Column(modifier = modifier) {
WCOutlinedTextField(
value = packageName,
onValueChange = onPackageNameChange,
label = stringResource(id = R.string.woo_shipping_labels_package_creation_package_name),
singleLine = true,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
modifier = modifier.fillMaxWidth()
)
}
}
}
Button(
modifier = modifier.fillMaxWidth(),
enabled = isAddPackageEnabled,
onClick = onAddPackageClick
onClick = { onAddPackageClick(isSaveAsTemplateChecked) }
) {
Text(stringResource(id = R.string.woo_shipping_labels_package_creation_add_package))
}
Expand All @@ -138,16 +165,19 @@ fun WooShippingCustomPackageCreationScreen(
fun PreviewWooShippingCustomPackageCreationScreen() {
WooThemeWithBackground {
WooShippingCustomPackageCreationScreen(
packageName = "Custom Package",
packageType = "Box",
packageLength = "10",
packageWidth = "10",
packageHeight = "10",
isAddPackageEnabled = true,
isSaveAsTemplateChecked = true,
onAddPackageClick = {},
onPackageTypeClick = {},
onLengthChange = {},
onWidthChange = {},
onHeightChange = {},
onPackageNameChange = {},
onSavePackageChanged = {}
)
}
Expand Down
1 change: 1 addition & 0 deletions WooCommerce/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4377,6 +4377,7 @@
<string name="woo_shipping_labels_package_creation_length">Length</string>
<string name="woo_shipping_labels_package_creation_width">Width</string>
<string name="woo_shipping_labels_package_creation_height">Height</string>
<string name="woo_shipping_labels_package_creation_package_name">Package Name</string>
<string name="woo_shipping_labels_package_creation_save_package_option">Save this as a new package template</string>
<string name="woo_shipping_labels_package_creation_add_package">Add Package</string>
<string name="woo_shipping_labels_package_creation_box_type">Box</string>
Expand Down
Loading

0 comments on commit 9731223

Please sign in to comment.