style:出库单据-添加锁定库存数量逻辑

main
黄伟杰 2 days ago
parent f0768cc63d
commit 5091775bc4

@ -14,6 +14,7 @@ export interface PalletVO {
planCode?: string
productId?: number | string
productCount?: number | string
lockedPackageCount?: number | string
qrcode?: string
templateJson?: string | any
purchaseDate?: string

@ -798,6 +798,8 @@ export default {
selectedPallets: 'Selected Pallets',
packageCount: 'Package Count',
outPackageCount: 'Outbound Package Count',
outLockedPackageCount: 'Outbound Locked Package Count',
outPackageCountExceededWarning: 'Outbound package count cannot exceed package count minus outbound locked package count. It has been adjusted to {count}.',
inPackageCount: 'Inbound Package Count',
inItemCount: 'Inbound Count',
inCount: 'Inbound Quantity',
@ -847,8 +849,7 @@ export default {
validatorOutboundPurposeRequired: 'Outbound purpose is required',
validatorOutModeRequired: 'Outbound mode is required',
validatorCountRequired: 'Quantity is required',
stockCountExceededWarning:
'Quantity cannot exceed stock. It has been adjusted to stock quantity.'
stockCountExceededWarning: 'Quantity cannot exceed available stock. It has been adjusted to available stock quantity.'
},
Check: {
no: 'Check No',

@ -798,6 +798,8 @@ export default {
selectedPallets: '已选托盘',
packageCount: '包数',
outPackageCount: '出库包数',
outLockedPackageCount: '出库锁定包数',
outPackageCountExceededWarning: '出库包数不能大于包数减出库锁定包数,已自动调整为{count}',
inPackageCount: '入库包数',
inItemCount: '入库个数',
inCount: '入库数量',
@ -847,7 +849,7 @@ export default {
validatorOutboundPurposeRequired: '出库用途不能为空',
validatorOutModeRequired: '出库方式不能为空',
validatorCountRequired: '产品数量不能为空',
stockCountExceededWarning: '数量不能超出库存,已自动调整为库存数量'
stockCountExceededWarning: '数量不能超出可用库存,已自动调整为可用库存数量'
},
Check: {
no: '盘点单号',

@ -61,6 +61,13 @@
</el-form-item>
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Item.lockedStock')" min-width="100">
<template #default="{ row }">
<el-form-item class="mb-0px!">
<el-input disabled v-model="row.lockedStockCount" :formatter="erpCountInputFormatter" />
</el-form-item>
</template>
</el-table-column>
<el-table-column :label="t('SparePartsManagement.SpareOut.itemProductCode')" min-width="150">
<template #default="{ row }">
<el-form-item class="mb-0px!">
@ -83,6 +90,8 @@
controls-position="right"
:min="0"
class="!w-100%"
@change="handleCountChange(row)"
@blur="handleCountChange(row)"
/>
</el-form-item>
</template>
@ -143,6 +152,7 @@ import {
} from '@/utils'
const { t } = useI18n()
const message = useMessage()
const props = defineProps<{
items: undefined
@ -236,6 +246,7 @@ const handleAdd = () => {
productBarCode: undefined, //
productPrice: undefined,
stockCount: undefined,
lockedStockCount: undefined,
count: 1,
totalPrice: undefined,
remark: undefined
@ -249,6 +260,23 @@ const handleDelete = (index) => {
}
/** 处理仓库变更 */
const getAvailableStockCount = (row) => {
const stockCount = Number(row.stockCount)
if (!Number.isFinite(stockCount)) return undefined
const lockedStockCount = Number(row.lockedStockCount)
return Math.max(stockCount - (Number.isFinite(lockedStockCount) ? lockedStockCount : 0), 0)
}
const handleCountChange = (row, showWarning = true) => {
const availableStockCount = getAvailableStockCount(row)
const count = Number(row.count)
if (availableStockCount === undefined || !Number.isFinite(count) || count <= availableStockCount) return
row.count = availableStockCount
if (showWarning) {
message.warning(t('ErpStock.Item.stockCountExceededWarning'))
}
}
const onChangeWarehouse = (warehouseId, row) => {
//
setStockCount(row)
@ -269,14 +297,19 @@ const onChangeProduct = (productId, row) => {
/** 加载库存 */
const setStockCount = async (row) => {
if (!row.productId || !row.warehouseId) {
row.stockCount = 0
row.lockedStockCount = 0
return
}
const stock = await StockApi.getStock2(row.productId, row.warehouseId)
row.stockCount = stock ? stock.count : 0
row.lockedStockCount = stock ? stock.lockedStockCount || 0 : 0
handleCountChange(row, false)
}
/** 表单校验 */
const validate = () => {
formData.value.forEach((row) => handleCountChange(row, false))
return formRef.value.validate()
}
defineExpose({ validate })

@ -173,7 +173,7 @@
</template>
</el-input>
<el-input-number v-else v-model="row.inputCount" controls-position="right" :min="0" :precision="0"
class="quantity-input !w-100%" @blur="handleInputCountBlur(row)">
class="quantity-input !w-100%" @change="handleInputCountBlur(row)" @blur="handleInputCountBlur(row)">
<template v-if="isPurchaseUnitStockOut" #suffix>
<span>{{ getInventoryQuantityUnitName(row) }}</span>
</template>
@ -314,7 +314,8 @@
<el-table v-else ref="palletTableRef" v-loading="palletDialogLoading" :data="palletDialogList" row-key="id"
:stripe="true" :show-overflow-tooltip="true" @row-click="handlePalletDialogRowClick"
@selection-change="handlePalletDialogSelectionChange">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true" />
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"
:selectable="isPalletSelectable" />
<el-table-column :label="t('ErpStock.Pallet.code')" prop="code" min-width="150" />
<el-table-column :label="t('ErpStock.Pallet.palletType')" prop="palletType" min-width="100">
<template #default="{ row }">
@ -338,6 +339,7 @@
</el-table-column>
<el-table-column :label="t('ErpStock.Pallet.productName')" prop="productName" min-width="100" />
<el-table-column :label="t('ErpStock.Item.packageCount')" prop="productCount" min-width="100" />
<el-table-column :label="t('ErpStock.Item.outLockedPackageCount')" prop="lockedPackageCount" min-width="130" />
<el-table-column v-if="currentSelectRow?.outMode === 2" :label="t('ErpStock.Item.outPackageCount')"
min-width="130">
<template #default="{ row }">
@ -1068,6 +1070,7 @@ const handlePalletDialogQuery = () => {
}
const handlePalletDialogRowClick = (row: PalletVO) => {
if (!isPalletSelectable(row)) return
palletTableRef.value?.toggleRowSelection(row)
}
@ -1130,7 +1133,7 @@ const syncPalletDialogSelection = () => {
const selectedIds = new Set((row.pallets || []).map((item: any) => item.palletId))
palletTableRef.value.clearSelection()
palletDialogList.value.forEach((pallet: any) => {
if (selectedIds.has(pallet.id)) {
if (selectedIds.has(pallet.id) && isPalletSelectable(pallet)) {
palletTableRef.value.toggleRowSelection(pallet, true)
}
})
@ -1138,7 +1141,18 @@ const syncPalletDialogSelection = () => {
const getPalletAvailablePackageCount = (pallet: PalletVO) => {
const packageCount = Number(pallet?.productCount)
return Number.isFinite(packageCount) ? packageCount : 0
const lockedPackageCount = getPalletLockedPackageCount(pallet)
return Number.isFinite(packageCount) ? Math.max(packageCount - lockedPackageCount, 0) : 0
}
const getPalletLockedPackageCount = (pallet: PalletVO) => {
const lockedPackageCount = Number(pallet?.lockedPackageCount)
return Number.isFinite(lockedPackageCount) ? Math.max(lockedPackageCount, 0) : 0
}
const isPalletSelectable = (pallet: PalletVO) => {
if (Number(currentSelectRow.value?.outMode) !== 1) return true
return getPalletLockedPackageCount(pallet) === 0
}
const handlePalletPackageCountChange = (value: number | undefined, pallet: any) => {
@ -1146,7 +1160,7 @@ const handlePalletPackageCountChange = (value: number | undefined, pallet: any)
const packageCount = Number(value)
if (!Number.isFinite(packageCount) || packageCount <= availablePackageCount) return
pallet.packageCount = availablePackageCount
message.warning(`出库包数不能大于包数,已自动调整为${availablePackageCount}`)
message.alertWarning(t('ErpStock.Item.outPackageCountExceededWarning', { count: availablePackageCount }))
}
const getPalletOutCount = (pallet: any) => {
@ -1366,18 +1380,25 @@ const syncCountByInputCount = (row: any) => {
row.count = inputCount
}
const getAvailableStockCount = (row: any) => {
const stockCount = Number(row.stockCount)
if (!Number.isFinite(stockCount)) return undefined
const lockedStockCount = Number(row.lockedStockCount)
return Math.max(stockCount - (Number.isFinite(lockedStockCount) ? lockedStockCount : 0), 0)
}
const handleInputCountBlur = (row: any) => {
if (!isProductMaterialStockOut.value) return
const inputCount = toIntegerCount(row.inputCount)
const stockCount = Number(row.stockCount)
if (inputCount === undefined || !Number.isFinite(stockCount)) return
const availableStockCount = getAvailableStockCount(row)
if (inputCount === undefined || availableStockCount === undefined) return
row.inputCount = inputCount
if (inputCount <= stockCount) {
if (inputCount <= availableStockCount) {
syncCountByInputCount(row)
syncPalletPackageCounts(row)
return
}
row.inputCount = Math.trunc(stockCount)
row.inputCount = Math.trunc(availableStockCount)
syncCountByInputCount(row)
syncPalletPackageCounts(row)
message.warning(t('ErpStock.Item.stockCountExceededWarning'))
@ -1454,6 +1475,7 @@ const setStockCount = async (row) => {
/** 表单校验 */
const validate = () => {
formData.value.forEach((row) => {
handleInputCountBlur(row)
syncPalletPackageCounts(row)
syncInputCountByPallets(row)
syncCountByInputCount(row)

@ -372,6 +372,16 @@ const outTypeToInfoKey = (outType: string) => {
}
return map[outType] || 'productInfo'
}
const getProductCategoryType = () => {
const outType = queryParams.outType || activeName.value || stockOutTypeOptions.value[0]?.value
const infoKey = outTypeToInfoKey(outType || '')
const map: Record<string, number> = {
productInfo: 1,
materialInfo: 2,
sparePartInfo: 3
}
return map[infoKey]
}
const activeName = ref('')
const queryFormRef = ref() // ?
const exportLoading = ref(false) //
@ -385,6 +395,16 @@ const toggleFilters = () => {
}
const productList = ref<ProductVO[]>([]) // у
const warehouseList = ref<WarehouseVO[]>([]) //
const getProductList = async () => {
const categoryType = getProductCategoryType()
productList.value = await ProductApi.getProductSimpleList(
categoryType !== undefined ? { categoryType } : undefined
)
if (queryParams.productId && !productList.value.some((item) => item.id === queryParams.productId)) {
queryParams.productId = undefined
}
}
const userList = ref<UserVO[]>([]) //
const formVisible = ref(false) //
@ -447,11 +467,12 @@ const handleQuery = () => {
}
/** 閲嶇疆鎸夐挳鎿嶄綔 */
const resetQuery = () => {
const resetQuery = async () => {
useInitialStatusFilter.value = false
queryFormRef.value.resetFields()
queryParams.statusList = []
queryParams.outType = activeName.value || stockOutTypeOptions.value[0]?.value
await getProductList()
handleQuery()
}
@ -574,6 +595,7 @@ watch(stockOutTypeOptions, (options) => {
if (!queryParams.outType && options.length) {
syncDefaultOutType()
queryParams.pageNo = 1
getProductList()
getList()
}
})
@ -585,7 +607,7 @@ onMounted(async () => {
updatePlanTableMaxHeight()
window.addEventListener('resize', updatePlanTableMaxHeight)
// у
productList.value = await ProductApi.getProductSimpleList()
await getProductList()
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
userList.value = await UserApi.getSimpleUserList()
})
@ -593,9 +615,10 @@ onMounted(async () => {
onBeforeUnmount(() => {
window.removeEventListener('resize', updatePlanTableMaxHeight)
})
const handleTabClick = (tab: TabsPaneContext) => {
const handleTabClick = async (tab: TabsPaneContext) => {
queryParams.outType = String(tab.paneName || '')
activeName.value = queryParams.outType
await getProductList()
handleQuery()
}
</script>

Loading…
Cancel
Save