Jelajahi Sumber

收货-批次信息设置判断调整2

zhaohuanhuan 3 minggu lalu
induk
melakukan
511693ef8d
1 mengubah file dengan 130 tambahan dan 60 penghapusan
  1. 130 60
      src/views/inbound/takeDelivery/task/index.vue

+ 130 - 60
src/views/inbound/takeDelivery/task/index.vue

@@ -102,7 +102,7 @@
               <span class="custom-title">{{ item.label }}</span>
             </template>
             <template #value>
-              <div>{{ item.mapping }}</div>
+              <div>{{ lotMap[item.mapping] ||  item.mapping }} </div>
             </template>
           </van-cell>
         </van-cell-group>
@@ -129,6 +129,8 @@
   <attribute ref="attributeRef" @set-attribute="setAttribute" />
   <!--  商品批次属性-->
   <lot-date ref="lotDateRef" @select-lot-date="selectLotDate" />
+  <!--  组合商品-->
+  <barcode-combine ref="barcodeCombineRef" @setCombine="setCombineReceiving" @cancel="onCombineCancel" :container="containerNo" :matched-sku="combineMatchedSku" />
   <!--  唯一码-->
   <unique-code-input ref="uniqueCodeRef"
                      v-model:uniqueCodeList="uniqueCodeList"
@@ -143,7 +145,7 @@
     v-model:show="lotQualityTrueFalseBy"
     cancel-text="取消"
     close-on-click-action
-    description="请选择质量状态"
+    :description="'请选择'+lotTitle"
   >
     <van-cell-group>
       <van-cell v-for="(value,key) in lotQualityMap" @click="onSelectLotQuality(key)">
@@ -168,6 +170,7 @@ import {
   getReceivingAsnDetails,
   setProductAttribute, setReceiving,
 } from '@/api/takeDelivery/index'
+import { getListCombineSku } from '@/api/picking'
 import { closeLoading, showLoading } from '@/utils/loading'
 import { useStore } from '@/store/modules/user'
 import { showNotify, showToast } from 'vant'
@@ -175,7 +178,9 @@ import { isAttribute } from '@/views/inbound/takeDelivery/task/hooks/attribute'
 import Attribute from '@/views/inbound/takeDelivery/components/Attribute.vue'
 import LotDate from '@/views/inbound/takeDelivery/components/LotDate.vue'
 import UniqueCodeInput from '@/views/inbound/takeDelivery/components/UniqueCodeInput.vue'
-import { barcodeToUpperCase, toMap } from '@/utils/dataType.js'
+import BarcodeCombine from '@/views/inbound/takeDelivery/components/BarcodeCombine.vue'
+import { receivingBarcodeCombine } from '@/views/inbound/takeDelivery/task/hooks/barcodeCombine'
+import { barcodeToUpperCase, toMap } from '@/utils/dataType'
 import { getCurrentTime } from '@/utils/date'
 
 const router = useRouter()
@@ -201,6 +206,8 @@ const taskInfo = ref({ receivedQty: 0, expectedQty: 0 })
 const currentTime = ref('--')
 const scanType = ref(2)
 
+//任务号下所有asn单数据
+const allAsnDetailList=ref([])
 const type=localStorage.getItem('checkAllType')?JSON.parse(localStorage.getItem('checkAllType')):true
 const checkAllType=ref(type)
 // 页面初始化
@@ -244,10 +251,9 @@ const stopTimer = () => {
 
 const back = ref(true)
 const inputBarcodeType = ref('task')
-//输入框组件
 const inputBarcodeRef = ref(null)
 const oldSearchBarcode = ref('')
-// 设置容器号
+// 任务号/容器号:code 为任务号时拉取任务及ASN明细
 const setBarcode = (code, type) => {
   if (inputBarcodeType.value === 'lot') {
     lotData.value.forEach((lot) => {
@@ -271,9 +277,6 @@ const setBarcode = (code, type) => {
         taskNo.value=''
         taskInfo.value={}
         switchTask()
-      }else {
-        taskInfo.value=res.data
-        taskNo.value=code
       }
       containerNo.value=''
       stopTimer()
@@ -284,11 +287,15 @@ const setBarcode = (code, type) => {
         startTimer()
         containerNo.value=''
       }
-      taskInfo.value=res.data
-      taskNo.value=code
     }
+    taskInfo.value=res.data
+    taskNo.value=code
     scanType.value=2
     uniqueCodeList.value=[]
+    const params = { warehouse, asnNos: taskInfo.value?.asnNos.join(',') }
+    getReceivingAsnDetails(params).then(res => {
+      allAsnDetailList.value = res.data
+    })
     scanSuccess()
   }).catch(err=>{
     inputBarcodeRef.value?.show('', '请扫描开单任务号',err.message)
@@ -298,9 +305,8 @@ const setBarcode = (code, type) => {
     closeLoading()
   })
 }
-// setBarcode('BSSH20250605000006')
+// setBarcode('BSSH20260318000003')
 
-//切换任务
 const switchTask = () => {
   inputBarcodeType.value = 'switchTask'
   back.value = false
@@ -314,17 +320,24 @@ const asnInfo = ref({})
 const reset = () => {
   asnInfo.value = {}
   lotData.value = []
+  lotMap.value={}
   searchCount.value = ''
   searchBarcode.value = ''
   oldSearchBarcode.value = ''
   uniqueCodeList.value = []
+  combineMatchedSku.value = []
+  combineAsnSelectList.value = []
+  isCombineSelectMode.value = false
+  combineReceivingData.value = []
 }
-// 选择单据
 const onDetailActive = (item) => {
+  if (isCombineSelectMode.value) {
+    _onCombineAsnSelected(item)
+    return
+  }
   asnInfo.value = item
   asnDetailsTrueFalseBy.value = false
   searchCount.value=1
-  // searchCount.value = asnInfo.value.expectedQuantity - asnInfo.value.receivedQuantity
   _getProductAttribute(item)
   _getProductLot(item)
   _getCommodityRule(item)
@@ -333,56 +346,126 @@ const onAsnCancel = () => {
   if (searchBarcode.value === '' || (oldSearchBarcode.value.length != searchBarcode.value.length && oldSearchBarcode.value != '')) {
     asnInfo.value = {}
     lotData.value = []
+    lotMap.value={}
     searchCount.value = ''
   }
 }
 const uniqueCodeList = ref([])
 
-// 扫描条码监听
+// 组合商品
+const barcodeCombineRef = ref(null)
+const combineMatchedSku = ref([])
+const combineAsnSelectList = ref([])
+const isCombineSelectMode = ref(false)
+const combineReceivingData = ref([]) // 确认实收数后暂存,完成收货时提交
+
+// 组合商品只支持1个
+const _handleCombineProduct = (code) => {
+  showLoading()
+  getListCombineSku({ combineSku: barcodeToUpperCase(code), workEnvironment: 'receiving' }).then((res) => {
+    const _err = (msg) => { closeLoading(); scanError(); showNotify({ type: 'danger', duration: 3000, message: msg }); reset() }
+    if (!res.data?.length) return _err(`${code}-商品条码不匹配,请重新扫描`)
+    if (res.data.length > 1) return _err('不支持多商品组合商品')
+    const combineData = res.data
+    const matchedList = receivingBarcodeCombine(allAsnDetailList.value, toMap(combineData, 'barcode'))
+    if (!matchedList.length) return _err('组合商品与待收货数据不匹配,请检查组合商品配置!')
+    const asnGroupMap = matchedList.reduce((acc, detail) => {
+      const key = detail.asnNo
+      if (!acc[key]) acc[key] = { asnNo: detail.asnNo, customerId: detail.customerId, expectedQuantity: 0, list: [] }
+      acc[key].list.push(detail)
+      acc[key].expectedQuantity += (detail.expectedQuantity || 0) - (detail.receivedQuantity || 0)
+      return acc
+    }, {})
+    const asnOptions = Object.values(asnGroupMap)
+    if (asnOptions.length > 1) {
+      isCombineSelectMode.value = true
+      combineAsnSelectList.value = asnOptions
+      combineMatchedSku.value = matchedList
+      asnDetailsList.value = asnOptions.map((opt) => ({ asnNo: opt.asnNo, customerId: opt.customerId, expectedQuantity: opt.expectedQuantity }))
+      asnDetailsTrueFalseBy.value = true
+    } else {
+      _showCombineDialog(matchedList)
+    }
+    closeLoading()
+    scanSuccess()
+  }).catch(() => { closeLoading(); scanError() })
+}
+
+const _showCombineDialog = (matchedList) => {
+  combineMatchedSku.value = matchedList
+  asnInfo.value = matchedList[0]
+  _getProductAttribute(matchedList[0])
+  _getProductLot(matchedList[0])
+  _getCommodityRule(matchedList[0])
+  barcodeCombineRef.value?.show()
+}
+
+// 组合商品取消:收货数量=1套总件数
+const onCombineCancel = () => {
+  const total = combineMatchedSku.value.reduce((sum, row) => sum + (row.matchedJson?.quantity || 0), 0)
+  searchCount.value = total ? String(total) : '1'
+  combineReceivingData.value = []
+}
+
+const _onCombineAsnSelected = (item) => {
+  const selected = combineAsnSelectList.value.find((opt) => opt.asnNo === item.asnNo)
+  if (selected?.list) _showCombineDialog(selected.list)
+  asnDetailsTrueFalseBy.value = isCombineSelectMode.value = false
+  combineAsnSelectList.value = []
+}
+
+// 组合商品确认实收数
+const setCombineReceiving = ({ dataList }) => {
+  if (!dataList?.length) return
+  const total = dataList.reduce((sum, row) => sum + (row.quantity || 0), 0)
+  searchCount.value = String(total)
+  combineReceivingData.value = dataList
+  showNotify({ type: 'success', duration: 2000, message: `已填入收货数量:${total},请点击完成收货提交` })
+}
+
+// 条码扫描:scanType 2商品/4数量/3唯一码/5容器
 const _handlerScan = (code) => {
   if (scanType.value == 2) {
     searchBarcode.value = code
     oldSearchBarcode.value = code
-    const params = { warehouse, barcode: code, asnNos: taskInfo.value?.asnNos.join(',') }
-    showLoading()
-    getReceivingAsnDetails(params).then(res => {
+      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
+      }
       uniqueCodeList.value=[]
-      asnDetailsList.value = res.data
-      if (res.data.length > 0) {
+
+      if (asnDetailsList.value.length > 0) {
         scanSuccess()
         closeLoading()
-        if (res.data.length == 1) {
-          const item = res.data[0]
+        if (asnDetailsList.value.length == 1) {
+          const item = asnDetailsList.value[0]
           asnInfo.value = item
-          // searchCount.value = item.expectedQuantity - item.receivedQuantity
-          searchCount.value=1
+          searchCount.value = 1
           _getProductAttribute(item)
           _getProductLot(item)
           _getCommodityRule(item)
         }
-        if (res.data.length > 1) {
+        if (asnDetailsList.value.length > 1) {
           asnInfo.value = {}
           lotData.value = []
+          lotMap.value={}
           searchCount.value = ''
           uniqueCodeList.value = []
           asnDetailsTrueFalseBy.value = true
         }
       } else {
-        scanError()
-        showNotify({ type: 'danger', duration: 3000, message: `暂未查询到条码《${code}》信息请重试` })
-        reset()
-        closeLoading()
+        _handleCombineProduct(code)
       }
-    }).catch(() => {
-      scanError()
-      closeLoading()
-    })
   } else if (scanType.value == 3) {
     if (code) {
       const uniqueCodeScanType = uniqueCodeRef.value?.uniqueCodeScanType
       if (checkAllType.value && uniqueCodeScanType === 'barcode') {
         const barcode = Array.from(new Set([asnInfo.value.barcode, asnInfo.value.barcode2, asnInfo.value.sku].filter(Boolean)));
-        if (barcode.some(item => barcodeToUpperCase(item) === barcodeToUpperCase(code))) {
+        if (barcode.some((bar) => barcodeToUpperCase(bar) === barcodeToUpperCase(code))) {
           scanSuccess();
           uniqueCodeRef.value.uniqueCodeScanType = 'unique'
           uniqueCodeRef.value.uniqueBarcode = code
@@ -428,9 +511,7 @@ const _handlerScan = (code) => {
     scanType.value=2
   }
 }
-/**
- * 物理属性
- */
+// 物理属性
 const attributeRef = ref(null)
 const attributeMap = ref({})
 const attributeTrueFalseBy = ref(true)
@@ -461,15 +542,10 @@ const setAttribute = (data) => {
     scanError()
   })
 }
-/**
- * 物理属性 end
- */
 
-/**
- * 商品批次属性
- */
-// 获取商品批次属性
+// 批次属性
 const lotData = ref([])
+const lotMap = ref({})
 const _getProductLot = (item) => {
   const params = { warehouse: item.warehouse, owner: item.customerId, barcode: item.sku }
   getProductLot(params).then(res => {
@@ -478,8 +554,12 @@ const _getProductLot = (item) => {
       if (lotField.startsWith('lotAtt') && lotField.length === 8) {
         lot.mapping = item[lotField]
       }
+      if(lot.format){
+        const format =JSON.parse(lot.format)
+        lotMap.value= {...lotMap.value, ...format }
+      }
     })
-    lotData.value = res.data
+    lotData.value = res.data.filter(item => item.lotAttFlag!='隐藏')
     _calculateShelfLife(item, lotData.value)
   })
 }
@@ -506,8 +586,9 @@ const lotField = ref('')
 const lotDateRef = ref(null)
 const lotQualityTrueFalseBy=ref(false)
 const lotQualityMap=ref({})
+const lotTitle=ref('质量状态')
 const onLot = (item) => {
-  console.log(item,"item")
+  lotTitle.value=item.label
   lotField.value = item.field
   if (item.field == 'lotAtt05' ) return
   if (item.type == 'Enum' ){
@@ -574,12 +655,7 @@ const selectLotDate = (date) => {
   inputBarcodeType.value = 'task'
 }
 
-/**
- * 商品批次属性end
- */
-/**
- * 唯一码
- */
+// 唯一码
 const uniqueCodeRef = ref(null)
 //规则列表
 const uniqueRuleList = ref([])
@@ -599,12 +675,9 @@ const _getCommodityRule = (item) => {
     uniqueRuleMap.value = toMap(res.data, 'type', 'uniqueRegExp')
   })
 }
-/**
- * 唯一码end
- */
 const containerNoRef = ref(null)
 const numberRef = ref(null)
-// 完成收货校验
+// 完成收货前校验
 const isCheck = () => {
   if (!asnInfo.value.asnNo) {
     scanError()
@@ -680,7 +753,7 @@ const isCheck = () => {
   }
   return true
 }
-// 收货
+// 完成收货
 const onConfirm = () => {
   if(isCheck()){
     const lotMap = toMap(lotData.value, 'field', 'mapping')
@@ -723,9 +796,6 @@ const loadData = () => {
   if (!taskNo.value) {
     inputBarcodeRef.value?.show('', '请扫描开单任务号','')
     return
-  } else {
-    // currentTime.value=getCurrentTime()
-    // startTimer()
   }
 }
 onUnmounted(() => {