Merge branch 'master' of http://115.159.85.185:8098/r/ZhongRui/ALDbanyunxiangmu
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | |
| | | //æ¤jsæä»¶æ¯ç¨æ¥èªå®ä¹æ©å±ä¸å¡ä»£ç ï¼å¯ä»¥æ©å±ä¸äºèªå®ä¹é¡µé¢æè
éæ°é
ç½®çæç代ç |
| | | import http from '@/api/http.js' |
| | | import { h,createVNode, render,reactive,ref } from 'vue'; |
| | | import { ElDialog , ElForm, ElFormItem, ElInput, ElButton, ElMessage ,ElSelect ,ElOption } from 'element-plus'; // å¼å
¥ElMessageï¼è§£å³æç¤ºæ ååº |
| | | |
| | | let extension = { |
| | | components: { |
| | | //æ¥è¯¢ç颿©å±ç»ä»¶ |
| | | gridHeader: '', |
| | | gridBody: '', |
| | | gridFooter: '', |
| | | //æ°å»ºãç¼è¾å¼¹åºæ¡æ©å±ç»ä»¶ |
| | | modelHeader: '', |
| | | modelBody: '', |
| | | modelFooter: '' |
| | | }, |
| | | tableAction: '', //æå®æå¼ 表çæé(è¿éå¡«å表å,é»è®¤ä¸ç¨å¡«å) |
| | | buttons: { view: [ |
| | | { |
| | | name: 'ç»ç', |
| | | type: 'primary', |
| | | value: 'ç»ç', |
| | | onClick: function () { // ä¿®å¤1ï¼ç§»é¤æ ç¨rowåæ°ï¼å æ¥å¿è°è¯ |
| | | console.log('ç»çæé®è¢«ç¹å»ï¼å¼å§æ ¡éª'); |
| | | const selectedRows = this.$refs.table.getSelected(); |
| | | |
| | | // æ ¡éª1ï¼æ¯å¦éä¸è¡ |
| | | if (selectedRows.length === 0) { |
| | | console.log('æ ¡éªä¸éè¿ï¼æªéä¸ä»»ä½åæ®'); |
| | | ElMessage.warning('è¯·éæ©ä¸æ¡åæ®'); |
| | | return; |
| | | } |
| | | // æ ¡éª2ï¼æ¯å¦éä¸åè¡ |
| | | if (selectedRows.length > 1) { |
| | | console.log('æ ¡éªä¸éè¿ï¼éä¸å¤è¡åæ®'); |
| | | ElMessage.warning('åªè½éæ©ä¸æ¡åæ®'); |
| | | return; |
| | | } |
| | | |
| | | const targetRow = selectedRows[0]; |
| | | |
| | | this.$emit('openPalletDialog', targetRow.inboundOrderNo); |
| | | } |
| | | }, |
| | | { |
| | | name: 'æ¤éç»ç', |
| | | type: 'primary', |
| | | value: 'æ¤éç»ç', |
| | | onClick: function () { |
| | | console.log('æ¤éç»çæé®è¢«ç¹å»'); |
| | | const mountNode = document.createElement('div'); |
| | | document.body.appendChild(mountNode); |
| | | |
| | | // ååºå¼è¡¨åæ°æ®ï¼æçå·ï¼å¿
å¡«ï¼ |
| | | const formData = reactive({ |
| | | palletCode: '' // æçå·è¾å
¥æ¡ |
| | | }); |
| | | |
| | | // æäº¤è¡¨åçç»ä¸é»è¾ |
| | | const submitForm = async () => { |
| | | const formRef = vnode.component.refs.cancelPalletForm; |
| | | try { |
| | | // æ§è¡è¡¨åæ ¡éªï¼æçå·å¿
å¡«ï¼ |
| | | await formRef.validate(); |
| | | } catch (err) { |
| | | ElMessage.warning('请è¾å
¥ææçæçå·'); |
| | | return; |
| | | } |
| | | |
| | | // åèµ·æ¤éç»çè¯·æ± |
| | | try { |
| | | //console.log('åèµ·æ¤éç»ç请æ±ï¼æçå·ï¼', formData.palletCode.trim()); |
| | | const response = await http.post('/api/InboundOrder/CancelPalletGroup', { |
| | | palletCode: formData.palletCode.trim() |
| | | }); |
| | | |
| | | const { status, message, data } = response; |
| | | if (status) { |
| | | ElMessage.success(`æ¤éç»çæåï¼æçå·ï¼${formData.palletCode.trim()}`); |
| | | this.refresh(); // æååå·æ°å表 |
| | | // å
³éå¯¹è¯æ¡ |
| | | render(null, mountNode); |
| | | document.body.removeChild(mountNode); |
| | | } else { |
| | | console.log('æ¤éç»ç失败ï¼å端æç¤ºï¼', message); |
| | | ElMessage.error(message || data?.message || 'æ¤éç»ç失败'); |
| | | selectPalletCodeInput(); // éä¸è¾å
¥æ¡æ¹ä¾¿éæ°è¾å
¥ |
| | | } |
| | | } catch (error) { |
| | | console.error('æ¤éç»ç请æ±å¼å¸¸ï¼', error); |
| | | ElMessage.error('ç½ç»å¼å¸¸ææ¥å£é误ï¼è¯·ç¨åéè¯'); |
| | | selectPalletCodeInput(); |
| | | } |
| | | }; |
| | | |
| | | // éä¸è¾å
¥æ¡ææ¬ï¼æ¹ä¾¿éæ°è¾å
¥ï¼ |
| | | const selectPalletCodeInput = () => { |
| | | setTimeout(() => { |
| | | const inputRef = vnode.component.refs.palletCodeInput; |
| | | if (inputRef) { |
| | | const targetInput = inputRef.$el?.querySelector('input') || inputRef; |
| | | targetInput?.focus(); |
| | | targetInput?.select(); |
| | | } |
| | | }, 100); |
| | | }; |
| | | |
| | | // åå»ºå¯¹è¯æ¡VNode |
| | | const vnode = createVNode(ElDialog, { |
| | | title: 'æ¤éç»ç', |
| | | width: '400px', |
| | | modelValue: true, |
| | | appendToBody: true, |
| | | onOpened: () => { |
| | | // å¯¹è¯æ¡æå¼åèªå¨èç¦è¾å
¥æ¡ |
| | | setTimeout(() => { |
| | | const inputRef = vnode.component.refs.palletCodeInput; |
| | | inputRef?.focus(); |
| | | }, 100); |
| | | }, |
| | | 'onUpdate:modelValue': (isVisible) => { |
| | | if (!isVisible) { |
| | | render(null, mountNode); |
| | | document.body.removeChild(mountNode); |
| | | } |
| | | } |
| | | }, { |
| | | default: () => h(ElForm, { |
| | | model: formData, |
| | | rules: { |
| | | palletCode: [ |
| | | { required: true, message: '请è¾å
¥æçå·', trigger: ['blur', 'enter'] }, |
| | | { min: 1, max: 50, message: 'æçå·é¿åº¦ä¸è½è¶
è¿50个å符', trigger: ['blur', 'input'] } |
| | | ] |
| | | }, |
| | | ref: 'cancelPalletForm' |
| | | }, [ |
| | | // æçå·è¾å
¥é¡¹ |
| | | h(ElFormItem, { label: 'æçå·', prop: 'palletCode', required: true }, [ |
| | | h(ElInput, { |
| | | type: 'text', |
| | | modelValue: formData.palletCode, |
| | | 'onUpdate:modelValue': (val) => { |
| | | formData.palletCode = val; |
| | | }, |
| | | ref: 'palletCodeInput', |
| | | placeholder: 'æ«ç è¾å
¥ææå¨è¾å
¥æçå·', |
| | | maxLength: 50, |
| | | // çå¬å车äºä»¶ï¼æ«ç æªé»è®¤ä¼åéåè½¦ï¼ |
| | | onKeydown: (e) => { |
| | | if (e.key === 'Enter') { |
| | | e.preventDefault(); |
| | | submitForm(); |
| | | } |
| | | } |
| | | }) |
| | | ]), |
| | | // åºé¨æé®åº |
| | | h('div', { style: { textAlign: 'right', marginTop: '16px' } }, [ |
| | | h(ElButton, { |
| | | type: 'text', |
| | | onClick: () => { |
| | | render(null, mountNode); |
| | | document.body.removeChild(mountNode); |
| | | ElMessage.info('åæ¶æ¤éç»ç'); |
| | | } |
| | | }, 'åæ¶'), |
| | | h(ElButton, { |
| | | type: 'primary', |
| | | onClick: submitForm.bind(this) // ç»å®thisä¸ä¸æ |
| | | }, '确认æ¤é') |
| | | ]) |
| | | ]) |
| | | }); |
| | | |
| | | vnode.appContext = this.$.appContext; |
| | | render(vnode, mountNode); |
| | | } |
| | | }, |
| | | { |
| | | name: 'åæ¹å
¥åº', |
| | | type: 'primary', |
| | | value: 'åæ¹å
¥åº', |
| | | onClick: async function () { |
| | | console.log('åæ¹å
¥åºæé®è¢«ç¹å»ï¼å¼å§æ ¡éª'); |
| | | const selectedRows = this.$refs.table.getSelected(); |
| | | |
| | | // æ ¡éª1ï¼æ¯å¦éä¸è¡ï¼è³å°éæ©ä¸æ¡ï¼ |
| | | if (selectedRows.length === 0) { |
| | | console.log('æ ¡éªä¸éè¿ï¼æªéä¸ä»»ä½åæ®'); |
| | | ElMessage.warning('è¯·éæ©è³å°ä¸æ¡åæ®'); |
| | | return; |
| | | } |
| | | |
| | | // æ¶éææéä¸åæ®çç¼å·ï¼è¿æ»¤æ åæ®å·çå¼å¸¸è¡ï¼ |
| | | const inboundOrderNos = selectedRows |
| | | .filter(row => row.inboundOrderNo) |
| | | .map(row => row.inboundOrderNo); |
| | | |
| | | // æ ¡éª2ï¼æ¯å¦æææåæ®å· |
| | | if (inboundOrderNos.length === 0) { |
| | | console.log('æ ¡éªä¸éè¿ï¼éä¸åæ®æ ææç¼å·'); |
| | | ElMessage.warning('éä¸ç忮䏿 ææç¼å·ï¼è¯·éæ°éæ©'); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | console.log('åèµ·åæ¹å
¥åºè¯·æ±ï¼åæ°ï¼', { inboundOrderNos}); |
| | | const response = await http.post('/api/InboundOrder/BatchOrderFeedbackToMes', { |
| | | orderNos: inboundOrderNos, |
| | | inout:1 |
| | | }); |
| | | |
| | | const { status, message, data } = response; |
| | | if (status) { |
| | | console.log('åæ¹å
¥åºæåï¼å端è¿åï¼', data); |
| | | ElMessage.success(`åæ¹å
¥åºæåï¼å
±å¤ç${inboundOrderNos.length}æ¡åæ®`); |
| | | this.refresh(); // å
¥åºæååå·æ°å表ï¼å¤ç¨åæé»è¾ï¼ |
| | | } else { |
| | | console.log('åæ¹å
¥åºå¤±è´¥ï¼å端æç¤ºï¼', message); |
| | | ElMessage.error(message || data?.message || 'åæ¹å
¥åºå¤±è´¥'); |
| | | } |
| | | } catch (error) { |
| | | console.error('åæ¹å
¥åºè¯·æ±å¼å¸¸ï¼', error); |
| | | ElMessage.error('ç½ç»å¼å¸¸ææ¥å£é误ï¼è¯·ç¨åéè¯'); |
| | | } |
| | | } |
| | | }, |
| | | { |
| | | name: '空æçå
¥åº', |
| | | type: 'primary', |
| | | value: '空æçå
¥åº', |
| | | |
| | | onClick: function () { |
| | | const mountNode = document.createElement('div'); |
| | | document.body.appendChild(mountNode); |
| | | |
| | | // ååºå¼è¡¨åæ°æ®ï¼æç®±ç ï¼å¿
å¡«ï¼æ«ç æª/æå¨è¾å
¥ï¼ |
| | | const formData = reactive({ |
| | | boxCode: '', |
| | | warehouseCode:'' |
| | | }); |
| | | |
| | | const warehouses = ref([]); |
| | | const isLoadingWarehouses = ref(false); |
| | | |
| | | const getWarehouseList = async () => { |
| | | isLoadingWarehouses.value = true; |
| | | try { |
| | | const { data, status } = await http.post('/api/LocationInfo/GetLocationTypes'); |
| | | if (status && Array.isArray(data)) { |
| | | // æ ¼å¼åä»åºé项ï¼éé
ElSelectçlabel-valueæ ¼å¼ |
| | | warehouses.value = data.map(item => ({ |
| | | label: item.locationTypeDesc, |
| | | value: item.locationType |
| | | })); |
| | | } else { |
| | | ElMessage.error('è·ååºåå表失败'); |
| | | warehouses.value = []; |
| | | } |
| | | } catch (err) { |
| | | ElMessage.error('åºåæ°æ®è¯·æ±å¼å¸¸ï¼è¯·ç¨åéè¯'); |
| | | warehouses.value = []; |
| | | } finally { |
| | | isLoadingWarehouses.value = false; |
| | | } |
| | | }; |
| | | |
| | | // æäº¤è¡¨åçç»ä¸é»è¾ï¼ä¾å车触ååæé®ç¹å»å
±ç¨ï¼ |
| | | const submitForm = async () => { |
| | | const formRef = vnode.component.refs.batchInForm; |
| | | try { |
| | | // æ§è¡è¡¨åæ ¡éªï¼æç®±ç å¿
å¡«ï¼ |
| | | await formRef.validate(); |
| | | } catch (err) { |
| | | ElMessage.warning('请è¾å
¥ææçæç®±ç '); |
| | | return; |
| | | } |
| | | |
| | | |
| | | http.post('/api/InboundOrder/EmptyMaterielGroup', { |
| | | palletCode: formData.boxCode.trim(), |
| | | warehouseCode:formData.warehouseCode |
| | | }).then(({ data, status, message }) => { |
| | | if (status) { |
| | | ElMessage.success(`å
¥åºæåï¼æç®±ç ï¼${formData.boxCode.trim()}`); |
| | | this.refresh(); |
| | | formData.boxCode = ''; |
| | | |
| | | setTimeout(() => { |
| | | const inputRef = vnode.component.refs.boxCodeInput; |
| | | inputRef?.focus(); |
| | | }, 100); |
| | | } else { |
| | | ElMessage.error(message || data?.message || 'å
¥åºå¤±è´¥'); |
| | | selectBoxCodeInput(); |
| | | } |
| | | }).catch(() => { |
| | | ElMessage.error('请æ±å¤±è´¥ï¼è¯·ç¨åéè¯'); |
| | | selectBoxCodeInput(); |
| | | }); |
| | | }; |
| | | |
| | | const selectBoxCodeInput = () => { |
| | | setTimeout(() => { |
| | | const inputRef = vnode.component.refs.boxCodeInput; |
| | | if (inputRef) { |
| | | const targetInput = inputRef.$el?.querySelector('input') || inputRef; |
| | | targetInput?.focus(); |
| | | targetInput?.select(); |
| | | } |
| | | }, 100); |
| | | } |
| | | const vnode = createVNode(ElDialog, { |
| | | title: '空æçå
¥åº', |
| | | width: '400px', |
| | | modelValue: true, |
| | | appendToBody: true, |
| | | |
| | | onOpened: async () => { |
| | | await getWarehouseList(); |
| | | const inputRef = vnode.component.refs.boxCodeInput; |
| | | inputRef?.focus(); |
| | | }, |
| | | 'onUpdate:modelValue': (isVisible) => { |
| | | if (!isVisible) { |
| | | render(null, mountNode); |
| | | document.body.removeChild(mountNode); |
| | | } |
| | | } |
| | | }, { |
| | | default: () => h(ElForm, { |
| | | model: formData, |
| | | rules: { |
| | | boxCode: [ |
| | | { required: true, message: '请è¾å
¥æç®±ç ', trigger: ['blur', 'enter'] } |
| | | ], |
| | | warehouseCode:[ |
| | | { required: true, message: 'è¯·éæ©åºå', trigger: ['change', 'blur'] } |
| | | ] |
| | | }, |
| | | ref: 'batchInForm' |
| | | }, [ |
| | | //ä»åºæ°æ® |
| | | h(ElFormItem, { label: 'åºå', prop: 'warehouseCode', required: true }, [ |
| | | h(ElSelect, { |
| | | modelValue: formData.warehouseCode, |
| | | 'onUpdate:modelValue': (val) => { |
| | | formData.warehouseCode = val; |
| | | }, |
| | | placeholder: 'è¯·éæ©å
¥åºåºå', |
| | | filterable: true, // æ¯ææç´¢ä»åº |
| | | loading: isLoadingWarehouses.value, // å è½½ç¶æ |
| | | style: { width: '100%' } |
| | | }, [ |
| | | // 渲æä»åºä¸æé项 |
| | | warehouses.value.map(item => h(ElOption, { |
| | | label: item.label, |
| | | value: item.value |
| | | })) |
| | | ]) |
| | | ]), |
| | | // æç®±ç è¾å
¥é¡¹ï¼æ¯æèç¦ãå车æäº¤ï¼ |
| | | h(ElFormItem, { label: 'æç®±ç ', prop: 'boxCode', required: true }, [ |
| | | h(ElInput, { |
| | | type: 'text', |
| | | modelValue: formData.boxCode, |
| | | 'onUpdate:modelValue': (val) => { |
| | | formData.boxCode = val; |
| | | }, |
| | | ref: 'boxCodeInput', |
| | | placeholder: 'æ«ç è¾å
¥ææå¨è¾å
¥æç®±ç ', |
| | | // çå¬å车äºä»¶ï¼æ«ç æªé»è®¤ä¼åéåè½¦ï¼ |
| | | onKeydown: (e) => { |
| | | if (e.key === 'Enter') { |
| | | e.preventDefault(); |
| | | submitForm(); |
| | | } |
| | | } |
| | | }) |
| | | ]), |
| | | // åºé¨æé®åº |
| | | h('div', { style: { textAlign: 'right', marginTop: '16px' } }, [ |
| | | h(ElButton, { |
| | | type: 'text', |
| | | onClick: () => { |
| | | render(null, mountNode); |
| | | document.body.removeChild(mountNode); |
| | | ElMessage.info('åæ¶å
¥åºä»»å¡'); |
| | | } |
| | | }, 'åæ¶'), |
| | | h(ElButton, { |
| | | type: 'primary', |
| | | onClick: submitForm |
| | | }, 'ç¡®å®') |
| | | ]) |
| | | ]) |
| | | }); |
| | | |
| | | vnode.appContext = this.$.appContext; |
| | | render(vnode, mountNode); |
| | | } |
| | | } |
| | | ], box: [], detail: [] }, |
| | | methods: { |
| | | //ä¸é¢è¿äºæ¹æ³å¯ä»¥ä¿çä¹å¯ä»¥å é¤ |
| | | onInit() { |
| | | }, |
| | | onInited() { |
| | | |
| | | //æ¡æ¶åå§åé
ç½®å |
| | | //妿è¦é
ç½®æç»è¡¨,卿¤æ¹æ³æä½ |
| | | //this.detailOptions.columns.forEach(column=>{ }); |
| | | }, |
| | | searchBefore(param) { |
| | | //ç颿¥è¯¢å,å¯ä»¥ç»param.wheresæ·»å æ¥è¯¢åæ° |
| | | //è¿åfalseï¼åä¸ä¼æ§è¡æ¥è¯¢ |
| | | let wheres = [{ |
| | | 'name': 'orderType', |
| | | 'value': '115', |
| | | 'displayType': 'text'}]; |
| | | |
| | | |
| | | param.wheres.push(...wheres); |
| | | // this.searchFormFields.orderType=[115] |
| | | return true; |
| | | }, |
| | | searchAfter(result) { |
| | | //æ¥è¯¢åï¼resultè¿åçæ¥è¯¢æ°æ®,å¯ä»¥å¨æ¾ç¤ºå°è¡¨æ ¼åå¤çè¡¨æ ¼çå¼ |
| | | return true; |
| | | }, |
| | | addBefore(formData) { |
| | | //æ°å»ºä¿ååformData为对象ï¼å
æ¬æç»è¡¨ï¼å¯ä»¥ç»ç»è¡¨å设置å¼ï¼èªå·±è¾åºçformDataçå¼ |
| | | return true; |
| | | }, |
| | | updateBefore(formData) { |
| | | //ç¼è¾ä¿ååformData为对象ï¼å
æ¬æç»è¡¨ãå é¤è¡çId |
| | | return true; |
| | | }, |
| | | rowClick({ row, column, event }) { |
| | | //æ¥è¯¢çé¢ç¹å»è¡äºä»¶ |
| | | this.$refs.table.$refs.table.toggleRowSelection(row); //åå»è¡æ¶éä¸å½åè¡; |
| | | }, |
| | | modelOpenAfter(row) { |
| | | //ç¹å»ç¼è¾ãæ°å»ºæé®å¼¹åºæ¡åï¼å¯ä»¥å¨æ¤å¤åé»è¾ï¼å¦ï¼ä»åå°è·åæ°æ® |
| | | //(1)夿æ¯ç¼è¾è¿æ¯æ°å»ºæä½ï¼ this.currentAction=='Add'; |
| | | //(2)ç»å¼¹åºæ¡è®¾ç½®é»è®¤å¼ |
| | | //(3)this.editFormFields.åæ®µ='xxx'; |
| | | //妿éè¦ç»ä¸ææ¡è®¾ç½®é»è®¤å¼ï¼è¯·éåthis.editFormOptionsæ¾å°å段é
置对åºdata屿§çkeyå¼ |
| | | //ç䏿就æè¾åºçï¼console.log(this.editFormOptions) |
| | | } |
| | | } |
| | | }; |
| | | export default extension; |
| | | |
| | |
| | | searchBefore(param) { |
| | | //ç颿¥è¯¢å,å¯ä»¥ç»param.wheresæ·»å æ¥è¯¢åæ° |
| | | //è¿åfalseï¼åä¸ä¼æ§è¡æ¥è¯¢ |
| | | this.searchFormFields.orderType=[0] |
| | | return true; |
| | | }, |
| | | searchAfter(result) { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | |
| | | //æ¤jsæä»¶æ¯ç¨æ¥èªå®ä¹æ©å±ä¸å¡ä»£ç ï¼å¯ä»¥æ©å±ä¸äºèªå®ä¹é¡µé¢æè
éæ°é
ç½®çæç代ç |
| | | import http from '@/api/http.js' |
| | | import { h,createVNode, render,reactive ,ref } from 'vue'; |
| | | import { ElDialog , ElForm, ElFormItem, ElInput, ElButton, ElMessage ,ElSelect, ElOption} from 'element-plus'; |
| | | |
| | | import gridBody from './extend/outOrderDetail.vue' |
| | | let extension = { |
| | | components: { |
| | | //æ¥è¯¢ç颿©å±ç»ä»¶ |
| | | gridHeader: '', |
| | | gridBody: gridBody, |
| | | gridFooter: '', |
| | | //æ°å»ºãç¼è¾å¼¹åºæ¡æ©å±ç»ä»¶ |
| | | modelHeader: '', |
| | | modelBody: '', |
| | | modelFooter: '' |
| | | }, |
| | | tableAction: '', //æå®æå¼ 表çæé(è¿éå¡«å表å,é»è®¤ä¸ç¨å¡«å) |
| | | buttons: { view: [ |
| | | /* { |
| | | name: 'åºåº', |
| | | type: 'primary', |
| | | value: 'åºåº', |
| | | onClick: function () { // ä¿®å¤ï¼ç¨ElMessageæ¿ä»£this.$message |
| | | const selectedRows = this.$refs.table.getSelected(); |
| | | if (selectedRows.length === 0) { |
| | | ElMessage.warning('请å
éæ©è¦çæä»»å¡çè¡'); |
| | | return; |
| | | } |
| | | if (selectedRows.length > 1) { |
| | | ElMessage.warning('åªè½éæ©ä¸è¡'); |
| | | return; |
| | | } |
| | | |
| | | |
| | | // æææ ¡éªéè¿ï¼è§¦å主ç»ä»¶æå¼åºåºå¼¹çª |
| | | console.log('æææ ¡éªéè¿ï¼è§¦åopenOutboundDialogäºä»¶ï¼åæ®æ°æ®ï¼', selectedRows[0]); |
| | | |
| | | this.$emit('openOutboundDialog', { |
| | | transNo: selectedRows[0].transNo, // åºåºåç¼å· |
| | | createDate: selectedRows[0].createDate || new Date().toLocaleDateString() // åºåºæ¥æ |
| | | }); |
| | | } |
| | | }, */ |
| | | { |
| | | name: '空æçåºåº', |
| | | type: 'primary', |
| | | value: '空æçåºåº', |
| | | onClick: function () { |
| | | |
| | | |
| | | const platformOptions = Array.from({ length: 1 }, (_, i) => { |
| | | const num = 1; |
| | | return { label: `ç«å°${num}`, value: `1-2` }; |
| | | }); |
| | | |
| | | const quantityOptions = Array.from({ length: 6 }, (_, i) => ({ |
| | | label: (i + 1).toString(), |
| | | value: i + 1 |
| | | })); |
| | | |
| | | const warehouseOptions = ref([]); |
| | | const isLoadingWarehouses = ref(false); |
| | | |
| | | const getWarehouseList = async () => { |
| | | isLoadingWarehouses.value = true; |
| | | try { |
| | | const { data, status } = await http.post('/api/LocationInfo/GetLocationTypes'); |
| | | if (status && Array.isArray(data)) { |
| | | // æ ¼å¼åä»åºé项ï¼éé
ElSelectçlabel-valueæ ¼å¼ |
| | | warehouseOptions.value = data.map(item => ({ |
| | | label: item.locationTypeDesc, |
| | | value: item.locationType |
| | | })); |
| | | } else { |
| | | ElMessage.error('è·ååºåå表失败'); |
| | | warehouseOptions.value = []; |
| | | } |
| | | } catch (err) { |
| | | ElMessage.error('åºåæ°æ®è¯·æ±å¼å¸¸ï¼è¯·ç¨åéè¯'); |
| | | warehouseOptions.value = []; |
| | | } finally { |
| | | isLoadingWarehouses.value = false; |
| | | } |
| | | }; |
| | | |
| | | const mountNode = document.createElement('div'); |
| | | document.body.appendChild(mountNode); |
| | | |
| | | |
| | | const formData = reactive({ |
| | | warehouseCode:'', |
| | | palletCode: '', |
| | | selectedPlatform: platformOptions[0].value, |
| | | quantity:1 |
| | | }); |
| | | |
| | | const vnode = createVNode(ElDialog, { |
| | | title: '空æçåºåº', |
| | | width: '500px', |
| | | modelValue: true, |
| | | appendToBody: true, |
| | | onOpened: async () => { |
| | | await getWarehouseList(); |
| | | const inputRef = vnode.component.refs.boxCodeInput; |
| | | inputRef?.focus(); |
| | | }, |
| | | 'onUpdate:modelValue': (isVisible) => { |
| | | if (!isVisible) { |
| | | render(null, mountNode); |
| | | document.body.removeChild(mountNode); |
| | | } |
| | | }, |
| | | style: { |
| | | padding: '20px 0', |
| | | borderRadius: '8px' |
| | | } |
| | | }, { |
| | | default: () => h(ElForm, { |
| | | model: formData, |
| | | rules: { |
| | | warehouseCode:[ |
| | | { required: true, message: 'è¯·éæ©åºå', trigger: ['change', 'blur'] } |
| | | ], |
| | | palletCode: [ |
| | | { type: 'string', message: 'æç®±å·å¿
须为å符串', trigger: 'blur' } |
| | | ], |
| | | selectedPlatform: [ |
| | | { required: true, message: 'è¯·éæ©åºåºç«å°', trigger: 'change' } |
| | | ], |
| | | quantity:[ |
| | | { required: true, message: 'è¯·éæ©ç©ºç®±æ°é', trigger: 'change'} |
| | | ] |
| | | }, |
| | | ref: 'batchOutForm', |
| | | labelWidth: '100px', |
| | | style: { |
| | | padding: '0 30px', |
| | | } |
| | | }, |
| | | [ |
| | | // h(ElFormItem, { |
| | | // label: 'ä»åºåºå', |
| | | // prop: 'warehouseCode', |
| | | // style: { |
| | | // marginBottom: '24px' |
| | | // } |
| | | // }, [ |
| | | // h(ElSelect, { |
| | | // placeholder: 'è¯·éæ©ä»åºåºå', |
| | | // modelValue: formData.warehouseCode, |
| | | // 'onUpdate:modelValue': (val) => { |
| | | // formData.warehouseCode = val; |
| | | // }, |
| | | // style: { |
| | | // width: '100%', |
| | | // height: '40px', |
| | | // borderRadius: '4px', |
| | | // borderColor: '#dcdfe6' |
| | | // } |
| | | // }, warehouseOptions.value.map(platform => |
| | | // h(ElOption, { label: platform.label, value: platform.value }) |
| | | // )) |
| | | // ]), |
| | | h(ElFormItem, { |
| | | label: 'åºåºç«å°', |
| | | prop: 'selectedPlatform', |
| | | style: { |
| | | marginBottom: '24px' |
| | | } |
| | | }, [ |
| | | h(ElSelect, { |
| | | placeholder: 'è¯·éæ©åºåºç«å°', |
| | | modelValue: formData.selectedPlatform, |
| | | 'onUpdate:modelValue': (val) => { |
| | | formData.selectedPlatform = val; |
| | | }, |
| | | style: { |
| | | width: '100%', |
| | | height: '40px', |
| | | borderRadius: '4px', |
| | | borderColor: '#dcdfe6' |
| | | } |
| | | }, platformOptions.map(platform => |
| | | h(ElOption, { label: platform.label, value: platform.value }) |
| | | )) |
| | | ]), |
| | | // h(ElFormItem,{ |
| | | // label:'åºåºæ°é', |
| | | // prop:'quantity', |
| | | // style:{ |
| | | // marginBottom:'24px' |
| | | // } |
| | | // },[h(ElSelect,{ |
| | | // placeholder:'è¯·éæ©ç©ºç®±æ°é', |
| | | // modelValue:formData.quantity, |
| | | // 'onUpdate:modelValue':(val)=>{ |
| | | // formData.quantity=val; |
| | | // }, |
| | | // style:{ |
| | | // width:'100%', |
| | | // height:'40px', |
| | | // borderRadius:'4px', |
| | | // borderColor:'#dcdfe6' |
| | | // }, |
| | | // filterable:false |
| | | // }, |
| | | // quantityOptions.map(option=> |
| | | // h(ElOption,{ |
| | | // label:option.label, |
| | | // value:option.value |
| | | // }) |
| | | // ) |
| | | // )]), |
| | | h(ElFormItem, { |
| | | label: 'æç®±å·', |
| | | prop: 'palletCode', |
| | | style: { |
| | | marginBottom: '16px' |
| | | } |
| | | }, [ |
| | | h(ElInput, { |
| | | type: 'text', |
| | | placeholder: 'å¯éè¾å
¥æç®±å·ï¼ä¸å¡«åèªå¨åé
空æç®±', |
| | | modelValue: formData.palletCode, |
| | | 'onUpdate:modelValue': (val) => { |
| | | formData.palletCode = val; |
| | | }, |
| | | style: { |
| | | width: '100%', |
| | | height: '40px', |
| | | borderRadius: '4px', |
| | | borderColor: '#dcdfe6' |
| | | }, |
| | | attrs: { |
| | | placeholderStyle: 'color: #909399;' |
| | | } |
| | | }) |
| | | ]), |
| | | |
| | | h('div', { |
| | | style: { |
| | | textAlign: 'right', |
| | | marginTop: '8px', |
| | | paddingRight: '4px' |
| | | } |
| | | }, [ |
| | | h(ElButton, { |
| | | type: 'text', |
| | | onClick: () => { |
| | | render(null, mountNode); |
| | | document.body.removeChild(mountNode); |
| | | ElMessage.info('åæ¶åºåºæä½'); |
| | | }, |
| | | style: { |
| | | marginRight: '8px', |
| | | color: '#606266' |
| | | } |
| | | }, 'åæ¶'), |
| | | h(ElButton, { |
| | | type: 'primary', |
| | | onClick: async () => { |
| | | const formRef = vnode.component.refs.batchOutForm; |
| | | try { |
| | | await formRef.validate(); |
| | | } catch (err) { |
| | | return; |
| | | } |
| | | |
| | | http.post('/api/Task/PalletOutboundTask?palletCode='+formData.palletCode+'&endStation='+formData.selectedPlatform, { |
| | | |
| | | }).then(({ data, status, message }) => { |
| | | if (status) { |
| | | |
| | | ElMessage.success(`åºåºæå`); |
| | | this.refresh(); |
| | | render(null, mountNode); |
| | | document.body.removeChild(mountNode); |
| | | } else { |
| | | ElMessage.error(message || data?.message || 'åºåºå¤±è´¥'); |
| | | } |
| | | }).catch(() => { |
| | | ElMessage.error('请æ±å¤±è´¥ï¼è¯·ç¨åéè¯'); |
| | | }); |
| | | }, |
| | | style: { |
| | | borderRadius: '4px', |
| | | padding: '8px 20px' |
| | | } |
| | | }, 'ç¡®å®') |
| | | ]) |
| | | ]) |
| | | }); |
| | | |
| | | vnode.appContext = this.$.appContext; |
| | | render(vnode, mountNode); |
| | | } |
| | | } |
| | | ], box: [], detail: [] }, //æ©å±çæé® |
| | | methods: { |
| | | //ä¸é¢è¿äºæ¹æ³å¯ä»¥ä¿çä¹å¯ä»¥å é¤ |
| | | onInit() { |
| | | //æ©å±é¡µé¢åå§åæä½ |
| | | this.columns.push({ |
| | | field: 'æä½', |
| | | title: 'æä½', |
| | | width: 90, |
| | | fixed: 'right', |
| | | align: 'center', |
| | | formatter: (row) => { |
| | | return ( |
| | | '<i style="cursor: pointer;color: #2d8cf0;"class="el-icon-view">æ¥çæç»</i>' |
| | | ); |
| | | }, |
| | | click: (row) => { |
| | | const table = this.$refs.table.$refs.table; |
| | | if(table){ |
| | | table.clearSelection(); |
| | | table.toggleRowSelection(row,true); |
| | | } |
| | | const rowId =row.id; |
| | | console.log(rowId); |
| | | this.$refs.gridBody.open(row); |
| | | } |
| | | }); |
| | | }, |
| | | onInited() { |
| | | //æ¡æ¶åå§åé
ç½®å |
| | | //妿è¦é
ç½®æç»è¡¨,卿¤æ¹æ³æä½ |
| | | //this.detailOptions.columns.forEach(column=>{ }); |
| | | }, |
| | | searchBefore(param) { |
| | | //ç颿¥è¯¢å,å¯ä»¥ç»param.wheresæ·»å æ¥è¯¢åæ° |
| | | //è¿åfalseï¼åä¸ä¼æ§è¡æ¥è¯¢ |
| | | // this.searchFormFields.orderType=[215] |
| | | |
| | | let wheres = [{ |
| | | 'name': 'orderType', |
| | | 'value': '215', |
| | | 'displayType': 'text'}]; |
| | | |
| | | |
| | | param.wheres.push(...wheres); |
| | | return true; |
| | | }, |
| | | searchAfter(result) { |
| | | //æ¥è¯¢åï¼resultè¿åçæ¥è¯¢æ°æ®,å¯ä»¥å¨æ¾ç¤ºå°è¡¨æ ¼åå¤çè¡¨æ ¼çå¼ |
| | | return true; |
| | | }, |
| | | addBefore(formData) { |
| | | //æ°å»ºä¿ååformData为对象ï¼å
æ¬æç»è¡¨ï¼å¯ä»¥ç»ç»è¡¨å设置å¼ï¼èªå·±è¾åºçformDataçå¼ |
| | | return true; |
| | | }, |
| | | updateBefore(formData) { |
| | | //ç¼è¾ä¿ååformData为对象ï¼å
æ¬æç»è¡¨ãå é¤è¡çId |
| | | return true; |
| | | }, |
| | | rowClick({ row, column, event }) { |
| | | //æ¥è¯¢çé¢ç¹å»è¡äºä»¶ |
| | | this.$refs.table.$refs.table.toggleRowSelection(row); //åå»è¡æ¶éä¸å½åè¡; |
| | | }, |
| | | modelOpenAfter(row) { |
| | | //ç¹å»ç¼è¾ãæ°å»ºæé®å¼¹åºæ¡åï¼å¯ä»¥å¨æ¤å¤åé»è¾ï¼å¦ï¼ä»åå°è·åæ°æ® |
| | | //(1)夿æ¯ç¼è¾è¿æ¯æ°å»ºæä½ï¼ this.currentAction=='Add'; |
| | | //(2)ç»å¼¹åºæ¡è®¾ç½®é»è®¤å¼ |
| | | //(3)this.editFormFields.åæ®µ='xxx'; |
| | | //妿éè¦ç»ä¸ææ¡è®¾ç½®é»è®¤å¼ï¼è¯·éåthis.editFormOptionsæ¾å°å段é
置对åºdata屿§çkeyå¼ |
| | | //ç䏿就æè¾åºçï¼console.log(this.editFormOptions) |
| | | } |
| | | } |
| | | }; |
| | | export default extension; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <vol-box v-model="showDetialBox" :lazy="true" width="500px" :padding="15" title=""> |
| | | <!-- æå°ä¸ç¨å®¹å¨ --> |
| | | <div id="printContainer" style="position: absolute; left: -9999px;"> |
| | | <div class="print-page" v-for="(item, index) in printData" :key="index"> |
| | | <div class="material-card"> |
| | | <!-- <div class="header">ååè½ç©ææ è¯å¡(å°å
)</div> --> |
| | | <div class="dual-column preview-card-header-qrcode"> |
| | | <div class="preview-card-header">ç©æå¡ {{ idx + 1 }}</div> |
| | | <VueQrcode :value="generateQr(item)" :size="20" id="qrcode" /> |
| | | </div> |
| | | <div class="content"> |
| | | <!-- äºç»´ç æ¾å¨å³ä¸è§ --> |
| | | <!-- <div class="qr-section"> --> |
| | | <!-- <VueQrcode :value="generateQr(item)" id="qrcode" /> --> |
| | | <!-- </div> --> |
| | | <div class="row dual-column"> |
| | | <div class="column"> |
| | | <span class="label">æå·</span> |
| | | <span class="value code-value">{{ item.materialCode }}</span> |
| | | </div> |
| | | <div class="column"> |
| | | <span class="label">ä¾åºåç¼ç </span> |
| | | <span class="value">{{ item.supplierCode }}</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row dual-column"> |
| | | <div class="column"> |
| | | <span class="label">åå</span> |
| | | <span class="value">{{ item.materialName }}</span> |
| | | </div> |
| | | <div class="column"> |
| | | <span class="label">éè´åå·</span> |
| | | <span class="value">{{ item.purchaseOrderNo }}</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row dual-column"> |
| | | <div class="column"> |
| | | <span class="label">è§æ ¼</span> |
| | | <span class="value full-width">{{ item.specification }}</span> |
| | | </div> |
| | | <div class="column"> |
| | | <span class="label">æ°é/æ»æ°</span> |
| | | <span class="value">{{ item.quantityTotal }}</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row dual-column"> |
| | | <div class="column"> |
| | | <span class="label">æ¹å·</span> |
| | | <span class="value">{{ item.batchNumber }}</span> |
| | | </div> |
| | | <div class="column"> |
| | | <span class="label">æ¹æ¬¡</span> |
| | | <span class="value">{{ item.batch }}</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row dual-column"> |
| | | <div class="column"> |
| | | <span class="label">ååº</span> |
| | | <span class="value">{{ item.factory }}</span> |
| | | </div> |
| | | <div class="column"> |
| | | <span class="label">æ¥æ</span> |
| | | <span class="value">{{ item.date }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- é¢è§åºå --> |
| | | <div id="previewContent" class="preview-container"> |
| | | <div class="preview-header">ååè½ç©ææ è¯å¡(å°å
) - é¢è§ (å
±{{ printData.length }}个)</div> |
| | | <div class="preview-scroll"> |
| | | <div v-for="(item, idx) in printData" :key="idx" class="preview-card"> |
| | | <div class="dual-column preview-card-header-qrcode"> |
| | | <div class="preview-card-header">ç©æå¡ {{ idx + 1 }}</div> |
| | | <VueQrcode :value="generateQr(item)" :size="20" id="qrcode" /> |
| | | </div> |
| | | <div class="preview-wrapper"> |
| | | <div class="content-preview"> |
| | | <div class="row-preview dual-column"> |
| | | <div class="column-preview"> |
| | | <span class="label-preview">æå·</span> |
| | | <span class="value-preview code-value">{{ item.materialCode }}</span> |
| | | </div> |
| | | <div class="column-preview"> |
| | | <span class="label-preview">ä¾åºåç¼ç </span> |
| | | <span class="value-preview">{{ item.supplierCode }}</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row-preview dual-column"> |
| | | <div class="column-preview"> |
| | | <span class="label-preview">åå</span> |
| | | <span class="value-preview">{{ item.materialName }}</span> |
| | | </div> |
| | | <div class="column-preview"> |
| | | <span class="label-preview">éè´åå·</span> |
| | | <span class="value-preview">{{ item.purchaseOrderNo }}</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row-preview dual-column"> |
| | | <div class="column-preview"> |
| | | <span class="label-preview">è§æ ¼</span> |
| | | <span class="value-preview full-width">{{ item.specification }}</span> |
| | | </div> |
| | | <div class="column-preview"> |
| | | <span class="label-preview">æ°é/æ»æ°</span> |
| | | <span class="value-preview">{{ item.quantityTotal }}</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row-preview dual-column"> |
| | | <div class="column-preview"> |
| | | <span class="label-preview">æ¹å·</span> |
| | | <span class="value-preview">{{ item.batchNumber }}</span> |
| | | </div> |
| | | <div class="column-preview"> |
| | | <span class="label-preview">æ¹æ¬¡</span> |
| | | <span class="value-preview">{{ item.batch }}</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row-preview dual-column"> |
| | | <div class="column-preview"> |
| | | <span class="label-preview">ååº</span> |
| | | <span class="value-preview">{{ item.factory }}</span> |
| | | </div> |
| | | <div class="column-preview"> |
| | | <span class="label-preview">æ¥æ</span> |
| | | <span class="value-preview">{{ item.date }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <template #footer> |
| | | <div class="footer-actions"> |
| | | <span class="print-count">å
± {{ printData.length }} ä¸ªç©æå¡å¾
æå°</span> |
| | | <div> |
| | | <el-button type="primary" size="small" @click="print">æå°å
¨é¨</el-button> |
| | | <el-button type="danger" size="small" @click="showDetialBox = false">å
³é</el-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </vol-box> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import VolBox from "@/components/basic/VolBox.vue"; |
| | | import VueQrcode from "vue-qrcode"; |
| | | |
| | | export default { |
| | | components: { VolBox, VueQrcode }, |
| | | data() { |
| | | return { |
| | | showDetialBox: false, |
| | | printData: [], // å卿尿°æ®éå |
| | | }; |
| | | }, |
| | | methods: { |
| | | generateQr(item) { |
| | | return `${item.materialCode}_${item.supplierCode}_${item.purchaseOrderNo}_${item.materialName}_${item.batch}_${item.batchNumber}_${item.factory}_${item.date}`; |
| | | }, |
| | | |
| | | open(rows) { |
| | | this.showDetialBox = true; |
| | | this.printData = Array.isArray(rows) ? rows : [rows]; |
| | | console.log('æå°æ°æ®:', this.printData); |
| | | }, |
| | | |
| | | async print() { |
| | | if (this.printData.length === 0) { |
| | | this.$message.warning('没æå¯æå°çæ°æ®'); |
| | | return; |
| | | } |
| | | |
| | | this.$nextTick(() => { |
| | | try { |
| | | const printContent = document.getElementById("printContainer").innerHTML; |
| | | const printWindow = window.open("", "_blank", "width=800,height=600,scrollbars=yes"); |
| | | |
| | | if (!printWindow) { |
| | | this.$message.error('æ æ³æå¼æå°çªå£ï¼è¯·æ£æ¥æµè§å¨å¼¹çªè®¾ç½®'); |
| | | return; |
| | | } |
| | | |
| | | printWindow.document.write(` |
| | | <!DOCTYPE html> |
| | | <html> |
| | | <head> |
| | | <meta charset="UTF-8"> |
| | | <title>ç©ææ è¯å¡æå° - å
±${this.printData.length}个</title> |
| | | <style> |
| | | /* éç½®æææ ·å¼ */ |
| | | * { |
| | | margin: 0; |
| | | padding: 0; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | body { |
| | | font-family: SimSun, "å®ä½", sans-serif; |
| | | -webkit-print-color-adjust: exact !important; |
| | | print-color-adjust: exact !important; |
| | | color-adjust: exact !important; |
| | | } |
| | | #qrcode { |
| | | width: 60px; |
| | | height: 60px; |
| | | display: block; |
| | | margin: 0, 15px |
| | | } |
| | | @media print { |
| | | @page { |
| | | size: 80mm 60mm; |
| | | margin: 0; |
| | | padding: 0; |
| | | } |
| | | |
| | | body { |
| | | margin: 0 !important; |
| | | padding: 0 !important; |
| | | width: 80mm !important; |
| | | background: white !important; |
| | | } |
| | | |
| | | .print-page { |
| | | width: 80mm !important; |
| | | height: 60mm !important; |
| | | page-break-after: always !important; |
| | | break-after: page !important; |
| | | margin: 0 !important; |
| | | padding: 2mm !important; |
| | | display: block !important; |
| | | } |
| | | |
| | | .print-page:last-child { |
| | | page-break-after: auto !important; |
| | | } |
| | | |
| | | .material-card { |
| | | width: 80mm !important; |
| | | height: 56mm !important; |
| | | border: 0.3mm solid #000 !important; |
| | | padding: 1mm !important; |
| | | box-sizing: border-box !important; |
| | | position: relative !important; |
| | | background: white !important; |
| | | } |
| | | |
| | | .header { |
| | | font-size: 3.5mm !important; |
| | | font-weight: bold !important; |
| | | text-align: center !important; |
| | | margin-bottom: 1mm !important; |
| | | padding-bottom: 0.5mm !important; |
| | | border-bottom: 0.2mm solid #000 !important; |
| | | } |
| | | |
| | | .content { |
| | | height: calc(100% - 6mm) !important; |
| | | position: relative !important; |
| | | } |
| | | |
| | | .row { |
| | | display: flex !important; |
| | | margin-bottom: 0.8mm !important; |
| | | min-height: 6mm !important; |
| | | } |
| | | |
| | | .dual-column { |
| | | display: flex !important; |
| | | justify-content: space-between !important; |
| | | } |
| | | |
| | | .column { |
| | | flex: 1 !important; |
| | | display: flex !important; |
| | | align-items: center !important; |
| | | } |
| | | |
| | | .column:first-child { |
| | | margin-right: 2mm !important; |
| | | } |
| | | |
| | | .label { |
| | | font-weight: bold !important; |
| | | flex: 0 0 15mm !important; |
| | | white-space: nowrap !important; |
| | | font-size: 2.2mm !important; |
| | | } |
| | | |
| | | .value { |
| | | flex: 1 !important; |
| | | overflow: hidden !important; |
| | | text-overflow: ellipsis !important; |
| | | white-space: nowrap !important; |
| | | border-bottom: 0.1mm dashed #666 !important; |
| | | padding-bottom: 0.2mm !important; |
| | | min-height: 2.5mm !important; |
| | | font-size: 2.2mm !important; |
| | | } |
| | | |
| | | .code-value { |
| | | font-weight: bold !important; |
| | | } |
| | | |
| | | .full-width { |
| | | white-space: normal !important; |
| | | word-break: break-all !important; |
| | | line-height: 1.2 !important; |
| | | } |
| | | |
| | | /* äºç»´ç æ ·å¼ */ |
| | | .qr-section { |
| | | width: 10mm !important; |
| | | height: 12mm !important; |
| | | font-siz:10px; |
| | | } |
| | | |
| | | .qr-section canvas { |
| | | width: 10mm !important; |
| | | height: 10mm !important; |
| | | max-width: 100% !important; |
| | | max-height: 100% !important; |
| | | } |
| | | } |
| | | |
| | | /* å±å¹é¢è§æ ·å¼ */ |
| | | @media screen { |
| | | body { |
| | | background: #f5f5f5; |
| | | padding: 10px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | |
| | | .print-page { |
| | | width: 80mm; |
| | | height: 60mm; |
| | | margin: 10px 0; |
| | | padding: 2mm; |
| | | background: white; |
| | | box-shadow: 0 2px 10px rgba(0,0,0,0.1); |
| | | border: 1px dashed #ccc; |
| | | } |
| | | |
| | | .material-card { |
| | | width: 80mm; |
| | | height: 60mm; |
| | | border: 0.3mm solid #000; |
| | | padding: 1.5mm; |
| | | background: white; |
| | | position: relative; |
| | | } |
| | | |
| | | .qr-section { |
| | | position: absolute; |
| | | top: 4mm; |
| | | right: 2mm; |
| | | width: 12mm; |
| | | height: 12mm; |
| | | border: 0.2mm solid #ccc; |
| | | padding: 0.5mm; |
| | | background: white; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .qr-section canvas { |
| | | width: 10mm !important; |
| | | height: 10mm !important; |
| | | } |
| | | } |
| | | </style> |
| | | </head> |
| | | <body> |
| | | ${printContent} |
| | | <script> |
| | | window.onload = function() { |
| | | console.log('æå°é¡µé¢å è½½å®æï¼å
±${this.printData.length}ä¸ªç©æå¡'); |
| | | // çå¾
äºç»´ç 渲æå®æ |
| | | setTimeout(() => { |
| | | // 强å¶è®¾ç½®äºç»´ç canvas尺寸 |
| | | const canvases = document.querySelectorAll('canvas'); |
| | | canvases.forEach(canvas => { |
| | | canvas.style.width = '10mm !important'; |
| | | canvas.style.height = '10mm !important'; |
| | | }); |
| | | window.print(); |
| | | }, 800); |
| | | }; |
| | | |
| | | window.onafterprint = function() { |
| | | setTimeout(() => { |
| | | window.close(); |
| | | }, 500); |
| | | }; |
| | | <\/script> |
| | | </body> |
| | | </html> |
| | | `); |
| | | |
| | | printWindow.document.close(); |
| | | |
| | | } catch (error) { |
| | | console.error('æå°é误:', error); |
| | | this.$message.error('æå°å¤±è´¥: ' + error.message); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | #qrcode { |
| | | width: 60px; |
| | | height: 60px; |
| | | display: block; |
| | | margin: 0, 15px |
| | | } |
| | | |
| | | .preview-container { |
| | | max-height: 500px; |
| | | overflow: hidden; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .preview-header { |
| | | text-align: center; |
| | | font-size: 16px; |
| | | font-weight: bold; |
| | | margin-bottom: 10px; |
| | | padding: 8px; |
| | | background: #f0f0f0; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .preview-scroll { |
| | | max-height: 400px; |
| | | overflow-y: auto; |
| | | padding: 10px; |
| | | border: 1px solid #e0e0e0; |
| | | border-radius: 4px; |
| | | background: #f9f9f9; |
| | | } |
| | | |
| | | .preview-card { |
| | | width: 320px; |
| | | height: 240px; |
| | | margin: 0 auto 15px auto; |
| | | padding: 8px; |
| | | border: 1px solid #ccc; |
| | | font-family: SimSun; |
| | | box-sizing: border-box; |
| | | border: 2px solid #000; |
| | | background: white; |
| | | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); |
| | | position: relative; |
| | | } |
| | | |
| | | .preview-card:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | .preview-card-header { |
| | | text-align: center; |
| | | font-size: 14px; |
| | | /* font-weight: bold; |
| | | margin-bottom: 8px; |
| | | padding-bottom: 4px; |
| | | border-bottom: 1px solid #000; |
| | | background: #f5f5f5; |
| | | padding: 4px; */ |
| | | height: 60px; |
| | | width: 60px; |
| | | } |
| | | |
| | | .preview-wrapper { |
| | | position: relative; |
| | | height: calc(100% - 40px); |
| | | } |
| | | |
| | | .content-preview { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .row-preview { |
| | | /* margin-bottom: px; */ |
| | | min-height: 32px; |
| | | } |
| | | |
| | | .dual-column { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | } |
| | | |
| | | .column-preview { |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .column-preview:first-child { |
| | | margin-right: 10px; |
| | | } |
| | | |
| | | .label-preview { |
| | | font-weight: bold; |
| | | flex: 0 0 60px; |
| | | white-space: nowrap; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .value-preview { |
| | | flex: 1; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | font-size: 12px; |
| | | border-bottom: 1px dashed #666; |
| | | padding-bottom: 2px; |
| | | } |
| | | |
| | | .code-value { |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .full-width { |
| | | display: block; |
| | | margin-top: 2px; |
| | | white-space: normal; |
| | | word-break: break-all; |
| | | line-height: 1.2; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | /* é¢è§åºåäºç»´ç æ ·å¼ */ |
| | | .qr-section-preview { |
| | | position: absolute; |
| | | top: 10px; |
| | | right: 10px; |
| | | width: 150px; |
| | | height: 175px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border: 1px solid #ddd; |
| | | background: white; |
| | | padding: 2px; |
| | | } |
| | | |
| | | .qr-section-preview canvas { |
| | | width: 56px !important; |
| | | height: 56px !important; |
| | | } |
| | | |
| | | .footer-actions { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | width: 100%; |
| | | } |
| | | |
| | | .print-count { |
| | | font-size: 14px; |
| | | color: #409EFF; |
| | | font-weight: bold; |
| | | } |
| | | </style> |
| | |
| | | path: '/materielToMes', |
| | | name: 'Dt_MaterielToMes', |
| | | component: () => import('@/views/inbound/Dt_MaterielToMes.vue') |
| | | }, |
| | | }, { |
| | | path:'/allocateinboundOrder', |
| | | name: 'allocateinboundOrder', |
| | | component: () => import('@/views/inbound/allocateinboundOrder.vue') |
| | | |
| | | },{ |
| | | path:'allocateoutboundOrder', |
| | | name: 'allocateoutboundOrder', |
| | | component: () => import('@/views/outbound/allocateoutboundOrder.vue') |
| | | }, |
| | | { |
| | | path: '/allocateOrder', |
| | | name: 'Dt_AllocateOrder', |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | |
| | | <template> |
| | | <view-grid |
| | | ref="grid" |
| | | @openPalletDialog="handleOpenPalletDialog" |
| | | :columns="columns" |
| | | :detail="detail" |
| | | :editFormFields="editFormFields" |
| | | :editFormOptions="editFormOptions" |
| | | :searchFormFields="searchFormFields" |
| | | :searchFormOptions="searchFormOptions" |
| | | :table="table" |
| | | :extend="extend" |
| | | > |
| | | </view-grid> |
| | | <!-- 2. ç»çå¼¹çªï¼ç¡®ä¿propsåäºä»¶ç»å®æ£ç¡® --> |
| | | <PalletDialog |
| | | v-model:visible="palletVisible" |
| | | :docNo="currentPalletDocNo" |
| | | @back-success="handlePalletBackSuccess" |
| | | ></PalletDialog> |
| | | |
| | | </template> |
| | | <script> |
| | | import extend from "@/extension/inbound/allocateinboundOrder.js"; |
| | | import ViewGrid from '@/components/basic/ViewGrid/ViewGrid.vue'; |
| | | import { ref, defineComponent } from "vue"; |
| | | import PalletDialog from "@/extension/inbound/extend/Pallet.vue"; |
| | | export default defineComponent({ |
| | | components: { |
| | | // å
³é®ä¿®å¤2ï¼ç»ä»¶æ³¨åå䏿¨¡æ¿æ ç¾åéé
ï¼kebab-case对åºview-gridï¼ |
| | | viewGrid: ViewGrid, // 注å为kebab-caseï¼æ¨¡æ¿ç¨<view-grid> |
| | | PalletDialog // 注åç»çå¼¹çª |
| | | |
| | | }, |
| | | setup() { |
| | | const table = ref({ |
| | | key: "id", |
| | | footer: "Foots", |
| | | cnName: "è°æ¨å(æºä»è°å¤é¨ä»åº)", |
| | | name: "inboundOrder", |
| | | url: "/InboundOrder/", |
| | | sortName: "id", |
| | | }); |
| | | const editFormFields = ref({ |
| | | orderType: "", |
| | | inboundOrderNo: "", |
| | | upperOrderNo: "", |
| | | remark: "", |
| | | }); |
| | | const editFormOptions = ref([ |
| | | [ |
| | | { |
| | | title: "åæ®ç±»å", |
| | | required: true, |
| | | field: "orderType", |
| | | type: "select", |
| | | dataKey: "inOrderType", |
| | | data: [], |
| | | }, |
| | | { |
| | | field: "inboundOrderNo", |
| | | title: "åæ®ç¼å·", |
| | | type: "string", |
| | | }, |
| | | { |
| | | title: "䏿¸¸åæ®ç¼å·", |
| | | field: "upperOrderNo", |
| | | type: "string", |
| | | }, |
| | | { |
| | | title: "夿³¨", |
| | | field: "remark", |
| | | type: "textarea", |
| | | }, |
| | | ], |
| | | ]); |
| | | const searchFormFields = ref({ |
| | | inboundOrderNo: "", |
| | | upperOrderNo: "", |
| | | orderType: "115", |
| | | orderStatus: "", |
| | | createType: "", |
| | | creater: "", |
| | | createDate: "", |
| | | }); |
| | | const searchFormOptions = ref([ |
| | | [ |
| | | { title: "åæ®ç¼å·", field: "inboundOrderNo", type: "like" }, |
| | | { title: "䏿¸¸åæ®ç¼å·", field: "upperOrderNo", type: "like" }, |
| | | { |
| | | title: "åæ®ç±»å", |
| | | field: "orderType", |
| | | type: "select", |
| | | dataKey: "inOrderType", |
| | | data: [], |
| | | }, |
| | | { |
| | | title: "åæ®ç¶æ", |
| | | field: "orderStatus", |
| | | type: "select", |
| | | dataKey: "inboundState", |
| | | data: [], |
| | | }, |
| | | ], |
| | | [ |
| | | { |
| | | title: "å建æ¹å¼", |
| | | field: "createType", |
| | | type: "select", |
| | | dataKey: "createType", |
| | | data: [], |
| | | }, |
| | | { title: "å建è
", field: "creater", type: "like" }, |
| | | { title: "å建æ¶é´", field: "createDate", type: "datetime" }, |
| | | ], |
| | | ]); |
| | | const columns = ref([ |
| | | { |
| | | field: "id", |
| | | title: "Id", |
| | | type: "int", |
| | | width: 90, |
| | | hidden: true, |
| | | readonly: true, |
| | | require: true, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "inboundOrderNo", |
| | | title: "åæ®ç¼å·", |
| | | type: "string", |
| | | width: 120, |
| | | align: "left", |
| | | link: true, |
| | | }, |
| | | { |
| | | field: "upperOrderNo", |
| | | title: "䏿¸¸åæ®ç¼å·", |
| | | type: "string", |
| | | width: 150, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "orderType", |
| | | title: "åæ®ç±»å", |
| | | type: "string", |
| | | width: 150, |
| | | align: "left", |
| | | bind: { key: "inOrderType", data: [] }, |
| | | }, |
| | | { |
| | | field: "businessType", |
| | | title: "ä¸å¡ç±»å", |
| | | type: "string", |
| | | width: 150, |
| | | align: "left", |
| | | bind: { key: "businessType", data: [] }, |
| | | }, |
| | | { |
| | | field: "orderStatus", |
| | | title: "åæ®ç¶æ", |
| | | type: "decimal", |
| | | width: 90, |
| | | align: "left", |
| | | bind: { key: "inboundState", data: [] }, |
| | | }, |
| | | { |
| | | field: "createType", |
| | | title: "å建æ¹å¼", |
| | | type: "string", |
| | | width: 120, |
| | | align: "left", |
| | | bind: { key: "createType", data: [] }, |
| | | }, |
| | | { |
| | | field: "factoryArea", |
| | | title: "ååº", |
| | | type: "string", |
| | | width: 120, |
| | | align: "left" |
| | | }, |
| | | { |
| | | field: "creater", |
| | | title: "å建人", |
| | | type: "string", |
| | | width: 90, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "createDate", |
| | | title: "å建æ¶é´", |
| | | type: "datetime", |
| | | width: 160, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "modifier", |
| | | title: "ä¿®æ¹äºº", |
| | | type: "string", |
| | | width: 100, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "modifyDate", |
| | | title: "ä¿®æ¹æ¶é´", |
| | | type: "datetime", |
| | | width: 160, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "remark", |
| | | title: "夿³¨", |
| | | type: "string", |
| | | width: 100, |
| | | align: "left", |
| | | }, |
| | | ]); |
| | | const detail = ref({ |
| | | cnName: "è°æ¨åæç»", |
| | | table: "InboundOrderDetail", |
| | | columns: [ |
| | | { |
| | | field: "id", |
| | | title: "Id", |
| | | type: "int", |
| | | width: 90, |
| | | hidden: true, |
| | | readonly: true, |
| | | require: true, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "orderId", |
| | | title: "è°æ¨å主é®", |
| | | type: "string", |
| | | width: 90, |
| | | align: "left", |
| | | hidden: true, |
| | | }, |
| | | { |
| | | field: "materielCode", |
| | | title: "ç©æç¼å·", |
| | | type: "select", |
| | | width: 150, |
| | | align: "left", |
| | | edit: { type: "" }, |
| | | required: true, |
| | | }, |
| | | { |
| | | field: "materielCode", |
| | | title: "ç©æåç§°", |
| | | type: "string", |
| | | width: 100, |
| | | align: "left", |
| | | bind: { key: "MaterielNames", data: [] }, |
| | | }, |
| | | { |
| | | field: "batchNo", |
| | | title: "æ¹æ¬¡å·", |
| | | type: "decimal", |
| | | width: 90, |
| | | align: "left", |
| | | edit: { type: "" }, |
| | | required: true, |
| | | }, |
| | | { |
| | | field: "supplyCode", |
| | | title: "ä¾åºåç¼å·", |
| | | type: "decimal", |
| | | width: 90, |
| | | align: "left", |
| | | edit: { type: "" }, |
| | | required: true, |
| | | }, |
| | | { |
| | | field: "warehouseCode", |
| | | title: "ä»åºå·", |
| | | type: "decimal", |
| | | width: 90, |
| | | align: "left", |
| | | required: true |
| | | }, |
| | | { |
| | | field: "barcode", |
| | | title: "æ¡ç ", |
| | | type: "decimal", |
| | | width: 90, |
| | | align: "left", |
| | | edit: { type: "" }, |
| | | required: true, |
| | | }, |
| | | { |
| | | field: "orderQuantity", |
| | | title: "åæ®æ°é", |
| | | type: "decimal", |
| | | width: 90, |
| | | align: "left", |
| | | edit: { type: "number" }, |
| | | required: true, |
| | | }, |
| | | { |
| | | field: "receiptQuantity", |
| | | title: "ç»çæ°é", |
| | | type: "int", |
| | | width: 120, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "overInQuantity", |
| | | title: "䏿¶æ°é", |
| | | type: "string", |
| | | width: 200, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "orderDetailStatus", |
| | | title: "订åæç»ç¶æ", |
| | | type: "string", |
| | | width: 180, |
| | | align: "left", |
| | | bind: { key: "orderDetailStatusEnum", data: [] }, |
| | | }, |
| | | { |
| | | field: "creater", |
| | | title: "å建人", |
| | | type: "string", |
| | | width: 90, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "createDate", |
| | | title: "å建æ¶é´", |
| | | type: "datetime", |
| | | width: 160, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "modifier", |
| | | title: "ä¿®æ¹äºº", |
| | | type: "string", |
| | | width: 100, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "modifyDate", |
| | | title: "ä¿®æ¹æ¶é´", |
| | | type: "datetime", |
| | | width: 160, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "remark", |
| | | title: "夿³¨", |
| | | type: "string", |
| | | width: 100, |
| | | align: "left", |
| | | }, |
| | | ], |
| | | sortName: "id", |
| | | key: "id", |
| | | }); |
| | | // 6. ç»çå¼¹çªèå¨ï¼ææåéå¿
é¡»è¿åï¼ |
| | | const palletVisible = ref(false); |
| | | const currentPalletDocNo = ref(""); |
| | | |
| | | const handleOpenPalletDialog = (docNo) => { |
| | | console.log('主ç»ä»¶æ¶å°ç»çäºä»¶ï¼åæ®å·ï¼', docNo); |
| | | currentPalletDocNo.value = docNo; |
| | | palletVisible.value = true; |
| | | }; |
| | | |
| | | const handlePalletBackSuccess = () => { |
| | | console.log('ç»çåä¼ æåï¼å·æ°è¡¨æ ¼'); |
| | | grid.value?.refresh(); // æ¤æ¶gridRefå·²æè½½ï¼å¯è°ç¨æ¹æ³ |
| | | }; |
| | | |
| | | return { |
| | | table, |
| | | extend, |
| | | editFormFields, |
| | | editFormOptions, |
| | | searchFormFields, |
| | | searchFormOptions, |
| | | columns, |
| | | detail, |
| | | // ç»çå¼¹çªç¸å
³ |
| | | PalletDialog, // å¼¹çªç»ä»¶ï¼æ éè¿åï¼æ³¨åå³å¯ï¼ä½åééè¿åï¼ |
| | | palletVisible, |
| | | currentPalletDocNo, |
| | | handleOpenPalletDialog, |
| | | handlePalletBackSuccess |
| | | }; |
| | | }, |
| | | }); |
| | | </script> |
| | | |
| | |
| | | const searchFormFields = ref({ |
| | | inboundOrderNo: "", |
| | | upperOrderNo: "", |
| | | orderType: "", |
| | | orderType: "0", |
| | | orderStatus: "", |
| | | createType: "", |
| | | creater: "", |
| | |
| | | field: "orderType", |
| | | type: "select", |
| | | dataKey: "inOrderType", |
| | | data: [], |
| | | data: [0], |
| | | }, |
| | | { |
| | | title: "åæ®ç¶æ", |
| | |
| | | @keyup.enter.native="onBarcodeScan"> |
| | | </el-input> |
| | | <el-button type="success" @click="confirmPicking">确认æ£é</el-button> |
| | | <el-button type="warning" @click="openSplitDialog">æå
</el-button> |
| | | <el-button type="info" @click="openRevertSplitDialog">æ¤éæå
</el-button> |
| | | <!-- <el-button type="warning" @click="openSplitDialog">æå
</el-button> |
| | | <el-button type="info" @click="openRevertSplitDialog">æ¤éæå
</el-button> --> |
| | | |
| | | <el-button type="primary" @click="openBatchReturnDialog">ååº</el-button> |
| | | <!-- <el-button type="danger" @click="handleDirectOutbound">ç´æ¥åºåº</el-button> --> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <print-view ref="childs" @parentcall="parentcall"></print-view> |
| | | </template> |
| | | |
| | | <script> |
| | |
| | | import { ref, defineComponent } from "vue"; |
| | | import { ElMessage } from 'element-plus' |
| | | import { useRoute } from 'vue-router' |
| | | import printView from "@/extension/outbound/extend/printView.vue" |
| | | |
| | | export default defineComponent({ |
| | | name: 'PickingConfirm', |
| | | components: { |
| | | |
| | | }, |
| | | components: {printView}, |
| | | props: { |
| | | orderNo: { |
| | | type: String, |
| | |
| | | this.$message.success('æ£é确认æå'); |
| | | this.scanData.barcode = ''; // æ¸
ç©ºç©ææ¡ç |
| | | this.loadData(); |
| | | |
| | | console.log(res.data.splitResults) |
| | | if(res.data && res.data.splitResults.length>0){ |
| | | // è°ç¨åç»ä»¶æå°æ¹æ³ |
| | | this.$refs.childs.open(res.data.splitResults); |
| | | //this.$refs.childs.printSplitLabel(res.data.splitResults); |
| | | } |
| | | // æååç»§ç»èç¦å°ç©ææ¡ç è¾å
¥æ¡ï¼åå¤ä¸ä¸ä¸ªæ«ç |
| | | this.$nextTick(() => { |
| | | this.$refs.barcodeInput.focus(); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | |
| | | <template> |
| | | <view-grid |
| | | ref="grid" |
| | | @openOutboundDialog="handleOpenOutboundDialog" |
| | | :columns="columns" |
| | | :detail="detail" |
| | | :editFormFields="editFormFields" |
| | | :editFormOptions="editFormOptions" |
| | | :searchFormFields="searchFormFields" |
| | | :searchFormOptions="searchFormOptions" |
| | | :table="table" |
| | | :extend="extend" |
| | | > |
| | | </view-grid> |
| | | <!-- åºåºæä½å¼¹çª --> |
| | | <OutboundDialog |
| | | v-model:visible="outboundVisible" |
| | | :selected-document="selectedOutboundDocument" |
| | | @outbound-success="handleOutboundSuccess" |
| | | ></OutboundDialog> |
| | | </template> |
| | | <script> |
| | | import extend from "@/extension/outbound/allocateoutboundOrder.js"; |
| | | import ViewGrid from '@/components/basic/ViewGrid/ViewGrid.vue'; |
| | | import { ref, defineComponent } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import OutboundDialog from "@/extension/outbound/extend/OutBound.vue"; // å¼å
¥åºåºå¼¹çªç»ä»¶ |
| | | |
| | | |
| | | export default defineComponent({ |
| | | components: { |
| | | // å
³é®ä¿®å¤2ï¼ç»ä»¶æ³¨åå䏿¨¡æ¿æ ç¾åéé
ï¼kebab-case对åºview-gridï¼ |
| | | viewGrid: ViewGrid, // 注å为kebab-caseï¼æ¨¡æ¿ç¨<view-grid> |
| | | OutboundDialog // 注ååºåºå¼¹çªç»ä»¶ |
| | | }, |
| | | setup() { |
| | | const table = ref({ |
| | | key: "id", |
| | | footer: "Foots", |
| | | cnName: "è°æ¨å(å¤é¨ä»åºè°æºä»)", |
| | | name: "outboundOrder", |
| | | url: "/OutboundOrder/", |
| | | sortName: "id", |
| | | }); |
| | | const editFormFields = ref({ |
| | | orderType: "", |
| | | orderNo:"", |
| | | upperOrderNo: "", |
| | | orderStatus: "", |
| | | remark: "", |
| | | warehouseId:"" |
| | | }); |
| | | const editFormOptions = ref([ |
| | | [ |
| | | { |
| | | title: "åæ®ç±»å", |
| | | required: true, |
| | | field: "orderType", |
| | | type: "select", |
| | | dataKey: "outOrderType", |
| | | data: [], |
| | | }, |
| | | { |
| | | field: "orderNo", |
| | | title: "åæ®ç¼å·", |
| | | type: "string", |
| | | readonly:true |
| | | }, |
| | | { |
| | | title: "䏿¸¸åæ®ç¼å·", |
| | | field: "upperOrderNo", |
| | | type: "string", |
| | | }, |
| | | { |
| | | title: "åæ®ç¶æ", |
| | | field: "orderStatus", |
| | | type: "select", |
| | | dataKey: "inboundState", |
| | | data: [], |
| | | readonly: true, |
| | | }, |
| | | { |
| | | title: "ä»åº", |
| | | field: "warehouseId", |
| | | type: "select", |
| | | dataKey: "warehouses", |
| | | data: [], |
| | | required: true, |
| | | }, |
| | | { |
| | | title: "夿³¨", |
| | | field: "remark", |
| | | type: "textarea", |
| | | }, |
| | | ], |
| | | ]); |
| | | const searchFormFields = ref({ |
| | | orderNo: "", |
| | | upperOrderNo: "", |
| | | orderType: "215", |
| | | orderStatus: "", |
| | | createType: "", |
| | | creater: "", |
| | | createDate: "", |
| | | }); |
| | | const searchFormOptions = ref([ |
| | | [ |
| | | { title: "åæ®ç¼å·", field: "orderNo", type: "like" }, |
| | | { title: "䏿¸¸åæ®ç¼å·", field: "upperOrderNo", type: "like" }, |
| | | { |
| | | title: "åæ®ç±»å", |
| | | field: "orderType", |
| | | type: "select", |
| | | dataKey: "outOrderType", |
| | | data: [], |
| | | }, |
| | | { |
| | | title: "åæ®ç¶æ", |
| | | field: "orderStatus", |
| | | type: "select", |
| | | dataKey: "outboundStatusEnum", |
| | | data: [], |
| | | }, |
| | | ], |
| | | [ |
| | | { |
| | | title: "å建æ¹å¼", |
| | | field: "createType", |
| | | type: "select", |
| | | dataKey: "createType", |
| | | data: [], |
| | | }, |
| | | { title: "å建è
", field: "creater", type: "like" }, |
| | | { title: "å建æ¶é´", field: "createDate", type: "datetime" }, |
| | | ], |
| | | ]); |
| | | const columns = ref([ |
| | | { |
| | | field: "id", |
| | | title: "Id", |
| | | type: "int", |
| | | width: 90, |
| | | hidden: true, |
| | | readonly: true, |
| | | require: true, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "orderNo", |
| | | title: "åæ®ç¼å·", |
| | | type: "string", |
| | | width: 160, |
| | | align: "left", |
| | | // link: true, |
| | | }, |
| | | { |
| | | field: "upperOrderNo", |
| | | title: "䏿¸¸åæ®ç¼å·", |
| | | type: "string", |
| | | width: 160, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "orderType", |
| | | title: "åæ®ç±»å", |
| | | type: "string", |
| | | width: 150, |
| | | align: "left", |
| | | bind: { key: "outOrderType", data: [] }, |
| | | }, |
| | | { |
| | | field: "businessType", |
| | | title: "ä¸å¡ç±»å", |
| | | type: "string", |
| | | width: 150, |
| | | align: "left", |
| | | bind: { key: "businessType", data: [] }, |
| | | }, |
| | | { |
| | | field: "orderStatus", |
| | | title: "åæ®ç¶æ", |
| | | type: "decimal", |
| | | width: 90, |
| | | align: "left", |
| | | bind: { key: "outboundStatusEnum", data: [] }, |
| | | }, |
| | | { |
| | | field: "createType", |
| | | title: "å建æ¹å¼", |
| | | type: "string", |
| | | width: 120, |
| | | align: "left", |
| | | bind: { key: "createType", data: [] }, |
| | | }, |
| | | { |
| | | field: "factoryArea", |
| | | title: "ååº", |
| | | type: "string", |
| | | width: 120, |
| | | align: "left" |
| | | }, |
| | | { |
| | | field: "departmentCode", |
| | | title: "ä¿®æ¹æ¶é´", |
| | | type: "string", |
| | | width: 120, |
| | | align: "left", |
| | | hidden:true |
| | | }, |
| | | { |
| | | field: "departmentName", |
| | | title: "é¨é¨åç§°", |
| | | type: "string", |
| | | width: 160, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "creater", |
| | | title: "å建人", |
| | | type: "string", |
| | | width: 90, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "createDate", |
| | | title: "å建æ¶é´", |
| | | type: "datetime", |
| | | width: 160, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "modifier", |
| | | title: "ä¿®æ¹äºº", |
| | | type: "string", |
| | | width: 100, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "modifyDate", |
| | | title: "ä¿®æ¹æ¶é´", |
| | | type: "datetime", |
| | | width: 160, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "remark", |
| | | title: "夿³¨", |
| | | type: "string", |
| | | width: 100, |
| | | align: "left", |
| | | }, |
| | | ]); |
| | | const detail = ref({ |
| | | cnName: "è°æ¨æç»å", |
| | | table: "OnboundOrderDetail", |
| | | columns: [ |
| | | { |
| | | field: "id", |
| | | title: "Id", |
| | | type: "int", |
| | | width: 90, |
| | | hidden: true, |
| | | readonly: true, |
| | | require: true, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "orderId", |
| | | title: "è°æ¨å主é®", |
| | | type: "string", |
| | | width: 90, |
| | | align: "left", |
| | | hidden: true, |
| | | }, |
| | | { |
| | | field: "materielCode", |
| | | title: "ç©æç¼å·", |
| | | type: "string", |
| | | width: 150, |
| | | align: "left", |
| | | edit: { type: "string" }, |
| | | required: true, |
| | | }, |
| | | { |
| | | field: "materielName", |
| | | title: "ç©æåç§°", |
| | | type: "string", |
| | | width: 150, |
| | | align: "left", |
| | | edit: { type: "string" }, |
| | | }, |
| | | { |
| | | field: "batchNo", |
| | | title: "æ¹æ¬¡å·", |
| | | type: "decimal", |
| | | width: 90, |
| | | align: "left", |
| | | edit: { type: "string" }, |
| | | required: true, |
| | | }, |
| | | { |
| | | field: "supplyCode", |
| | | title: "ä¾åºåç¼å·", |
| | | type: "string", |
| | | width: 90, |
| | | align: "left", |
| | | edit: { type: "string" }, |
| | | required: true, |
| | | }, |
| | | { |
| | | field: "orderQuantity", |
| | | title: "åæ®æ°é", |
| | | type: "string", |
| | | width: 90, |
| | | align: "left", |
| | | edit: { type: "number" }, |
| | | required: true, |
| | | }, |
| | | { |
| | | field: "rowNo", |
| | | title: "è¡å·", |
| | | type: "string", |
| | | width: 90, |
| | | align: "left", |
| | | edit: { type: "number" }, |
| | | required: true, |
| | | }, |
| | | { |
| | | field: "lockQuantity", |
| | | title: "é宿°é", |
| | | type: "int", |
| | | width: 120, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "overOutQuantity", |
| | | title: "å·²åºæ°é", |
| | | type: "string", |
| | | width: 200, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "orderDetailStatus", |
| | | title: "订åæç»ç¶æ", |
| | | type: "string", |
| | | width: 180, |
| | | align: "left", |
| | | bind: { key: "orderDetailStatusEnum", data: [] }, |
| | | }, |
| | | { |
| | | field: "creater", |
| | | title: "å建人", |
| | | type: "string", |
| | | width: 90, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "createDate", |
| | | title: "å建æ¶é´", |
| | | type: "datetime", |
| | | width: 160, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "modifier", |
| | | title: "ä¿®æ¹äºº", |
| | | type: "string", |
| | | width: 100, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "modifyDate", |
| | | title: "ä¿®æ¹æ¶é´", |
| | | type: "datetime", |
| | | width: 160, |
| | | align: "left", |
| | | }, |
| | | { |
| | | field: "remark", |
| | | title: "夿³¨", |
| | | type: "string", |
| | | width: 100, |
| | | align: "left", |
| | | }, |
| | | ], |
| | | sortName: "id", |
| | | key: "id", |
| | | }); |
| | | // è°æ¨å¼¹çªç¸å
³ |
| | | const outboundVisible = ref(false); |
| | | const selectedOutboundDocument = ref({}); // åå¨éä¸çè°æ¨åæ°æ® |
| | | |
| | | // æå¼è°æ¨å¼¹çªï¼ä»æ©å±é
ç½®çæé®äºä»¶è§¦åï¼ |
| | | const handleOpenOutboundDialog = (docData) => { |
| | | selectedOutboundDocument.value = docData; // ä¿åéä¸çåæ®æ°æ® |
| | | outboundVisible.value = true; // æ¾ç¤ºå¼¹çª |
| | | }; |
| | | |
| | | // è°æ¨æååçåè° |
| | | const handleOutboundSuccess = (docNo) => { |
| | | ElMessage.success(`åæ® ${docNo} è°æ¨æå`); |
| | | gridRef.value?.refresh(); // å·æ°è¡¨æ ¼æ°æ® |
| | | }; |
| | | |
| | | // åå§åæ©å±é
ç½®ï¼ä¸ºè°æ¨æé®æ·»å äºä»¶è§¦åé»è¾ |
| | | const initExtension = () => { |
| | | // æ¾å°"è°æ¨"æé®å¹¶ç»å®æå¼å¼¹çªçé»è¾ |
| | | const outboundBtn = extend.buttons.view.find(btn => btn.name === 'åºåº'); |
| | | if (outboundBtn) { |
| | | const originalOnClick = outboundBtn.onClick; |
| | | outboundBtn.onClick = function() { |
| | | // å
æ§è¡åææ ¡éªé»è¾ |
| | | const selectedRows = this.$refs.table.getSelected(); |
| | | if (selectedRows.length === 1) { |
| | | // æ ¡éªéè¿åï¼è§¦å主ç»ä»¶çåºåºå¼¹çªäºä»¶ |
| | | this.$emit('openOutboundDialog', selectedRows[0]); |
| | | } else { |
| | | // åæé»è¾å·²å¤çæç¤ºï¼æ ééå¤ |
| | | originalOnClick.call(this); |
| | | } |
| | | }; |
| | | } |
| | | }; |
| | | return { |
| | | table, |
| | | extend, |
| | | editFormFields, |
| | | editFormOptions, |
| | | searchFormFields, |
| | | searchFormOptions, |
| | | columns, |
| | | detail, |
| | | // åºåºç¸å
³ |
| | | outboundVisible, |
| | | selectedOutboundDocument, |
| | | handleOpenOutboundDialog, |
| | | handleOutboundSuccess |
| | | }; |
| | | }, |
| | | }); |
| | | </script> |
| | | |
| | |
| | | using System.Threading.Tasks; |
| | | using WIDESEA_Core; |
| | | using WIDESEA_Core.BaseRepository; |
| | | using WIDESEA_DTO.Allocate; |
| | | using WIDESEA_DTO.Basic; |
| | | using WIDESEA_DTO.Inbound; |
| | | using WIDESEA_DTO.Outbound; |
| | |
| | | _inboundOrderRepository = inboundOrderRepository; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å
¥åºåé¦ |
| | | /// </summary> |
| | | /// <param name="model"></param> |
| | | /// <returns></returns> |
| | | /// <exception cref="HttpRequestException"></exception> |
| | | public async Task<ResponseModel> FeedbackInbound(FeedbackInboundRequestModel model) |
| | | { |
| | | string json =JsonConvert.SerializeObject(model, new JsonSerializerSettings |
| | |
| | | |
| | | return JsonConvert.DeserializeObject<ResponseModel>(body); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// åºåºåé¦ |
| | | /// </summary> |
| | | /// <param name="model"></param> |
| | | /// <returns></returns> |
| | | /// <exception cref="HttpRequestException"></exception> |
| | | public async Task<ResponseModel> FeedbackOutbound(FeedbackOutboundRequestModel model) |
| | | { |
| | | string json = JsonConvert.SerializeObject(model, new JsonSerializerSettings |
| | |
| | | throw new HttpRequestException(body); |
| | | } |
| | | |
| | | |
| | | return JsonConvert.DeserializeObject<ResponseModel>(body); |
| | | } |
| | | |
| | | public async Task<ResponseModel> FeedbackAllocate(AllocateDto model) |
| | | { |
| | | string json = JsonConvert.SerializeObject(model, new JsonSerializerSettings |
| | | { |
| | | ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() |
| | | }); |
| | | var content = new StringContent(json, Encoding.UTF8, "application/json"); |
| | | var _client = _httpClientFactory.CreateClient("MESUrl"); |
| | | _client.DefaultRequestHeaders.Clear(); |
| | | _client.DefaultRequestHeaders.Add("Accept", "application/json"); |
| | | _logger.LogInformation("InvokeMESService FeedbackAllocate : " + json); |
| | | var response = await _client.PostAsync("AldAllocationOperation/AllocationOperation", content); |
| | | string body = await response.Content.ReadAsStringAsync(); |
| | | _logger.LogInformation("InvokeMESService FeedbackAllocate body: " + body); |
| | | if (!response.IsSuccessStatusCode) |
| | | { |
| | | |
| | | throw new HttpRequestException(body); |
| | | } |
| | | |
| | | return JsonConvert.DeserializeObject<ResponseModel>(body); |
| | | } |
| | |
| | | |
| | | var content = new StringContent(json, Encoding.UTF8, "application/json"); |
| | | |
| | | _logger.LogInformation("InvokeMESService FeedbackInbound : " + json); |
| | | _logger.LogInformation("InvokeMESService NewMaterielToMes : " + json); |
| | | |
| | | using var response = await client.PostAsync("AldBarcodeInformation/BarcodeInformation", content); |
| | | var responseText = await response.Content.ReadAsStringAsync(); |
| | | _logger.LogInformation("InvokeMESService NewMaterielToMes body: " + responseText); |
| | | if (!response.IsSuccessStatusCode) |
| | | { |
| | | throw new HttpRequestException(responseText); |
| | |
| | | |
| | | List<string> lockLocationCodes = locationCaches.Select(x => x.LocationCode).ToList(); |
| | | |
| | | Dictionary<string, OrderByType> orderBy = new Dictionary<string, OrderByType>() |
| | | Dictionary<string, SqlSugar.OrderByType> orderBy = new Dictionary<string, OrderByType>() |
| | | { |
| | | { nameof(Dt_LocationInfo.RoadwayNo),OrderByType.Asc }, |
| | | { nameof(Dt_LocationInfo.Layer),OrderByType.Asc }, |
| | |
| | | if (first != null) |
| | | { |
| | | locationCaches.Add(new LocationCache { LocationCode = first?.LocationCode, DateTime = DateTime.Now }); |
| | | } |
| | | Db.Updateable<Dt_LocationInfo>().SetColumns(x => new Dt_LocationInfo |
| | | { |
| | | LocationStatus = (int)LocationStatusEnum.InStockLock, |
| | | }).Where(x => x.Id == first.Id).ExecuteCommand(); |
| | | } |
| | | |
| | | return first; |
| | | } |
| | |
| | | }; |
| | | |
| | | var first = BaseDal.QueryFirst(x => x.LocationStatus == LocationStatusEnum.Free.ObjToInt() && x.EnableStatus != EnableStatusEnum.Disable.ObjToInt() && !lockLocationCodes.Contains(x.LocationCode), orderBy);//æ¥è¯¢ç©ºè´§ä½ä¿¡æ¯å¹¶æé¤5åéå
åé
çè´§ä½,æ ¹æ®å±ãåãæ·±åº¦ãè¡æåº |
| | | |
| | | locationCaches.Add(new LocationCache { LocationCode = first.LocationCode, DateTime = DateTime.Now }); |
| | | if (first != null) |
| | | { |
| | | locationCaches.Add(new LocationCache { LocationCode = first.LocationCode, DateTime = DateTime.Now }); |
| | | } |
| | | |
| | | return first; |
| | | } |
| | |
| | | using Newtonsoft.Json; |
| | | using Dm.filter; |
| | | using Microsoft.Extensions.Logging; |
| | | using Newtonsoft.Json; |
| | | using Newtonsoft.Json.Serialization; |
| | | using System; |
| | | using System.Collections.Generic; |
| | |
| | | using WIDESEA_Core.BaseRepository; |
| | | using WIDESEA_Core.BaseServices; |
| | | using WIDESEA_Core.Helper; |
| | | using WIDESEA_DTO.Basic; |
| | | using WIDESEA_DTO.Outbound; |
| | | using WIDESEA_IBasicService; |
| | | using WIDESEA_Model.Models; |
| | |
| | | internal class MaterielToMesService : ServiceBase<Dt_MaterielToMes, IRepository<Dt_MaterielToMes>>, IMaterielToMesService |
| | | { |
| | | private readonly IInvokeMESService _invokeMESService; |
| | | |
| | | public MaterielToMesService(IRepository<Dt_MaterielToMes> BaseDal, IInvokeMESService invokeMESService) : base(BaseDal) |
| | | private readonly ILogger<MaterielToMesService> _logger; |
| | | public MaterielToMesService(IRepository<Dt_MaterielToMes> BaseDal, IInvokeMESService invokeMESService, ILogger<MaterielToMesService> logger) : base(BaseDal) |
| | | { |
| | | _invokeMESService = invokeMESService; |
| | | _logger = logger; |
| | | } |
| | | // å建ä¸ä¸ªä½¿ç¨å°é©¼å³°å½åæ³çåºåå设置 |
| | | JsonSerializerSettings settings = new JsonSerializerSettings |
| | |
| | | }; |
| | | public IRepository<Dt_MaterielToMes> Repository => BaseDal; |
| | | |
| | | public override WebResponseContent AddData(Dt_MaterielToMes saveModel) |
| | | public async Task<WebResponseContent> AddMaterielToMes(Dt_MaterielToMes saveModel,int operationtype) |
| | | { |
| | | |
| | | WebResponseContent content = base.AddData(saveModel); |
| | | if (content.Status) |
| | | try |
| | | { |
| | | |
| | | base.AddData(saveModel); |
| | | |
| | | string request = JsonConvert.SerializeObject(saveModel, settings); |
| | | |
| | | MaterielToMesDTO dto = new MaterielToMesDTO |
| | | { |
| | | batchNo = saveModel.BatchNo, |
| | | factoryArea = saveModel.factoryArea, |
| | | materialCode = saveModel.MaterielCode, |
| | | newmaterialCode = saveModel.NewMaterialBarCode, |
| | | oldmaterialCode = saveModel.OldMaterialBarCode, |
| | | operationType = 1, |
| | | qty = saveModel.Qty, |
| | | supplyCode = saveModel.supplyCode, |
| | | unit = saveModel.Unit, |
| | | warehouseCode = saveModel.warehouseCode, |
| | | reqCode = Guid.NewGuid().ToString(), |
| | | reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") |
| | | }; |
| | | |
| | | var result = await _invokeMESService.NewMaterielToMes(dto); |
| | | |
| | | if (result != null && result.code == 200) |
| | | { |
| | | await Db.Updateable<Dt_MaterielToMes>() |
| | | .SetColumns(it => it.ReturnToMESStatus ==1) |
| | | .Where(it => it.Id == saveModel.Id) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | |
| | | return WebResponseContent.Instance.OK(); |
| | | } |
| | | else |
| | | catch (Exception ex) |
| | | { |
| | | return content; |
| | | _logger.LogError("MaterielToMesService add Dt_MaterielToMes: " + ex.Message); |
| | | return WebResponseContent.Instance.Error(ex.Message); |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | } |
| | |
| | | å·²æå
= 1, |
| | | å·²æ¤é = 2, |
| | | å·²æ£é = 3, |
| | | å·²ååº = 4 |
| | | å·²ååº = 4, |
| | | } |
| | | public enum OutLockStockStatusEnum |
| | | { |
| | |
| | | |
| | | [Description("å
¥åºç¡®è®¤")] |
| | | å
¥åºç¡®è®¤ = 3, |
| | | |
| | | |
| | | [Description("å
¥åºå®æ")] |
| | | å
¥åºå®æ = 6, |
| | | |
| | |
| | | /// è¯·æ±æ¶é´ |
| | | /// </summary> |
| | | [JsonProperty("reqTime")] |
| | | public DateTime ReqTime { get; set; } |
| | | public string ReqTime { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 订åç¼å· |
| | |
| | | [JsonProperty("business_type")] |
| | | public string BusinessType { get; set; } |
| | | |
| | | public string fromWarehouse { get; set; } |
| | | |
| | | public string toWarehouse { get; set; } |
| | | |
| | | /// <summary> |
| | | /// æ¯å¦åæ¹ |
| | | /// </summary> |
| | |
| | | [JsonProperty("factoryArea")] |
| | | public string FactoryArea { get; set; } |
| | | |
| | | [JsonProperty("operator")] |
| | | public string Operator { get; set; } |
| | | |
| | | /// <summary> |
| | | /// æä½ç±»å |
| | | /// </summary> |
| | |
| | | public class SummaryPickingDto |
| | | { |
| | | |
| | | public string PalletCode { get; set; } |
| | | public string PalletCode { get; set; } |
| | | public string MaterielCode { get; set; } |
| | | public int UnpickedCount { get; set; } |
| | | public decimal UnpickedQuantity { get; set; } |
| | |
| | | public string OrderNo { get; set; } = string.Empty; // åºåºåå· |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | public class PickingConfirmReq |
| | | { |
| | |
| | | public string MaterielBarcode { get; set; } = string.Empty; // ç©ææ¡ç |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | public class SplitPackageReq |
| | | { |
| | |
| | | public decimal SplitQty { get; set; } // æ°æ¡ç åé
æ°é |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | public class StockReturnReq |
| | | { |
| | |
| | | public string TaskNum { get; set; } = string.Empty; // ä»»å¡å·ï¼å¯éï¼ |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | public class OutStockLockDetailReq |
| | | { |
| | | public long OutStockLockId { get; set; } // åºåºè¯¦æ
ID |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | public class MaterielBarcodeValidateResp |
| | | { |
| | |
| | | public decimal PackageQty { get; set; } // æ´å
æ°éï¼åé
æ°éï¼ |
| | | public string Message { get; set; } = string.Empty; |
| | | } |
| | | |
| | | |
| | | |
| | | public class OutStockLockDetailResp |
| | | { |
| | |
| | | public decimal AssignQuantity { get; set; } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | public class OutStockLockListResp |
| | | { |
| | |
| | | public bool IsSplitted { get; set; } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | public class PickedRecordListResp |
| | | { |
| | |
| | | // æå
ç»æç±» |
| | | public class SplitResult |
| | | { |
| | | public string OriginalBarcode { get; set; } |
| | | public string NewBarcode { get; set; } |
| | | public decimal SplitQuantity { get; set; } |
| | | public decimal RemainQuantity { get; set; } |
| | | public string materialCode { get; set; } |
| | | public string supplierCode { get; set; } |
| | | |
| | | public string quantityTotal { get; set; } |
| | | |
| | | public string batchNumber { get; set; } |
| | | |
| | | public string batch { get; set; } |
| | | public string factory { get; set; } |
| | | |
| | | public string date { get; set; } |
| | | |
| | | // public string OriginalBarcode { get; set; } |
| | | // public string NewBarcode { get; set; } |
| | | //public decimal SplitQuantity { get; set; } |
| | | //public decimal RemainQuantity { get; set; } |
| | | } |
| | | } |
| | |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using WIDESEA_Core; |
| | | using WIDESEA_DTO.Allocate; |
| | | using WIDESEA_DTO.Basic; |
| | | using WIDESEA_DTO.Inbound; |
| | | using WIDESEA_DTO.Outbound; |
| | |
| | | |
| | | Task<ResponseModel> FeedbackOutbound(FeedbackOutboundRequestModel model); |
| | | |
| | | Task<ResponseModel> FeedbackAllocate(AllocateDto model); |
| | | Task<string> GetToken(String username, string password); |
| | | |
| | | Task<ResponseModel> NewMaterielToMes(MaterielToMesDTO model); |
| | |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using WIDESEA_Core; |
| | | using WIDESEA_Core.BaseRepository; |
| | | using WIDESEA_Core.BaseServices; |
| | | using WIDESEA_Model.Models; |
| | |
| | | public interface IMaterielToMesService : IService<Dt_MaterielToMes> |
| | | { |
| | | IRepository<Dt_MaterielToMes> Repository { get; } |
| | | |
| | | Task<WebResponseContent> AddMaterielToMes(Dt_MaterielToMes saveModel, int operationtype); |
| | | } |
| | | } |
| | |
| | | |
| | | Task<LockInfoDetailDto> GetLockInfoDetail(int lockInfoId); |
| | | Dt_OutStockLockInfo GetOutStockLockInfo(Dt_OutboundOrder outboundOrder,Dt_OutboundOrderDetail outboundOrderDetail,Dt_StockInfo outStock, decimal assignQuantity, string barcode = null); |
| | | |
| | | List<Dt_OutStockLockInfo> GetOutStockLockInfos(Dt_OutboundOrder outboundOrder, Dt_OutboundOrderDetail outboundOrderDetail, List<Dt_StockInfo> outStocks, int? taskNum = null); |
| | | Task<List<Dt_OutStockLockInfo>> GetPalletLockInfos(string palletCode); |
| | | Task<WebResponseContent> UpdateLockInfoBarcode(int lockInfoId, string newBarcode); |
| | | } |
| | |
| | | public (List<Dt_StockInfo>, List<Dt_OutboundOrderDetail>, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>) AssignStockOutbound(List<Dt_OutboundOrderDetail> outboundOrderDetails); |
| | | |
| | | WebResponseContent LockOutboundStockDataUpdate(List<Dt_StockInfo> stockInfos, List<Dt_OutboundOrderDetail> outboundOrderDetails, List<Dt_OutStockLockInfo> outStockLockInfos, List<Dt_LocationInfo> locationInfos, LocationStatusEnum locationStatus = LocationStatusEnum.Lock, List<Dt_Task>? tasks = null); |
| | | |
| | | (List<Dt_StockInfo>, Dt_OutboundOrderDetail, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>) AssignStockOutbound(Dt_OutboundOrderDetail outboundOrderDetail, List<StockSelectViewDTO> stockSelectViews); |
| | | //List<Dt_OutboundOrderDetail> GetOutboundStockDataById(int id); |
| | | |
| | | } |
| | |
| | | { |
| | | IRepository<Dt_PickingRecord> Repository { get; } |
| | | |
| | | Task<WebResponseContent> CancelPicking(string orderNo, string palletCode, string barcode); |
| | | Task<bool> CheckPalletNeedReturn(string orderNo, string palletCode); |
| | | Task<WebResponseContent> ConfirmPicking(string orderNo, string palletCode, string barcode); |
| | | Task<WebResponseContent> DirectOutbound(DirectOutboundRequest request); |
| | | Task<List<OutStockLockListResp>> GetOutStockLockListAsync(string orderNo); |
| | | Task<WebResponseContent> GetPalletOutboundStatus(string palletCode); |
| | | Task<List<Dt_OutStockLockInfo>> GetPickedList(string orderNo, string palletCode); |
| | | Task<List<Dt_PickingRecord>> GetPickingHistory(int orderId); |
| | | Task<object> GetPickingSummary(ConfirmPickingDto dto); |
| | | |
| | | Task<List<Dt_OutStockLockInfo>> GetUnpickedList(string orderNo, string palletCode); |
| | | |
| | | Task<List<Dt_OutStockLockInfo>> GetPickedList(string orderNo, string palletCode); |
| | | |
| | | Task<WebResponseContent> CancelPicking(string orderNo, string palletCode, string barcode); |
| | | Task<WebResponseContent> ConfirmPicking(string orderNo, string palletCode, string barcode); |
| | | Task<WebResponseContent> ReturnRemaining(string orderNo, string palletCode, string reason); |
| | | Task<WebResponseContent> ValidateBarcode(string barcode); |
| | | } |
| | | } |
| | |
| | | { |
| | | IRepository<Dt_StockInfo> Repository { get; } |
| | | Dt_StockInfo? GetStockByPalletCode(string palletCode); |
| | | |
| | | List<Dt_StockInfo> GetStockInfosByPalletCodes(List<string> palletCodes); |
| | | List<Dt_StockInfo> GetStockInfos(string materielCode, string lotNo, string supplyCode, List<string> locationCodes); |
| | | |
| | | List<Dt_StockInfo> GetUseableStocks(string materielCode, string batchNo,string supplyCode); |
| | |
| | | Task<WebResponseContent> TaskCompleted(string taskNum); |
| | | |
| | | Task<WebResponseContent> GenerateOutboundTasksAsync(int[] keys, string outStation); |
| | | |
| | | |
| | | WebResponseContent GenerateOutboundTask(int orderDetailId, List<StockSelectViewDTO> stockSelectViews); |
| | | |
| | | |
| | | } |
| | | } |
| | |
| | | private readonly IRepository<Dt_StockInfoDetail> _stockDetailRepository; |
| | | private readonly IRepository<Dt_InboundOrder> _inboundOrderRepository; |
| | | private readonly IRepository<Dt_WarehouseArea> _warehouseAreaRepository; |
| | | private readonly IRepository<Dt_LocationType> _locationTypeRepository; |
| | | private readonly IRepository<Dt_StockInfo> _stockRepository; |
| | | public IRepository<Dt_InboundOrder> Repository => BaseDal; |
| | | |
| | | public InboundOrderService(IRepository<Dt_InboundOrder> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IRepository<Dt_Task> taskRepository, IStockService stockService, IInboundOrderDetailService inboundOrderDetailService, IMaterialUnitService materialUnitService, IRepository<Dt_StockInfoDetail> stockDetailRepository, IRepository<Dt_InboundOrder> inboundOrderRepository, IRepository<Dt_WarehouseArea> warehouseAreaRepository,IRepository<Dt_StockInfo> stockRepository) : base(BaseDal) |
| | | public InboundOrderService(IRepository<Dt_InboundOrder> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IRepository<Dt_Task> taskRepository, IStockService stockService, IInboundOrderDetailService inboundOrderDetailService, IMaterialUnitService materialUnitService, IRepository<Dt_StockInfoDetail> stockDetailRepository, IRepository<Dt_InboundOrder> inboundOrderRepository, IRepository<Dt_WarehouseArea> warehouseAreaRepository, IRepository<Dt_StockInfo> stockRepository, IRepository<Dt_LocationType> locationTypeRepository) : base(BaseDal) |
| | | { |
| | | _mapper = mapper; |
| | | _unitOfWorkManage = unitOfWorkManage; |
| | |
| | | _inboundOrderRepository = inboundOrderRepository; |
| | | _warehouseAreaRepository = warehouseAreaRepository; |
| | | _stockRepository = stockRepository; |
| | | _locationTypeRepository = locationTypeRepository; |
| | | } |
| | | |
| | | public async Task<WebResponseContent> ReceiveInboundOrder(List<Dt_InboundOrder> models, int operateType) |
| | |
| | | (bool, string, object?) result2 = ModelValidate.ValidateModelData(materielGroupDTO); |
| | | if (!result2.Item1) return content = WebResponseContent.Instance.Error(result2.Item2); |
| | | |
| | | bool code = _warehouseAreaRepository.Db.Queryable<Dt_WarehouseArea>().Where(x => x.Id == materielGroupDTO.WarehouseCode).Any(); |
| | | bool code = _locationTypeRepository.Db.Queryable<Dt_LocationType>().Where(x => x.LocationType == materielGroupDTO.WarehouseCode).Any(); |
| | | if (!code) |
| | | { |
| | | return content = WebResponseContent.Instance.Error($"ä»åºä¸æ²¡æè¯¥{materielGroupDTO.WarehouseCode}ç¼å·ã"); |
| | | return content = WebResponseContent.Instance.Error($"åºå䏿²¡æè¯¥{materielGroupDTO.WarehouseCode}ç¼å·ã"); |
| | | } |
| | | |
| | | if(_stockRepository.QueryFirst(x=>x.PalletCode == materielGroupDTO.PalletCode)!=null){ |
| | |
| | | { |
| | | return WebResponseContent.Instance.Error("æçå·ä¸è½ä¸ºç©º"); |
| | | } |
| | | var stock= _stockRepository.Db.Queryable<Dt_StockInfo>().Includes(o=>o.Details).First(x => x.PalletCode == palletCode && x.StockStatus==3); |
| | | var stock= _stockRepository.Db.Queryable<Dt_StockInfo>().Includes(o=>o.Details).First(x => x.PalletCode == palletCode ); |
| | | if (stock == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"æªæ¾å°æçå·{palletCode}对åºçåºåè®°å½"); |
| | |
| | | |
| | | var barcodes = stock.Details.Select(d => d.Barcode).ToList(); |
| | | |
| | | |
| | | // å¹é
åºåæ¡ç 对åºçå
¥åºåæç» |
| | | var matchedInboundDetails = inboundOrders.Details |
| | | ?.Where(d => barcodes.Contains(d.Barcode)) |
| | |
| | | public string MaterielCode { get; set; } = null!; |
| | | |
| | | |
| | | |
| | | public int ReturnToMESStatus { get; set; } |
| | | |
| | | } |
| | | } |
| | |
| | | |
| | | public int? ParentLockId { get; set; } |
| | | |
| | | [SugarColumn(IsNullable = false, Length = 50, ColumnDescription = "æä½è
")] |
| | | public string Operator { get; set; } |
| | | |
| | | [Navigate(NavigateType.OneToOne, nameof(StockInfo))]//ä¸å¯¹ä¸ SchoolIdæ¯StudentAç±»éé¢ç |
| | | public Dt_StockInfo StockInfo { get; set; } //ä¸è½èµå¼åªè½æ¯null |
| | | |
| | |
| | | |
| | | // ç¡®å®æ¡ç |
| | | string targetBarcode; |
| | | var firstAvailableDetail=new Dt_StockInfoDetail(); |
| | | if (!string.IsNullOrEmpty(barcode)) |
| | | { |
| | | // éªè¯æå®çæ¡ç æ¯å¦åå¨ |
| | | var specifiedBarcodeDetail = stockDetails.FirstOrDefault(x => x.Barcode == barcode); |
| | | if (specifiedBarcodeDetail == null) |
| | | firstAvailableDetail = stockDetails.FirstOrDefault(x => x.Barcode == barcode); |
| | | if (firstAvailableDetail == null) |
| | | { |
| | | throw new Exception($"æå®çæ¡ç [{barcode}]å¨åºåä¸ä¸åå¨"); |
| | | } |
| | | |
| | | targetBarcode = barcode; |
| | | } |
| | | else |
| | | { |
| | | // 使ç¨ç¬¬ä¸ä¸ªå¯ç¨æ¡ç |
| | | var firstAvailableDetail = stockDetails |
| | | firstAvailableDetail = stockDetails |
| | | .Where(x => x.StockQuantity > x.OutboundQuantity) |
| | | .OrderBy(x => x.CreateDate) |
| | | .FirstOrDefault(); |
| | |
| | | } |
| | | |
| | | return new Dt_OutStockLockInfo() |
| | | { |
| | | lineNo= outboundOrderDetail.lineNo, |
| | | |
| | | { |
| | | PalletCode = outStock.PalletCode, |
| | | AssignQuantity = assignQuantity, |
| | | MaterielCode = outboundOrderDetail.MaterielCode, |
| | | BatchNo = outboundOrderDetail.BatchNo ?? outStock.Details.FirstOrDefault()?.BatchNo, |
| | | AssignQuantity = assignQuantity, |
| | | LocationCode = outStock.LocationCode, |
| | | MaterielName = outboundOrderDetail.MaterielName, |
| | | OrderDetailId = outboundOrderDetail.Id, |
| | |
| | | .Where(x => x.MaterielCode == outboundOrderDetail.MaterielCode) |
| | | .Sum(x => x.StockQuantity), |
| | | Status = (int)OutLockStockStatusEnum.å·²åé
, |
| | | StockId = outStock.Id, |
| | | Unit = outboundOrderDetail.Unit, |
| | | FactoryArea = outboundOrder.FactoryArea, |
| | | StockId = outStock.Id, |
| | | OrderType=outboundOrder.OrderType, |
| | | SupplyCode = outboundOrderDetail.SupplyCode, |
| | | WarehouseCode = outboundOrderDetail.WarehouseCode, |
| | | SupplyCode = firstAvailableDetail.SupplyCode, |
| | | WarehouseCode = firstAvailableDetail.WarehouseCode, |
| | | // æ°å¢å段 |
| | | CurrentBarcode = targetBarcode, |
| | | OriginalLockQuantity = assignQuantity, |
| | | IsSplitted = 0 |
| | | IsSplitted = 0, |
| | | MaterielCode = outboundOrderDetail.MaterielCode, |
| | | BatchNo = firstAvailableDetail.BatchNo, |
| | | Unit = firstAvailableDetail.Unit, |
| | | FactoryArea = firstAvailableDetail.FactoryArea, |
| | | lineNo = outboundOrderDetail.lineNo, |
| | | }; |
| | | } |
| | | |
| | | |
| | | public List<Dt_OutStockLockInfo> GetOutStockLockInfos(Dt_OutboundOrder outboundOrder, Dt_OutboundOrderDetail outboundOrderDetail, List<Dt_StockInfo> outStocks, int? taskNum = null) |
| | | { |
| | | List<Dt_OutStockLockInfo> outStockLockInfos = new List<Dt_OutStockLockInfo>(); |
| | | |
| | | foreach (var item in outStocks) |
| | | { |
| | | Dt_OutStockLockInfo outStockLockInfo = new Dt_OutStockLockInfo() |
| | | { |
| | | PalletCode = item.PalletCode, |
| | | AssignQuantity = item.Details.Where(x => x.MaterielCode == outboundOrderDetail.MaterielCode).Sum(x => x.OutboundQuantity), |
| | | MaterielCode = outboundOrderDetail.MaterielCode, |
| | | BatchNo = outboundOrderDetail.BatchNo, |
| | | LocationCode = item.LocationCode, |
| | | MaterielName = outboundOrderDetail.MaterielName, |
| | | OrderDetailId = outboundOrderDetail.Id, |
| | | OrderNo = outboundOrder.OrderNo, |
| | | OrderType = outboundOrder.OrderType, |
| | | OriginalQuantity = item.Details.Where(x => x.MaterielCode == outboundOrderDetail.MaterielCode).Sum(x => x.StockQuantity), |
| | | Status = taskNum == null ? OutLockStockStatusEnum.å·²åé
.ObjToInt() : OutLockStockStatusEnum.åºåºä¸.ObjToInt(), |
| | | StockId = item.Id, |
| | | TaskNum = taskNum, |
| | | |
| | | |
| | | }; |
| | | outStockLockInfos.Add(outStockLockInfo); |
| | | } |
| | | |
| | | return outStockLockInfos; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è®¢åæç»IDè·ååºåºéå®ä¿¡æ¯ |
| | | /// </summary> |
| | |
| | | using Microsoft.Extensions.Logging; |
| | | using SqlSugar; |
| | | using WIDESEA_Common.LocationEnum; |
| | | using WIDESEA_Common.OrderEnum; |
| | | using WIDESEA_Common.StockEnum; |
| | | using WIDESEA_Core; |
| | | using WIDESEA_Core.BaseRepository; |
| | |
| | | |
| | | |
| | | private readonly IStockService _stockService; |
| | | |
| | | private readonly IOutStockLockInfoService _outStockLockInfoService; |
| | | private readonly ILocationInfoService _locationInfoService; |
| | | private readonly IBasicService _basicService; |
| | |
| | | _locationStatusChangeRecordService = locationStatusChangeRecordService; |
| | | _outboundOrderService = outboundOrderService; |
| | | _logger = logger; |
| | | |
| | | } |
| | | |
| | | |
| | |
| | | if (remainingAllocate <= 0) break; |
| | | |
| | | // 计ç®è¿ä¸ªæç»è¿éè¦åé
çæ°é |
| | | var detailNeed = detail.OrderQuantity - detail.OverOutQuantity - detail.LockQuantity; |
| | | var detailNeed = detail.OrderQuantity - detail.OverOutQuantity - detail.LockQuantity-detail.MoveQty; |
| | | if (detailNeed <= 0) continue; |
| | | |
| | | // åé
æ°é |
| | |
| | | return new PageGridData<Dt_OutboundOrderDetail> (); |
| | | } |
| | | |
| | | |
| | | public (List<Dt_StockInfo>, Dt_OutboundOrderDetail, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>) AssignStockOutbound(Dt_OutboundOrderDetail outboundOrderDetail, List<StockSelectViewDTO> stockSelectViews) |
| | | { |
| | | (bool, string) checkResult = CheckSelectStockDeital(outboundOrderDetail, stockSelectViews); |
| | | if (!checkResult.Item1) throw new Exception(checkResult.Item2); |
| | | |
| | | Dt_OutboundOrder outboundOrder = _outboundOrderService.Repository.QueryFirst(x => x.Id == outboundOrderDetail.OrderId); |
| | | var originalNeedQuantity = outboundOrderDetail.OrderQuantity - outboundOrderDetail.LockQuantity; |
| | | |
| | | var needQuantity = originalNeedQuantity; |
| | | |
| | | List<Dt_StockInfo> outStocks = _stockService.StockInfoService.GetStockInfosByPalletCodes(stockSelectViews.Select(x => x.PalletCode).ToList()); |
| | | var assignQuantity =0m; |
| | | outStocks.ForEach(x => |
| | | { |
| | | x.Details.ForEach(v => |
| | | { |
| | | assignQuantity += v.StockQuantity - v.OutboundQuantity; |
| | | }); |
| | | }); |
| | | |
| | | outboundOrderDetail.LockQuantity += assignQuantity; |
| | | outStocks.ForEach(x => |
| | | { |
| | | x.Details.ForEach(v => |
| | | { |
| | | v.OutboundQuantity = v.StockQuantity; |
| | | }); |
| | | }); |
| | | needQuantity -= assignQuantity; |
| | | if (outboundOrderDetail.OrderQuantity > outboundOrderDetail.LockQuantity) |
| | | { |
| | | List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks(outboundOrderDetail.MaterielCode, outboundOrderDetail.BatchNo,""); |
| | | stockInfos = stockInfos.Where(x => !stockSelectViews.Select(v => v.PalletCode).Contains(x.PalletCode)).ToList(); |
| | | var (autoAssignStocks, stockAllocations) = _stockService.StockInfoService.GetOutboundStocks(stockInfos, outboundOrderDetail.MaterielCode, needQuantity, out decimal residueQuantity); |
| | | outboundOrderDetail.LockQuantity += needQuantity - residueQuantity; |
| | | outStocks.AddRange(autoAssignStocks); |
| | | outboundOrderDetail.OrderDetailStatus = OrderDetailStatusEnum.AssignOver.ObjToInt(); |
| | | if (residueQuantity > 0) |
| | | { |
| | | outboundOrderDetail.OrderDetailStatus = OrderDetailStatusEnum.AssignOverPartial.ObjToInt(); |
| | | } |
| | | } |
| | | |
| | | List<Dt_OutStockLockInfo> outStockLockInfos = _outStockLockInfoService.GetOutStockLockInfos(outboundOrder, outboundOrderDetail, outStocks); |
| | | |
| | | List<Dt_LocationInfo> locationInfos = _locationInfoService.GetLocationInfos(outStocks.Select(x => x.LocationCode).ToList()); |
| | | |
| | | return (outStocks, outboundOrderDetail, outStockLockInfos, locationInfos); |
| | | } |
| | | private (bool, string) CheckSelectStockDeital(Dt_OutboundOrderDetail outboundOrderDetail, List<StockSelectViewDTO> stockSelectViews) |
| | | { |
| | | if (outboundOrderDetail == null) |
| | | { |
| | | return (false, "æªæ¾å°åºåºåæç»ä¿¡æ¯"); |
| | | } |
| | | if (outboundOrderDetail.OrderDetailStatus != OrderDetailStatusEnum.New.ObjToInt() && outboundOrderDetail.OrderDetailStatus != OrderDetailStatusEnum.AssignOverPartial.ObjToInt()) |
| | | { |
| | | return (false, "该æç»ä¸å¯æä½"); |
| | | } |
| | | if (stockSelectViews.Sum(x => x.UseableQuantity) > outboundOrderDetail.OrderQuantity - outboundOrderDetail.LockQuantity) |
| | | { |
| | | return (false, "éæ©æ°éè¶
åºåæ®æ°é"); |
| | | } |
| | | return (true, "æå"); |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | using Dm.filter; |
| | | using MailKit.Search; |
| | | using Microsoft.AspNetCore.Http; |
| | | using Microsoft.AspNetCore.Mvc; |
| | | using Microsoft.Extensions.Logging; |
| | | using SqlSugar; |
| | | using System; |
| | |
| | | _dailySequenceService = dailySequenceService; |
| | | } |
| | | |
| | | |
| | | #region æ¥è¯¢åºåºè¯¦æ
å表 |
| | | public async Task<List<OutStockLockListResp>> GetOutStockLockListAsync(string orderNo) |
| | | { |
| | | var locks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(t => t.OrderNo == orderNo) |
| | | .ToListAsync(); |
| | | |
| | | return locks.Select(t => new OutStockLockListResp |
| | | { |
| | | Id = t.Id, |
| | | // TaskNum = t.TaskNum, |
| | | PalletCode = t.PalletCode, |
| | | CurrentBarcode = t.CurrentBarcode, |
| | | AssignQuantity = t.AssignQuantity, |
| | | PickedQty = t.PickedQty, |
| | | Status = t.Status, |
| | | // IsSplitted = t.IsSplitted |
| | | }).ToList(); |
| | | } |
| | | #endregion |
| | | public async Task<WebResponseContent> ValidateBarcode(string barcode) |
| | | { |
| | | try |
| | | { |
| | | if (string.IsNullOrEmpty(barcode)) |
| | | { |
| | | return WebResponseContent.Instance.Error("æ¡ç ä¸è½ä¸ºç©º"); |
| | | } |
| | | |
| | | // æ ¹æ®æ¡ç æ¥è¯¢åºåæç» |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Includes(x => x.StockInfo) |
| | | .Where(x => x.Barcode == barcode) |
| | | .FirstAsync(); |
| | | |
| | | if (stockDetail == null) |
| | | { |
| | | return WebResponseContent.Instance.Error("æ¡ç ä¸åå¨"); |
| | | } |
| | | |
| | | |
| | | |
| | | var result = new |
| | | { |
| | | Barcode = barcode, |
| | | MaterielCode = stockDetail.MaterielCode, |
| | | |
| | | BatchNo = stockDetail.BatchNo, |
| | | AvailableQuantity = stockDetail.StockQuantity - stockDetail.OutboundQuantity, |
| | | LocationCode = stockDetail.StockInfo?.LocationCode, |
| | | PalletCode = stockDetail.StockInfo?.PalletCode |
| | | }; |
| | | |
| | | return WebResponseContent.Instance.OK(null, result); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | return WebResponseContent.Instance.Error($"æ¡ç éªè¯å¤±è´¥: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | // æ£æ¥å¹¶æ´æ°è®¢åç¶æ |
| | | private async Task CheckAndUpdateOrderStatus(string orderNo) |
| | | { |
| | | |
| | | var orderDetails = _stockInfoDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id) // å
³èæ¡ä»¶ï¼ç¶è¡¨ Id = å表 OrderId |
| | | .Where((o, item) => item.OrderNo == orderNo) // è¿æ»¤ç¶è¡¨ OrderNo |
| | | .Select((o, item) => o) // åªè¿ååè¡¨æ°æ® |
| | | .ToList(); |
| | | |
| | | //var orderDetails = await _stockInfoDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | // .Where(x => x.OrderId == orderNo.ObjToInt()) |
| | | // .ToListAsync(); |
| | | |
| | | bool allCompleted = true; |
| | | foreach (var detail in orderDetails) |
| | | { |
| | | if (detail.OverOutQuantity < detail.NeedOutQuantity) |
| | | { |
| | | allCompleted = false; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (allCompleted) |
| | | { |
| | | try |
| | | { |
| | | await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>() |
| | | .SetColumns(x => x.OrderStatus == 2) // 已宿 |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | var outboundOrder = _stockInfoService.Db.Queryable<Dt_OutboundOrder>().First(x => x.OrderNo == orderNo); |
| | | |
| | | |
| | | if (outboundOrder != null && outboundOrder.OrderStatus == OutOrderStatusEnum.åºåºå®æ.ObjToInt()) |
| | | { |
| | | |
| | | if (outboundOrder.OrderType == OutOrderTypeEnum.Allocate.ObjToInt().ObjToInt())//è°æ¨åºåº |
| | | { |
| | | |
| | | } |
| | | else if (outboundOrder.OrderType == OutOrderTypeEnum.ReCheck.ObjToInt()) //鿣åºåº |
| | | { |
| | | |
| | | } |
| | | else |
| | | { |
| | | var feedmodel = new FeedbackOutboundRequestModel |
| | | { |
| | | reqCode = Guid.NewGuid().ToString(), |
| | | reqTime = DateTime.Now.ToString(), |
| | | business_type = outboundOrder.BusinessType, |
| | | factoryArea = outboundOrder.FactoryArea, |
| | | operationType = 1, |
| | | Operator = outboundOrder.Operator, |
| | | orderNo = outboundOrder.UpperOrderNo, |
| | | status = outboundOrder.OrderStatus, |
| | | details = new List<FeedbackOutboundDetailsModel>() |
| | | |
| | | }; |
| | | var lists = _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>().Where(x => x.OrderNo == orderNo).ToList(); |
| | | |
| | | var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.lineNo, item.Unit, item.WarehouseCode }) |
| | | .Select(group => new FeedbackOutboundDetailsModel |
| | | { |
| | | materialCode = group.Key.MaterielCode, |
| | | lineNo = group.Key.lineNo, |
| | | warehouseCode = group.Key.WarehouseCode, |
| | | currentDeliveryQty = group.Sum(x => x.OrderQuantity), |
| | | // warehouseCode= "1072", |
| | | unit = group.Key.Unit, |
| | | barcodes = group.Select(row => new WIDESEA_DTO.Outbound.BarcodesModel |
| | | { |
| | | barcode = row.CurrentBarcode, |
| | | supplyCode = row.SupplyCode, |
| | | batchNo = row.BatchNo, |
| | | unit = row.Unit, |
| | | qty = row.AssignQuantity |
| | | }).ToList() |
| | | }).ToList(); |
| | | feedmodel.details = groupedData; |
| | | |
| | | _invokeMESService.FeedbackOutbound(feedmodel); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError(" OutboundPickingService FeedbackOutbound : " + ex.Message); |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | public async Task<WebResponseContent> ConfirmPicking(string orderNo, string palletCode, string barcode) |
| | | { |
| | | try |
| | | { |
| | | _unitOfWorkManage.BeginTran(); |
| | | |
| | | // 1. æ¥æ¾åºåºéå®ä¿¡æ¯ |
| | | var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.OrderNo == orderNo && |
| | | it.Status == (int)OutLockStockStatusEnum.åºåºä¸ && |
| | | it.PalletCode == palletCode && |
| | | it.CurrentBarcode == barcode) |
| | | .FirstAsync(); |
| | | |
| | | if (lockInfo == null) |
| | | { |
| | | lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.CurrentBarcode == barcode && |
| | | it.Status == (int)OutLockStockStatusEnum.åºåºä¸) |
| | | .FirstAsync(); |
| | | |
| | | if (lockInfo == null) |
| | | throw new Exception($"æ¡ç {barcode}ä¸å±äºæç{palletCode}æä¸åå¨å¾
åæ£è®°å½"); |
| | | } |
| | | |
| | | if (lockInfo.PalletCode != palletCode) |
| | | throw new Exception($"æ¡ç {barcode}ä¸å±äºæç{palletCode}"); |
| | | |
| | | var outorderdetail = _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>().First(x => x.Id == lockInfo.OrderDetailId); |
| | | if (outorderdetail != null && lockInfo.AssignQuantity > outorderdetail.OrderQuantity) |
| | | { |
| | | throw new Exception($"æ¡ç {barcode}çåºåºæ°é大äºè®¢åçæ°é"); |
| | | } |
| | | |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(x => x.Barcode == barcode && x.StockId == lockInfo.StockId) |
| | | .FirstAsync(); |
| | | |
| | | if (stockDetail == null) |
| | | return WebResponseContent.Instance.Error("æ æçæ¡ç æç©æç¼ç "); |
| | | |
| | | decimal actualQty = lockInfo.AssignQuantity - lockInfo.PickedQty; |
| | | decimal stockQuantity = stockDetail.StockQuantity; |
| | | |
| | | List<SplitResult> splitResults = new List<SplitResult>(); |
| | | |
| | | if (actualQty < stockQuantity) |
| | | { |
| | | // æ
åµ1: åé
æ°éå°äºåºåæ°éï¼éè¦èªå¨æå
|
| | | // 计ç®å©ä½åºåæ°é |
| | | decimal remainingStockQty = stockQuantity - actualQty; |
| | | |
| | | // æ´æ°åæ¡ç åºå为å©ä½æ°é |
| | | stockDetail.StockQuantity = remainingStockQty; |
| | | stockDetail.OutboundQuantity = remainingStockQty; |
| | | await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync(); |
| | | |
| | | // çææ°æ¡ç ç¨äºè®°å½æ£éæ°éï¼ä½ä¸å建åºåè®°å½ï¼ |
| | | var seq = await _dailySequenceService.GetNextSequenceAsync(); |
| | | string newBarcode = "WSLOT" + DateTime.Now.ToString("yyyyMMdd") + seq.ToString()?.PadLeft(5, '0'); |
| | | |
| | | // ä¸ºæ°æ¡ç å建åºåºéå®ä¿¡æ¯ï¼ç¨äºè®°å½æ£éï¼ |
| | | var newLockInfo = new Dt_OutStockLockInfo |
| | | { |
| | | OrderNo = lockInfo.OrderNo, |
| | | OrderDetailId = lockInfo.OrderDetailId, |
| | | BatchNo = lockInfo.BatchNo, |
| | | MaterielCode = lockInfo.MaterielCode, |
| | | MaterielName = lockInfo.MaterielName, |
| | | StockId = lockInfo.StockId, |
| | | OrderQuantity = actualQty, |
| | | OriginalQuantity = actualQty, |
| | | AssignQuantity = actualQty, |
| | | PickedQty = actualQty, |
| | | LocationCode = lockInfo.LocationCode, |
| | | PalletCode = lockInfo.PalletCode, |
| | | TaskNum = lockInfo.TaskNum, |
| | | Status = (int)OutLockStockStatusEnum.æ£é宿, |
| | | Unit = lockInfo.Unit, |
| | | SupplyCode = lockInfo.SupplyCode, |
| | | OrderType = lockInfo.OrderType, |
| | | CurrentBarcode = newBarcode, |
| | | OriginalLockQuantity = actualQty, |
| | | IsSplitted = 1, |
| | | ParentLockId = lockInfo.Id |
| | | }; |
| | | await _outStockLockInfoService.Db.Insertable(newLockInfo).ExecuteCommandAsync(); |
| | | |
| | | // è®°å½æå
åå²ï¼ç¨äºè¿½è¸ªï¼ |
| | | var splitHistory = new Dt_SplitPackageRecord |
| | | { |
| | | FactoryArea = lockInfo.FactoryArea, |
| | | TaskNum = lockInfo.TaskNum, |
| | | OutStockLockInfoId = lockInfo.Id, |
| | | StockId = stockDetail.StockId, |
| | | Operator = App.User.UserName, |
| | | IsReverted = false, |
| | | OriginalBarcode = barcode, |
| | | NewBarcode = newBarcode, |
| | | SplitQty = actualQty, |
| | | RemainQuantity = remainingStockQty, |
| | | MaterielCode = lockInfo.MaterielCode, |
| | | SplitTime = DateTime.Now, |
| | | OrderNo = lockInfo.OrderNo, |
| | | PalletCode = lockInfo.PalletCode, |
| | | Status = (int)SplitPackageStatusEnum.å·²æ£é |
| | | }; |
| | | await _splitPackageService.Db.Insertable(splitHistory).ExecuteCommandAsync(); |
| | | |
| | | // æ´æ°åéå®ä¿¡æ¯ä¸ºå©ä½åºåæ°é |
| | | lockInfo.AssignQuantity = remainingStockQty; |
| | | lockInfo.PickedQty = 0; |
| | | |
| | | await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync(); |
| | | |
| | | splitResults.Add(new SplitResult |
| | | { |
| | | OriginalBarcode = barcode, |
| | | NewBarcode = newBarcode, |
| | | SplitQuantity = actualQty, |
| | | RemainQuantity = remainingStockQty |
| | | }); |
| | | |
| | | // æ´æ°æ£éè®°å½ä¸çæ¡ç ä¸ºæ°æ¡ç |
| | | barcode = newBarcode; |
| | | lockInfo = newLockInfo; |
| | | } |
| | | else if (actualQty == stockQuantity) |
| | | { |
| | | // æ
åµ2: åé
æ°éçäºåºåæ°éï¼æ´å
åºåº |
| | | stockDetail.StockQuantity = 0; |
| | | stockDetail.OutboundQuantity = 0; |
| | | await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync(); |
| | | |
| | | lockInfo.PickedQty += actualQty; |
| | | lockInfo.Status = (int)OutLockStockStatusEnum.æ£é宿; |
| | | await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync(); |
| | | } |
| | | else |
| | | { |
| | | // æ
åµ3: åé
æ°é大äºåºåæ°éï¼åºåæ´å
åºåº |
| | | // æ´å
åºåºå½ååºå |
| | | decimal stockOutQty = stockQuantity; |
| | | stockDetail.StockQuantity = 0; |
| | | stockDetail.OutboundQuantity = 0; |
| | | await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync(); |
| | | |
| | | // 计ç®å©ä½åé
æ°é |
| | | decimal remainingAssignQty = actualQty - stockQuantity; |
| | | |
| | | // æ´æ°éå®ä¿¡æ¯ï¼åªå®æåºåé¨åï¼ |
| | | lockInfo.PickedQty += stockOutQty; |
| | | lockInfo.AssignQuantity = remainingAssignQty; |
| | | |
| | | await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync(); |
| | | |
| | | var _relatedSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>() |
| | | .Where(it => it.OriginalBarcode == barcode || it.NewBarcode == barcode) |
| | | .Where(it => !it.IsReverted) |
| | | .ToListAsync(); |
| | | |
| | | foreach (var record in _relatedSplitRecords) |
| | | { |
| | | record.Status = (int)SplitPackageStatusEnum.å·²æ£é; |
| | | await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>() |
| | | .SetColumns(it => it.PickedQty == it.PickedQty + actualQty) |
| | | .Where(it => it.Id == lockInfo.OrderDetailId) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | await CheckAndUpdateOrderStatus(orderNo); |
| | | |
| | | // æ¥è¯¢ä»»å¡è¡¨ |
| | | var task = _taskRepository.QueryData(x => x.OrderNo == orderNo && x.PalletCode == palletCode).FirstOrDefault(); |
| | | |
| | | // è®°å½æ£éåå² |
| | | var pickingHistory = new Dt_PickingRecord |
| | | { |
| | | FactoryArea = lockInfo.FactoryArea, |
| | | TaskNo = task?.TaskNum ?? 0, |
| | | LocationCode = task?.SourceAddress ?? "", |
| | | StockId = stockDetail.Id, |
| | | OrderNo = orderNo, |
| | | OrderDetailId = lockInfo.OrderDetailId, |
| | | PalletCode = palletCode, |
| | | Barcode = barcode, |
| | | MaterielCode = lockInfo.MaterielCode, |
| | | PickQuantity = actualQty, |
| | | PickTime = DateTime.Now, |
| | | Operator = App.User.UserName, |
| | | OutStockLockId = lockInfo.Id |
| | | }; |
| | | await Db.Insertable(pickingHistory).ExecuteCommandAsync(); |
| | | |
| | | _unitOfWorkManage.CommitTran(); |
| | | |
| | | // 妿ææå
ç»æï¼è¿åæå
ä¿¡æ¯ |
| | | if (splitResults.Any()) |
| | | { |
| | | return WebResponseContent.Instance.OK("æ£é确认æåï¼å·²èªå¨æå
", new { SplitResults = splitResults }); |
| | | } |
| | | |
| | | return WebResponseContent.Instance.OK("æ£é确认æå"); |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return WebResponseContent.Instance.Error($"æ£é确认失败ï¼{ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// ååºæä½ |
| | | /// </summary> |
| | | |
| | | public async Task<WebResponseContent> ReturnRemaining(string orderNo, string palletCode, string reason) |
| | | { |
| | | try |
| | | { |
| | | _unitOfWorkManage.BeginTran(); |
| | | |
| | | // è·åæææªåæ£çåºåºéå®è®°å½ï¼å
æ¬æå
产ççè®°å½ |
| | | var remainingLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.OrderNo == orderNo && it.Status == (int)OutLockStockStatusEnum.åºåºä¸) |
| | | .ToListAsync(); |
| | | |
| | | var stockinfo = _stockInfoService.Db.Queryable<Dt_StockInfo>().First(x => x.PalletCode == palletCode); |
| | | |
| | | var tasks = new List<Dt_Task>(); |
| | | |
| | | // æ¥è¯¢ä»»å¡è¡¨ |
| | | var task = remainingLocks.Any() |
| | | ? _taskRepository.QueryData(x => x.TaskNum == remainingLocks.First().TaskNum).FirstOrDefault() |
| | | : _taskRepository.QueryData(x => x.PalletCode == palletCode).FirstOrDefault(); |
| | | |
| | | if (task == null) |
| | | { |
| | | return WebResponseContent.Instance.Error("æªæ¾å°å¯¹åºçä»»å¡ä¿¡æ¯"); |
| | | } |
| | | |
| | | // æ£æ¥æç䏿¯å¦æå
¶ä»éåºåºè´§ç©ï¼åºåè´§ç©ï¼ |
| | | var palletStockGoods = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.StockId == stockinfo.Id && |
| | | (it.Status == StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt() || |
| | | it.Status == StockStatusEmun.å
¥åºå®æ.ObjToInt() || |
| | | it.Status == StockStatusEmun.åºåºéå®.ObjToInt())) |
| | | .Where(it => it.OutboundQuantity == 0 || it.OutboundQuantity < it.StockQuantity) // æªå®å
¨åºåºç |
| | | .ToListAsync(); |
| | | |
| | | // æ£æ¥æå
è®°å½ï¼æ¾åºéè¦ååºçæ¡ç |
| | | var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>() |
| | | .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && !it.IsReverted) |
| | | .ToListAsync(); |
| | | |
| | | // 计ç®éè¦ååºçæå
æ¡ç |
| | | var splitBarcodesToReturn = new List<string>(); |
| | | foreach (var splitRecord in splitRecords) |
| | | { |
| | | // æ£æ¥åæ¡ç æ¯å¦è¿æåºåéè¦ååº |
| | | var originalStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.Barcode == splitRecord.OriginalBarcode && it.StockId == stockinfo.Id) |
| | | .FirstAsync(); |
| | | |
| | | if (originalStock != null && originalStock.StockQuantity > 0) |
| | | { |
| | | splitBarcodesToReturn.Add(splitRecord.OriginalBarcode); |
| | | } |
| | | |
| | | // æ£æ¥æ°æ¡ç æ¯å¦è¿æåºåéè¦ååº |
| | | var newStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.Barcode == splitRecord.NewBarcode && it.StockId == stockinfo.Id) |
| | | .FirstAsync(); |
| | | |
| | | if (newStock != null && newStock.StockQuantity > 0) |
| | | { |
| | | splitBarcodesToReturn.Add(splitRecord.NewBarcode); |
| | | } |
| | | } |
| | | |
| | | // å¦ææ²¡æéè¦ååºçè´§ç©ï¼æ¢æ æªåæ£åºåºè´§ç©ï¼ä¹æ å
¶ä»åºåè´§ç©ï¼ä¹æ æå
å©ä½è´§ç©ï¼ |
| | | if (!remainingLocks.Any() && !palletStockGoods.Any() && !splitBarcodesToReturn.Any()) |
| | | { |
| | | // æ£æ¥æ¯å¦ææè´§ç©é½å·²æ£é宿 |
| | | var allPicked = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode) |
| | | .AnyAsync(it => it.Status == (int)OutLockStockStatusEnum.æ£é宿); |
| | | |
| | | if (allPicked) |
| | | { |
| | | return WebResponseContent.Instance.OK("ææè´§ç©å·²æ£éå®æï¼æç为空"); |
| | | } |
| | | else |
| | | { |
| | | return WebResponseContent.Instance.Error("没æéè¦ååºçå©ä½è´§ç©"); |
| | | } |
| | | } |
| | | |
| | | var firstlocation = _locationInfoService.Db.Queryable<Dt_LocationInfo>().First(x => x.LocationCode == task.SourceAddress); |
| | | decimal totalReturnQty = 0; |
| | | |
| | | // æ
åµ1ï¼å¤çæªåæ£çåºåºéå®è®°å½ |
| | | if (remainingLocks.Any(x => x.PalletCode == palletCode)) |
| | | { |
| | | var palletLocks = remainingLocks.Where(x => x.PalletCode == palletCode).ToList(); |
| | | totalReturnQty = palletLocks.Sum(x => x.AssignQuantity - x.PickedQty); |
| | | |
| | | if (totalReturnQty > 0) |
| | | { |
| | | // åé
æ°è´§ä½ |
| | | var newLocation = _locationInfoService.AssignLocation(firstlocation.LocationType); |
| | | |
| | | // æ´æ°åºåºéå®è®°å½ç¶æ |
| | | var lockIds = palletLocks.Select(x => x.Id).ToList(); |
| | | await _outStockLockInfoService.Db.Updateable<Dt_OutStockLockInfo>() |
| | | .SetColumns(it => new Dt_OutStockLockInfo { Status = (int)OutLockStockStatusEnum.ååºä¸ }) |
| | | .Where(it => lockIds.Contains(it.Id)) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | |
| | | |
| | | // å¤çåºåè®°å½ |
| | | foreach (var lockInfo in palletLocks) |
| | | { |
| | | decimal returnQty = lockInfo.AssignQuantity - lockInfo.PickedQty; |
| | | |
| | | // æ£æ¥åºåè®°å½æ¯å¦åå¨ |
| | | var existingStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.Barcode == lockInfo.CurrentBarcode && it.StockId == lockInfo.StockId) |
| | | .FirstAsync(); |
| | | |
| | | if (existingStock != null) |
| | | { |
| | | // åºåè®°å½åå¨ï¼æ¢å¤é宿°é |
| | | existingStock.OutboundQuantity = 0; |
| | | |
| | | await _stockInfoDetailService.Db.Updateable(existingStock).ExecuteCommandAsync(); |
| | | } |
| | | else |
| | | { |
| | | // åºåè®°å½ä¸åå¨ï¼å¯è½æ¯æå
产ççæ°æ¡ç ï¼ï¼å建æ°çåºåè®°å½ |
| | | var newStockDetail = new Dt_StockInfoDetail |
| | | { |
| | | StockId = lockInfo.StockId, |
| | | MaterielCode = lockInfo.MaterielCode, |
| | | MaterielName = lockInfo.MaterielName, |
| | | OrderNo = lockInfo.OrderNo, |
| | | BatchNo = lockInfo.BatchNo, |
| | | StockQuantity = returnQty, |
| | | OutboundQuantity = 0, |
| | | Barcode = lockInfo.CurrentBarcode, |
| | | InboundOrderRowNo = "", |
| | | Status = StockStatusEmun.å
¥åºå®æ.ObjToInt(), |
| | | SupplyCode = lockInfo.SupplyCode, |
| | | WarehouseCode = lockInfo.WarehouseCode, |
| | | Unit = lockInfo.Unit |
| | | }; |
| | | await _stockInfoDetailService.Db.Insertable(newStockDetail).ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | |
| | | // å建ååºä»»å¡ |
| | | CreateReturnTask(tasks, task, palletCode, newLocation); |
| | | } |
| | | } |
| | | |
| | | // æ
åµ2ï¼å¤çæå
å©ä½çåºåè´§ç© |
| | | if (splitBarcodesToReturn.Any()) |
| | | { |
| | | decimal splitReturnQty = 0; |
| | | |
| | | foreach (var barcode in splitBarcodesToReturn) |
| | | { |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.Barcode == barcode && it.StockId == stockinfo.Id) |
| | | .FirstAsync(); |
| | | |
| | | if (stockDetail != null && stockDetail.StockQuantity > 0) |
| | | { |
| | | splitReturnQty += stockDetail.StockQuantity; |
| | | |
| | | // æ¢å¤åºåç¶æä¸ºå
¥åºå®æ |
| | | stockDetail.OutboundQuantity = 0; |
| | | |
| | | await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | |
| | | totalReturnQty += splitReturnQty; |
| | | |
| | | // å¦ææ²¡æå建任å¡ï¼å建ååºä»»å¡ |
| | | if (!tasks.Any()) |
| | | { |
| | | var newLocation = _locationInfoService.AssignLocation(firstlocation.LocationType); |
| | | CreateReturnTask(tasks, task, palletCode, newLocation); |
| | | } |
| | | } |
| | | |
| | | // æ
åµ3ï¼åºåºè´§ç©å·²åæ£å®ï¼ä½æçä¸è¿æå
¶ä»åºåè´§ç©éè¦ååº |
| | | if (palletStockGoods.Any() && !remainingLocks.Any(x => x.PalletCode == palletCode)) |
| | | { |
| | | decimal otherReturnQty = palletStockGoods.Sum(x => x.StockQuantity - x.OutboundQuantity); |
| | | totalReturnQty += otherReturnQty; |
| | | // æ´æ°è¿äºåºåè´§ç©çç¶æ |
| | | foreach (var stockGood in palletStockGoods) |
| | | { |
| | | stockGood.OutboundQuantity = 0; |
| | | |
| | | await _stockInfoDetailService.Db.Updateable(stockGood).ExecuteCommandAsync(); |
| | | } |
| | | // å¦ææ²¡æå建任å¡ï¼å建ååºä»»å¡ |
| | | if (!tasks.Any()) |
| | | { |
| | | var newLocation = _locationInfoService.AssignLocation(firstlocation.LocationType); |
| | | CreateReturnTask(tasks, task, palletCode, newLocation); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | var allSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>() |
| | | .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && !it.IsReverted) |
| | | .ToListAsync(); |
| | | |
| | | foreach (var record in allSplitRecords) |
| | | { |
| | | record.Status = (int)SplitPackageStatusEnum.å·²ååº; |
| | | await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync(); |
| | | } |
| | | // ä¿åä»»å¡ ç»ESSä¸åä»»å¡ |
| | | if (tasks.Any()) |
| | | { |
| | | try |
| | | { |
| | | await _taskRepository.Db.Insertable(tasks).ExecuteCommandAsync(); |
| | | var targetAddress = task.TargetAddress; |
| | | _taskRepository.DeleteData(task); |
| | | |
| | | // ç» ESS æµå¨ä¿¡å·ååå»ºä»»å¡ |
| | | try |
| | | { |
| | | var result = await _eSSApiService.MoveContainerAsync(new WIDESEA_DTO.Basic.MoveContainerRequest |
| | | { |
| | | slotCode = movestations[targetAddress], |
| | | containerCode = palletCode |
| | | }); |
| | | |
| | | if (result) |
| | | { |
| | | TaskModel esstask = new TaskModel() |
| | | { |
| | | taskType = "putaway", |
| | | taskGroupCode = "", |
| | | groupPriority = 0, |
| | | tasks = new List<TasksType> |
| | | { |
| | | new() |
| | | { |
| | | taskCode = tasks.First().TaskNum.ToString(), |
| | | taskPriority = 0, |
| | | taskDescribe = new TaskDescribeType { |
| | | containerCode = palletCode, |
| | | containerType = "CT_KUBOT_STANDARD", |
| | | fromLocationCode = stations.GetValueOrDefault(targetAddress) ?? "", |
| | | toStationCode = "", |
| | | toLocationCode = tasks.First().TargetAddress, |
| | | deadline = 0, storageTag = "" |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | |
| | | var resulttask = await _eSSApiService.CreateTaskAsync(esstask); |
| | | _logger.LogInformation("ReturnRemaining å建任å¡è¿å: " + resulttask); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogInformation("ReturnRemaining å建任å¡è¿å catch err: " + ex.Message); |
| | | } |
| | | |
| | | _unitOfWorkManage.CommitTran(); |
| | | return WebResponseContent.Instance.OK($"ååºæä½æåï¼å
±ååºæ°éï¼{totalReturnQty}"); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return WebResponseContent.Instance.Error($"å建ååºä»»å¡å¤±è´¥: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return WebResponseContent.Instance.Error("æªå建任ä½ååºä»»å¡"); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return WebResponseContent.Instance.Error($"ååºæä½å¤±è´¥: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// å建ååºä»»å¡ |
| | | /// </summary> |
| | | private void CreateReturnTask(List<Dt_Task> tasks, Dt_Task originalTask, string palletCode, Dt_LocationInfo newLocation) |
| | | { |
| | | Dt_Task newTask = new() |
| | | { |
| | | CurrentAddress = stations[originalTask.TargetAddress], |
| | | Grade = 0, |
| | | PalletCode = palletCode, |
| | | NextAddress = "", |
| | | OrderNo = originalTask.OrderNo, |
| | | Roadway = newLocation.RoadwayNo, |
| | | SourceAddress = stations[originalTask.TargetAddress], |
| | | TargetAddress = newLocation.LocationCode, |
| | | TaskStatus = TaskStatusEnum.New.ObjToInt(), |
| | | TaskType = TaskTypeEnum.InPick.ObjToInt(), |
| | | PalletType = originalTask.PalletType, |
| | | WarehouseId = originalTask.WarehouseId, |
| | | |
| | | }; |
| | | tasks.Add(newTask); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ£æ¥æçæ¯å¦éè¦ååºçè¾
婿¹æ³ |
| | | /// </summary> |
| | | public async Task<bool> CheckPalletNeedReturn(string orderNo, string palletCode) |
| | | { |
| | | // 1. æ£æ¥æ¯å¦ææªåæ£çåºåºè®°å½ |
| | | var hasUnpickedLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && it.Status == 1) |
| | | .AnyAsync(); |
| | | |
| | | if (hasUnpickedLocks) |
| | | return true; |
| | | |
| | | // 2. æ£æ¥åºåºæ¯å¦å·²å®æä½æçè¿æåºåè´§ç© |
| | | var outboundFinished = !await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.PalletCode == palletCode && it.Status == 1) |
| | | .AnyAsync(); |
| | | |
| | | var stockinfo = _stockInfoService.Db.Queryable<Dt_StockInfo>().First(x => x.PalletCode == palletCode); |
| | | |
| | | |
| | | var hasRemainingGoods = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.StockId == stockinfo.Id && it.Status == StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt()) |
| | | .Where(it => it.OutboundQuantity == 0 || it.OutboundQuantity < it.StockQuantity) |
| | | .AnyAsync(); |
| | | |
| | | return outboundFinished && hasRemainingGoods; |
| | | } |
| | | |
| | | // åæ¶æ£éåè½ |
| | | public async Task<WebResponseContent> CancelPicking(string orderNo, string palletCode, string barcode) |
| | | { |
| | | try |
| | | { |
| | | _unitOfWorkManage.BeginTran(); |
| | | |
| | | //æ¥æ¾æ£éè®°å½ |
| | | var pickingRecord = await Db.Queryable<Dt_PickingRecord>() |
| | | .Where(it => it.OrderNo == orderNo && |
| | | it.PalletCode == palletCode && |
| | | it.Barcode == barcode) |
| | | .OrderByDescending(it => it.PickTime) |
| | | .FirstAsync(); |
| | | |
| | | if (pickingRecord == null) |
| | | return WebResponseContent.Instance.Error("æªæ¾å°å¯¹åºçæ£éè®°å½"); |
| | | |
| | | // æ¥æ¾åºåºéå®ä¿¡æ¯ |
| | | var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.Id == pickingRecord.OutStockLockId) |
| | | .FirstAsync(); |
| | | |
| | | if (lockInfo == null) |
| | | return WebResponseContent.Instance.Error("æªæ¾å°å¯¹åºçåºåºéå®ä¿¡æ¯"); |
| | | |
| | | //æ£æ¥æ¯å¦å¯ä»¥åæ¶ï¼ç¶æå¿
é¡»æ¯æ£éå®æï¼ |
| | | if (lockInfo.Status != (int)OutLockStockStatusEnum.æ£é宿) |
| | | return WebResponseContent.Instance.Error("å½åç¶æä¸å
è®¸åæ¶åæ£"); |
| | | |
| | | decimal cancelQty = pickingRecord.PickQuantity; |
| | | |
| | | // æ£æ¥æå
é¾å
³ç³» |
| | | var splitChain = await GetSplitChain(barcode); |
| | | |
| | | if (splitChain.Any()) |
| | | { |
| | | // æ
åµAï¼å¤çæå
é¾çåæ¶ï¼å¤æ¬¡æå¨æå
ï¼ |
| | | await HandleSplitChainCancel(orderNo, palletCode, barcode, cancelQty, lockInfo, pickingRecord, splitChain); |
| | | } |
| | | else |
| | | { |
| | | // æ
åµBï¼å¤çæ®éæ¡ç çåæ¶ |
| | | await HandleNormalBarcodeCancel(orderNo, palletCode, barcode, cancelQty, lockInfo, pickingRecord); |
| | | } |
| | | |
| | | _unitOfWorkManage.CommitTran(); |
| | | return WebResponseContent.Instance.OK($"忶忣æåï¼æ¢å¤æ°éï¼{cancelQty}"); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return WebResponseContent.Instance.Error($"åæ¶åæ£å¤±è´¥ï¼{ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è·åæå
é¾ï¼ä»å½åæ¡ç 追溯å°åå§æ¡ç ï¼ |
| | | /// </summary> |
| | | // å¨ GetSplitChain æ¹æ³ä¸æ·»å æ´ä¸¥æ ¼çéªè¯ |
| | | private async Task<List<SplitChainItem>> GetSplitChain(string currentBarcode) |
| | | { |
| | | var chain = new List<SplitChainItem>(); |
| | | var visited = new HashSet<string>(); |
| | | |
| | | string current = currentBarcode; |
| | | int maxDepth = 10; // 鲿¢æ éå¾ªç¯ |
| | | |
| | | while (!string.IsNullOrEmpty(current) && maxDepth > 0) |
| | | { |
| | | maxDepth--; |
| | | |
| | | if (visited.Contains(current)) |
| | | { |
| | | _logger.LogWarning($"æ£æµå°å¾ªç¯å¼ç¨å¨æå
é¾ä¸: {current}"); |
| | | break; |
| | | } |
| | | |
| | | visited.Add(current); |
| | | |
| | | var splitRecord = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>() |
| | | .Where(it => it.NewBarcode == current && !it.IsReverted) |
| | | .FirstAsync(); |
| | | |
| | | if (splitRecord == null) |
| | | break; |
| | | |
| | | // éªè¯æå
è®°å½ç宿´æ§ |
| | | if (string.IsNullOrEmpty(splitRecord.OriginalBarcode)) |
| | | { |
| | | _logger.LogError($"æå
è®°å½ {splitRecord.Id} 缺å°åå§æ¡ç "); |
| | | break; |
| | | } |
| | | |
| | | var item = new SplitChainItem |
| | | { |
| | | SplitRecord = splitRecord, |
| | | OriginalBarcode = splitRecord.OriginalBarcode, |
| | | NewBarcode = splitRecord.NewBarcode, |
| | | SplitQuantity = splitRecord.SplitQty |
| | | }; |
| | | |
| | | chain.Add(item); |
| | | |
| | | current = splitRecord.OriginalBarcode; |
| | | } |
| | | |
| | | if (maxDepth <= 0) |
| | | { |
| | | _logger.LogWarning($"æå
é¾è¿½æº¯è¾¾å°æå¤§æ·±åº¦: {currentBarcode}"); |
| | | } |
| | | |
| | | chain.Reverse(); |
| | | return chain; |
| | | } |
| | | /// <summary> |
| | | /// å¤çæå
é¾ç忶忣 |
| | | /// </summary> |
| | | private async Task HandleSplitChainCancel(string orderNo, string palletCode, string barcode, |
| | | decimal cancelQty, Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord, List<SplitChainItem> splitChain) |
| | | { |
| | | if (!splitChain.Any()) |
| | | return; |
| | | |
| | | // æ¾å°åå§æ¡ç ï¼é¾ç第ä¸ä¸ªï¼ |
| | | var originalSplitItem = splitChain.First(); |
| | | var originalBarcode = originalSplitItem.OriginalBarcode; |
| | | |
| | | // æ¥æ¾åå§æ¡ç çéå®ä¿¡æ¯ååºå |
| | | var originalLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.CurrentBarcode == originalBarcode && it.Status == (int)OutLockStockStatusEnum.åºåºä¸) |
| | | .FirstAsync(); |
| | | |
| | | var originalStockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.Barcode == originalBarcode && it.StockId == originalLockInfo.StockId) |
| | | .FirstAsync(); |
| | | |
| | | if (originalLockInfo == null || originalStockDetail == null) |
| | | throw new Exception("æªæ¾å°åå§æ¡ç çéå®ä¿¡æ¯æåºåä¿¡æ¯"); |
| | | |
| | | // æ¢å¤åå§æ¡ç åºåï¼å°åæ¶çæ°éå åå»ï¼ |
| | | originalStockDetail.StockQuantity += cancelQty; |
| | | originalStockDetail.OutboundQuantity += cancelQty; |
| | | await _stockInfoDetailService.Db.Updateable(originalStockDetail).ExecuteCommandAsync(); |
| | | |
| | | // æ¢å¤åå§æ¡ç éå®ä¿¡æ¯ |
| | | originalLockInfo.AssignQuantity += cancelQty; |
| | | await _outStockLockInfoService.Db.Updateable(originalLockInfo).ExecuteCommandAsync(); |
| | | |
| | | // å 餿å
é¾ä¸æææ°æ¡ç çéå®ä¿¡æ¯ååºåè®°å½ |
| | | var allNewBarcodes = splitChain.Select(x => x.NewBarcode).ToList(); |
| | | |
| | | // å é¤éå®ä¿¡æ¯ |
| | | await _outStockLockInfoService.Db.Deleteable<Dt_OutStockLockInfo>() |
| | | .Where(it => allNewBarcodes.Contains(it.CurrentBarcode)) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | // å é¤åºåè®°å½ï¼åªå 餿å
产ççæ°æ¡ç åºåï¼ä¿çåå§æ¡ç ï¼ |
| | | await _stockInfoDetailService.Db.Deleteable<Dt_StockInfoDetail>() |
| | | .Where(it => allNewBarcodes.Contains(it.Barcode) && it.Barcode != originalBarcode) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | // æ´æ°æå
é¾ä¸æææå
è®°å½ç¶æä¸ºå·²æå
|
| | | foreach (var chainItem in splitChain) |
| | | { |
| | | chainItem.SplitRecord.Status = (int)SplitPackageStatusEnum.å·²æå
; |
| | | await _splitPackageService.Db.Updateable(chainItem.SplitRecord).ExecuteCommandAsync(); |
| | | } |
| | | |
| | | // æ¢å¤è®¢åæç»æ£éæ°éï¼ä½¿ç¨åå§éå®ä¿¡æ¯ç订åæç»IDï¼ |
| | | await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>() |
| | | .SetColumns(it => it.PickedQty == it.PickedQty - cancelQty) |
| | | .Where(it => it.Id == originalLockInfo.OrderDetailId) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | // æ¢å¤è®¢åç¶æ |
| | | await CheckAndRevertOrderStatus(orderNo); |
| | | |
| | | // å 餿£éè®°å½ |
| | | await Db.Deleteable<Dt_PickingRecord>() |
| | | .Where(it => it.Id == pickingRecord.Id) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | //// è®°å½åæ¶æä½åå² |
| | | //await RecordCancelHistory(orderNo, palletCode, barcode, cancelQty, pickingRecord.Id, |
| | | // lockInfo.MaterielCode, "åæ¶æå
é¾åæ£"); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å¤çæ®éæ¡ç ç忶忣 |
| | | /// </summary> |
| | | private async Task HandleNormalBarcodeCancel(string orderNo, string palletCode, string barcode, |
| | | decimal cancelQty, Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord) |
| | | { |
| | | // 1. æ¥æ¾åºåä¿¡æ¯ |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.Barcode == barcode && it.StockId == lockInfo.StockId) |
| | | .FirstAsync(); |
| | | |
| | | if (stockDetail == null) |
| | | throw new Exception("æªæ¾å°å¯¹åºçåºåä¿¡æ¯"); |
| | | |
| | | // 2. æ¢å¤åºåæ°é |
| | | if (stockDetail.StockQuantity == 0) |
| | | { |
| | | // æ´å
åºåºçæ
åµ |
| | | stockDetail.StockQuantity = cancelQty; |
| | | stockDetail.OutboundQuantity = cancelQty; |
| | | } |
| | | else |
| | | { |
| | | // é¨ååºåºçæ
åµ |
| | | stockDetail.StockQuantity += cancelQty; |
| | | stockDetail.OutboundQuantity += cancelQty; |
| | | } |
| | | await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync(); |
| | | |
| | | // 3. æ¢å¤éå®ä¿¡æ¯ç¶æ |
| | | lockInfo.AssignQuantity += cancelQty; |
| | | lockInfo.PickedQty -= cancelQty; |
| | | |
| | | if (lockInfo.PickedQty == 0) |
| | | { |
| | | lockInfo.Status = (int)OutLockStockStatusEnum.åºåºä¸; |
| | | } |
| | | await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync(); |
| | | |
| | | // 4. å¤çç¸å
³çæå
è®°å½ç¶ææ¢å¤ |
| | | var relatedSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>() |
| | | .Where(it => it.OriginalBarcode == barcode && |
| | | it.Status == (int)SplitPackageStatusEnum.å·²æ£é) |
| | | .ToListAsync(); |
| | | |
| | | foreach (var record in relatedSplitRecords) |
| | | { |
| | | record.Status = (int)SplitPackageStatusEnum.å·²æå
; |
| | | await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync(); |
| | | } |
| | | |
| | | // 5. æ¢å¤è®¢åæç»çæ£éæ°é |
| | | await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>() |
| | | .SetColumns(it => it.PickedQty == it.PickedQty - cancelQty) |
| | | .Where(it => it.Id == lockInfo.OrderDetailId) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | // 6. æ¢å¤è®¢åç¶æ |
| | | await CheckAndRevertOrderStatus(orderNo); |
| | | |
| | | // 7. å 餿£éè®°å½ |
| | | await Db.Deleteable<Dt_PickingRecord>().Where(it => it.Id == pickingRecord.Id).ExecuteCommandAsync(); |
| | | |
| | | //// 8. è®°å½åæ¶æä½åå² |
| | | //await RecordCancelHistory(orderNo, palletCode, barcode, cancelQty, pickingRecord.Id, |
| | | // lockInfo.MaterielCode, "忶忣"); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ£æ¥å¹¶æ¢å¤è®¢åç¶æ |
| | | /// </summary> |
| | | private async Task CheckAndRevertOrderStatus(string orderNo) |
| | | { |
| | | var order = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>() |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .FirstAsync(); |
| | | |
| | | if (order != null && order.OrderStatus == OutOrderStatusEnum.åºåºå®æ.ObjToInt()) |
| | | { |
| | | await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>() |
| | | .SetColumns(x => x.OrderStatus == OutOrderStatusEnum.åºåºä¸.ObjToInt()) |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è®°å½åæ¶æä½åå² |
| | | /// </summary> |
| | | private async Task RecordCancelHistory(string orderNo, string palletCode, string barcode, |
| | | decimal cancelQty, int pickingRecordId, string materielCode, string reason) |
| | | { |
| | | |
| | | //var cancelHistory = new Dt_PickingCancelRecord |
| | | //{ |
| | | // OrderNo = orderNo, |
| | | // PalletCode = palletCode, |
| | | // Barcode = barcode, |
| | | // CancelQuantity = cancelQty, |
| | | // CancelTime = DateTime.Now, |
| | | // Operator = App.User.UserName, |
| | | // OriginalPickingRecordId = pickingRecordId, |
| | | // MaterielCode = materielCode, |
| | | // Reason = reason |
| | | //}; |
| | | //await Db.Insertable(cancelHistory).ExecuteCommandAsync(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æå
é¾é¡¹ |
| | | /// </summary> |
| | | public class SplitChainItem |
| | | { |
| | | public Dt_SplitPackageRecord SplitRecord { get; set; } |
| | | public string OriginalBarcode { get; set; } |
| | | public string NewBarcode { get; set; } |
| | | public decimal SplitQuantity { get; set; } |
| | | } |
| | | // è·åæªæ£éå表 |
| | | public async Task<List<Dt_OutStockLockInfo>> GetUnpickedList(string orderNo, string palletCode) |
| | | { |
| | |
| | | |
| | | return summary; |
| | | } |
| | | |
| | | #region æ ¸å¿ä¸å¡æµç¨ |
| | | /// <summary> |
| | | /// è·åæ£éåå² |
| | | /// æ£é |
| | | /// </summary> |
| | | public async Task<List<Dt_PickingRecord>> GetPickingHistory(int orderId) |
| | | /// <param name="orderNo"></param> |
| | | /// <param name="palletCode"></param> |
| | | /// <param name="barcode"></param> |
| | | /// <returns></returns> |
| | | public async Task<WebResponseContent> ConfirmPicking(string orderNo, string palletCode, string barcode) |
| | | { |
| | | // éè¿åºåºåIDæ¥è¯¢ç¸å
³çæ£éåå² |
| | | // 注æï¼Dt_PickingRecord 䏿²¡æç´æ¥åå¨OrderIdï¼éè¦éè¿åºåºåæç»å
³è |
| | | var detailIds = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .Where(d => d.OrderId == orderId) |
| | | .Select(d => d.Id) |
| | | .ToListAsync(); |
| | | |
| | | return await Db.Queryable<Dt_PickingRecord>() |
| | | .Where(p => detailIds.Contains(p.OrderDetailId)) |
| | | .OrderByDescending(p => p.PickTime) |
| | | .ToListAsync(); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// è·åæççåºåºç¶æä¿¡æ¯ |
| | | /// </summary> |
| | | public async Task<WebResponseContent> GetPalletOutboundStatus(string palletCode) |
| | | { |
| | | // è·åæççéå®ä¿¡æ¯ |
| | | var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(x => x.PalletCode == palletCode) |
| | | .ToListAsync(); |
| | | |
| | | // è·åæçåºåä¿¡æ¯ |
| | | var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>() |
| | | .Includes(x => x.Details) |
| | | .Where(x => x.PalletCode == palletCode) |
| | | .FirstAsync(); |
| | | |
| | | if (stockInfo == null) |
| | | return WebResponseContent.Instance.Error("æªæ¾å°æçä¿¡æ¯"); |
| | | |
| | | // 计ç®åç§æ°é |
| | | var totalStockQuantity = stockInfo.Details.Sum(x => x.StockQuantity); |
| | | var totalOutboundQuantity = stockInfo.Details.Sum(x => x.OutboundQuantity); |
| | | var totalLockedQuantity = lockInfos.Where(x => x.Status == (int)OutLockStockStatusEnum.åºåºä¸) |
| | | .Sum(x => x.AssignQuantity - x.PickedQty); |
| | | var totalPickedQuantity = lockInfos.Sum(x => x.PickedQty); |
| | | |
| | | var result = new |
| | | try |
| | | { |
| | | PalletCode = palletCode, |
| | | LocationCode = stockInfo.LocationCode, |
| | | StockStatus = stockInfo.StockStatus, |
| | | TotalStockQuantity = totalStockQuantity, |
| | | TotalOutboundQuantity = totalOutboundQuantity, |
| | | TotalLockedQuantity = totalLockedQuantity, |
| | | TotalPickedQuantity = totalPickedQuantity, |
| | | AvailableQuantity = totalStockQuantity - totalOutboundQuantity, |
| | | LockInfos = lockInfos.Select(x => new |
| | | { |
| | | x.Id, |
| | | x.MaterielCode, |
| | | x.OrderDetailId, |
| | | x.AssignQuantity, |
| | | x.PickedQty, |
| | | x.Status, |
| | | x.CurrentBarcode, |
| | | x.IsSplitted |
| | | }).ToList(), |
| | | StockDetails = stockInfo.Details.Select(x => new |
| | | { |
| | | x.Barcode, |
| | | x.MaterielCode, |
| | | StockQuantity = x.StockQuantity, |
| | | OutboundQuantity = x.OutboundQuantity, |
| | | AvailableQuantity = x.StockQuantity - x.OutboundQuantity |
| | | }).ToList() |
| | | }; |
| | | _unitOfWorkManage.BeginTran(); |
| | | |
| | | var validationResult = await ValidatePickingRequest(orderNo, palletCode, barcode); |
| | | if (!validationResult.IsValid) |
| | | return WebResponseContent.Instance.Error(validationResult.ErrorMessage); |
| | | |
| | | return WebResponseContent.Instance.OK(null, result); |
| | | var (lockInfo, orderDetail, stockDetail) = validationResult.Data; |
| | | |
| | | // 计ç®å®é
æ£éæ°é |
| | | var quantityResult = await CalculateActualPickingQuantity(lockInfo, orderDetail, stockDetail); |
| | | if (!quantityResult.IsValid) |
| | | return WebResponseContent.Instance.Error(quantityResult.ErrorMessage); |
| | | |
| | | var (actualQty, adjustedReason) = quantityResult.Data; |
| | | |
| | | var overPickingValidation = await ValidateOverPicking(orderDetail.Id, actualQty); |
| | | if (!overPickingValidation.IsValid) |
| | | { |
| | | return WebResponseContent.Instance.Error(overPickingValidation.ErrorMessage); |
| | | } |
| | | |
| | | // æ§è¡åæ£é»è¾ |
| | | var pickingResult = await ExecutePickingLogic(lockInfo, orderDetail, stockDetail, orderNo, palletCode, barcode, actualQty); |
| | | |
| | | // æ´æ°ç¸å
³æ°æ® |
| | | await UpdateOrderRelatedData(orderDetail.Id, pickingResult.ActualPickedQty, orderNo); |
| | | |
| | | // è®°å½æä½åå² |
| | | await RecordPickingHistory(pickingResult, orderNo, palletCode); |
| | | |
| | | _unitOfWorkManage.CommitTran(); |
| | | |
| | | return CreatePickingResponse(pickingResult, adjustedReason); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | _logger.LogError($"ConfirmPicking失败 - OrderNo: {orderNo}, PalletCode: {palletCode}, Barcode: {barcode}, Error: {ex.Message}"); |
| | | return WebResponseContent.Instance.Error($"æ£é确认失败ï¼{ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// ç´æ¥åºåº - æ´ä¸ªæçåºåºï¼æ¸
空åºå |
| | | /// åæ¶æ£é |
| | | /// </summary> |
| | | public async Task<WebResponseContent> DirectOutbound(DirectOutboundRequest request) |
| | | /// <param name="orderNo"></param> |
| | | /// <param name="palletCode"></param> |
| | | /// <param name="barcode"></param> |
| | | /// <returns></returns> |
| | | public async Task<WebResponseContent> CancelPicking(string orderNo, string palletCode, string barcode) |
| | | { |
| | | try |
| | | { |
| | | if (await IsPalletReturned(palletCode)) |
| | | { |
| | | return WebResponseContent.Instance.Error($"æç{palletCode}å·²ç»ååºï¼ä¸è½åæ¶åæ£"); |
| | | } |
| | | _unitOfWorkManage.BeginTran(); |
| | | |
| | | // 1. åç½®éªè¯ |
| | | var validationResult = await ValidateCancelRequest(orderNo, palletCode, barcode); |
| | | if (!validationResult.IsValid) |
| | | return WebResponseContent.Instance.Error(validationResult.ErrorMessage); |
| | | |
| | | var (pickingRecord, lockInfo, orderDetail) = validationResult.Data; |
| | | |
| | | // 2. æ§è¡åæ¶é»è¾ |
| | | await ExecuteCancelLogic(lockInfo, pickingRecord, orderDetail, orderNo); |
| | | |
| | | _unitOfWorkManage.CommitTran(); |
| | | |
| | | return WebResponseContent.Instance.OK($"忶忣æåï¼æ¢å¤æ°éï¼{pickingRecord.PickQuantity}"); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | _logger.LogError($"CancelPicking失败 - OrderNo: {orderNo}, PalletCode: {palletCode}, Barcode: {barcode}, Error: {ex.Message}"); |
| | | return WebResponseContent.Instance.Error($"åæ¶åæ£å¤±è´¥ï¼{ex.Message}"); |
| | | } |
| | | } |
| | | /// <summary> |
| | | /// ååº |
| | | /// </summary> |
| | | /// <param name="orderNo"></param> |
| | | /// <param name="palletCode"></param> |
| | | /// <param name="reason"></param> |
| | | /// <returns></returns> |
| | | public async Task<WebResponseContent> ReturnRemaining(string orderNo, string palletCode, string reason) |
| | | { |
| | | try |
| | | { |
| | | _unitOfWorkManage.BeginTran(); |
| | | |
| | | var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>() |
| | | .Includes(x => x.Details) |
| | | .Where(x => x.PalletCode == request.PalletCode).FirstAsync(); |
| | | // 1. åºç¡éªè¯ |
| | | if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(palletCode)) |
| | | return WebResponseContent.Instance.Error("订åå·åæçç ä¸è½ä¸ºç©º"); |
| | | |
| | | // 2. è·ååºååä»»å¡ä¿¡æ¯ |
| | | var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>().FirstAsync(x => x.PalletCode == palletCode); |
| | | |
| | | if (stockInfo == null) |
| | | return WebResponseContent.Instance.Error("æªæ¾å°æçåºåä¿¡æ¯"); |
| | | return WebResponseContent.Instance.Error($"æªæ¾å°æç {palletCode} 对åºçåºåä¿¡æ¯"); |
| | | |
| | | var task = await GetCurrentTask(orderNo, palletCode); |
| | | if (task == null) |
| | | return WebResponseContent.Instance.Error("æªæ¾å°å¯¹åºçä»»å¡ä¿¡æ¯"); |
| | | |
| | | var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(x => x.OrderNo == request.OrderNo && x.PalletCode == request.PalletCode) |
| | | .ToListAsync(); |
| | | // 3. åæéè¦ååºçè´§ç© |
| | | var returnAnalysis = await AnalyzeReturnItems(orderNo, palletCode, stockInfo.Id); |
| | | if (!returnAnalysis.HasItemsToReturn) |
| | | return await HandleNoReturnItems(orderNo, palletCode,task); |
| | | |
| | | // 4. æ§è¡ååºæä½ |
| | | await ExecuteReturnOperations(orderNo, palletCode, stockInfo, task, returnAnalysis); |
| | | |
| | | foreach (var lockInfo in lockInfos) |
| | | { |
| | | if (lockInfo.Status == (int)OutLockStockStatusEnum.åºåºä¸) |
| | | { |
| | | lockInfo.PickedQty = lockInfo.AssignQuantity; |
| | | } |
| | | lockInfo.Status = (int)OutLockStockStatusEnum.å·²åºåº; |
| | | await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync(); |
| | | |
| | | var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .Where(x => x.Id == lockInfo.OrderDetailId) |
| | | .FirstAsync(); |
| | | if (orderDetail != null) |
| | | { |
| | | orderDetail.OverOutQuantity += lockInfo.PickedQty; |
| | | orderDetail.LockQuantity -= lockInfo.PickedQty; |
| | | orderDetail.OrderDetailStatus = (int)OrderDetailStatusEnum.Over; |
| | | orderDetail.LockQuantity = 0; |
| | | await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | var groupDetails = lockInfos.GroupBy(x => x.OrderDetailId).Select(x => new |
| | | { |
| | | OrderDetailId = x.Key, |
| | | TotalQuantity = x.Sum(o => o.PickedQty) |
| | | }).ToList(); |
| | | foreach (var item in groupDetails) |
| | | { |
| | | var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>().Where(x => x.Id == item.OrderDetailId).FirstAsync(); |
| | | if (orderDetail != null) |
| | | { |
| | | orderDetail.OverOutQuantity = item.TotalQuantity; |
| | | orderDetail.LockQuantity = 0; |
| | | orderDetail.OrderDetailStatus = (int)OrderDetailStatusEnum.Over; |
| | | await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | |
| | | await CheckAndUpdateOrderStatus(request.OrderNo); |
| | | |
| | | var lockInfoIds = lockInfos.Select(x => x.Id).ToList(); |
| | | var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>() |
| | | .Where(x => lockInfoIds.Contains(x.OutStockLockInfoId) && |
| | | x.Status == (int)SplitPackageStatusEnum.å·²æå
) |
| | | .ToListAsync(); |
| | | |
| | | foreach (var record in splitRecords) |
| | | { |
| | | record.Status = (int)SplitPackageStatusEnum.å·²æ£é; |
| | | await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync(); |
| | | } |
| | | |
| | | |
| | | var location = await _locationInfoService.Db.Queryable<Dt_LocationInfo>() |
| | | .Where(x => x.LocationCode == stockInfo.LocationCode) |
| | | .FirstAsync(); |
| | | if (location != null) |
| | | { |
| | | location.LocationStatus = (int)LocationStatusEnum.Free; |
| | | await _locationInfoService.Db.Updateable(location).ExecuteCommandAsync(); |
| | | } |
| | | |
| | | foreach (var detail in stockInfo.Details) |
| | | { |
| | | await _stockInfoDetailService.Db.Deleteable(detail).ExecuteCommandAsync(); |
| | | } |
| | | await _stockInfoService.Db.Deleteable(stockInfo).ExecuteCommandAsync(); |
| | | |
| | | |
| | | // 5. å建ååºä»»å¡ |
| | | await CreateReturnTaskAndHandleESS(orderNo, palletCode, task, returnAnalysis); |
| | | |
| | | _unitOfWorkManage.CommitTran(); |
| | | return WebResponseContent.Instance.OK("ç´æ¥åºåºæå"); |
| | | |
| | | // 6. æ´æ°è®¢åç¶æï¼ä¸è§¦åMESåä¼ ï¼ |
| | | await UpdateOrderStatusForReturn(orderNo); |
| | | |
| | | return WebResponseContent.Instance.OK($"ååºæä½æåï¼å
±ååºæ°éï¼{returnAnalysis.TotalReturnQty}"); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return WebResponseContent.Instance.Error($"ç´æ¥åºåºå¤±è´¥: {ex.Message}"); |
| | | _logger.LogError($"ReturnRemaining失败 - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}"); |
| | | return WebResponseContent.Instance.Error($"ååºæä½å¤±è´¥: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region åæ£ç¡®è®¤ç§ææ¹æ³ |
| | | |
| | | private async Task<ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>> ValidatePickingRequest(string orderNo, string palletCode, string barcode) |
| | | { |
| | | // 1. åºç¡åæ°éªè¯ |
| | | if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(palletCode) || string.IsNullOrEmpty(barcode)) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error("订åå·ãæçç åæ¡ç ä¸è½ä¸ºç©º"); |
| | | |
| | | // 2. æ¥æ¾ææçéå®ä¿¡æ¯ |
| | | var lockInfo = await FindValidLockInfo(orderNo, palletCode, barcode); |
| | | if (lockInfo == null) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"æªæ¾å°ææçéå®ä¿¡æ¯"); |
| | | |
| | | // 3. æ£æ¥è®¢åç¶æ |
| | | var order = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>() |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .FirstAsync(); |
| | | |
| | | if (order?.OrderStatus == (int)OutOrderStatusEnum.åºåºå®æ) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"订å{orderNo}已宿ï¼ä¸è½ç»§ç»åæ£"); |
| | | |
| | | // 4. è·å订åæç» |
| | | var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .FirstAsync(x => x.Id == lockInfo.OrderDetailId); |
| | | |
| | | if (orderDetail == null) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"æªæ¾å°è®¢åæç»"); |
| | | |
| | | // 5. æ£æ¥è®¢åæç»æ°é |
| | | if (orderDetail.OverOutQuantity >= orderDetail.NeedOutQuantity) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"订åæç»éæ±æ°é已满足"); |
| | | |
| | | // 6. è·ååºåæç» |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(x => x.Barcode == barcode && x.StockId == lockInfo.StockId && |
| | | x.Status != StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt()) |
| | | .FirstAsync(); |
| | | |
| | | if (stockDetail == null) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"æ æçæ¡ç æç©æç¼ç "); |
| | | |
| | | // 7. æ£æ¥åºåç¶æåæ°é |
| | | if (stockDetail.StockQuantity <= 0) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"æ¡ç {barcode}åºåä¸è¶³"); |
| | | |
| | | if (stockDetail.Status != StockStatusEmun.åºåºéå®.ObjToInt()) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"æ¡ç {barcode}ç¶æä¸æ£ç¡®ï¼æ æ³åæ£"); |
| | | |
| | | // 8. æ£æ¥æ¯å¦éå¤åæ£ |
| | | var existingPicking = await Db.Queryable<Dt_PickingRecord>() |
| | | .Where(x => x.Barcode == barcode && x.OrderNo == orderNo && x.PalletCode == palletCode && x.OutStockLockId == lockInfo.Id) |
| | | .FirstAsync(); |
| | | |
| | | if (existingPicking != null) |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Error($"æ¡ç {barcode}å·²ç»åæ£è¿"); |
| | | |
| | | return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail)>.Success((lockInfo, orderDetail, stockDetail)); |
| | | } |
| | | |
| | | private async Task<Dt_OutStockLockInfo> FindValidLockInfo(string orderNo, string palletCode, string barcode) |
| | | { |
| | | // ä¼å
æ¥æ¾ç²¾ç¡®å¹é
çè®°å½ |
| | | var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.OrderNo == orderNo && |
| | | it.Status == (int)OutLockStockStatusEnum.åºåºä¸ && |
| | | it.PalletCode == palletCode && |
| | | it.CurrentBarcode == barcode && |
| | | it.AssignQuantity > it.PickedQty).FirstAsync(); |
| | | |
| | | if (lockInfo == null) |
| | | { |
| | | // æ¥æ¾åä¸è®¢åä¸çè®°å½ |
| | | lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.OrderNo == orderNo && it.CurrentBarcode == barcode && it.Status == (int)OutLockStockStatusEnum.åºåºä¸ && it.AssignQuantity > it.PickedQty).FirstAsync(); |
| | | |
| | | if (lockInfo == null) |
| | | { |
| | | // æ£æ¥æ¯å¦å·²ç»å®æåæ£ |
| | | var completedLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.CurrentBarcode == barcode && |
| | | (it.Status == (int)OutLockStockStatusEnum.æ£é宿 || |
| | | it.PickedQty >= it.AssignQuantity)).FirstAsync(); |
| | | |
| | | if (completedLockInfo != null) |
| | | throw new Exception($"æ¡ç {barcode}å·²ç»å®æåæ£ï¼ä¸è½éå¤åæ£"); |
| | | else |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | return lockInfo; |
| | | } |
| | | |
| | | private async Task<ValidationResult<(decimal, string)>> CalculateActualPickingQuantity( |
| | | Dt_OutStockLockInfo lockInfo, Dt_OutboundOrderDetail orderDetail, Dt_StockInfoDetail stockDetail) |
| | | { |
| | | decimal plannedQty = lockInfo.AssignQuantity - lockInfo.PickedQty; |
| | | decimal remainingOrderQty = orderDetail.NeedOutQuantity - orderDetail.OverOutQuantity; |
| | | decimal stockQuantity = stockDetail.StockQuantity; |
| | | |
| | | if (plannedQty <= 0) |
| | | { |
| | | return ValidationResult<(decimal, string)>.Error($"è®¡åæ£éæ°éå¿
须大äº0ï¼å½å: {plannedQty}"); |
| | | } |
| | | |
| | | if (remainingOrderQty <= 0) |
| | | { |
| | | return ValidationResult<(decimal, string)>.Error($"订åå©ä½éæ±æ°éå¿
须大äº0ï¼å½å: {remainingOrderQty}"); |
| | | } |
| | | |
| | | if (stockQuantity <= 0) |
| | | { |
| | | return ValidationResult<(decimal, string)>.Error($"åºåæ°éå¿
须大äº0ï¼å½å: {stockQuantity}"); |
| | | } |
| | | // ä¸éæ£æ¥ï¼åæå°å¼ |
| | | decimal actualQty = plannedQty; |
| | | string adjustedReason = null; |
| | | |
| | | if (plannedQty > remainingOrderQty) |
| | | { |
| | | actualQty = remainingOrderQty; |
| | | adjustedReason = $"è®¢åæ°ééå¶ï¼ä»{plannedQty}è°æ´ä¸º{actualQty}"; |
| | | } |
| | | if (actualQty > stockQuantity) |
| | | { |
| | | actualQty = stockQuantity; |
| | | adjustedReason = adjustedReason != null |
| | | ? $"{adjustedReason}ï¼åºåæ°ééå¶ï¼è¿ä¸æ¥è°æ´ä¸º{actualQty}" |
| | | : $"åºåæ°ééå¶ï¼ä»{plannedQty}è°æ´ä¸º{actualQty}"; |
| | | } |
| | | if (actualQty <= 0) |
| | | { |
| | | return ValidationResult<(decimal, string)>.Error($"æ æ³åæ£ï¼è®¡ç®åçå®é
æ°é为{actualQty}"); |
| | | } |
| | | decimal projectedOverOut = orderDetail.OverOutQuantity + actualQty; |
| | | if (projectedOverOut > orderDetail.NeedOutQuantity) |
| | | { |
| | | // 妿ä¼è¶
æ£ï¼è°æ´ä¸ºåå¥½æ»¡è¶³éæ±çæ°é |
| | | actualQty = orderDetail.NeedOutQuantity - orderDetail.OverOutQuantity; |
| | | adjustedReason = adjustedReason != null |
| | | ? $"{adjustedReason}ï¼é²è¶
æ£éå¶ï¼æç»è°æ´ä¸º{actualQty}" |
| | | : $"é²è¶
æ£éå¶ï¼ä»{plannedQty}è°æ´ä¸º{actualQty}"; |
| | | } |
| | | |
| | | if (adjustedReason != null) |
| | | { |
| | | _logger.LogWarning($"忣æ°éè°æ´ï¼{adjustedReason}ï¼è®¢å{orderDetail.NeedOutQuantity}ï¼å·²åºåº{orderDetail.OverOutQuantity}ï¼åºå{stockQuantity}"); |
| | | } |
| | | |
| | | return ValidationResult<(decimal, string)>.Success((actualQty, adjustedReason)); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// ä¸é¨éªè¯æ¯å¦ä¼åçè¶
æ£ |
| | | /// </summary> |
| | | private async Task<ValidationResult<bool>> ValidateOverPicking(int orderDetailId, decimal pickingQty) |
| | | { |
| | | var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .FirstAsync(x => x.Id == orderDetailId); |
| | | |
| | | if (orderDetail == null) |
| | | return ValidationResult<bool>.Error("æªæ¾å°è®¢åæç»"); |
| | | |
| | | decimal projectedOverOut = orderDetail.OverOutQuantity + pickingQty; |
| | | |
| | | if (projectedOverOut > orderDetail.NeedOutQuantity) |
| | | { |
| | | return ValidationResult<bool>.Error( |
| | | $"忣åå°å¯¼è´è¶
æ£ï¼å½åå·²åºåº{orderDetail.OverOutQuantity}ï¼æ¬æ¬¡åæ£{pickingQty}ï¼å计{projectedOverOut}ï¼è¶
è¿éæ±{orderDetail.NeedOutQuantity}"); |
| | | } |
| | | |
| | | return ValidationResult<bool>.Success(true); |
| | | } |
| | | private async Task<PickingResult> ExecutePickingLogic( |
| | | Dt_OutStockLockInfo lockInfo, Dt_OutboundOrderDetail orderDetail, Dt_StockInfoDetail stockDetail, |
| | | string orderNo, string palletCode, string barcode, decimal actualQty) |
| | | { |
| | | decimal stockQuantity = stockDetail.StockQuantity; |
| | | var result = new PickingResult |
| | | { |
| | | FinalLockInfo = lockInfo, |
| | | FinalBarcode = barcode, |
| | | FinalStockId = stockDetail.Id, |
| | | ActualPickedQty = actualQty |
| | | }; |
| | | |
| | | if (actualQty < stockQuantity) |
| | | { |
| | | await HandleSplitPacking(lockInfo, stockDetail, actualQty, stockQuantity, result); |
| | | } |
| | | else if (actualQty == stockQuantity) |
| | | { |
| | | await HandleFullPicking(lockInfo, stockDetail, actualQty, result); |
| | | } |
| | | else |
| | | { |
| | | await HandlePartialPicking(lockInfo, stockDetail, actualQty, stockQuantity, result); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | private async Task HandleSplitPacking(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail, |
| | | decimal actualQty, decimal stockQuantity, PickingResult result) |
| | | { |
| | | decimal remainingStockQty = stockQuantity - actualQty; |
| | | |
| | | // 1. æ´æ°åæ¡ç åºå |
| | | stockDetail.StockQuantity = remainingStockQty; |
| | | stockDetail.OutboundQuantity = remainingStockQty; |
| | | await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync(); |
| | | |
| | | // 2. çææ°æ¡ç |
| | | string newBarcode = await GenerateNewBarcode(); |
| | | |
| | | // 3. å建æ°éå®ä¿¡æ¯ |
| | | var newLockInfo = await CreateSplitLockInfo(lockInfo, actualQty, newBarcode); |
| | | |
| | | // 4. è®°å½æå
åå² |
| | | await RecordSplitHistory(lockInfo, stockDetail, actualQty, remainingStockQty, newBarcode); |
| | | |
| | | // 5. æ´æ°åéå®ä¿¡æ¯ |
| | | lockInfo.AssignQuantity = remainingStockQty; |
| | | lockInfo.PickedQty = 0; |
| | | lockInfo.Operator = App.User.UserName; |
| | | await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync(); |
| | | |
| | | // 6. è®¾ç½®ç»æ |
| | | result.FinalLockInfo = newLockInfo; |
| | | result.FinalBarcode = newBarcode; |
| | | result.SplitResults.AddRange(CreateSplitResults(lockInfo, actualQty, remainingStockQty, newBarcode, stockDetail.Barcode)); |
| | | } |
| | | |
| | | private async Task HandleFullPicking(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail, |
| | | decimal actualQty, PickingResult result) |
| | | { |
| | | // 1. æ´æ°åºå |
| | | stockDetail.StockQuantity = 0; |
| | | stockDetail.OutboundQuantity = 0; |
| | | stockDetail.Status = StockStatusEmun.åºåºå®æ.ObjToInt(); |
| | | await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync(); |
| | | |
| | | // 2. æ´æ°éå®ä¿¡æ¯ |
| | | lockInfo.PickedQty += actualQty; |
| | | lockInfo.Status = (int)OutLockStockStatusEnum.æ£é宿; |
| | | lockInfo.Operator = App.User.UserName; |
| | | await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync(); |
| | | } |
| | | |
| | | private async Task HandlePartialPicking(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail, |
| | | decimal actualQty, decimal stockQuantity, PickingResult result) |
| | | { |
| | | decimal stockOutQty = stockQuantity; |
| | | decimal remainingAssignQty = actualQty - stockQuantity; |
| | | |
| | | // 1. æ´æ°åºå |
| | | stockDetail.StockQuantity = 0; |
| | | stockDetail.OutboundQuantity = 0; |
| | | stockDetail.Status = StockStatusEmun.åºåºå®æ.ObjToInt(); |
| | | await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync(); |
| | | |
| | | // 2. æ´æ°éå®ä¿¡æ¯ |
| | | lockInfo.PickedQty += stockOutQty; |
| | | lockInfo.AssignQuantity = remainingAssignQty; |
| | | lockInfo.Operator = App.User.UserName; |
| | | await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync(); |
| | | |
| | | // 3. æ´æ°æå
è®°å½ç¶æ |
| | | await UpdateSplitRecordsStatus(stockDetail.Barcode); |
| | | |
| | | result.ActualPickedQty = stockOutQty; |
| | | } |
| | | |
| | | private async Task UpdateOrderRelatedData(int orderDetailId, decimal pickedQty, string orderNo) |
| | | { |
| | | // è·åææ°ç订åæç»æ°æ® |
| | | var currentOrderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .FirstAsync(x => x.Id == orderDetailId); |
| | | |
| | | decimal newOverOutQuantity = currentOrderDetail.OverOutQuantity + pickedQty; |
| | | decimal newPickedQty = currentOrderDetail.PickedQty + pickedQty; |
| | | |
| | | if (newOverOutQuantity > currentOrderDetail.NeedOutQuantity) |
| | | { |
| | | |
| | | _logger.LogError($"é²è¶
æ£æ£æ¥å¤±è´¥ - OrderDetailId: {orderDetailId}, å·²åºåº: {newOverOutQuantity}, éæ±: {currentOrderDetail.NeedOutQuantity}, æ¬æ¬¡åæ£: {pickedQty}"); |
| | | |
| | | |
| | | decimal adjustedQty = currentOrderDetail.NeedOutQuantity - currentOrderDetail.OverOutQuantity; |
| | | |
| | | if (adjustedQty > 0) |
| | | { |
| | | _logger.LogWarning($"èªå¨è°æ´åæ£æ°é鲿¢è¶
æ£ï¼ä»{pickedQty}è°æ´ä¸º{adjustedQty}"); |
| | | newOverOutQuantity = currentOrderDetail.NeedOutQuantity; |
| | | newPickedQty = currentOrderDetail.PickedQty + adjustedQty; |
| | | } |
| | | else |
| | | { |
| | | throw new Exception($"忣åå°å¯¼è´å·²åºåºæ°é({newOverOutQuantity})è¶
è¿è®¢åéæ±æ°é({currentOrderDetail.NeedOutQuantity})ï¼ä¸æ æ³èªå¨è°æ´"); |
| | | } |
| | | } |
| | | |
| | | // æ´æ°è®¢åæç» |
| | | await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>() |
| | | .SetColumns(it => new Dt_OutboundOrderDetail |
| | | { |
| | | PickedQty = newPickedQty, |
| | | OverOutQuantity = newOverOutQuantity, |
| | | }) |
| | | .Where(it => it.Id == orderDetailId) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | // æ£æ¥å¹¶æ´æ°è®¢åç¶æ |
| | | await CheckAndUpdateOrderStatus(orderNo); |
| | | } |
| | | |
| | | private async Task RecordPickingHistory(PickingResult result, string orderNo, string palletCode) |
| | | { |
| | | var task = await _taskRepository.Db.Queryable<Dt_Task>() |
| | | .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode) |
| | | .FirstAsync(); |
| | | |
| | | if (result.FinalLockInfo.Id <= 0) |
| | | { |
| | | throw new Exception($"éå®ä¿¡æ¯IDæ æ: {result.FinalLockInfo.Id}ï¼æ æ³è®°å½æ£éåå²"); |
| | | } |
| | | |
| | | var pickingHistory = new Dt_PickingRecord |
| | | { |
| | | FactoryArea = result.FinalLockInfo.FactoryArea, |
| | | TaskNo = task?.TaskNum ?? 0, |
| | | LocationCode = task?.SourceAddress ?? "", |
| | | StockId = result.FinalStockId, |
| | | OrderNo = orderNo, |
| | | OrderDetailId = result.FinalLockInfo.OrderDetailId, |
| | | PalletCode = palletCode, |
| | | Barcode = result.FinalBarcode, |
| | | MaterielCode = result.FinalLockInfo.MaterielCode, |
| | | PickQuantity = result.ActualPickedQty, |
| | | PickTime = DateTime.Now, |
| | | Operator = App.User.UserName, |
| | | OutStockLockId = result.FinalLockInfo.Id |
| | | }; |
| | | |
| | | await Db.Insertable(pickingHistory).ExecuteCommandAsync(); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region åæ¶åæ£ç§ææ¹æ³ |
| | | |
| | | private async Task<ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>> ValidateCancelRequest(string orderNo, string palletCode, string barcode) |
| | | { |
| | | // åºç¡åæ°éªè¯ |
| | | if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(palletCode) || string.IsNullOrEmpty(barcode)) |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("订åå·ãæçç åæ¡ç ä¸è½ä¸ºç©º"); |
| | | |
| | | // æ¥æ¾æ£éè®°å½ |
| | | var pickingRecord = await Db.Queryable<Dt_PickingRecord>() |
| | | .Where(it => it.OrderNo == orderNo && |
| | | it.PalletCode == palletCode && |
| | | it.Barcode == barcode) |
| | | .OrderByDescending(it => it.PickTime) |
| | | .FirstAsync(); |
| | | |
| | | if (pickingRecord == null) |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("æªæ¾å°å¯¹åºçæ£éè®°å½"); |
| | | |
| | | if (pickingRecord.PickQuantity <= 0) |
| | | { |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error($"æ£éè®°å½æ°éæ æ: {pickingRecord.PickQuantity}"); |
| | | } |
| | | // æ¥æ¾éå®ä¿¡æ¯ |
| | | var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.Id == pickingRecord.OutStockLockId) |
| | | .FirstAsync(); |
| | | |
| | | if (lockInfo == null) |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("æªæ¾å°å¯¹åºçåºåºéå®ä¿¡æ¯"); |
| | | |
| | | if (lockInfo.PickedQty < pickingRecord.PickQuantity) |
| | | { |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error( |
| | | $"åæ¶æ°é({pickingRecord.PickQuantity})è¶
è¿éå®ä¿¡æ¯çå·²æ£éæ°é({lockInfo.PickedQty})"); |
| | | } |
| | | // æ£æ¥ç¶ææ¯å¦å
è®¸åæ¶ |
| | | if (lockInfo.Status != (int)OutLockStockStatusEnum.æ£é宿) |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("å½åç¶æä¸å
è®¸åæ¶åæ£"); |
| | | |
| | | var order = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().FirstAsync(x => x.OrderNo == orderNo); |
| | | |
| | | if (order?.OrderStatus == (int)OutOrderStatusEnum.åºåºå®æ) |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("订åå·²åºåºå®æï¼ä¸å
è®¸åæ¶åæ£"); |
| | | |
| | | var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>().FirstAsync(x => x.Id == pickingRecord.OrderDetailId); |
| | | |
| | | if (orderDetail == null) |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error($"æªæ¾å°è®¢åæç»ï¼ID: {pickingRecord.OrderDetailId}"); |
| | | |
| | | // æ£æ¥è®¢åæç»çå·²æ£éæ°éæ¯å¦è¶³å¤åæ¶ |
| | | if (orderDetail.PickedQty < pickingRecord.PickQuantity) |
| | | { |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error($"åæ¶æ°é({pickingRecord.PickQuantity})è¶
è¿è®¢åæç»çå·²æ£éæ°é({orderDetail.PickedQty})"); |
| | | } |
| | | |
| | | // æ£æ¥è®¢åæç»çå·²åºåºæ°éæ¯å¦è¶³å¤åæ¶ |
| | | if (orderDetail.OverOutQuantity < pickingRecord.PickQuantity) |
| | | { |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error($"åæ¶æ°é({pickingRecord.PickQuantity})è¶
è¿è®¢åæç»çå·²åºåºæ°é({orderDetail.OverOutQuantity})"); |
| | | } |
| | | |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>().FirstAsync(it => it.Barcode == barcode && it.StockId == pickingRecord.StockId); |
| | | |
| | | if (stockDetail != null) |
| | | { |
| | | // æ£æ¥åºåç¶æ - å¦æç¶ææ¯å
¥åºç¡®è®¤æå
¥åºå®æï¼è¯´æå·²ç»ååº |
| | | if (stockDetail.Status == StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt() || |
| | | stockDetail.Status == StockStatusEmun.å
¥åºå®æ.ObjToInt()) |
| | | { |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error($"æ¡ç {barcode}å·²ç»ååºï¼ä¸è½åæ¶åæ£"); |
| | | } |
| | | } |
| | | |
| | | return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Success((pickingRecord, lockInfo, orderDetail)); |
| | | } |
| | | /// <summary> |
| | | /// æ£æ¥æ¡ç æ¯å¦å·²ç»ååº |
| | | /// </summary> |
| | | private async Task<bool> IsBarcodeReturned(string barcode, int stockId) |
| | | { |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.Barcode == barcode && it.StockId == stockId) |
| | | .FirstAsync(); |
| | | |
| | | if (stockDetail == null) |
| | | return false; |
| | | |
| | | // å¦æç¶ææ¯å
¥åºç¡®è®¤æå
¥åºå®æï¼è¯´æå·²ç»ååº |
| | | return stockDetail.Status == StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt() || |
| | | stockDetail.Status == StockStatusEmun.å
¥åºå®æ.ObjToInt(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ£æ¥éå®ä¿¡æ¯å¯¹åºçæ¡ç æ¯å¦å·²ç»ååº |
| | | /// </summary> |
| | | private async Task<bool> IsLockInfoReturned(Dt_OutStockLockInfo lockInfo) |
| | | { |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.Barcode == lockInfo.CurrentBarcode && it.StockId == lockInfo.StockId) |
| | | .FirstAsync(); |
| | | |
| | | if (stockDetail == null) |
| | | return false; |
| | | |
| | | return stockDetail.Status == StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt() || |
| | | stockDetail.Status == StockStatusEmun.å
¥åºå®æ.ObjToInt(); |
| | | } |
| | | private async Task ExecuteCancelLogic(Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord, |
| | | Dt_OutboundOrderDetail orderDetail, string orderNo) |
| | | { |
| | | decimal cancelQty = pickingRecord.PickQuantity; |
| | | |
| | | var currentStockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.Barcode == pickingRecord.Barcode && it.StockId == pickingRecord.StockId) |
| | | .FirstAsync(); |
| | | |
| | | if (currentStockDetail != null && |
| | | (currentStockDetail.Status == StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt() || |
| | | currentStockDetail.Status == StockStatusEmun.å
¥åºå®æ.ObjToInt())) |
| | | { |
| | | throw new Exception($"æ¡ç {pickingRecord.Barcode}å·²ç»ååºï¼æ æ³åæ¶åæ£"); |
| | | } |
| | | // æ£æ¥åæ¶åæ°éä¸ä¼ä¸ºè´æ° |
| | | decimal newOverOutQuantity = orderDetail.OverOutQuantity - cancelQty; |
| | | decimal newPickedQty = orderDetail.PickedQty - cancelQty; |
| | | |
| | | if (newOverOutQuantity < 0 || newPickedQty < 0) |
| | | { |
| | | throw new Exception($"忶忣å°å¯¼è´æ°æ®å¼å¸¸ï¼å·²åºåº{newOverOutQuantity}ï¼å·²æ£é{newPickedQty}"); |
| | | } |
| | | |
| | | // å¤çä¸åç±»åçåæ¶ |
| | | if (lockInfo.IsSplitted == 1 && lockInfo.ParentLockId.HasValue) |
| | | { |
| | | await HandleSplitBarcodeCancel(lockInfo, pickingRecord, cancelQty); |
| | | } |
| | | else |
| | | { |
| | | await HandleNormalBarcodeCancel(lockInfo, pickingRecord, cancelQty); |
| | | } |
| | | |
| | | // æ´æ°è®¢åæç» |
| | | await UpdateOrderDetailOnCancel(pickingRecord.OrderDetailId, cancelQty); |
| | | |
| | | // å 餿£éè®°å½ |
| | | await Db.Deleteable<Dt_PickingRecord>() |
| | | .Where(x => x.Id == pickingRecord.Id) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | // éæ°æ£æ¥è®¢åç¶æ |
| | | await UpdateOrderStatusForReturn(orderNo); |
| | | } |
| | | |
| | | private async Task HandleSplitBarcodeCancel(Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord, decimal cancelQty) |
| | | { |
| | | // æ¥æ¾ç¶éå®ä¿¡æ¯ |
| | | var parentLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(x => x.Id == lockInfo.ParentLockId.Value) |
| | | .FirstAsync(); |
| | | |
| | | if (parentLockInfo == null) |
| | | throw new Exception("æªæ¾å°ç¶éå®ä¿¡æ¯ï¼æ æ³åæ¶æå
忣"); |
| | | |
| | | if (await IsLockInfoReturned(parentLockInfo)) |
| | | { |
| | | throw new Exception($"ç¶æ¡ç {parentLockInfo.CurrentBarcode}å·²ç»ååºï¼æ æ³åæ¶æå
忣"); |
| | | } |
| | | if (await IsLockInfoReturned(lockInfo)) |
| | | { |
| | | throw new Exception($"æå
æ¡ç {lockInfo.CurrentBarcode}å·²ç»ååºï¼æ æ³åæ¶æå
忣"); |
| | | } |
| | | // æ¢å¤ç¶éå®ä¿¡æ¯çåé
æ°é |
| | | parentLockInfo.AssignQuantity += cancelQty; |
| | | await _outStockLockInfoService.Db.Updateable(parentLockInfo).ExecuteCommandAsync(); |
| | | |
| | | // æ¢å¤åºå |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(x => x.Barcode == parentLockInfo.CurrentBarcode && x.StockId == parentLockInfo.StockId) |
| | | .FirstAsync(); |
| | | |
| | | if (stockDetail != null) |
| | | { |
| | | stockDetail.StockQuantity += cancelQty; |
| | | stockDetail.OutboundQuantity = stockDetail.StockQuantity; |
| | | stockDetail.Status = StockStatusEmun.åºåºéå®.ObjToInt(); |
| | | await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync(); |
| | | } |
| | | |
| | | // æ´æ°æå
è®°å½ç¶æ |
| | | await _splitPackageService.Db.Updateable<Dt_SplitPackageRecord>() |
| | | .SetColumns(x => new Dt_SplitPackageRecord |
| | | { |
| | | Status = (int)SplitPackageStatusEnum.å·²æ¤é, |
| | | IsReverted = true, |
| | | }) |
| | | .Where(x => x.NewBarcode == lockInfo.CurrentBarcode && !x.IsReverted) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | // å 餿å
产ççéå®ä¿¡æ¯ |
| | | await _outStockLockInfoService.Db.Deleteable<Dt_OutStockLockInfo>() |
| | | .Where(x => x.Id == lockInfo.Id) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | |
| | | private async Task HandleNormalBarcodeCancel(Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord, decimal cancelQty) |
| | | { |
| | | if (await IsLockInfoReturned(lockInfo)) |
| | | { |
| | | throw new Exception($"æ¡ç {lockInfo.CurrentBarcode}å·²ç»ååºï¼æ æ³åæ¶åæ£"); |
| | | } |
| | | // æ¢å¤éå®ä¿¡æ¯ |
| | | lockInfo.PickedQty -= cancelQty; |
| | | if (lockInfo.PickedQty < 0) lockInfo.PickedQty = 0; |
| | | |
| | | lockInfo.Status = (int)OutLockStockStatusEnum.åºåºä¸; |
| | | await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync(); |
| | | |
| | | // æ¢å¤åºå |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(x => x.Barcode == pickingRecord.Barcode && x.StockId == pickingRecord.StockId) |
| | | .FirstAsync(); |
| | | |
| | | if (stockDetail != null) |
| | | { |
| | | stockDetail.StockQuantity += cancelQty; |
| | | stockDetail.OutboundQuantity = stockDetail.StockQuantity; |
| | | stockDetail.Status = StockStatusEmun.åºåºéå®.ObjToInt(); |
| | | await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | |
| | | private async Task UpdateOrderDetailOnCancel(int orderDetailId, decimal cancelQty) |
| | | { |
| | | // è·åææ°ç订åæç»æ°æ® |
| | | var currentOrderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .FirstAsync(x => x.Id == orderDetailId); |
| | | |
| | | decimal newOverOutQuantity = currentOrderDetail.OverOutQuantity - cancelQty; |
| | | decimal newPickedQty = currentOrderDetail.PickedQty - cancelQty; |
| | | |
| | | // æ£æ¥åæ¶åæ°éä¸ä¼ä¸ºè´æ° |
| | | if (newOverOutQuantity < 0 || newPickedQty < 0) |
| | | { |
| | | throw new Exception($"忶忣å°å¯¼è´å·²åºåºæ°é({newOverOutQuantity})æå·²æ£éæ°é({newPickedQty})ä¸ºè´æ°"); |
| | | } |
| | | |
| | | await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>() |
| | | .SetColumns(it => new Dt_OutboundOrderDetail |
| | | { |
| | | PickedQty = newPickedQty, |
| | | OverOutQuantity = newOverOutQuantity, |
| | | }) |
| | | .Where(it => it.Id == orderDetailId) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ååºæä½ç§ææ¹æ³ |
| | | |
| | | private async Task<Dt_StockInfo> GetStockInfo(string palletCode) |
| | | { |
| | | return await _stockInfoService.Db.Queryable<Dt_StockInfo>() |
| | | .FirstAsync(x => x.PalletCode == palletCode); |
| | | } |
| | | /// <summary> |
| | | /// æ£æ¥æ´ä¸ªæçæ¯å¦å·²ç»ååº |
| | | /// </summary> |
| | | private async Task<bool> IsPalletReturned(string palletCode) |
| | | { |
| | | var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>() |
| | | .Where(x => x.PalletCode == palletCode) |
| | | .FirstAsync(); |
| | | |
| | | if (stockInfo == null) |
| | | return false; |
| | | |
| | | // 妿æçç¶ææ¯å
¥åºç¡®è®¤æå
¥åºå®æï¼è¯´æå·²ç»ååº |
| | | return stockInfo.StockStatus == StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt() || |
| | | stockInfo.StockStatus == StockStatusEmun.å
¥åºå®æ.ObjToInt(); |
| | | } |
| | | private async Task<Dt_Task> GetCurrentTask(string orderNo, string palletCode) |
| | | { |
| | | // å
å°è¯éè¿è®¢åå·åæçå·æ¥æ¾ä»»å¡ |
| | | var task = await _taskRepository.Db.Queryable<Dt_Task>() |
| | | .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode) |
| | | .FirstAsync(); |
| | | |
| | | if (task == null) |
| | | { |
| | | // 妿æ¾ä¸å°ï¼åéè¿æçå·æ¥æ¾ |
| | | task = await _taskRepository.Db.Queryable<Dt_Task>() |
| | | .Where(x => x.PalletCode == palletCode) |
| | | .FirstAsync(); |
| | | } |
| | | |
| | | return task; |
| | | } |
| | | |
| | | private async Task<ReturnAnalysisResult> AnalyzeReturnItems(string orderNo, string palletCode, int stockId) |
| | | { |
| | | var result = new ReturnAnalysisResult(); |
| | | |
| | | // æ
åµ1ï¼è·åæªåæ£çåºåºéå®è®°å½ |
| | | var remainingLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.OrderNo == orderNo && |
| | | it.PalletCode == palletCode && |
| | | it.Status == (int)OutLockStockStatusEnum.åºåºä¸) |
| | | .ToListAsync(); |
| | | |
| | | if (remainingLocks.Any()) |
| | | { |
| | | result.HasRemainingLocks = true; |
| | | result.RemainingLocks = remainingLocks; |
| | | result.RemainingLocksReturnQty = remainingLocks.Sum(x => x.AssignQuantity - x.PickedQty); |
| | | } |
| | | |
| | | // æ
åµ2ï¼æ£æ¥æç䏿¯å¦æå
¶ä»åºåè´§ç© |
| | | var palletStockGoods = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.StockId == stockId && |
| | | (it.Status == StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt() || |
| | | it.Status == StockStatusEmun.å
¥åºå®æ.ObjToInt() || |
| | | it.Status == StockStatusEmun.åºåºéå®.ObjToInt())) |
| | | .Where(it => it.StockQuantity > 0) |
| | | .ToListAsync(); |
| | | |
| | | if (palletStockGoods.Any()) |
| | | { |
| | | result.HasPalletStockGoods = true; |
| | | result.PalletStockGoods = palletStockGoods; |
| | | result.PalletStockReturnQty = palletStockGoods.Sum(x => x.StockQuantity); |
| | | } |
| | | |
| | | // æ
åµ3ï¼æ£æ¥æå
è®°å½ |
| | | var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>() |
| | | .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && !it.IsReverted && it.Status != (int)SplitPackageStatusEnum.å·²ååº) |
| | | .ToListAsync(); |
| | | |
| | | if (splitRecords.Any()) |
| | | { |
| | | result.HasSplitRecords = true; |
| | | result.SplitRecords = splitRecords; |
| | | result.SplitReturnQty = await CalculateSplitReturnQuantity(splitRecords, stockId); |
| | | } |
| | | |
| | | result.TotalReturnQty = result.RemainingLocksReturnQty + result.PalletStockReturnQty + result.SplitReturnQty; |
| | | result.HasItemsToReturn = result.TotalReturnQty > 0; |
| | | |
| | | return result; |
| | | } |
| | | |
| | | private async Task<decimal> CalculateSplitReturnQuantity(List<Dt_SplitPackageRecord> splitRecords, int stockId) |
| | | { |
| | | decimal totalQty = 0; |
| | | var processedBarcodes = new HashSet<string>(); |
| | | |
| | | foreach (var splitRecord in splitRecords) |
| | | { |
| | | // æ£æ¥åæ¡ç |
| | | if (!processedBarcodes.Contains(splitRecord.OriginalBarcode)) |
| | | { |
| | | var originalStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.Barcode == splitRecord.OriginalBarcode && it.StockId == stockId) |
| | | .FirstAsync(); |
| | | |
| | | if (originalStock != null && originalStock.StockQuantity > 0) |
| | | { |
| | | totalQty += originalStock.StockQuantity; |
| | | processedBarcodes.Add(splitRecord.OriginalBarcode); |
| | | } |
| | | } |
| | | |
| | | // æ£æ¥æ°æ¡ç |
| | | if (!processedBarcodes.Contains(splitRecord.NewBarcode)) |
| | | { |
| | | var newStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.Barcode == splitRecord.NewBarcode && it.StockId == stockId) |
| | | .FirstAsync(); |
| | | |
| | | if (newStock != null && newStock.StockQuantity > 0) |
| | | { |
| | | totalQty += newStock.StockQuantity; |
| | | processedBarcodes.Add(splitRecord.NewBarcode); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return totalQty; |
| | | } |
| | | |
| | | private async Task<WebResponseContent> HandleNoReturnItems(string orderNo, string palletCode,Dt_Task originalTask) |
| | | { |
| | | // æ£æ¥æ¯å¦ææè´§ç©é½å·²æ£é宿 |
| | | var allPicked = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode) |
| | | .AnyAsync(it => it.Status == (int)OutLockStockStatusEnum.æ£é宿); |
| | | |
| | | if (allPicked) |
| | | { |
| | | // å é¤åå§åºåºä»»å¡ |
| | | await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync(); |
| | | return WebResponseContent.Instance.OK("ææè´§ç©å·²æ£éå®æï¼æç为空"); |
| | | } |
| | | else |
| | | { |
| | | // å é¤åå§åºåºä»»å¡ |
| | | await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync(); |
| | | return WebResponseContent.Instance.Error("没æéè¦ååºçå©ä½è´§ç©"); |
| | | } |
| | | //空æçå¦ä½å¤ç è¿æä¸ä¸ªåºåºä»»å¡è¦å¤çã |
| | | |
| | | } |
| | | |
| | | private async Task ExecuteReturnOperations(string orderNo, string palletCode, Dt_StockInfo stockInfo, |
| | | Dt_Task task, ReturnAnalysisResult analysis) |
| | | { |
| | | // æ
åµ1ï¼å¤çæªåæ£çåºåºéå®è®°å½ |
| | | if (analysis.HasRemainingLocks) |
| | | { |
| | | await HandleRemainingLocksReturn(analysis.RemainingLocks, stockInfo.Id); |
| | | |
| | | // å
³é®ï¼æ´æ°è®¢åæç»çå·²æ£éæ°é |
| | | await UpdateOrderDetailsOnReturn(analysis.RemainingLocks); |
| | | } |
| | | |
| | | // å¤çæçä¸å
¶ä»åºåè´§ç© |
| | | if (analysis.HasPalletStockGoods) |
| | | { |
| | | await HandlePalletStockGoodsReturn(analysis.PalletStockGoods); |
| | | } |
| | | |
| | | // å¤çæå
è®°å½ |
| | | if (analysis.HasSplitRecords) |
| | | { |
| | | await HandleSplitRecordsReturn(analysis.SplitRecords, orderNo, palletCode); |
| | | } |
| | | |
| | | // æ´æ°åºåä¸»è¡¨ç¶æ |
| | | await UpdateStockInfoStatus(stockInfo); |
| | | } |
| | | |
| | | private async Task HandleRemainingLocksReturn(List<Dt_OutStockLockInfo> remainingLocks, int stockId) |
| | | { |
| | | var lockIds = remainingLocks.Select(x => x.Id).ToList(); |
| | | |
| | | // æ´æ°åºåºéå®è®°å½ç¶æä¸ºååºä¸ |
| | | await _outStockLockInfoService.Db.Updateable<Dt_OutStockLockInfo>() |
| | | .SetColumns(it => new Dt_OutStockLockInfo |
| | | { |
| | | Status = (int)OutLockStockStatusEnum.ååºä¸, |
| | | }) |
| | | .Where(it => lockIds.Contains(it.Id)) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | // å¤çåºåè®°å½ |
| | | foreach (var lockInfo in remainingLocks) |
| | | { |
| | | decimal returnQty = lockInfo.AssignQuantity - lockInfo.PickedQty; |
| | | |
| | | // æ¥æ¾å¯¹åºçåºåæç» |
| | | var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(it => it.Barcode == lockInfo.CurrentBarcode && it.StockId == lockInfo.StockId) |
| | | .FirstAsync(); |
| | | |
| | | if (stockDetail != null) |
| | | { |
| | | // æ¢å¤åºåç¶æ |
| | | stockDetail.OutboundQuantity = Math.Max(0, stockDetail.OutboundQuantity - returnQty); |
| | | stockDetail.Status = StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt(); |
| | | await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync(); |
| | | } |
| | | else |
| | | { |
| | | // å建æ°çåºåè®°å½ |
| | | var newStockDetail = new Dt_StockInfoDetail |
| | | { |
| | | StockId = lockInfo.StockId, |
| | | MaterielCode = lockInfo.MaterielCode, |
| | | MaterielName = lockInfo.MaterielName, |
| | | OrderNo = lockInfo.OrderNo, |
| | | BatchNo = lockInfo.BatchNo, |
| | | StockQuantity = returnQty, |
| | | OutboundQuantity = 0, |
| | | Barcode = lockInfo.CurrentBarcode, |
| | | InboundOrderRowNo = "", |
| | | Status = StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt(), |
| | | SupplyCode = lockInfo.SupplyCode, |
| | | WarehouseCode = lockInfo.WarehouseCode, |
| | | Unit = lockInfo.Unit, |
| | | }; |
| | | await _stockInfoDetailService.Db.Insertable(newStockDetail).ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private async Task UpdateOrderDetailsOnReturn(List<Dt_OutStockLockInfo> remainingLocks) |
| | | { |
| | | // æè®¢åæç»åç» |
| | | var orderDetailGroups = remainingLocks.GroupBy(x => x.OrderDetailId); |
| | | |
| | | foreach (var group in orderDetailGroups) |
| | | { |
| | | var orderDetailId = group.Key; |
| | | var totalReturnQty = group.Sum(x => x.AssignQuantity - x.PickedQty); |
| | | |
| | | // è·åå½å订åæç» |
| | | var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .FirstAsync(x => x.Id == orderDetailId); |
| | | |
| | | if (orderDetail != null) |
| | | { |
| | | // è°æ´å·²æ£éæ°éåå·²åºåºæ°é |
| | | decimal newPickedQty = Math.Max(0, orderDetail.PickedQty - totalReturnQty); |
| | | decimal newOverOutQuantity = Math.Max(0, orderDetail.OverOutQuantity - totalReturnQty); |
| | | |
| | | await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>() |
| | | .SetColumns(it => new Dt_OutboundOrderDetail |
| | | { |
| | | PickedQty = newPickedQty, |
| | | OverOutQuantity = newOverOutQuantity, |
| | | }) |
| | | .Where(it => it.Id == orderDetailId) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private async Task HandlePalletStockGoodsReturn(List<Dt_StockInfoDetail> palletStockGoods) |
| | | { |
| | | _logger.LogInformation($"ååºæä½ï¼åç°{palletStockGoods.Count}个åºåæç»éè¦ååºï¼çå¾
AGVæ¬è¿"); |
| | | foreach (var stockGood in palletStockGoods) |
| | | { |
| | | _logger.LogInformation($"å¾
ååºè´§ç© - æ¡ç : {stockGood.Barcode}, æ°é: {stockGood.StockQuantity}, å½åç¶æ: {stockGood.Status}"); |
| | | |
| | | // æ¢å¤åºåç¶æ |
| | | stockGood.OutboundQuantity = 0; |
| | | stockGood.Status = StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt(); |
| | | |
| | | await _stockInfoDetailService.Db.Updateable(stockGood).ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | |
| | | private async Task HandleSplitRecordsReturn(List<Dt_SplitPackageRecord> splitRecords, string orderNo, string palletCode) |
| | | { |
| | | // æ´æ°æå
è®°å½ç¶æ |
| | | await _splitPackageService.Db.Updateable<Dt_SplitPackageRecord>() |
| | | .SetColumns(x => new Dt_SplitPackageRecord |
| | | { |
| | | Status = (int)SplitPackageStatusEnum.å·²ååº, |
| | | }) |
| | | .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode && !x.IsReverted) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | |
| | | private async Task UpdateStockInfoStatus(Dt_StockInfo stockInfo) |
| | | { |
| | | _logger.LogInformation($"ååºæä½ï¼æç{stockInfo.PalletCode}çå¾
AGVååºæ¬è¿"); |
| | | // æ´æ°åºåä¸»è¡¨ç¶æ |
| | | stockInfo.StockStatus = StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt(); |
| | | await _stockInfoService.Db.Updateable(stockInfo).ExecuteCommandAsync(); |
| | | } |
| | | /// <summary> |
| | | /// å建ååºä»»å¡ |
| | | /// </summary> |
| | | /// <param name="orderNo"></param> |
| | | /// <param name="palletCode"></param> |
| | | /// <param name="originalTask"></param> |
| | | /// <param name="analysis"></param> |
| | | /// <returns></returns> |
| | | private async Task CreateReturnTaskAndHandleESS(string orderNo, string palletCode, Dt_Task originalTask, ReturnAnalysisResult analysis) |
| | | { |
| | | var firstLocation = await _locationInfoService.Db.Queryable<Dt_LocationInfo>() |
| | | .FirstAsync(x => x.LocationCode == originalTask.SourceAddress); |
| | | |
| | | // åé
æ°è´§ä½ |
| | | var newLocation = _locationInfoService.AssignLocation(firstLocation.LocationType); |
| | | |
| | | Dt_Task returnTask = new() |
| | | { |
| | | CurrentAddress = stations[originalTask.TargetAddress], |
| | | Grade = 0, |
| | | PalletCode = palletCode, |
| | | NextAddress = "", |
| | | OrderNo = originalTask.OrderNo, |
| | | Roadway = newLocation.RoadwayNo, |
| | | SourceAddress = stations[originalTask.TargetAddress], |
| | | TargetAddress = newLocation.LocationCode, |
| | | TaskStatus = TaskStatusEnum.New.ObjToInt(), |
| | | TaskType = TaskTypeEnum.InPick.ObjToInt(), |
| | | PalletType = originalTask.PalletType, |
| | | WarehouseId = originalTask.WarehouseId |
| | | |
| | | }; |
| | | // ä¿åååºä»»å¡ |
| | | await _taskRepository.Db.Insertable(returnTask).ExecuteCommandAsync(); |
| | | var targetAddress = originalTask.TargetAddress; |
| | | |
| | | // å é¤åå§åºåºä»»å¡ |
| | | await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync(); |
| | | |
| | | // ç» ESS åéæµå¨ä¿¡å·ååå»ºä»»å¡ |
| | | await SendESSCommands(palletCode, targetAddress, returnTask); |
| | | } |
| | | /// <summary> |
| | | /// ç»ESSä¸ä»»å¡ |
| | | /// </summary> |
| | | /// <param name="palletCode"></param> |
| | | /// <param name="targetAddress"></param> |
| | | /// <param name="returnTask"></param> |
| | | /// <returns></returns> |
| | | /// <exception cref="Exception"></exception> |
| | | private async Task SendESSCommands(string palletCode, string targetAddress, Dt_Task returnTask) |
| | | { |
| | | try |
| | | { |
| | | // 1. åéæµå¨ä¿¡å· |
| | | var moveResult = await _eSSApiService.MoveContainerAsync(new WIDESEA_DTO.Basic.MoveContainerRequest |
| | | { |
| | | slotCode = movestations[targetAddress], |
| | | containerCode = palletCode |
| | | }); |
| | | |
| | | if (moveResult) |
| | | { |
| | | // 2. å建ååºä»»å¡ |
| | | var essTask = new TaskModel() |
| | | { |
| | | taskType = "putaway", |
| | | taskGroupCode = "", |
| | | groupPriority = 0, |
| | | tasks = new List<TasksType> |
| | | { |
| | | new() |
| | | { |
| | | taskCode = returnTask.TaskNum.ToString(), |
| | | taskPriority = 0, |
| | | taskDescribe = new TaskDescribeType |
| | | { |
| | | containerCode = palletCode, |
| | | containerType = "CT_KUBOT_STANDARD", |
| | | fromLocationCode = stations.GetValueOrDefault(targetAddress) ?? "", |
| | | toStationCode = "", |
| | | toLocationCode = returnTask.TargetAddress, |
| | | deadline = 0, |
| | | storageTag = "" |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | |
| | | var resultTask = await _eSSApiService.CreateTaskAsync(essTask); |
| | | _logger.LogInformation($"ReturnRemaining åå»ºä»»å¡æå: {resultTask}"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError($"ReturnRemaining ESSå½ä»¤åé失败: {ex.Message}"); |
| | | throw new Exception($"ESSç³»ç»é信失败: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region 订åç¶æç®¡ç |
| | | |
| | | private async Task CheckAndUpdateOrderStatus(string orderNo) |
| | | { |
| | | try |
| | | { |
| | | var orderDetails = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id) |
| | | .Where((o, item) => item.OrderNo == orderNo) |
| | | .Select((o, item) => o) |
| | | .ToListAsync(); |
| | | |
| | | bool allCompleted = true; |
| | | foreach (var detail in orderDetails) |
| | | { |
| | | if (detail.OverOutQuantity < detail.NeedOutQuantity) |
| | | { |
| | | allCompleted = false; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>() |
| | | .FirstAsync(x => x.OrderNo == orderNo); |
| | | |
| | | if (outboundOrder == null) return; |
| | | |
| | | int newStatus = allCompleted ? (int)OutOrderStatusEnum.åºåºå®æ : (int)OutOrderStatusEnum.åºåºä¸; |
| | | |
| | | if (outboundOrder.OrderStatus != newStatus) |
| | | { |
| | | await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>() |
| | | .SetColumns(x => x.OrderStatus == newStatus) |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | // åªææ£å¸¸åæ£å®ææ¶æåMESåé¦ |
| | | if (allCompleted && newStatus == (int)OutOrderStatusEnum.åºåºå®æ) |
| | | { |
| | | await HandleOrderCompletion(outboundOrder, orderNo); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError($"CheckAndUpdateOrderStatus失败 - OrderNo: {orderNo}, Error: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | private async Task UpdateOrderStatusForReturn(string orderNo) |
| | | { |
| | | try |
| | | { |
| | | var orderDetails = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>() |
| | | .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id) |
| | | .Where((o, item) => item.OrderNo == orderNo) |
| | | .Select((o, item) => o) |
| | | .ToListAsync(); |
| | | |
| | | bool allCompleted = true; |
| | | foreach (var detail in orderDetails) |
| | | { |
| | | if (detail.OverOutQuantity < detail.NeedOutQuantity) |
| | | { |
| | | allCompleted = false; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>() |
| | | .FirstAsync(x => x.OrderNo == orderNo); |
| | | |
| | | if (outboundOrder == null) return; |
| | | |
| | | int newStatus = allCompleted ? (int)OutOrderStatusEnum.åºåºå®æ : (int)OutOrderStatusEnum.åºåºä¸; |
| | | |
| | | if (outboundOrder.OrderStatus != newStatus) |
| | | { |
| | | await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>() |
| | | .SetColumns(x => x.OrderStatus == newStatus) |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | _logger.LogInformation($"ååºæä½æ´æ°è®¢åç¶æ - OrderNo: {orderNo}, æ°ç¶æ: {newStatus}"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError($"UpdateOrderStatusForReturn失败 - OrderNo: {orderNo}, Error: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | private async Task HandleOrderCompletion(Dt_OutboundOrder outboundOrder, string orderNo) |
| | | { |
| | | // è°æ¨åºåºå鿣åºåºä¸éè¦åé¦MES |
| | | if (outboundOrder.OrderType == OutOrderTypeEnum.Allocate.ObjToInt() || |
| | | outboundOrder.OrderType == OutOrderTypeEnum.ReCheck.ObjToInt()) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | try |
| | | { |
| | | var feedmodel = new FeedbackOutboundRequestModel |
| | | { |
| | | reqCode = Guid.NewGuid().ToString(), |
| | | reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), |
| | | business_type = outboundOrder.BusinessType, |
| | | factoryArea = outboundOrder.FactoryArea, |
| | | operationType = 1, |
| | | Operator = App.User.UserName, |
| | | orderNo = outboundOrder.UpperOrderNo, |
| | | status = outboundOrder.OrderStatus, |
| | | details = new List<FeedbackOutboundDetailsModel>() |
| | | }; |
| | | |
| | | // åªè·åå·²æ£é宿çéå®è®°å½ |
| | | var lists = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(x => x.OrderNo == orderNo && x.Status == (int)OutLockStockStatusEnum.æ£é宿) |
| | | .ToListAsync(); |
| | | |
| | | var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.lineNo, item.Unit, item.WarehouseCode }) |
| | | .Select(group => new FeedbackOutboundDetailsModel |
| | | { |
| | | materialCode = group.Key.MaterielCode, |
| | | lineNo = group.Key.lineNo, |
| | | warehouseCode = group.Key.WarehouseCode, |
| | | qty = group.Sum(x => x.PickedQty), |
| | | currentDeliveryQty = group.Sum(x => x.PickedQty), |
| | | unit = group.Key.Unit, |
| | | barcodes = group.Select(row => new WIDESEA_DTO.Outbound.BarcodesModel |
| | | { |
| | | barcode = row.CurrentBarcode, |
| | | supplyCode = row.SupplyCode, |
| | | batchNo = row.BatchNo, |
| | | unit = row.Unit, |
| | | qty = row.PickedQty |
| | | }).ToList() |
| | | }).ToList(); |
| | | |
| | | feedmodel.details = groupedData; |
| | | |
| | | var result = await _invokeMESService.FeedbackOutbound(feedmodel); |
| | | if (result != null && result.code == 200) |
| | | { |
| | | await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>() |
| | | .SetColumns(x => x.ReturnToMESStatus == 1) |
| | | .Where(x => x.OrderId == outboundOrder.Id) |
| | | .ExecuteCommandAsync(); |
| | | |
| | | await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>() |
| | | .SetColumns(x => x.ReturnToMESStatus == 1) |
| | | .Where(x => x.OrderNo == orderNo) |
| | | .ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError($"FeedbackOutbound失败 - OrderNo: {orderNo}, Error: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region è¾
婿¹æ³ |
| | | |
| | | private async Task<string> GenerateNewBarcode() |
| | | { |
| | | var seq = await _dailySequenceService.GetNextSequenceAsync(); |
| | | return "WSLOT" + DateTime.Now.ToString("yyyyMMdd") + seq.ToString()?.PadLeft(5, '0'); |
| | | } |
| | | |
| | | private async Task<Dt_OutStockLockInfo> CreateSplitLockInfo(Dt_OutStockLockInfo originalLock, decimal quantity, string newBarcode) |
| | | { |
| | | var newLockInfo = new Dt_OutStockLockInfo |
| | | { |
| | | OrderNo = originalLock.OrderNo, |
| | | OrderDetailId = originalLock.OrderDetailId, |
| | | BatchNo = originalLock.BatchNo, |
| | | MaterielCode = originalLock.MaterielCode, |
| | | MaterielName = originalLock.MaterielName, |
| | | StockId = originalLock.StockId, |
| | | OrderQuantity = quantity, |
| | | OriginalQuantity = quantity, |
| | | AssignQuantity = quantity, |
| | | PickedQty = quantity, |
| | | LocationCode = originalLock.LocationCode, |
| | | PalletCode = originalLock.PalletCode, |
| | | TaskNum = originalLock.TaskNum, |
| | | Status = (int)OutLockStockStatusEnum.æ£é宿, |
| | | Unit = originalLock.Unit, |
| | | SupplyCode = originalLock.SupplyCode, |
| | | OrderType = originalLock.OrderType, |
| | | CurrentBarcode = newBarcode, |
| | | OriginalLockQuantity = quantity, |
| | | IsSplitted = 1, |
| | | ParentLockId = originalLock.Id, |
| | | Operator= App.User.UserName, |
| | | FactoryArea=originalLock.FactoryArea, |
| | | lineNo=originalLock.lineNo, |
| | | WarehouseCode=originalLock.WarehouseCode, |
| | | |
| | | }; |
| | | |
| | | var newLockId = await _outStockLockInfoService.Db.Insertable(newLockInfo).ExecuteReturnIdentityAsync(); |
| | | newLockInfo.Id = newLockId; |
| | | return newLockInfo; |
| | | } |
| | | |
| | | private async Task RecordSplitHistory(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail, |
| | | decimal splitQty, decimal remainQty, string newBarcode) |
| | | { |
| | | var splitHistory = new Dt_SplitPackageRecord |
| | | { |
| | | FactoryArea = lockInfo.FactoryArea, |
| | | TaskNum = lockInfo.TaskNum, |
| | | OutStockLockInfoId = lockInfo.Id, |
| | | StockId = stockDetail.StockId, |
| | | Operator = App.User.UserName, |
| | | IsReverted = false, |
| | | OriginalBarcode = stockDetail.Barcode, |
| | | NewBarcode = newBarcode, |
| | | SplitQty = splitQty, |
| | | RemainQuantity = remainQty, |
| | | MaterielCode = lockInfo.MaterielCode, |
| | | SplitTime = DateTime.Now, |
| | | OrderNo = lockInfo.OrderNo, |
| | | PalletCode = lockInfo.PalletCode, |
| | | Status = (int)SplitPackageStatusEnum.å·²æ£é |
| | | }; |
| | | |
| | | await _splitPackageService.Db.Insertable(splitHistory).ExecuteCommandAsync(); |
| | | } |
| | | |
| | | private List<SplitResult> CreateSplitResults(Dt_OutStockLockInfo lockInfo, decimal splitQty, decimal remainQty, string newBarcode, string originalBarcode) |
| | | { |
| | | return new List<SplitResult> |
| | | { |
| | | new SplitResult |
| | | { |
| | | materialCode = lockInfo.MaterielCode, |
| | | supplierCode = lockInfo.SupplyCode, |
| | | quantityTotal = splitQty.ToString("F2"), |
| | | batchNumber = newBarcode, |
| | | batch = lockInfo.BatchNo, |
| | | factory = lockInfo.FactoryArea, |
| | | date = DateTime.Now.ToString("yyyy-MM-dd"), |
| | | }, |
| | | new SplitResult |
| | | { |
| | | materialCode = lockInfo.MaterielCode, |
| | | supplierCode = lockInfo.SupplyCode, |
| | | quantityTotal = remainQty.ToString("F2"), |
| | | batchNumber = originalBarcode, |
| | | batch = lockInfo.BatchNo, |
| | | factory = lockInfo.FactoryArea, |
| | | date = DateTime.Now.ToString("yyyy-MM-dd"), |
| | | } |
| | | }; |
| | | } |
| | | |
| | | private async Task UpdateSplitRecordsStatus(string barcode) |
| | | { |
| | | var relatedSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>() |
| | | .Where(it => it.OriginalBarcode == barcode || it.NewBarcode == barcode) |
| | | .Where(it => !it.IsReverted) |
| | | .ToListAsync(); |
| | | |
| | | foreach (var record in relatedSplitRecords) |
| | | { |
| | | record.Status = (int)SplitPackageStatusEnum.å·²æ£é; |
| | | await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync(); |
| | | } |
| | | } |
| | | |
| | | private async Task<int> GenerateTaskNumber() |
| | | { |
| | | return await _dailySequenceService.GetNextSequenceAsync(); |
| | | } |
| | | |
| | | private WebResponseContent CreatePickingResponse(PickingResult result, string adjustedReason) |
| | | { |
| | | //if (result.SplitResults.Any()) |
| | | //{ |
| | | // var responseData = new { SplitResults = result.SplitResults, AdjustedReason = "" }; |
| | | // if (!string.IsNullOrEmpty(adjustedReason)) |
| | | // { |
| | | // responseData = new { SplitResults = result.SplitResults, AdjustedReason = adjustedReason }; |
| | | // } |
| | | // return WebResponseContent.Instance.OK("æ£é确认æåï¼å·²èªå¨æå
", responseData); |
| | | //} |
| | | |
| | | //if (!string.IsNullOrEmpty(adjustedReason)) |
| | | //{ |
| | | // return WebResponseContent.Instance.OK($"æ£é确认æåï¼{adjustedReason}ï¼"); |
| | | //} |
| | | |
| | | //return WebResponseContent.Instance.OK("æ£é确认æå"); |
| | | |
| | | if (result.SplitResults.Any()) |
| | | { |
| | | return WebResponseContent.Instance.OK("æ£é确认æåï¼å·²èªå¨æå
", new { SplitResults = result.SplitResults }); |
| | | } |
| | | return WebResponseContent.Instance.OK("æ£é确认æå", new { SplitResults = new List<SplitResult>() }); |
| | | } |
| | | |
| | | #endregion |
| | | } |
| | | |
| | | #region æ¯æç±»å®ä¹ |
| | | |
| | | public class ValidationResult<T> |
| | | { |
| | | public bool IsValid { get; set; } |
| | | public T Data { get; set; } |
| | | public string ErrorMessage { get; set; } |
| | | |
| | | public static ValidationResult<T> Success(T data) |
| | | { |
| | | return new ValidationResult<T> |
| | | { |
| | | IsValid = true, |
| | | Data = data |
| | | }; |
| | | } |
| | | |
| | | public static ValidationResult<T> Error(string message) |
| | | { |
| | | return new ValidationResult<T> |
| | | { |
| | | IsValid = false, |
| | | ErrorMessage = message |
| | | }; |
| | | } |
| | | } |
| | | |
| | | public class PickingResult |
| | | { |
| | | public Dt_OutStockLockInfo FinalLockInfo { get; set; } |
| | | public string FinalBarcode { get; set; } |
| | | public int FinalStockId { get; set; } |
| | | public decimal ActualPickedQty { get; set; } |
| | | public List<SplitResult> SplitResults { get; set; } = new List<SplitResult>(); |
| | | } |
| | | |
| | | public class ReturnAnalysisResult |
| | | { |
| | | public bool HasItemsToReturn { get; set; } |
| | | public bool HasRemainingLocks { get; set; } |
| | | public bool HasPalletStockGoods { get; set; } |
| | | public bool HasSplitRecords { get; set; } |
| | | public decimal RemainingLocksReturnQty { get; set; } |
| | | public decimal PalletStockReturnQty { get; set; } |
| | | public decimal SplitReturnQty { get; set; } |
| | | public decimal TotalReturnQty { get; set; } |
| | | public List<Dt_OutStockLockInfo> RemainingLocks { get; set; } = new List<Dt_OutStockLockInfo>(); |
| | | public List<Dt_StockInfoDetail> PalletStockGoods { get; set; } = new List<Dt_StockInfoDetail>(); |
| | | public List<Dt_SplitPackageRecord> SplitRecords { get; set; } = new List<Dt_SplitPackageRecord>(); |
| | | } |
| | | |
| | | #endregion |
| | | } |
| | |
| | | using WIDESEA_IOutboundService; |
| | | using WIDESEA_IStockService; |
| | | using WIDESEA_Model.Models; |
| | | using WIDESEA_Model.Models.Basic; |
| | | |
| | | namespace WIDESEA_OutboundService |
| | | { |
| | |
| | | private readonly IOutStockLockInfoService _outStockLockInfoService; |
| | | private readonly IDailySequenceService _dailySequenceService; |
| | | private readonly IInvokeMESService _invokeMESService; |
| | | |
| | | private readonly IMaterielToMesService _materielToMesService; |
| | | private readonly ILogger<SplitPackageService> _logger; |
| | | public SplitPackageService(IRepository<Dt_SplitPackageRecord> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, IOutStockLockInfoService outStockLockInfoService, IStockInfoDetailService stockInfoDetailService, IDailySequenceService dailySequenceService, IInvokeMESService invokeMESService, ILogger<SplitPackageService> logger) : base(BaseDal) |
| | | public SplitPackageService(IRepository<Dt_SplitPackageRecord> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, IOutStockLockInfoService outStockLockInfoService, IStockInfoDetailService stockInfoDetailService, IDailySequenceService dailySequenceService, IInvokeMESService invokeMESService, ILogger<SplitPackageService> logger, IMaterielToMesService materielToMesService) : base(BaseDal) |
| | | { |
| | | _unitOfWorkManage = unitOfWorkManage; |
| | | _stockInfoService = stockInfoService; |
| | |
| | | _dailySequenceService = dailySequenceService; |
| | | _invokeMESService = invokeMESService; |
| | | _logger = logger; |
| | | _materielToMesService = materielToMesService; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æå
æç®±æä½ |
| | | /// </summary> |
| | | //public async Task<WebResponseContent> SplitPackage(SplitPackageDto request) |
| | | //{ |
| | | // try |
| | | // { |
| | | // _unitOfWorkManage.BeginTran(); |
| | | |
| | | // // 1. éªè¯åºåºéå®ä¿¡æ¯ |
| | | // var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | // .Where(x => x.OrderNo == request.OrderNo && |
| | | // x.PalletCode == request.PalletCode && |
| | | // x.CurrentBarcode == request.OriginalBarcode && |
| | | // x.Status == 1) |
| | | // .FirstAsync(); |
| | | |
| | | // if (lockInfo == null) |
| | | // return WebResponseContent.Instance.Error("æªæ¾å°ææçåºåºéå®ä¿¡æ¯"); |
| | | |
| | | // // 2. æ£æ¥å©ä½é宿°é |
| | | // decimal remainingLockQuantity = lockInfo.OriginalQuantity - lockInfo.PickedQty; |
| | | // if (request.SplitQuantity > remainingLockQuantity) |
| | | // return WebResponseContent.Instance.Error($"æå
æ°éä¸è½å¤§äºå©ä½é宿°éï¼å©ä½ï¼{remainingLockQuantity}"); |
| | | |
| | | // var baseStockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | // .Where(x => x.Barcode == request.OriginalBarcode && x.StockId == lockInfo.StockId) |
| | | // .FirstAsync(); |
| | | // if (baseStockDetail == null) |
| | | // throw new Exception($"æªæ¾å°æ¡ç {request.OriginalBarcode}对åºçåºåè®°å½"); |
| | | |
| | | |
| | | // // 4. è®¡ç®æååçæ°é |
| | | // decimal remainingQty = baseStockDetail.StockQuantity - request.SplitQuantity; |
| | | |
| | | // // æ´æ°åºç¡æ¡ç çåºåæ°é为å©ä½æ°é |
| | | // baseStockDetail.StockQuantity = remainingQty; |
| | | // baseStockDetail.OutboundQuantity = remainingQty; |
| | | // await _stockInfoDetailService.Db.Updateable(baseStockDetail).ExecuteCommandAsync(); |
| | | |
| | | |
| | | // var seq = await _dailySequenceService.GetNextSequenceAsync(); |
| | | // // 3. çææ°æ¡ç |
| | | // string newBarcode = "WSLOT" + DateTime.Now.ToString("yyyyMMdd") + seq.ToString()?.PadLeft(5, '0'); |
| | | |
| | | |
| | | // // 为æå
产ççæ°æ¡ç å建åºåè®°å½ |
| | | // var newStockDetail = new Dt_StockInfoDetail |
| | | // { |
| | | // SupplyCode = baseStockDetail.SupplyCode, |
| | | // WarehouseCode = baseStockDetail.WarehouseCode, |
| | | // BarcodeQty = baseStockDetail.BarcodeQty, |
| | | // BarcodeUnit = baseStockDetail.BarcodeUnit, |
| | | // BusinessType = baseStockDetail.BusinessType, |
| | | // Unit = baseStockDetail.Unit, |
| | | // StockId = lockInfo.StockId, |
| | | // MaterielCode = baseStockDetail.MaterielCode, |
| | | // OrderNo = baseStockDetail.OrderNo, |
| | | // BatchNo = baseStockDetail.BatchNo, |
| | | // StockQuantity = request.SplitQuantity, // æ°æ¡ç è·å¾æåæ°é |
| | | // OutboundQuantity = request.SplitQuantity, |
| | | // Barcode = newBarcode, |
| | | // InboundOrderRowNo = baseStockDetail.InboundOrderRowNo, |
| | | |
| | | // }; |
| | | // await _outStockLockInfoService.Db.Insertable(newStockDetail).ExecuteCommandAsync(); |
| | | |
| | | // // 4. å建æ°çåºåºéå®ä¿¡æ¯ï¼æ°æ¡ç ï¼ |
| | | // var newLockInfo = new Dt_OutStockLockInfo |
| | | // { |
| | | |
| | | // OrderNo = lockInfo.OrderNo, |
| | | // OrderDetailId = lockInfo.OrderDetailId, |
| | | // BatchNo = lockInfo.BatchNo, |
| | | // MaterielCode = lockInfo.MaterielCode, |
| | | // MaterielName = lockInfo.MaterielName, |
| | | // StockId = lockInfo.StockId, |
| | | // OrderQuantity = request.SplitQuantity, |
| | | // OriginalQuantity = request.SplitQuantity, |
| | | // AssignQuantity = request.SplitQuantity, // æ°æ¡ç åé
æ°é |
| | | // PickedQty = 0, // æ°æ¡ç æªæ£é |
| | | // LocationCode = lockInfo.LocationCode, |
| | | // PalletCode = lockInfo.PalletCode, |
| | | // TaskNum = lockInfo.TaskNum, |
| | | // Status = (int)OutLockStockStatusEnum.åºåºä¸, |
| | | // Unit = lockInfo.Unit, |
| | | // SupplyCode = lockInfo.SupplyCode, |
| | | // OrderType = lockInfo.OrderType, |
| | | // CurrentBarcode = newBarcode, // æ°æ¡ç |
| | | // OriginalLockQuantity = request.SplitQuantity, |
| | | // IsSplitted = 1, |
| | | // ParentLockId = lockInfo.Id // è®°å½ç¶çº§éå®ID |
| | | // }; |
| | | // await _outStockLockInfoService.Db.Insertable(newLockInfo).ExecuteCommandAsync(); |
| | | |
| | | // lockInfo.AssignQuantity = remainingQty; |
| | | // lockInfo.IsSplitted = 1; // æ 记为已æå
|
| | | // await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync(); |
| | | |
| | | // var previousSplitRecord = await Db.Queryable<Dt_SplitPackageRecord>() |
| | | // .Where(x => x.OriginalBarcode == request.OriginalBarcode && !x.IsReverted) |
| | | // .OrderByDescending(x => x.SplitTime) |
| | | // .FirstAsync(); |
| | | |
| | | // // 6. è®°å½æå
åå²ï¼ç¨äºè¿½è¸ªï¼ |
| | | // var splitHistory = new Dt_SplitPackageRecord |
| | | // { |
| | | // FactoryArea = lockInfo.FactoryArea, |
| | | // TaskNum = lockInfo.TaskNum, |
| | | // OutStockLockInfoId = lockInfo.Id, |
| | | // StockId = baseStockDetail.StockId, |
| | | // Operator = App.User.UserName, |
| | | // IsReverted = false, |
| | | // OriginalBarcode = request.OriginalBarcode, |
| | | // NewBarcode = newBarcode, |
| | | // SplitQty = request.SplitQuantity, |
| | | // RemainQuantity = remainingQty, // è®°å½æååçå©ä½æ°é |
| | | // MaterielCode = lockInfo.MaterielCode, |
| | | // SplitTime = DateTime.Now, |
| | | // OrderNo = request.OrderNo, |
| | | // PalletCode = request.PalletCode, |
| | | // Status = (int)SplitPackageStatusEnum.å·²æå
, |
| | | // PreviousSplitRecordId = previousSplitRecord?.Id??0 // è®°å½å䏿¬¡æå
IDï¼å»ºç«æå
é¾ |
| | | // }; |
| | | // await Db.Insertable(splitHistory).ExecuteCommandAsync(); |
| | | |
| | | // _unitOfWorkManage.CommitTran(); |
| | | |
| | | // try |
| | | // { |
| | | // MaterielToMesDTO dto = new MaterielToMesDTO |
| | | // { |
| | | // batchNo = baseStockDetail.BatchNo, |
| | | // factoryArea = baseStockDetail.FactoryArea, |
| | | // materialCode = baseStockDetail.MaterielCode, |
| | | // newmaterialCode = newBarcode, |
| | | // oldmaterialCode = request.OriginalBarcode, |
| | | // operationType = 1, |
| | | // qty = remainingQty, |
| | | // supplyCode = baseStockDetail.SupplyCode, |
| | | // unit = baseStockDetail.BarcodeUnit, |
| | | // warehouseCode = baseStockDetail.WarehouseCode, |
| | | // reqCode = Guid.NewGuid().ToString(), |
| | | // reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") |
| | | // }; |
| | | // _invokeMESService.NewMaterielToMes(dto); |
| | | // } |
| | | // catch(Exception ex) |
| | | // { |
| | | // _logger.LogError("SplitPackage åä¼ MES: " + ex.Message); |
| | | // } |
| | | // return WebResponseContent.Instance.OK("æå
æå", new |
| | | // { |
| | | // NewBarcode = newBarcode, |
| | | // NewLockInfoId = newLockInfo.Id |
| | | // }); |
| | | // } |
| | | // catch (Exception ex) |
| | | // { |
| | | // _unitOfWorkManage.RollbackTran(); |
| | | // return WebResponseContent.Instance.Error($"æå
失败: {ex.Message}"); |
| | | // } |
| | | //} |
| | | // è·åæ¡ç çæå
åå²é¾ |
| | | |
| | | public async Task<WebResponseContent> SplitPackage(SplitPackageDto request) |
| | | { |
| | |
| | | CurrentBarcode = newBarcode, |
| | | OriginalLockQuantity = request.SplitQuantity, |
| | | IsSplitted = 1, |
| | | ParentLockId = lockInfo.Id |
| | | ParentLockId = lockInfo.Id, |
| | | Operator = App.User.UserName, |
| | | FactoryArea = lockInfo.FactoryArea, |
| | | lineNo = lockInfo.lineNo, |
| | | WarehouseCode = lockInfo.WarehouseCode, |
| | | }; |
| | | await _outStockLockInfoService.Db.Insertable(newLockInfo).ExecuteCommandAsync(); |
| | | |
| | |
| | | await Db.Insertable(splitHistory).ExecuteCommandAsync(); |
| | | |
| | | _unitOfWorkManage.CommitTran(); |
| | | |
| | | try |
| | | { |
| | | |
| | | var dt_MaterielToMes = new Dt_MaterielToMes |
| | | { |
| | | OldMaterialBarCode = request.OriginalBarcode, |
| | | NewMaterialBarCode = newBarcode, |
| | | Unit = baseStockDetail.BarcodeUnit, |
| | | factoryArea = baseStockDetail.FactoryArea, |
| | | Qty = remainingQty, |
| | | supplyCode = baseStockDetail.SupplyCode, |
| | | warehouseCode = baseStockDetail.WarehouseCode, |
| | | BatchNo = baseStockDetail.BatchNo, |
| | | MaterielCode = baseStockDetail.MaterielCode, |
| | | |
| | | }; |
| | | _materielToMesService.AddData(dt_MaterielToMes); |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError("SplitPackage åä¼ MES: " + ex.Message); |
| | | } |
| | | |
| | | return WebResponseContent.Instance.OK("æå
æå", new SplitPackageChainDto |
| | | { |
| | |
| | | { |
| | | record.IsReverted = true; |
| | | record.RevertTime = DateTime.Now; |
| | | |
| | | |
| | | record.Status = (int)SplitPackageStatusEnum.å·²æ¤é; |
| | | } |
| | | await Db.Updateable(splitRecords).ExecuteCommandAsync(); |
| | |
| | | // è·å坿¤éçæå
è®°å½å表 |
| | | public Dt_SplitPackageRecord GetRevertableSplitRecords(string originalBarcode) |
| | | { |
| | | var revertableRecords = Db.Queryable<Dt_SplitPackageRecord>() |
| | | var revertableRecords = Db.Queryable<Dt_SplitPackageRecord>() |
| | | .Where(x => x.OriginalBarcode == originalBarcode && !x.IsReverted) |
| | | .OrderBy(x => x.SplitTime) |
| | | .First(); |
| | | |
| | | return revertableRecords ; |
| | | return revertableRecords; |
| | | } |
| | | |
| | | |
| | | // è·åæå
ä¿¡æ¯ |
| | | public async Task<WebResponseContent> GetSplitPackageInfo(string orderNo, string palletCode, string barcode) |
| | | { |
| | |
| | | return Db.Queryable<Dt_StockInfo>().Where(x => x.StockStatus == StockStatusEmun.å
¥åºå®æ.ObjToInt() && SqlFunc.Subqueryable<Dt_LocationInfo>().Where(v => v.LocationCode == x.LocationCode && v.LocationType == locationType && v.LocationStatus == LocationStatusEnum.Pallet.ObjToInt() && (v.EnableStatus == EnableStatusEnum.OnlyOut.ObjToInt() || EnableStatusEnum.Normal.ObjToInt() == v.EnableStatus)).Any()).OrderBy(x => x.ModifyDate).First(); |
| | | } |
| | | |
| | | public List<Dt_StockInfo> GetStockInfosByPalletCodes(List<string> palletCodes) |
| | | { |
| | | return Db.Queryable<Dt_StockInfo>().Where(x => palletCodes.Contains(x.PalletCode)).Includes(x => x.Details).ToList(); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// |
| | | /// </summary> |
| | |
| | | using WIDESEA_Core.BaseServices; |
| | | using WIDESEA_Core.Enums; |
| | | using WIDESEA_Core.Helper; |
| | | using WIDESEA_DTO.Allocate; |
| | | using WIDESEA_DTO.Basic; |
| | | using WIDESEA_DTO.Inbound; |
| | | using WIDESEA_DTO.Task; |
| | | using WIDESEA_IAllocateService; |
| | | using WIDESEA_IBasicService; |
| | | using WIDESEA_IInboundService; |
| | | using WIDESEA_IOutboundService; |
| | |
| | | private readonly IESSApiService _eSSApiService; |
| | | private readonly IStockService _stockService; |
| | | private readonly IRecordService _recordService; |
| | | |
| | | private readonly IAllocateService _allocateService; |
| | | private readonly IInvokeMESService _invokeMESService; |
| | | public IRepository<Dt_Task> Repository => BaseDal; |
| | | |
| | |
| | | |
| | | public List<int> TaskOutboundTypes => typeof(TaskTypeEnum).GetEnumIndexList(); |
| | | |
| | | public TaskService(IRepository<Dt_Task> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_StockInfo> stockRepository, ILocationInfoService locationInfoService, IInboundOrderService inboundOrderService, ILocationStatusChangeRecordService locationStatusChangeRecordService, IESSApiService eSSApiService, ILogger<TaskService> logger, IStockService stockService, IRecordService recordService, IInboundOrderDetailService inboundOrderDetailService, IOutboundOrderService outboundOrderService, IOutboundOrderDetailService outboundOrderDetailService, IInvokeMESService invokeMESService, IOutStockLockInfoService outStockLockInfoService) : base(BaseDal) |
| | | public TaskService(IRepository<Dt_Task> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_StockInfo> stockRepository, ILocationInfoService locationInfoService, IInboundOrderService inboundOrderService, ILocationStatusChangeRecordService locationStatusChangeRecordService, IESSApiService eSSApiService, ILogger<TaskService> logger, IStockService stockService, IRecordService recordService, IInboundOrderDetailService inboundOrderDetailService, IOutboundOrderService outboundOrderService, IOutboundOrderDetailService outboundOrderDetailService, IInvokeMESService invokeMESService, IOutStockLockInfoService outStockLockInfoService, IAllocateService allocateService) : base(BaseDal) |
| | | { |
| | | _mapper = mapper; |
| | | _unitOfWorkManage = unitOfWorkManage; |
| | |
| | | _outboundOrderDetailService = outboundOrderDetailService; |
| | | _invokeMESService = invokeMESService; |
| | | _outStockLockInfoService = outStockLockInfoService; |
| | | _allocateService = allocateService; |
| | | } |
| | | |
| | | |
| | |
| | | { |
| | | if (inboundOrder.OrderType == InOrderTypeEnum.Allocat.ObjToInt())//è°æ¨å
¥åº |
| | | { |
| | | if (inboundOrder != null && inboundOrder.OrderStatus == InOrderStatusEnum.å
¥åºå®æ.ObjToInt()) |
| | | { |
| | | var allocate = _allocateService.Repository.QueryData(x => x.OrderNo == inboundOrder.InboundOrderNo).First(); |
| | | var feedmodel = new AllocateDto |
| | | { |
| | | ReqCode = Guid.NewGuid().ToString(), |
| | | ReqTime = DateTime.Now.ToString(), |
| | | BusinessType = "2", |
| | | FactoryArea = inboundOrder.FactoryArea, |
| | | OperationType = 1, |
| | | Operator = inboundOrder.Operator, |
| | | OrderNo = inboundOrder.UpperOrderNo, |
| | | fromWarehouse = allocate?.FromWarehouse??"", |
| | | toWarehouse = allocate?.ToWarehouse??"", |
| | | Details = new List<AllocateDtoDetail>() |
| | | |
| | | }; |
| | | |
| | | var groupedData = inboundOrder.Details.GroupBy(item => new { item.MaterielCode, item.SupplyCode, item.BatchNo, item.lineNo, item.BarcodeUnit, item.WarehouseCode }) |
| | | .Select(group => new AllocateDtoDetail |
| | | { |
| | | MaterialCode = group.Key.MaterielCode, |
| | | LineNo = group.Key.lineNo, |
| | | WarehouseCode = group.Key.WarehouseCode, |
| | | Qty = group.Sum(x => x.BarcodeQty), |
| | | // warehouseCode= "1072", |
| | | Unit = group.Key.BarcodeUnit, |
| | | Barcodes = group.Select(row => new BarcodeInfo |
| | | { |
| | | Barcode = row.Barcode, |
| | | Qty = row.BarcodeQty, |
| | | BatchNo = row.BatchNo, |
| | | SupplyCode = row.SupplyCode, |
| | | Unit = row.Unit |
| | | }).ToList() |
| | | }).ToList(); |
| | | feedmodel.Details = groupedData; |
| | | |
| | | var result = await _invokeMESService.FeedbackAllocate(feedmodel); |
| | | if (result != null && result.code == 200) |
| | | { |
| | | _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1 }) |
| | | .Where(it => it.Id == inboundOrder.Id).ExecuteCommand(); |
| | | _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 }) |
| | | .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand(); |
| | | } |
| | | } |
| | | } |
| | | else if (inboundOrder.OrderType == InOrderTypeEnum.ReCheck.ObjToInt()) //鿣å
¥åº |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | public WebResponseContent InPickTaskCompleted(Dt_Task task) |
| | | public async Task<WebResponseContent> InPickTaskCompleted(Dt_Task task) |
| | | { |
| | | _logger.LogInformation($"TaskService InPickTaskCompleted: {task.TaskNum}"); |
| | | //æ¥åºå |
| | |
| | | { |
| | | return WebResponseContent.Instance.Error($"æªæ¾å°è¯¥æçåºåæç»ä¿¡æ¯"); |
| | | } |
| | | |
| | | //æ¥è´§ä½ |
| | | Dt_LocationInfo locationInfo = _locationInfoService.Repository.QueryFirst(x => x.LocationCode == task.TargetAddress); |
| | | if (locationInfo == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"æªæ¾å°å¯¹åºçç»ç¹è´§ä½ä¿¡æ¯"); |
| | | } |
| | | // è·åææååºä¸çåºåºéå®è®°å½ |
| | | var returnLocks = _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>() |
| | | .Where(it => it.OrderNo == task.OrderNo && it.PalletCode == task.PalletCode && it.Status == (int)OutLockStockStatusEnum.ååºä¸) |
| | |
| | | } |
| | | _outStockLockInfoService.Db.Updateable(returnLocks).ExecuteCommand(); |
| | | |
| | | //æ¥è´§ä½ |
| | | Dt_LocationInfo locationInfo = _locationInfoService.Repository.QueryFirst(x => x.LocationCode == task.TargetAddress); |
| | | if (locationInfo == null) |
| | | { |
| | | return WebResponseContent.Instance.Error($"æªæ¾å°å¯¹åºçç»ç¹è´§ä½ä¿¡æ¯"); |
| | | } |
| | | await DeleteZeroQuantityStockDetails(stockInfo.Id); |
| | | |
| | | stockInfo.LocationCode = task.TargetAddress; |
| | | stockInfo.StockStatus = StockStatusEmun.å
¥åºå®æ.ObjToInt(); |
| | | stockInfo.Details.ForEach(x => |
| | |
| | | }); |
| | | _stockService.StockInfoService.Repository.UpdateData(stockInfo); |
| | | _stockService.StockInfoDetailService.Repository.UpdateData(stockInfo.Details); |
| | | await ProcessStockDetailsForReturn(task, stockInfo.Id); |
| | | |
| | | |
| | | |
| | | if (stockInfo.PalletType == PalletTypeEnum.Empty.ObjToInt()) |
| | | { |
| | |
| | | return WebResponseContent.Instance.OK(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å é¤åºåæ°ä¸º0çåºåæç»è®°å½ |
| | | /// </summary> |
| | | private async Task DeleteZeroQuantityStockDetails(int stockId) |
| | | { |
| | | try |
| | | { |
| | | // å é¤åºåæ°é为0çè®°å½ |
| | | var deleteCount = await _stockService.StockInfoDetailService.Db.Deleteable<Dt_StockInfoDetail>() |
| | | .Where(x => x.StockId == stockId && |
| | | x.StockQuantity == 0 && |
| | | (x.Status==StockStatusEmun.åºåºå®æ.ObjToInt()|| x.Status== |
| | | StockStatusEmun.å
¥åºå®æ.ObjToInt())) // åªå é¤å·²å®æç¶æçé¶åºå |
| | | .ExecuteCommandAsync(); |
| | | |
| | | if (deleteCount > 0) |
| | | { |
| | | _logger.LogInformation($"å é¤{deleteCount}æ¡é¶åºåæç»è®°å½ - StockId: {stockId}"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogWarning($"å é¤é¶åºåè®°å½å¤±è´¥ - StockId: {stockId}, Error: {ex.Message}"); |
| | | // 注æï¼å é¤å¤±è´¥ä¸åºè¯¥å½±å主æµç¨ï¼è®°å½æ¥å¿åç»§ç» |
| | | } |
| | | } |
| | | /// <summary> |
| | | /// å¤çååºç¸å
³çææåºåæç»ç¶æåæ´ |
| | | /// </summary> |
| | | private async Task ProcessStockDetailsForReturn(Dt_Task returnTask, int stockId) |
| | | { |
| | | // è·å该æç䏿æéè¦ååºçåºåæç» |
| | | var stockDetails = await _stockService.StockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>() |
| | | .Where(x => x.StockId == stockId && |
| | | x.StockQuantity > 0 && |
| | | ( x.Status == StockStatusEmun.åºåºéå®.ObjToInt()|| x.Status== |
| | | StockStatusEmun.å
¥åºç¡®è®¤.ObjToInt())) // å
æ¬åºåºéå®åå
¥åºç¡®è®¤ç |
| | | .ToListAsync(); |
| | | |
| | | foreach (var detail in stockDetails) |
| | | { |
| | | |
| | | detail.Status = StockStatusEmun.å
¥åºå®æ.ObjToInt(); |
| | | detail.OutboundQuantity = 0; // æ¸
空åºåºæ°é |
| | | |
| | | _logger.LogInformation($"æ´æ°åºåæç»ç¶æ - æ¡ç : {detail.Barcode}, æ°é: {detail.StockQuantity}"); |
| | | } |
| | | |
| | | if (stockDetails.Any()) |
| | | { |
| | | await _stockService.StockInfoDetailService.Db.Updateable(stockDetails).ExecuteCommandAsync(); |
| | | _logger.LogInformation($"å
±æ´æ°{stockDetails.Count}个åºåæç»ç¶æä¸ºå
¥åºå®æ"); |
| | | } |
| | | } |
| | | public async Task<WebResponseContent> OutEmptyTaskCompleted(Dt_Task task) |
| | | { |
| | | WebResponseContent content = new WebResponseContent(); |
| | |
| | | if (stockInfos != null && stockInfos.Count > 0 && outboundOrderDetails != null && outboundOrderDetails.Count > 0 && outStockLockInfos != null && outStockLockInfos.Count > 0 && locationInfos != null && locationInfos.Count > 0) |
| | | { |
| | | stockInfos.ForEach(x => |
| | | { |
| | | { |
| | | x.StockStatus = StockStatusEmun.åºåºéå®.ObjToInt(); |
| | | }); |
| | | outboundOrderDetails.ForEach(x => |
| | |
| | | { |
| | | _outboundOrderService.Repository.UpdateData(outboundOrder); |
| | | } |
| | | outboundOrder.Operator = App.User.UserName; |
| | | _outboundOrderService.Repository.UpdateData(outboundOrder); |
| | | WebResponseContent content = _outboundOrderDetailService.LockOutboundStockDataUpdate(stockInfos, outboundOrderDetails, outStockLockInfos, locationInfos, tasks: tasks); |
| | | |
| | | if (!content.Status) |
| | |
| | | return tasks; |
| | | } |
| | | |
| | | public List<Dt_Task> GetTasks(List<Dt_StockInfo> stockInfos, TaskTypeEnum taskType) |
| | | { |
| | | List<Dt_Task> tasks = new List<Dt_Task>(); |
| | | List<Dt_LocationInfo> locationInfos = _locationInfoService.Repository.QueryData(x => stockInfos.Select(x => x.LocationCode).Contains(x.LocationCode)); |
| | | for (int i = 0; i < stockInfos.Count; i++) |
| | | { |
| | | Dt_StockInfo stockInfo = stockInfos[i]; |
| | | |
| | | if (stockInfo != null) |
| | | { |
| | | Dt_LocationInfo? locationInfo = locationInfos.FirstOrDefault(x => x.LocationCode == stockInfo.LocationCode); |
| | | if (!tasks.Exists(x => x.PalletCode == stockInfo.PalletCode)) |
| | | { |
| | | Dt_Task task = new() |
| | | { |
| | | CurrentAddress = stockInfo.LocationCode, |
| | | Grade = 0, |
| | | PalletCode = stockInfo.PalletCode, |
| | | NextAddress = "", |
| | | Roadway = locationInfo.RoadwayNo, |
| | | SourceAddress = stockInfo.LocationCode, |
| | | TargetAddress = "", |
| | | TaskStatus = TaskStatusEnum.New.ObjToInt(), |
| | | TaskType = taskType.ObjToInt(), |
| | | //TaskNum = BaseDal.GetTaskNum(nameof(SequenceEnum.SeqTaskNum)), |
| | | PalletType = stockInfo.PalletType, |
| | | WarehouseId = stockInfo.WarehouseId, |
| | | |
| | | }; |
| | | //if (taskType != TaskTypeEnum.OutEmpty) |
| | | //{ |
| | | // task.MaterielCode = stockInfo.Details?.Where(x => x.StockId == stockInfo.Id).FirstOrDefault()?.MaterielCode; |
| | | // task.Quantity = (float)stockInfo.Details?.Where(x => x.StockId == stockInfo.Id).Sum(x => x.StockQuantity); |
| | | // task.BatchNo = stockInfo.Details?.Where(x => x.StockId == stockInfo.Id).FirstOrDefault()?.BatchNo; |
| | | //} |
| | | //if (stockInfo.StockLength > 0) |
| | | //{ |
| | | // task.TaskLength = stockInfo.StockLength; |
| | | //} |
| | | tasks.Add(task); |
| | | } |
| | | } |
| | | } |
| | | return tasks; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// çæåºåºä»»å¡ |
| | |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// çæåºåºä»»å¡ |
| | | /// </summary> |
| | | /// <param name="orderDetailId"></param> |
| | | /// <param name="stockSelectViews"></param> |
| | | /// <returns></returns> |
| | | public WebResponseContent GenerateOutboundTask(int orderDetailId, List<StockSelectViewDTO> stockSelectViews) |
| | | { |
| | | try |
| | | { |
| | | (List<Dt_Task>, List<Dt_StockInfo>?, List<Dt_OutboundOrderDetail>?, List<Dt_OutStockLockInfo>?, List<Dt_LocationInfo>?) result = OutboundTaskDataHandle(orderDetailId, stockSelectViews); |
| | | |
| | | WebResponseContent content = GenerateOutboundTaskDataUpdate(result.Item1, result.Item2, result.Item3, result.Item4, result.Item5); |
| | | |
| | | return content; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | return WebResponseContent.Instance.Error(ex.Message); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// åºåºä»»å¡æ°æ®å¤ç |
| | | /// </summary> |
| | | /// <param name="orderDetailId"></param> |
| | | /// <param name="stockSelectViews"></param> |
| | | /// <returns></returns> |
| | | /// <exception cref="Exception"></exception> |
| | | public (List<Dt_Task>, List<Dt_StockInfo>?, List<Dt_OutboundOrderDetail>?, List<Dt_OutStockLockInfo>?, List<Dt_LocationInfo>?) OutboundTaskDataHandle(int orderDetailId, List<StockSelectViewDTO> stockSelectViews) |
| | | { |
| | | List<Dt_Task> tasks = new List<Dt_Task>(); |
| | | Dt_OutboundOrderDetail outboundOrderDetail = _outboundOrderDetailService.Repository.QueryFirst(x => x.Id == orderDetailId); |
| | | |
| | | if (outboundOrderDetail == null) |
| | | { |
| | | throw new Exception("æªæ¾å°åºåºåæç»ä¿¡æ¯"); |
| | | } |
| | | |
| | | if (stockSelectViews.Sum(x => x.UseableQuantity) > outboundOrderDetail.OrderQuantity - outboundOrderDetail.LockQuantity) |
| | | { |
| | | throw new Exception("éæ©æ°éè¶
åºåæ®æ°é"); |
| | | } |
| | | List<Dt_StockInfo>? stockInfos = null; |
| | | Dt_OutboundOrderDetail? orderDetail = null; |
| | | List<Dt_OutStockLockInfo>? outStockLockInfos = null; |
| | | List<Dt_LocationInfo>? locationInfos = null; |
| | | if (outboundOrderDetail.OrderDetailStatus == OrderDetailStatusEnum.New.ObjToInt()) |
| | | { |
| | | (List<Dt_StockInfo>, Dt_OutboundOrderDetail, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>) result = _outboundOrderDetailService.AssignStockOutbound(outboundOrderDetail, stockSelectViews); |
| | | if (result.Item1 != null && result.Item1.Count > 0) |
| | | { |
| | | Dt_OutboundOrder outboundOrder = _outboundOrderService .Repository.QueryFirst(x => x.Id == outboundOrderDetail.OrderId); |
| | | TaskTypeEnum typeEnum = outboundOrder.OrderType switch |
| | | { |
| | | (int)OutOrderTypeEnum.Issue => TaskTypeEnum.Outbound, |
| | | (int)OutOrderTypeEnum.Allocate => TaskTypeEnum.OutAllocate, |
| | | (int)OutOrderTypeEnum.Quality => TaskTypeEnum.OutQuality, |
| | | _ => new TaskTypeEnum() |
| | | }; |
| | | tasks = GetTasks(result.Item1, typeEnum); |
| | | result.Item2.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); |
| | | result.Item3.ForEach(x => |
| | | { |
| | | x.Status = OutLockStockStatusEnum.åºåºä¸.ObjToInt(); |
| | | }); |
| | | |
| | | stockInfos = result.Item1; |
| | | orderDetail = result.Item2; |
| | | outStockLockInfos = result.Item3; |
| | | locationInfos = result.Item4; |
| | | } |
| | | else |
| | | { |
| | | throw new Exception("æ åºå"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | List<Dt_OutStockLockInfo> stockLockInfos = _outStockLockInfoService.GetByOrderDetailId(outboundOrderDetail.OrderId, OutLockStockStatusEnum.å·²åé
); |
| | | if (stockLockInfos != null && stockLockInfos.Count > 0) |
| | | { |
| | | List<Dt_StockInfo> stocks = _stockService.StockInfoService.GetStockInfosByPalletCodes(stockLockInfos.Select(x => x.PalletCode).Distinct().ToList()); |
| | | tasks = GetTasks(stocks, TaskTypeEnum.Outbound); |
| | | } |
| | | } |
| | | |
| | | return (tasks, stockInfos, orderDetail == null ? null : new List<Dt_OutboundOrderDetail> { orderDetail }, outStockLockInfos, locationInfos); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// çæåºåºä»»å¡åæ°æ®æ´æ°å°æ°æ®åº |
| | | /// </summary> |
| | | /// <param name="tasks"></param> |
| | | /// <param name="stockInfos"></param> |
| | | /// <param name="outboundOrderDetails"></param> |
| | | /// <param name="outStockLockInfos"></param> |
| | | /// <param name="locationInfos"></param> |
| | | /// <returns></returns> |
| | | public WebResponseContent GenerateOutboundTaskDataUpdate(List<Dt_Task> tasks, List<Dt_StockInfo>? stockInfos = null, List<Dt_OutboundOrderDetail>? outboundOrderDetails = null, List<Dt_OutStockLockInfo>? outStockLockInfos = null, List<Dt_LocationInfo>? locationInfos = null) |
| | | { |
| | | try |
| | | { |
| | | _unitOfWorkManage.BeginTran(); |
| | | |
| | | BaseDal.AddData(tasks); |
| | | if (stockInfos != null && stockInfos.Count > 0 && outboundOrderDetails != null && outboundOrderDetails.Count > 0 && outStockLockInfos != null && outStockLockInfos.Count > 0 && locationInfos != null && locationInfos.Count > 0) |
| | | { |
| | | stockInfos.ForEach(x => |
| | | { |
| | | x.StockStatus = StockStatusEmun.åºåºéå®.ObjToInt(); |
| | | }); |
| | | outboundOrderDetails.ForEach(x => |
| | | { |
| | | x.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); |
| | | }); |
| | | Dt_OutboundOrder outboundOrder = _outboundOrderService.Repository.QueryFirst(x => x.Id == outboundOrderDetails.FirstOrDefault().OrderId); |
| | | if (outboundOrder.OrderStatus != OutOrderStatusEnum.åºåºä¸.ObjToInt()) |
| | | { |
| | | _outboundOrderService.Repository.UpdateData(outboundOrder); |
| | | } |
| | | WebResponseContent content = _outboundOrderDetailService.LockOutboundStockDataUpdate(stockInfos, outboundOrderDetails, outStockLockInfos, locationInfos, tasks: tasks); |
| | | |
| | | if (!content.Status) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return content; |
| | | } |
| | | } |
| | | else if (outboundOrderDetails != null && outboundOrderDetails.Count > 0) |
| | | { |
| | | outboundOrderDetails.ForEach(x => |
| | | { |
| | | x.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt(); |
| | | }); |
| | | Dt_OutboundOrder outboundOrder = _outboundOrderService.Repository.QueryFirst(x => x.Id == outboundOrderDetails.FirstOrDefault().OrderId); |
| | | if (outboundOrder.OrderStatus != OutOrderStatusEnum.åºåºä¸.ObjToInt()) |
| | | { |
| | | _outboundOrderService.Repository.UpdateData(outboundOrder); |
| | | } |
| | | _outboundOrderDetailService.Repository.UpdateData(outboundOrderDetails); |
| | | } |
| | | _unitOfWorkManage.CommitTran(); |
| | | //PushTasksToWCS(tasks); |
| | | return WebResponseContent.Instance.OK(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _unitOfWorkManage.RollbackTran(); |
| | | return WebResponseContent.Instance.Error(ex.Message); |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | </PropertyGroup> |
| | | |
| | | <ItemGroup> |
| | | <ProjectReference Include="..\WIDESEA_IAllocateService\WIDESEA_IAllocateService.csproj" /> |
| | | <ProjectReference Include="..\WIDESEA_IBasicService\WIDESEA_IBasicService.csproj" /> |
| | | <ProjectReference Include="..\WIDESEA_IInboundService\WIDESEA_IInboundService.csproj" /> |
| | | <ProjectReference Include="..\WIDESEA_IOutboundService\WIDESEA_IOutboundService.csproj" /> |
| | |
| | | using System.Data.Common; |
| | | using System.Diagnostics.Eventing.Reader; |
| | | using System.Threading.Tasks; |
| | | using WIDESEA_Common.AllocateEnum; |
| | | using WIDESEA_Core; |
| | | using WIDESEA_Core.Attributes; |
| | | using WIDESEA_Core.BaseController; |
| | |
| | | { |
| | | OrderNo = model.OrderNo, |
| | | UpperOrderNo = model.OrderNo, |
| | | BusinessType=model.BusinessType, |
| | | FactoryArea=model.FactoryArea, |
| | | IsBatch=model.IsBatch, |
| | | BusinessType = model.BusinessType, |
| | | FactoryArea = model.FactoryArea, |
| | | IsBatch = model.IsBatch, |
| | | CreateType = model.OperationType, |
| | | Details = new List<Dt_AllocateOrderDetail>() |
| | | FromWarehouse=model.fromWarehouse, |
| | | ToWarehouse=model.toWarehouse, |
| | | Details = new List<Dt_AllocateOrderDetail>() |
| | | }; |
| | | Enum.TryParse<BusinessTypeEnum>(allocateOrder.BusinessType, out var businessType); |
| | | |
| | | |
| | | foreach (var detailDto in model.Details) |
| | | { |
| | | if (businessType == BusinessTypeEnum.æºä»è°å¤é¨ä»åº && (detailDto.Barcodes == null || !detailDto.Barcodes.Any())) |
| | | { |
| | | return WebResponseContent.Instance.Error($"æ¡ç ä¸è½ä¸ºç©º"); |
| | | } |
| | | if (detailDto.Barcodes != null && detailDto.Barcodes.Any()) |
| | | { |
| | | foreach (var barcodeDto in detailDto.Barcodes) |
| | |
| | | MaterielCode = detailDto.MaterialCode, |
| | | LineNo = detailDto.LineNo, |
| | | OrderQuantity = detailDto.Qty, |
| | | SupplyCode= barcodeDto.SupplyCode, |
| | | SupplyCode = barcodeDto.SupplyCode, |
| | | Unit = detailDto.Unit, |
| | | Barcode = barcodeDto.Barcode, |
| | | BatchNo = barcodeDto.BatchNo, |
| | |
| | | } |
| | | allocateOrder.Details.AddRange(allocateOrder.Details); |
| | | } |
| | | var content =await Service.ReceiveAllocateOrder(allocateOrder, model.OperationType); |
| | | var content = await Service.ReceiveAllocateOrder(allocateOrder, model.OperationType); |
| | | |
| | | if (content.Status) return WebResponseContent.Instance.OK(200); |
| | | else return WebResponseContent.Instance.Error(content.Message); |
| | |
| | | return content; |
| | | |
| | | } |
| | | |
| | | [HttpPost, Route("UndoPalletGroup"), AllowAnonymous, MethodParamsValidate] |
| | | public WebResponseContent UndoPalletGroup(string palletCode) |
| | | { |
| | | return Service.UndoPalletGroup(palletCode); |
| | | } |
| | | /// <summary> |
| | | /// |
| | | /// </summary> |
| | |
| | | _splitPackageService = splitPackageService; |
| | | _outStockLockInfoService = outStockLockInfoService; |
| | | } |
| | | /// <summary> |
| | | /// è·åæççåºåºç¶æ |
| | | /// </summary> |
| | | [HttpPost("GetPalletOutboundStatus")] |
| | | public async Task<WebResponseContent> GetPalletOutboundStatus(string palletCode) |
| | | { |
| | | return await Service.GetPalletOutboundStatus(palletCode); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// è·åæççéå®ä¿¡æ¯ |
| | |
| | | return await Service.ReturnRemaining(dto.OrderNo, dto.PalletCode, ""); |
| | | } |
| | | |
| | | [HttpPost("direct-outbound")] |
| | | public async Task<WebResponseContent> DirectOutbound([FromBody] DirectOutboundRequest dto) |
| | | { |
| | | return await Service.DirectOutbound(dto); |
| | | |
| | | } |
| | | |
| | | ///// <summary> |
| | | ///// æ£é确认 |
| | | ///// </summary> |
| | | //[HttpPost("ConfirmPicking")] |
| | | //public async Task<WebResponseContent> ConfirmPicking([FromBody] PickingConfirmRequest request) |
| | | //[HttpPost("direct-outbound")] |
| | | //public async Task<WebResponseContent> DirectOutbound([FromBody] DirectOutboundRequest dto) |
| | | //{ |
| | | // return await Service.ConfirmPicking(request); |
| | | //} |
| | | /// <summary> |
| | | /// éªè¯æ¡ç å¹¶è·åç©æä¿¡æ¯ |
| | | /// </summary> |
| | | [HttpGet("ValidateBarcode")] |
| | | public async Task<WebResponseContent> ValidateBarcode(string barcode) |
| | | { |
| | | return await Service.ValidateBarcode(barcode); |
| | | } |
| | | // return await Service.DirectOutbound(dto); |
| | | |
| | | |
| | | ///// <summary> |
| | | ///// ç´æ¥åºåº |
| | | ///// </summary> |
| | | //[HttpPost("DirectOutbound")] |
| | | //public async Task<WebResponseContent> DirectOutbound([FromBody] DirectOutboundRequest request) |
| | | //{ |
| | | // return await Service.DirectOutbound(request); |
| | | //} |
| | | |
| | | /// <summary> |
| | | /// è·åæ£éåå² |
| | | /// </summary> |
| | | [HttpGet("GetPickingHistory")] |
| | | public async Task<WebResponseContent> GetPickingHistory(int orderId) |
| | | { |
| | | var history = await Service.GetPickingHistory(orderId); |
| | | return WebResponseContent.Instance.OK(null, history); |
| | | } |
| | | |
| | | //} |
| | | |
| | | /// <summary> |
| | | /// æ¤éæ£é |
| | | /// </summary> |
| | |
| | | return await Service.GenerateOutboundTasksAsync(data.taskIds,data.outboundPlatform); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// çæåºåºä»»å¡ |
| | | /// </summary> |
| | | /// <param name="orderDetailId"></param> |
| | | /// <param name="stockSelectViews"></param> |
| | | /// <returns></returns> |
| | | [HttpPost, HttpGet, Route("GenerateOutboundTask"), AllowAnonymous] |
| | | public WebResponseContent GenerateOutboundTask(int orderDetailId, [FromBody] List<StockSelectViewDTO> stockSelectViews) |
| | | { |
| | | return Service.GenerateOutboundTask(orderDetailId, stockSelectViews); |
| | | } |
| | | |
| | | } |
| | | } |