Commit 90de60f4 by qinjianhui

feat: 拣胚完成创建入库单功能

parent 6e1adba3
...@@ -206,6 +206,7 @@ export interface RestockData { ...@@ -206,6 +206,7 @@ export interface RestockData {
export interface PickCompleteData { export interface PickCompleteData {
id: number id: number
warehouseId?: number
warehouseName?: string warehouseName?: string
skuImage?: string skuImage?: string
productName?: string productName?: string
......
...@@ -206,6 +206,7 @@ export interface RestockData { ...@@ -206,6 +206,7 @@ export interface RestockData {
export interface PickCompleteData { export interface PickCompleteData {
id: number id: number
warehouseId?: number
warehouseName?: string warehouseName?: string
skuImage?: string skuImage?: string
productName?: string productName?: string
......
...@@ -84,11 +84,39 @@ ...@@ -84,11 +84,39 @@
:pickable="true" :pickable="true"
@adjust-pick-order-success="open" @adjust-pick-order-success="open"
/> />
<ReceiptProductDialog
ref="receiptProductDialogRef"
v-model:visible="receiptDialogVisible"
v-model:user-mark="receiptUserMark"
v-model:select-sku="receiptSelectSku"
title="创建入库单"
:disable-warehouse="true"
:show-user-mark-filter="false"
:show-query-button="false"
:show-batch-add-button="false"
:show-import-button="false"
:edit-form="receiptEditForm"
:rules="receiptRules"
:warehouse-list="warehouseList"
:other-purchase-data="otherPurchaseData"
:location-list="locationList"
:user-mark-list="userMarkList"
:sku-data="skuData"
:filter-sku-data="filterSkuData"
@warehouse-change="handleReceiptWarehouseChange"
@selection-change="handleReceiptProductSelectionChange"
@set-cost-price="setCostPrice"
@location-change="handleReceiptLocationChange"
@update:remark="updateReceiptRemark"
@update:warehouse-id="updateReceiptWarehouseId"
@delete="deleteReceiptProducts"
@save="handleReceiptSave"
/>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage, ElLoading } from 'element-plus'
import { import {
pickCompleteByIdsDataApi, pickCompleteByIdsDataApi,
pickCompleteApi, pickCompleteApi,
...@@ -96,9 +124,25 @@ import { ...@@ -96,9 +124,25 @@ import {
} from '@/api/factoryOrderNew' } from '@/api/factoryOrderNew'
import type { PickCompleteData } from '@/types/api/factoryOrderNew' import type { PickCompleteData } from '@/types/api/factoryOrderNew'
import type { BaseRespData } from '@/types/api' import type { BaseRespData } from '@/types/api'
import type {
InterProductList,
InterWarehouseDetail,
InterskuList,
ILocation,
} from '@/types/api/warehouse'
import {
warehouseInfoGetAll,
getBySkuAndUserMarkApi,
getByWareHouseIdAndCodeApi,
addInRecordApi,
type warehouseInfo,
} from '@/api/warehouse'
import { useValue } from '@/utils/hooks/useValue'
import { useReceiptProductDialog } from '@/views/warehouse/hooks/useReceiptProductDialog'
import TableView from '@/components/TableView.vue' import TableView from '@/components/TableView.vue'
import Icon from '@/components/Icon.vue' import Icon from '@/components/Icon.vue'
import OperateDetailsDialog from './OperateDetailsDialog.vue' import OperateDetailsDialog from './OperateDetailsDialog.vue'
import ReceiptProductDialog from '@/views/warehouse/components/ReceiptProductDialog.vue'
interface PickData { interface PickData {
overallMessage?: string overallMessage?: string
pickingSituationList?: PickCompleteData[] pickingSituationList?: PickCompleteData[]
...@@ -110,13 +154,182 @@ const emit = defineEmits<{ ...@@ -110,13 +154,182 @@ const emit = defineEmits<{
success: [] success: []
}>() }>()
const receiptRules = {
warehouseId: [{ required: true, message: '请选择仓库', trigger: 'change' }],
}
const [receiptEditForm, resetReceiptEditForm] = useValue<InterWarehouseDetail>({
inNo: '',
warehouseId: '',
warehouseName: '',
remark: '',
factoryCode: '',
factoryId: 0,
productList: [],
})
const receiptDialogVisible = ref(false)
const warehouseList = ref<warehouseInfo[]>([])
const otherPurchaseData = ref<InterProductList[]>([])
const locationList = ref<ILocation[]>([])
const receiptUserMark = ref(0)
const batchUserMark = ref(0)
const importUserMark = ref(0)
const receiptSelectSku = ref('')
const userMarkList = ref<
{ userId: number; userMark: string; userName: string }[]
>([{ userId: 0, userMark: '', userName: '' }])
const { skuData, setCostPrice, filterSkuData } = useReceiptProductDialog({
editForm: receiptEditForm,
otherPurchaseData,
userMark: receiptUserMark,
batchUserMark,
importUserMark,
selectSku: receiptSelectSku,
userMarkList,
})
const receiptProductDialogRef = ref<{
validateForm: () => Promise<void>
} | null>(null)
const otherReceiptSelection = ref<InterProductList[]>([])
const fetchReceiptLocationList = async (query: string) => {
if (!receiptEditForm.value.warehouseId) return
try {
const res = await getByWareHouseIdAndCodeApi(
receiptEditForm.value.warehouseId,
query,
)
const result = res.data || []
locationList.value = result.map((item: ILocation) => ({
locationId: item.id,
locationCode: item.locationCode,
}))
} catch (e) {
console.error(e)
}
}
const updateReceiptRemark = (value: string) => {
receiptEditForm.value.remark = value
}
const updateReceiptWarehouseId = (value: number | string | undefined) => {
receiptEditForm.value.warehouseId = value
}
const handleReceiptWarehouseChange = (val: number | string | undefined) => {
const found = warehouseList.value.find(
(item: warehouseInfo) => item.id === val,
)
receiptEditForm.value.warehouseName = found ? found.name : ''
}
const handleReceiptProductSelectionChange = (v: InterProductList[]) => {
otherReceiptSelection.value = v
}
const handleReceiptLocationChange = (
val: number | null | undefined,
row: InterProductList,
) => {
const found = locationList.value.find(
(item: ILocation) => item.locationId === val,
)
row.locationCode = found ? found.locationCode : ''
}
const deleteReceiptProducts = () => {
const arr = otherReceiptSelection.value
if (arr.length === 0) return
const idList = arr.map((v: InterProductList) => v.warehouseSku)
otherPurchaseData.value = otherPurchaseData.value.filter(
(item: InterProductList) => !idList.includes(item.warehouseSku),
)
}
function mapInterskuToProduct(val: InterskuList): InterProductList {
const warehouseSku = val.warehouseSku || val.sku || ''
const skuNameVal = val.skuName || val.productName || ''
let customerId: number | null = null
if (val.customerId != null && val.customerId !== '') {
const n = Number(val.customerId)
if (!Number.isNaN(n)) customerId = n
}
return {
skuImage: val.skuImage || val.image || '',
warehouseSku,
skuName: skuNameVal,
productNo: val.productNo ?? null,
locationCode: val.locationCode ?? '',
locationId: val.locationId ?? null,
costPrice: val.costPrice ?? null,
buyStored: null,
totalPrice: null,
currencyName: val.currencyName ?? null,
currencyCode: val.currencyCode ?? null,
customerId,
customerName: val.customerName ?? null,
userMark: val.userMark ?? null,
}
}
const handleReceiptSave = async () => {
try {
await receiptProductDialogRef.value?.validateForm()
} catch {
return
}
const arr = otherPurchaseData.value
if (arr.length === 0) {
ElMessage.error('请至少选择一条数据')
return
}
for (let i = 0; i < arr.length; i++) {
if (!arr[i].buyStored) {
ElMessage.error('请输入入库数量')
return
}
if (!arr[i].locationId) {
ElMessage.error('请选择库位')
return
}
const found = locationList.value.find(
(item: ILocation) => item.locationId === arr[i].locationId,
)
if (!arr[i].locationCode) {
arr[i].locationCode = found ? found?.locationCode : ''
}
}
const params = {
...receiptEditForm.value,
productList: otherPurchaseData.value,
}
const loading = ElLoading.service({
text: '保存中...',
background: 'rgba(0, 0, 0, 0.3)',
})
try {
await addInRecordApi(params)
ElMessage.success('保存成功')
receiptDialogVisible.value = false
} catch (e) {
console.error(e)
} finally {
loading.close()
}
}
const visible = ref(false) const visible = ref(false)
const pickData = ref<PickData | null>(null) const pickData = ref<PickData | null>(null)
const selections = ref<PickCompleteData[]>([]) const selections = ref<PickCompleteData[]>([])
const dialogTitle = ref('拣胚完成') const dialogTitle = ref('拣胚完成')
const submitApi = ref<(ids: (number | string)[]) => Promise<BaseRespData<void>>>( const submitApi =
ref<(ids: (number | string)[]) => Promise<BaseRespData<void>>>(
pickCompleteApi, pickCompleteApi,
) )
const columns = [ const columns = [
{ {
...@@ -207,7 +420,9 @@ const open = async ( ...@@ -207,7 +420,9 @@ const open = async (
pickData.value = null pickData.value = null
dialogTitle.value = options?.title || '拣胚完成' dialogTitle.value = options?.title || '拣胚完成'
submitApi.value = submitApi.value =
options?.submitType === 'replenish' ? replenishmentCompleteApi : pickCompleteApi options?.submitType === 'replenish'
? replenishmentCompleteApi
: pickCompleteApi
const loading = ElLoading.service({ const loading = ElLoading.service({
text: '操作中...', text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)', background: 'rgba(0, 0, 0, 0.3)',
...@@ -241,8 +456,62 @@ const handleClose = () => { ...@@ -241,8 +456,62 @@ const handleClose = () => {
pickData.value = null pickData.value = null
} }
const handleCreateInbound = () => { const handleCreateInbound = async () => {
ElMessage.info('创建入库单功能待实现') const partialRows = selections.value.filter(
(r) => r.pickingStatus === 'partial',
)
if (
selections.value.length === 0 ||
!selections.value.every((r) => r.pickingStatus === 'partial')
) {
return ElMessage.warning('请选择需调整拣胚顺序的数据')
}
const firstWid = partialRows[0].warehouseId
if (partialRows.some((r) => r.warehouseId !== firstWid)) {
return ElMessage.error('请选择相同仓库的库存SKU!')
}
resetReceiptEditForm()
otherPurchaseData.value = []
receiptUserMark.value = 0
receiptSelectSku.value = ''
skuData.value = []
otherReceiptSelection.value = []
const userJson = localStorage.getItem('user')
if (userJson) {
try {
const userData = JSON.parse(userJson)
receiptEditForm.value.factoryCode = userData.factoryCode || ''
receiptEditForm.value.factoryId = userData.factoryId || 0
} catch {
// ignore
}
}
receiptEditForm.value.warehouseId = firstWid
receiptEditForm.value.warehouseName = partialRows[0].warehouseName || ''
const wh = warehouseList.value.find((w) => w.id == firstWid)
if (wh) {
receiptEditForm.value.warehouseName = wh.name
}
const loading = ElLoading.service({
text: '加载中...',
background: 'rgba(0, 0, 0, 0.3)',
})
try {
const skus = partialRows.map((r) => r.thirdSkuCode as string)
const res = await getBySkuAndUserMarkApi(firstWid, skus.join(','), null)
if (res.code !== 200) return
otherPurchaseData.value = res.data.map((item: InterskuList) =>
mapInterskuToProduct(item),
)
await fetchReceiptLocationList('')
const listRes = await warehouseInfoGetAll()
warehouseList.value = listRes.data || []
receiptDialogVisible.value = true
} catch (e) {
console.error(e)
} finally {
loading.close()
}
} }
const operateDetailsDialogRef = ref() const operateDetailsDialogRef = ref()
const handleSelectionChange = (selection: PickCompleteData[]) => { const handleSelectionChange = (selection: PickCompleteData[]) => {
......
...@@ -291,7 +291,7 @@ ...@@ -291,7 +291,7 @@
style="width: 150px" style="width: 150px"
> >
<ElOption <ElOption
v-for="(item, index) in ['自有物流', '工厂物流']" v-for="(item, index) in ['自有物流', '九猫统筹物流']"
:key="index" :key="index"
:value="index" :value="index"
:label="item" :label="item"
......
...@@ -191,7 +191,12 @@ ...@@ -191,7 +191,12 @@
size="small" size="small"
@update:model-value="emit('update:selectSku', $event)" @update:model-value="emit('update:selectSku', $event)"
/> />
<el-popover placement="top-start" width="1200" trigger="click"> <el-popover
v-if="showQueryButton"
placement="top-start"
width="1200"
trigger="click"
>
<div v-if="skuData.length > 0" style="height: 50vh"> <div v-if="skuData.length > 0" style="height: 50vh">
<ElTable size="small" :data="filterSkuData" height="100%" border> <ElTable size="small" :data="filterSkuData" height="100%" border>
<ElTableColumn <ElTableColumn
...@@ -354,6 +359,7 @@ const props = withDefaults( ...@@ -354,6 +359,7 @@ const props = withDefaults(
title: string title: string
disableWarehouse?: boolean disableWarehouse?: boolean
showUserMarkFilter?: boolean showUserMarkFilter?: boolean
showQueryButton?: boolean
showBatchAddButton?: boolean showBatchAddButton?: boolean
showImportButton?: boolean showImportButton?: boolean
editForm: InterWarehouseDetail editForm: InterWarehouseDetail
...@@ -370,6 +376,7 @@ const props = withDefaults( ...@@ -370,6 +376,7 @@ const props = withDefaults(
{ {
disableWarehouse: false, disableWarehouse: false,
showUserMarkFilter: true, showUserMarkFilter: true,
showQueryButton: true,
showBatchAddButton: true, showBatchAddButton: true,
showImportButton: true, showImportButton: true,
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment