405 lines
15 KiB
Kotlin
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)
|
|
}
|
|
}
|
|
} |