采购单数据合并---

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)
}
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) 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)
//}
//
///**
// * 搜索结果列表,可选中
// */
//@Composable
//fun SingleSelectButtonGroup(
// options: List<SearchGoodsInfo.Record>,
// modifier: Modifier = Modifier,
// onOptionSelected: (SearchGoodsInfo.Record) -> Unit,
// horizontalSpacing: Dp = 13.dp,
// verticalSpacing: Dp = 13.dp,
// unSelectedTextStyle: TextStyle = AppTypography.gray96a0aaTextStyle,
// onLoadMore: (Int) -> Unit = {},
// isMoreLoading: Boolean = false,
// canLoadMore: Boolean = true,
// checkedItem: SearchGoodsInfo.Record? = null
//) {
// val context = LocalContext.current
// var selectedItem by remember { mutableStateOf(options.firstOrNull() ?: "") }
//
// val lazyGridState = rememberLazyGridState()
// var pageNum by remember { mutableIntStateOf(1) }
//
// // 检测是否滚动到底部
// LaunchedEffect(lazyGridState) {
// snapshotFlow { lazyGridState.layoutInfo }
// .map { layoutInfo ->
// val lastVisibleItem = layoutInfo.visibleItemsInfo.lastOrNull()
// lastVisibleItem?.index == layoutInfo.totalItemsCount - 1
// }
// .distinctUntilChanged()
// .collect { reachedEnd ->
// Timber.d("加载更多 reachedEnd = $reachedEnd, isMoreLoading = $isMoreLoading, canLoadMore = $canLoadMore")
// if (reachedEnd && !isMoreLoading && canLoadMore) {
// pageNum++
// onLoadMore(pageNum)
// }
// }
// }
//
// // 定义颜色
// val selectedColor = Color(0xFFD9E3F9)
// val unselectedColor = Color(0xFFDCDCF0)
//
// LazyVerticalGrid(
// state = lazyGridState,
// columns = GridCells.Fixed(2), // 每行2列
// modifier = Modifier
// .fillMaxWidth(),
// horizontalArrangement = Arrangement.spacedBy(horizontalSpacing),
// verticalArrangement = Arrangement.spacedBy(verticalSpacing)
// ) {
// itemsIndexed(items = options, key = { index, it -> index }) { index, item ->
// val isChecked = item.goodsId == checkedItem?.goodsId
// Box(
// modifier = modifier
// .border(
// width = 2.dp,
// shape = RoundedCornerShape(10.dp),
// color = if (isChecked) selectedColor else unselectedColor,
// ) // )
// SingleSelectButtonGroup(list) // .clip(RoundedCornerShape(10.dp))
} // .background(if (isChecked) selectedColor else Color.Transparent)
// .clickable {
/** //// selectedItem = item
* 搜索结果列表,可选中 // onOptionSelected(item)
*/ // },
@Composable // contentAlignment = Alignment.Center
fun SingleSelectButtonGroup( //// .padding(vertical = 20.dp)
options: List<SearchGoodsInfo.Record>, // ) {
modifier: Modifier = Modifier, // Text(
onOptionSelected: (SearchGoodsInfo.Record) -> Unit, // text = item.goodsNameStr,
horizontalSpacing: Dp = 13.dp, // style = if (isChecked) AppTypography.BlueTextStyle else unSelectedTextStyle,
verticalSpacing: Dp = 13.dp, // modifier = Modifier
unSelectedTextStyle: TextStyle = AppTypography.gray96a0aaTextStyle, //// .width(192.dp)
onLoadMore: (Int) -> Unit = {}, //// .height(64.dp)
isMoreLoading: Boolean = false, // .wrapContentWidth()
canLoadMore: Boolean = true, // .padding(horizontal = 10.dp), // 水平内边距
checkedItem: SearchGoodsInfo.Record? = null // textAlign = TextAlign.Center,
) { // maxLines = 1,
val context = LocalContext.current // overflow = TextOverflow.Ellipsis,
var selectedItem by remember { mutableStateOf(options.firstOrNull() ?: "") } // softWrap = false
// )
val lazyGridState = rememberLazyGridState() // }
var pageNum by remember { mutableIntStateOf(1) } // }
// }
// 检测是否滚动到底部 //}
LaunchedEffect(lazyGridState) {
snapshotFlow { lazyGridState.layoutInfo }
.map { layoutInfo ->
val lastVisibleItem = layoutInfo.visibleItemsInfo.lastOrNull()
lastVisibleItem?.index == layoutInfo.totalItemsCount - 1
}
.distinctUntilChanged()
.collect { reachedEnd ->
Timber.d("加载更多 reachedEnd = $reachedEnd, isMoreLoading = $isMoreLoading, canLoadMore = $canLoadMore")
if (reachedEnd && !isMoreLoading && canLoadMore) {
pageNum++
onLoadMore(pageNum)
}
}
}
// 定义颜色
val selectedColor = Color(0xFFD9E3F9)
val unselectedColor = Color(0xFFDCDCF0)
LazyVerticalGrid(
state = lazyGridState,
columns = GridCells.Fixed(2), // 每行2列
modifier = Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(horizontalSpacing),
verticalArrangement = Arrangement.spacedBy(verticalSpacing)
) {
itemsIndexed(items = options, key = { index, it -> index }) { index, item ->
val isChecked = item.goodsId == checkedItem?.goodsId
Box(
modifier = modifier
.border(
width = 2.dp,
shape = RoundedCornerShape(10.dp),
color = if (isChecked) selectedColor else unselectedColor,
)
.clip(RoundedCornerShape(10.dp))
.background(if (isChecked) selectedColor else Color.Transparent)
.clickable {
// selectedItem = item
onOptionSelected(item)
},
contentAlignment = Alignment.Center
// .padding(vertical = 20.dp)
) {
Text(
text = item.goodsNameStr,
style = if (isChecked) AppTypography.BlueTextStyle else unSelectedTextStyle,
modifier = Modifier
// .width(192.dp)
// .height(64.dp)
.wrapContentWidth()
.padding(horizontal = 10.dp), // 水平内边距
textAlign = TextAlign.Center,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
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)
} }
/** /**