|
|
|
|
@ -24,7 +24,7 @@ v-model="row.warehouseId" clearable filterable
|
|
|
|
|
filterable
|
|
|
|
|
:placeholder="t('ErpStock.Item.placeholderArea')"
|
|
|
|
|
:disabled="!row.warehouseId"
|
|
|
|
|
@change="setStockCount(row)"
|
|
|
|
|
@change="handleAreaChange(row)"
|
|
|
|
|
>
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="item in getAreaOptions(row.warehouseId)" :key="item.id" :label="getAreaLabel(item)"
|
|
|
|
|
@ -33,7 +33,7 @@ v-for="item in getAreaOptions(row.warehouseId)" :key="item.id" :label="getAreaLa
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column :label="t('ErpStock.Item.barcode')" min-width="160">
|
|
|
|
|
<el-table-column :label="codeColumnLabel" min-width="160">
|
|
|
|
|
<!-- <template #default="{ row }">
|
|
|
|
|
<el-form-item class="mb-0px!">
|
|
|
|
|
<el-input disabled v-model="row.productBarCode" />
|
|
|
|
|
@ -73,13 +73,18 @@ v-model="row.productId" :options="productCascaderOptions" :props="productCascade
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
|
|
|
|
<el-table-column :label="t('ErpStock.Item.inventoryUnit')" min-width="80">
|
|
|
|
|
<el-table-column v-if="!isProductStockOut" :label="t('ErpStock.Item.inventoryUnit')" min-width="80">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-form-item class="mb-0px!">
|
|
|
|
|
<el-input disabled v-model="row.productUnitName" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column v-if="isProductStockOut" :label="t('ErpStock.Item.packageItemCount')" min-width="120">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-input :model-value="row.packageQuantity ?? '-'" disabled />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column v-if="isPurchaseUnitStockOut" :label="t('ErpStock.Item.purchaseUnit')" min-width="100">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-form-item class="mb-0px!">
|
|
|
|
|
@ -112,7 +117,7 @@ v-model="row.productId" :options="productCascaderOptions" :props="productCascade
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column v-if="isSparePartStockOut" :label="t('ErpStock.Item.outboundPurpose')" min-width="140">
|
|
|
|
|
<template #default="{ row, $index }">
|
|
|
|
|
<el-form-item :prop="`${$index}.outUsageType`" class="mb-0px!">
|
|
|
|
|
<el-form-item :prop="`${$index}.outUsageType`" :rules="formRules.outUsageType" class="mb-0px!">
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="row.outUsageType"
|
|
|
|
|
clearable
|
|
|
|
|
@ -129,6 +134,30 @@ v-model="row.productId" :options="productCascaderOptions" :props="productCascade
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column v-if="isProductStockOut" :label="t('ErpStock.Item.outMode')" width="200">
|
|
|
|
|
<template #default="{ row, $index }">
|
|
|
|
|
<el-form-item :prop="`${$index}.outMode`" :rules="formRules.outMode" class="mb-0px!">
|
|
|
|
|
<el-radio-group v-model="row.outMode" class="out-mode-radio-group" @change="handleOutModeChange(row)">
|
|
|
|
|
<el-radio-button :label="1">{{ t('ErpStock.Item.outModeWholePallet') }}</el-radio-button>
|
|
|
|
|
<el-radio-button :label="2">{{ t('ErpStock.Item.outModeSplitPallet') }}</el-radio-button>
|
|
|
|
|
</el-radio-group>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column v-if="isProductStockOut" :label="t('ErpStock.Item.palletCode')" min-width="180">
|
|
|
|
|
<template #default="{ row, $index }">
|
|
|
|
|
<el-form-item :prop="`${$index}.pallets`" :rules="formRules.pallets" class="mb-0px!">
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="row.palletCode"
|
|
|
|
|
readonly
|
|
|
|
|
clearable
|
|
|
|
|
:placeholder="t('ErpStock.Item.placeholderPalletCode')"
|
|
|
|
|
@click="openPalletSelectDialog(row)"
|
|
|
|
|
@clear="clearPallet(row)"
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column
|
|
|
|
|
v-if="showRelatedRepairColumn"
|
|
|
|
|
:label="t('ErpStock.Item.relatedRepairOrder')"
|
|
|
|
|
@ -182,7 +211,9 @@ v-model="row.productId" :options="productCascaderOptions" :props="productCascade
|
|
|
|
|
<el-table-column v-if="isProductMaterialStockOut" :label="t('ErpStock.Item.count')" prop="inputCount" min-width="140">
|
|
|
|
|
<template #default="{ row, $index }">
|
|
|
|
|
<el-form-item :prop="`${$index}.inputCount`" :rules="formRules.inputCount" class="mb-0px!">
|
|
|
|
|
<el-input v-if="isProductStockOut" :model-value="row.inputCount ?? '-'" disabled />
|
|
|
|
|
<el-input-number
|
|
|
|
|
v-else
|
|
|
|
|
v-model="row.inputCount" controls-position="right" :min="0.001" :precision="3"
|
|
|
|
|
class="!w-100%"
|
|
|
|
|
@blur="handleInputCountBlur(row)"
|
|
|
|
|
@ -280,6 +311,90 @@ v-loading="productDialogLoading" :data="productDialogList" row-key="id" :stripe=
|
|
|
|
|
</template>
|
|
|
|
|
</Dialog>
|
|
|
|
|
|
|
|
|
|
<Dialog :title="t('ErpStock.Item.selectPalletCode')" v-model="palletDialogVisible" width="980px">
|
|
|
|
|
<el-form :model="palletQueryParams" :inline="true" class="-mb-15px">
|
|
|
|
|
<el-form-item :label="t('ErpStock.Pallet.code')">
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="palletQueryParams.code"
|
|
|
|
|
clearable
|
|
|
|
|
:placeholder="t('ErpStock.Pallet.placeholderCode')"
|
|
|
|
|
@keyup.enter="handlePalletDialogQuery"
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item :label="t('ErpStock.Pallet.status')">
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="palletQueryParams.status"
|
|
|
|
|
clearable
|
|
|
|
|
:placeholder="t('ErpStock.Pallet.placeholderStatus')"
|
|
|
|
|
class="!w-180px"
|
|
|
|
|
>
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="dict in getIntDictOptions(DICT_TYPE.STORAGE_PALLET_STATUS)"
|
|
|
|
|
:key="dict.value"
|
|
|
|
|
:label="dict.label"
|
|
|
|
|
:value="dict.value"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item>
|
|
|
|
|
<el-button type="primary" @click="handlePalletDialogQuery">
|
|
|
|
|
<Icon icon="ep:search" class="mr-5px" /> {{ t('common.query') }}
|
|
|
|
|
</el-button>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
<el-table
|
|
|
|
|
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 :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 }">
|
|
|
|
|
<dict-tag :type="DICT_TYPE.STORAGE_PALLET_TYPES" :value="row.palletType" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column :label="t('ErpStock.Pallet.status')" prop="status" min-width="100">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<dict-tag :type="DICT_TYPE.STORAGE_PALLET_STATUS" :value="row.status" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column :label="t('ErpStock.Pallet.planCode')" prop="planCode" min-width="150" />
|
|
|
|
|
<el-table-column :label="t('ErpStock.Pallet.productId')" prop="productId" min-width="100" />
|
|
|
|
|
<el-table-column :label="t('ErpStock.Item.packageCount')" prop="productCount" min-width="100" />
|
|
|
|
|
<el-table-column v-if="currentSelectRow?.outMode === 2" label="出库包数" min-width="130">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-input-number
|
|
|
|
|
v-model="row.packageCount"
|
|
|
|
|
controls-position="right"
|
|
|
|
|
:min="0"
|
|
|
|
|
:precision="0"
|
|
|
|
|
class="!w-100%"
|
|
|
|
|
@change="handlePalletPackageCountChange($event, row)"
|
|
|
|
|
@click.stop
|
|
|
|
|
/>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
<div class="product-dialog-pagination">
|
|
|
|
|
<Pagination
|
|
|
|
|
:total="palletDialogTotal"
|
|
|
|
|
v-model:page="palletQueryParams.pageNo"
|
|
|
|
|
v-model:limit="palletQueryParams.pageSize"
|
|
|
|
|
@pagination="getPalletDialogList"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<template #footer>
|
|
|
|
|
<el-button type="primary" @click="confirmPalletSelect">{{ t('common.ok') }}</el-button>
|
|
|
|
|
<el-button @click="palletDialogVisible = false">{{ t('common.cancel') }}</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
</Dialog>
|
|
|
|
|
|
|
|
|
|
<Dialog :title="relatedOrderDialogTitle" v-model="relatedOrderDialogVisible" width="1100px">
|
|
|
|
|
<el-table
|
|
|
|
|
v-loading="relatedOrderLoading"
|
|
|
|
|
@ -383,9 +498,10 @@ import { ProductApi, ProductVO } from '@/api/erp/product/product'
|
|
|
|
|
import { WarehouseApi, WarehouseVO } from '@/api/erp/stock/warehouse'
|
|
|
|
|
import { WarehouseAreaApi, WarehouseAreaVO } from '@/api/erp/stock/warehousearea'
|
|
|
|
|
import { StockApi } from '@/api/erp/stock/stock'
|
|
|
|
|
import { PalletApi, PalletVO } from '@/api/erp/stock/pallet'
|
|
|
|
|
import { DvRepairApi } from '@/api/mes/dvrepair'
|
|
|
|
|
import { TicketManagementApi } from '@/api/mes/ticketManagement'
|
|
|
|
|
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
|
|
|
|
|
import { DICT_TYPE, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
|
|
|
|
|
import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
|
|
|
|
|
import {
|
|
|
|
|
erpCountInputFormatter,
|
|
|
|
|
@ -407,6 +523,9 @@ const formRules = reactive({
|
|
|
|
|
warehouseId: [{ required: true, message: t('ErpStock.Item.validatorWarehouseRequired'), trigger: 'blur' }],
|
|
|
|
|
areaId: [{ required: true, message: t('ErpStock.Item.validatorAreaRequired'), trigger: 'change' }],
|
|
|
|
|
productId: [{ required: true, message: t('ErpStock.Item.validatorProductRequired'), trigger: 'blur' }],
|
|
|
|
|
outUsageType: [{ required: true, message: t('ErpStock.Item.validatorOutboundPurposeRequired'), trigger: 'change' }],
|
|
|
|
|
outMode: [{ required: true, message: t('ErpStock.Item.validatorOutModeRequired'), trigger: 'change' }],
|
|
|
|
|
pallets: [{ validator: validatePallets, trigger: 'change' }],
|
|
|
|
|
inputCount: [{ required: true, message: t('ErpStock.Item.validatorCountRequired'), trigger: 'blur' }],
|
|
|
|
|
count: [{ required: true, message: t('ErpStock.Item.validatorCountRequired'), trigger: 'blur' }]
|
|
|
|
|
})
|
|
|
|
|
@ -427,6 +546,12 @@ const isProductMaterialStockOut = computed(() => Boolean(activeCategoryType.valu
|
|
|
|
|
const isProductStockOut = computed(() => activeCategoryType.value === 1)
|
|
|
|
|
const isPurchaseUnitStockOut = computed(() => activeCategoryType.value === 2 || activeCategoryType.value === 3)
|
|
|
|
|
const isSparePartStockOut = computed(() => activeCategoryType.value === 3)
|
|
|
|
|
const codeColumnLabel = computed(() => {
|
|
|
|
|
if (activeCategoryType.value === 1) return t('ErpStock.Item.productLabel')
|
|
|
|
|
if (activeCategoryType.value === 2) return t('ErpStock.Item.materialLabel')
|
|
|
|
|
if (activeCategoryType.value === 3) return t('ErpStock.Item.sparePartLabel')
|
|
|
|
|
return t('ErpStock.Item.barcode')
|
|
|
|
|
})
|
|
|
|
|
const outboundPurposeOptions = computed(() => getStrDictOptions(DICT_TYPE.WAREHOUSE_OUTBOUND_PURPOSE))
|
|
|
|
|
const purchaseUnitConvertTipText = computed(() => t('FactoryModeling.ProductInformation.dialogPurchaseUnitConvertTip'))
|
|
|
|
|
const productDialogVisible = ref(false)
|
|
|
|
|
@ -442,6 +567,18 @@ const productQueryParams = reactive({
|
|
|
|
|
})
|
|
|
|
|
const currentSelectRow = ref<any>()
|
|
|
|
|
const selectedProductId = ref<number>()
|
|
|
|
|
const palletDialogVisible = ref(false)
|
|
|
|
|
const palletDialogLoading = ref(false)
|
|
|
|
|
const palletDialogList = ref<PalletVO[]>([])
|
|
|
|
|
const palletDialogTotal = ref(0)
|
|
|
|
|
const palletTableRef = ref()
|
|
|
|
|
const selectedPalletRows = ref<PalletVO[]>([])
|
|
|
|
|
const palletQueryParams = reactive({
|
|
|
|
|
pageNo: 1,
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
code: undefined,
|
|
|
|
|
status: undefined
|
|
|
|
|
})
|
|
|
|
|
const RELATED_PURPOSE_REPAIR = '1'
|
|
|
|
|
const RELATED_PURPOSE_MAINTAIN = '2'
|
|
|
|
|
const relatedOrderDialogVisible = ref(false)
|
|
|
|
|
@ -468,6 +605,14 @@ const showRelatedMaintainColumn = computed(
|
|
|
|
|
() => isSparePartStockOut.value && formData.value.some((row) => isMaintainPurpose(row.outUsageType))
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
function validatePallets(_: any, value: any[], callback: (error?: Error) => void) {
|
|
|
|
|
if (!isProductStockOut.value || (Array.isArray(value) && value.length > 0)) {
|
|
|
|
|
callback()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
callback(new Error(t('ErpStock.Item.validatorPalletRequired')))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const productCascaderProps = {
|
|
|
|
|
emitPath: false,
|
|
|
|
|
value: 'value',
|
|
|
|
|
@ -544,6 +689,7 @@ watch(
|
|
|
|
|
row.inputCount = row.inputCount ?? row.count ?? 1
|
|
|
|
|
if (isProductStockOut.value) {
|
|
|
|
|
row.inputUnitType = row.inputUnitType || '个'
|
|
|
|
|
row.outMode = Number(row.outMode || 1)
|
|
|
|
|
}
|
|
|
|
|
syncCountByInputCount(row)
|
|
|
|
|
})
|
|
|
|
|
@ -605,11 +751,23 @@ const handleAdd = () => {
|
|
|
|
|
purchaseUnitName: undefined,
|
|
|
|
|
supplierName: undefined,
|
|
|
|
|
purchaseUnitConvertQuantity: undefined,
|
|
|
|
|
packagingSchemeRelationId: undefined,
|
|
|
|
|
packagingSchemeId: undefined,
|
|
|
|
|
packagingSchemeName: undefined,
|
|
|
|
|
packageQuantity: undefined,
|
|
|
|
|
palletPackageQuantity: undefined,
|
|
|
|
|
palletTotalQuantity: undefined,
|
|
|
|
|
palletCount: undefined,
|
|
|
|
|
packageCount: undefined,
|
|
|
|
|
pieceCount: undefined,
|
|
|
|
|
inputUnitType: isProductStockOut.value ? '个' : undefined,
|
|
|
|
|
inputCount: isProductMaterialStockOut.value ? 1 : undefined,
|
|
|
|
|
stockCount: undefined,
|
|
|
|
|
count: isProductMaterialStockOut.value ? undefined : 1,
|
|
|
|
|
outMode: isProductStockOut.value ? 1 : undefined,
|
|
|
|
|
outUsageType: undefined,
|
|
|
|
|
pallets: [],
|
|
|
|
|
palletCode: undefined,
|
|
|
|
|
repairId: undefined,
|
|
|
|
|
repairDeviceId: undefined,
|
|
|
|
|
maintenanceId: undefined,
|
|
|
|
|
@ -644,6 +802,7 @@ const onChangeProductCode = (productBarCode, row) => {
|
|
|
|
|
/** 处理仓库变更 */
|
|
|
|
|
const onChangeWarehouse = (warehouseId, row) => {
|
|
|
|
|
row.areaId = undefined
|
|
|
|
|
clearPallet(row)
|
|
|
|
|
if (warehouseId && isProductMaterialStockOut.value) {
|
|
|
|
|
loadWarehouseAreas(warehouseId)
|
|
|
|
|
}
|
|
|
|
|
@ -651,6 +810,11 @@ const onChangeWarehouse = (warehouseId, row) => {
|
|
|
|
|
setStockCount(row)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleAreaChange = (row: any) => {
|
|
|
|
|
clearPallet(row)
|
|
|
|
|
setStockCount(row)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 处理产品变更 */
|
|
|
|
|
const onChangeProduct = (productId, row) => {
|
|
|
|
|
const product = productList.value.find((item) => item.id === productId)
|
|
|
|
|
@ -669,9 +833,26 @@ const fillRowByProduct = (row: any, product: any) => {
|
|
|
|
|
row.purchaseUnitName = product.purchaseUnitName
|
|
|
|
|
row.supplierName = getDefaultSupplierName(product)
|
|
|
|
|
row.purchaseUnitConvertQuantity = product.purchaseUnitConvertQuantity
|
|
|
|
|
fillPackagingSchemeByProduct(row, product)
|
|
|
|
|
syncCountByInputCount(row)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const fillPackagingSchemeByProduct = (row: any, product: any) => {
|
|
|
|
|
const schemes = Array.isArray(product?.packagingSchemes) ? product.packagingSchemes : []
|
|
|
|
|
const defaultSchemeId = product?.defaultPackagingSchemeId
|
|
|
|
|
const scheme =
|
|
|
|
|
schemes.find((item: any) => Number(item?.defaultStatus) === 1) ||
|
|
|
|
|
schemes.find((item: any) => item?.packagingSchemeId === defaultSchemeId || item?.id === defaultSchemeId) ||
|
|
|
|
|
schemes[0]
|
|
|
|
|
row.packagingSchemeRelationId = scheme?.id
|
|
|
|
|
row.packagingSchemeId = scheme?.packagingSchemeId ?? scheme?.id
|
|
|
|
|
row.packagingSchemeName = scheme?.packagingSchemeName ?? scheme?.name
|
|
|
|
|
row.packageQuantity = scheme?.packageQuantity ?? product?.packageQuantity
|
|
|
|
|
row.palletPackageQuantity = scheme?.palletPackageQuantity ?? product?.palletPackageQuantity
|
|
|
|
|
row.palletTotalQuantity = scheme?.palletTotalQuantity ?? product?.palletTotalQuantity
|
|
|
|
|
syncInputCountByPallets(row)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getDefaultSupplierName = (product: any) => {
|
|
|
|
|
if (!product) return undefined
|
|
|
|
|
if (product.supplierName) return product.supplierName
|
|
|
|
|
@ -689,6 +870,15 @@ const normalizeRow = (row: any) => {
|
|
|
|
|
row.outUsageType = String(row.outUsageType)
|
|
|
|
|
}
|
|
|
|
|
row.inputCount = row.inputCount ?? row.count
|
|
|
|
|
if (isProductStockOut.value) {
|
|
|
|
|
row.outMode = Number(row.outMode || 1)
|
|
|
|
|
if (!Array.isArray(row.pallets)) {
|
|
|
|
|
row.pallets = row.palletId ? [{ palletId: row.palletId, packageCount: row.packageCount }] : []
|
|
|
|
|
}
|
|
|
|
|
if (!row.palletCode && Array.isArray(row.pallets) && row.pallets.length > 0) {
|
|
|
|
|
row.palletCode = row.pallets.map((item) => item.palletCode || item.code).filter(Boolean).join(', ')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (row.repairId) {
|
|
|
|
|
row.relatedOrderNo = row.relatedOrderNo || row.repairCode || row.repairNo || String(row.repairId)
|
|
|
|
|
row.relatedOrderName = row.relatedOrderName || row.repairName
|
|
|
|
|
@ -740,6 +930,16 @@ const clearProduct = (row: any) => {
|
|
|
|
|
row.purchaseUnitName = undefined
|
|
|
|
|
row.supplierName = undefined
|
|
|
|
|
row.purchaseUnitConvertQuantity = undefined
|
|
|
|
|
row.packagingSchemeRelationId = undefined
|
|
|
|
|
row.packagingSchemeId = undefined
|
|
|
|
|
row.packagingSchemeName = undefined
|
|
|
|
|
row.packageQuantity = undefined
|
|
|
|
|
row.palletPackageQuantity = undefined
|
|
|
|
|
row.palletTotalQuantity = undefined
|
|
|
|
|
row.palletCount = undefined
|
|
|
|
|
row.packageCount = undefined
|
|
|
|
|
row.pieceCount = undefined
|
|
|
|
|
clearPallet(row)
|
|
|
|
|
row.inputCount = isProductMaterialStockOut.value ? undefined : row.inputCount
|
|
|
|
|
row.count = isProductMaterialStockOut.value ? undefined : row.count
|
|
|
|
|
}
|
|
|
|
|
@ -782,14 +982,161 @@ const handleProductDialogRowClick = (row: any) => {
|
|
|
|
|
selectedProductId.value = row.id
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const confirmProductSelect = () => {
|
|
|
|
|
const confirmProductSelect = async () => {
|
|
|
|
|
const product = productDialogList.value.find((item) => item.id === selectedProductId.value)
|
|
|
|
|
if (!product || !currentSelectRow.value) return
|
|
|
|
|
fillRowByProduct(currentSelectRow.value, product)
|
|
|
|
|
let finalProduct = product
|
|
|
|
|
if (!Array.isArray((product as any).packagingSchemes)) {
|
|
|
|
|
finalProduct = await ProductApi.getProduct(product.id)
|
|
|
|
|
}
|
|
|
|
|
fillRowByProduct(currentSelectRow.value, finalProduct)
|
|
|
|
|
clearPallet(currentSelectRow.value)
|
|
|
|
|
setStockCount(currentSelectRow.value)
|
|
|
|
|
productDialogVisible.value = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleOutModeChange = (row: any) => {
|
|
|
|
|
clearPallet(row)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const openPalletSelectDialog = async (row: any) => {
|
|
|
|
|
currentSelectRow.value = row
|
|
|
|
|
selectedPalletRows.value = []
|
|
|
|
|
palletQueryParams.pageNo = 1
|
|
|
|
|
palletQueryParams.code = undefined
|
|
|
|
|
palletQueryParams.status = undefined
|
|
|
|
|
palletDialogVisible.value = true
|
|
|
|
|
await getPalletDialogList()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getPalletDialogList = async () => {
|
|
|
|
|
palletDialogLoading.value = true
|
|
|
|
|
try {
|
|
|
|
|
const data = await PalletApi.getPalletPage({
|
|
|
|
|
...palletQueryParams,
|
|
|
|
|
productId: currentSelectRow.value?.productId,
|
|
|
|
|
warehouseId: currentSelectRow.value?.warehouseId,
|
|
|
|
|
areaId: currentSelectRow.value?.areaId
|
|
|
|
|
})
|
|
|
|
|
const selectedPackageMap = new Map((currentSelectRow.value?.pallets || []).map((item: any) => [item.palletId, item.packageCount]))
|
|
|
|
|
palletDialogList.value = (data?.list || []).map((pallet: any) => {
|
|
|
|
|
const selectedPackageCount = selectedPackageMap.get(pallet.id)
|
|
|
|
|
return {
|
|
|
|
|
...pallet,
|
|
|
|
|
packageCount: selectedPackageCount ?? 0
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
palletDialogTotal.value = data?.total || 0
|
|
|
|
|
await nextTick()
|
|
|
|
|
syncPalletDialogSelection()
|
|
|
|
|
} finally {
|
|
|
|
|
palletDialogLoading.value = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handlePalletDialogQuery = () => {
|
|
|
|
|
palletQueryParams.pageNo = 1
|
|
|
|
|
getPalletDialogList()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handlePalletDialogRowClick = (row: PalletVO) => {
|
|
|
|
|
palletTableRef.value?.toggleRowSelection(row)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handlePalletDialogSelectionChange = (rows: PalletVO[]) => {
|
|
|
|
|
selectedPalletRows.value = rows
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const confirmPalletSelect = () => {
|
|
|
|
|
if (!currentSelectRow.value) return
|
|
|
|
|
const row = currentSelectRow.value
|
|
|
|
|
row.pallets = selectedPalletRows.value.map((pallet: any) => ({
|
|
|
|
|
palletId: pallet.id,
|
|
|
|
|
palletCode: pallet.code,
|
|
|
|
|
packageCount: getPalletPackageCount(row, pallet)
|
|
|
|
|
}))
|
|
|
|
|
row.palletCode = selectedPalletRows.value.map((pallet) => pallet.code).filter(Boolean).join(', ')
|
|
|
|
|
syncInputCountByPallets(row)
|
|
|
|
|
palletDialogVisible.value = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const clearPallet = (row: any) => {
|
|
|
|
|
if (!row) return
|
|
|
|
|
row.pallets = []
|
|
|
|
|
row.palletCode = undefined
|
|
|
|
|
row.palletCount = isProductStockOut.value ? undefined : row.palletCount
|
|
|
|
|
row.packageCount = isProductStockOut.value ? undefined : row.packageCount
|
|
|
|
|
row.pieceCount = isProductStockOut.value ? undefined : row.pieceCount
|
|
|
|
|
row.inputCount = isProductStockOut.value ? undefined : row.inputCount
|
|
|
|
|
row.count = isProductStockOut.value ? undefined : row.count
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const syncPalletDialogSelection = () => {
|
|
|
|
|
const row = currentSelectRow.value
|
|
|
|
|
if (!row || !palletTableRef.value) return
|
|
|
|
|
const selectedIds = new Set((row.pallets || []).map((item: any) => item.palletId))
|
|
|
|
|
palletTableRef.value.clearSelection()
|
|
|
|
|
palletDialogList.value.forEach((pallet: any) => {
|
|
|
|
|
if (selectedIds.has(pallet.id)) {
|
|
|
|
|
palletTableRef.value.toggleRowSelection(pallet, true)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getPalletAvailablePackageCount = (pallet: PalletVO) => {
|
|
|
|
|
const packageCount = Number(pallet?.productCount)
|
|
|
|
|
return Number.isFinite(packageCount) ? packageCount : 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handlePalletPackageCountChange = (value: number | undefined, pallet: any) => {
|
|
|
|
|
const availablePackageCount = getPalletAvailablePackageCount(pallet)
|
|
|
|
|
const packageCount = Number(value)
|
|
|
|
|
if (!Number.isFinite(packageCount) || packageCount <= availablePackageCount) return
|
|
|
|
|
pallet.packageCount = availablePackageCount
|
|
|
|
|
message.warning(`出库包数不能大于包数,已自动调整为${availablePackageCount}`)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getPalletPackageCount = (row: any, pallet: any) => {
|
|
|
|
|
const availablePackageCount = getPalletAvailablePackageCount(pallet)
|
|
|
|
|
if (Number(row.outMode) === 1) {
|
|
|
|
|
return availablePackageCount
|
|
|
|
|
}
|
|
|
|
|
const packageCount = Number(pallet.packageCount)
|
|
|
|
|
if (!Number.isFinite(packageCount)) return 0
|
|
|
|
|
return Math.min(Math.max(packageCount, 0), availablePackageCount)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const syncPalletPackageCounts = (row: any) => {
|
|
|
|
|
if (!Array.isArray(row?.pallets)) return
|
|
|
|
|
row.pallets = row.pallets.map((item: any) => {
|
|
|
|
|
const pallet = currentSelectRow.value === row ? palletDialogList.value.find((p) => p.id === item.palletId) : undefined
|
|
|
|
|
const packageCount = pallet ? getPalletPackageCount(row, pallet) : Number(item.packageCount ?? 0)
|
|
|
|
|
return {
|
|
|
|
|
...item,
|
|
|
|
|
packageCount
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const syncInputCountByPallets = (row: any) => {
|
|
|
|
|
if (!isProductStockOut.value || !Array.isArray(row?.pallets)) return
|
|
|
|
|
const packageQuantity = Number(row.packageQuantity)
|
|
|
|
|
if (!Number.isFinite(packageQuantity)) {
|
|
|
|
|
row.packageCount = undefined
|
|
|
|
|
row.pieceCount = undefined
|
|
|
|
|
row.inputCount = undefined
|
|
|
|
|
row.count = undefined
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const totalPackageCount = getSumValue(row.pallets.map((item: any) => Number(item.packageCount)))
|
|
|
|
|
const pieceCount = totalPackageCount > 0 ? packageQuantity * totalPackageCount : undefined
|
|
|
|
|
row.palletCount = row.pallets.length || undefined
|
|
|
|
|
row.packageCount = totalPackageCount > 0 ? totalPackageCount : undefined
|
|
|
|
|
row.pieceCount = pieceCount
|
|
|
|
|
row.inputCount = pieceCount
|
|
|
|
|
syncCountByInputCount(row)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const isRepairPurpose = (purpose: any) => String(purpose ?? '') === RELATED_PURPOSE_REPAIR
|
|
|
|
|
const isMaintainPurpose = (purpose: any) => String(purpose ?? '') === RELATED_PURPOSE_MAINTAIN
|
|
|
|
|
|
|
|
|
|
@ -906,7 +1253,12 @@ watch(
|
|
|
|
|
() => formData.value.map((row) => [row.inputCount, row.purchaseUnitConvertQuantity]),
|
|
|
|
|
() => {
|
|
|
|
|
if (!isProductMaterialStockOut.value) return
|
|
|
|
|
formData.value.forEach(syncCountByInputCount)
|
|
|
|
|
formData.value.forEach((row) => {
|
|
|
|
|
syncCountByInputCount(row)
|
|
|
|
|
if (isProductStockOut.value && Number(row.outMode) === 2) {
|
|
|
|
|
syncPalletPackageCounts(row)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
{ deep: true }
|
|
|
|
|
)
|
|
|
|
|
@ -919,7 +1271,7 @@ const syncCountByInputCount = (row: any) => {
|
|
|
|
|
row.count = undefined
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (!row.purchaseUnitId && !row.purchaseUnitName) {
|
|
|
|
|
if (isProductStockOut.value || (!row.purchaseUnitId && !row.purchaseUnitName)) {
|
|
|
|
|
row.count = inputCount
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -934,6 +1286,7 @@ const handleInputCountBlur = (row: any) => {
|
|
|
|
|
if (inputCount <= stockCount) return
|
|
|
|
|
row.inputCount = stockCount
|
|
|
|
|
syncCountByInputCount(row)
|
|
|
|
|
syncPalletPackageCounts(row)
|
|
|
|
|
message.warning(t('ErpStock.Item.stockCountExceededWarning'))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -977,6 +1330,9 @@ const fillProductNames = (rows: any[]) => {
|
|
|
|
|
row.purchaseUnitName = row.purchaseUnitName ?? (product as any).purchaseUnitName
|
|
|
|
|
row.supplierName = row.supplierName ?? getDefaultSupplierName(product)
|
|
|
|
|
row.purchaseUnitConvertQuantity = row.purchaseUnitConvertQuantity ?? (product as any).purchaseUnitConvertQuantity
|
|
|
|
|
if (row.packageQuantity == null) {
|
|
|
|
|
fillPackagingSchemeByProduct(row, product)
|
|
|
|
|
}
|
|
|
|
|
syncCountByInputCount(row)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
@ -992,6 +1348,11 @@ const setStockCount = async (row) => {
|
|
|
|
|
|
|
|
|
|
/** 表单校验 */
|
|
|
|
|
const validate = () => {
|
|
|
|
|
formData.value.forEach((row) => {
|
|
|
|
|
syncPalletPackageCounts(row)
|
|
|
|
|
syncInputCountByPallets(row)
|
|
|
|
|
syncCountByInputCount(row)
|
|
|
|
|
})
|
|
|
|
|
return formRef.value.validate()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -1030,6 +1391,11 @@ onMounted(async () => {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.out-mode-radio-group {
|
|
|
|
|
width: 100%;
|
|
|
|
|
justify-content: space-around;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.product-dialog-pagination {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
|