diff --git a/ant-design-vue-jeecg/src/api/api.js b/ant-design-vue-jeecg/src/api/api.js index 04ac0f0..7ddb057 100644 --- a/ant-design-vue-jeecg/src/api/api.js +++ b/ant-design-vue-jeecg/src/api/api.js @@ -135,7 +135,7 @@ export const createReceiptBatchTask = (params) => postAction('/receipt/receiptCo export const completeTaskByWMS = (params) => postAction('/task/taskHeader/completeTaskByWMS', params); //下发任务给WCS export const execute = (params) => postAction('/task/taskHeader/execute', params); -//取消任务/////////// +//取消任务 export const cancelTask = (params) => postAction('/task/taskHeader/cancelTask?ids=' + params, params); //盘点任务创建 @@ -266,10 +266,16 @@ export const receiveHeader = (params) => postAction('/receipt/receiveHeader/rece export const crossDocking = (params) => postAction('/receipt/receiptHeader/crossDocking?id=' + params, params); //收货详情转质检 export const receiveDetailToQuality = (params) => postAction('/receipt/receiveHeader/receiveDetailToQuality?id=' + params, params); -//质检 +//入库质检 export const qualityTesting = (params) => postAction('/receipt/qualityHeader/qualityTesting', params); //全部转质检 export const receiveHeaderToQuality = (params) => postAction('/receipt/receiveHeader/receiveHeaderToQuality?id=' + params, params); +//生成库内质检任务 +export const qualityInventoryDetail = (params) => postAction('/inventory/inventoryHeader/qualityInventoryDetail', params); +//质检登记 +export const qualityRegister = (params) => postAction('/task/taskHeader/qualityRegister', params); +//创建出库任务,AGV去接 +export const createShipmentTaskByAgv = (params) => postAction('/shipment/shipmentCombination/createShipmentTask', params); // 中转HTTP请求 export const transitRESTful = { diff --git a/ant-design-vue-jeecg/src/views/system/inventory/QualityInventoryDetailModal.vue b/ant-design-vue-jeecg/src/views/system/inventory/QualityInventoryDetailModal.vue new file mode 100644 index 0000000..57d6e73 --- /dev/null +++ b/ant-design-vue-jeecg/src/views/system/inventory/QualityInventoryDetailModal.vue @@ -0,0 +1,111 @@ +<template> + <j-modal + :title="title" + :width="width" + :visible="visible" + :confirmLoading="confirmLoading" + switchFullscreen + @ok="handleOk" + @cancel="handleCancel" + cancelText="关闭" + > + <a-spin :spinning="confirmLoading"> + <a-form-model ref="form" :model="model" :rules="validatorRules"> + <a-row> + <a-col :span="24"> + <a-form-model-item label="出库口" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="outPortCode"> + <a-select show-search placeholder="请选择出库口" option-filter-prop="children" v-model="model.outPortCode"> + <a-select-option v-for="item in portList" :key="item.name" :value="item.code"> + {{ item.name }} + </a-select-option> + </a-select> + </a-form-model-item> + </a-col> + </a-row> + </a-form-model> + </a-spin> + </j-modal> +</template> + +<script> +import {getZoneList, selectPickPort, shipmentInventoryDetail, qualityInventoryDetail} from '@/api/api' + +export default { + name: 'QualityInventoryDetailModal', + components: { }, + data() { + return { + title: '操作', + width: 400, + portList: [], + inventoryDetailList: [], + querySource: {}, + visible: false, + model: {}, + labelCol: { + xs: { span: 24 }, + sm: { span: 5 } + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 16 } + }, + // 选择用户查询条件配置 + selectUserQueryConfig: [], + confirmLoading: false, + validatorRules: { + outPortCode: [{ required: true, message: '请选择出库口!' }] + } + } + }, + created() { + //备份model原始值 + this.modelDefault = JSON.parse(JSON.stringify(this.model)); + }, + methods: { + add() { + this.edit(this.modelDefault) + }, + edit(record) { + this.visible = true; + this.model.containerCode = record[0].containerCode; + this.inventoryDetailList = record; + this.getPortList(); + }, + close() { + this.$emit('close') + this.visible = false + this.$refs.form.clearValidate() + }, + getPortList() { + this.querySource.containerCode = this.model.containerCode + selectPickPort(this.querySource).then(res => { + if (res.success) { + this.portList = res.result; + this.visible = true; + } + }) + }, + handleOk() { + if (this.model.outPortCode === ''){ + this.$message.warning('请选择出库口'); + } + this.inventoryDetailList.forEach(x=>{ + x["toPortCode"]=this.model.outPortCode; + }) + qualityInventoryDetail(this.inventoryDetailList).then((res) => { + if (res.success) { + this.$message.success(res.message); + } else { + this.$message.error(res.message); + } + }); + this.$emit("ok", this.model.outPortCode); + this.close() + }, + handleCancel() { + this.close() + } + } +} +</script> \ No newline at end of file diff --git a/ant-design-vue-jeecg/src/views/system/inventory/SimpleInventoryDetailList.vue b/ant-design-vue-jeecg/src/views/system/inventory/SimpleInventoryDetailList.vue index 48f9a45..9d57310 100644 --- a/ant-design-vue-jeecg/src/views/system/inventory/SimpleInventoryDetailList.vue +++ b/ant-design-vue-jeecg/src/views/system/inventory/SimpleInventoryDetailList.vue @@ -125,12 +125,8 @@ <!-- 操作按钮区域 --> <div class="table-operator"> - <a-button v-has="'inventoryDetail:add'" @click="handleAdd" type="primary" icon="plus">新增</a-button> - <a-button v-has="'inventoryDetail:export'" type="primary" icon="download" @click="handleExportXls('库存详情')" - >导出 - </a-button - > + <a-button v-has="'inventoryDetail:export'" type="primary" icon="download" @click="handleExportXls('库存详情')">导出</a-button> <a-upload v-has="'inventoryDetail:import'" name="file" @@ -138,25 +134,15 @@ :multiple="false" :headers="tokenHeader" :action="importExcelUrl" - @change="handleImportExcel" - > - <a-button type="primary" icon="import">导入</a-button> + @change="handleImportExcel"><a-button type="primary" icon="import">导入</a-button> </a-upload> <a-button v-has="'inventoryDetail:controller'" @click='controller()' type='primary'>冻结</a-button> - <a-button v-has="'inventoryDetail:releaseController'" @click='releaseController()' type='primary'>释放冻结 - </a-button> - <a-button v-has="'inventoryHeader:quickShipmentInventoryHeader'" @click='quickShipment()' type='primary'> - 快速出库 - </a-button> + <a-button v-has="'inventoryDetail:releaseController'" @click='releaseController()' type='primary'>释放冻结</a-button> + <a-button v-has="'inventoryHeader:quickShipmentInventoryHeader'" @click='quickShipment()' type='primary'>快速出库</a-button> + <a-button v-has="'inventoryHeader:qualityInventoryDetail'" @click='qualityInventoryDetail()' type='primary'>质检</a-button> <!-- 高级查询区域 --> <j-super-query :fieldList="superFieldList" v-has="'inventoryDetail:superQuery'" @handleSuperQuery="handleSuperQuery"/> - <!-- <a-dropdown v-if="selectedRowKeys.length > 0">--> - <!-- <a-menu slot="overlay">--> - <!-- <a-menu-item v-has="'inventoryDetail:delete'" key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>--> - <!-- </a-menu>--> - <!-- <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>--> - <!-- </a-dropdown>--> </div> <!-- table区域-begin --> @@ -239,7 +225,8 @@ </div> <simple-inventory-detail-modal ref="modalForm" @ok="modalFormOk"></simple-inventory-detail-modal> - <quick-shipment-detail-model ref='quickShipmentModel'></quick-shipment-detail-model> + <quick-shipment-detail-model ref='quickShipmentModel' @ok="modalFormOk"></quick-shipment-detail-model> + <quality-inventory-detail-modal ref="qualityInventoryDetailModal" @ok="modalFormOk"></quality-inventory-detail-modal> </a-card> </template> @@ -252,11 +239,13 @@ import {filterMultiDictText} from '@/components/dict/JDictSelectUtil' import {getCompanyList, getZoneList,} from "@api/api"; import {postAction} from '@/api/manage' import QuickShipmentDetailModel from "@views/system/shipment/modules/QuickShipmentDetailModal"; +import QualityInventoryDetailModal from "@views/system/inventory/QualityInventoryDetailModal"; export default { name: 'SimpleInventoryDetailList', mixins: [JeecgListMixin, mixinDevice], components: { + QualityInventoryDetailModal, QuickShipmentDetailModel, SimpleInventoryDetailModal }, @@ -538,6 +527,34 @@ export default { }) } }, + controller: function () { + if (this.selectedRowKeys.length <= 0) { + this.$message.warning('请选择一条记录!') + } else { + let that = this; + this.$confirm({ + title: '确认冻结', + content: '是否冻结选中数据?', + onOk: function () { + that.loading = true; + postAction(that.url.controller, that.selectedRowKeys).then((res) => { + if (res.success) { + //重新计算分页问题 + that.reCalculatePage(that.selectedRowKeys.length); + that.$message.success(res.message); + that.loadData(); + that.onClearSelected(); + } else { + that.$message.warning(res.message); + this.selectedRowKeys = []; + } + }).finally(() => { + that.loading = false; + }) + } + }) + } + }, onSelectChange(selectedRowKeys, selectionRows) { if (selectedRowKeys != null && selectedRowKeys.length > 0) { this.selectedMainId = selectedRowKeys[0].toString(); @@ -558,6 +575,19 @@ export default { this.$refs.quickShipmentModel.title = '选择出库口'; } }, + qualityInventoryDetail() { + if (this.selectedRowKeys.length <= 0) { + this.$message.warning('请选择一条记录!'); + } else { + let zoneCodes = this.selectRecord.map(row => row.zoneCode); + if (new Set(zoneCodes).size !== 1) { + this.$message.warning('所选数据非同库区'); + return; + } + this.$refs.qualityInventoryDetailModal.edit(this.selectRecord); + this.$refs.qualityInventoryDetailModal.title = '选择出库口'; + } + }, solutionCompany(value) { var actions = [] Object.keys(this.companyList).some(key => { diff --git a/ant-design-vue-jeecg/src/views/system/receipt/QualityReportDetailList.vue b/ant-design-vue-jeecg/src/views/system/receipt/QualityReportDetailList.vue new file mode 100644 index 0000000..b373479 --- /dev/null +++ b/ant-design-vue-jeecg/src/views/system/receipt/QualityReportDetailList.vue @@ -0,0 +1,453 @@ +<template> + <a-card :bordered="false"> + <!-- 查询区域 --> + <div class="table-page-search-wrapper"> + <a-form layout="inline" @keyup.enter.native="searchQuery"> + <a-row :gutter="24"> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <a-form-item label="库区"> + <a-form-model-item prop="zoneOptions"> + <j-multi-select-tag + v-model="queryParam.zoneCode" + :options="zoneOptions" + placeholder="请选择库区"> + </j-multi-select-tag> + </a-form-model-item> + </a-form-item> + </a-col> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <a-form-item label="货主"> + <a-select + show-search + placeholder="请选择货主" + option-filter-prop="children" + v-model="queryParam.companyCode"> + <a-select-option v-for="item in companyList" :key="item.name" :value="item.code">{{ + item.name + }} + </a-select-option> + </a-select> + </a-form-item> + </a-col> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <a-form-item label="库位编码"> + <a-input placeholder="请输入库位编码" v-model="queryParam.locationCode"></a-input> + </a-form-item> + </a-col> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <a-form-item label="容器编码"> + <a-input placeholder="请输入容器编码" v-model="queryParam.containerCode"></a-input> + </a-form-item> + </a-col> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <a-form-item label="库存状态"> + <j-dict-select-tag + placeholder="请选择库存状态" + v-model="queryParam.inventoryStatus" + dictCode="inventory_status" + /> + </a-form-item> + </a-col> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <a-form-item label="可用状态"> + <j-dict-select-tag + placeholder="请选择可用状态" + v-model="queryParam.controller" + dictCode="inventory_enable" + /> + </a-form-item> + </a-col> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <a-form-item label="物料编码"> + <a-input placeholder="请输入物料编码" v-model="queryParam.materialCode"></a-input> + </a-form-item> + </a-col> + <template v-if="toggleSearchStatus"> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <a-form-item label="物料名称"> + <a-input placeholder="请输入物料名称" v-model="queryParam.materialName"></a-input> + </a-form-item> + </a-col> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <a-form-item label="物料规格"> + <a-input placeholder="请输入物料规格" v-model="queryParam.materialSpec"></a-input> + </a-form-item> + </a-col> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <a-form-item label="物料单位"> + <a-input placeholder="请输入物料单位" v-model="queryParam.materialUnit"></a-input> + </a-form-item> + </a-col> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <a-form-item label="批次"> + <a-input placeholder="请输入批次" v-model="queryParam.batch"></a-input> + </a-form-item> + </a-col> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <a-form-item label="巷道"> + <a-input placeholder="请输入巷道" v-model="queryParam.roadWay"></a-input> + </a-form-item> + </a-col> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <a-form-item label="序列号"> + <a-input placeholder="请输入序列号" v-model="queryParam.sn"></a-input> + </a-form-item> + </a-col> + <a-col :xl="12" :lg="14" :md="16" :sm="24"> + <a-form-item label="创建日期"> + <j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间" + class="query-group-cust" v-model="queryParam.createTime_begin"></j-date> + <span class="query-group-split-cust"></span> + <j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间" + class="query-group-cust" v-model="queryParam.createTime_end"></j-date> + </a-form-item> + </a-col> + <a-col :xl='6' :lg='7' :md='8' :sm='24'> + <a-form-item label='库龄大于(天)'> + <a-input placeholder='请输入库龄大于(天)' v-model='queryParam.inventoryAge'></a-input> + </a-form-item> + </a-col> + </template> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons"> + <a-button id="search" type="primary" @click="searchQuery" icon="search">查询</a-button> + <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button> + <a @click="handleToggleSearch" style="margin-left: 8px"> + {{ toggleSearchStatus ? '收起' : '展开' }} + <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/> + </a> + </span> + </a-col> + </a-row> + </a-form> + </div> + <!-- 查询区域-END --> + + <!-- 操作按钮区域 --> + <div class="table-operator"> + <a-button v-has="'inventoryDetail:add'" @click="handleAdd" type="primary" icon="plus">新增</a-button> + <a-button v-has="'inventoryDetail:export'" type="primary" icon="download" @click="handleExportXls('库存详情')">导出</a-button> + <a-upload + v-has="'inventoryDetail:import'" + name="file" + :showUploadList="false" + :multiple="false" + :headers="tokenHeader" + :action="importExcelUrl" + @change="handleImportExcel"><a-button type="primary" icon="import">导入</a-button> + </a-upload> + <!-- 高级查询区域 --> + <j-super-query :fieldList="superFieldList" v-has="'inventoryDetail:superQuery'" + @handleSuperQuery="handleSuperQuery"/> + </div> + + <!-- table区域-begin --> + <div> + <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;"> + <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a + style="font-weight: 600">{{ selectedRowKeys.length }}</a> 项 + <a style="margin-left: 24px" @click="onClearSelected">清空</a> + </div> + + <a-table + ref="table" + size="middle" + :scroll="{ x: true }" + bordered + rowKey="id" + class="j-table-force-nowrap" + :columns="columns" + :dataSource="dataSource" + :pagination="ipagination" + :loading="loading" + :rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }" + @change="handleTableChange" + > + + <span slot="inventoryStatus_dictText" slot-scope="inventoryStatus_dictText"> + <a-tag :key="inventoryStatus_dictText" :color="getStatusColor(inventoryStatus_dictText)"> + {{ inventoryStatus_dictText }} + </a-tag> + </span> + + <span slot="companyCode" slot-scope="companyCode"> + <a-tag :key="companyCode" color="blue"> + {{ solutionCompany(companyCode) }} + </a-tag> + </span> + + <span slot="zoneCode" slot-scope="zoneCode"> + <a-tag :key="zoneCode" color=blue> + {{ solutionZoneCode(zoneCode) }} + </a-tag> + </span> + + <template slot="htmlSlot" slot-scope="text"> + <div v-html="text"></div> + </template> + <template slot="imgSlot" slot-scope="text"> + <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span> + <img + v-else + :src="getImgView(text)" + height="25px" + alt="" + style="max-width:80px;font-size: 12px;font-style: italic;" + /> + </template> + <template slot="fileSlot" slot-scope="text"> + <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span> + <a-button v-else :ghost="true" type="primary" icon="download" size="small" @click="downloadFile(text)">下载 + </a-button> + </template> + <span slot="action" slot-scope="text, record"> + <a v-has="'inventoryDetail:edit'" @click="handleEdit(record)">编辑<a-divider type="vertical"/></a> + <a-popconfirm v-has="'inventoryDetail:delete'" title="确定删除吗?" @confirm="() => handleDelete(record.id)"> + <a>删除</a> + </a-popconfirm> + </span> + </a-table> + </div> + + <simple-inventory-detail-modal ref="modalForm" @ok="modalFormOk"></simple-inventory-detail-modal> + <quick-shipment-detail-model ref='quickShipmentModel' @ok="modalFormOk"></quick-shipment-detail-model> + <quality-inventory-detail-modal ref="qualityInventoryDetailModal" @ok="modalFormOk"></quality-inventory-detail-modal> + </a-card> +</template> + +<script> +import '@/assets/less/TableExpand.less' +import {mixinDevice} from '@/utils/mixin' +import {JeecgListMixin} from '@/mixins/JeecgListMixin' +import {filterMultiDictText} from '@/components/dict/JDictSelectUtil' +import {getCompanyList, getZoneList,} from "@api/api"; +import {postAction} from '@/api/manage' +import QuickShipmentDetailModel from "@views/system/shipment/modules/QuickShipmentDetailModal"; +import QualityInventoryDetailModal from "@views/system/inventory/QualityInventoryDetailModal"; + +export default { + name: 'QualityReportDetailList', + mixins: [JeecgListMixin, mixinDevice], + components: { + QualityInventoryDetailModal, + QuickShipmentDetailModel, + }, + data() { + return { + zoneList: [], + zoneOptions: [], + companyList: [], + firstLoad:0, + description: '库存详情管理页面', + // 表头 + columns: [ + { + title: '#', + dataIndex: '', + key:'rowIndex', + width:60, + align:"center", + customRender:function (t,r,index) { + return parseInt(index)+1; + } + }, + { + title:'物料编码', + align:"center", + dataIndex: 'materialCode' + }, + { + title:'物料名称', + align:"center", + dataIndex: 'materialName' + }, + { + title:'物料规格', + align:"center", + dataIndex: 'materialSpec' + }, + { + title:'物料单位', + align:"center", + dataIndex: 'materialUnit' + }, + { + title:'单据数量', + align:"center", + dataIndex: 'qty' + }, + { + title:'合格数量', + align:"center", + dataIndex: 'qualityfiedQty' + }, + { + title:'不合格数量', + align:"center", + dataIndex: 'unqualityfiedQty' + }, + { + title:'不合格原因', + align:"center", + dataIndex: 'remark' + }, + // { + // title:'批次', + // align:"center", + // dataIndex: 'batch' + // }, + // { + // title:'批号', + // align:"center", + // dataIndex: 'lot' + // }, + // { + // title:'项目号', + // align:"center", + // dataIndex: 'project' + // }, + // { + // title:'单据状态', + // align:"center", + // dataIndex: 'status_dictText' + // }, + // { + // title:'上游单号', + // align:"center", + // dataIndex: 'referCode' + // }, + // { + // title:'上游行号', + // align:"center", + // dataIndex: 'referLineNum' + // }, + { + title:'创建人', + align:"center", + dataIndex: 'createBy' + }, + { + title:'创建日期', + align:"center", + dataIndex: 'createTime' + }, + { + title:'更新人', + align:"center", + dataIndex: 'updateBy' + }, + { + title:'更新日期', + align:"center", + dataIndex: 'updateTime' + }, + { + title: '操作', + dataIndex: 'action', + align:"center", + fixed:"right", + width:147, + scopedSlots: { customRender: 'action' }, + } + ], + url: { + list: '/receipt/qualityDetail/list', + delete: '/receipt/qualityDetail/delete', + deleteBatch: '/receipt/qualityDetail/deleteBatch', + exportXlsUrl: '/receipt/qualityDetail/exportXls', + importExcelUrl: 'receipt/qualityDetail/importExcel', + }, + dictOptions: {}, + superFieldList: [], + selectRecord: [], + } + }, + created() { + this.loadFrom() + this.getSuperFieldList() + }, + mounted() { + if(this.firstLoad == 0) { + this.firstLoad = 1; + return; + } + //页面没加载完,此时methods里的方法找不到,使用定时器模拟点击 + let timeSearch=setInterval(()=>{ + let eleSearch= document.getElementById("search"); + if (eleSearch!=null){ + //调用成功,清除定时器 + clearInterval(timeSearch) + eleSearch.click(); + } + },200) + }, + computed: { + importExcelUrl: function () { + return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}` + } + }, + methods: { + getStatusColor(status) { + const colors = { + '良品': 'green', + '报废品': 'purple', + '待确认 ': 'grey', + '次品': 'red', + '锁定': 'red', + '冻结': 'red', + default: 'blue' + }; + return colors[status] || colors.default; + }, + loadFrom() { + getZoneList().then((res) => { + if (res.success) { + this.zoneList = res.result + //延迟半秒执行,避免组件未加载完,数据已经加载完 + setTimeout(() => { + //slice可以在数组的任何位置进行删除/添加操作 + this.zoneOptions.splice(0, 1); + for (let i = 0; i < res.result.length; i++) { + this.zoneOptions.push({value: res.result[i].code, text: res.result[i].name}) + } + }, 500) + } + }); + getCompanyList().then(res => { + if (res.success) { + this.companyList = res.result + } + }) + }, + initDictConfig() { + }, + getSuperFieldList() { + let fieldList = [] + fieldList.push({type: 'string', value: 'companyCode', text: '货主', dictCode: ''}) + fieldList.push({type: 'string', value: 'zoneCode', text: '库区', dictCode: ''}) + fieldList.push({type: 'string', value: 'containerCode', text: '容器编码', dictCode: ''}) + fieldList.push({type: 'string', value: 'locationCode', text: '库位编码', dictCode: ''}) + fieldList.push({type: 'string', value: 'materialCode', text: '物料编码', dictCode: ''}) + fieldList.push({type: 'string', value: 'materialName', text: '物料名称', dictCode: ''}) + fieldList.push({type: 'string', value: 'materialSpec', text: '物料规格', dictCode: ''}) + fieldList.push({type: 'string', value: 'materialUnit', text: '物料单位', dictCode: ''}) + fieldList.push({type: 'BigDecimal', value: 'qty', text: '数量', dictCode: ''}) + fieldList.push({type: 'BigDecimal', value: 'taskQty', text: '任务锁定数量', dictCode: ''}) + fieldList.push({type: 'string', value: 'inventoryStatus', text: '库存状态', dictCode: 'inventory_status'}) + fieldList.push({type: 'int', value: 'enable', text: '可用状态', dictCode: 'inventory_enable'}) + fieldList.push({type: 'string', value: 'batch', text: '批次', dictCode: ''}) + // fieldList.push({type:'string',value:'sn',text:'序列号',dictCode:''}) + fieldList.push({type: 'datetime', value: 'receiptDate', text: '入库日期'}) + fieldList.push({type: 'int', value: 'inventoryAge', text: '库龄(天)', dictCode: ''}) + fieldList.push({type: 'string', value: 'createBy', text: '创建人', dictCode: ''}) + fieldList.push({type: 'datetime', value: 'createTime', text: '创建日期'}) + fieldList.push({type: 'string', value: 'updateBy', text: '更新人', dictCode: ''}) + fieldList.push({type: 'datetime', value: 'updateTime', text: '更新日期'}) + this.superFieldList = fieldList + } + } +} +</script> +<style scoped> +@import '~@assets/less/common.less'; +</style> \ No newline at end of file diff --git a/ant-design-vue-jeecg/src/views/system/shipment/ShipmentContainerHeaderList.vue b/ant-design-vue-jeecg/src/views/system/shipment/ShipmentContainerHeaderList.vue index 21334af..4056167 100644 --- a/ant-design-vue-jeecg/src/views/system/shipment/ShipmentContainerHeaderList.vue +++ b/ant-design-vue-jeecg/src/views/system/shipment/ShipmentContainerHeaderList.vue @@ -103,6 +103,13 @@ :customRow="clickThenSelect" :rowClassName="rowClassName" @change="handleTableChange"> + + <span slot="zoneCode" slot-scope="zoneCode"> + <a-tag :key="zoneCode" color=blue> + {{ solutionZoneCode(zoneCode) }} + </a-tag> + </span> + <span slot="taskType_dictText" slot-scope="taskType_dictText"> <a-tag :key="taskType_dictText" :color="getStatusColor(taskType_dictText)"> {{ taskType_dictText }} @@ -115,7 +122,8 @@ </span> <span slot="action" slot-scope="text, record"> - <a v-if="record.status == 0" @click="selectPort(record)"><a-button type="primary">生成任务</a-button><a-divider type="vertical"/></a> + <a v-if="record.status == 0 && record.zoneType =='A'" @click="createShipmentTaskByAgv(record)"><a-button type="primary">生成任务</a-button><a-divider type="vertical"/></a> + <a v-if="record.status == 0 && record.zoneType !='A'" @click="selectPort(record)"><a-button type="primary">生成任务</a-button><a-divider type="vertical"/></a> <a-popconfirm v-if="record.status == 0" v-has="'shipmentContainerHeader:delete'" title="确定取消配盘吗?" @confirm="() => handleDelete(record.id)"> <a><a-button type="danger">取消配盘</a-button> <a-divider type="vertical"/></a> </a-popconfirm> @@ -143,8 +151,8 @@ import {deleteAction, getAction} from '@/api/manage' import ShipmentContainerDetailList from './ShipmentContainerDetailList' import {initDictOptions, filterMultiDictText} from '@/components/dict/JDictSelectUtil' import '@/assets/less/TableExpand.less' -import {createShipmentTask} from '@/api/api' -import {selectSortingPort} from '@/api/api' +import {createShipmentTask, execute, getCompanyList, getCustomerList, getShipmentTypeList, getZoneList} from '@/api/api' +import {selectSortingPort, createShipmentTaskByAgv} from '@/api/api' import ShipmentContainerSelectModal from "./modules/ShipmentContainerSelectModal"; export default { @@ -161,6 +169,7 @@ export default { description: '出库组盘管理页面', querySource: {}, portList: [], + zoneList: [], hh:'123', firstLoad:0, isorter: { @@ -187,6 +196,13 @@ export default { scopedSlots: {customRender: 'status_dictText'} }, { + title: '库区', + align: "center", + dataIndex: 'zoneCode', + key: 'zoneCode', + scopedSlots: {customRender: 'zoneCode'} + }, + { title: '起始库位', align: "center", dataIndex: 'fromLocationCode' @@ -259,6 +275,7 @@ export default { }, created() { this.getSuperFieldList(); + this.loadFrom(); }, mounted() { if(this.firstLoad == 0) { @@ -324,6 +341,18 @@ export default { this.$refs.modalForm2.edit(record); this.$refs.modalForm2.title = "选择出库口"; }, + createShipmentTaskByAgv(record) { + this.loading = true; + createShipmentTaskByAgv(record).then((res) => { + this.loading = false; + if (res.success) { + this.$message.success(res.message); + } else { + this.$message.error(res.message); + } + this.searchQuery(); + }); + }, createBatchTask() { if (this.selectedRowKeys.length <= 0) { this.$message.warning('至少选择一条记录!') @@ -391,6 +420,24 @@ export default { } }) }, + solutionZoneCode(value) { + var actions = [] + console.log("solutionZoneCode " + this.zoneList); + Object.keys(this.zoneList).some((key) => { + if (this.zoneList[key].code == ('' + value)) { + actions.push(this.zoneList[key].name) + return true + } + }) + return actions.join('') + }, + loadFrom() { + getZoneList().then((res) => { + if (res.success) { + this.zoneList = res.result + } + }); + }, loadData(arg) { if (!this.url.list) { this.$message.error("请设置url.list属性!") diff --git a/ant-design-vue-jeecg/src/views/system/task/AllTaskHeaderList.vue b/ant-design-vue-jeecg/src/views/system/task/AllTaskHeaderList.vue index 7154eb3..b00c2cf 100644 --- a/ant-design-vue-jeecg/src/views/system/task/AllTaskHeaderList.vue +++ b/ant-design-vue-jeecg/src/views/system/task/AllTaskHeaderList.vue @@ -82,13 +82,13 @@ <!-- 查询区域-END --> <!-- 操作按钮区域 --> -<!-- <div class="table-operator">--> + <div class="table-operator"> <!-- <a-button @click="createEmptyIn()" v-has="'taskHeader:emptyIn'" type="primary">空托入库</a-button>--> <!-- <a-button @click="createManyEmptyIn()" v-has="'taskHeader:manyEmptyIn'" type="primary">空托组入库</a-button>--> <!-- <a-button @click="openDemo()" type="primary">弹出demo</a-button>--> -<!-- </div>--> - <j-super-query :fieldList="superFieldList" v-has="'taskHeader:superQuery'" @handleSuperQuery="handleSuperQuery"/> - <a-button v-has="'taskHeader:export'" type="primary" icon="download" @click="handleExportXls('任务表')">导出</a-button> + <j-super-query :fieldList="superFieldList" v-has="'taskHeader:superQuery'" @handleSuperQuery="handleSuperQuery"/> + <a-button v-has="'taskHeader:export'" type="primary" icon="download" @click="handleExportXls('任务表')">导出</a-button> + </div> <!-- table区域-begin --> <div> diff --git a/ant-design-vue-jeecg/src/views/system/task/ReceiptTaskHeaderList.vue b/ant-design-vue-jeecg/src/views/system/task/ReceiptTaskHeaderList.vue index d4962e2..d0d040f 100644 --- a/ant-design-vue-jeecg/src/views/system/task/ReceiptTaskHeaderList.vue +++ b/ant-design-vue-jeecg/src/views/system/task/ReceiptTaskHeaderList.vue @@ -83,13 +83,13 @@ <!-- 操作按钮区域 --> <div class="table-operator"> - <a-button @click="createEmptyIn()" v-has="'taskHeader:emptyIn'" type="primary">空托入库</a-button> - <a-button @click="createManyEmptyIn()" v-has="'taskHeader:manyEmptyIn'" type="primary">空托组入库</a-button> + <a-button v-has="'taskHeader:emptyIn'" @click="createEmptyIn()" type="primary">空托入库</a-button> + <a-button v-has="'taskHeader:manyEmptyIn'" @click="createManyEmptyIn()" type="primary">空托组入库</a-button> <a-button v-has="'taskHeader:quickReceipt'" @click="quickReceipt()" type="primary">快速入库</a-button> <a-button v-has="'taskHeader:callReceiptBox'" @click="callReceiptBox()" type="primary" >呼叫入库有货托盘</a-button> <a-button v-has="'taskHeader:callReceiptBox'" @click="callReceiptEmptyBox()" type="primary" >呼叫入库空托盘</a-button> <j-super-query :fieldList="superFieldList" v-has="'taskHeader:superQuery'" @handleSuperQuery="handleSuperQuery"/> - <a-button v-has="'taskHeader:export'" type="primary" icon="download" @click="handleExportXls('任务表')">导出</a-button> + <a-button v-has="'taskHeader:export'" @click="handleExportXls('任务表')" type="primary" icon="download">导出</a-button> </div> <!-- table区域-begin --> diff --git a/ant-design-vue-jeecg/src/views/system/task/TaskDetailList.vue b/ant-design-vue-jeecg/src/views/system/task/TaskDetailList.vue index 5a603bd..48b349e 100644 --- a/ant-design-vue-jeecg/src/views/system/task/TaskDetailList.vue +++ b/ant-design-vue-jeecg/src/views/system/task/TaskDetailList.vue @@ -80,7 +80,9 @@ <span slot="action" slot-scope="text, record"> <adjustment-doc-modal ref="adjustmentModal" @ok="modalFormOk" :id="record.id" :taskHeaderId="record.taskHeaderId"/> - <a v-if="record.taskType==700" @click="createMany(record)">实盘登记<a-divider type="vertical" /></a> + <quality-register-detail-modal ref="qualityRegisterModal" @ok="modalFormOk" :id="record.id" :taskHeaderId="record.taskHeaderId"/> + <a v-if="record.taskType==700 && record.status!=100" @click="createMany(record)">实盘登记<a-divider type="vertical" /></a> + <a v-if="record.taskType==1400 && record.status!=100" @click="qualityRegister(record)">质检登记<a-divider type="vertical" /></a> <a v-has="'taskDetail:edit'" @click="handleEdit(record)">编辑<a-divider type="vertical" /></a> <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)"> <a v-has="'taskDetail:delete'">删除</a> @@ -100,11 +102,12 @@ import {JeecgListMixin} from '@/mixins/JeecgListMixin' import TaskDetailModal from './modules/TaskDetailModal' import AdjustmentDocModal from "../stocktaking/modules/AdjustmentDocModal"; import { getCompanyList } from '@api/api' +import QualityRegisterDetailModal from "@views/system/task/modules/QualityRegisterDetailModal"; export default { name: "TaskDetailList", mixins: [JeecgListMixin], - components: {TaskDetailModal,AdjustmentDocModal}, + components: {QualityRegisterDetailModal, TaskDetailModal,AdjustmentDocModal}, props: { mainId: { type: String, @@ -269,7 +272,10 @@ export default { this.$refs.adjustmentModal.edit(record); this.$refs.adjustmentModal.title = "实盘登记"; }, - + qualityRegister(record) { + this.$refs.qualityRegisterModal.edit(record); + this.$refs.qualityRegisterModal.title = "质检登记"; + }, } } </script> diff --git a/ant-design-vue-jeecg/src/views/system/task/modules/QualityRegisterDetailModal.vue b/ant-design-vue-jeecg/src/views/system/task/modules/QualityRegisterDetailModal.vue new file mode 100644 index 0000000..2c9f307 --- /dev/null +++ b/ant-design-vue-jeecg/src/views/system/task/modules/QualityRegisterDetailModal.vue @@ -0,0 +1,137 @@ +<template> + <j-modal + :title="title" + :width="width" + :visible="visible" + :confirmLoading="confirmLoading" + switchFullscreen + @ok="handleOk" + @cancel="handleCancel" + cancelText="关闭"> + <a-spin :spinning="confirmLoading"> + <a-form-model ref="form" :model="model" :rules="validatorRules"> + <a-row> + <a-col :xs="24"> + <a-form-model-item label="id" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="id"> + <a-input v-model="model.id" placeholder="请输入id" disabled="true"></a-input> + </a-form-model-item> + </a-col> + <a-col :xs="24"> + <a-form-model-item label="物料编码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="materialCode"> + <a-input v-model="model.materialCode" placeholder="请输入物料编码" disabled="true"></a-input> + </a-form-model-item> + </a-col> + <a-col :xs="24"> + <a-form-model-item label="物料数量" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="qty"> + <a-input v-model="model.qty" placeholder="请输入物料数量" disabled="true"></a-input> + </a-form-model-item> + </a-col> + <a-col :xs="24"> + <a-form-model-item label="合格数量" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="qualityfiedQty"> + <a-input v-model="model.qualityfiedQty" placeholder="请输入合格数量"></a-input> + </a-form-model-item> + </a-col> + <a-col :xs="24"> + <a-form-model-item label="不合格数量" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="unqualityfiedQty"> + <a-input v-model="model.unqualityfiedQty" placeholder="请输入不合格数量"></a-input> + </a-form-model-item> + </a-col> + <a-col :xs="24"> + <a-form-model-item label="不合格原因" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="remark"> + <a-input v-model="model.remark" placeholder="请输入不合格原因"></a-input> + </a-form-model-item> + </a-col> + </a-row> + </a-form-model> + </a-spin> + </j-modal> +</template> + +<script> + +import {createManyEmptyIn, qualityRegister} from '@/api/api' +import {confirmGapQty} from "../../../../api/api"; +import Utils from '../../../../components/jeecgbiz/JButtonBizComponent/util.js'; + +export default { + name: "QualityRegisterDetailModal", + components: {}, + props: { + taskHeaderId:"", + }, + data() { + return { + title: "操作", + width: 500, + visible: false, + model: {}, + labelCol: { + xs: {span: 24}, + sm: {span: 5}, + }, + wrapperCol: { + xs: {span: 24}, + sm: {span: 16}, + }, + + confirmLoading: false, + validatorRules: { + countedQty: [ + {required: true, message: '请输入实盘数量!'}, + ], + }, + url: { + add: "/cycleCountDetail/cycleCountDetail/confirmGapQty", + } + + } + }, + + + created() { + //备份model原始值 + this.modelDefault = JSON.parse(JSON.stringify(this.model)); + }, + + methods: { + add() { + this.edit(this.modelDefault); + }, + edit(record) { + this.visible = true; + this.model = Object.assign({}, record); + }, + close() { + this.$emit('close'); + this.visible = false; + this.$refs.form.clearValidate(); + }, + handleOk() { + const that = this; + // 触发表单验证 + this.$refs.form.validate(valid => { + if (valid) { + that.confirmLoading = true; + qualityRegister(this.model).then((res) => { + if (res.success) { + that.$message.success(res.message); + } else { + that.$message.warning(res.message); + } + }).finally(() => { + that.confirmLoading = false; + that.close(); + }) + } else { + return false + } + }) + }, + handleCancel() { + this.close() + }, + + + } +} +</script> \ No newline at end of file diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/controller/InventoryHeaderController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/controller/InventoryHeaderController.java index f903443..3ae9c93 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/controller/InventoryHeaderController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/controller/InventoryHeaderController.java @@ -410,7 +410,6 @@ public class InventoryHeaderController extends JeecgController<InventoryHeader, @AutoLog("批量出库存详情") @ApiOperation(value = "批量出库存详情", notes = "批量出库存详情") - @ApiLogger(apiName = "批量出库存详情") @PostMapping("/decuceInventoryDetail") @ResponseBody public Result decuceInventoryDetail(@RequestBody List<InventoryDetail> inventoryDetailList, HttpServletRequest req) { @@ -420,4 +419,16 @@ public class InventoryHeaderController extends JeecgController<InventoryHeader, String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(req); return inventoryHeaderService.decuceInventoryDetail(inventoryDetailList, warehouseCode); } + + @AutoLog("按照库存详情质检") + @ApiOperation(value = "按照库存详情质检", notes = "按照库存详情质检") + @PostMapping("/qualityInventoryDetail") + @ResponseBody + public Result qualityInventoryDetail(@RequestBody List<InventoryDetail> inventoryDetailList, HttpServletRequest req) { + if (StringUtils.isEmpty(inventoryDetailList)) { + return Result.error("库存明细为空"); + } + String warehouseCode = HuahengJwtUtil.getWarehouseCodeByToken(req); + return inventoryHeaderService.qualityInventoryDetail(inventoryDetailList, warehouseCode); + } } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/IInventoryHeaderService.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/IInventoryHeaderService.java index ed6da24..aaf210f 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/IInventoryHeaderService.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/IInventoryHeaderService.java @@ -51,4 +51,6 @@ public interface IInventoryHeaderService extends IService<InventoryHeader> { Result decuceInventoryDetail(List<InventoryDetail> inventoryDetailList, String warehouseCode); boolean updateInventory(String containerCode, String locationCode, String warehouseCode); + + Result qualityInventoryDetail(List<InventoryDetail> inventoryDetailList, String warehouseCode); } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryHeaderServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryHeaderServiceImpl.java index 960391f..4e28115 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryHeaderServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryHeaderServiceImpl.java @@ -283,6 +283,12 @@ public class InventoryHeaderServiceImpl extends ServiceImpl<InventoryHeaderMappe return Result.OK("批量快速出库成功"); } + /** + * 快速出库,按照库存详情 + * @param inventoryDetailList + * @param warehouseCode + * @return + */ @Override @Transactional(rollbackFor = JeecgBootException.class) public Result shipmentInventoryDetail(List<InventoryDetail> inventoryDetailList, String warehouseCode) { @@ -369,6 +375,12 @@ public class InventoryHeaderServiceImpl extends ServiceImpl<InventoryHeaderMappe return Result.OK("批量快速出库成功"); } + /** + * 批量出库存详情 + * @param inventoryDetailList + * @param warehouseCode + * @return + */ @Override @Transactional(rollbackFor = JeecgBootException.class) public Result decuceInventoryDetail(List<InventoryDetail> inventoryDetailList, String warehouseCode) { @@ -483,4 +495,36 @@ public class InventoryHeaderServiceImpl extends ServiceImpl<InventoryHeaderMappe return success; } + /** + * 按照库存详情质检 + * @param inventoryDetailList + * @param warehouseCode + * @return + */ + @Override + @Transactional(rollbackFor = JeecgBootException.class) + public Result qualityInventoryDetail(List<InventoryDetail> inventoryDetailList, String warehouseCode) { + if (StringUtils.isEmpty(inventoryDetailList)) { + return Result.error("质检库存详情失败,所选库存详情为空"); + } + String toPortCode = inventoryDetailList.get(0).getToPortCode(); + if (StringUtils.isEmpty(toPortCode)) { + return Result.error("质检库存详情失败,出库站台编码为空"); + } + inventoryDetailList = + inventoryDetailList.stream().filter((item) -> item.getContainerStatus().equals(QuantityConstant.STATUS_CONTAINER_EMPTY)).collect(Collectors.toList()); + if (StringUtils.isEmpty(inventoryDetailList)) { + return Result.error("质检库存详情失败, 排除锁定库存后没有可出库存详情"); + } + + List<String> containerCodeList = inventoryDetailList.stream().map(InventoryDetail::getContainerCode).collect(Collectors.toList()); + for (String containerCode : containerCodeList) { + Result result = taskHeaderService.createQualityTask(containerCode, toPortCode, warehouseCode); + if (!result.isSuccess()) { + throw new JeecgBootException(result.getMessage()); + } + } + return Result.ok("生成质检任务成功"); + } + } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/controller/QualityReportDetailController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/controller/QualityReportDetailController.java new file mode 100644 index 0000000..ad2aa63 --- /dev/null +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/controller/QualityReportDetailController.java @@ -0,0 +1,145 @@ +package org.jeecg.modules.wms.receipt.qualityHeader.controller; + +import java.util.Arrays; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.jeecg.common.system.base.controller.JeecgController; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.modules.wms.receipt.qualityHeader.entity.QualityDetail; +import org.jeecg.modules.wms.receipt.qualityHeader.service.IQualityDetailService; +import org.jeecg.utils.constant.QuantityConstant; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; + +/** + * @Description: 质检报告 + * @Author: jeecg-boot + * @Date: 2023-03-09 + * @Version: V1.0 + */ +@Api(tags = "质检报告") +@RestController +@RequestMapping("/receipt/qualityDetail") +@Slf4j +public class QualityReportDetailController extends JeecgController<QualityDetail, IQualityDetailService> { + @Autowired + private IQualityDetailService qualityDetailService; + + /** + * 分页列表查询 + */ + // @AutoLog(value = "库存详情-分页列表查询") + @ApiOperation(value = "质检报告-分页列表查询", notes = "质检报告-分页列表查询") + @GetMapping(value = "/list") + public Result<IPage<QualityDetail>> queryPageList(QualityDetail qualityDetail, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { + QueryWrapper<QualityDetail> queryWrapper = QueryGenerator.initQueryWrapper(qualityDetail, req.getParameterMap()); + queryWrapper.lambda().eq(QualityDetail::getStatus, QuantityConstant.QUALITY_HEADER_COMPLETE); + Page<QualityDetail> page = new Page<QualityDetail>(pageNo, pageSize); + IPage<QualityDetail> pageList = qualityDetailService.page(page, queryWrapper); + return Result.OK(pageList); + } + + /** + * 添加 + * @param qualityDetail + * @return + */ + @AutoLog(value = "质检报告-添加") + @ApiOperation(value = "质检报告-添加", notes = "质检报告-添加") + @PostMapping(value = "/add") + public Result<String> add(@RequestBody QualityDetail qualityDetail) { + qualityDetailService.save(qualityDetail); + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * @param qualityDetail + * @return + */ + @AutoLog(value = "质检报告-编辑") + @ApiOperation(value = "质检报告-编辑", notes = "质检报告-编辑") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) + public Result<String> edit(@RequestBody QualityDetail qualityDetail) { + qualityDetailService.updateById(qualityDetail); + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * @param id + * @return + */ + @AutoLog(value = "质检报告-通过id删除") + @ApiOperation(value = "质检报告-通过id删除", notes = "质检报告-通过id删除") + @DeleteMapping(value = "/delete") + public Result<String> delete(@RequestParam(name = "id", required = true) String id) { + qualityDetailService.removeById(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * @param ids + * @return + */ + @AutoLog(value = "质检报告-批量删除") + @ApiOperation(value = "质检报告-批量删除", notes = "质检报告-批量删除") + @DeleteMapping(value = "/deleteBatch") + public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + this.qualityDetailService.removeByIds(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * @param id + * @return + */ + // @AutoLog(value = "库存详情-通过id查询") + @ApiOperation(value = "库存详情-通过id查询", notes = "库存详情-通过id查询") + @GetMapping(value = "/queryById") + public Result<QualityDetail> queryById(@RequestParam(name = "id", required = true) String id) { + QualityDetail qualityDetail = qualityDetailService.getById(id); + if (qualityDetail == null) { + return Result.error("未找到对应数据"); + } + return Result.OK(qualityDetail); + } + + /** + * 导出excel + * @param request + * @param qualityDetail + */ + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, QualityDetail qualityDetail) { + return super.exportXls(request, qualityDetail, QualityDetail.class, "质检报告"); + } + + /** + * 通过excel导入数据 + * @param request + * @param response + * @return + */ + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) { + return super.importExcel(request, response, QualityDetail.class); + } + +} diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/entity/QualityDetail.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/entity/QualityDetail.java index cccd257..e531c91 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/entity/QualityDetail.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/receipt/qualityHeader/entity/QualityDetail.java @@ -38,6 +38,10 @@ public class QualityDetail implements Serializable { @Excel(name = "质检单号", width = 15) @ApiModelProperty(value = "质检单号") private java.lang.String qualityCode; + /** 质检类型 */ + @Excel(name = "质检类型", width = 15) + @ApiModelProperty(value = "质检类型") + private java.lang.String type; /** 仓库编码 */ @Excel(name = "仓库编码", width = 15) @ApiModelProperty(value = "仓库编码") diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java index eb4d759..5cc1d59 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java @@ -149,13 +149,12 @@ public class ShipmentCombinationServiceImpl implements IShipmentCombinationServi inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getWarehouseCode, warehouseCode).eq(InventoryDetail::getCompanyCode, companyCode) .eq(InventoryDetail::getMaterialCode, materialCode).eq(InventoryDetail::getInventoryStatus, inventoryStatus) .eq(InventoryDetail::getEnable, QuantityConstant.INVENTORY_DETAIL_STATUS_ENABLE) - .eq(StringUtils.isNotEmpty(zoneCode), InventoryDetail::getZoneCode, zoneCode) .eq(InventoryDetail::getContainerStatus, QuantityConstant.STATUS_CONTAINER_EMPTY); String value = parameterConfigurationService.getValueByCode(QuantityConstant.RULE_SHIPMENT_ZONE); if (StringUtils.isNotEmpty(value)) { int shipmentZoneRule = Integer.parseInt(value); if (shipmentZoneRule == QuantityConstant.SHIPMENT_BY_ZONE) { - inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getZoneCode, zoneCode); + inventoryDetailLambdaQueryWrapper.eq(StringUtils.isNotEmpty(zoneCode), InventoryDetail::getZoneCode, zoneCode); } } List<InventoryDetail> inventoryDetailList = inventoryDetailService.list(inventoryDetailLambdaQueryWrapper); @@ -192,14 +191,13 @@ public class ShipmentCombinationServiceImpl implements IShipmentCombinationServi LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery(); inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getWarehouseCode, warehouseCode).eq(InventoryDetail::getCompanyCode, companyCode) .eq(InventoryDetail::getMaterialCode, materialCode).eq(InventoryDetail::getInventoryStatus, inventoryStatus) - .eq(InventoryDetail::getEnable, QuantityConstant.INVENTORY_DETAIL_STATUS_ENABLE) - .eq(StringUtils.isNotEmpty(zoneCode), InventoryDetail::getZoneCode, zoneCode).eq(InventoryDetail::getContainerCode, containerCode) + .eq(InventoryDetail::getEnable, QuantityConstant.INVENTORY_DETAIL_STATUS_ENABLE).eq(InventoryDetail::getContainerCode, containerCode) .eq(InventoryDetail::getContainerStatus, QuantityConstant.STATUS_CONTAINER_EMPTY); String value = parameterConfigurationService.getValueByCode(QuantityConstant.RULE_SHIPMENT_ZONE); if (StringUtils.isNotEmpty(value)) { int shipmentZoneRule = Integer.parseInt(value); if (shipmentZoneRule == QuantityConstant.SHIPMENT_BY_ZONE) { - inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getZoneCode, zoneCode); + inventoryDetailLambdaQueryWrapper.eq(StringUtils.isNotEmpty(zoneCode), InventoryDetail::getZoneCode, zoneCode); } } List<InventoryDetail> inventoryDetailList = inventoryDetailService.list(inventoryDetailLambdaQueryWrapper); @@ -234,7 +232,7 @@ public class ShipmentCombinationServiceImpl implements IShipmentCombinationServi if (StringUtils.isNotEmpty(value)) { int shipmentZoneRule = Integer.parseInt(value); if (shipmentZoneRule == QuantityConstant.SHIPMENT_BY_ZONE) { - inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getZoneCode, zoneCode); + inventoryDetailLambdaQueryWrapper.eq(StringUtils.isNotEmpty(zoneCode), InventoryDetail::getZoneCode, zoneCode); } } List<InventoryDetail> inventoryDetailList = inventoryDetailService.list(inventoryDetailLambdaQueryWrapper); @@ -486,7 +484,19 @@ public class ShipmentCombinationServiceImpl implements IShipmentCombinationServi String containerCode = inventoryDetail.getContainerCode(); String warehouseCode = inventoryDetail.getWarehouseCode(); String locationCode = inventoryDetail.getLocationCode(); + Location location = locationService.getLocationByCode(locationCode, warehouseCode); + if (location == null) { + throw new JeecgBootException("新增出库配盘头失败, 没有找到库位"); + } Container container = containerService.getContainerByCode(containerCode, warehouseCode); + if (container == null) { + throw new JeecgBootException("新增出库配盘头失败, 没有找到容器"); + } + String zoneCode = location.getZoneCode(); + Zone zone = zoneService.getZoneByCode(zoneCode, warehouseCode); + if (zone == null) { + throw new JeecgBootException("新增出库配盘头失败, 没有找到库区"); + } // 每次组盘都需判断是整盘出库还是分拣出库 LambdaQueryWrapper<ShipmentContainerHeader> shipmentContainerHeaderLambdaQueryWrapper = Wrappers.lambdaQuery(); shipmentContainerHeaderLambdaQueryWrapper.eq(ShipmentContainerHeader::getContainerCode, containerCode) @@ -513,11 +523,13 @@ public class ShipmentCombinationServiceImpl implements IShipmentCombinationServi } else { String value = parameterConfigurationService.getValueByCode(QuantityConstant.RULE_TASK_LOCATION, container.getZoneCode()); if (StringUtils.isEmpty(value)) { - throw new JeecgBootException("取消入库任务时, 没有获取到配置属性"); + throw new JeecgBootException("新增出库配盘头失败, 没有获取到配置属性"); } int taskLocationRule = Integer.parseInt(value); shipmentContainerHeader = new ShipmentContainerHeader(); shipmentContainerHeader.setContainerCode(containerCode); + shipmentContainerHeader.setZoneCode(zone.getCode()); + shipmentContainerHeader.setZoneType(zone.getType()); shipmentContainerHeader.setFromLocationCode(locationCode); if (taskLocationRule == QuantityConstant.RULE_TASK_SET_LOCATION && taskType == QuantityConstant.TASK_TYPE_SORTINGSHIPMENT) { shipmentContainerHeader.setToLocationCode(locationCode); @@ -530,7 +542,7 @@ public class ShipmentCombinationServiceImpl implements IShipmentCombinationServi shipmentContainerHeader.setTaskType(taskType); boolean success = shipmentContainerHeaderService.save(shipmentContainerHeader); if (!success) { - throw new JeecgBootException("新增出库组盘头失败"); + throw new JeecgBootException("新增出库配盘头失败"); } } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/entity/ShipmentContainerHeader.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/entity/ShipmentContainerHeader.java index ae5e7be..a032800 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/entity/ShipmentContainerHeader.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/entity/ShipmentContainerHeader.java @@ -57,6 +57,14 @@ public class ShipmentContainerHeader implements Serializable { @Dict(dicCode = "shipment_container_status") @ApiModelProperty(value = "状态") private Integer status; + /** 库区编码 */ + @Excel(name = "库区编码", width = 15) + @ApiModelProperty(value = "库区编码") + private String zoneCode; + /** 库区类型 */ + @Excel(name = "库区类型", width = 15) + @ApiModelProperty(value = "库区类型") + private String zoneType; /** 起始库位 */ @Excel(name = "起始库位", width = 15) @ApiModelProperty(value = "起始库位") diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/controller/TaskHeaderController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/controller/TaskHeaderController.java index 26c1a02..2918203 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/controller/TaskHeaderController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/controller/TaskHeaderController.java @@ -1,6 +1,7 @@ package org.jeecg.modules.wms.task.taskHeader.controller; import java.io.IOException; +import java.math.BigDecimal; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -430,7 +431,7 @@ public class TaskHeaderController extends HuahengBaseController { Result result = handleMultiProcess("createEmptyIn", new MultiProcessListener() { @Override public Result<?> doProcess() { - Result result = taskHeaderService.createEmptyIn(contaienrCode, toLocationCode, warehouseCode,toPortCode); + Result result = taskHeaderService.createEmptyIn(contaienrCode, toLocationCode, warehouseCode, toPortCode); return result; } }); @@ -752,4 +753,27 @@ public class TaskHeaderController extends HuahengBaseController { }); return result; } + + /** + * 质检登记 + * @return + */ + @AutoLog(value = "质检登记") + @PostMapping("qualityRegister") + @ApiOperation("质检登记") + @ResponseBody + public Result qualityRegister(@RequestBody TaskDetail taskDetail, HttpServletRequest req) { + int id = taskDetail.getId(); + BigDecimal qualityfiedQty = taskDetail.getQualityfiedQty(); + BigDecimal unqualityfiedQty = taskDetail.getUnqualityfiedQty(); + String remark = taskDetail.getRemark(); + Result result = handleMultiProcess("qualityRegister", new MultiProcessListener() { + @Override + public Result<?> doProcess() { + Result result = taskHeaderService.qualityRegister(id, qualityfiedQty, unqualityfiedQty, remark); + return result; + } + }); + return result; + } } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/entity/TaskDetail.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/entity/TaskDetail.java index c9ef1d5..b9ebca9 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/entity/TaskDetail.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/entity/TaskDetail.java @@ -114,6 +114,21 @@ public class TaskDetail implements Serializable { @ApiModelProperty(value = "数量") private BigDecimal qty; + /** 合格数量 */ + @Excel(name = "合格数量", width = 15) + @ApiModelProperty(value = "合格数量") + private BigDecimal qualityfiedQty; + + /** 不合格数量 */ + @Excel(name = "不合格数量", width = 15) + @ApiModelProperty(value = "不合格数量") + private BigDecimal unqualityfiedQty; + + /** 备注 */ + @Excel(name = "备注", width = 15) + @ApiModelProperty(value = "备注") + private String remark; + /** 批次 */ @Excel(name = "批次", width = 15) @ApiModelProperty(value = "批次") @@ -129,6 +144,11 @@ public class TaskDetail implements Serializable { @ApiModelProperty(value = "项目号") private String project; + /** 质检单据详情id */ + @Excel(name = "质检单据详情id", width = 15) + @ApiModelProperty(value = "质检单据详情id") + private Integer qualityDetailId; + /** 库存状态 */ @Excel(name = "库存状态", width = 15) @Dict(dicCode = "inventory_status") diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/ITaskHeaderService.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/ITaskHeaderService.java index 73952ea..4086e2f 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/ITaskHeaderService.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/ITaskHeaderService.java @@ -1,6 +1,7 @@ package org.jeecg.modules.wms.task.taskHeader.service; import java.io.Serializable; +import java.math.BigDecimal; import java.util.Collection; import java.util.List; @@ -101,7 +102,7 @@ public interface ITaskHeaderService extends IService<TaskHeader> { * @param taskHeader * @return */ - public Result cancelLocationAndContainerStatus(TaskHeader taskHeader); + Result cancelLocationAndContainerStatus(TaskHeader taskHeader); /** * 取消WMS任务 @@ -161,6 +162,15 @@ public interface ITaskHeaderService extends IService<TaskHeader> { Result createCheckOutTask(String containerCode, String toPortCode, String warehouseCode); /** + * 创建质检任务 + * @param containerCode + * @param toPortCode + * @param warehouseCode + * @return + */ + Result createQualityTask(String containerCode, String toPortCode, String warehouseCode); + + /** * 创建跨站任务任务 * @param containerCode * @param fromPortCode @@ -305,6 +315,13 @@ public interface ITaskHeaderService extends IService<TaskHeader> { Result completeManyEmptyOutTask(TaskHeader taskHeader); /** + * 完成质检任务 + * @param taskHeader + * @return + */ + Result completeQualityTask(TaskHeader taskHeader); + + /** * 取消入库 * @param taskHeader * @return @@ -415,4 +432,9 @@ public interface ITaskHeaderService extends IService<TaskHeader> { */ Result switchTask(int id); + /** + * 质检登记 + */ + Result qualityRegister(int id, BigDecimal qualityfiedQty, BigDecimal unqualityfiedQty, String remark); + } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java index 1b44a64..5977b4b 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java @@ -33,6 +33,8 @@ import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryHeaderS import org.jeecg.modules.wms.inventory.inventoryTransaction.entity.InventoryTransaction; import org.jeecg.modules.wms.inventory.inventoryTransaction.service.IInventoryTransactionService; import org.jeecg.modules.wms.lockStation.service.ILockStationService; +import org.jeecg.modules.wms.receipt.qualityHeader.entity.QualityDetail; +import org.jeecg.modules.wms.receipt.qualityHeader.service.IQualityDetailService; import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContainerHeader; import org.jeecg.modules.wms.receipt.receiptContainerHeader.service.IReceiptContainerHeaderService; import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptDetail; @@ -153,6 +155,8 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea private IShipmentCombinationService shipmentCombinationService; @Resource private ILockStationService lockStationService; + @Resource + private IQualityDetailService qualityDetailService; @Override @Transactional @@ -324,11 +328,11 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea } // 校验入库组盘 if (receiptContainerHeaderService.havaUnCompleteCombineByContainerCode(containerCode, warehouseCode)) { - return Result.error("创建出库查看任务时,容器:" + containerCode + "存在入库组盘,不能移库"); + return Result.error("创建出库查看任务时,容器:" + containerCode + "存在入库组盘,不能生成任务"); } // 校验出库组盘 if (shipmentContainerHeaderService.havaUnCompleteCombineByContainerCode(containerCode, warehouseCode)) { - return Result.error("创建出库查看任务时, 容器:" + containerCode + "存在出库组盘,不能移库"); + return Result.error("创建出库查看任务时, 容器:" + containerCode + "存在出库组盘,不能生成任务"); } String fromLocationCode = container.getLocationCode(); String toLocationCode = QuantityConstant.EMPTY_STRING; @@ -349,23 +353,6 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea throw new JeecgBootException("创建出库查看任务时,没有找到出库口:" + toPortCode); } boolean success = false; - LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery(); - inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getContainerCode, containerCode).eq(InventoryDetail::getWarehouseCode, warehouseCode) - .eq(InventoryDetail::getLocationCode, fromLocationCode); - List<InventoryDetail> inventoryDetailList = inventoryDetailService.list(inventoryDetailLambdaQueryWrapper); - List<InventoryDetail> inventoryDetailList1 = new ArrayList<>(); - if (inventoryDetailList.size() != 0) { - for (InventoryDetail inventoryDetail : inventoryDetailList) { - InventoryDetail inventoryDetail1 = new InventoryDetail(); - inventoryDetail1.setId(inventoryDetail.getId()); - inventoryDetail1.setTaskQty(inventoryDetail.getQty()); - inventoryDetailList1.add(inventoryDetail1); - } - success = inventoryDetailService.updateBatchById(inventoryDetailList1); - if (!success) { - throw new JeecgBootException("创建出库查看任务时,更新库存详情失败"); - } - } TaskHeader taskHeader = new TaskHeader(); taskHeader.setWarehouseCode(warehouseCode); taskHeader.setTaskType(QuantityConstant.TASK_TYPE_CHECK_OUT); @@ -386,6 +373,98 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea @Override @Transactional(rollbackFor = Exception.class) + public Result createQualityTask(String containerCode, String toPortCode, String warehouseCode) { + log.info("开始创建质检任务,容器编码" + containerCode + "目标站台号" + toPortCode); + if (StringUtils.isEmpty(containerCode)) { + return Result.error("创建质检任务失败,容器编码为空"); + } + if (StringUtils.isEmpty(toPortCode)) { + return Result.error("创建质检任务失败,目标站台号为空"); + } + if (StringUtils.isEmpty(warehouseCode)) { + return Result.error("创建质检任务失败,仓库编码为空"); + } + Container container = containerService.getContainerByCode(containerCode, warehouseCode); + if (container == null) { + return Result.error("创建质检任务失败,容器为空"); + } + // 校验入库组盘 + if (receiptContainerHeaderService.havaUnCompleteCombineByContainerCode(containerCode, warehouseCode)) { + return Result.error("创建质检任务失败,容器:" + containerCode + "存在入库组盘,不能生成任务"); + } + // 校验出库组盘 + if (shipmentContainerHeaderService.havaUnCompleteCombineByContainerCode(containerCode, warehouseCode)) { + return Result.error("创建质检任务失败, 容器:" + containerCode + "存在出库组盘,不能生成任务"); + } + String fromLocationCode = container.getLocationCode(); + String toLocationCode = QuantityConstant.EMPTY_STRING; + String value = parameterConfigurationService.getValueByCode(QuantityConstant.RULE_TASK_LOCATION, container.getZoneCode()); + int taskLocationRule = Integer.parseInt(value); + if (taskLocationRule == QuantityConstant.RULE_TASK_SET_LOCATION) { + toLocationCode = fromLocationCode; + } + Result result = + taskHeaderService.createTaskLockContainerAndLocation(QuantityConstant.TASK_TYPE_QUALITY, containerCode, fromLocationCode, toLocationCode, warehouseCode); + if (!result.isSuccess()) { + throw new JeecgBootException(result.getMessage()); + } + TaskLockEntity taskLockEntity = (TaskLockEntity)result.getResult(); + String zoneCode = taskLockEntity.getZoneCode(); + Port port = portService.getPortByCode(toPortCode, zoneCode, warehouseCode); + if (port == null) { + throw new JeecgBootException("创建质检任务失败,没有找到出库口:" + toPortCode); + } + boolean success = false; + TaskHeader taskHeader = new TaskHeader(); + taskHeader.setWarehouseCode(warehouseCode); + taskHeader.setTaskType(QuantityConstant.TASK_TYPE_QUALITY); + taskHeader.setInnernalTaskType(QuantityConstant.TASK_INTENERTYPE_CYCLECOUNT); + taskHeader.setContainerCode(containerCode); + taskHeader.setZoneCode(zoneCode); + taskHeader.setFromLocationCode(fromLocationCode); + taskHeader.setToPortCode(toPortCode); + taskHeader.setToLocationCode(toLocationCode); + taskHeader.setStatus(QuantityConstant.TASK_STATUS_BUILD); + success = taskHeaderService.save(taskHeader); + log.info("创建质检任务失败,容器编码" + containerCode + "目标站台号" + toPortCode); + if (!success) { + throw new JeecgBootException("创建质检任务失败, 创建任务失败"); + } + LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery(); + inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getContainerCode, containerCode).eq(InventoryDetail::getWarehouseCode, warehouseCode) + .eq(InventoryDetail::getLocationCode, fromLocationCode); + List<InventoryDetail> inventoryDetailList = inventoryDetailService.list(inventoryDetailLambdaQueryWrapper); + List<TaskDetail> taskDetailList = new ArrayList<>(); + if (inventoryDetailList.size() != 0) { + for (InventoryDetail inventoryDetail : inventoryDetailList) { + TaskDetail taskDetail = new TaskDetail(); + taskDetail.setTaskHeaderId(taskHeader.getId()); + taskDetail.setTaskType(QuantityConstant.TASK_TYPE_QUALITY); + taskDetail.setWarehouseCode(warehouseCode); + taskDetail.setCompanyCode(inventoryDetail.getCompanyCode()); + taskDetail.setMaterialCode(inventoryDetail.getMaterialCode()); + taskDetail.setMaterialName(inventoryDetail.getMaterialName()); + taskDetail.setMaterialSpec(inventoryDetail.getMaterialSpec()); + taskDetail.setMaterialUnit(inventoryDetail.getMaterialUnit()); + taskDetail.setFromInventoryDetailId(inventoryDetail.getId()); + taskDetail.setInventoryStatus(inventoryDetail.getInventoryStatus()); + taskDetail.setQty(inventoryDetail.getQty()); + taskDetail.setBatch(inventoryDetail.getBatch()); + taskDetail.setLot(inventoryDetail.getLot()); + taskDetail.setProject(inventoryDetail.getProject()); + taskDetail.setReceiveTime(inventoryDetail.getReceiveTime()); + taskDetailList.add(taskDetail); + } + success = taskDetailService.saveBatch(taskDetailList); + if (!success) { + throw new JeecgBootException("创建质检任务失败,增加任务详情失败"); + } + } + return Result.OK("创建质检任务成功"); + } + + @Override + @Transactional(rollbackFor = Exception.class) public Result createOverStationTask(String containerCode, String fromPortCode, String toPortCode, String warehouseCode) { log.info("开始创建跨站任务,容器编码" + containerCode + ",起始站台号" + fromPortCode + ",目标站台号" + toPortCode); if (StringUtils.isEmpty(containerCode)) { @@ -869,6 +948,9 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea case QuantityConstant.TASK_TYPE_MANY_EMPTYSHIPMENT: result = taskHeaderService.completeManyEmptyOutTask(taskHeader); break; + case QuantityConstant.TASK_TYPE_QUALITY: + result = taskHeaderService.completeQualityTask(taskHeader); + break; default: throw new JeecgBootException("不支持的任务类型" + taskType); } @@ -892,7 +974,6 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea } // 保存历史任务表 taskHeaderHistoryService.saveById(taskHeader.getId()); - if (!taskHeaderService.removeById(taskId)) { throw new JeecgBootException("取消任务失败, 删除任务失败"); } @@ -1605,6 +1686,7 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea case QuantityConstant.TASK_TYPE_CYCLECOUNT: case QuantityConstant.TASK_TYPE_TRANSFER: case QuantityConstant.TASK_TYPE_CHECK_OUT: + case QuantityConstant.TASK_TYPE_QUALITY: result = taskHeaderService.createSortTaskLockContainerAndLocation(containerCode, fromLocationCode, toLocationCode, warehouseCode); break; case QuantityConstant.TASK_TYPE_OVER_STATION: @@ -1826,6 +1908,7 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea case QuantityConstant.TASK_TYPE_CYCLECOUNT: case QuantityConstant.TASK_TYPE_TRANSFER: case QuantityConstant.TASK_TYPE_CHECK_OUT: + case QuantityConstant.TASK_TYPE_QUALITY: if (StringUtils.isEmpty(fromLocationCode)) { return Result.error("任务类型" + taskType + "完成任务时, 起始库位编码为空"); } @@ -2135,6 +2218,30 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea return Result.ok("切换任务成功"); } + @Override + @Transactional(rollbackFor = Exception.class) + public Result qualityRegister(int id, BigDecimal qualityfiedQty, BigDecimal unqualityfiedQty, String remark) { + TaskDetail taskDetail = taskDetailService.getById(id); + if (taskDetail == null) { + return Result.error("质检登记失败,没有找到对应任务详情" + id); + } + BigDecimal qty = taskDetail.getQty(); + BigDecimal totalQty = qualityfiedQty.add(unqualityfiedQty); + if (qty.compareTo(totalQty) != 0) { + return Result.error("质检登记失败,质检数量必须等于任务数量"); + } + + TaskDetail taskDetail1 = new TaskDetail(); + taskDetail1.setId(id); + taskDetail1.setQualityfiedQty(qualityfiedQty); + taskDetail1.setUnqualityfiedQty(unqualityfiedQty); + taskDetail1.setRemark(remark); + if (!taskDetailService.updateById(taskDetail1)) { + throw new JeecgBootException("质检登记失败, 保存质检记录失败"); + } + return Result.ok("质检登记成功"); + } + /** * 完成空托盘入库任务 * @param taskHeader 任务 @@ -2627,8 +2734,6 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea if (inventoryDetailList.size() != 0) { List<InventoryDetail> inventoryDetailList1 = new ArrayList<>(); for (InventoryDetail inventoryDetail : inventoryDetailList) { - inventoryDetail.setTaskQty(BigDecimal.ZERO); - inventoryDetail.setLocationCode(toLocationCode); InventoryDetail inventoryDetail1 = new InventoryDetail(); inventoryDetail1.setId(inventoryDetail.getId()); inventoryDetail1.setLocationCode(toLocationCode); @@ -2809,6 +2914,134 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea return Result.ok("完成空托盘组出库任务成功"); } + @Override + @Transactional(rollbackFor = Exception.class) + public Result completeQualityTask(TaskHeader taskHeader) { + log.info("开始完成质检任务" + taskHeader.getId()); + String warehouseCode = taskHeader.getWarehouseCode(); + String containerCode = taskHeader.getContainerCode(); + String fromLocationCode = taskHeader.getFromLocationCode(); + String toLocationCode = taskHeader.getToLocationCode(); + String toPortCode = taskHeader.getToPortCode(); + + if (StringUtils.isEmpty(containerCode)) { + return Result.error("完成质检任务时, 托盘号为空"); + } + if (StringUtils.isEmpty(warehouseCode)) { + return Result.error("完成质检任务时, 仓库编码为空"); + } + if (StringUtils.isEmpty(fromLocationCode)) { + return Result.error("完成质检任务时, 起始库位编码为空"); + } + if (StringUtils.isEmpty(toPortCode)) { + return Result.error("完成质检任务时, 目标出入口号为空"); + } + if (StringUtils.isEmpty(toLocationCode)) { + return Result.error("完成质检任务时, 目标库位编码为空"); + } + + List<TaskDetail> taskDetailList = taskDetailService.getTaskDetailListByTaskId(taskHeader.getId()); + if (CollectionUtils.isEmpty(taskDetailList)) { + return Result.error("完成质检任务时, 没有对应任务详情"); + } + boolean success = false; + for (TaskDetail taskDetail : taskDetailList) { + InventoryDetail inventoryDetail = inventoryDetailService.getById(taskDetail.getFromInventoryDetailId()); + if (inventoryDetail == null) { + throw new JeecgBootException("完成质检任务时, 没有找到匹配的库存"); + } + BigDecimal qualityfiedQty = taskDetail.getQualityfiedQty(); + BigDecimal unqualityfiedQty = taskDetail.getUnqualityfiedQty(); + + QualityDetail qualityDetail = new QualityDetail(); + qualityDetail.setType(QuantityConstant.QUALITY_TYPE_INHOUSE_FULL); + qualityDetail.setMaterialCode(taskDetail.getMaterialCode()); + qualityDetail.setMaterialName(taskDetail.getMaterialName()); + qualityDetail.setMaterialUnit(taskDetail.getMaterialUnit()); + qualityDetail.setMaterialSpec(taskDetail.getMaterialSpec()); + qualityDetail.setQty(taskDetail.getQty()); + qualityDetail.setQualityfiedQty(qualityfiedQty); + qualityDetail.setUnqualityfiedQty(unqualityfiedQty); + qualityDetail.setRemark(taskDetail.getRemark()); + qualityDetail.setCompanyCode(taskDetail.getCompanyCode()); + qualityDetail.setBatch(taskDetail.getBatch()); + qualityDetail.setLot(taskDetail.getLot()); + qualityDetail.setProject(taskDetail.getProject()); + qualityDetail.setStatus(QuantityConstant.QUALITY_HEADER_COMPLETE); + if (!qualityDetailService.save(qualityDetail)) { + throw new JeecgBootException("质检登记失败, 保存质检记录失败"); + } + + if (qualityfiedQty.compareTo(BigDecimal.ZERO) > 0) { + if (!inventoryDetailService.updateQtyById(qualityfiedQty, inventoryDetail.getId())) { + throw new JeecgBootException("完成质检任务时, 更新库存失败"); + } + } else { + if (!inventoryDetailService.removeById(inventoryDetail.getId())) { + throw new JeecgBootException("完成质检任务时, 删除库存失败"); + } + } + if (qualityfiedQty.compareTo(BigDecimal.ZERO) == 0 && unqualityfiedQty.compareTo(BigDecimal.ZERO) == 0) { + throw new JeecgBootException("完成质检任务时, 没有质检登记"); + } + List<InventoryTransaction> inventoryTransactionList = new ArrayList<>(); + if (qualityfiedQty.compareTo(BigDecimal.ZERO) > 0) { + InventoryTransaction inventoryTransaction = new InventoryTransaction(); + inventoryTransaction.setType(QuantityConstant.INVENTORY_TRANSACTION_QUALITY); + inventoryTransaction.setWarehouseCode(taskDetail.getWarehouseCode()); + inventoryTransaction.setCompanyCode(taskDetail.getCompanyCode()); + inventoryTransaction.setContainerCode(containerCode); + inventoryTransaction.setZoneCode(taskHeader.getZoneCode()); + inventoryTransaction.setFromLocationCode(fromLocationCode); + inventoryTransaction.setToLocationCode(toLocationCode); + inventoryTransaction.setMaterialCode(taskDetail.getMaterialCode()); + inventoryTransaction.setMaterialName(taskDetail.getMaterialName()); + inventoryTransaction.setMaterialSpec(taskDetail.getMaterialSpec()); + inventoryTransaction.setMaterialUnit(taskDetail.getMaterialUnit()); + inventoryTransaction.setBatch(taskDetail.getBatch()); + inventoryTransaction.setLot(taskDetail.getLot()); + inventoryTransaction.setProject(taskDetail.getProject()); + inventoryTransaction.setInventoryStatus(QuantityConstant.QUALITY_GOOD); + inventoryTransaction.setQty(qualityfiedQty); + inventoryTransactionList.add(inventoryTransaction); + } + if (unqualityfiedQty.compareTo(BigDecimal.ZERO) > 0) { + InventoryTransaction inventoryTransaction = new InventoryTransaction(); + inventoryTransaction.setType(QuantityConstant.INVENTORY_TRANSACTION_QUALITY); + inventoryTransaction.setWarehouseCode(taskDetail.getWarehouseCode()); + inventoryTransaction.setCompanyCode(taskDetail.getCompanyCode()); + inventoryTransaction.setContainerCode(containerCode); + inventoryTransaction.setZoneCode(taskHeader.getZoneCode()); + inventoryTransaction.setFromLocationCode(fromLocationCode); + inventoryTransaction.setToLocationCode(toLocationCode); + inventoryTransaction.setMaterialCode(taskDetail.getMaterialCode()); + inventoryTransaction.setMaterialName(taskDetail.getMaterialName()); + inventoryTransaction.setMaterialSpec(taskDetail.getMaterialSpec()); + inventoryTransaction.setMaterialUnit(taskDetail.getMaterialUnit()); + inventoryTransaction.setBatch(taskDetail.getBatch()); + inventoryTransaction.setLot(taskDetail.getLot()); + inventoryTransaction.setProject(taskDetail.getProject()); + inventoryTransaction.setInventoryStatus(QuantityConstant.QUALITY_DEFECTIVE); + inventoryTransaction.setQty(unqualityfiedQty); + inventoryTransactionList.add(inventoryTransaction); + } + if (!inventoryTransactionService.saveBatch(inventoryTransactionList)) { + throw new JeecgBootException("完成质检任务时,增加库存交易记录失败"); + } + } + Result result = taskHeaderService.completeTaskUnLockContainerAndLocation(taskHeader.getContainerFillStatus(), QuantityConstant.TASK_TYPE_QUALITY, + containerCode, fromLocationCode, toLocationCode, warehouseCode); + if (!result.isSuccess()) { + throw new JeecgBootException(result.getMessage()); + } + success = taskHeaderService.updateStatusById(QuantityConstant.TASK_STATUS_COMPLETED, taskHeader.getId()); + log.info("完成质检任务" + taskHeader.getId()); + if (!success) { + throw new JeecgBootException("完成质检任务时,保存任务失败"); + } + return Result.ok("完成质检任务"); + } + /** * 取消入库任务 * @param taskHeader 任务 diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/constant/QuantityConstant.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/constant/QuantityConstant.java index aa49a40..06a4516 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/constant/QuantityConstant.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/constant/QuantityConstant.java @@ -201,6 +201,12 @@ public class QuantityConstant { /** 空托盘组出库 */ public static final int TASK_TYPE_MANY_EMPTYSHIPMENT = 1200; + /** 空托盘组换站 */ + public static final int TASK_TYPE_MANY_EMPTYSHIPMENT_OVER_STATION = 1300; + + /** 质检 */ + public static final int TASK_TYPE_QUALITY = 1400; + // 7、任务状态 /** 生成任务 */ diff --git a/huaheng-wms-core/src/main/resources/application-dev.yml b/huaheng-wms-core/src/main/resources/application-dev.yml index de768bd..c0620b9 100644 --- a/huaheng-wms-core/src/main/resources/application-dev.yml +++ b/huaheng-wms-core/src/main/resources/application-dev.yml @@ -136,7 +136,7 @@ spring: connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000 datasource: master: - url: jdbc:log4jdbc:mysql://localhost:3306/wms4?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&autoReconnect=true&maxReconnects=9999 + url: jdbc:log4jdbc:mysql://localhost:3306/wms4?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true username: root password: 123456 driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy diff --git a/huaheng-wms-core/src/main/resources/application-prod.yml b/huaheng-wms-core/src/main/resources/application-prod.yml index 0d5f5be..b85c196 100644 --- a/huaheng-wms-core/src/main/resources/application-prod.yml +++ b/huaheng-wms-core/src/main/resources/application-prod.yml @@ -136,7 +136,7 @@ spring: connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000 datasource: master: - url: jdbc:mysql://172.16.29.45:3306/wms4?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&autoReconnect=true&maxReconnects=9999 + url: jdbc:mysql://172.16.29.45:3306/wms4?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true username: root password: hhsoftware driver-class-name: com.mysql.cj.jdbc.Driver diff --git a/huaheng-wms-core/src/main/resources/application-test.yml b/huaheng-wms-core/src/main/resources/application-test.yml index 3f1a0e1..f9a38b7 100644 --- a/huaheng-wms-core/src/main/resources/application-test.yml +++ b/huaheng-wms-core/src/main/resources/application-test.yml @@ -137,7 +137,7 @@ spring: datasource: master: # mysql数据源配置 - url: jdbc:log4jdbc:mysql://172.16.29.45:3306/wms4?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&autoReconnect=true&maxReconnects=9999 + url: jdbc:log4jdbc:mysql://172.16.29.45:3306/wms4?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true username: root password: hhsoftware driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy