Files
Inbound/app/src/main/java/com/sw/inbound/viewmodel/SelfProcurementViewModel.kt
T
zxj 3cda898756 修复了消耗值为空字符串时重量不显示的问题
修复了相机未初始化或已关闭时调用拍照报错问题
调整了未确认列表允许收货
调整了重量大于1kg时显示kg
2025-08-22 14:51:43 +08:00

405 lines
15 KiB
Kotlin

package com.sw.inbound.viewmodel
import androidx.lifecycle.viewModelScope
import com.sw.inbound.GlobalData
import com.sw.inbound.ext.toFormattedString
import com.sw.inbound.ext.toSafeBigDecimal
import com.sw.inbound.ext.toSafeDouble
import com.sw.inbound.model.request.GoodsAddParam
import com.sw.inbound.model.request.GoodsPurchaseUnitParam
import com.sw.inbound.model.request.PurchaseWarehouseParam
import com.sw.inbound.model.response.DictType
import com.sw.inbound.model.response.SearchGoodsInfo
import com.sw.inbound.repository.RemoteRepository
import com.sw.inbound.utils.ContextUtils
import com.sw.inbound.utils.FileUtils
import com.sw.inbound.utils.ToastUtils
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
/**
* 自采购
*/
@HiltViewModel
class SelfProcurementViewModel @Inject constructor(
private val repository: RemoteRepository
) : BaseViewModel(repository) {
private val _addGoodsResult = MutableStateFlow<Boolean>(false)
val addGoodsResult: StateFlow<Boolean> = _addGoodsResult
private val _addGoodsPurchaseUnitResult = MutableStateFlow<Boolean>(false)
val addGoodsPurchaseUnitResult: StateFlow<Boolean> = _addGoodsPurchaseUnitResult
private val _addToWarehouseResult = MutableStateFlow<Boolean>(false)
val addToWarehouseResult: StateFlow<Boolean> = _addToWarehouseResult
private val _selectedItem = MutableStateFlow<PurchaseWarehouseParam?>(null)
val selectedItem: StateFlow<PurchaseWarehouseParam?> = _selectedItem
// 全局仓库信息
private val _globalWarehouse = MutableStateFlow<DictType>(DictType(-1, "选择仓库"))
val globalWarehouse: StateFlow<DictType> = _globalWarehouse
// 采购列表
private val _purchaseList = MutableStateFlow<List<PurchaseWarehouseParam>>(emptyList())
val purchaseList: StateFlow<List<PurchaseWarehouseParam>> = _purchaseList
// 表单状态
private val _goodsAddParam = MutableStateFlow<GoodsAddParam>(GoodsAddParam())
val goodsAddParam: StateFlow<GoodsAddParam> = _goodsAddParam
private val _goodsAddUnitParam =
MutableStateFlow<GoodsPurchaseUnitParam>(GoodsPurchaseUnitParam())
val goodsAddUnitParam: StateFlow<GoodsPurchaseUnitParam> = _goodsAddUnitParam
// 快速添加弹窗状态
private val _showAddProductDialog = MutableStateFlow<Boolean>(false)
val showAddProductDialog: StateFlow<Boolean> = _showAddProductDialog
// 添加采购单位弹窗状态
private val _showAddPurchaseUnitDialog = MutableStateFlow<Boolean>(false)
val showAddPurchaseUnitDialog: StateFlow<Boolean> = _showAddPurchaseUnitDialog
// 是否可以修改库存单位
private val _canChangeKcUnit = MutableStateFlow<Boolean>(false)
val canChangeKcUnit: StateFlow<Boolean> = _canChangeKcUnit
// 是否可以修改消耗值
private val _canChangeConsumeValue = MutableStateFlow<Boolean>(false)
val canChangeConsumeValue: StateFlow<Boolean> = _canChangeConsumeValue
/**
* 数量是否是用户输入的值
*/
private val _countUserInput = MutableStateFlow<Boolean>(false)
/**
* 单价是否是用户输入的值
*/
private val _priceUserInput = MutableStateFlow<Boolean>(false)
/**
* 金额输入状态
*/
private val _amountUserInput = MutableStateFlow<Boolean>(false)
/**
* 更新全局仓库
*/
fun updateGlobalWarehouse(dictType: DictType) {
_globalWarehouse.value = dictType
}
override fun handleSensorScale(weight: Double) {
val currentItem = _selectedItem.value
currentItem?.let { info ->
val selectUnitType = currentItem.selectUnitType
// 用户输入数量后不再通过重量反算
if (_countUserInput.value || selectUnitType == null) {
_selectedItem.value = info.copy(
goodsWeight = weight.toSafeBigDecimal(),
)
return
}
// val selectUnitType = currentItem.selectUnitType
// if (selectUnitType == null) return@startScale
var consumeValue = selectUnitType.consumeValue?.toSafeDouble() ?: 1.0
var purchaseValue = selectUnitType.purchaseValue?.toDouble() ?: 1.0
if (consumeValue == 0.0) {
consumeValue = 1.0
}
if (purchaseValue == 0.0) {
purchaseValue = 1.0
}
val count =
weight * 1000 / consumeValue / purchaseValue
val finalCount = count.toSafeDouble(currentItem.unitName)
Timber.d("startSensorScale weight = $weight, count = $count, finalCount = $finalCount, consumeValue = $consumeValue, purchaseValue = $purchaseValue")
Timber.d("startSensorScale goodsUnitPrice = ${info.goodsUnitPrice}, goodsPrice = ${info.goodsPrice} ")
// 计算单价 金额不为空,数量也不为空, 不是数量输入 也不是单价输入
val finalPrice =
if (finalCount == 0.0) {
0.0
} else if (_amountUserInput.value && !_priceUserInput.value) {
info.goodsPrice.div(finalCount).toSafeDouble()
} else 0.0
// 计算金额 单价不为空,不是数量输入 也不是金额输入
val finalAmount =
if (finalCount == 0.0) {
0.0
} else if (_priceUserInput.value && !_amountUserInput.value) {
finalCount.times(info.goodsUnitPrice).toSafeDouble()
} else 0.0
Timber.d("startSensorScale finalPrice = $finalPrice, finalAmount = $finalAmount ")
_selectedItem.value = info.copy(
goodsWeight = weight.toSafeBigDecimal(),
// 数量
goodsCountTemp = finalCount.toFormattedString(),
goodsCount = finalCount,
// 单价
goodsUnitPrice = if (_priceUserInput.value) info.goodsUnitPrice else finalPrice,
goodsUnitPriceTemp = if (_priceUserInput.value) info.goodsUnitPriceTemp else finalPrice.toFormattedString(),
// 金额
goodsPrice = if (_amountUserInput.value) info.goodsPrice else finalAmount,
goodsPriceTemp = if (_amountUserInput.value) info.goodsPriceTemp else finalAmount.toFormattedString()
)
}
}
fun updateAddProductDialog(show: Boolean) {
_showAddProductDialog.value = show
if (!show) {
_goodsAddParam.value = GoodsAddParam()
}
}
fun updateSelectedItem(purchaseOrder: PurchaseWarehouseParam?) {
// updateLastPhotoUri(null)
if (purchaseOrder != null) {
if (purchaseOrder.goodsCount != 0.0) {
if (purchaseOrder.goodsUnitPriceTemp.isNotEmpty()) { // 计算金额 单价不为空,并且金额没有手动输入
Timber.d("updateSelectedItem 计算金额")
val result =
purchaseOrder.goodsCount.times(purchaseOrder.goodsUnitPrice)
purchaseOrder.goodsPrice = result.toSafeDouble()
purchaseOrder.goodsPriceTemp = result.toFormattedString()
} else if (purchaseOrder.goodsPriceTemp.isNotEmpty()) { // 计算单价 金额不为空,并且单价没有手动输入
Timber.d("updateSelectedItem 计算单价")
val result =
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 {
// 重置输入状态
Timber.d("重置输入状态")
_countUserInput.value = false
_priceUserInput.value = false
_amountUserInput.value = false
}
_selectedItem.value = purchaseOrder
Timber.d("updateSelectedItem 更新,goodsUnitPrice = ${_selectedItem.value?.goodsUnitPrice}, ${_selectedItem.value?.goodsUnitPriceTemp}")
}
fun updateGoodsAddParam(newState: GoodsAddParam) {
_goodsAddParam.value = newState
}
fun cleanGoodsAddParam() {
_goodsAddParam.value = GoodsAddParam()
}
// 添加订单
fun addPurchaseItem(purchaseOrder: PurchaseWarehouseParam) {
_purchaseList.update { currentList ->
currentList + purchaseOrder
}
updateSelectedItem(null)
}
// 更新订单
fun updatePurchaseItem(purchaseOrder: PurchaseWarehouseParam) {
_purchaseList.update { currentList ->
currentList.map { order ->
if (order.goodsId == purchaseOrder.goodsId) purchaseOrder else order
}
}
}
// 删除订单
fun removePurchaseOrder(orderId: Int) {
_purchaseList.update { currentList ->
currentList.filterNot { it.goodsId == orderId }
}
}
/**
* 根据位置删除物品
*/
fun removePurchaseOrderByIndex(index: Int) {
_purchaseList.update { currentList ->
currentList.toMutableList().apply {
removeAt(index)
}
}
}
// 清空列表
fun clearPurchaseOrders() {
_purchaseList.value = emptyList()
}
override fun handleIdentityItem(goodsInfo: SearchGoodsInfo.Record) {
updateSelectedItemWithSearch(goodsInfo)
}
fun updateSelectedItemWithSearch(searchFirst: SearchGoodsInfo.Record) {
val warehouse = _globalWarehouse.value
viewModelScope.launch {
updateSelectedItem(null)
delay(50)
_selectedItem.value = PurchaseWarehouseParam(
warehouseId = warehouse.id,
goodsId = searchFirst.goodsId ?: 0,
goodsName = searchFirst.goodsName,
kcUnitId = searchFirst.kcUnitId ?: 0,
unitList = searchFirst.unitVoList,
consumeValue = searchFirst.consumeValue ?: ""
)
}
}
/**
* 数量输入状态
*/
fun updateCountInputState(boolean: Boolean) {
_countUserInput.value = boolean
}
/**
* 单价输入状态
*/
fun updatePriceInputState(boolean: Boolean) {
_priceUserInput.value = boolean
}
/**
* 金额输入状态
*/
fun updateAmountInputState(boolean: Boolean) {
_amountUserInput.value = boolean
}
/**
* 添加商品
*/
fun addGoodsInfo() {
val imageUri = GlobalData.imageUri
if (imageUri == null) {
ToastUtils.showToast("请先进行图片采集")
return
}
val errInfo = _goodsAddParam.value.hasNullField()
if (errInfo != null) {
ToastUtils.showToast(errInfo)
return
}
launchWithLoading {
val uploadResponse = repository.uploadImage(imageUri)
if (!parseResponse(uploadResponse)) {
return@launchWithLoading
}
// ToastUtils.showToast("图片上传成功,${uploadResponse.data}")
GlobalData.imageUri = null
_goodsAddParam.value.relativeUrl = uploadResponse.result
val response = repository.selfPurchaseGoodsAdd(_goodsAddParam.value)
if (!parseResponse(response)) {
return@launchWithLoading
}
FileUtils.deleteFileWithUri(context = ContextUtils.getAppContext(), uri = imageUri)
_showAddProductDialog.value = false
_goodsAddParam.value = GoodsAddParam()
val searchFirst = response.result!!.records?.get(0)
searchFirst?.let {
updateSelectedItemWithSearch(searchFirst)
}
_addGoodsResult.value = true
}
}
fun updateAddPurchaseUnitDialog(show: Boolean) {
if (_selectedItem.value == null) return
_showAddPurchaseUnitDialog.value = show
if (show) {
val hasUnitId = GlobalData.unitTypeList.any { it.id == _selectedItem.value!!.kcUnitId }
_canChangeKcUnit.value = !hasUnitId
_canChangeConsumeValue.value =
_selectedItem.value!!.consumeValue.trim().isEmpty() == true
} else {
_goodsAddUnitParam.value = GoodsPurchaseUnitParam()
}
}
fun updateGoodsPurchaseUnit(goodsPurchaseUnitParam: GoodsPurchaseUnitParam?) {
if (goodsPurchaseUnitParam == null) {
_goodsAddUnitParam.value = GoodsPurchaseUnitParam()
} else {
_goodsAddUnitParam.value = goodsPurchaseUnitParam
}
}
fun updateDropdownTextChange(canChange: Boolean) {
_canChangeKcUnit.value == canChange
}
fun addGoodsPurchaseUnit() {
val errorInfo = _goodsAddUnitParam.value.hasNullField()
if (errorInfo != null) {
ToastUtils.showToast(errorInfo)
return
}
launchWithLoading {
val response = repository.selfPurchaseGoodsAddUnit(_goodsAddUnitParam.value)
if (parseResponse(response)) {
_showAddPurchaseUnitDialog.value = false
_goodsAddUnitParam.value = GoodsPurchaseUnitParam()
// _addGoodsPurchaseUnitResult.value = true
ToastUtils.showToast("采购单位添加成功")
// 通过id搜索物品,补充采购单位
val response = repository.searchGoodsInfoList(
goodsName = "${_selectedItem.value?.goodsId}"
)
if (parseResponse(response)) {
val searchList: List<SearchGoodsInfo.Record> =
response.result?.records ?: emptyList()
if (searchList.isNotEmpty()) {
val searchItem = searchList[0]
_selectedItem.value = _selectedItem.value?.copy(
unitList = searchItem.unitVoList,
kcUnitId = searchItem.kcUnitId ?: 0,
consumeValue = searchItem.consumeValue ?: ""
)
}
}
}
}
}
/**
* 物品提交入库
*/
fun addToWarehouse() {
if (_purchaseList.value.isEmpty()) {
ToastUtils.showToast("采购列表为空")
return
}
launchWithLoading {
val response = repository.selfPurchaseWarehousing(_purchaseList.value)
_addToWarehouseResult.value = parseResponse(response)
}
}
}