处理数量、单价、金额之间的计算
This commit is contained in:
@@ -36,7 +36,7 @@ object NetworkModule {
|
||||
Timber.d("okhttp logger ==>${it}")
|
||||
}).apply {
|
||||
level = if (MyApp.DEBUG) {
|
||||
HttpLoggingInterceptor.Level.BASIC
|
||||
HttpLoggingInterceptor.Level.BODY
|
||||
} else {
|
||||
HttpLoggingInterceptor.Level.NONE
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ import kotlin.math.pow
|
||||
fun Float.toFormattedString(decimalPlaces: Int = 2): String {
|
||||
return when (this) {
|
||||
0f -> ""
|
||||
else -> "%.${decimalPlaces}f".format(this)
|
||||
else -> "%.${decimalPlaces}f".format(this) // 先格式化为固定位数
|
||||
// .replace(Regex("\\.?0+$"), "") // 移除末尾的0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +16,7 @@ fun Double.toFormattedString(decimalPlaces: Int = 2): String {
|
||||
return when (this) {
|
||||
0.0 -> ""
|
||||
else -> "%.${decimalPlaces}f".format(this)
|
||||
// .replace(Regex("\\.?0+$"), "")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,10 @@ fun String.isNumeric(): Boolean {
|
||||
return this.matches("-?\\d+(\\.\\d+)?".toRegex())
|
||||
}
|
||||
|
||||
fun String.toFormattedString(decimalPlaces: Int = 2): String {
|
||||
fun String?.toFormattedString(decimalPlaces: Int = 2): String {
|
||||
return when (this) {
|
||||
else -> "%.${decimalPlaces}f".format(this)
|
||||
null -> ""
|
||||
else -> "%.${decimalPlaces}s".format(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +74,14 @@ fun String.toSafeDouble(): Double {
|
||||
|
||||
fun String.isValidFloat(): Boolean {
|
||||
if (startsWith(".")) return false
|
||||
val decimalRegex = Regex("^\\d*\\.?\\d{0,2}$")
|
||||
// 处理前导零的情况
|
||||
if (length > 1 && startsWith("0")) {
|
||||
// 允许 "0" 和 "0.x" 但不允许 "00", "01", "00.1" 等
|
||||
if (!startsWith("0.")) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
val decimalRegex = Regex("^\\d+\\.?\\d{0,2}$")
|
||||
return this.matches(decimalRegex)
|
||||
// return input.matches(Regex("-?\\d+(\\.\\d+)?"))
|
||||
}
|
||||
|
||||
@@ -93,14 +93,6 @@ data class GoodsInfo(
|
||||
var unitList: List<UnitVo> = emptyList<UnitVo>()
|
||||
) : Parcelable, BaseBean() {
|
||||
|
||||
val unitDictTypeList: List<DictType>
|
||||
get() {
|
||||
return unitList.map {
|
||||
DictType(it.businessUnitId!!.toInt(), it.purchaseUnitName!!)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val goodNameStr: String
|
||||
get() {
|
||||
if (goodName == null) return "-"
|
||||
|
||||
@@ -540,7 +540,8 @@ private fun ReceiptProductEditView(
|
||||
label = "收货数量",
|
||||
value = selectedItem!!.receivedNumTemp,
|
||||
onValueChange = { value ->
|
||||
viewModel.updateCountInputState(value.isNotEmpty())
|
||||
viewModel.updateCountInputState(true)
|
||||
|
||||
selectedItem?.let {
|
||||
viewModel.updateSelectedItem(
|
||||
selectedItem!!.copy(
|
||||
@@ -557,14 +558,17 @@ private fun ReceiptProductEditView(
|
||||
|
||||
RowInputLayout(
|
||||
label = "收货单价",
|
||||
value = selectedItem!!.recUnitPriceTaxInTemp ?: "",
|
||||
value = selectedItem!!.recUnitPriceTaxInTemp,
|
||||
trailingLabel = "元",
|
||||
isInitUpdate = true,
|
||||
onValueChange = { value ->
|
||||
viewModel.updatePriceInputState(value.isNotEmpty())
|
||||
viewModel.updatePriceInputState(true)
|
||||
viewModel.updateAmountInputState(false)
|
||||
selectedItem?.let {
|
||||
viewModel.updateSelectedItem(
|
||||
selectedItem!!.copy(
|
||||
recPriceExItemTemp = "",
|
||||
recPriceExItem = 0f,
|
||||
recUnitPriceTaxInTemp = value,
|
||||
recUnitPriceTaxIn = value.toSafeFloat()
|
||||
)
|
||||
@@ -574,14 +578,18 @@ private fun ReceiptProductEditView(
|
||||
)
|
||||
RowInputLayout(
|
||||
label = "收货金额",
|
||||
value = selectedItem!!.recPriceExItemTemp ?: "",
|
||||
value = selectedItem!!.recPriceExItemTemp,
|
||||
trailingLabel = "元",
|
||||
isInitUpdate = true,
|
||||
onValueChange = { value ->
|
||||
viewModel.updateAmountInputState(value.isNotEmpty())
|
||||
viewModel.updateAmountInputState(true)
|
||||
viewModel.updatePriceInputState(false)
|
||||
selectedItem?.let {
|
||||
viewModel.updateSelectedItem(
|
||||
selectedItem!!.copy(
|
||||
recUnitPriceTaxInTemp = "",
|
||||
recUnitPriceTaxIn = 0f,
|
||||
|
||||
recPriceExItemTemp = value,
|
||||
recPriceExItem = value.toSafeFloat()
|
||||
)
|
||||
|
||||
@@ -656,7 +656,7 @@ private fun SelfProductEditView(
|
||||
isInitUpdate = true,
|
||||
onValueChange = { value ->
|
||||
Timber.d("采购数量 onValueChange value = $value")
|
||||
viewModel.updateCountInputState(value.isNotEmpty())
|
||||
viewModel.updateCountInputState(true)
|
||||
selectedItem.let {
|
||||
viewModel.updateSelectedItem(
|
||||
selectedItem!!.copy(
|
||||
@@ -676,11 +676,14 @@ private fun SelfProductEditView(
|
||||
trailingLabel = "元",
|
||||
isInitUpdate = true,
|
||||
onValueChange = { value ->
|
||||
viewModel.updatePriceInputState(value.isNotEmpty())
|
||||
viewModel.updatePriceInputState(true)
|
||||
viewModel.updateAmountInputState(false)
|
||||
selectedItem.let {
|
||||
Timber.d("goodsUnitPrice 更新 = $value")
|
||||
viewModel.updateSelectedItem(
|
||||
selectedItem!!.copy(
|
||||
goodsPrice = 0.0,
|
||||
goodsPriceTemp = "",
|
||||
goodsUnitPriceTemp = value,
|
||||
goodsUnitPrice = value.toSafeDouble()
|
||||
)
|
||||
@@ -694,10 +697,13 @@ private fun SelfProductEditView(
|
||||
trailingLabel = "元",
|
||||
isInitUpdate = true,
|
||||
onValueChange = { value ->
|
||||
viewModel.updateAmountInputState(value.isNotEmpty())
|
||||
viewModel.updateAmountInputState(true)
|
||||
viewModel.updatePriceInputState(false)
|
||||
selectedItem.let {
|
||||
viewModel.updateSelectedItem(
|
||||
selectedItem!!.copy(
|
||||
goodsUnitPrice = 0.0,
|
||||
goodsUnitPriceTemp = "",
|
||||
goodsPriceTemp = value,
|
||||
goodsPrice = value.toSafeDouble()
|
||||
)
|
||||
|
||||
@@ -108,9 +108,7 @@ fun CustomTextField(
|
||||
onClick: () -> Unit = {}, // 点击
|
||||
) {
|
||||
val containerColor = if (enabled) Color.Transparent else Gray_DCDCF0
|
||||
// var inputValue by remember { mutableStateOf(value) }
|
||||
var isUserInput by remember { mutableStateOf(false) }
|
||||
var inputValue by remember(if (isInitUpdate && !isUserInput) value else null) {
|
||||
var inputValue by remember(if (isInitUpdate) value else null) {
|
||||
mutableStateOf(value)
|
||||
}
|
||||
val focusManager = LocalFocusManager.current
|
||||
@@ -134,7 +132,6 @@ fun CustomTextField(
|
||||
textStyle = newTextStyle,
|
||||
onValueChange = { newValue ->
|
||||
Timber.d("onValueChange newValue = $newValue")
|
||||
isUserInput = newValue.isNotEmpty()
|
||||
when (inputType) {
|
||||
InputType.Number -> {
|
||||
if (newValue.isEmpty() || newValue.isValidNumber()) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
@@ -47,7 +48,9 @@ fun ReceiptUnadjustedListView(
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(30.dp)
|
||||
.padding(horizontal = 60.dp)
|
||||
.height(84.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
CustomSingleRightText(
|
||||
modifier = Modifier.weight(1f),
|
||||
@@ -89,7 +92,8 @@ fun ReceiptUnadjustedListView(
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.background(color = checkedBg)
|
||||
.padding(30.dp)
|
||||
.height(80.dp)
|
||||
.padding(horizontal = 60.dp)
|
||||
.clickable {
|
||||
onItemCheckedClick(it)
|
||||
}, verticalAlignment = Alignment.CenterVertically
|
||||
|
||||
@@ -114,23 +114,26 @@ class ReceiptViewModel @Inject constructor(
|
||||
*/
|
||||
fun updateSelectedItem(purchaseOrder: GoodsInfo?) {
|
||||
if (purchaseOrder != null) {
|
||||
purchaseOrder.receivedNum.takeIf { it != 0f }?.let { receivedNum ->
|
||||
// 计算金额 单价不为空,并且金额没有手动输入
|
||||
// if (purchaseOrder.recUnitPriceTaxIn != null && purchaseOrder.recUnitPriceTaxIn == 0f && !_amountUserInput.value) {
|
||||
if (purchaseOrder.recUnitPriceTaxIn != null && !_amountUserInput.value) {
|
||||
if (purchaseOrder.receivedNum != null && purchaseOrder.receivedNum != 0f) {
|
||||
if (purchaseOrder.recUnitPriceTaxInTemp.isNotEmpty()) { // 计算金额 单价不为空,并且金额没有手动输入
|
||||
val result =
|
||||
receivedNum.times(purchaseOrder.recUnitPriceTaxIn!!)
|
||||
purchaseOrder.receivedNum!!.times(purchaseOrder.recUnitPriceTaxIn!!)
|
||||
purchaseOrder.recPriceExItem = result.toSafeFloat()
|
||||
purchaseOrder.recPriceExItemTemp = result.toFormattedString()
|
||||
}
|
||||
// 计算单价 金额不为空,并且单价没有手动输入
|
||||
// if (purchaseOrder.recPriceExItem != null && purchaseOrder.recPriceExItem == 0f && !_priceUserInput.value) {
|
||||
if (purchaseOrder.recPriceExItem != null && !_priceUserInput.value) {
|
||||
} else if (purchaseOrder.recPriceExItemTemp.isNotEmpty()) { // 计算单价 金额不为空,并且单价没有手动输入
|
||||
val result =
|
||||
purchaseOrder.recPriceExItem!!.div(receivedNum)
|
||||
purchaseOrder.recPriceExItem!!.div(purchaseOrder.receivedNum!!)
|
||||
purchaseOrder.recUnitPriceTaxIn = result.toSafeFloat()
|
||||
purchaseOrder.recUnitPriceTaxInTemp = result.toFormattedString()
|
||||
}
|
||||
} else {
|
||||
if (_priceUserInput.value) {
|
||||
purchaseOrder.recPriceExItem = 0f
|
||||
purchaseOrder.recPriceExItemTemp = ""
|
||||
} else if (_amountUserInput.value) {
|
||||
purchaseOrder.recUnitPriceTaxIn = 0f
|
||||
purchaseOrder.recUnitPriceTaxInTemp = ""
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_countUserInput.value = false
|
||||
@@ -254,31 +257,35 @@ class ReceiptViewModel @Inject constructor(
|
||||
val finalCount = count.toSafeFloat(currentItem.unitName)
|
||||
Timber.d("startSensorScale weight = $weight, count = $count, finalCount = $finalCount, consumeValue = $consumeValue, purchaseValue = $purchaseValue")
|
||||
// 计算单价
|
||||
val finalPrice = if (count == 0.0) {
|
||||
val finalPrice = when {
|
||||
count == 0.0 -> {
|
||||
0f
|
||||
} else if (!_countUserInput.value && !_priceUserInput.value) {
|
||||
if (info.recPriceExItemTemp.isNotEmpty()) {
|
||||
}
|
||||
|
||||
_amountUserInput.value && !_priceUserInput.value -> {
|
||||
info.recPriceExItem!!.div(count).toSafeFloat()
|
||||
} else {
|
||||
0f
|
||||
}
|
||||
} else info.recUnitPriceTaxIn ?: 0f
|
||||
|
||||
else -> 0f
|
||||
}
|
||||
// 计算金额
|
||||
val finalAmount = if (count == 0.0) {
|
||||
0f
|
||||
} else if (!_countUserInput.value && !_amountUserInput.value) {
|
||||
if (info.recUnitPriceTaxInTemp.isNotEmpty()) {
|
||||
count.times(info.recUnitPriceTaxIn!!).toSafeFloat()
|
||||
} else {
|
||||
val finalAmount = when {
|
||||
count == 0.0 -> {
|
||||
0f
|
||||
}
|
||||
} else info.recPriceExItem ?: 0f
|
||||
|
||||
_priceUserInput.value && !_amountUserInput.value -> {
|
||||
count.times(info.recUnitPriceTaxIn!!).toSafeFloat()
|
||||
}
|
||||
|
||||
else -> 0f
|
||||
}
|
||||
|
||||
_selectedItem.value = info.copy(
|
||||
goodsWeight = weight.toSafeBigDecimal(),
|
||||
// 收货数量
|
||||
receivedNumTemp = if (_countUserInput.value) info.receivedNumTemp else count.toFormattedString(),
|
||||
receivedNum = if (_countUserInput.value) info.receivedNum else finalCount,
|
||||
receivedNumTemp = count.toFormattedString(),
|
||||
receivedNum = finalCount,
|
||||
// 单价
|
||||
recUnitPriceTaxIn = if (_priceUserInput.value) info.recUnitPriceTaxIn else finalPrice,
|
||||
recUnitPriceTaxInTemp = if (_priceUserInput.value) info.recUnitPriceTaxInTemp else finalPrice.toFormattedString(),
|
||||
|
||||
@@ -113,31 +113,23 @@ class SelfProcurementViewModel @Inject constructor(
|
||||
val finalPrice =
|
||||
if (count == 0.0) {
|
||||
0.0
|
||||
} else if (!_countUserInput.value && !_priceUserInput.value) {
|
||||
if (info.goodsPriceTemp.isNotEmpty()) {
|
||||
} else if (_amountUserInput.value && !_priceUserInput.value) {
|
||||
info.goodsPrice.div(count).toSafeDouble()
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
} else info.goodsUnitPrice
|
||||
} else 0.0
|
||||
|
||||
// 计算金额 单价不为空,不是数量输入 也不是金额输入
|
||||
val finalAmount =
|
||||
if (count == 0.0) {
|
||||
0.0
|
||||
} else if (!_countUserInput.value && !_amountUserInput.value) {
|
||||
if (info.goodsUnitPriceTemp.isNotEmpty()) {
|
||||
} else if (_priceUserInput.value && !_amountUserInput.value) {
|
||||
count.times(info.goodsUnitPrice).toSafeDouble()
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
} else info.goodsPrice
|
||||
} else 0.0
|
||||
Timber.d("startSensorScale finalPrice = $finalPrice, finalAmount = $finalAmount ")
|
||||
_selectedItem.value = info.copy(
|
||||
goodsWeight = weight.toSafeBigDecimal(),
|
||||
// 数量
|
||||
goodsCountTemp = if (_countUserInput.value) info.goodsCountTemp else finalCount.toFormattedString(),
|
||||
goodsCount = if (_countUserInput.value) info.goodsCount else finalCount,
|
||||
goodsCountTemp = finalCount.toFormattedString(),
|
||||
goodsCount = finalCount,
|
||||
// 单价
|
||||
goodsUnitPrice = if (_priceUserInput.value) info.goodsUnitPrice else finalPrice,
|
||||
goodsUnitPriceTemp = if (_priceUserInput.value) info.goodsUnitPriceTemp else finalPrice.toFormattedString(),
|
||||
@@ -160,25 +152,28 @@ class SelfProcurementViewModel @Inject constructor(
|
||||
|
||||
fun updateSelectedItem(purchaseOrder: PurchaseWarehouseParam?) {
|
||||
if (purchaseOrder != null) {
|
||||
purchaseOrder.goodsCount.takeIf { it != 0.0 }?.let { receivedNum ->
|
||||
// 计算金额 单价不为空,并且金额没有手动输入
|
||||
// if (purchaseOrder.goodsUnitPrice == 0.0 && !_amountUserInput.value) {
|
||||
if (!_amountUserInput.value) {
|
||||
if (purchaseOrder.goodsCount != 0.0) {
|
||||
if (purchaseOrder.goodsUnitPriceTemp.isNotEmpty()) { // 计算金额 单价不为空,并且金额没有手动输入
|
||||
Timber.d("updateSelectedItem 计算金额")
|
||||
val result =
|
||||
receivedNum.times(purchaseOrder.goodsUnitPrice)
|
||||
purchaseOrder.goodsCount.times(purchaseOrder.goodsUnitPrice)
|
||||
purchaseOrder.goodsPrice = result.toSafeDouble()
|
||||
purchaseOrder.goodsPriceTemp = result.toFormattedString()
|
||||
}
|
||||
// 计算单价 金额不为空,并且单价没有手动输入
|
||||
// if (purchaseOrder.goodsPrice == 0.0 && !_priceUserInput.value) {
|
||||
if (!_priceUserInput.value) {
|
||||
} else if (purchaseOrder.goodsPriceTemp.isNotEmpty()) { // 计算单价 金额不为空,并且单价没有手动输入
|
||||
Timber.d("updateSelectedItem 计算单价")
|
||||
val result =
|
||||
purchaseOrder.goodsPrice.div(receivedNum)
|
||||
purchaseOrder.goodsPrice.div(purchaseOrder.goodsCount)
|
||||
purchaseOrder.goodsUnitPrice = result.toSafeDouble()
|
||||
purchaseOrder.goodsUnitPriceTemp = result.toFormattedString()
|
||||
}
|
||||
} else {
|
||||
if (_priceUserInput.value) {
|
||||
purchaseOrder.goodsPrice = 0.0
|
||||
purchaseOrder.goodsPriceTemp = ""
|
||||
} else if (_amountUserInput.value) {
|
||||
purchaseOrder.goodsUnitPrice = 0.0
|
||||
purchaseOrder.goodsUnitPriceTemp = ""
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 重置输入状态
|
||||
|
||||
Reference in New Issue
Block a user