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.

556 lines
17 KiB

<template>
<view>
<u-popup v-model="show" mode="bottom" :maskClick='false'>
<view class="">
<view class="popup_box">
<view class="pop_title uni-flex space-between">
<view class="" style="font-size: 35rpx;">
扫描箱码
</view>
<view class="">
<image class="fr icons_scan_close" src="/static/icons/icons_scan_close.svg"
@click="closeScanPopup()"></image>
</view>
</view>
<!-- <view class="uni-flex uni-row" style="align-items: center;
background-color: #fff;
margin-left: 20rpx;
margin-right: 20rpx;
padding:20rpx;
border-radius: 8rpx;">
<view class="uni-center">
位置 :
</view>
<view class="" style="width: 75%;padding: 0rpx">
<view class="uni-flex u-col-center uni-row" @click="showSelect">
<view class="" style="margin-left: 15rpx;font-size: 30rpx;">
{{positionInfo}}
</view>
<u-select v-model="show" mode="mutil-column-auto" :list="positionList" :defaultValue="defaultValueList"
@confirm="confirmSelect"></u-select>
</view>
</view>
</view>
<u-line class='line_color'></u-line> -->
<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="headerType" :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">
<view class="uni-flex u-col" v-for="(record,index) in issueRecord">
<view style="width: 100%;">
<u-swipe-action ref="swipeAction" :options="scanOptions"
@click="(...event)=>swipeClick(event,record,index)">
<view style="padding: 0px 10px">
<balance :dataContent="record" :isShowLocation="false"
:isShowStdPack="false"></balance>
u
</view>
</u-swipe-action>
<u-line class='line_color'></u-line>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
</view>
</view>
</u-popup>
<balance-select ref="balanceSelect" @onSelectItem='selectBalanceItem'></balance-select>
<comMessage ref="comMessage"></comMessage>
<balance-qty-edit ref="balanceQtyEdit" @confirm="confirm" :isShowStatus="true"></balance-qty-edit>
</view>
</template>
<script setup lang="ts">
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
} from '@/common/array.js';
import {
getDirectoryItemArray,
} from '@/common/directory.js';
import {
calc
} from '@/common/calc.js';
import {
getWorkShopLineStation
} from '@/api/request2.js';
import {
getBalanceByManagementPrecision
} from '@/common/balance.js';
import {ref, onMounted} from 'vue';
const props = defineProps({
title: {
type: String,
default: ''
},
headerType: {
type: String,
default: "HPQ,HMQ"
}
});
const emit = defineEmits(['closeScan','updateData'])
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 positionInfo = ref("请选择位置");
const positionList = ref([]);
const defaultValueList = ref([]);
const label = ref({});
const fromInventoryStatuses = ref([]);
const packageInfo = ref({});
const popup = ref(null);
const balanceSelect = ref(null);
const comscan = ref(null);
const comMessage = ref(null);
const receiptHint = ref(null);
const balanceQtyEdit = ref(null);
const detailOptions = ref('')
const toLocationCombox = ref('')
const showItem = ref('')
onMounted(() => {
detailOptions.value = getDetailOption();
scanOptions.value = getDetailEditRemoveOption();
});
// 方法
const openScanPopup = (content, jobcontent) => {
issueRecord.value = [];
dataContent.value = content;
jobContent.value = jobcontent;
initData();
positionInfo.value = jobContent.value.workShopCode + "-" + jobContent.value.subList[0].productionLineCode +
"-" + jobContent.value.subList[0].workStationCode;
show.value = true
setTimeout(() => {
getfocus();
}, 500);
};
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 = getDirectoryItemArray(jobContent.value.outInventoryStatuses);
toLocation.value = dataContent.value[0];
toLocationCode.value = dataContent.value[0].toLocationCode;
fromLocationList.value = getFromLocationList();
}
};
const showBalanceSelect = (items, packageInfo) => {
packageInfo.value = packageInfo;
balanceSelect.value.openPopup(items);
};
const getFromLocationList = () => {
let list = [];
let location = dataContent.value.find(r => r.toLocationCode == toLocationCode.value);
if (location != undefined) {
location.Items.forEach(item => {
item.Locations.forEach(f => {
list.push(f.fromLocationCode);
});
});
fromLocationCode.value = list[0];
return list;
} else {
comMessage.value.showErrorMessages('需求库位【' + toLocationCode.value + '】不存在', res => {
toLocationCode.value = '';
});
}
};
const fromLocationUpdate = (fromlocation) => {
let location = fromLocationList.value.find(r => r == fromlocation);
fromLocationCode.value = fromlocation;
};
const onScan = (result) => {
try {
if (fromLocationCode.value == '') {
showErrorMessage('请选择来源库位', res => {
toLocationCombox.value.onFocus();
});
return;
}
let packageInfo = result.package;
let itemCode = result.label.itemCode;
let packingCode = result.label.packingNumber;
let lot = result.label.batch;
let item = toLocation.value.Items.find(r => r.itemCode == itemCode);
if (item == undefined) {
showErrorMessage('未查找到物料【' + itemCode + '】的发货明细', res => {
getfocus();
});
return;
} else {
uni.showLoading({
title: '加载中',
mask: true
});
getBalanceByManagementPrecision(result.label, fromLocationCode.value, fromInventoryStatuses.value, balanceRes => {
if (balanceRes.success) {
if (balanceRes.data.list.length == 0) {
showErrorMessage('在来源库位[' + fromLocationCode.value + '],未查找到该包装的库存记录', res => {
packGetFocus();
});
} else if (balanceRes.data.list.length == 1) {
let balance = balanceRes.data.list[0];
afterGetBalance(result.label, balance, packageInfo);
} else {
label.value = result.label;
showBalanceSelect(balanceRes.data.list, packageInfo);
}
} else {
showErrorMessage(balanceRes.message.message);
}
uni.hideLoading();
});
}
} catch (e) {
showErrorMessage(e.stack);
uni.hideLoading();
}
};
const selectBalanceItem = (balance) => {
afterGetBalance(balance, balance, packageInfo.value);
};
const afterGetBalance = (label, balance, packageInfo) => {
try {
let itemCode = label.itemCode;
let packingCode = label.packingNumber;
let lot = label.batch;
let item = toLocation.value.Items.find(r => r.itemCode == itemCode);
let fromLocation = item.Locations.find(l => l.fromLocationCode == fromLocationCode.value);
// 成品发货任务--同一物料,可以扫描提交不在任务中的库位
if (!fromLocation) {
fromLocation = {
Batchs: [{
Recommends: [],
Records: [],
batch: label.batch,
detail: {
...packageInfo,
fromLocationCode: balance.locationCode,
toLocationCode: toLocationCode.value
},
handleQty: 0,
packingNumber: null,
qty: label.qty,
uom: label.uom
}],
toLocationCode: toLocationCode.value,
fromLocationCode: balance.locationCode,
handleQty: 0,
qty: label.qty,
uom: label.uom
};
item.Locations.push(fromLocation);
}
if (fromLocation != undefined) {
let batch = fromLocation.Batchs.find(r => r.batch == lot);
if (batch != undefined) {
if (batch.Records == undefined) {
batch.Records = [];
}
let record = batch.Records.find(r => r.packingNumber == packingCode);
if (record == undefined) {
// 如果有推荐箱码
if (batch.Recommends && batch.Recommends.length > 0) {
let recommend = batch.Recommends.find(r => r.packingNumber == packingCode);
if (recommend != undefined) {
addRecord(batch, label, balance, packageInfo);
} else {
// 允许修改箱码
if (jobContent.value.allowModifyPackingNumber == 'TRUE') {
addRecord(batch, label, balance, packageInfo);
} else {
showErrorMessage('未查找到该箱码【' + packingCode + '】的明细', res => {
getfocus();
});
}
}
} else {
addRecord(batch, label, balance, packageInfo);
}
} else {
showErrorMessage('箱码【' + packingCode + '】已经扫描,请继续扫描下一箱', res => {
getfocus();
});
}
} else {
if (jobContent.value.allowModifyBatch == "TRUE") {
showQuestionMessage('在【' + fromLocationCode.value + '】库位下,未查找到批次【' + lot +
'】的发货明细,是否要继续发货?', res => {
if (res) {
let batch = createBatchInfo(label, balance, packageInfo);
fromLocation.Batchs.unshift(batch);
}
});
} else {
showErrorMessage('未查找到批次【' + lot + '】的发货明细', res => {
getfocus();
});
}
}
} else {
showErrorMessage('未查找到推荐库位【' + fromLocationCode.value + '】的发货明细', res => {
getfocus();
});
}
} catch (e) {
showErrorMessage(e.stack, res => {
getfocus();
});
}
};
const createBatchInfo = (data, balance, packageInfo) => {
let batch = {
batch: data.lot || data.batch,
qty: 0,
uom: data.uom,
handleQty: Number(data.qty),
Records: [],
detail: {
fromLocationCode: fromLocationCode.value, //balance.locationCode
toLocationCode: toLocationCode.value,
itemCode: data.itemCode,
handleQty: Number(data.qty),
packingNumber: data.packingNumber,
qty: 0,
uom: data.uom,
itemName: packageInfo.itemName,
itemDesc1: packageInfo.itemDesc1,
itemDesc2: packageInfo.itemDesc2,
singlePrice: balance.singlePrice,
amount: balance.amount
}
};
let record = creatRecord(data, balance, packageInfo);
batch.Records.push(record);
issueRecord.value.unshift(record);
return batch;
};
const creatRecord = (label, balance, packageInfo) => {
balance.packQty = packageInfo.packQty;
balance.packUnit = packageInfo.packUnit;
let record = {
scaned: true,
itemCode: label.itemCode,
packingNumber: label.packingNumber,
batch: label.batch,
qty: Number(label.qty) > Number(balance.qty) ? Number(balance.qty) : Number(label.qty),
uom: balance.uom,
inventoryStatus: balance.inventoryStatus,
balance: balance,
toLocationCode: toLocationCode.value,
supplierCode: label.supplierCode,
packUnit: packageInfo.packUnit,
packQty: packageInfo.packQty,
singlePrice: balance.singlePrice,
amount: balance.amount
};
return record;
};
const calcBatchHandleQty = (batch) => {
let handleQty = 0;
batch.Records.forEach(res => {
handleQty = calc.add(handleQty, res.qty);
});
batch.handleQty = handleQty;
};
const addRecord = (batch, label, balance, packageInfo) => {
let record = creatRecord(label, balance, packageInfo);
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 ? "arrow-down" : "arrow-up";
};
const swipeClick = (e, item, index) => {
if (e.content.text == "详情") {
detail(item);
} else if (e.content.text == "编辑") {
edit(item);
} else if (e.content.text == "移除") {
remove(item, index);
}
};
const edit = (item) => {
editItem.value = item;
item.balance.balanceQty = item.balance.qty;
balanceQtyEdit.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);
let item = toLocation.value.Items.find(r => r.itemCode == record.itemCode);
if (item != undefined) {
item.Locations.forEach(l => {
let batch = l.Batchs.find(b => b.packingNumber == record.packingNumber && b.batch == record.batch);
let rIndex = batch.Records.findIndex(r => r.packingNumber == record.packingNumber && r.batch == record.batch);
batch.Records.splice(rIndex, 1);
});
}
emit('updateData', item);
}
});
};
const packGetFocus = () => {
comscan.value.getfocus();
};
const packLoseFocus = () => {
comscan.value.losefocus();
};
const showMessage = (message, callback) => {
setTimeout(() => {
packLoseFocus();
comMessage.value.showMessage(message, callback);
});
};
const showErrorMessage = (message, callback) => {
setTimeout(() => {
packLoseFocus();
comMessage.value.showErrorMessage(message, callback);
});
};
const showQuestionMessage = (message, callback) => {
setTimeout(() => {
packLoseFocus();
comMessage.value.showQuestionMessage(message, callback);
});
};
const confirm = (val) => {
editItem.value.qty = Number(val);
emit('updateData', editItem.value);
};
const cancle = () => {
closeScanPopup();
};
</script>
<style lang="scss">
button {
border: none;
}
button::after {
border: none
}
.scroll-view {
overflow-y: scroll;
height: auto;
max-height: 300rpx;
padding: 10rpx;
}
</style>