采购单数据合并---

This commit is contained in:
2025-10-30 19:10:38 +08:00
parent 89fabe7322
commit 980c7ade4e
10 changed files with 212 additions and 193 deletions
@@ -21,6 +21,7 @@ import com.sw.inbound.dialog.DropdownPopup
import com.sw.inbound.dialog.GoodsRecognizeDialog import com.sw.inbound.dialog.GoodsRecognizeDialog
import com.sw.inbound.dialog.GoodsSearchDialog import com.sw.inbound.dialog.GoodsSearchDialog
import com.sw.inbound.dialog.NotReceiptWarnDialog import com.sw.inbound.dialog.NotReceiptWarnDialog
import com.sw.inbound.ext.toSafeDouble
import com.sw.inbound.model.request.GoodsAddParam import com.sw.inbound.model.request.GoodsAddParam
import com.sw.inbound.model.request.PurchaseWarehouseParam import com.sw.inbound.model.request.PurchaseWarehouseParam
import com.sw.inbound.model.request.UploadInfo import com.sw.inbound.model.request.UploadInfo
@@ -275,9 +276,30 @@ abstract class GoodsListActivity : ComponentActivity() {
//isCameraReady = false //isCameraReady = false
} }
fun addGoods(it: GoodsInfo) { fun Double?.plus2(value:Double?):Double {
goodsList.add(it) return (this?:0.0) + (value?:0.0)
binding.rvGoodsList.adapter?.notifyItemInserted(goodsList.size - 1) }
fun addGoods(goods: GoodsInfo) {
val item = goodsList.firstOrNull {it.goodId == goods.goodId}
if (item == null) {
goods.isSelected = true
goodsList.add(goods)
binding.rvGoodsList.adapter?.notifyItemInserted(goodsList.size - 1)
return
}
item.isSelected = true
val finalNum = item.receivedNum.plus2(goods.receivedNum)
val finalAmount = item.recUnitPriceTaxIn.plus2(goods.recUnitPriceTaxIn)
val finalPrice = if(finalAmount == 0.toDouble() || finalNum == 0.toDouble()) 0.toDouble() else finalAmount/finalNum
item.run {
receivedNum = finalNum
receiveCountAll = finalAmount
recUnitPriceTaxIn = goods.recUnitPriceTaxIn
receivePriceIn = finalPrice.toSafeDouble()
goodsWeight = goods.goodsWeight
}
binding.rvGoodsList.adapter?.notifyItemChanged(goodsList.indexOf(item))
} }
fun searchGoods( fun searchGoods(
@@ -15,14 +15,7 @@ import kotlinx.coroutines.launch
class ReceiptActivity : GoodsListActivity() { class ReceiptActivity : GoodsListActivity() {
private val adapter by lazy { private val adapter by lazy {
ReceiptGoodsAdapter(goodsList).apply { ReceiptGoodsAdapter(goodsList)
setOnItemClickListener { adapter, view, position ->
goodsList[position].let {
it.isSelected = it.isSelected.not()
}
notifyItemChanged(position)
}
}
} }
override fun initRecyclerView() { override fun initRecyclerView() {
@@ -11,6 +11,7 @@ import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.sw.inbound.R import com.sw.inbound.R
import com.sw.inbound.databinding.ListItemReceiptGoodsBinding import com.sw.inbound.databinding.ListItemReceiptGoodsBinding
import com.sw.inbound.ext.toSafeDouble
import com.sw.inbound.model.bean.ReceiptGoodsInfo import com.sw.inbound.model.bean.ReceiptGoodsInfo
import com.sw.inbound.model.response.GoodsInfo import com.sw.inbound.model.response.GoodsInfo
import com.sw.inbound.utils.ext.dp import com.sw.inbound.utils.ext.dp
@@ -49,11 +50,11 @@ class ReceiptGoodsAdapter(var list: MutableList<GoodsInfo>) :
) )
tvGoodsName.text = item.goodName.ifNullOrBlank("-") tvGoodsName.text = item.goodName.ifNullOrBlank("-")
tvProcurementUnit.text = item.unitName.ifNullOrBlank("-") tvProcurementUnit.text = item.unitName.ifNullOrBlank("-")
tvProcurementCount.text = item.receiveCountStr.ifNullOrBlank("-") tvProcurementCount.text = item.receiveCount.ifNullOrZero("-")
tvProcurementPrice.text = item.recUnitPriceTaxInStr.ifNullOrBlank("-") tvProcurementPrice.text = item.recUnitPriceTaxIn.toSafeDouble(2).ifNullOrZero("-")
tvProcurementAmount.text = item.recPriceExItemStr.ifNullOrBlank("-") tvProcurementAmount.text = item.recPriceExItem.toSafeDouble(2).ifNullOrZero("-")
tvReceiptCount.text = item.receivedNumStr.ifNullOrBlank("-") tvReceiptCount.text = item.receivedNum.toSafeDouble(2).ifNullOrZero("-")
tvGoodsWeight.text = item.goodsWeightStr.ifNullOrBlank("-") tvGoodsWeight.text = item.goodsWeight?.toDouble().toSafeDouble(2).ifNullOrZero("-")
tvState.gone() tvState.gone()
ivState.run { ivState.run {
@@ -193,9 +193,9 @@ class GoodsStoreDialog(
//goodsPurId = binding.tvProcurementUnit.tag.toString(), //goodsPurId = binding.tvProcurementUnit.tag.toString(),
kcUnitId = binding.tvProcurementUnit.tag.toString(), kcUnitId = binding.tvProcurementUnit.tag.toString(),
unitName = unit, unitName = unit,
receiveCount = countText.toDoubleOrNull(), receivedNum = countText.toDoubleOrNull(),
recUnitPriceTaxIn = priceText.toDoubleOrNull(), recUnitPriceTaxIn = priceText.toDoubleOrNull(),
recPriceExItem = amountText.toDoubleOrNull(), receivePriceIn = amountText.toDoubleOrNull(),
goodsWeight = realWeight.toBigDecimal(), goodsWeight = realWeight.toBigDecimal(),
isLocalGoods = true isLocalGoods = true
) )
@@ -87,6 +87,7 @@ data class GoodsInfo(
// 收货数量 收货入参 // 收货数量 收货入参
var receivedNum: Double? = null, var receivedNum: Double? = null,
var receiveCountAll: Double? = null,
// 收货数量显示 // 收货数量显示
var receivedNumTemp: String = "", var receivedNumTemp: String = "",
// 重量 收货入参 // 重量 收货入参
@@ -100,7 +101,9 @@ data class GoodsInfo(
//-------------------------------------------------------- //--------------------------------------------------------
var isSelected: Boolean = false, var isSelected: Boolean = false,
var isLocalGoods: Boolean = false, var isLocalGoods: Boolean = false,
var kcUnitId: String?="" var kcUnitId: String?="",
var receivePriceIn:Double?=null
//-------------------------------------------------------- //--------------------------------------------------------
) : Parcelable, BaseBean() { ) : Parcelable, BaseBean() {
@@ -40,8 +40,8 @@ data class SearchGoodsInfo(
/** /**
* 物品id * 物品id
*/ */
@SerializedName("goodsId") // @SerializedName("goodsId")
val goodsId: String? = "", // val goodsId: String? = "",
/** /**
* 物品名称 * 物品名称
*/ */
@@ -153,12 +153,12 @@ fun PurchaseOrderScreen(
) { ) {
items(items = products, key = { it!!.id?:"" }) { items(items = products, key = { it!!.id?:"" }) {
PurchaseOrderItem(it!!) { PurchaseOrderItem(it!!) {
// navController.navigate( navController.navigate(
// Screen.ReceiptProduct.createRoute( Screen.ReceiptProduct.createRoute(
// it.id, it.id,
// it.supplierId it.supplierId
// ) )
// ) )
navController.context.startActivity<ReceiptActivity> { navController.context.startActivity<ReceiptActivity> {
putExtra(GoodsListActivity.ID,it!!.id) putExtra(GoodsListActivity.ID,it!!.id)
putExtra(GoodsListActivity.SUPPLIER_ID,it.supplierId) putExtra(GoodsListActivity.SUPPLIER_ID,it.supplierId)
@@ -1,147 +1,147 @@
package com.sw.inbound.ui.weight //package com.sw.inbound.ui.weight
//
import androidx.compose.foundation.background //import androidx.compose.foundation.background
import androidx.compose.foundation.border //import androidx.compose.foundation.border
import androidx.compose.foundation.clickable //import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement //import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box //import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth //import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding //import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentWidth //import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.lazy.grid.GridCells //import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid //import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.itemsIndexed //import androidx.compose.foundation.lazy.grid.itemsIndexed
import androidx.compose.foundation.lazy.grid.rememberLazyGridState //import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.foundation.shape.RoundedCornerShape //import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text //import androidx.compose.material3.Text
import androidx.compose.runtime.Composable //import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect //import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue //import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf //import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf //import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember //import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue //import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow //import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment //import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier //import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip //import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color //import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext //import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle //import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign //import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow //import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview //import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp //import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp //import androidx.compose.ui.unit.dp
import com.sw.inbound.model.response.SearchGoodsInfo //import com.sw.inbound.model.response.SearchGoodsInfo
import com.sw.inbound.ui.theme.AppTypography //import com.sw.inbound.ui.theme.AppTypography
import kotlinx.coroutines.flow.distinctUntilChanged //import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map //import kotlinx.coroutines.flow.map
import timber.log.Timber //import timber.log.Timber
//
//
@Preview(showBackground = true) //@Preview(showBackground = true)
@Composable //@Composable
fun testSingleGroup() { //fun testSingleGroup() {
val list = mutableListOf<SearchGoodsInfo.Record>() // val list = mutableListOf<SearchGoodsInfo.Record>()
list.add(SearchGoodsInfo.Record(goodsName = "胶东大白菜胶东大白菜胶东大白菜胶东大白菜")) // list.add(SearchGoodsInfo.Record(goodsName = "胶东大白菜胶东大白菜胶东大白菜胶东大白菜"))
for (i in 1..20) { // for (i in 1..20) {
list.add(SearchGoodsInfo.Record(goodsName = "胶东大白菜$i")) // list.add(SearchGoodsInfo.Record(goodsName = "胶东大白菜$i"))
} // }
//
// val list = arrayListOf<String>( //// val list = arrayListOf<String>(
// "胶东大白菜", //// "胶东大白菜",
// "玉田尖白菜1", //// "玉田尖白菜1",
// "玉田尖白菜2", //// "玉田尖白菜2",
// "玉田尖白菜3", //// "玉田尖白菜3",
// "玉田尖白菜4" //// "玉田尖白菜4"
// ) //// )
// SingleSelectButtonGroup(list) //// SingleSelectButtonGroup(list)
} //}
//
/** ///**
* 搜索结果列表,可选中 // * 搜索结果列表,可选中
*/ // */
@Composable //@Composable
fun SingleSelectButtonGroup( //fun SingleSelectButtonGroup(
options: List<SearchGoodsInfo.Record>, // options: List<SearchGoodsInfo.Record>,
modifier: Modifier = Modifier, // modifier: Modifier = Modifier,
onOptionSelected: (SearchGoodsInfo.Record) -> Unit, // onOptionSelected: (SearchGoodsInfo.Record) -> Unit,
horizontalSpacing: Dp = 13.dp, // horizontalSpacing: Dp = 13.dp,
verticalSpacing: Dp = 13.dp, // verticalSpacing: Dp = 13.dp,
unSelectedTextStyle: TextStyle = AppTypography.gray96a0aaTextStyle, // unSelectedTextStyle: TextStyle = AppTypography.gray96a0aaTextStyle,
onLoadMore: (Int) -> Unit = {}, // onLoadMore: (Int) -> Unit = {},
isMoreLoading: Boolean = false, // isMoreLoading: Boolean = false,
canLoadMore: Boolean = true, // canLoadMore: Boolean = true,
checkedItem: SearchGoodsInfo.Record? = null // checkedItem: SearchGoodsInfo.Record? = null
) { //) {
val context = LocalContext.current // val context = LocalContext.current
var selectedItem by remember { mutableStateOf(options.firstOrNull() ?: "") } // var selectedItem by remember { mutableStateOf(options.firstOrNull() ?: "") }
//
val lazyGridState = rememberLazyGridState() // val lazyGridState = rememberLazyGridState()
var pageNum by remember { mutableIntStateOf(1) } // var pageNum by remember { mutableIntStateOf(1) }
//
// 检测是否滚动到底部 // // 检测是否滚动到底部
LaunchedEffect(lazyGridState) { // LaunchedEffect(lazyGridState) {
snapshotFlow { lazyGridState.layoutInfo } // snapshotFlow { lazyGridState.layoutInfo }
.map { layoutInfo -> // .map { layoutInfo ->
val lastVisibleItem = layoutInfo.visibleItemsInfo.lastOrNull() // val lastVisibleItem = layoutInfo.visibleItemsInfo.lastOrNull()
lastVisibleItem?.index == layoutInfo.totalItemsCount - 1 // lastVisibleItem?.index == layoutInfo.totalItemsCount - 1
} // }
.distinctUntilChanged() // .distinctUntilChanged()
.collect { reachedEnd -> // .collect { reachedEnd ->
Timber.d("加载更多 reachedEnd = $reachedEnd, isMoreLoading = $isMoreLoading, canLoadMore = $canLoadMore") // Timber.d("加载更多 reachedEnd = $reachedEnd, isMoreLoading = $isMoreLoading, canLoadMore = $canLoadMore")
if (reachedEnd && !isMoreLoading && canLoadMore) { // if (reachedEnd && !isMoreLoading && canLoadMore) {
pageNum++ // pageNum++
onLoadMore(pageNum) // onLoadMore(pageNum)
} // }
} // }
} // }
//
// 定义颜色 // // 定义颜色
val selectedColor = Color(0xFFD9E3F9) // val selectedColor = Color(0xFFD9E3F9)
val unselectedColor = Color(0xFFDCDCF0) // val unselectedColor = Color(0xFFDCDCF0)
//
LazyVerticalGrid( // LazyVerticalGrid(
state = lazyGridState, // state = lazyGridState,
columns = GridCells.Fixed(2), // 每行2列 // columns = GridCells.Fixed(2), // 每行2列
modifier = Modifier // modifier = Modifier
.fillMaxWidth(), // .fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(horizontalSpacing), // horizontalArrangement = Arrangement.spacedBy(horizontalSpacing),
verticalArrangement = Arrangement.spacedBy(verticalSpacing) // verticalArrangement = Arrangement.spacedBy(verticalSpacing)
) { // ) {
itemsIndexed(items = options, key = { index, it -> index }) { index, item -> // itemsIndexed(items = options, key = { index, it -> index }) { index, item ->
val isChecked = item.goodsId == checkedItem?.goodsId // val isChecked = item.goodsId == checkedItem?.goodsId
Box( // Box(
modifier = modifier // modifier = modifier
.border( // .border(
width = 2.dp, // width = 2.dp,
shape = RoundedCornerShape(10.dp), // shape = RoundedCornerShape(10.dp),
color = if (isChecked) selectedColor else unselectedColor, // color = if (isChecked) selectedColor else unselectedColor,
) // )
.clip(RoundedCornerShape(10.dp)) // .clip(RoundedCornerShape(10.dp))
.background(if (isChecked) selectedColor else Color.Transparent) // .background(if (isChecked) selectedColor else Color.Transparent)
.clickable { // .clickable {
// selectedItem = item //// selectedItem = item
onOptionSelected(item) // onOptionSelected(item)
}, // },
contentAlignment = Alignment.Center // contentAlignment = Alignment.Center
// .padding(vertical = 20.dp) //// .padding(vertical = 20.dp)
) { // ) {
Text( // Text(
text = item.goodsNameStr, // text = item.goodsNameStr,
style = if (isChecked) AppTypography.BlueTextStyle else unSelectedTextStyle, // style = if (isChecked) AppTypography.BlueTextStyle else unSelectedTextStyle,
modifier = Modifier // modifier = Modifier
// .width(192.dp) //// .width(192.dp)
// .height(64.dp) //// .height(64.dp)
.wrapContentWidth() // .wrapContentWidth()
.padding(horizontal = 10.dp), // 水平内边距 // .padding(horizontal = 10.dp), // 水平内边距
textAlign = TextAlign.Center, // textAlign = TextAlign.Center,
maxLines = 1, // maxLines = 1,
overflow = TextOverflow.Ellipsis, // overflow = TextOverflow.Ellipsis,
softWrap = false // softWrap = false
) // )
} // }
} // }
} // }
} //}
@@ -132,18 +132,18 @@ abstract class BaseViewModel(
_lastPhotoUri.value = photoUri _lastPhotoUri.value = photoUri
} }
fun updateReceiptList(list: List<GoodsInfo>) { // fun updateReceiptList(list: List<GoodsInfo>) {
_receiptList.value = list.map { goods -> // _receiptList.value = list.map { goods ->
SearchGoodsInfo.Record( // SearchGoodsInfo.Record(
goodsId = goods.goodId, // goodsId = goods.goodId,
goodsName = goods.goodName // goodsName = goods.goodName
) // )
} // }
} // }
//
fun updateIdentityList(list: List<SearchGoodsInfo.Record>) { // fun updateIdentityList(list: List<SearchGoodsInfo.Record>) {
_identityListItems.value = list // _identityListItems.value = list
} // }
/** /**
* 获取识别列表 * 获取识别列表
@@ -111,13 +111,13 @@ class ReceiptViewModel @Inject constructor(
// } // }
override fun handleIdentityItem(goodsInfo: SearchGoodsInfo.Record) { override fun handleIdentityItem(goodsInfo: SearchGoodsInfo.Record) {
val firstItem = unadjustedOrders.value.find { order -> // val firstItem = unadjustedOrders.value.find { order ->
order.goodId == goodsInfo.goodsId // order.goodId == goodsInfo.goodsId
} // }
updateLastPhotoUri(null) // updateLastPhotoUri(null)
updateIdentityList(emptyList()) // updateIdentityList(emptyList())
_selectedItem.value = firstItem // _selectedItem.value = firstItem
// updateSelectedItemWithSwitch(firstItem) //// updateSelectedItemWithSwitch(firstItem)
} }
/** /**