Files
Inbound/app/src/main/java/com/sw/inbound/viewmodel/ReceiptViewModel.kt
T

385 lines
13 KiB
Kotlin

package com.sw.inbound.viewmodel
import android.net.Uri
import android.util.Log
import androidx.lifecycle.viewModelScope
import com.sw.inbound.ext.toFormattedString
import com.sw.inbound.ext.toSafeBigDecimal
import com.sw.inbound.ext.toSafeDouble
import com.sw.inbound.ext.toSafeFloat
import com.sw.inbound.model.request.GoodsAddParam
import com.sw.inbound.model.request.PurchaseWarehouseParam
import com.sw.inbound.model.request.UploadInfo
import com.sw.inbound.model.response.DictType
import com.sw.inbound.model.response.GoodsInfo
import com.sw.inbound.model.response.PurchaseInfo
import com.sw.inbound.model.response.SearchGoodsInfo
import com.sw.inbound.repository.RemoteRepository
import com.sw.inbound.utils.ToastUtils
import com.sw.inbound.utils.ext.toJsonString
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
/**
* 收货
*/
@HiltViewModel
class ReceiptViewModel @Inject constructor(
private val repository: RemoteRepository
) : BaseViewModel(repository) {
// 调整状态
private val _adjustState = MutableStateFlow<Boolean>(true)
val adjustState: StateFlow<Boolean> = _adjustState
private val _showReceiptDialog = MutableStateFlow(false)
val showReceiptDialog: StateFlow<Boolean> = _showReceiptDialog
// 当前要收货的供应商
private val _currentPurchaseInfo = MutableStateFlow<PurchaseInfo?>(null)
val currentPurchaseInfo: StateFlow<PurchaseInfo?> = _currentPurchaseInfo
private val _orders = MutableStateFlow<List<GoodsInfo>>(emptyList())
val orders: StateFlow<List<GoodsInfo>> = _orders.asStateFlow()
fun initOrders() {
_orders.value = _currentPurchaseInfo.value?.receiveGoodsInfoList ?: emptyList()
}
// 已调整列表
val adjustedOrders: StateFlow<List<GoodsInfo>> = _orders
.map { orders -> orders.filter { it.isAdjusted } }
.stateIn(viewModelScope, SharingStarted.Lazily, emptyList())
// 未调整列表
val unadjustedOrders: StateFlow<List<GoodsInfo>> = _orders
.map { orders -> orders.filter { !it.isAdjusted } }
.stateIn(viewModelScope, SharingStarted.Lazily, emptyList())
// 选中的商品
private val _selectedItem = MutableStateFlow<GoodsInfo?>(null)
val selectedItem: StateFlow<GoodsInfo?> = _selectedItem
// 收货请求结果
private val _receiptResult = MutableStateFlow<Boolean>(false)
val receiptResult: StateFlow<Boolean> = _receiptResult
// 物品数量 是否由用户输入
private val _countUserInput = MutableStateFlow<Boolean>(false)
private val _priceUserInput = MutableStateFlow<Boolean>(false)
private val _amountUserInput = MutableStateFlow<Boolean>(false)
/**
* 更新调整状态
* @param isAdjustState true 已调整 false 未调整
*/
fun updateAdjustState(isAdjustState: Boolean) {
_adjustState.value = isAdjustState
}
fun StateFlow<List<GoodsInfo>>.getValidOrders(): List<GoodsInfo> {
return this.value.filter { it.goodId != null }
}
/**
* 更新收货提示弹窗
*/
fun updateReceiptDialog(showDialog: Boolean) {
if (_orders.getValidOrders().isEmpty()) {
ToastUtils.showToast("订单为空或包含异常数据")
return
}
// if (!unadjustedOrders.value.isEmpty()) {
// ToastUtils.showToast("请先确认物品信息")
// return
// }
_showReceiptDialog.value = showDialog
}
// fun updateSelectedItemWithSwitch(purchaseOrder: GoodsInfo?) {
// viewModelScope.launch {
// updateSelectedItem(purchaseOrder)
// }
// }
override fun handleIdentityItem(goodsInfo: SearchGoodsInfo.Record) {
val firstItem = unadjustedOrders.value.find { order ->
order.goodId == goodsInfo.goodsId
}
updateLastPhotoUri(null)
updateIdentityList(emptyList())
_selectedItem.value = firstItem
// updateSelectedItemWithSwitch(firstItem)
}
/**
* 更新选中的item
*/
// fun updateSelectedItem(purchaseOrder: GoodsInfo?) {
// if (purchaseOrder != null) {
// if (purchaseOrder.receivedNum != null && purchaseOrder.receivedNum != 0f) {
// if (purchaseOrder.newRecUnitPriceTaxInTemp.isNotEmpty()) { // 计算金额 单价不为空,并且金额没有手动输入
// val result =
// purchaseOrder.receivedNum!!.times(purchaseOrder.newRecUnitPriceTaxIn!!)
// purchaseOrder.recPriceExItem = result.toSafeFloat()
// purchaseOrder.recPriceExItemTemp = result.toFormattedString()
// } else if (purchaseOrder.recPriceExItemTemp.isNotEmpty()) { // 计算单价 金额不为空,并且单价没有手动输入
// val result =
// purchaseOrder.recPriceExItem!!.div(purchaseOrder.receivedNum!!)
// purchaseOrder.newRecUnitPriceTaxIn = result.toSafeFloat()
// purchaseOrder.newRecUnitPriceTaxInTemp = result.toFormattedString()
// }
// } else {
// if (_priceUserInput.value) {
// purchaseOrder.recPriceExItem = 0f
// purchaseOrder.recPriceExItemTemp = ""
// } else if (_amountUserInput.value) {
// purchaseOrder.newRecUnitPriceTaxIn = 0f
// purchaseOrder.newRecUnitPriceTaxInTemp = ""
// }
// }
// } else {
// _countUserInput.value = false
// _priceUserInput.value = false
// _amountUserInput.value = false
// }
// _selectedItem.value = purchaseOrder
// }
fun getReceiveDetail(id: String, action: (PurchaseInfo?) -> Unit = {}) {
launchWithLoading {
val response = repository.getReceiveDetail(id)
if (parseResponse(response)) {
action(response.result)
_currentPurchaseInfo.value = response.result
initOrders()
}
}
}
/**
* 更新当前供应商信息
*/
fun updateCurrentPurchaseInfo(purchaseInfo: PurchaseInfo?) {
_currentPurchaseInfo.value = purchaseInfo
}
// 添加订单
fun addPurchaseItem(purchaseOrder: GoodsInfo) {
_orders.update { currentList ->
// 当已经添加过则忽略
if (currentList.any { it.goodId == purchaseOrder.goodId }) {
currentList
} else {
currentList + purchaseOrder
}
}
}
// 更新订单
fun updatePurchaseItem(purchaseOrder: GoodsInfo) {
_orders.update { currentList ->
currentList.map { order ->
if (order.id == purchaseOrder.id) purchaseOrder else order
}
}
}
/**
* 有异常的订单数量
*/
fun hasWrongCount(): Boolean {
return _orders.value.any {
it.receiveCount != it.receivedNum
}
}
/**
* 更新所有商品仓库
*/
// fun updateAllPurchaseStore(warehouse: DictType, predicate: (GoodsInfo) -> Boolean = { true }) {
// _orders.update { currentList ->
// currentList.map { order ->
// if (predicate(order)) order.copy(
// warehouseId = warehouse.id,
// warehouseName = warehouse.value
// ) else order
// }
// }
// }
// 删除订单
// fun removePurchaseOrder(orderId: Int) {
// _orders.update { current ->
// current.filterNot { it.goodId == orderId }
// }
// }
// 清空列表
fun clearPurchaseOrders() {
_orders.value = emptyList()
}
/**
* 更新数量输入状态
*/
fun updateCountInputState(boolean: Boolean) {
_countUserInput.value = boolean
}
/**
* 更新单价输入状态
*/
fun updatePriceInputState(boolean: Boolean) {
_priceUserInput.value = boolean
}
/**
* 更新金额输入状态
*/
fun updateAmountInputState(boolean: Boolean) {
_amountUserInput.value = boolean
}
//private var weightCallback: ((Int) -> Unit)? = null
//fun readWeight(callback: (Int) -> Unit) {
// weightCallback = callback
//}
override fun handleSensorScale(weight: Double) {
// weightCallback?.invoke((weight * 1000).toInt())
// val currentItem = _selectedItem.value
//
// currentItem?.let { info ->
// // 用户输入数量后不再通过重量反算
// if (_countUserInput.value) {
// _selectedItem.value = info.copy(
// goodsWeight = weight.toSafeBigDecimal(),
// )
// return
// }
// var consumeValue = currentItem.consumeValue?.toSafeDouble() ?: 1.0
// var purchaseValue = currentItem.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.toSafeFloat(currentItem.unitName)
// Timber.d("startSensorScale weight = $weight, count = $count, finalCount = $finalCount, consumeValue = $consumeValue, purchaseValue = $purchaseValue")
// // 计算单价
// val finalPrice = when {
// finalCount == 0f -> {
// 0f
// }
//
// _amountUserInput.value && !_priceUserInput.value -> {
// info.recPriceExItem!!.div(finalCount).toSafeFloat()
// }
//
// else -> 0f
// }
// // 计算金额
// val finalAmount = when {
// finalCount == 0f -> {
// 0f
// }
//
// _priceUserInput.value && !_amountUserInput.value -> {
// finalCount.times(info.newRecUnitPriceTaxIn!!).toSafeFloat()
// }
//
// else -> 0f
// }
//
// _selectedItem.value = info.copy(
// goodsWeight = weight.toSafeBigDecimal(),
// // 收货数量
// receivedNumTemp = finalCount.toFormattedString(),
// receivedNum = finalCount,
// // 单价
// newRecUnitPriceTaxIn = if (_priceUserInput.value) info.newRecUnitPriceTaxIn else finalPrice,
// newRecUnitPriceTaxInTemp = if (_priceUserInput.value) info.newRecUnitPriceTaxInTemp else finalPrice.toFormattedString(),
// // 金额
// recPriceExItem = if (_amountUserInput.value) info.recPriceExItem else finalAmount,
// recPriceExItemTemp = if (_amountUserInput.value) info.recPriceExItemTemp else finalAmount.toFormattedString(),
// )
// }
}
fun partialReceipt(uploadInfo: UploadInfo) {
launchWithLoading {
val response = repository.partialReceipt(uploadInfo)
if (parseResponse(response)) {
ToastUtils.showToast("部分收货成功")
_receiptResult.value = true
}
}
}
fun confirmReceipt(uploadInfo: UploadInfo) {
launchWithLoading {
val response = repository.confirmReceipt(uploadInfo)
if (parseResponse(response)) {
ToastUtils.showToast("收货成功")
_receiptResult.value = true
}
}
}
fun confirmReceipt(uploadInfo: UploadInfo, callback: (Boolean) -> Unit) {
launchWithLoading {
val resp = repository.confirmReceipt(uploadInfo)
callback(resp.data == true)
}
}
fun addToWarehouse(list: List<PurchaseWarehouseParam>, callback: (Boolean) -> Unit) {
launchWithLoading {
val resp = repository.selfPurchaseWarehousing(list)
callback(resp.data == true)
}
}
fun uploadImage(imageUri: Uri, callback: (String?) -> Unit) {
launchWithLoading {
val resp = repository.uploadImage(imageUri)
if (!parseResponse(resp)) {
callback(null)
return@launchWithLoading
}
callback(resp.data)
}
}
fun createNewGoods(imageUri: Uri? = null, param: GoodsAddParam, callback: (Boolean) -> Unit) {
launchWithLoading {
if (imageUri != null) {
val resp = repository.uploadImage(imageUri)
if (!parseResponse(resp)) {
callback(false)
return@launchWithLoading
}
param.relativeUrl = resp.data
}
Timber.tag("ReceiptViewModel").d("createNewGoods入参:${param.toJsonString()}")
val response = repository.selfPurchaseGoodsAdd(param)
if (!parseResponse(response)) {
callback(false)
return@launchWithLoading
}
callback(true)
}
}
}