You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

824 lines
26 KiB

<template>
<view>
<u-popup v-model="show" mode="bottom">
<view class="">
<view class="popup_box">
<view class="pop_title">
扫描箱码
<text class="fr" @click="closeScanPopup()">关闭</text>
</view>
<!-- <view class="uni-flex uni-row" style="align-items: center; background-color: #fff; margin-left: 20rpx; margin-right: 20rpx; margin-top: 8rpx; border-radius: 8rpx">-->
<!-- <view class="uni-center" style="width: 25%"> 来源库位 </view>-->
<!-- <view class="" style="width: 75%; padding: 8rpx">-->
<!-- <uni-combox :candidates="fromLocationList" v-model="fromLocationCode" placeholder="请选择库位" @confirm="fromLocationUpdate"></uni-combox>-->
<!-- </view>-->
<!-- </view>-->
<view class="">
<view class="">
<win-com-scan ref="comscan" placeholder="箱标签" @getResult="onScan" :clearResult="true" headerType="HPQ,HMQ" :isShowHistory="false"> </win-com-scan>
<view style="width: 100%">
<view style="width: 100%" v-if="issueRecord.length > 0">
<view class="uni-flex uni-row space-between u-col-center">
<view class="" style="padding: 10rpx"> 历史记录 </view>
<view class="" style="padding-right: 10rpx">
<u-icon :name="expendIcon" size="35rpx" @click="expands()"></u-icon>
</view>
</view>
<u-line class="line_color" style="padding-top: 10rpx; padding-bottom: 20rpx"> </u-line>
<scroll-view :scroll-y="true" class="scroll-view" v-if="expand && issueRecord.length > 0" style="width: 100%">
<u-swipe-action :show="item.show" :index="index" v-for="(item, index) in issueRecord" :key="index" :options="scanOptions" bg-color="rgba(255,255,255,0)" @click="(...event) => swipeClick($event, item)">
<view style="padding: 0px 10px">
<balance :dataContent="item" :isShowFromLocation="false" :isShowStatus="true" :isShowStdPack="false"></balance>
</view>
</u-swipe-action>
</scroll-view>
</view>
</view>
</view>
</view>
</view>
</view>
</u-popup>
<balance-select ref="balanceSelectRef" @onSelectItem="selectBalanceItem"></balance-select>
<com-message ref="comMessageRef" />
<balance-qty-edit ref="balanceQtyEditRef" @confirm="confirm" :isShowStatus="true"></balance-qty-edit>
</view>
</template>
<script setup lang="ts">
import { ref, getCurrentInstance, nextTick, onMounted } from 'vue'
import winComScan from '@/mycomponents/scan/winComScan.vue'
import balance from '@/mycomponents/balance/balance.vue'
import balanceQtyEdit from '@/mycomponents/qty/balanceQtyEdit.vue'
import balanceSelect from '@/mycomponents/balance/balanceSelect.vue'
import { getDetailOption, getDetailEditRemoveOption, getDetailGiveupOption } from '@/common/array.js'
import { getWorkShopLineStation, getBalanceByFilter, getBalanceByParams } from '@/api/request2.js'
import { calc } from '@/common/calc.js'
import { uniqueArray } from '@/common/basic.js'
import { getBalanceByManagementPrecision } from '@/common/balance.js'
import { getDirectoryItemArray,getInventoryStatusDesc,getListLocationAreaTypeDesc } from '../../../common/directory.js'
import { getLabelInfo } from '@/common/label.js'
const props = defineProps({
title: {
type: String,
default: ''
}
})
const dataContent = ref({})
const jobContent = ref({})
const expendIcon = ref('arrow-down')
const show = ref(false)
const scanList = ref([])
const toLocation = ref(null)
const toLocationCode = ref('')
const fromLocationList = ref([])
const fromLocationCode = ref('')
const fromLocation = ref(null)
const issueRecord = ref([]) // 发料历史
const expand = ref(true)
const scanOptions = ref({})
const editItem = ref({})
const positionList = ref([])
const defaultValueList = ref([])
const label = ref({})
const fromInventoryStatuses = ref('')
const packageInfo = ref({})
const comMessageRef = ref('')
const balanceSelectRef = ref()
const toLocationCombox = ref()
const comscan = ref()
const balanceQtyEditRef = ref()
const detailOptions = ref([])
const detailGiveupOptions = ref([])
const toLocationAreaTypeList = ref([])
onMounted(() => {
detailOptions.value = getDetailOption()
detailGiveupOptions.value = getDetailGiveupOption()
})
const openScanPopup = (content, jobcontent) => {
issueRecord.value = []
dataContent.value = content
jobContent.value = jobcontent
initData()
setTimeout((res) => {
show.value = true
getfocus()
}, 500)
}
const openScanPopupForJobSimulate = (content, jobcontent, scanMessage) => {
issueRecord.value = []
dataContent.value = content
jobContent.value = jobcontent
initData()
getLabelInfo(scanMessage, headerType.value, (callback) => {
if (callback.success) {
onScan(callback)
} else {
showErrorMessage(callback.message)
}
})
}
const closeScanPopup = () => {
losefocus()
show.value = false
emit('closeScan')
// 清除数据,恢复默认值
// Object.assign(this.$data, this.$options.data());
}
const initData = () => {
fromLocationList.value = []
if (dataContent.value != null) {
fromInventoryStatuses.value = jobContent.value.outInventoryStatuses
toLocation.value = dataContent.value[0]
toLocationCode.value = dataContent.value[0].toLocationCode
toLocationAreaTypeList.value = getDirectoryItemArray(jobContent.value.toAreaTypes)
// fromLocationList.value = getFromLocationList()
}
}
const showBalanceSelect = (items) => {
balanceSelectRef.value.openPopup(items)
}
// const getFromLocationList = () => {
// let list = []
// const location = dataContent.value.find((r) => r.toLocationCode == toLocationCode.value)
// if (location != undefined) {
// location.Items.forEach((item) => {
// item.Locations.forEach((f) => {
// list.push(f.fromLocationCode)
// })
// })
// // 去掉重复库位
// list = uniqueArray(list)
// fromLocationCode.value = list[0]
// return list
// }
// comMessageRef.value.showErrorMessages(`需求库位【${toLocationCode.value}】不存在`, (res) => {
// if (res) {
// scanMsg.value = ''
// getfocus()
// }
// })
// }
const fromLocationUpdate = (fromlocation) => {
const location = fromLocationList.value.find((r) => r == fromlocation)
if (location == undefined) {
fromLocationCode.value = ''
showErrorMessage(`发料库位【${fromlocation}】不存在`,()=>{
getfocus()
})
}
}
const onScan = (result)=> {
if (!result.package) {
this.showErrorMessage('扫描数据错误[' + result.label.code + "]",
res => {
getfocus();
}
)
return;
}
if (toLocation.value && result.package.packUnit) {
let item = toLocation.value.Items.find(r => r.itemCode == result.package.itemCode);
if (!item) {
showErrorMessage('扫描物料代码不属于该任务',()=>{
getfocus()
});
return
}
if (result.package.packUnit !== item.packUnit) {
comMessageRef.value.showQuestionMessage(
`扫描物料包装【${result.package.packUnit}】与任务推荐包装规格【${item.packUnit}】不一致.是否要继续发料?`, res => {
if (res) {
getToLocationBalance(result)
}
});
} else {
getToLocationBalance(result)
}
}else{
getToLocationBalance(result)
}
}
//查询到目标库位的库存余额
const getToLocationBalance = (result)=> {
uni.showLoading({
title: '查询中',
mask: true
})
let filters = []
if (result.package.parentNumber) {
let packingNumber = result.package.parentNumber + "," + result.package.number;
filters.push({
column: "packingNumber",
action: "in",
value: packingNumber
})
} else {
filters.push({
column: "packingNumber",
action: "==",
value: result.package.number
})
}
filters.push({
column: "itemCode",
action: "==",
value: result.package.itemCode
})
filters.push({
column: "batch",
action: "==",
value: result.package.batch
})
filters.push({
column: "areaType",
action: "in",
value: toLocationAreaTypeList.value.join(',')
})
var params = {
filters: filters,
pageNo: 1,
pageSize: 100,
}
getBalanceByFilter(params).then(res => {
uni.hideLoading()
if (res.data.list.length > 0) {
showErrorMessage("包装在库位【" + res.data.list[0].locationCode + "】已有库存余额",()=>{
getfocus()
});
} else {
queryBalance(result);
}
// callback(res.data)
}).catch(err => {
uni.hideLoading()
showErrorMessage(err.message,()=>{
getfocus()
});
})
}
const queryBalance = (result) => {
try {
// if (fromLocationCode.value == '') {
// showErrorMessage('请选择来源库位', (res) => {
// toLocationCombox.value.onFocus()
// })
// return
// }
const packageInfoParams = result.package
const { itemCode } = result.label
const packingCode = result.label.packingNumber
const lot = result.label.batch
const item = toLocation.value.Items.find((r) => r.itemCode == itemCode)
if (item == undefined) {
showErrorMessage(`未查找到物料【${itemCode}】的发料明细`, (res) => {
getfocus()
})
return
}
var params = {
itemCode: result.package.itemCode,
batch: result.label.batch,
packingNumber: result.label.packingNumber,
parentPackingNumber: result.package.parentNumber,
inventoryStatus: jobContent.value.outInventoryStatuses.split(','),
areaType: jobContent.value.fromAreaTypes.split(','),
bussinessCode: jobContent.value.businessType
}
// 查找库存信息
uni.showLoading({
title: '查询中',
mask: true
})
getBalanceByParams(params).then(res => {
if (res.data.length == 0) {
let status = getInventoryStatusDesc(params.inventoryStatus)
let areaType = getListLocationAreaTypeDesc(params.areaType)
let hint =
"按物料号 [" + params.itemCode + "] \n" +
"包装号 [" + params.packingNumber + "] \n" +
"批次 [" + params.batch + "] \n" +
"状态 [" + status + "] \n" +
"库区 [" + areaType + "] \n" +
"未查找到库存余额"
showErrorMessage(hint,()=>{
getfocus()
})
} else if (res.data.length == 1) {
result.balance = res.data[0]
if (result.label.packingNumber != result.balance.packingNumber) {
result.balance.qty = Number(result.label.qty)
} else {
result.balance.qty = Number(result.balance.qty)
}
afterGetBalance(result.label, result.balance, result.package);
} else {
//多条记录
balanceSelectRef.value.openPopup(res.data);
}
uni.hideLoading()
}).catch(error => {
uni.hideLoading()
showErrorMessage(error,()=>{
getfocus()
})
})
// getBalance(result.label, packageInfoParams, (balances) => {
// packageInfo.value = packageInfoParams
// // 扫描的是外包装
// const s = ''
// if (!result.package.parentNumber) {
// if (balances.list.length == 0) {
// showErrorMessage('未查找到该包装的库存信息,请重新扫描')
// } else {
// const newBalances = balances.list.filter((b) => b.locationCode == that.fromLocationCode)
// if (newBalances.length == 0) {
// showErrorMessage('未查找到该包装的库存信息,请重新扫描')
// } else if (newBalances.length == 1) {
// const balance1 = newBalances[0]
// afterGetBalance(result.label, balance1, packageInfoParams)
// } else {
// showBalanceSelect(newBalances)
// }
// }
// } else {
// // 扫描的是小包装
// if (balances.list.length == 0) {
// showErrorMessage('未查找到该包装的库存信息,请重新扫描')
// } else {
// // 小包装库存
// const subPackitems = balances.list.filter((r) => r.packingNumber == packageInfoParams.number)
// // 外包装库存
// const subParentPackitems = balances.list.filter((r) => r.packingNumber == packageInfoParams.parentNumber && r.locationCode == fromLocationCode.value)
//
// // 小包装没有库存,
// if (subPackitems.length == 0) {
// // 外包装有库存,出库后剩余库存未转换为出库包装规格
//
// if (subParentPackitems.length > 0) {
// if (subParentPackitems.length == 1) {
// const balance = subParentPackitems[0]
// balance.qty = packageInfoParams.qty
// afterGetBalance(result.label, balance, packageInfoParams)
// } else {
// showBalanceSelect(subParentPackitems)
// }
// } else {
// showErrorMessage(`按外包装【${packageInfoParams.parentNumber}】和子包装【${packageInfoParams.number}】都未查找到库存余额`)
// }
// } else {
// let locationCode = fromLocationCode.value
// if (balances.list == 1) {
// locationCode = balances.list[0].locationCode
// } else {
// const manyBlances = balances.list.filter((r) => r.locationCode != fromLocationCode.value)
// if (manyBlances.length > 0) {
// locationCode = manyBlances[0].locationCode
// }
// }
// showErrorMessage(`该包装【${packageInfoParams.number}】在库位【${locationCode}】已经有库存余额,请重新扫描`)
// }
// }
// }
// uni.hideLoading()
// })
} catch (e) {
showErrorMessage(e.stack,()=>{
getfocus()
})
uni.hideLoading()
}
}
// const getBalance = (labelParams, packageInfo, callback) => {
// const filters = []
// if (packageInfo.parentNumber) {
// const packingNumber = `${packageInfo.parentNumber},${labelParams.packingNumber}`
// filters.push({
// column: 'packingNumber',
// action: 'in',
// value: packingNumber
// })
// } else {
// filters.push({
// column: 'packingNumber',
// action: '==',
// value: labelParams.packingNumber
// })
// }
// filters.push({
// column: 'packingNumber',
// action: '==',
// value: labelParams.packingNumber
// })
// filters.push({
// column: 'itemCode',
// action: '==',
// value: labelParams.itemCode
// })
// filters.push({
// column: 'batch',
// action: '==',
// value: labelParams.batch
// })
//
// if (fromInventoryStatuses.value != null && fromInventoryStatuses.value != '') {
// filters.push({
// column: 'inventoryStatus',
// action: 'in',
// value: fromInventoryStatuses.value
// })
// }
//
// const params = {
// filters,
// pageNo: 1,
// pageSize: 100
// }
// getBalanceByFilter(params)
// .then((res) => {
// callback(res.data)
// })
// .catch((err) => {
// showErrorMessage(err.message)
// })
// }
const selectBalanceItem = (balanceParams) => {
afterGetBalance(balanceParams, balanceParams, packageInfo.value)
}
const afterGetBalance = (labelParams, balanceParams, packageInfo) => {
try {
const { itemCode } = labelParams
const packingCode = labelParams.packingNumber
const lot = labelParams.batch
const item = toLocation.value.Items.find((r) => r.itemCode == itemCode)
fromLocationCode.value = balanceParams.locationCode;
const fromLocation = item.Locations.find((l) => l.fromLocationCode == fromLocationCode.value)
//如果库存余额中的库位与任务推荐的不一致
if (fromLocation) {
const batch = fromLocation.Batchs.find((r) => r.batch == lot)
if (batch != undefined) {
if (batch.Records == undefined) {
batch.Records = []
}
const record = batch.Records.find((r) => r.packingNumber == packingCode)
if (record == undefined) {
// 如果有推荐箱码
if (batch.Recommends != undefined && batch.Recommends.length > 0) {
const recommend = batch.Recommends.find((r) => r.packingNumber == packingCode)
if (recommend != undefined) {
addRecord(batch, labelParams, balanceParams, packageInfo)
} else {
// 允许修改箱码
if (jobContent.value.allowModifyPackingNumber == 'TRUE') {
addRecord(batch, labelParams, balanceParams, packageInfo)
} else {
showErrorMessage(`未查找到该箱码【${packingCode}】的明细`, (res) => {
getfocus()
})
}
}
} else {
addRecord(batch, labelParams, balanceParams, packageInfo)
}
} else {
showErrorMessage(`箱码【${packingCode}】已经扫描,请继续扫描下一箱`, (res) => {
getfocus()
})
}
} else if (jobContent.value.allowModifyBatch == 'TRUE') {
showQuestionMessage(`在【${fromLocationCode.value}】库位下,批次【${lot}】不是推荐批次,是否要继续发料?`, (res) => {
if (res) {
const batch = createBatchInfo(labelParams, balanceParams, packageInfo)
if (fromLocation.Batchs.length > 0) {
batch.detail = fromLocation.Batchs[0].detail
}
fromLocation.Batchs.unshift(batch)
getfocus()
}
})
} else {
showErrorMessage(`未查找到批次【${lot}】的发料明细`, (res) => {
getfocus()
})
}
} else {
if (jobContent.value.allowModifyLocation == "TRUE") {
this.showQuestionMessage("扫描物料[" + itemCode + "]的库位【" + fromLocationCode.value +
"】与推荐的库位不一致,是否要继续发料?", res => {
if (res) {
let locaion = createLocationInfo(label, balance, packageInfo);
item.Locations.push(locaion);
getfocus();
emit("afterScan");
}
})
} else {
showErrorMessage("扫描物料[" + itemCode + "]的库位【" + fromLocationCode.value +
"】与推荐的库位不一致,不允许继续发料?")
}
}
} catch (e) {
showErrorMessage(e.stack, (res) => {
getfocus()
})
}
}
//增加实际扫描的明细
const createLocationInfo = (labelParams, balanceParams, packageInfo)=> {
let location = {
fromLocationCode: balanceParams.locationCode,
qty: balanceParams.qty,
uom: balanceParams.uom,
handleQty: 0,
isNewAdd: true,
Batchs: []
}
let batch = createBatchInfo(labelParams, balanceParams, packageInfo);
batch.detail = balanceParams;
batch.detail.fromLocationCode = balance.locationCode;
location.Batchs.push(batch);
return location;
}
const createBatchInfo = (labelParams, balanceParams, packageInfo) => {
const batch = {
batch: labelParams.batch,
qty: 0,
uom: labelParams.uom,
handleQty: Number(balanceParams.qty),
Records: []
}
let record = {}
if (balanceParams != null) {
record = creatRecordByBalance(balanceParams, packageInfo)
batch.handleQty = Number(labelParams.qty)
} else {
record = creatRecordByLabel(labelParams, packageInfo)
batch.handleQty = Number(balanceParams.qty)
}
batch.Records.push(record)
issueRecord.value.unshift(record)
return batch
}
const creatRecordByLabel = (labelParams, packageInfo) => {
const record = {
scaned: true,
itemCode: labelParams.itemCode,
packingNumber: labelParams.packingNumber,
parentPackingNumber: packageInfo.parentNumber,
batch: labelParams.batch,
qty: Number(labelParams.qty),
// qty: Number(label.qty)>Number(balance.qty)?Number(balance.qty):Number(label.qty),
uom: labelParams.uom,
inventoryStatus: 'OK',
balance: null,
toLocationCode: toLocationCode.value,
supplierCode: labelParams.supplierCode,
packUnit: packageInfo.packUnit,
packQty: packageInfo.packQty
}
return record
}
const creatRecordByBalance = (balanceParams, packageInfo) => {
balanceParams.packQty = packageInfo.packQty
balanceParams.packUnit = packageInfo.packUnit
const record = {
scaned: true,
itemCode: balanceParams.itemCode,
packingNumber: packageInfo.number,
parentPackingNumber: packageInfo.parentNumber,
batch: packageInfo.batch,
qty: Number(balanceParams.qty),
// qty: Number(label.qty)>Number(balance.qty)?Number(balance.qty):Number(label.qty),
uom: balanceParams.uom,
inventoryStatus: balanceParams.inventoryStatus,
balance: balanceParams,
toLocationCode: toLocationCode.value,
supplierCode: balance.supplierCode
}
return record
}
const calcBatchHandleQty = (batch) => {
let handleQty = 0
batch.Records.forEach((res) => {
handleQty = calc.add(handleQty, res.qty)
})
batch.handleQty = handleQty
dataContent.value.forEach((toLocationCode1) => {
toLocationCode1.Items.forEach((item) => {
let itemCodeHandleQty = 0
item.Locations.forEach((batch1) => {
batch1.Batchs.forEach((batchHandleQty) => {
itemCodeHandleQty = calc.add(itemCodeHandleQty, batchHandleQty.handleQty)
})
})
item.handleQty = itemCodeHandleQty
})
})
}
const addRecord = (batch, labelParams, balanceParams, packageInfo) => {
let record = {}
if (balanceParams == null) {
console.log(9999)
console.log(labelParams)
console.log(packageInfo)
console.log(9999)
record = creatRecordByLabel(labelParams, packageInfo)
} else {
console.log(8888)
console.log(balanceParams)
console.log(packageInfo)
console.log(8888)
record = creatRecordByBalance(balanceParams, packageInfo)
}
if (packageInfo.parentNumber) {
let checkData = batch.Records.find(r => {
if (r.packingNumber == packageInfo.parentNumber &&
r.batch == packageInfo.batch) {
return r;
}
})
if (checkData) {
//提示已经扫描
showErrorMessage("箱码[" + packageInfo.number + "]批次[" + packageInfo.batch +
"]的父包装已经扫描")
} else {
batch.Records.push(record)
issueRecord.value.unshift(record)
calcBatchHandleQty(batch)
getfocus()
}
} else {
//扫描的是父包装
let checkData = batch.Records.find(r => {
if (r.parentPackingNumber == packageInfo.number &&
r.batch == packageInfo.batch) {
return r;
}
})
if (checkData) {
//是否移除
comMessageRef.value.showQuestionMessage("扫描箱码[" + checkData.parentPackingNumber + "]" + "批次[" +
packageInfo
.batch + "]是父包装,是否移除子包装", res => {
if (res) {
batch.Records = []
batch.Records.push(record);
issueRecord.value.unshift(record)
calcBatchHandleQty(batch);
getfocus();
}
})
console.log("扫描的是父包装,是否移除子包装")
} else {
batch.Records.push(record);
issueRecord.value.unshift(record)
calcBatchHandleQty(batch);
getfocus();
}
}
}
const getfocus = () => {
if (comscan.value != undefined) {
comscan.value.getfocus()
}
}
const losefocus = () => {
if (comscan.value != undefined) {
comscan.value.losefocus()
}
}
const expands = () => {
expand.value = !expand.value
expendIcon.value = expand.value == true ? 'arrow-down' : 'arrow-up'
}
const swipeClick = (params, item) => {
const { text } = scanOptions.value[params[1]]
if (text == '详情') {
detail(item)
} else if (text == '编辑') {
edit(item)
} else if (text == '库位') {
showLocation(item)
} else if (text == '移除') {
remove(item)
}
}
const edit = (item) => {
editItem.value = item
// item.balance.balanceQty = item.balance.qty;
item.balance.balanceQty = item.balance.qty
balanceQtyEditRef.value.openEditPopup(item.balance, item.qty)
}
const detail = (item) => {
showItem.value = item
receiptHint.value.openScanPopup()
}
const remove = (record, index) => {
showQuestionMessage('确定移除扫描信息?', (res) => {
if (res) {
record.qty = 0
issueRecord.value.splice(index, 1)
const item = toLocation.value.Items.find((r) => r.itemCode == record.itemCode)
if (item != undefined) {
item.Locations.forEach((l) => {
const batch = l.Batchs.find((b) => (b.packingNumber == record.packingNumber || b.packingNumber == null || b.packingNumber == '') && b.batch == record.batch)
const rIndex = batch.Records.findIndex((r) => r.packingNumber == record.packingNumber && r.batch == record.batch)
batch.Records.splice(rIndex, 1)
})
}
emit('updateData', record)
}
})
}
const packGetFocus = () => {
if (comscan.value) {
comscan.value.getfocus()
}
}
const packLoseFocus = () => {
if (comscan.value) {
comscan.value.losefocus()
}
}
const showMessage = (message, callback) => {
setTimeout((r) => {
packLoseFocus()
comMessageRef.value.showMessage(message, callback)
})
}
const showErrorMessage = (message, callback) => {
setTimeout((r) => {
packLoseFocus()
comMessageRef.value.showErrorMessage(message, callback)
})
}
const showQuestionMessage = (message, callback) => {
setTimeout((r) => {
packLoseFocus()
comMessageRef.value.showQuestionMessage(message, callback)
})
}
const confirm = (val) => {
editItem.value.qty = Number(val)
emit('updateData', editItem.value)
}
const cancle = () => {
closeScanPopup()
}
// 传递给父类
const emit = defineEmits(['updateData', 'closeScan'])
defineExpose({
openScanPopup,
closeScanPopup
})
</script>
<style lang="scss">
button {
border: none;
}
button::after {
border: none;
}
// .scroll-view {
// overflow-y: scroll;
// height: auto;
// max-height: 300rpx;
// padding: 10rpx;
// }
::v-deep uni-movable-view {
width: auto !important;
}
</style>