Skip to content

[Refunds] Update networking layer to support multiple tax rates #14002

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ import com.woocommerce.android.analytics.AnalyticsEvent.REFUND_CREATE_SUCCESS
import com.woocommerce.android.analytics.AnalyticsTracker
import com.woocommerce.android.analytics.AnalyticsTrackerWrapper
import com.woocommerce.android.extensions.adminUrlOrDefault
import com.woocommerce.android.extensions.calculateTotalSubtotal
import com.woocommerce.android.extensions.calculateTotalTaxes
import com.woocommerce.android.extensions.calculateTotals
import com.woocommerce.android.extensions.isCashPayment
import com.woocommerce.android.extensions.isEqualTo
import com.woocommerce.android.extensions.joinToString
Expand All @@ -38,9 +35,6 @@ import com.woocommerce.android.ui.payments.refunds.IssueRefundViewModel.IssueRef
import com.woocommerce.android.ui.payments.refunds.IssueRefundViewModel.IssueRefundEvent.ShowNumberPicker
import com.woocommerce.android.ui.payments.refunds.IssueRefundViewModel.IssueRefundEvent.ShowRefundConfirmation
import com.woocommerce.android.ui.payments.refunds.IssueRefundViewModel.IssueRefundEvent.ShowRefundSummary
import com.woocommerce.android.ui.payments.refunds.RefundFeeListAdapter.FeeRefundListItem
import com.woocommerce.android.ui.payments.refunds.RefundProductListAdapter.ProductRefundListItem
import com.woocommerce.android.ui.payments.refunds.RefundShippingListAdapter.ShippingRefundListItem
import com.woocommerce.android.util.CurrencyFormatter
import com.woocommerce.android.util.max
import com.woocommerce.android.util.min
Expand All @@ -56,8 +50,8 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.parcelize.Parcelize
import org.wordpress.android.fluxc.model.refunds.RefundRequestItem
import org.wordpress.android.fluxc.model.refunds.WCRefundModel
import org.wordpress.android.fluxc.model.refunds.WCRefundModel.WCRefundItem
import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooResult
import org.wordpress.android.fluxc.store.WCGatewayStore
import org.wordpress.android.fluxc.store.WCOrderStore
Expand Down Expand Up @@ -387,7 +381,7 @@ class IssueRefundViewModel @Inject constructor(
}

private suspend fun initiateRefund(): WooResult<WCRefundModel> {
val allItems = mutableListOf<WCRefundItem>()
val allItems = mutableListOf<RefundRequestItem>()
refundItems.value?.let {
it.forEach { item -> allItems.add(item.toDataModel()) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ import androidx.lifecycle.SavedStateHandle
import com.woocommerce.android.R
import com.woocommerce.android.analytics.AnalyticsEvent
import com.woocommerce.android.analytics.AnalyticsTracker
import com.woocommerce.android.extensions.calculateTotals
import com.woocommerce.android.extensions.isCashPayment
import com.woocommerce.android.model.Order
import com.woocommerce.android.model.OrderMapper
import com.woocommerce.android.model.Refund
import com.woocommerce.android.model.toAppModel
import com.woocommerce.android.tools.SelectedSite
import com.woocommerce.android.ui.payments.refunds.RefundProductListAdapter.ProductRefundListItem
import com.woocommerce.android.ui.products.addons.AddonRepository
import com.woocommerce.android.util.CoroutineDispatchers
import com.woocommerce.android.util.CurrencyFormatter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.woocommerce.android.ui.payments.refunds

import android.os.Parcelable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
Expand All @@ -9,9 +8,6 @@ import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.switchmaterial.SwitchMaterial
import com.woocommerce.android.R
import com.woocommerce.android.extensions.hide
import com.woocommerce.android.model.Order
import kotlinx.parcelize.Parcelize
import org.wordpress.android.fluxc.model.refunds.WCRefundModel.WCRefundItem
import java.math.BigDecimal

class RefundFeeListAdapter(
Expand Down Expand Up @@ -71,18 +67,4 @@ class RefundFeeListAdapter(
val switch: SwitchMaterial = view.findViewById(R.id.issueRefund_feeLineSwitch)
val divider: View = view.findViewById(R.id.issueRefund_feesDivider)
}

@Parcelize
data class FeeRefundListItem(
val feeLine: Order.FeeLine
) : Parcelable {
fun toDataModel(): WCRefundItem {
return WCRefundItem(
feeLine.id,
quantity = 1, /* Hardcoded because a fee line always has a quantity of 1 */
subtotal = feeLine.total,
totalTax = feeLine.totalTax
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.woocommerce.android.ui.payments.refunds

import android.annotation.SuppressLint
import android.os.Parcelable
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
Expand All @@ -24,12 +23,8 @@ import com.woocommerce.android.extensions.show
import com.woocommerce.android.model.Order
import com.woocommerce.android.tools.ProductImageMap
import com.woocommerce.android.ui.payments.refunds.RefundProductListAdapter.RefundViewHolder
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import org.wordpress.android.fluxc.model.refunds.WCRefundModel.WCRefundItem
import org.wordpress.android.util.PhotonUtils
import java.math.BigDecimal
import java.math.RoundingMode.HALF_UP

typealias ViewAddonClickListener = (Order.Item) -> Unit

Expand Down Expand Up @@ -175,28 +170,6 @@ class RefundProductListAdapter(
}
}

@Parcelize
data class ProductRefundListItem(
val orderItem: Order.Item,
val maxQuantity: Float = 0f,
val quantity: Int = 0,
val subtotal: String? = null,
val taxes: String? = null
) : Parcelable {
@IgnoredOnParcel
val availableRefundQuantity
get() = maxQuantity.toInt()
fun toDataModel(): WCRefundItem {
return WCRefundItem(
orderItem.itemId,
quantity,
quantity.toBigDecimal().times(orderItem.price),
orderItem.totalTax.divide(orderItem.quantity.toBigDecimal(), 2, HALF_UP)
.times(quantity.toBigDecimal())
)
}
}

class OrderItemDiffCallback(
private val oldList: List<ProductRefundListItem>,
private val newList: List<ProductRefundListItem>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.woocommerce.android.ui.payments.refunds

import android.os.Parcelable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
Expand All @@ -9,9 +8,6 @@ import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.switchmaterial.SwitchMaterial
import com.woocommerce.android.R
import com.woocommerce.android.extensions.hide
import com.woocommerce.android.model.Order
import kotlinx.parcelize.Parcelize
import org.wordpress.android.fluxc.model.refunds.WCRefundModel.WCRefundItem
import java.math.BigDecimal

class RefundShippingListAdapter(
Expand Down Expand Up @@ -71,18 +67,4 @@ class RefundShippingListAdapter(
val switch: SwitchMaterial = view.findViewById(R.id.issueRefund_shippingLineSwitch)
val divider: View = view.findViewById(R.id.issueRefund_shippingDivider)
}

@Parcelize
data class ShippingRefundListItem(
val shippingLine: Order.ShippingLine
) : Parcelable {
fun toDataModel(): WCRefundItem {
return WCRefundItem(
shippingLine.itemId,
quantity = 1, /* Hardcoded because a shipping line always has a quantity of 1 */
subtotal = shippingLine.total,
totalTax = shippingLine.totalTax
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.woocommerce.android.extensions
package com.woocommerce.android.ui.payments.refunds

import com.woocommerce.android.ui.payments.refunds.RefundProductListAdapter.ProductRefundListItem
import java.math.BigDecimal
import java.math.RoundingMode.HALF_UP

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.woocommerce.android.ui.payments.refunds

import android.os.Parcelable
import com.woocommerce.android.model.Order
import kotlinx.parcelize.Parcelize
import org.wordpress.android.fluxc.model.refunds.RefundRequestItem
import org.wordpress.android.fluxc.model.refunds.RefundRequestTax
import java.math.RoundingMode.HALF_UP

@Parcelize
data class ProductRefundListItem(
val orderItem: Order.Item,
val maxQuantity: Float = 0f,
val quantity: Int = 0,
val subtotal: String? = null,
val taxes: String? = null
) : Parcelable {
val availableRefundQuantity
get() = maxQuantity.toInt()

fun toDataModel(): RefundRequestItem {
return RefundRequestItem(
itemId = orderItem.itemId,
quantity = quantity,
refundTotal = quantity.toBigDecimal().times(orderItem.price),
refundTax = listOf(
RefundRequestTax(
taxRateId = 0L,
refundTotal = orderItem.totalTax.divide(orderItem.quantity.toBigDecimal(), 2, HALF_UP)
.times(quantity.toBigDecimal())
)
)
)
}
}

@Parcelize
data class ShippingRefundListItem(
val shippingLine: Order.ShippingLine
) : Parcelable {
fun toDataModel(): RefundRequestItem {
return RefundRequestItem(
shippingLine.itemId,
quantity = 1, /* Hardcoded because a shipping line always has a quantity of 1 */
refundTotal = shippingLine.total,
refundTax = listOf(
RefundRequestTax(
taxRateId = 0L,
refundTotal = shippingLine.totalTax
)
)
)
}
}

@Parcelize
data class FeeRefundListItem(
val feeLine: Order.FeeLine
) : Parcelable {
fun toDataModel(): RefundRequestItem {
return RefundRequestItem(
feeLine.id,
quantity = 1, /* Hardcoded because a fee line always has a quantity of 1 */
refundTotal = feeLine.total,
refundTax = listOf(
RefundRequestTax(
taxRateId = 0L,
refundTotal = feeLine.totalTax,
)
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class FeeLine {

@SerializedName("tax_status")
var taxStatus: FeeLineTaxStatus? = null

@SerializedName("taxes")
var taxes: List<LineTaxEntry>? = null
}

enum class FeeLineTaxStatus(val value: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ data class LineItem(
@SerializedName("bundled_by")
val bundledBy: String? = null,
@SerializedName("composite_parent")
val compositeParent: String? = null
val compositeParent: String? = null,
@SerializedName("taxes")
val taxes: List<LineTaxEntry>? = null,
) {
class Attribute(val key: String?, val value: String?)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.wordpress.android.fluxc.model.order

import com.google.gson.annotations.SerializedName
import java.math.BigDecimal

/**
* Tax information for a line item, it can be part of a line item or a shipping line or a fee line.
*/
data class LineTaxEntry(
@SerializedName("id")
val rateId: Long? = null,
@SerializedName("total")
private val _total: String? = null,
) {
val total: BigDecimal?
get() = _total?.toBigDecimalOrNull()
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ data class ShippingLine(
@JsonAdapter(NullStringJsonAdapter::class, nullSafe = false)
val methodId: String? = null,
@SerializedName("method_title")
val methodTitle: String? = null
val methodTitle: String? = null,
@SerializedName("taxes")
val taxes: List<LineTaxEntry>? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class RefundMapper @Inject constructor() {
total = it.total?.toBigDecimalOrNull(),
sku = it.sku,
price = it.price?.toBigDecimalOrNull(),
metaData = it.metaData
metaData = it.metaData,
taxes = it.taxes
)
} ?: emptyList(),
shippingLineItems = response.shippingLineItems ?: emptyList(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.wordpress.android.fluxc.model.refunds

import com.google.gson.annotations.SerializedName
import java.math.BigDecimal

data class RefundRequestItem(
@SerializedName("id")
val itemId: Long,
@SerializedName("quantity")
val quantity: Int?,
@SerializedName("refund_total")
val refundTotal: BigDecimal,
@SerializedName("refund_tax")
val refundTax: List<RefundRequestTax>
) {
val total: BigDecimal
get() = refundTotal + refundTax.sumOf { it.refundTotal }
}

data class RefundRequestTax(
@SerializedName("id")
val taxRateId: Long,
@SerializedName("refund_total")
val refundTotal: BigDecimal
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.wordpress.android.fluxc.model.refunds

import com.google.gson.annotations.SerializedName
import org.wordpress.android.fluxc.model.metadata.WCMetaData
import org.wordpress.android.fluxc.model.order.LineTaxEntry
import java.math.BigDecimal
import java.util.Date

Expand All @@ -26,20 +27,17 @@ data class WCRefundModel(
) {
data class WCRefundItem(
val itemId: Long,
@SerializedName("qty")
val quantity: Int,
@SerializedName("refund_total")
val subtotal: BigDecimal,
@SerializedName("refund_tax")
val totalTax: BigDecimal,
val name: String? = null,
val productId: Long? = null,
val variationId: Long? = null,
val total: BigDecimal? = null,
val sku: String? = null,
val price: BigDecimal? = null,
@SerializedName("meta_data")
val metaData: List<WCMetaData>? = null
val metaData: List<WCMetaData>? = null,
val taxes: List<LineTaxEntry>? = null
)

data class WCRefundShippingLine(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.google.gson.annotations.SerializedName
import org.wordpress.android.fluxc.generated.endpoint.WOOCOMMERCE
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.model.order.LineItem
import org.wordpress.android.fluxc.model.refunds.WCRefundModel
import org.wordpress.android.fluxc.model.refunds.RefundRequestItem
import org.wordpress.android.fluxc.model.refunds.WCRefundModel.WCRefundFeeLine
import org.wordpress.android.fluxc.model.refunds.WCRefundModel.WCRefundShippingLine
import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooNetwork
Expand Down Expand Up @@ -35,14 +35,14 @@ class RefundRestClient @Inject constructor(private val wooNetwork: WooNetwork) {
orderId: Long,
reason: String,
automaticRefund: Boolean,
items: List<WCRefundModel.WCRefundItem>,
items: List<RefundRequestItem>,
restockItems: Boolean
): WooPayload<RefundResponse> {
val body = mapOf(
"reason" to reason,
"amount" to items.sumBy { it.subtotal + it.totalTax }.toString(),
"amount" to items.sumBy { it.total }.toString(),
"api_refund" to automaticRefund.toString(),
"line_items" to items.associateBy { it.itemId },
"line_items" to items,
"restock_items" to restockItems
)
return createRefund(site, orderId, body)
Expand Down
Loading