|
@@ -17,7 +17,12 @@
|
|
|
</div>
|
|
</div>
|
|
|
<div class="info-no-tips">
|
|
<div class="info-no-tips">
|
|
|
<div>货主:<span style="color: #333;font-weight: bold;">{{ taskInfo.customerName || '--' }}</span></div>
|
|
<div>货主:<span style="color: #333;font-weight: bold;">{{ taskInfo.customerName || '--' }}</span></div>
|
|
|
- <div>任务数:<span style="color: #0077ff;font-weight: bold;">{{ taskInfo.receivedQty || 0 }}/{{ taskInfo.expectedQty || 0}}</span></div>
|
|
|
|
|
|
|
+ <div>任务数:<span style="font-weight: bold"
|
|
|
|
|
+ ><span
|
|
|
|
|
+ :style="{
|
|
|
|
|
+ color: (Number(taskInfo.receivedQty || 0) + Number(taskInfo.overReceiveQuantity || 0)) > Number(taskInfo.expectedQty || 0) ? '#ee0a24' : '#0077ff',
|
|
|
|
|
+ }"
|
|
|
|
|
+ >{{ Number(taskInfo.receivedQty || 0) + Number(taskInfo.overReceiveQuantity || 0) }}</span><span style="color: #0077ff">/{{ taskInfo.expectedQty || 0 }}</span></span></div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="take-info-number">
|
|
<div class="take-info-number">
|
|
@@ -48,7 +53,16 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- <van-progress v-if="taskInfo.receivedQty/taskInfo.expectedQty>=0" :percentage="((taskInfo.receivedQty/taskInfo.expectedQty)*100).toFixed(2)" stroke-width="4" />
|
|
|
|
|
|
|
+ <van-progress
|
|
|
|
|
+ v-if="Number(taskInfo.expectedQty) > 0"
|
|
|
|
|
+ :percentage="Number((((Number(taskInfo.receivedQty || 0) + Number(taskInfo.overReceiveQuantity || 0)) / Number(taskInfo.expectedQty)) * 100).toFixed(2))"
|
|
|
|
|
+ :color="(Number(taskInfo.receivedQty || 0) + Number(taskInfo.overReceiveQuantity || 0)) / Number(taskInfo.expectedQty) * 100 > 100 ? '#ee0a24' : '#1989fa'"
|
|
|
|
|
+ stroke-width="4"
|
|
|
|
|
+ />
|
|
|
|
|
+ <div v-if="showOverReceiveTag" class="over-receive-hint" role="status">
|
|
|
|
|
+ <span class="over-receive-hint__badge">超收</span>
|
|
|
|
|
+ <span class="over-receive-hint__text">无待收行明细的收货</span>
|
|
|
|
|
+ </div>
|
|
|
<div class="take-barcode">
|
|
<div class="take-barcode">
|
|
|
<div class="barcode-input">
|
|
<div class="barcode-input">
|
|
|
<van-search
|
|
<van-search
|
|
@@ -77,15 +91,24 @@
|
|
|
autocomplete="off"
|
|
autocomplete="off"
|
|
|
show-action
|
|
show-action
|
|
|
:min="1"
|
|
:min="1"
|
|
|
- :max="asnInfo.asnNo?asnInfo.expectedQuantity-asnInfo.receivedQuantity:10000"
|
|
|
|
|
|
|
+ :max="999999"
|
|
|
@search="isCheck()"
|
|
@search="isCheck()"
|
|
|
:class="[scanType===4?'search-input-barcode':'','van-hairline--bottom']"
|
|
:class="[scanType===4?'search-input-barcode':'','van-hairline--bottom']"
|
|
|
@focus="scanType=4"
|
|
@focus="scanType=4"
|
|
|
>
|
|
>
|
|
|
|
|
+ <!-- :max="asnInfo.asnNo?asnInfo.expectedQuantity-asnInfo.receivedQuantity:10000" -->
|
|
|
<template #action>
|
|
<template #action>
|
|
|
<div style="display: flex; align-items: center;flex-direction: column;margin-left: 20px" v-if="asnInfo.asnNo">
|
|
<div style="display: flex; align-items: center;flex-direction: column;margin-left: 20px" v-if="asnInfo.asnNo">
|
|
|
<div style="height: 20px;font-size: 12px">已收/预计</div>
|
|
<div style="height: 20px;font-size: 12px">已收/预计</div>
|
|
|
- <div style="font-size: 16px;font-weight: bold">{{ asnInfo.receivedQuantity}}/{{ asnInfo.expectedQuantity }}
|
|
|
|
|
|
|
+ <div style="font-size: 16px;font-weight: bold;color: #323233">
|
|
|
|
|
+ <span
|
|
|
|
|
+ :style="{
|
|
|
|
|
+ color:
|
|
|
|
|
+ (Number(asnInfo.receivedQuantity || 0) + Number(asnInfo.overReceiveQuantity || 0)) > Number(asnInfo.expectedQuantity || 0)
|
|
|
|
|
+ ? '#ee0a24'
|
|
|
|
|
+ : '#323233',
|
|
|
|
|
+ }"
|
|
|
|
|
+ >{{ Number(asnInfo.receivedQuantity || 0) + Number(asnInfo.overReceiveQuantity || 0) }}</span>/{{ asnInfo.expectedQuantity }}
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
@@ -108,7 +131,7 @@
|
|
|
</van-cell-group>
|
|
</van-cell-group>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="take-button">
|
|
<div class="take-button">
|
|
|
- <van-button type="primary" size="large" round style="height: 36px" @click="onConfirm">完成收货</van-button>
|
|
|
|
|
|
|
+ <van-button type="primary" size="large" round style="height: 36px" @click="onConfirm(false)">完成收货</van-button>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -116,7 +139,13 @@
|
|
|
<!-- 条码输入组件 -->
|
|
<!-- 条码输入组件 -->
|
|
|
<input-barcode :back="back" @setBarcode="setBarcode" ref="inputBarcodeRef" />
|
|
<input-barcode :back="back" @setBarcode="setBarcode" ref="inputBarcodeRef" />
|
|
|
<!-- 单据选择-->
|
|
<!-- 单据选择-->
|
|
|
- <van-action-sheet v-model:show="asnDetailsTrueFalseBy" cancel-text="取消" description="请选择具体单据" close-on-click-action>
|
|
|
|
|
|
|
+ <van-action-sheet
|
|
|
|
|
+ v-model:show="asnDetailsTrueFalseBy"
|
|
|
|
|
+ cancel-text="取消"
|
|
|
|
|
+ description="请选择具体单据"
|
|
|
|
|
+ close-on-click-action
|
|
|
|
|
+ @closed="onAsnActionSheetClosed"
|
|
|
|
|
+ >
|
|
|
<van-cell-group>
|
|
<van-cell-group>
|
|
|
<van-cell v-for="item in asnDetailsList" @click="onDetailActive(item)">
|
|
<van-cell v-for="item in asnDetailsList" @click="onDetailActive(item)">
|
|
|
<template #title>
|
|
<template #title>
|
|
@@ -140,7 +169,7 @@
|
|
|
:combine-set-count="combineReceivingSetCount"
|
|
:combine-set-count="combineReceivingSetCount"
|
|
|
:asnInfo="asnInfo"
|
|
:asnInfo="asnInfo"
|
|
|
:resolve-panpass-codes="isCombinePanpass ? resolvePanpassScan : undefined"
|
|
:resolve-panpass-codes="isCombinePanpass ? resolvePanpassScan : undefined"
|
|
|
- @setUniqueCode="onConfirm"
|
|
|
|
|
|
|
+ @setUniqueCode="onConfirm(false)"
|
|
|
|
|
|
|
|
/>
|
|
/>
|
|
|
<van-action-sheet
|
|
<van-action-sheet
|
|
@@ -177,7 +206,7 @@ import {
|
|
|
import { getListCombineSku } from '@/api/picking'
|
|
import { getListCombineSku } from '@/api/picking'
|
|
|
import { closeLoading, showLoading } from '@/utils/loading'
|
|
import { closeLoading, showLoading } from '@/utils/loading'
|
|
|
import { useStore } from '@/store/modules/user'
|
|
import { useStore } from '@/store/modules/user'
|
|
|
-import { showNotify, showToast } from 'vant'
|
|
|
|
|
|
|
+import { showNotify, showToast,showConfirmDialog} from 'vant'
|
|
|
import { isAttribute } from '@/views/inbound/takeDelivery/task/hooks/attribute'
|
|
import { isAttribute } from '@/views/inbound/takeDelivery/task/hooks/attribute'
|
|
|
import Attribute from '@/views/inbound/takeDelivery/components/Attribute.vue'
|
|
import Attribute from '@/views/inbound/takeDelivery/components/Attribute.vue'
|
|
|
import LotDate from '@/views/inbound/takeDelivery/components/LotDate.vue'
|
|
import LotDate from '@/views/inbound/takeDelivery/components/LotDate.vue'
|
|
@@ -275,50 +304,61 @@ const setBarcode = (code, type) => {
|
|
|
}
|
|
}
|
|
|
getIReceivingTask({ taskNo:code,version:'V6',warehouse }).then(res=>{
|
|
getIReceivingTask({ taskNo:code,version:'V6',warehouse }).then(res=>{
|
|
|
back.value = true
|
|
back.value = true
|
|
|
- if(res.data.receivedQty==res.data.expectedQty && res.data.expectedQty>0 ){
|
|
|
|
|
- reset()
|
|
|
|
|
- taskNo.value = ''
|
|
|
|
|
- taskInfo.value = {}
|
|
|
|
|
- containerNo.value = ''
|
|
|
|
|
- stopTimer()
|
|
|
|
|
- allAsnDetailList.value = []
|
|
|
|
|
- ownerPanpassEnabled.value = false
|
|
|
|
|
|
|
+ const data = res.data
|
|
|
|
|
+ const applyTaskAfterFetch = () => {
|
|
|
|
|
+ if (!type) {
|
|
|
|
|
+ currentTime.value = getCurrentTime()
|
|
|
|
|
+ startTimer()
|
|
|
|
|
+ containerNo.value = ''
|
|
|
|
|
+ }
|
|
|
|
|
+ taskInfo.value = data
|
|
|
|
|
+ taskNo.value = code
|
|
|
scanType.value = 2
|
|
scanType.value = 2
|
|
|
uniqueCodeList.value = []
|
|
uniqueCodeList.value = []
|
|
|
- if (type) {
|
|
|
|
|
- switchTask()
|
|
|
|
|
|
|
+ const ownerCode = data?.customerId
|
|
|
|
|
+ if (ownerCode) {
|
|
|
|
|
+ getOwnerRule(ownerCode).then((ruleRes) => {
|
|
|
|
|
+ ownerPanpassEnabled.value = !!ruleRes.data?.panpassEnabled
|
|
|
|
|
+ }).catch(() => {
|
|
|
|
|
+ ownerPanpassEnabled.value = false
|
|
|
|
|
+ })
|
|
|
} else {
|
|
} else {
|
|
|
- inputBarcodeType.value = 'task'
|
|
|
|
|
- back.value = true
|
|
|
|
|
- inputBarcodeRef.value?.show('', '请扫描开单任务号', '')
|
|
|
|
|
|
|
+ ownerPanpassEnabled.value = false
|
|
|
}
|
|
}
|
|
|
|
|
+ const params = { warehouse, asnNos: taskInfo.value?.asnNos.join(',') }
|
|
|
|
|
+ getReceivingAsnDetails(params).then((detailRes) => {
|
|
|
|
|
+ allAsnDetailList.value = detailRes.data
|
|
|
|
|
+ })
|
|
|
scanSuccess()
|
|
scanSuccess()
|
|
|
- return
|
|
|
|
|
}
|
|
}
|
|
|
- if(!type){//切换任务成功重启计时器
|
|
|
|
|
- currentTime.value=getCurrentTime()
|
|
|
|
|
- startTimer()
|
|
|
|
|
- containerNo.value=''
|
|
|
|
|
- }
|
|
|
|
|
- taskInfo.value=res.data
|
|
|
|
|
- taskNo.value=code
|
|
|
|
|
- scanType.value=2
|
|
|
|
|
- uniqueCodeList.value=[]
|
|
|
|
|
- const ownerCode = res.data?.customerId
|
|
|
|
|
- if (ownerCode) {
|
|
|
|
|
- getOwnerRule(ownerCode).then((ruleRes) => {
|
|
|
|
|
- ownerPanpassEnabled.value = !!ruleRes.data?.panpassEnabled
|
|
|
|
|
- }).catch(() => {
|
|
|
|
|
- ownerPanpassEnabled.value = false
|
|
|
|
|
|
|
+ if (data.receivedQty == data.expectedQty && data.expectedQty > 0) {
|
|
|
|
|
+ showConfirmDialog({
|
|
|
|
|
+ title: '温馨提示',
|
|
|
|
|
+ message: `${data.taskNo}任务已完成收货,是否继续收货?`,
|
|
|
})
|
|
})
|
|
|
- } else {
|
|
|
|
|
- ownerPanpassEnabled.value = false
|
|
|
|
|
|
|
+ .then(applyTaskAfterFetch)
|
|
|
|
|
+ .catch(() => {
|
|
|
|
|
+ reset()
|
|
|
|
|
+ taskNo.value = ''
|
|
|
|
|
+ taskInfo.value = {}
|
|
|
|
|
+ containerNo.value = ''
|
|
|
|
|
+ stopTimer()
|
|
|
|
|
+ allAsnDetailList.value = []
|
|
|
|
|
+ ownerPanpassEnabled.value = false
|
|
|
|
|
+ scanType.value = 2
|
|
|
|
|
+ uniqueCodeList.value = []
|
|
|
|
|
+ if (type) {
|
|
|
|
|
+ switchTask()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ inputBarcodeType.value = 'task'
|
|
|
|
|
+ back.value = true
|
|
|
|
|
+ inputBarcodeRef.value?.show('', '请扫描开单任务号', '')
|
|
|
|
|
+ }
|
|
|
|
|
+ scanSuccess()
|
|
|
|
|
+ })
|
|
|
|
|
+ return
|
|
|
}
|
|
}
|
|
|
- const params = { warehouse, asnNos: taskInfo.value?.asnNos.join(',') }
|
|
|
|
|
- getReceivingAsnDetails(params).then(res => {
|
|
|
|
|
- allAsnDetailList.value = res.data
|
|
|
|
|
- })
|
|
|
|
|
- scanSuccess()
|
|
|
|
|
|
|
+ applyTaskAfterFetch()
|
|
|
}).catch(err=>{
|
|
}).catch(err=>{
|
|
|
ownerPanpassEnabled.value = false
|
|
ownerPanpassEnabled.value = false
|
|
|
inputBarcodeRef.value?.show('', '请扫描开单任务号',err.message)
|
|
inputBarcodeRef.value?.show('', '请扫描开单任务号',err.message)
|
|
@@ -360,8 +400,23 @@ function resetCombineProductState() {
|
|
|
asnDetailsTrueFalseBy.value = false
|
|
asnDetailsTrueFalseBy.value = false
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/** 超收:多 ASN 选单已打开(无明细造行,选单中) */
|
|
|
|
|
+const overReceiveSheetActive = ref(false)
|
|
|
|
|
+const showOverReceiveTag = computed(
|
|
|
|
|
+ () =>
|
|
|
|
|
+ !!asnInfo.value?.isOverReceive
|
|
|
|
|
+ || (overReceiveSheetActive.value && !!asnDetailsTrueFalseBy.value),
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+const onAsnActionSheetClosed = () => {
|
|
|
|
|
+ if (overReceiveSheetActive.value && !asnInfo.value?.asnNo) {
|
|
|
|
|
+ overReceiveSheetActive.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
const reset = () => {
|
|
const reset = () => {
|
|
|
resetCombineProductState()
|
|
resetCombineProductState()
|
|
|
|
|
+ overReceiveSheetActive.value = false
|
|
|
asnInfo.value = {}
|
|
asnInfo.value = {}
|
|
|
lotData.value = []
|
|
lotData.value = []
|
|
|
lotMap.value={}
|
|
lotMap.value={}
|
|
@@ -376,6 +431,7 @@ const onDetailActive = (item) => {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
asnInfo.value = item
|
|
asnInfo.value = item
|
|
|
|
|
+ overReceiveSheetActive.value = false
|
|
|
asnDetailsTrueFalseBy.value = false
|
|
asnDetailsTrueFalseBy.value = false
|
|
|
searchCount.value=1
|
|
searchCount.value=1
|
|
|
_getProductAttribute(item)
|
|
_getProductAttribute(item)
|
|
@@ -489,16 +545,86 @@ const isCombinePanpass = computed(
|
|
|
() => ownerPanpassEnabled.value && combineReceivingData.value.length > 0,
|
|
() => ownerPanpassEnabled.value && combineReceivingData.value.length > 0,
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * 无 ASN 行明细时(allAsnDetailList 无匹配/为空)的「超收」占位行:不依赖待收货列表校验,由任务号 + 选中 ASN 构造。
|
|
|
|
|
+ */
|
|
|
|
|
+const buildOverReceiveAsnLine = (asnNo, code) => {
|
|
|
|
|
+ const wh = taskInfo.value.warehouse || warehouse
|
|
|
|
|
+ const skuU = barcodeToUpperCase(code)
|
|
|
|
|
+ return {
|
|
|
|
|
+ warehouse: wh,
|
|
|
|
|
+ customerId: taskInfo.value.customerId,
|
|
|
|
|
+ sku: skuU,
|
|
|
|
|
+ barcode: skuU,
|
|
|
|
|
+ asnNo,
|
|
|
|
|
+ expectedQuantity: 0,
|
|
|
|
|
+ receivedQuantity: 0,
|
|
|
|
|
+ /** 与正常 ASN 行区分,用于页面「超收」标记与逻辑 */
|
|
|
|
|
+ isOverReceive: true,
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 组合接口查不到时
|
|
|
|
|
+ */
|
|
|
|
|
+const _fallbackReceiveByProductLotProbe = (code) => {
|
|
|
|
|
+ const { asnNos = [], warehouse, customerId } = taskInfo.value
|
|
|
|
|
+ const item = { warehouse, customerId, sku: barcodeToUpperCase(code) }
|
|
|
|
|
+ const continueOverReceiveLine = (line) => {
|
|
|
|
|
+ overReceiveSheetActive.value = false
|
|
|
|
|
+ asnInfo.value = line
|
|
|
|
|
+ searchCount.value = 1
|
|
|
|
|
+ _getProductAttribute(line)
|
|
|
|
|
+ _getProductLot(line)
|
|
|
|
|
+ _getCommodityRule(line)
|
|
|
|
|
+ closeLoading()
|
|
|
|
|
+ scanSuccess()
|
|
|
|
|
+ }
|
|
|
|
|
+ _getProductLot(item)
|
|
|
|
|
+ .then(() => {
|
|
|
|
|
+ if (lotData.value.length === 0) {
|
|
|
|
|
+ closeLoading()
|
|
|
|
|
+ scanError()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (asnNos.length === 0) {
|
|
|
|
|
+ closeLoading()
|
|
|
|
|
+ scanError()
|
|
|
|
|
+ showNotify({ type: 'danger', duration: 3000, message: '任务无 ASN 单,无法超收' })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (asnNos.length > 1) {
|
|
|
|
|
+ const synthetic = asnNos.map((asnNo) => buildOverReceiveAsnLine(asnNo, code))
|
|
|
|
|
+ asnDetailsList.value = synthetic
|
|
|
|
|
+ asnInfo.value = {}
|
|
|
|
|
+ lotData.value = []
|
|
|
|
|
+ lotMap.value = {}
|
|
|
|
|
+ searchCount.value = ''
|
|
|
|
|
+ uniqueCodeList.value = []
|
|
|
|
|
+ overReceiveSheetActive.value = true
|
|
|
|
|
+ asnDetailsTrueFalseBy.value = true
|
|
|
|
|
+ closeLoading()
|
|
|
|
|
+ scanSuccess()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ continueOverReceiveLine(buildOverReceiveAsnLine(asnNos[0], code))
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(() => {
|
|
|
|
|
+ closeLoading()
|
|
|
|
|
+ scanError()
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// 组合商品只支持1个
|
|
// 组合商品只支持1个
|
|
|
const _handleCombineProduct = (code) => {
|
|
const _handleCombineProduct = (code) => {
|
|
|
showLoading()
|
|
showLoading()
|
|
|
getListCombineSku({ combineSku: barcodeToUpperCase(code), workEnvironment: 'receiving' }).then((res) => {
|
|
getListCombineSku({ combineSku: barcodeToUpperCase(code), workEnvironment: 'receiving' }).then((res) => {
|
|
|
const _err = (msg) => { closeLoading(); scanError(); showNotify({ type: 'danger', duration: 3000, message: msg }); reset() }
|
|
const _err = (msg) => { closeLoading(); scanError(); showNotify({ type: 'danger', duration: 3000, message: msg }); reset() }
|
|
|
- if (!res.data?.length) return _err(`${code}-商品条码不匹配,请重新扫描`)
|
|
|
|
|
|
|
+ if (!res.data?.length) return _fallbackReceiveByProductLotProbe(code)
|
|
|
if (res.data.length > 1) return _err('不支持多商品组合商品')
|
|
if (res.data.length > 1) return _err('不支持多商品组合商品')
|
|
|
const combineData = res.data
|
|
const combineData = res.data
|
|
|
const matchedList = receivingBarcodeCombine(allAsnDetailList.value, toMap(combineData, 'barcode'))
|
|
const matchedList = receivingBarcodeCombine(allAsnDetailList.value, toMap(combineData, 'barcode'))
|
|
|
- if (!matchedList.length) return _err('组合商品与待收货数据不匹配,请检查组合商品配置!')
|
|
|
|
|
|
|
+ if (!matchedList.length) return _fallbackReceiveByProductLotProbe(code)
|
|
|
const asnGroupMap = matchedList.reduce((acc, detail) => {
|
|
const asnGroupMap = matchedList.reduce((acc, detail) => {
|
|
|
const key = detail.asnNo
|
|
const key = detail.asnNo
|
|
|
if (!acc[key]) acc[key] = { asnNo: detail.asnNo, customerId: detail.customerId, expectedQuantity: 0, list: [] }
|
|
if (!acc[key]) acc[key] = { asnNo: detail.asnNo, customerId: detail.customerId, expectedQuantity: 0, list: [] }
|
|
@@ -562,17 +688,19 @@ let productLotGeneration = 0
|
|
|
// 条码扫描:scanType 2商品/4数量/3唯一码/5容器
|
|
// 条码扫描:scanType 2商品/4数量/3唯一码/5容器
|
|
|
const _handlerScan = (code) => {
|
|
const _handlerScan = (code) => {
|
|
|
if (scanType.value == 2) {
|
|
if (scanType.value == 2) {
|
|
|
- searchBarcode.value = code
|
|
|
|
|
- oldSearchBarcode.value = code
|
|
|
|
|
|
|
+ searchBarcode.value = code
|
|
|
|
|
+ oldSearchBarcode.value = code
|
|
|
resetCombineProductState()
|
|
resetCombineProductState()
|
|
|
- if ( allAsnDetailList.value.length > 0) {
|
|
|
|
|
- const upperCode = barcodeToUpperCase(code) || ''
|
|
|
|
|
- const clientMatched = allAsnDetailList.value.filter((detail) => {
|
|
|
|
|
- const bars = [detail.barcode, detail.barcode2, detail.sku].filter(Boolean)
|
|
|
|
|
- return bars.some((bar) => bar && barcodeToUpperCase(bar) === upperCode)
|
|
|
|
|
- })
|
|
|
|
|
- asnDetailsList.value = clientMatched
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ overReceiveSheetActive.value = false
|
|
|
|
|
+ const upperCode = barcodeToUpperCase(code) || ''
|
|
|
|
|
+ const clientMatched =
|
|
|
|
|
+ allAsnDetailList.value.length > 0
|
|
|
|
|
+ ? allAsnDetailList.value.filter((detail) => {
|
|
|
|
|
+ const bars = [detail.barcode, detail.barcode2, detail.sku].filter(Boolean)
|
|
|
|
|
+ return bars.some((bar) => bar && barcodeToUpperCase(bar) === upperCode)
|
|
|
|
|
+ })
|
|
|
|
|
+ : []
|
|
|
|
|
+ asnDetailsList.value = clientMatched
|
|
|
uniqueCodeList.value=[]
|
|
uniqueCodeList.value=[]
|
|
|
|
|
|
|
|
if (asnDetailsList.value.length > 0) {
|
|
if (asnDetailsList.value.length > 0) {
|
|
@@ -692,7 +820,7 @@ const _getProductLot = (item) => {
|
|
|
lotMap.value = {}
|
|
lotMap.value = {}
|
|
|
lotData.value = []
|
|
lotData.value = []
|
|
|
const params = { warehouse: item.warehouse, owner: item.customerId, barcode: item.sku }
|
|
const params = { warehouse: item.warehouse, owner: item.customerId, barcode: item.sku }
|
|
|
- getProductLot(params).then((res) => {
|
|
|
|
|
|
|
+ return getProductLot(params).then((res) => {
|
|
|
if (gen !== productLotGeneration) return
|
|
if (gen !== productLotGeneration) return
|
|
|
const rows = res.data
|
|
const rows = res.data
|
|
|
if (!rows?.length) {
|
|
if (!rows?.length) {
|
|
@@ -824,6 +952,9 @@ const _getCommodityRule = (item) => {
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
uniqueRuleMap.value = toMap(res.data, 'type', 'uniqueRegExp')
|
|
uniqueRuleMap.value = toMap(res.data, 'type', 'uniqueRegExp')
|
|
|
|
|
+ }).catch(() => {
|
|
|
|
|
+ closeLoading()
|
|
|
|
|
+ scanError()
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
const containerNoRef = ref(null)
|
|
const containerNoRef = ref(null)
|
|
@@ -844,8 +975,13 @@ const isCheck = () => {
|
|
|
}
|
|
}
|
|
|
return false
|
|
return false
|
|
|
}
|
|
}
|
|
|
- // //商品批次属性判断
|
|
|
|
|
- const incompleteLot = lotData.value.find(lot => lot.require && !lot.mapping)
|
|
|
|
|
|
|
+ // //商品批次属性判断(超收不校验 lotAtt05 必填)
|
|
|
|
|
+ const incompleteLot = lotData.value.find(
|
|
|
|
|
+ (lot) =>
|
|
|
|
|
+ lot.require &&
|
|
|
|
|
+ !lot.mapping &&
|
|
|
|
|
+ !(asnInfo.value.isOverReceive && lot.field === 'lotAtt05'),
|
|
|
|
|
+ )
|
|
|
if (incompleteLot) {
|
|
if (incompleteLot) {
|
|
|
scanError()
|
|
scanError()
|
|
|
showToast({ duration: 3000, message: `请先补充${incompleteLot.label}` })
|
|
showToast({ duration: 3000, message: `请先补充${incompleteLot.label}` })
|
|
@@ -863,12 +999,6 @@ const isCheck = () => {
|
|
|
showToast({ duration: 3000, message: `失效日期不能小于等于生产日期` })
|
|
showToast({ duration: 3000, message: `失效日期不能小于等于生产日期` })
|
|
|
return false
|
|
return false
|
|
|
}
|
|
}
|
|
|
- // // 检查失效日期是否小于当前日期
|
|
|
|
|
- // if (expirationDate <= currentDate) {
|
|
|
|
|
- // scanError()
|
|
|
|
|
- // showToast({ duration: 3000, message: `失效日期不能小于等于当前日期` })
|
|
|
|
|
- // return false
|
|
|
|
|
- // }
|
|
|
|
|
}
|
|
}
|
|
|
if(productionDate){
|
|
if(productionDate){
|
|
|
// 如果有生产日期,进行有效性检查
|
|
// 如果有生产日期,进行有效性检查
|
|
@@ -908,10 +1038,10 @@ const isCheck = () => {
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
|
// 完成收货
|
|
// 完成收货
|
|
|
-const onConfirm = () => {
|
|
|
|
|
|
|
+const onConfirm = (confirmOverReceive=false) => {
|
|
|
if(isCheck()){
|
|
if(isCheck()){
|
|
|
const lotMap = toMap(lotData.value, 'field', 'mapping')
|
|
const lotMap = toMap(lotData.value, 'field', 'mapping')
|
|
|
- const { asnLineNo, asnNo, warehouse,customerId } = asnInfo.value
|
|
|
|
|
|
|
+ const { asnLineNo, asnNo, warehouse,customerId,sku} = asnInfo.value
|
|
|
const {taskNo: taskCode } = taskInfo.value
|
|
const {taskNo: taskCode } = taskInfo.value
|
|
|
const data = {
|
|
const data = {
|
|
|
asnLineNo,
|
|
asnLineNo,
|
|
@@ -922,18 +1052,32 @@ const onConfirm = () => {
|
|
|
customerId,
|
|
customerId,
|
|
|
serialNos: uniqueCodeList.value.length > 0 ? uniqueCodeList.value : undefined,
|
|
serialNos: uniqueCodeList.value.length > 0 ? uniqueCodeList.value : undefined,
|
|
|
...lotMap,
|
|
...lotMap,
|
|
|
- taskNo:taskCode
|
|
|
|
|
|
|
+ taskNo:taskCode,
|
|
|
|
|
+ sku,
|
|
|
|
|
+ confirmOverReceive
|
|
|
}
|
|
}
|
|
|
showLoading()
|
|
showLoading()
|
|
|
inputBarcodeType.value='task'
|
|
inputBarcodeType.value='task'
|
|
|
setReceiving(data).then(res => {
|
|
setReceiving(data).then(res => {
|
|
|
- scanSuccess()
|
|
|
|
|
- showNotify({ type: 'success', duration: 3000, message: `${searchBarcode.value}收货完成,请继续收货!`})
|
|
|
|
|
- setBarcode(taskNo.value, '2')
|
|
|
|
|
- reset()
|
|
|
|
|
- taskInfo.value={}
|
|
|
|
|
- scanType.value=2
|
|
|
|
|
- closeLoading()
|
|
|
|
|
|
|
+ console.log('res',res)
|
|
|
|
|
+ if(res.data.overReceive){
|
|
|
|
|
+ scanError()
|
|
|
|
|
+ showConfirmDialog({
|
|
|
|
|
+ title: '温馨提示',
|
|
|
|
|
+ message: '是否确认超收?',
|
|
|
|
|
+ }).then(() => {
|
|
|
|
|
+ onConfirm(true)
|
|
|
|
|
+ }).catch(() => {
|
|
|
|
|
+ })
|
|
|
|
|
+ }else{
|
|
|
|
|
+ scanSuccess()
|
|
|
|
|
+ showNotify({ type: 'success', duration: 3000, message: `${searchBarcode.value}收货完成,请继续收货!`})
|
|
|
|
|
+ setBarcode(taskNo.value, '2')
|
|
|
|
|
+ reset()
|
|
|
|
|
+ taskInfo.value={}
|
|
|
|
|
+ scanType.value=2
|
|
|
|
|
+ closeLoading()
|
|
|
|
|
+ }
|
|
|
}).catch(err => {
|
|
}).catch(err => {
|
|
|
if(err.message.includes('序列号已存在')){
|
|
if(err.message.includes('序列号已存在')){
|
|
|
scanType.value = 3
|
|
scanType.value = 3
|
|
@@ -941,8 +1085,10 @@ const onConfirm = () => {
|
|
|
}
|
|
}
|
|
|
scanError()
|
|
scanError()
|
|
|
closeLoading()
|
|
closeLoading()
|
|
|
|
|
+ }).finally(() => {
|
|
|
|
|
+ closeLoading()
|
|
|
})
|
|
})
|
|
|
- }
|
|
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 数据刷新
|
|
// 数据刷新
|
|
@@ -960,6 +1106,36 @@ window.onRefresh = loadData
|
|
|
|
|
|
|
|
</script>
|
|
</script>
|
|
|
<style scoped lang="scss">
|
|
<style scoped lang="scss">
|
|
|
|
|
+.over-receive-hint {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ margin: 8px 10px 0;
|
|
|
|
|
+ padding: 8px 10px;
|
|
|
|
|
+ background: #fff4e5;
|
|
|
|
|
+ border: 1px solid #f5d4a3;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: #8a5a00;
|
|
|
|
|
+ line-height: 1.4;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.over-receive-hint__badge {
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ padding: 2px 8px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ background: linear-gradient(135deg, #e67e22, #d35400);
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.over-receive-hint__text {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ text-align: left;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.take-delivery {
|
|
.take-delivery {
|
|
|
.take-info {
|
|
.take-info {
|
|
|
padding: 6px 10px;
|
|
padding: 6px 10px;
|