Commit 416f0a7e2166bcedcee49c5b91a1e129c5205b25

Authored by 肖超群
1 parent 1bed0ead

1.开发生成出库任务接口

2.开发完成出库任务接口
Showing 36 changed files with 1578 additions and 34 deletions
jeecg-boot-master/ant-design-vue-jeecg/src/api/api.js
... ... @@ -106,9 +106,11 @@ export const getReceiptTypeList = (params)=>getAction('/config/receiptType/getRe
106 106 export const getShipmentTypeList = (params)=>getAction('/config/shipmentType/getShipmentTypeList', params);
107 107 export const searchMaterialByCode = (params)=>postAction('/config/material/searchMaterialByCode', params);
108 108 export const listReceiveByReceiptId = (params)=>postAction('/receipt/receiveHeader/listReceiveByReceiptId', params);
109   -export const createTask = (params)=>postAction('/receipt/receiptContainerHeader/createTask', params);
  109 +export const createReceiptTask = (params)=>postAction('/receipt/receiptContainerHeader/createReceiptTask', params);
110 110 export const completeTaskByWMS = (params)=>postAction('/task/taskHeader/completeTaskByWMS', params);
111 111 export const execute = (params)=>postAction('/task/taskHeader/execute', params);
  112 +export const autoCombination = (params)=>postAction('/shipment/shipmentCombination/autoCombination', params);
  113 +export const createShipmentTask = (params)=>postAction('/shipment/shipmentCombination/createShipmentTask', params);
112 114  
113 115 // 中转HTTP请求
114 116 export const transitRESTful = {
... ...
jeecg-boot-master/ant-design-vue-jeecg/src/views/system/receipt/ReceiptContainerHeaderList.vue
... ... @@ -149,7 +149,7 @@
149 149 import ReceiptContainerDetailList from './ReceiptContainerDetailList'
150 150 import {initDictOptions,filterMultiDictText} from '@/components/dict/JDictSelectUtil'
151 151 import '@/assets/less/TableExpand.less'
152   - import {createTask} from '@/api/api'
  152 + import {createReceiptTask} from '@/api/api'
153 153  
154 154 export default {
155 155 name: "ReceiptContainerHeaderList",
... ... @@ -290,7 +290,7 @@
290 290 const that = this;
291 291 this.model = Object.assign({}, record);
292 292 that.querySource.id = record.id;
293   - createTask(that.querySource).then((res) => {
  293 + createReceiptTask(that.querySource).then((res) => {
294 294 this.loading = false;
295 295 if (res.success) {
296 296 this.$message.success(res.message);
... ...
jeecg-boot-master/ant-design-vue-jeecg/src/views/system/receipt/ReceiptHeaderList.vue
... ... @@ -390,7 +390,7 @@
390 390 this.dataSource = res.result.records;
391 391 this.ipagination.total = res.result.total;
392 392 }
393   - if(res.code===510){
  393 + if(res.code===510) {
394 394 this.$message.warning(res.message)
395 395 }
396 396 this.loading = false;
... ...
jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentContainerHeaderList.vue
... ... @@ -62,7 +62,7 @@
62 62 </a-form>
63 63 </div>
64 64 <!-- 查询区域-END -->
65   -
  65 +
66 66 <!-- 操作按钮区域 -->
67 67 <div class="table-operator">
68 68 <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
... ... @@ -118,7 +118,8 @@
118 118  
119 119 <span slot="action" slot-scope="text, record">
120 120 <a @click="handleEdit(record)">编辑</a>
121   -
  121 + <a-divider type="vertical" />
  122 + <a v-if="record.status == 0" @click="createTask(record)">生成任务</a>
122 123 <a-divider type="vertical" />
123 124 <a-dropdown>
124 125 <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
... ... @@ -153,6 +154,7 @@
153 154 import ShipmentContainerDetailList from './ShipmentContainerDetailList'
154 155 import {initDictOptions,filterMultiDictText} from '@/components/dict/JDictSelectUtil'
155 156 import '@/assets/less/TableExpand.less'
  157 + import {createShipmentTask} from '@/api/api'
156 158  
157 159 export default {
158 160 name: "ShipmentContainerHeaderList",
... ... @@ -164,6 +166,7 @@
164 166 data () {
165 167 return {
166 168 description: '出库组盘管理页面',
  169 + querySource:{},
167 170 // 表头
168 171 columns: [
169 172 {
... ... @@ -282,6 +285,22 @@
282 285 this.selectedRowKeys = selectedRowKeys;
283 286 this.selectionRows = selectionRows;
284 287 },
  288 + createTask(record) {
  289 + this.loading = true;
  290 + const that = this;
  291 + this.model = Object.assign({}, record);
  292 + that.querySource.id = record.id;
  293 + createShipmentTask(that.querySource).then((res) => {
  294 + this.loading = false;
  295 + if (res.success) {
  296 + this.$message.success(res.message);
  297 + }
  298 + else {
  299 + this.$message.error(res.message);
  300 + }
  301 + this.searchQuery();
  302 + });
  303 + },
285 304 loadData(arg) {
286 305 if(!this.url.list){
287 306 this.$message.error("请设置url.list属性!")
... ...
jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentDetailList.vue
... ... @@ -112,14 +112,9 @@
112 112 // 表头
113 113 columns: [
114 114 {
115   - title: '#',
116   - dataIndex: '',
117   - key:'rowIndex',
118   - width:60,
  115 + title:'单据详情ID',
119 116 align:"center",
120   - customRender:function (t,r,index) {
121   - return parseInt(index)+1;
122   - }
  117 + dataIndex: 'id'
123 118 },
124 119 {
125 120 title:'物料编码',
... ... @@ -164,7 +159,7 @@
164 159 {
165 160 title:'单据状态',
166 161 align:"center",
167   - dataIndex: 'status'
  162 + dataIndex: 'status_dictText',
168 163 },
169 164 {
170 165 title:'创建人',
... ...
jeecg-boot-master/ant-design-vue-jeecg/src/views/system/shipment/ShipmentHeaderList.vue
... ... @@ -166,6 +166,8 @@
166 166 </template>
167 167  
168 168 <span slot="action" slot-scope="text, record">
  169 + <a @click="autoShipmentCombine(record)">自动配盘</a>
  170 + <a-divider type="vertical" />
169 171 <a @click="handleEdit(record)">编辑</a>
170 172  
171 173 <a-divider type="vertical" />
... ... @@ -205,6 +207,7 @@
205 207 import {getCompanyList} from '@/api/api'
206 208 import {getShipmentTypeList} from '@/api/api'
207 209 import {getCustomerList} from '@/api/api'
  210 + import {autoCombination} from '@/api/api'
208 211  
209 212 export default {
210 213 name: "ShipmentHeaderList",
... ... @@ -416,6 +419,18 @@
416 419 })
417 420 return actions.join('')
418 421 },
  422 + autoShipmentCombine(record) {
  423 + this.loading = true;
  424 + autoCombination(record).then((res) => {
  425 + if (res.success) {
  426 + this.$message.success(res.message);
  427 + } else {
  428 + this.$message.warning(res.message)
  429 + }
  430 + this.loading = false;
  431 + this.searchQuery();
  432 + });
  433 + },
419 434 loadData(arg) {
420 435 if(!this.url.list){
421 436 this.$message.error("请设置url.list属性!")
... ...
jeecg-boot-master/ant-design-vue-jeecg/src/views/system/task/TaskHeaderList.vue renamed to jeecg-boot-master/ant-design-vue-jeecg/src/views/system/task/ReceiptTaskHeaderList.vue
... ... @@ -341,6 +341,7 @@
341 341 }
342 342 this.onClearSelected()
343 343 var params = this.getQueryParams();//查询条件
  344 + params.innernalTaskType = 100;
344 345 this.loading = true;
345 346 getAction(this.url.list, params).then((res) => {
346 347 if (res.success) {
... ...
jeecg-boot-master/ant-design-vue-jeecg/src/views/system/task/ShipmentTaskHeaderList.vue 0 → 100644
  1 +<template>
  2 + <a-card :bordered="false">
  3 + <!-- 查询区域 -->
  4 + <div class="table-page-search-wrapper">
  5 + <a-form layout="inline" @keyup.enter.native="searchQuery">
  6 + <a-row :gutter="24">
  7 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
  8 + <a-form-item label="任务类型">
  9 + <j-dict-select-tag placeholder="请选择任务类型" v-model="queryParam.taskType" dictCode="task_type"/>
  10 + </a-form-item>
  11 + </a-col>
  12 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
  13 + <a-form-item label="容器号">
  14 + <a-input placeholder="请输入容器号" v-model="queryParam.containerCode"></a-input>
  15 + </a-form-item>
  16 + </a-col>
  17 + <template v-if="toggleSearchStatus">
  18 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
  19 + <a-form-item label="起始库位">
  20 + <a-input placeholder="请输入起始库位" v-model="queryParam.fromLocationCode"></a-input>
  21 + </a-form-item>
  22 + </a-col>
  23 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
  24 + <a-form-item label="目标库位">
  25 + <a-input placeholder="请输入目标库位" v-model="queryParam.toLocationCode"></a-input>
  26 + </a-form-item>
  27 + </a-col>
  28 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
  29 + <a-form-item label="是否空出">
  30 + <j-dict-select-tag placeholder="请选择是否空出" v-model="queryParam.isEmptyOut" dictCode="is_or_not"/>
  31 + </a-form-item>
  32 + </a-col>
  33 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
  34 + <a-form-item label="是否重入">
  35 + <j-dict-select-tag placeholder="请选择是否重入" v-model="queryParam.isDoubleIn" dictCode="is_or_not"/>
  36 + </a-form-item>
  37 + </a-col>
  38 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
  39 + <a-form-item label="重入库位号">
  40 + <a-input placeholder="请输入重入库位号" v-model="queryParam.originLocationCode"></a-input>
  41 + </a-form-item>
  42 + </a-col>
  43 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
  44 + <a-form-item label="任务状态">
  45 + <j-dict-select-tag placeholder="请选择任务状态" v-model="queryParam.status" dictCode="task_header_status"/>
  46 + </a-form-item>
  47 + </a-col>
  48 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
  49 + <a-form-item label="起始出入口">
  50 + <a-input placeholder="请输入起始出入口" v-model="queryParam.fromPort"></a-input>
  51 + </a-form-item>
  52 + </a-col>
  53 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
  54 + <a-form-item label="目标出入口">
  55 + <a-input placeholder="请输入目标出入口" v-model="queryParam.toPort"></a-input>
  56 + </a-form-item>
  57 + </a-col>
  58 + <a-col :xl="10" :lg="11" :md="12" :sm="24">
  59 + <a-form-item label="创建日期">
  60 + <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>
  61 + <span class="query-group-split-cust"></span>
  62 + <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>
  63 + </a-form-item>
  64 + </a-col>
  65 + </template>
  66 + <a-col :xl="6" :lg="7" :md="8" :sm="24">
  67 + <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
  68 + <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
  69 + <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
  70 + <a @click="handleToggleSearch" style="margin-left: 8px">
  71 + {{ toggleSearchStatus ? '收起' : '展开' }}
  72 + <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
  73 + </a>
  74 + </span>
  75 + </a-col>
  76 + </a-row>
  77 + </a-form>
  78 + </div>
  79 + <!-- 查询区域-END -->
  80 +
  81 + <!-- 操作按钮区域 -->
  82 +<!-- <div class="table-operator">-->
  83 +<!-- <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>-->
  84 +<!-- <a-button type="primary" icon="download" @click="handleExportXls('任务表')">导出</a-button>-->
  85 +<!-- <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">-->
  86 +<!-- <a-button type="primary" icon="import">导入</a-button>-->
  87 +<!-- </a-upload>-->
  88 +<!-- &lt;!&ndash; 高级查询区域 &ndash;&gt;-->
  89 +<!-- <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>-->
  90 +<!-- </div>-->
  91 +
  92 + <!-- table区域-begin -->
  93 + <div>
  94 + <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
  95 + <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
  96 + <a style="margin-left: 24px" @click="onClearSelected">清空</a>
  97 + </div>
  98 +
  99 + <a-table
  100 + ref="table"
  101 + size="middle"
  102 + bordered
  103 + rowKey="id"
  104 + class="j-table-force-nowrap"
  105 + :scroll="{x:true}"
  106 + :columns="columns"
  107 + :dataSource="dataSource"
  108 + :pagination="ipagination"
  109 + :loading="loading"
  110 + :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type:'radio'}"
  111 + :customRow="clickThenSelect"
  112 + @change="handleTableChange">
  113 +
  114 + <template slot="htmlSlot" slot-scope="text">
  115 + <div v-html="text"></div>
  116 + </template>
  117 + <template slot="imgSlot" slot-scope="text">
  118 + <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
  119 + <img v-else :src="getImgView(text)" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
  120 + </template>
  121 + <template slot="fileSlot" slot-scope="text">
  122 + <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
  123 + <a-button
  124 + v-else
  125 + :ghost="true"
  126 + type="primary"
  127 + icon="download"
  128 + size="small"
  129 + @click="downloadFile(text)">
  130 + 下载
  131 + </a-button>
  132 + </template>
  133 +
  134 + <span slot="action" slot-scope="text, record">
  135 + <a v-if="record.status == 1" @click="executeTask(record)">执行</a>
  136 + <a-divider type="vertical" />
  137 + <a v-if="record.status < 100" @click="completeTask(record)">完成</a>
  138 + <a-divider type="vertical" />
  139 + <a-dropdown>
  140 + <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
  141 + <a-menu slot="overlay">
  142 + <a-menu-item>
  143 + <a @click="handleEdit(record)">编辑</a>
  144 + </a-menu-item>
  145 + <a-menu-item>
  146 + <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
  147 + <a>删除</a>
  148 + </a-popconfirm>
  149 + </a-menu-item>
  150 + </a-menu>
  151 + </a-dropdown>
  152 + </span>
  153 +
  154 + </a-table>
  155 + </div>
  156 +
  157 + <a-tabs defaultActiveKey="1">
  158 + <a-tab-pane tab="任务详情" key="1" >
  159 + <TaskDetailList :mainId="selectedMainId" />
  160 + </a-tab-pane>
  161 + </a-tabs>
  162 +
  163 + <taskHeader-modal ref="modalForm" @ok="modalFormOk"></taskHeader-modal>
  164 + </a-card>
  165 +</template>
  166 +
  167 +<script>
  168 +
  169 + import { JeecgListMixin } from '@/mixins/JeecgListMixin'
  170 + import TaskHeaderModal from './modules/TaskHeaderModal'
  171 + import { getAction } from '@/api/manage'
  172 + import TaskDetailList from './TaskDetailList'
  173 + import {initDictOptions,filterMultiDictText} from '@/components/dict/JDictSelectUtil'
  174 + import '@/assets/less/TableExpand.less'
  175 + import {completeTaskByWMS} from '@/api/api'
  176 + import {execute} from '@/api/api'
  177 +
  178 + export default {
  179 + name: "TaskHeaderList",
  180 + mixins:[JeecgListMixin],
  181 + components: {
  182 + TaskDetailList,
  183 + TaskHeaderModal
  184 + },
  185 + data () {
  186 + return {
  187 + description: '任务表管理页面',
  188 + // 表头
  189 + columns: [
  190 + {
  191 + title:'任务ID',
  192 + align:"center",
  193 + dataIndex: 'id',
  194 + },
  195 + {
  196 + title:'任务类型',
  197 + align:"center",
  198 + dataIndex: 'taskType_dictText',
  199 + },
  200 + {
  201 + title:'容器号',
  202 + align:"center",
  203 + dataIndex: 'containerCode'
  204 + },
  205 + {
  206 + title:'起始库位',
  207 + align:"center",
  208 + dataIndex: 'fromLocationCode'
  209 + },
  210 + {
  211 + title:'目标库位',
  212 + align:"center",
  213 + dataIndex: 'toLocationCode'
  214 + },
  215 + // {
  216 + // title:'是否空出',
  217 + // align:"center",
  218 + // dataIndex: 'isEmptyOut_dictText',
  219 + // },
  220 + {
  221 + title:'是否重入',
  222 + align:"center",
  223 + dataIndex: 'isDoubleIn_dictText',
  224 + },
  225 + {
  226 + title:'重入库位号',
  227 + align:"center",
  228 + dataIndex: 'originLocationCode'
  229 + },
  230 + {
  231 + title:'任务状态',
  232 + align:"center",
  233 + dataIndex: 'status_dictText',
  234 + },
  235 + {
  236 + title:'起始出入口',
  237 + align:"center",
  238 + dataIndex: 'fromPort'
  239 + },
  240 + {
  241 + title:'目标出入口',
  242 + align:"center",
  243 + dataIndex: 'toPort'
  244 + },
  245 + {
  246 + title:'创建人',
  247 + align:"center",
  248 + dataIndex: 'createBy'
  249 + },
  250 + {
  251 + title:'创建日期',
  252 + align:"center",
  253 + dataIndex: 'createTime'
  254 + },
  255 + {
  256 + title:'更新人',
  257 + align:"center",
  258 + dataIndex: 'updateBy'
  259 + },
  260 + {
  261 + title:'更新日期',
  262 + align:"center",
  263 + dataIndex: 'updateTime'
  264 + },
  265 + {
  266 + title: '操作',
  267 + dataIndex: 'action',
  268 + align:"center",
  269 + fixed:"right",
  270 + width:147,
  271 + scopedSlots: { customRender: 'action' },
  272 + }
  273 + ],
  274 + url: {
  275 + list: "/task/taskHeader/list",
  276 + delete: "/task/taskHeader/delete",
  277 + deleteBatch: "/task/taskHeader/deleteBatch",
  278 + exportXlsUrl: "/task/taskHeader/exportXls",
  279 + importExcelUrl: "task/taskHeader/importExcel",
  280 + },
  281 + dictOptions:{
  282 + taskType:[],
  283 + isEmptyOut:[],
  284 + isDoubleIn:[],
  285 + status:[],
  286 + },
  287 + /* 分页参数 */
  288 + ipagination:{
  289 + current: 1,
  290 + pageSize: 5,
  291 + pageSizeOptions: ['5', '10', '50'],
  292 + showTotal: (total, range) => {
  293 + return range[0] + "-" + range[1] + " 共" + total + "条"
  294 + },
  295 + showQuickJumper: true,
  296 + showSizeChanger: true,
  297 + total: 0
  298 + },
  299 + selectedMainId:'',
  300 + superFieldList:[],
  301 + }
  302 + },
  303 + created() {
  304 + this.getSuperFieldList();
  305 + },
  306 + computed: {
  307 + importExcelUrl: function(){
  308 + return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
  309 + }
  310 + },
  311 + methods: {
  312 + initDictConfig(){
  313 + },
  314 + clickThenSelect(record) {
  315 + return {
  316 + on: {
  317 + click: () => {
  318 + this.onSelectChange(record.id.split(","), [record]);
  319 + }
  320 + }
  321 + }
  322 + },
  323 + onClearSelected() {
  324 + this.selectedRowKeys = [];
  325 + this.selectionRows = [];
  326 + this.selectedMainId=''
  327 + },
  328 + onSelectChange(selectedRowKeys, selectionRows) {
  329 + this.selectedMainId=selectedRowKeys[0]
  330 + this.selectedRowKeys = selectedRowKeys;
  331 + this.selectionRows = selectionRows;
  332 + },
  333 + loadData(arg) {
  334 + if(!this.url.list){
  335 + this.$message.error("请设置url.list属性!")
  336 + return
  337 + }
  338 + //加载数据 若传入参数1则加载第一页的内容
  339 + if (arg === 1) {
  340 + this.ipagination.current = 1;
  341 + }
  342 + this.onClearSelected()
  343 + var params = this.getQueryParams();//查询条件
  344 + params.innernalTaskType = 200; //只差出库任务
  345 + this.loading = true;
  346 + getAction(this.url.list, params).then((res) => {
  347 + if (res.success) {
  348 + this.dataSource = res.result.records;
  349 + this.ipagination.total = res.result.total;
  350 + }
  351 + if(res.code===510){
  352 + this.$message.warning(res.message)
  353 + }
  354 + this.loading = false;
  355 + })
  356 + },
  357 + completeTask(record) {
  358 + this.loading = true;
  359 + this.model = Object.assign({}, record);
  360 + completeTaskByWMS(this.model).then((res) => {
  361 + this.loading = false;
  362 + if (res.success) {
  363 + this.$message.success(res.message);
  364 + }
  365 + else {
  366 + this.$message.error(res.message);
  367 + }
  368 + this.searchQuery();
  369 + });
  370 + },
  371 + executeTask(record) {
  372 + this.loading = true;
  373 + this.model = Object.assign({}, record);
  374 + execute(this.model).then((res) => {
  375 + this.loading = false;
  376 + if (res.success) {
  377 + this.$message.success(res.message);
  378 + }
  379 + else {
  380 + this.$message.error(res.message);
  381 + }
  382 + this.searchQuery();
  383 + });
  384 + },
  385 + getSuperFieldList(){
  386 + let fieldList=[];
  387 + fieldList.push({type:'int',value:'taskType',text:'任务类型',dictCode:'task_type'})
  388 + fieldList.push({type:'string',value:'containerCode',text:'容器号',dictCode:''})
  389 + fieldList.push({type:'string',value:'fromLocationCode',text:'起始库位',dictCode:''})
  390 + fieldList.push({type:'string',value:'toLocationCode',text:'目标库位',dictCode:''})
  391 + fieldList.push({type:'string',value:'isEmptyOut',text:'是否空出',dictCode:'is_or_not'})
  392 + fieldList.push({type:'int',value:'isDoubleIn',text:'是否重入',dictCode:'is_or_not'})
  393 + fieldList.push({type:'string',value:'originLocationCode',text:'重入库位号',dictCode:''})
  394 + fieldList.push({type:'int',value:'status',text:'任务状态',dictCode:'task_header_status'})
  395 + fieldList.push({type:'string',value:'fromPort',text:'起始出入口',dictCode:''})
  396 + fieldList.push({type:'string',value:'toPort',text:'目标出入口',dictCode:''})
  397 + fieldList.push({type:'string',value:'createBy',text:'创建人',dictCode:''})
  398 + fieldList.push({type:'datetime',value:'createTime',text:'创建日期'})
  399 + fieldList.push({type:'string',value:'updateBy',text:'更新人',dictCode:''})
  400 + fieldList.push({type:'datetime',value:'updateTime',text:'更新日期'})
  401 + this.superFieldList = fieldList
  402 + }
  403 + }
  404 + }
  405 +</script>
  406 +<style scoped>
  407 + @import '~@assets/less/common.less'
  408 +</style>
0 409 \ No newline at end of file
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/config/container/service/IContainerService.java
... ... @@ -20,4 +20,6 @@ public interface IContainerService extends IService&lt;Container&gt; {
20 20  
21 21 boolean updateLocationCodeAndStatus(String containerCode, String locationCode,
22 22 String status, String warehouseCode);
  23 + //创建零时容器
  24 + Container createLSContainer(String warehouseCode);
23 25 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/config/container/service/impl/ContainerServiceImpl.java
1 1 package org.jeecg.modules.wms.config.container.service.impl;
2 2  
  3 +import com.aliyun.oss.ServiceException;
3 4 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
4 5 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
5 6 import org.jeecg.common.api.vo.Result;
... ... @@ -7,12 +8,15 @@ import org.jeecg.modules.wms.config.container.entity.Container;
7 8 import org.jeecg.modules.wms.config.container.mapper.ContainerMapper;
8 9 import org.jeecg.modules.wms.config.container.service.IContainerService;
9 10 import org.jeecg.modules.wms.config.containerType.service.IContainerTypeService;
  11 +import org.jeecg.utils.constant.QuantityConstant;
10 12 import org.springframework.stereotype.Service;
11 13  
12 14 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
13 15  
14 16 import javax.annotation.Resource;
  17 +import java.text.MessageFormat;
15 18 import java.util.ArrayList;
  19 +import java.util.Calendar;
16 20 import java.util.Date;
17 21 import java.util.List;
18 22  
... ... @@ -84,6 +88,21 @@ public class ContainerServiceImpl extends ServiceImpl&lt;ContainerMapper, Container
84 88 return result;
85 89 }
86 90  
  91 + @Override
  92 + public Container createLSContainer(String warehouseCode) {
  93 + String code = MessageFormat.format("{0}{1}",
  94 + "LS",
  95 + String.format("%d", Calendar.getInstance().getTimeInMillis()));
  96 + Container container = new Container();
  97 + container.setCode(code);
  98 + container.setWarehouseCode(warehouseCode);
  99 + container.setStatus(QuantityConstant.STATUS_CONTAINER_EMPTY);
  100 + if (!save(container)){
  101 + throw new ServiceException("新增容器失败");
  102 + }
  103 + return container;
  104 + }
  105 +
87 106  
88 107 private int getStartNumber(String containerTypeCode, String warehouseCode) {
89 108 LambdaQueryWrapper<Container> containerLambdaQueryWrapper = Wrappers.lambdaQuery();
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/IInventoryDetailService.java
... ... @@ -16,4 +16,6 @@ public interface IInventoryDetailService extends IService&lt;InventoryDetail&gt; {
16 16 public List<InventoryDetail> selectByMainId(String mainId);
17 17  
18 18 List<InventoryDetail> getInventoryDetailListByInventoryHeaderId(Integer inventoryHeaderId);
  19 +
  20 + List<InventoryDetail> getInventoryDetailListByContainerCode(String containerCode, String warehouseCode);
19 21 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/inventory/inventoryHeader/service/impl/InventoryDetailServiceImpl.java
... ... @@ -36,4 +36,13 @@ public class InventoryDetailServiceImpl extends ServiceImpl&lt;InventoryDetailMappe
36 36 List<InventoryDetail> inventoryDetailList = list(inventoryDetailLambdaQueryWrapper);
37 37 return inventoryDetailList;
38 38 }
  39 +
  40 + @Override
  41 + public List<InventoryDetail> getInventoryDetailListByContainerCode(String containerCode, String warehouseCode) {
  42 + LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
  43 + inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getContainerCode, containerCode)
  44 + .eq(InventoryDetail::getWarehouseCode, warehouseCode);
  45 + List<InventoryDetail> inventoryDetailList = list(inventoryDetailLambdaQueryWrapper);
  46 + return inventoryDetailList;
  47 + }
39 48 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/controller/ReceiptContainerHeaderController.java
... ... @@ -296,11 +296,11 @@ public class ReceiptContainerHeaderController extends JeecgController&lt;ReceiptCon
296 296 * @return
297 297 */
298 298 @ApiOperation(value="入库组盘-创建任务", notes="入库组盘-创建任务")
299   - @PostMapping("/createTask")
  299 + @PostMapping("/createReceiptTask")
300 300 @ResponseBody
301   - public Result createTask(@RequestBody ReceiptContainerHeader receiptContainerHeader, HttpServletRequest req) {
  301 + public Result createReceiptTask(@RequestBody ReceiptContainerHeader receiptContainerHeader, HttpServletRequest req) {
302 302 String warehouseCode = JwtUtil.getWarehouseCodeByToken(req);
303   - return receiptContainerHeaderService.createTask(receiptContainerHeader, warehouseCode);
  303 + return receiptContainerHeaderService.createReceiptTask(receiptContainerHeader, warehouseCode);
304 304 }
305 305  
306 306  
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/IReceiptContainerDetailService.java
... ... @@ -14,4 +14,6 @@ import java.util.List;
14 14 public interface IReceiptContainerDetailService extends IService<ReceiptContainerDetail> {
15 15  
16 16 public List<ReceiptContainerDetail> selectByMainId(String mainId);
  17 +
  18 + public List<ReceiptContainerDetail> getReceiptContainerDetailListByHeaderId(int receiptContainerHeaderId);
17 19 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/IReceiptContainerHeaderService.java
... ... @@ -30,7 +30,12 @@ public interface IReceiptContainerHeaderService extends IService&lt;ReceiptContaine
30 30  
31 31 ReceiptContainerHeader getUnCompleteReceiptContainerByCode(String containerCode, String warehouseCode);
32 32  
33   - public Result createTask(ReceiptContainerHeader receiptContainerHeader, String warehouseCode);
  33 + public Result createReceiptTask(ReceiptContainerHeader receiptContainerHeader, String warehouseCode);
34 34  
35 35 boolean updateStatusById(int status, int id);
  36 +
  37 + // 获取没有完成的入库组盘
  38 + List<ReceiptContainerHeader> getUnCompleteCombineList();
  39 +
  40 + boolean havaUnCompleteCombine(String containerCode, String warehouseCode);
36 41 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerDetailServiceImpl.java
1 1 package org.jeecg.modules.wms.receipt.receiptContainerHeader.service.impl;
2 2  
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
3 5 import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContainerDetail;
4 6 import org.jeecg.modules.wms.receipt.receiptContainerHeader.mapper.ReceiptContainerDetailMapper;
5 7 import org.jeecg.modules.wms.receipt.receiptContainerHeader.service.IReceiptContainerDetailService;
... ... @@ -24,4 +26,12 @@ public class ReceiptContainerDetailServiceImpl extends ServiceImpl&lt;ReceiptContai
24 26 public List<ReceiptContainerDetail> selectByMainId(String mainId) {
25 27 return receiptContainerDetailMapper.selectByMainId(mainId);
26 28 }
  29 +
  30 + @Override
  31 + public List<ReceiptContainerDetail> getReceiptContainerDetailListByHeaderId(int receiptContainerHeaderId) {
  32 + LambdaQueryWrapper<ReceiptContainerDetail> receiptContainerDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
  33 + receiptContainerDetailLambdaQueryWrapper.eq(ReceiptContainerDetail::getReceiptContainerId, receiptContainerHeaderId);
  34 + List<ReceiptContainerDetail> receiptContainerDetailList = list(receiptContainerDetailLambdaQueryWrapper);
  35 + return receiptContainerDetailList;
  36 + }
27 37 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptContainerHeader/service/impl/ReceiptContainerHeaderServiceImpl.java
... ... @@ -93,7 +93,7 @@ public class ReceiptContainerHeaderServiceImpl extends ServiceImpl&lt;ReceiptContai
93 93  
94 94 @Override
95 95 @Transactional
96   - public Result createTask(ReceiptContainerHeader receiptContainerHeader, String warehouseCode) {
  96 + public Result createReceiptTask(ReceiptContainerHeader receiptContainerHeader, String warehouseCode) {
97 97 int id = receiptContainerHeader.getId();
98 98 receiptContainerHeader = this.getById(id);
99 99 if (receiptContainerHeader == null) {
... ... @@ -107,11 +107,9 @@ public class ReceiptContainerHeaderServiceImpl extends ServiceImpl&lt;ReceiptContai
107 107 if(container.getStatus().equals(QuantityConstant.STATUS_CONTAINER_LOCK)) {
108 108 return Result.error("托盘已经锁定,不能生成任务");
109 109 }
110   - LambdaQueryWrapper<ReceiptContainerDetail> receiptContainerDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
111   - receiptContainerDetailLambdaQueryWrapper.eq(ReceiptContainerDetail::getReceiptContainerId, receiptContainerHeader.getId());
112 110 List<ReceiptContainerDetail> receiptContainerDetailList =
113   - receiptContainerDetailService.list(receiptContainerDetailLambdaQueryWrapper);
114   - if(receiptContainerDetailList.isEmpty()) {
  111 + receiptContainerDetailService.getReceiptContainerDetailListByHeaderId(receiptContainerHeader.getId());
  112 + if(receiptContainerDetailList.size() == 0) {
115 113 return Result.error("id:" + id + "的入库组盘,没有组盘明细,请先组盘!");
116 114 }
117 115 boolean result = containerService.updateStatus(containerCode,
... ... @@ -233,4 +231,26 @@ public class ReceiptContainerHeaderServiceImpl extends ServiceImpl&lt;ReceiptContai
233 231 return success;
234 232 }
235 233  
  234 + @Override
  235 + public List<ReceiptContainerHeader> getUnCompleteCombineList() {
  236 + LambdaQueryWrapper<ReceiptContainerHeader> receiptContainerHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
  237 + receiptContainerHeaderLambdaQueryWrapper
  238 + .lt(ReceiptContainerHeader::getStatus, QuantityConstant.RECEIPT_CONTAINER_FINISHED);
  239 + List<ReceiptContainerHeader> receiptContainerHeaderList = list(receiptContainerHeaderLambdaQueryWrapper);
  240 + return receiptContainerHeaderList;
  241 + }
  242 +
  243 + @Override
  244 + public boolean havaUnCompleteCombine(String containerCode, String warehouseCode) {
  245 + LambdaQueryWrapper<ReceiptContainerHeader> receiptContainerHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
  246 + receiptContainerHeaderLambdaQueryWrapper.eq(ReceiptContainerHeader::getContainerCode, containerCode)
  247 + .eq(ReceiptContainerHeader::getWarehouseCode, warehouseCode)
  248 + .lt(ReceiptContainerHeader::getStatus, QuantityConstant.RECEIPT_CONTAINER_FINISHED);
  249 + ReceiptContainerHeader receiptContainerHeader = getOne(receiptContainerHeaderLambdaQueryWrapper);
  250 + if(receiptContainerHeader != null) {
  251 + return true;
  252 + }
  253 + return false;
  254 + }
  255 +
236 256 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiptHeader/service/impl/ReceiptHeaderServiceImpl.java
... ... @@ -51,6 +51,10 @@ public class ReceiptHeaderServiceImpl extends ServiceImpl&lt;ReceiptHeaderMapper, R
51 51 @Override
52 52 @Transactional
53 53 public void delMain(String id) {
  54 + ReceiptHeader receiptHeader = getById(id);
  55 + if(receiptHeader.getFirstStatus().intValue() > QuantityConstant.RECEIPT_HEADER_BUILD) {
  56 + throw new ServiceException("不能删除非新建状态单据");
  57 + }
54 58 receiptDetailMapper.deleteByMainId(id);
55 59 receiptHeaderMapper.deleteById(id);
56 60 }
... ... @@ -59,6 +63,10 @@ public class ReceiptHeaderServiceImpl extends ServiceImpl&lt;ReceiptHeaderMapper, R
59 63 @Transactional
60 64 public void delBatchMain(Collection<? extends Serializable> idList) {
61 65 for(Serializable id:idList) {
  66 + ReceiptHeader receiptHeader = getById(id);
  67 + if(receiptHeader.getFirstStatus().intValue() > QuantityConstant.RECEIPT_HEADER_BUILD) {
  68 + throw new ServiceException("不能删除非新建状态单据");
  69 + }
62 70 receiptDetailMapper.deleteByMainId(id.toString());
63 71 receiptHeaderMapper.deleteById(id);
64 72 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiving/controller/ReceiveController.java
... ... @@ -5,6 +5,7 @@ import io.swagger.annotations.Api;
5 5 import io.swagger.annotations.ApiOperation;
6 6 import lombok.extern.slf4j.Slf4j;
7 7 import org.jeecg.common.api.vo.Result;
  8 +import org.jeecg.common.aspect.annotation.AutoLog;
8 9 import org.jeecg.common.system.query.QueryGenerator;
9 10 import org.jeecg.common.system.util.JwtUtil;
10 11 import org.jeecg.modules.wms.config.container.entity.Container;
... ... @@ -71,6 +72,7 @@ public class ReceiveController {
71 72 * 收货
72 73 * @return
73 74 */
  75 + @AutoLog("入库单-收货")
74 76 @ApiOperation(value="入库单-收货", notes="入库单-收货")
75 77 @PostMapping("/receiving")
76 78 @ResponseBody
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/receipt/receiving/service/impl/ReceiveServiceImpl.java
... ... @@ -64,7 +64,7 @@ public class ReceiveServiceImpl extends ServiceImpl&lt;ReceiveMapper, Receive&gt; imp
64 64 * 7.更新入库单状态
65 65 */
66 66 @Override
67   - @Transactional
  67 + @Transactional(rollbackFor = ServiceException.class)
68 68 public Result receiving(List<Receive> receiveList, String warehouseCode) {
69 69 boolean result = false;
70 70 if(receiveList == null || receiveList.size() == 0) {
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/controller/shipmentCombinationController.java 0 → 100644
  1 +package org.jeecg.modules.wms.shipment.shipmentCombination.controller;
  2 +
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  5 +import io.swagger.annotations.Api;
  6 +import io.swagger.annotations.ApiOperation;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +import org.jeecg.common.api.vo.Result;
  9 +import org.jeecg.common.aspect.annotation.AutoLog;
  10 +import org.jeecg.common.system.util.JwtUtil;
  11 +import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContainerHeader;
  12 +import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptHeader;
  13 +import org.jeecg.modules.wms.receipt.receiving.domain.Receive;
  14 +import org.jeecg.modules.wms.shipment.shipmentCombination.service.IShipmentCombinationService;
  15 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
  16 +import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
  17 +import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader;
  18 +import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService;
  19 +import org.jeecg.utils.StringUtils;
  20 +import org.springframework.web.bind.annotation.*;
  21 +
  22 +import javax.annotation.Resource;
  23 +import javax.servlet.http.HttpServletRequest;
  24 +import java.util.List;
  25 +
  26 +/**
  27 + * @author 游杰
  28 + */
  29 +@Api(tags="入库表主表")
  30 +@RestController
  31 +@RequestMapping("/shipment/shipmentCombination")
  32 +@Slf4j
  33 +public class shipmentCombinationController {
  34 +
  35 + @Resource
  36 + private IShipmentDetailService shipmentDetailService;
  37 + @Resource
  38 + private IShipmentCombinationService shipmentCombinationService;
  39 +
  40 + /**
  41 + * 获取单据列表
  42 + * @param shipmentCode
  43 + * @return
  44 + */
  45 + @GetMapping("/getShipmentDetailListByShipmentCode")
  46 + @ResponseBody
  47 + public Result getShipmentDetailListByShipmentCode(String shipmentCode, HttpServletRequest req) {
  48 + if(StringUtils.isEmpty(shipmentCode)){
  49 + return null;
  50 + }
  51 + String warehouseCode = JwtUtil.getWarehouseCodeByToken(req);
  52 + LambdaQueryWrapper<ShipmentDetail> shipmentDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
  53 + shipmentDetailLambdaQueryWrapper.eq(ShipmentDetail::getShipmentCode, shipmentCode)
  54 + .eq(ShipmentDetail::getWarehouseCode, warehouseCode);
  55 + List<ShipmentDetail> shipmentDetails = shipmentDetailService.list(shipmentDetailLambdaQueryWrapper) ;
  56 + return Result.ok(shipmentDetails);
  57 + }
  58 +
  59 + /**
  60 + * 自动组盘
  61 + * @return
  62 + */
  63 + @AutoLog("出库单-自动配盘")
  64 + @ApiOperation(value="出库单-自动配盘", notes="出库单-自动配盘")
  65 + @PostMapping("/autoCombination")
  66 + @ResponseBody
  67 + public Result autoCombination(@RequestBody ShipmentHeader shipmentHeader) {
  68 + String shipmentCode = shipmentHeader.getCode();
  69 + String warehouseCode = shipmentHeader.getWarehouseCode();
  70 + return shipmentCombinationService.autoCombination(shipmentCode, warehouseCode);
  71 + }
  72 +
  73 + /**
  74 + * 创建任务
  75 + * @return
  76 + */
  77 + @ApiOperation(value="入库组盘-创建任务", notes="入库组盘-创建任务")
  78 + @PostMapping("/createShipmentTask")
  79 + @ResponseBody
  80 + public Result createShipmentTask(@RequestBody ShipmentContainerHeader shipmentContainerHeader, HttpServletRequest req) {
  81 + String warehouseCode = JwtUtil.getWarehouseCodeByToken(req);
  82 + return shipmentCombinationService.createShipmentTask(shipmentContainerHeader, warehouseCode);
  83 + }
  84 +}
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/entity/CombinationModel.java 0 → 100644
  1 +package org.jeecg.modules.wms.shipment.shipmentCombination.entity;
  2 +
  3 +import lombok.Data;
  4 +import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
  5 +import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
  6 +
  7 +import java.math.BigDecimal;
  8 +
  9 +@Data
  10 +public class CombinationModel {
  11 +
  12 + //组盘时的出库明细Id
  13 + private ShipmentDetail shipmentDetail;
  14 + //组盘时选择的库存
  15 + private InventoryDetail inventoryDetail;
  16 + //组盘数量
  17 + private BigDecimal shipQty;
  18 +
  19 +}
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/IShipmentCombinationService.java 0 → 100644
  1 +package org.jeecg.modules.wms.shipment.shipmentCombination.service;
  2 +
  3 +
  4 +import org.jeecg.common.api.vo.Result;
  5 +import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
  6 +import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContainerHeader;
  7 +import org.jeecg.modules.wms.shipment.shipmentCombination.entity.CombinationModel;
  8 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
  9 +import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
  10 +
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * @author 游杰
  15 + */
  16 +public interface IShipmentCombinationService {
  17 +
  18 + public List<InventoryDetail> getInventorys(ShipmentDetail shipmentDetail);
  19 +
  20 + public Result autoCombination(String shipmentCode, String warehouseCode);
  21 +
  22 + public Result autoCombination(ShipmentDetail shipmentDetail);
  23 +
  24 + public Result combination(CombinationModel combinationModel);
  25 +
  26 + public Result createShipmentTask(ShipmentContainerHeader shipmentContainerHeader, String warehouseCode);
  27 +}
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java 0 → 100644
  1 +package org.jeecg.modules.wms.shipment.shipmentCombination.service.impl;
  2 +
  3 +import com.aliyun.oss.ServiceException;
  4 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  5 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  6 +import org.jeecg.common.api.vo.Result;
  7 +import org.jeecg.modules.wms.config.container.entity.Container;
  8 +import org.jeecg.modules.wms.config.container.service.IContainerService;
  9 +import org.jeecg.modules.wms.config.location.entity.Location;
  10 +import org.jeecg.modules.wms.config.location.service.ILocationService;
  11 +import org.jeecg.modules.wms.config.material.entity.Material;
  12 +import org.jeecg.modules.wms.config.material.service.IMaterialService;
  13 +import org.jeecg.modules.wms.config.parameterConfiguration.entity.ParameterConfiguration;
  14 +import org.jeecg.modules.wms.config.parameterConfiguration.service.IParameterConfigurationService;
  15 +import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
  16 +import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryDetailService;
  17 +import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryHeaderService;
  18 +import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContainerHeader;
  19 +import org.jeecg.modules.wms.receipt.receiptContainerHeader.service.IReceiptContainerHeaderService;
  20 +import org.jeecg.modules.wms.shipment.shipmentCombination.entity.CombinationModel;
  21 +import org.jeecg.modules.wms.shipment.shipmentCombination.service.IShipmentCombinationService;
  22 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerDetail;
  23 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
  24 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerDetailService;
  25 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerHeaderService;
  26 +import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
  27 +import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader;
  28 +import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService;
  29 +import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentHeaderService;
  30 +import org.jeecg.modules.wms.task.taskHeader.entity.TaskDetail;
  31 +import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader;
  32 +import org.jeecg.modules.wms.task.taskHeader.service.ITaskDetailService;
  33 +import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService;
  34 +import org.jeecg.utils.StringUtils;
  35 +import org.jeecg.utils.constant.QuantityConstant;
  36 +import org.springframework.stereotype.Service;
  37 +import org.springframework.transaction.annotation.Transactional;
  38 +
  39 +import javax.annotation.Resource;
  40 +import java.math.BigDecimal;
  41 +import java.util.ArrayList;
  42 +import java.util.List;
  43 +
  44 +/**
  45 + * @author 游杰
  46 + */
  47 +@Service
  48 +public class ShipmentCombinationServiceImpl implements IShipmentCombinationService {
  49 +
  50 + @Resource
  51 + private IInventoryDetailService inventoryDetailService;
  52 + @Resource
  53 + private IShipmentHeaderService shipmentHeaderService;
  54 + @Resource
  55 + private IShipmentDetailService shipmentDetailService;
  56 + @Resource
  57 + private IReceiptContainerHeaderService receiptContainerHeaderService;
  58 + @Resource
  59 + private IShipmentContainerHeaderService shipmentContainerHeaderService;
  60 + @Resource
  61 + private IContainerService containerService;
  62 + @Resource
  63 + private ILocationService locationService;
  64 + @Resource
  65 + private IShipmentContainerDetailService shipmentContainerDetailService;
  66 + @Resource
  67 + private IMaterialService materialService;
  68 + @Resource
  69 + private IParameterConfigurationService parameterConfigurationService;
  70 + @Resource
  71 + private ITaskHeaderService taskHeaderService;
  72 + @Resource
  73 + private ITaskDetailService taskDetailService;
  74 +
  75 + /**
  76 + * 根据出库单详情,匹配到可用出库的库存详情
  77 + * 默认匹配条件是 仓库,货主,物料编码,库存状态,批次 是一致的就可以出库
  78 + * @param shipmentDetail
  79 + * @return
  80 + */
  81 + @Override
  82 + public List<InventoryDetail> getInventorys(ShipmentDetail shipmentDetail) {
  83 + String warehouseCode = shipmentDetail.getWarehouseCode();
  84 + String companyCode = shipmentDetail.getCompanyCode();
  85 + String materialCode = shipmentDetail.getMaterialCode();
  86 + String inventoryStatus = shipmentDetail.getInventoryStatus();
  87 + String batch = shipmentDetail.getBatch();
  88 + int shipmentId = shipmentDetail.getShipmentId();
  89 + if(StringUtils.isEmpty(warehouseCode)) {
  90 + throw new ServiceException("寻找库存详情时,出库详情没有仓库编码");
  91 + }
  92 + if(StringUtils.isEmpty(companyCode)) {
  93 + throw new ServiceException("寻找库存详情时,出库详情没有货主编码");
  94 + }
  95 + if(StringUtils.isEmpty(materialCode)) {
  96 + throw new ServiceException("寻找库存详情时, 出库详情没有物料编码");
  97 + }
  98 + if(StringUtils.isEmpty(inventoryStatus)) {
  99 + throw new ServiceException("寻找库存详情时, 出库详情没有物料品质");
  100 + }
  101 + LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
  102 + inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getWarehouseCode, warehouseCode)
  103 + .eq(InventoryDetail::getCompanyCode, companyCode)
  104 + .eq(InventoryDetail::getMaterialCode, materialCode)
  105 + .eq(InventoryDetail::getInventoryStatus, inventoryStatus);
  106 + List<InventoryDetail> inventoryDetailList = inventoryDetailService.list(inventoryDetailLambdaQueryWrapper);
  107 + return inventoryDetailList;
  108 + }
  109 +
  110 + @Override
  111 + @Transactional(rollbackFor = ServiceException.class)
  112 + public Result autoCombination(String shipmentCode, String warehouseCode) {
  113 + LambdaQueryWrapper<ShipmentHeader> shipmentHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
  114 + shipmentHeaderLambdaQueryWrapper.eq(ShipmentHeader::getWarehouseCode, warehouseCode)
  115 + .eq(ShipmentHeader::getCode, shipmentCode);
  116 + ShipmentHeader shipmentHeader = shipmentHeaderService.getOne(shipmentHeaderLambdaQueryWrapper);
  117 + if(shipmentHeader == null) {
  118 + throw new ServiceException("系统没有此单据");
  119 + }
  120 + if(shipmentHeader.getLastStatus() >= QuantityConstant.SHIPMENT_HEADER_COMPLETED) {
  121 + return Result.OK("出库单已经作业完毕");
  122 + }
  123 + LambdaQueryWrapper<ShipmentDetail> shipmentDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
  124 + shipmentDetailLambdaQueryWrapper.eq(ShipmentDetail::getShipmentCode, shipmentCode)
  125 + .eq(ShipmentDetail::getWarehouseCode, warehouseCode);
  126 + List<ShipmentDetail> shipmentDetailList = shipmentDetailService.list(shipmentDetailLambdaQueryWrapper);
  127 + boolean over = true;
  128 + for(ShipmentDetail shipmentDetail : shipmentDetailList) {
  129 + if(shipmentDetail.getTaskQty().compareTo(shipmentDetail.getQty()) < 0) {
  130 + over = false;
  131 + }
  132 + Result result = autoCombination(shipmentDetail);
  133 + if(!result.isSuccess()) {
  134 + throw new ServiceException(result.getMessage());
  135 + }
  136 + }
  137 + if(over) {
  138 + return Result.OK("出库单已经配盘");
  139 + }
  140 + return Result.OK("自动组盘成功");
  141 + }
  142 +
  143 + @Override
  144 + @Transactional(rollbackFor = ServiceException.class)
  145 + public Result autoCombination(ShipmentDetail shipmentDetail) {
  146 + //出库数量
  147 + BigDecimal shipmentQty = shipmentDetail.getQty().subtract(shipmentDetail.getTaskQty());
  148 + //判断是否还有需要出库的物料,如果没有就跳过该物料
  149 + if (shipmentQty.compareTo(BigDecimal.ZERO) <= 0) {
  150 + return Result.OK("出库数量必须大于0");
  151 + }
  152 + List<InventoryDetail> inventoryList = getInventorys(shipmentDetail);
  153 + //去除已锁的库存
  154 + ArrayList<InventoryDetail> removeInventoryList = new ArrayList<>();
  155 + List<ReceiptContainerHeader> receiptContainerHeaderList =
  156 + receiptContainerHeaderService.getUnCompleteCombineList();
  157 + List<ShipmentContainerHeader> shipmentContainerHeaderList =
  158 + shipmentContainerHeaderService.getUnCompleteCombineList();
  159 + for (InventoryDetail inventoryDetail : inventoryList) {
  160 + String containerCode = inventoryDetail.getContainerCode();
  161 + String warehouseCode = inventoryDetail.getWarehouseCode();
  162 + Container container = containerService.getContainerByCode(
  163 + containerCode, warehouseCode);
  164 + if(container == null) {
  165 + return Result.error("自动配盘时,没有找到容器:" + containerCode);
  166 + }
  167 + if(container.getStatus().equals(QuantityConstant.STATUS_CONTAINER_LOCK)) {
  168 + removeInventoryList.add(inventoryDetail);
  169 + continue;
  170 + }
  171 + for(ReceiptContainerHeader receiptContainerHeader : receiptContainerHeaderList) {
  172 + if(receiptContainerHeader.getContainerCode().equals(containerCode)) {
  173 + removeInventoryList.add(inventoryDetail);
  174 + continue;
  175 + }
  176 + }
  177 + for(ShipmentContainerHeader shipmentContainerHeader : shipmentContainerHeaderList) {
  178 + if(shipmentContainerHeader.getContainerCode().equals(containerCode)) {
  179 + removeInventoryList.add(inventoryDetail);
  180 + continue;
  181 + }
  182 + }
  183 + }
  184 + inventoryList.removeAll(removeInventoryList);
  185 + if (inventoryList.size() < 1){
  186 + return Result.error(shipmentDetail.getMaterialName()+"' 没有符合出库条件的库存");
  187 + }
  188 +
  189 + for (InventoryDetail inventoryDetail : inventoryList) {
  190 + //判断需要配盘数量是否等于0,等于0代表配盘完毕,完毕就退出内循环
  191 + if (shipmentQty.compareTo(BigDecimal.ZERO) == 0) {
  192 + break;
  193 + }
  194 + if (shipmentQty.compareTo(BigDecimal.ZERO) < 0) {
  195 + throw new ServiceException("配盘时,出库数量不能小于0");
  196 + }
  197 + CombinationModel combinationModel = new CombinationModel();
  198 + combinationModel.setShipmentDetail(shipmentDetail);
  199 + combinationModel.setInventoryDetail(inventoryDetail);
  200 + BigDecimal inventoryQty = inventoryDetail.getQty().subtract(inventoryDetail.getTaskQty());
  201 + if (inventoryQty.compareTo(shipmentQty) >= 0) {
  202 + combinationModel.setShipQty(shipmentQty);
  203 + shipmentQty = BigDecimal.ZERO;
  204 + } else {
  205 + combinationModel.setShipQty(inventoryQty);
  206 + shipmentQty = shipmentQty.subtract(inventoryQty);
  207 + }
  208 + Result result = combination(combinationModel);
  209 + if(!result.isSuccess()) {
  210 + throw new ServiceException(result.getMessage());
  211 + }
  212 + }
  213 + return Result.OK("自动组盘成功");
  214 + }
  215 +
  216 + @Override
  217 + @Transactional(rollbackFor = ServiceException.class)
  218 + public Result combination(CombinationModel combinationModel) {
  219 + BigDecimal shipmentQty = combinationModel.getShipQty();
  220 + ShipmentDetail shipmentDetail = combinationModel.getShipmentDetail();
  221 + InventoryDetail inventoryDetail = combinationModel.getInventoryDetail();
  222 + if(shipmentQty.compareTo(BigDecimal.ZERO) <= 0) {
  223 + return Result.error("配盘时,出库数量必须大于0");
  224 + }
  225 + if(shipmentDetail == null){
  226 + return Result.error("配盘时,出库明细未找到");
  227 + }
  228 + if(inventoryDetail == null){
  229 + return Result.error("配盘时,库存未找到");
  230 + }
  231 + String containerCode = inventoryDetail.getContainerCode();
  232 + String warehouseCode = inventoryDetail.getWarehouseCode();
  233 + String locationCode = inventoryDetail.getLocationCode();
  234 + if(!warehouseCode.equals(shipmentDetail.getWarehouseCode())) {
  235 + return Result.error("配盘时,库存仓库编码和出库单仓库编码不一致");
  236 + }
  237 + boolean success = receiptContainerHeaderService.havaUnCompleteCombine(containerCode, warehouseCode);
  238 + if(success) {
  239 + return Result.error("配盘时, 容器:" + containerCode + " 已经用于入库组盘");
  240 + }
  241 + Location location = locationService.getLocationByCode(locationCode, warehouseCode);
  242 + if(location == null) {
  243 + return Result.error("配盘时, 没有找到库位, 编码" + locationCode);
  244 + }
  245 + Container container = containerService.getContainerByCode(containerCode, warehouseCode);
  246 + if(container == null) {
  247 + return Result.error("配盘时, 没有找到容器, 编码" + containerCode);
  248 + }
  249 + if(container.getStatus().equals(QuantityConstant.STATUS_CONTAINER_LOCK)) {
  250 + return Result.error("配盘时, 托盘已经锁定,不能再组盘");
  251 + }
  252 + BigDecimal shipmentDetailQty = shipmentDetail.getQty();
  253 + BigDecimal shipmentDetailTaskQty = shipmentDetail.getTaskQty();
  254 + //可出数量
  255 + BigDecimal shipmentDetailAvailableQty = shipmentDetailQty.subtract(shipmentDetailTaskQty);
  256 + if(shipmentDetailAvailableQty.compareTo(shipmentQty) < 0) {
  257 + return Result.error("配盘时, 录入数量超出出库单明细待出数量");
  258 + }
  259 + BigDecimal inventoryDetailQty = inventoryDetail.getQty();
  260 + BigDecimal inventoryDetailTaskQty = inventoryDetail.getTaskQty();
  261 + BigDecimal inventoryDetailAvailableQty = inventoryDetailQty.subtract(inventoryDetailTaskQty);
  262 + if(inventoryDetailAvailableQty.compareTo(shipmentQty) < 0) {
  263 + return Result.error("配盘时, 录入数量超出库存详情待出数量");
  264 + }
  265 + if(!shipmentDetail.getMaterialCode().equals(inventoryDetail.getMaterialCode())){
  266 + return Result.error("配盘时, 配盘物料不一致");
  267 + }
  268 + inventoryDetailTaskQty = inventoryDetailTaskQty.add(shipmentQty);
  269 + if(inventoryDetailTaskQty.compareTo(BigDecimal.ZERO) <= 0) {
  270 + return Result.error("配盘时, 库存详情的任务数量必须大于0");
  271 + }
  272 + if(inventoryDetailTaskQty.compareTo(inventoryDetailQty) > 0) {
  273 + return Result.error("配盘时, 库存详情的任务数量不能超过库存数量");
  274 + }
  275 + inventoryDetail.setTaskQty(inventoryDetailTaskQty);
  276 + success = inventoryDetailService.updateById(inventoryDetail);
  277 + if(!success) {
  278 + throw new ServiceException("配盘时, 更新库存详情失败");
  279 + }
  280 + shipmentDetailTaskQty = shipmentDetailTaskQty.add(shipmentQty);
  281 + if(shipmentDetailTaskQty.compareTo(BigDecimal.ZERO) <= 0) {
  282 + return Result.error("配盘时, 出库详情的任务数量必须大于0");
  283 + }
  284 + if(shipmentDetailTaskQty.compareTo(shipmentDetailQty) > 0) {
  285 + return Result.error("配盘时, 出库详情的任务数量不能超过单据数量");
  286 + } else if(inventoryDetailTaskQty.compareTo(inventoryDetailQty) == 0) {
  287 + shipmentDetail.setStatus(QuantityConstant.SHIPMENT_HEADER_COMPLETED);
  288 + } else if(inventoryDetailTaskQty.compareTo(inventoryDetailQty) < 0) {
  289 + shipmentDetail.setStatus(QuantityConstant.SHIPMENT_HEADER_OFF_SHELF);
  290 + }
  291 + shipmentDetail.setTaskQty(shipmentDetailTaskQty);
  292 + success = shipmentDetailService.updateById(shipmentDetail);
  293 + if(!success) {
  294 + throw new ServiceException("配盘时, 更新出库详情失败");
  295 + }
  296 + ShipmentContainerHeader shipmentContainerHeader = addShipmentContainerHeader(inventoryDetail, shipmentDetail);
  297 + if(shipmentContainerHeader == null) {
  298 + throw new ServiceException("配盘时, 新增出库组盘头失败");
  299 + }
  300 + ShipmentContainerDetail shipmentContainerDetail = addShipmentContainerDetail(shipmentContainerHeader, combinationModel);
  301 + if(shipmentContainerDetail == null) {
  302 + throw new ServiceException("配盘时, 新增出库组盘详情失败");
  303 + }
  304 + success = shipmentHeaderService.updateShipmentHeaderStatus(shipmentDetail.getShipmentId());
  305 + if(!success) {
  306 + throw new ServiceException("配盘时, 更新出库单失败");
  307 + }
  308 + return Result.ok("配盘成功");
  309 + }
  310 +
  311 + @Transactional(rollbackFor = ServiceException.class)
  312 + public ShipmentContainerHeader addShipmentContainerHeader(InventoryDetail inventoryDetail,
  313 + ShipmentDetail shipmentDetail) {
  314 + String containerCode = inventoryDetail.getContainerCode();
  315 + String warehouseCode = inventoryDetail.getWarehouseCode();
  316 + String locationCode = inventoryDetail.getLocationCode();
  317 + Container container = containerService.getContainerByCode(containerCode, warehouseCode);
  318 + LambdaQueryWrapper<ShipmentContainerHeader> shipmentContainerHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
  319 + shipmentContainerHeaderLambdaQueryWrapper.eq(ShipmentContainerHeader::getContainerCode, containerCode)
  320 + .eq(ShipmentContainerHeader::getFromLocationCode, locationCode)
  321 + .eq(ShipmentContainerHeader::getWarehouseCode, warehouseCode)
  322 + .lt(ShipmentContainerHeader::getStatus,QuantityConstant.SHIPMENT_CONTAINER_FINISHED);
  323 + ShipmentContainerHeader shipmentContainerHeader = shipmentContainerHeaderService.getOne(shipmentContainerHeaderLambdaQueryWrapper);
  324 + if(shipmentContainerHeader != null) {
  325 + return shipmentContainerHeader;
  326 + } else {
  327 + List<InventoryDetail> inventoryDetailList = inventoryDetailService.getInventoryDetailListByContainerCode(containerCode, warehouseCode);
  328 + int taskType = QuantityConstant.TASK_TYPE_WHOLESHIPMENT;
  329 + // 如果库存还有剩余,那么就是分拣出库
  330 + if(inventoryDetailList != null && inventoryDetailList.size() > 0) {
  331 + for(InventoryDetail inventoryDetail1 : inventoryDetailList) {
  332 + if(inventoryDetail1.getQty().subtract(inventoryDetail1.getTaskQty()).
  333 + compareTo(BigDecimal.ZERO) > 0) {
  334 + taskType = QuantityConstant.TASK_TYPE_SORTINGSHIPMENT;
  335 + }
  336 + }
  337 + }
  338 + shipmentContainerHeader = new ShipmentContainerHeader();
  339 + shipmentContainerHeader.setContainerCode(containerCode);
  340 + shipmentContainerHeader.setFromLocationCode(locationCode);
  341 + shipmentContainerHeader.setWarehouseCode(warehouseCode);
  342 + shipmentContainerHeader.setCompanyCode(shipmentDetail.getCompanyCode());
  343 + shipmentContainerHeader.setContainerTypeCode(container.getContainerTypeCode());
  344 + shipmentContainerHeader.setToPort(shipmentDetail.getToPort());
  345 + shipmentContainerHeader.setStatus(QuantityConstant.SHIPMENT_CONTAINER_BUILD);
  346 + shipmentContainerHeader.setTaskType(taskType);
  347 + boolean success = shipmentContainerHeaderService.save(shipmentContainerHeader);
  348 + if (!success) {
  349 + throw new ServiceException("新增出库组盘头失败");
  350 + }
  351 + return shipmentContainerHeader;
  352 + }
  353 + }
  354 +
  355 + @Transactional(rollbackFor = ServiceException.class)
  356 + public ShipmentContainerDetail addShipmentContainerDetail(ShipmentContainerHeader shipmentContainerHeader,
  357 + CombinationModel combinationModel) {
  358 + boolean success = false;
  359 + BigDecimal shipmentQty = combinationModel.getShipQty();
  360 + ShipmentDetail shipmentDetail = combinationModel.getShipmentDetail();
  361 + InventoryDetail inventoryDetail = combinationModel.getInventoryDetail();
  362 + String containerCode = inventoryDetail.getContainerCode();
  363 + String warehouseCode = inventoryDetail.getWarehouseCode();
  364 + String locationCode = inventoryDetail.getLocationCode();
  365 + String materialCode = inventoryDetail.getMaterialCode();
  366 + LambdaQueryWrapper<ShipmentContainerDetail> shipmentContainerDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
  367 + shipmentContainerDetailLambdaQueryWrapper.eq(ShipmentContainerDetail::getShipmentContainerId, shipmentContainerHeader.getId())
  368 + .eq(ShipmentContainerDetail::getShipmentDetailId, shipmentDetail.getId())
  369 + .eq(ShipmentContainerDetail::getInventoryDetailId, inventoryDetail.getId())
  370 + .eq(ShipmentContainerDetail::getWarehouseCode, warehouseCode);
  371 + ShipmentContainerDetail shipmentContainerDetail = shipmentContainerDetailService.getOne(shipmentContainerDetailLambdaQueryWrapper);
  372 + if(shipmentContainerDetail != null) {
  373 + shipmentContainerDetail.setQty(shipmentContainerDetail.getQty().add(combinationModel.getShipQty()));
  374 + success = shipmentContainerDetailService.updateById(shipmentContainerDetail);
  375 + if(!success) {
  376 + throw new ServiceException("更新出库组盘详情失败");
  377 + }
  378 + } else {
  379 + Material material = materialService.getMaterialByCode(materialCode);
  380 + if (material == null) {
  381 + throw new ServiceException("出库单(" + shipmentDetail.getShipmentCode() + ")的物料(" + materialCode + ")不存在!");
  382 + }
  383 + shipmentContainerDetail = new ShipmentContainerDetail();
  384 + shipmentContainerDetail.setWarehouseCode(shipmentContainerHeader.getWarehouseCode());
  385 + shipmentContainerDetail.setCompanyCode(shipmentDetail.getCompanyCode());
  386 + shipmentContainerDetail.setContainerCode(shipmentContainerHeader.getContainerCode());
  387 + shipmentContainerDetail.setFromLocationCode(shipmentContainerHeader.getFromLocationCode());
  388 + shipmentContainerDetail.setToLocationCode(shipmentContainerHeader.getToLocationCode());
  389 + shipmentContainerDetail.setInventoryDetailId(inventoryDetail.getId());
  390 + shipmentContainerDetail.setInventoryStatus(shipmentDetail.getInventoryStatus());
  391 + shipmentContainerDetail.setShipmentCode(shipmentDetail.getShipmentCode());
  392 + shipmentContainerDetail.setShipmentId(shipmentDetail.getShipmentId());
  393 + shipmentContainerDetail.setShipmentDetailId(shipmentDetail.getId());
  394 + shipmentContainerDetail.setShipmentContainerId(shipmentContainerHeader.getId());
  395 + shipmentContainerDetail.setMaterialCode(shipmentDetail.getMaterialCode());
  396 + shipmentContainerDetail.setMaterialName(shipmentDetail.getMaterialName());
  397 + shipmentContainerDetail.setMaterialSpec(shipmentDetail.getMaterialSpec());
  398 + shipmentContainerDetail.setMaterialUnit(shipmentDetail.getMaterialUnit());
  399 + shipmentContainerDetail.setQty(shipmentQty);
  400 + shipmentContainerDetail.setBatch(shipmentDetail.getBatch());
  401 + shipmentContainerDetail.setLot(shipmentDetail.getLot());
  402 + shipmentContainerDetail.setProject(shipmentDetail.getProject());
  403 + success = shipmentContainerDetailService.save(shipmentContainerDetail);
  404 + if(!success){
  405 + throw new ServiceException("新建组盘明细失败,sql错误");
  406 + }
  407 + }
  408 + return shipmentContainerDetail;
  409 + }
  410 +
  411 + @Override
  412 + @Transactional(rollbackFor = ServiceException.class)
  413 + public Result createShipmentTask(ShipmentContainerHeader shipmentContainerHeader, String warehouseCode) {
  414 + Integer preTaskNo = 0;
  415 + if (shipmentContainerHeader == null) {
  416 + return Result.error("生成出库任务时, 出库组盘头" + "未找到,操作中止");
  417 + }
  418 + shipmentContainerHeader = shipmentContainerHeaderService.getById(shipmentContainerHeader.getId());
  419 + if (shipmentContainerHeader.getStatus() >= QuantityConstant.SHIPMENT_CONTAINER_TASK) {
  420 + return Result.error("生成出库任务时, 出库组盘头" + shipmentContainerHeader.getId() + "已经生成任务,请不要重复生成,操作中止");
  421 + }
  422 + List<ShipmentContainerDetail> shipmentContainerDetailList = shipmentContainerDetailService.getShipmentContainerDetailListByHeaderId(shipmentContainerHeader.getId());
  423 + if (shipmentContainerDetailList.size() == 0) {
  424 + return Result.error("生成出库任务时, 出库组盘头" + shipmentContainerHeader.getId() + "没有子任务,操作中止");
  425 + }
  426 + if(!shipmentContainerHeader.getWarehouseCode().equals(warehouseCode)) {
  427 + return Result.error("生成出库任务时, 出库组盘头" + shipmentContainerHeader.getId() + "仓库编码和登录的仓库编码不一致");
  428 + }
  429 + String fromLocationCode = shipmentContainerHeader.getFromLocationCode();
  430 + String toLocationCode = shipmentContainerHeader.getToLocationCode();
  431 + String containerCode = shipmentContainerHeader.getContainerCode();
  432 + if(StringUtils.isEmpty(fromLocationCode)) {
  433 + return Result.error("生成出库任务时, 出库组盘头没有起始库位号为空");
  434 + }
  435 + Location location = locationService.getLocationByCode(fromLocationCode, warehouseCode);
  436 + if(location == null) {
  437 + return Result.error("生成出库任务时, 库位号" + fromLocationCode + "没有找到库位");
  438 + }
  439 + if(location.getRowFlag() == QuantityConstant.ROW_OUT) {
  440 + Location location1 = locationService.getNear(location);
  441 + if(location1 != null) {
  442 + String locationCode = location1.getCode();
  443 + TaskHeader taskHeader = taskHeaderService
  444 + .getUnCompleteTaskByToLocationCode(locationCode, warehouseCode);
  445 + preTaskNo = taskHeader.getPreTaskNo();
  446 + }
  447 + }
  448 + Container container = containerService.getContainerByCode(containerCode, warehouseCode);
  449 + if(container == null) {
  450 + return Result.error("生成出库任务时, 托盘不存在" + containerCode);
  451 + }
  452 + if(container.getStatus().equals(QuantityConstant.STATUS_CONTAINER_LOCK)) {
  453 + return Result.error("生成出库任务时, 托盘已经锁定" + containerCode);
  454 + }
  455 + container.setStatus(QuantityConstant.STATUS_CONTAINER_LOCK);
  456 + boolean success = containerService.updateById(container);
  457 + if(!success) {
  458 + throw new ServiceException("生成出库任务时, 更新容器失败" + containerCode);
  459 + }
  460 + success = locationService.updateStatus(fromLocationCode,
  461 + QuantityConstant.STATUS_LOCATION_LOCK, warehouseCode);
  462 + if(!success) {
  463 + throw new ServiceException("生成出库任务时, 更新库位失败" + fromLocationCode);
  464 + }
  465 + List<InventoryDetail> inventoryDetailList = inventoryDetailService
  466 + .getInventoryDetailListByContainerCode(containerCode, warehouseCode);
  467 + BigDecimal inventoryTotal = BigDecimal.ZERO;
  468 + for (InventoryDetail inventoryDetail : inventoryDetailList) {
  469 + inventoryTotal = inventoryTotal.add(inventoryDetail.getQty());
  470 + }
  471 + BigDecimal shipmentTotal = BigDecimal.ZERO;
  472 + for (ShipmentContainerDetail shipmentContainerDetail : shipmentContainerDetailList) {
  473 + shipmentTotal = shipmentTotal.add(shipmentContainerDetail.getQty());
  474 + }
  475 + int taskType = QuantityConstant.TASK_TYPE_WHOLESHIPMENT;
  476 + if (inventoryTotal.compareTo(shipmentTotal) == 0) {
  477 + taskType = QuantityConstant.TASK_TYPE_WHOLESHIPMENT;
  478 + } else if(inventoryTotal.compareTo(shipmentTotal) < 0) {
  479 + return Result.error("生成出库任务时, 库存数量少于出库数量");
  480 + } else if(inventoryTotal.compareTo(shipmentTotal) > 0) {
  481 + taskType = QuantityConstant.TASK_TYPE_SORTINGSHIPMENT;
  482 + }
  483 + String value = parameterConfigurationService.getValueByCode(QuantityConstant.RULE_SHIPMENT_TASK);
  484 + int shipmentTaskRule = Integer.parseInt(value);
  485 + if(shipmentTaskRule == QuantityConstant.RULE_TASK_PICK_SHIPMENT) {
  486 + taskType = QuantityConstant.TASK_TYPE_SORTINGSHIPMENT;
  487 + }
  488 + value = parameterConfigurationService.getValueByCode(QuantityConstant.RULE_TASK_LOCATION);
  489 + int taskLocationRule = Integer.parseInt(value);
  490 + if (taskLocationRule == QuantityConstant.RULE_TASK_SET_LOCATION) {
  491 + toLocationCode = fromLocationCode;
  492 + shipmentContainerHeader.setToLocationCode(toLocationCode);
  493 + }
  494 + shipmentContainerHeader.setTaskType(taskType);
  495 + String zoneCode = location.getZoneCode();
  496 + TaskHeader taskHeader = new TaskHeader();
  497 + taskHeader.setPreTaskNo(preTaskNo);
  498 + taskHeader.setTaskType(taskType);
  499 + taskHeader.setInnernalTaskType(QuantityConstant.TASK_INTENERTYPE_SHIPMENT);
  500 + taskHeader.setZoneCode(zoneCode);
  501 + taskHeader.setWarehouseCode(warehouseCode);
  502 + taskHeader.setStatus(QuantityConstant.TASK_STATUS_BUILD);
  503 + taskHeader.setContainerCode(containerCode);
  504 + taskHeader.setToPort(shipmentContainerHeader.getToPort());
  505 + taskHeader.setFromLocationCode(fromLocationCode);
  506 + if(taskType == QuantityConstant.TASK_TYPE_SORTINGSHIPMENT) {
  507 + taskHeader.setToLocationCode(toLocationCode);
  508 + }
  509 + taskHeader.setShipmentContainerHeaderId(shipmentContainerHeader.getId());
  510 + success = taskHeaderService.save(taskHeader);
  511 + if(!success) {
  512 + throw new ServiceException("生成出库任务时, 创建任务失败");
  513 + }
  514 + int taskHeaderId = taskHeader.getId();
  515 + List<TaskDetail> taskDetailList = new ArrayList<>();
  516 + for (ShipmentContainerDetail shipmentContainerDetail : shipmentContainerDetailList) {
  517 + TaskDetail taskDetail = new TaskDetail();
  518 + taskDetail.setTaskHeaderId(taskHeaderId);
  519 + taskDetail.setWarehouseCode(warehouseCode);
  520 + taskDetail.setCompanyCode(shipmentContainerDetail.getCompanyCode());
  521 + taskDetail.setFromInventoryDetailId(shipmentContainerDetail.getInventoryDetailId());
  522 + taskDetail.setShipmentId(shipmentContainerDetail.getShipmentId());
  523 + taskDetail.setShipmentDetailId(shipmentContainerDetail.getShipmentDetailId());
  524 + taskDetail.setShipmentContainerDetailId(shipmentContainerDetail.getId());
  525 + taskDetail.setTaskType(taskType);
  526 + taskDetail.setBatch(shipmentContainerDetail.getBatch());
  527 + taskDetail.setLot(shipmentContainerDetail.getLot());
  528 + taskDetail.setProject(shipmentContainerDetail.getProject());
  529 + taskDetail.setInventoryStatus(shipmentContainerDetail.getInventoryStatus());
  530 + taskDetail.setMaterialCode(shipmentContainerDetail.getMaterialCode());
  531 + taskDetail.setMaterialSpec(shipmentContainerDetail.getMaterialSpec());
  532 + taskDetail.setMaterialName(shipmentContainerDetail.getMaterialName());
  533 + taskDetail.setMaterialUnit(shipmentContainerDetail.getMaterialUnit());
  534 + taskDetail.setQty(shipmentContainerDetail.getQty());
  535 + taskDetailList.add(taskDetail);
  536 + }
  537 + success = taskDetailService.saveBatch(taskDetailList);
  538 + if(!success) {
  539 + throw new ServiceException("生成出库任务时, 创建任务详情失败");
  540 + }
  541 + shipmentContainerHeader.setStatus(QuantityConstant.SHIPMENT_CONTAINER_TASK);
  542 + success = shipmentContainerHeaderService.updateById(shipmentContainerHeader);
  543 + if(!success) {
  544 + throw new ServiceException("生成出库任务时, 更新出库组盘头失败");
  545 + }
  546 +
  547 + return Result.OK("生成出库任务成功");
  548 + }
  549 +}
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/entity/ShipmentContainerDetail.java
... ... @@ -53,6 +53,18 @@ public class ShipmentContainerDetail implements Serializable {
53 53 @Excel(name = "货主编码", width = 15)
54 54 @ApiModelProperty(value = "货主编码")
55 55 private String companyCode;
  56 + /**容器号*/
  57 + @Excel(name = "容器号", width = 15)
  58 + @ApiModelProperty(value = "容器号")
  59 + private String containerCode;
  60 + /**起始库位*/
  61 + @Excel(name = "起始库位", width = 15)
  62 + @ApiModelProperty(value = "起始库位")
  63 + private String fromLocationCode;
  64 + /**目标库位*/
  65 + @Excel(name = "目标库位", width = 15)
  66 + @ApiModelProperty(value = "目标库位")
  67 + private String toLocationCode;
56 68 /**物料编码*/
57 69 @Excel(name = "物料编码", width = 15)
58 70 @ApiModelProperty(value = "物料编码")
... ... @@ -69,10 +81,14 @@ public class ShipmentContainerDetail implements Serializable {
69 81 @Excel(name = "物料单位", width = 15)
70 82 @ApiModelProperty(value = "物料单位")
71 83 private String materialUnit;
72   - /**数量*/
73   - @Excel(name = "数量", width = 15)
  84 + /**数量*/
  85 + @Excel(name = "数量", width = 15)
74 86 @ApiModelProperty(value = "数量")
75   - private Integer qty;
  87 + private java.math.BigDecimal qty;
  88 + /**库存详情ID*/
  89 + @Excel(name = "库存详情ID", width = 15)
  90 + @ApiModelProperty(value = "库存详情ID")
  91 + private Integer inventoryDetailId;
76 92 /**库存状态*/
77 93 @Excel(name = "库存状态", width = 15)
78 94 @ApiModelProperty(value = "库存状态")
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/IShipmentContainerDetailService.java
... ... @@ -13,4 +13,6 @@ import java.util.List;
13 13 public interface IShipmentContainerDetailService extends IService<ShipmentContainerDetail> {
14 14  
15 15 public List<ShipmentContainerDetail> selectByMainId(String mainId);
  16 +
  17 + public List<ShipmentContainerDetail> getShipmentContainerDetailListByHeaderId(int shipmentContainerHeaderId);
16 18 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/IShipmentContainerHeaderService.java
... ... @@ -26,5 +26,8 @@ public interface IShipmentContainerHeaderService extends IService&lt;ShipmentContai
26 26 */
27 27 public void delBatchMain (Collection<? extends Serializable> idList);
28 28  
  29 + public List<ShipmentContainerHeader> getUnCompleteCombineList();
  30 +
  31 + boolean havaUnCompleteCombine(String containerCode, String warehouseCode);
29 32  
30 33 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/impl/ShipmentContainerDetailServiceImpl.java
1 1 package org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.impl;
2 2  
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
3 5 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerDetail;
4 6 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.mapper.ShipmentContainerDetailMapper;
5 7 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerDetailService;
... ... @@ -24,4 +26,12 @@ public class ShipmentContainerDetailServiceImpl extends ServiceImpl&lt;ShipmentCont
24 26 public List<ShipmentContainerDetail> selectByMainId(String mainId) {
25 27 return shipmentContainerDetailMapper.selectByMainId(mainId);
26 28 }
  29 +
  30 + @Override
  31 + public List<ShipmentContainerDetail> getShipmentContainerDetailListByHeaderId(int shipmentContainerHeaderId) {
  32 + LambdaQueryWrapper<ShipmentContainerDetail> shipmentContainerDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
  33 + shipmentContainerDetailLambdaQueryWrapper.eq(ShipmentContainerDetail::getShipmentContainerId, shipmentContainerHeaderId);
  34 + List<ShipmentContainerDetail> shipmentContainerDetailList = list(shipmentContainerDetailLambdaQueryWrapper);
  35 + return shipmentContainerDetailList;
  36 + }
27 37 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentContainerHeader/service/impl/ShipmentContainerHeaderServiceImpl.java
1 1 package org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.impl;
2 2  
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  5 +import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptDetail;
  6 +import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptHeader;
3 7 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
4 8 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerDetail;
5 9 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.mapper.ShipmentContainerDetailMapper;
6 10 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.mapper.ShipmentContainerHeaderMapper;
7 11 import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerHeaderService;
  12 +import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
  13 +import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader;
  14 +import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService;
  15 +import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentHeaderService;
  16 +import org.jeecg.utils.constant.QuantityConstant;
8 17 import org.springframework.stereotype.Service;
9 18 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
10 19 import org.springframework.beans.factory.annotation.Autowired;
11 20 import org.springframework.transaction.annotation.Transactional;
  21 +
  22 +import javax.annotation.Resource;
12 23 import java.io.Serializable;
13 24 import java.util.List;
14 25 import java.util.Collection;
... ... @@ -26,6 +37,10 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl&lt;ShipmentCont
26 37 private ShipmentContainerHeaderMapper shipmentContainerHeaderMapper;
27 38 @Autowired
28 39 private ShipmentContainerDetailMapper shipmentContainerDetailMapper;
  40 + @Resource
  41 + private IShipmentDetailService shipmentDetailService;
  42 + @Resource
  43 + private IShipmentHeaderService shipmentHeaderService;
29 44  
30 45 @Override
31 46 @Transactional
... ... @@ -43,4 +58,29 @@ public class ShipmentContainerHeaderServiceImpl extends ServiceImpl&lt;ShipmentCont
43 58 }
44 59 }
45 60  
  61 + @Override
  62 + public List<ShipmentContainerHeader> getUnCompleteCombineList() {
  63 + LambdaQueryWrapper<ShipmentContainerHeader> shipmentContainerHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
  64 + shipmentContainerHeaderLambdaQueryWrapper
  65 + .lt(ShipmentContainerHeader::getStatus, QuantityConstant.SHIPMENT_CONTAINER_FINISHED);
  66 + List<ShipmentContainerHeader> shipmentContainerHeaderList = list(shipmentContainerHeaderLambdaQueryWrapper);
  67 + return shipmentContainerHeaderList;
  68 + }
  69 +
  70 + @Override
  71 + public boolean havaUnCompleteCombine(String containerCode, String warehouseCode) {
  72 + LambdaQueryWrapper<ShipmentContainerHeader> shipmentContainerHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
  73 + shipmentContainerHeaderLambdaQueryWrapper
  74 + .eq(ShipmentContainerHeader::getContainerCode, containerCode)
  75 + .eq(ShipmentContainerHeader::getWarehouseCode, warehouseCode)
  76 + .lt(ShipmentContainerHeader::getStatus, QuantityConstant.SHIPMENT_CONTAINER_FINISHED);
  77 + ShipmentContainerHeader shipmentContainerHeader = getOne(shipmentContainerHeaderLambdaQueryWrapper);
  78 + if(shipmentContainerHeader != null) {
  79 + return true;
  80 + }
  81 + return false;
  82 + }
  83 +
  84 +
  85 +
46 86 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/entity/ShipmentDetail.java
... ... @@ -88,12 +88,17 @@ public class ShipmentDetail implements Serializable {
88 88 private String project;
89 89 /**单据状态*/
90 90 @Excel(name = "单据状态", width = 15)
  91 + @Dict(dicCode = "shipment_status")
91 92 @ApiModelProperty(value = "单据状态")
92 93 private Integer status;
93 94 /**上游单号*/
94 95 @Excel(name = "上游单号", width = 15)
95 96 @ApiModelProperty(value = "上游单号")
96 97 private String referCode;
  98 + /**目标出入口*/
  99 + @Excel(name = "目标出入口", width = 15)
  100 + @ApiModelProperty(value = "目标出入口")
  101 + private String toPort;
97 102 /**上游行号*/
98 103 @Excel(name = "上游行号", width = 15)
99 104 @ApiModelProperty(value = "上游行号")
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/service/IShipmentHeaderService.java
1 1 package org.jeecg.modules.wms.shipment.shipmentHeader.service;
2 2  
3 3 import org.jeecg.common.api.vo.Result;
  4 +import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContainerHeader;
  5 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
4 6 import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
5 7 import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader;
6 8 import com.baomidou.mybatisplus.extension.service.IService;
... ... @@ -30,4 +32,7 @@ public interface IShipmentHeaderService extends IService&lt;ShipmentHeader&gt; {
30 32 public Result saveShipmentHeader(ShipmentHeader shipmentHeader);
31 33  
32 34 public String createCode(String shipmentType);
  35 +
  36 + public boolean updateShipmentHeaderStatus(Integer id);
  37 +
33 38 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/shipment/shipmentHeader/service/impl/ShipmentHeaderServiceImpl.java
... ... @@ -4,15 +4,29 @@ import com.aliyun.oss.ServiceException;
4 4 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
5 5 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
6 6 import org.jeecg.common.api.vo.Result;
  7 +import org.jeecg.modules.wms.config.container.entity.Container;
  8 +import org.jeecg.modules.wms.config.container.service.IContainerService;
  9 +import org.jeecg.modules.wms.config.location.entity.Location;
  10 +import org.jeecg.modules.wms.config.location.service.ILocationService;
  11 +import org.jeecg.modules.wms.config.parameterConfiguration.service.IParameterConfigurationService;
7 12 import org.jeecg.modules.wms.config.receiptType.entity.ReceiptType;
8 13 import org.jeecg.modules.wms.config.shipmentType.entity.ShipmentType;
9 14 import org.jeecg.modules.wms.config.shipmentType.service.IShipmentTypeService;
  15 +import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail;
  16 +import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryDetailService;
  17 +import org.jeecg.modules.wms.inventory.inventoryHeader.service.IInventoryHeaderService;
10 18 import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptHeader;
  19 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerDetail;
  20 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
  21 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerDetailService;
11 22 import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader;
12 23 import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail;
13 24 import org.jeecg.modules.wms.shipment.shipmentHeader.mapper.ShipmentDetailMapper;
14 25 import org.jeecg.modules.wms.shipment.shipmentHeader.mapper.ShipmentHeaderMapper;
  26 +import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService;
15 27 import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentHeaderService;
  28 +import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader;
  29 +import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService;
16 30 import org.jeecg.utils.StringUtils;
17 31 import org.jeecg.utils.constant.QuantityConstant;
18 32 import org.springframework.stereotype.Service;
... ... @@ -22,6 +36,7 @@ import org.springframework.transaction.annotation.Transactional;
22 36  
23 37 import javax.annotation.Resource;
24 38 import java.io.Serializable;
  39 +import java.math.BigDecimal;
25 40 import java.text.SimpleDateFormat;
26 41 import java.util.Date;
27 42 import java.util.List;
... ... @@ -42,10 +57,30 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl&lt;ShipmentHeaderMapper,
42 57 private ShipmentDetailMapper shipmentDetailMapper;
43 58 @Resource
44 59 private IShipmentTypeService shipmentTypeService;
  60 + @Resource
  61 + private IShipmentHeaderService shipmentHeaderService;
  62 + @Resource
  63 + private IShipmentDetailService shipmentDetailService;
  64 + @Resource
  65 + private IShipmentContainerDetailService shipmentContainerDetailService;
  66 + @Resource
  67 + private ILocationService locationService;
  68 + @Resource
  69 + private IContainerService containerService;
  70 + @Resource
  71 + private ITaskHeaderService taskHeaderService;
  72 + @Resource
  73 + private IInventoryDetailService inventoryDetailService;
  74 + @Resource
  75 + private IParameterConfigurationService parameterConfigurationService;
45 76  
46 77 @Override
47 78 @Transactional
48 79 public void delMain(String id) {
  80 + ShipmentHeader shipmentHeader = getById(id);
  81 + if(shipmentHeader.getFirstStatus().intValue() > QuantityConstant.RECEIPT_HEADER_BUILD) {
  82 + throw new ServiceException("不能删除非新建状态单据");
  83 + }
49 84 shipmentDetailMapper.deleteByMainId(id);
50 85 shipmentHeaderMapper.deleteById(id);
51 86 }
... ... @@ -54,6 +89,10 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl&lt;ShipmentHeaderMapper,
54 89 @Transactional
55 90 public void delBatchMain(Collection<? extends Serializable> idList) {
56 91 for(Serializable id:idList) {
  92 + ShipmentHeader shipmentHeader = getById(id);
  93 + if(shipmentHeader.getFirstStatus().intValue() > QuantityConstant.RECEIPT_HEADER_BUILD) {
  94 + throw new ServiceException("不能删除非新建状态单据");
  95 + }
57 96 shipmentDetailMapper.deleteByMainId(id.toString());
58 97 shipmentHeaderMapper.deleteById(id);
59 98 }
... ... @@ -111,4 +150,39 @@ public class ShipmentHeaderServiceImpl extends ServiceImpl&lt;ShipmentHeaderMapper,
111 150 }
112 151 return code;
113 152 }
  153 +
  154 + @Override
  155 + public boolean updateShipmentHeaderStatus(Integer id) {
  156 + LambdaQueryWrapper<ShipmentDetail> shipmentDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
  157 + shipmentDetailLambdaQueryWrapper.eq(ShipmentDetail::getShipmentId, id);
  158 + List<ShipmentDetail> shipmentDetailList = shipmentDetailService.list(shipmentDetailLambdaQueryWrapper);
  159 + ShipmentHeader shipmentHeader = shipmentHeaderService.getById(id);
  160 + if(shipmentHeader == null) {
  161 + return false;
  162 + }
  163 + int minStatus;
  164 + int maxStatus;
  165 + if(shipmentDetailList.size() == 0) {
  166 + minStatus = QuantityConstant.RECEIPT_HEADER_BUILD;
  167 + maxStatus = QuantityConstant.RECEIPT_HEADER_BUILD;
  168 + } else {
  169 + minStatus = shipmentDetailList.get(0).getStatus();
  170 + maxStatus = shipmentDetailList.get(0).getStatus();
  171 + for(ShipmentDetail shipmentDetail : shipmentDetailList) {
  172 + int status = shipmentDetail.getStatus();
  173 + if (minStatus > status) {
  174 + minStatus = status;
  175 + }
  176 + if (maxStatus < status) {
  177 + maxStatus = status;
  178 + }
  179 + }
  180 + }
  181 +
  182 + shipmentHeader.setFirstStatus(maxStatus);
  183 + shipmentHeader.setLastStatus(minStatus);
  184 + boolean result = shipmentHeaderService.updateById(shipmentHeader);
  185 + return result;
  186 + }
  187 +
114 188 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/entity/TaskHeader.java
... ... @@ -34,10 +34,14 @@ public class TaskHeader implements Serializable {
34 34 @Excel(name = "前置任务号", width = 15)
35 35 @ApiModelProperty(value = "前置任务号")
36 36 private Integer preTaskNo;
37   - /**前置任务号*/
  37 + /**入库组盘ID*/
38 38 @Excel(name = "入库组盘ID", width = 15)
39 39 @ApiModelProperty(value = "入库组盘ID")
40 40 private Integer receiptContainerHeaderId;
  41 + /**出库组盘ID*/
  42 + @Excel(name = "出库组盘ID", width = 15)
  43 + @ApiModelProperty(value = "出库组盘ID")
  44 + private Integer shipmentContainerHeaderId;
41 45 /**仓库*/
42 46 @Excel(name = "仓库", width = 15)
43 47 @ApiModelProperty(value = "仓库")
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/ITaskHeaderService.java
... ... @@ -31,6 +31,7 @@ public interface ITaskHeaderService extends IService&lt;TaskHeader&gt; {
31 31  
32 32 Result createTransferTask(String fromLocationCode, String toLocationCode, String warehouseCode);
33 33  
  34 +
34 35 TaskHeader getUnCompleteTaskByFromLocationCode(String fromLocationCode, String warehouseCode);
35 36  
36 37 TaskHeader getUnCompleteTaskByToLocationCode(String toLocationCode, String warehouseCode);
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java
... ... @@ -22,6 +22,11 @@ import org.jeecg.modules.wms.receipt.receiptContainerHeader.service.IReceiptCont
22 22 import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptDetail;
23 23 import org.jeecg.modules.wms.receipt.receiptHeader.service.IReceiptDetailService;
24 24 import org.jeecg.modules.wms.receipt.receiptHeader.service.IReceiptHeaderService;
  25 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerDetail;
  26 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerHeader;
  27 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerDetailService;
  28 +import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerHeaderService;
  29 +import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentHeaderService;
25 30 import org.jeecg.modules.wms.task.taskHeader.entity.TaskDetail;
26 31 import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader;
27 32 import org.jeecg.modules.wms.task.taskHeader.mapper.TaskDetailMapper;
... ... @@ -78,6 +83,12 @@ public class TaskHeaderServiceImpl extends ServiceImpl&lt;TaskHeaderMapper, TaskHea
78 83 @Resource
79 84 private IReceiptContainerHeaderService receiptContainerHeaderService;
80 85 @Resource
  86 + private IShipmentContainerDetailService shipmentContainerDetailService;
  87 + @Resource
  88 + private IShipmentContainerHeaderService shipmentContainerHeaderService;
  89 + @Resource
  90 + private IShipmentHeaderService shipmentHeaderService;
  91 + @Resource
81 92 private IMaterialService materialService;
82 93 @Resource
83 94 private WcsService wcsService;
... ... @@ -316,6 +327,10 @@ public class TaskHeaderServiceImpl extends ServiceImpl&lt;TaskHeaderMapper, TaskHea
316 327 case QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT:
317 328 result = completeReceiptTask(taskHeader);
318 329 break;
  330 + case QuantityConstant.TASK_TYPE_WHOLESHIPMENT:
  331 + case QuantityConstant.TASK_TYPE_SORTINGSHIPMENT:
  332 + result = completeShipmentTask(taskHeader);
  333 + break;
319 334 default:
320 335 throw new ServiceException("不支持的任务类型" + taskType);
321 336 }
... ... @@ -349,7 +364,6 @@ public class TaskHeaderServiceImpl extends ServiceImpl&lt;TaskHeaderMapper, TaskHea
349 364 boolean success = false;
350 365 String warehouseCode = taskHeader.getWarehouseCode();
351 366 String containerCode = taskHeader.getContainerCode();
352   - String toLocationCode = taskHeader.getToLocationCode();
353 367  
354 368 InventoryHeader inventoryHeader = inventoryHeaderService.
355 369 getInventoryHeaderByContainerCode(containerCode, warehouseCode);
... ... @@ -361,9 +375,9 @@ public class TaskHeaderServiceImpl extends ServiceImpl&lt;TaskHeaderMapper, TaskHea
361 375 if(inventoryDetailList.size() == 0) {
362 376 throw new ServiceException("合并库存时, 没有找到库存详情");
363 377 }
364   - if(inventoryDetailList.size() == 1) {
365   - return true;
366   - }
  378 +// if(inventoryDetailList.size() == 1) {
  379 +// return true;
  380 +// }
367 381 for (int i = 0; i < inventoryDetailList.size() - 1; i++) {
368 382 for (int j = inventoryDetailList.size() - 1; j > i; j--) {
369 383 InventoryDetail inventoryDetail1 = inventoryDetailList.get(i);
... ... @@ -378,7 +392,7 @@ public class TaskHeaderServiceImpl extends ServiceImpl&lt;TaskHeaderMapper, TaskHea
378 392 if(!success) {
379 393 throw new ServiceException("合并库存时, 更新库存详情失败:" + inventoryDetail1.getId());
380 394 }
381   - success = inventoryDetailService.removeById(inventoryDetail2);
  395 + success = inventoryDetailService.removeById(inventoryDetail2.getId());
382 396 if(!success) {
383 397 throw new ServiceException("合并库存时, 删除库存详情失败:" + inventoryDetail2.getId());
384 398 }
... ... @@ -417,6 +431,12 @@ public class TaskHeaderServiceImpl extends ServiceImpl&lt;TaskHeaderMapper, TaskHea
417 431 int taskType = taskHeader.getTaskType();
418 432 List<TaskDetail> taskDetailList = taskDetailService.getTaskDetailListByTaskId(taskHeader.getId());
419 433 boolean success = false;
  434 + if(taskHeader == null) {
  435 + return Result.error("任务未找到,执行中止");
  436 + }
  437 + if (taskHeader.getStatus().equals(QuantityConstant.TASK_STATUS_COMPLETED)) {
  438 + return Result.ok("任务(" +taskHeader.getId() + ")任务已经是完成的!");
  439 + }
420 440 if (taskDetailList.isEmpty()) {
421 441 throw new ServiceException("任务明细为空");
422 442 }
... ... @@ -560,4 +580,170 @@ public class TaskHeaderServiceImpl extends ServiceImpl&lt;TaskHeaderMapper, TaskHea
560 580 return Result.ok("完成入库任务");
561 581 }
562 582  
  583 + /**
  584 + * 完成出库任务
  585 + * @param taskHeader 任务
  586 + * @return result 完成出库任务
  587 + */
  588 + @Transactional(rollbackFor = Exception.class)
  589 + public Result completeShipmentTask(TaskHeader taskHeader) {
  590 + String warehouseCode = taskHeader.getWarehouseCode();
  591 + String fromLocationCode = taskHeader.getFromLocationCode();
  592 + String toLocationCode = taskHeader.getToLocationCode();
  593 + String zoneCode = taskHeader.getZoneCode();
  594 + String containerCode = taskHeader.getContainerCode();
  595 + int taskType = taskHeader.getTaskType();
  596 + List<TaskDetail> taskDetailList = taskDetailService.getTaskDetailListByTaskId(taskHeader.getId());
  597 + boolean success = false;
  598 + if(taskHeader == null) {
  599 + return Result.error("完成出库任务未找到,执行中止");
  600 + }
  601 + if (taskHeader.getStatus().equals(QuantityConstant.TASK_STATUS_COMPLETED)) {
  602 + return Result.ok("完成出库任务,(" + taskHeader.getId() + ")任务已经是完成的!");
  603 + }
  604 + if (taskDetailList.isEmpty()) {
  605 + throw new ServiceException("完成出库任务,任务明细为空");
  606 + }
  607 + if (StringUtils.isEmpty(fromLocationCode)) {
  608 + throw new ServiceException("完成出库任务" + taskHeader.getId() + "没有起始库位,执行中止");
  609 + }
  610 + if (StringUtils.isEmpty(toLocationCode)
  611 + && taskType == QuantityConstant.TASK_TYPE_SORTINGSHIPMENT) {
  612 + throw new ServiceException("完成出库任务,任务" + taskHeader.getId() + "没有目的库位,执行中止");
  613 + }
  614 + InventoryHeader inventoryHeader = inventoryHeaderService
  615 + .getInventoryHeaderByContainerCode(containerCode, warehouseCode);
  616 + if(inventoryHeader == null) {
  617 + throw new ServiceException("完成出库任务,出库任务" + taskHeader.getId() + "没有找到库存头");
  618 + }
  619 + List<InventoryTransaction> inventoryTransactionList = new ArrayList<>();
  620 + List<Integer> shipmentIdList = new ArrayList<>();
  621 + for(TaskDetail taskDetail : taskDetailList) {
  622 + ShipmentContainerDetail shipmentContainerDetail =
  623 + shipmentContainerDetailService.getById(taskDetail.getShipmentContainerDetailId());
  624 + if(shipmentContainerDetail == null) {
  625 + throw new ServiceException("完成出库任务, 出库任务没有找到出库组盘详情" + taskDetail.getShipmentContainerDetailId());
  626 + }
  627 + InventoryDetail inventoryDetail =
  628 + inventoryDetailService.getById(taskDetail.getFromInventoryDetailId());
  629 + if(inventoryDetail == null) {
  630 + throw new ServiceException("完成出库任务,出库任务没有找到库存详情" + taskDetail.getFromInventoryDetailId());
  631 + }
  632 + inventoryDetail.setTaskQty(inventoryDetail.getTaskQty().subtract(taskDetail.getQty()));
  633 + inventoryDetail.setQty(inventoryDetail.getQty().subtract(taskDetail.getQty()));
  634 + inventoryDetail.setLocationCode(toLocationCode);
  635 + //扣减后的库存不能小于0
  636 + if (inventoryDetail.getQty().compareTo(BigDecimal.ZERO) < 0) {
  637 + throw new ServiceException("完成出库任务,扣减库存大于wms库存");
  638 + }
  639 + if (inventoryDetail.getQty().compareTo(BigDecimal.ZERO) == 0) {
  640 + if(inventoryDetail.getTaskQty().compareTo(BigDecimal.ZERO) != 0) {
  641 + throw new ServiceException("完成出库任务,扣减库存的库存详情任务数量不为0");
  642 + }
  643 + success = inventoryDetailService.removeById(inventoryDetail.getId());
  644 + if(!success) {
  645 + throw new ServiceException("完成出库任务,删除库存详情失败");
  646 + }
  647 + } else {
  648 + success = inventoryDetailService.updateById(inventoryDetail);
  649 + if(!success) {
  650 + throw new ServiceException("完成出库任务,更新库存详情失败");
  651 + }
  652 + }
  653 +
  654 + InventoryTransaction inventoryTransaction = new InventoryTransaction();
  655 + inventoryTransaction.setType(QuantityConstant.INVENTORY_TRANSACTION_SHIPMENT);
  656 + inventoryTransaction.setWarehouseCode(warehouseCode);
  657 + inventoryTransaction.setCompanyCode(inventoryDetail.getCompanyCode());
  658 + inventoryTransaction.setContainerCode(containerCode);
  659 + inventoryTransaction.setLocationCode(fromLocationCode);
  660 + inventoryTransaction.setMaterialCode(inventoryDetail.getMaterialCode());
  661 + inventoryTransaction.setMaterialName(inventoryDetail.getMaterialName());
  662 + inventoryTransaction.setMaterialSpec(inventoryDetail.getMaterialSpec());
  663 + inventoryTransaction.setMaterialUnit(inventoryDetail.getMaterialUnit());
  664 + inventoryTransaction.setInventoryStatus(inventoryDetail.getInventoryStatus());
  665 + inventoryTransaction.setShipmentId(taskDetail.getShipmentId());
  666 + inventoryTransaction.setShipmentDetailId(taskDetail.getShipmentDetailId());
  667 + inventoryTransaction.setShipmentContainerDetailId(taskDetail.getShipmentContainerDetailId());
  668 + inventoryTransaction.setBatch(inventoryDetail.getBatch());
  669 + inventoryTransaction.setLot(inventoryDetail.getLot());
  670 + inventoryTransaction.setProject(inventoryDetail.getProject());
  671 + inventoryTransaction.setQty(taskDetail.getQty());
  672 + inventoryTransactionList.add(inventoryTransaction);
  673 + shipmentIdList.add(taskDetail.getShipmentId());
  674 + }
  675 + String containerStatus = QuantityConstant.STATUS_CONTAINER_SOME;
  676 + List<InventoryDetail> inventoryDetailList = inventoryDetailService
  677 + .getInventoryDetailListByInventoryHeaderId(inventoryHeader.getId());
  678 + if(inventoryDetailList.size() == 0) {
  679 + success = inventoryHeaderService.removeById(inventoryHeader.getId());
  680 + if(!success) {
  681 + throw new ServiceException("完成出库任务,删除库存头失败");
  682 + }
  683 + containerStatus = QuantityConstant.STATUS_CONTAINER_EMPTY;
  684 + } else {
  685 + if(taskType == QuantityConstant.TASK_TYPE_WHOLESHIPMENT) {
  686 + throw new ServiceException("完成整盘出库任务,不能还剩库存详情");
  687 + }
  688 + containerStatus = QuantityConstant.STATUS_CONTAINER_SOME;
  689 + }
  690 +
  691 + success = inventoryTransactionService.saveBatch(inventoryTransactionList);
  692 + if(!success) {
  693 + throw new ServiceException("完成出库任务,保存库存详情失败");
  694 + }
  695 + taskHeader.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
  696 + success = taskHeaderService.updateById(taskHeader);
  697 + if(!success) {
  698 + throw new ServiceException("完成出库任务,保存任务头失败");
  699 + }
  700 + if(taskType == QuantityConstant.TASK_TYPE_WHOLESHIPMENT) {
  701 + success = locationService.updateContainerCodeAndStatus(
  702 + fromLocationCode, QuantityConstant.EMPTY_STRING, QuantityConstant.STATUS_LOCATION_EMPTY, warehouseCode);
  703 + if(!success) {
  704 + throw new ServiceException("完成整盘出库任务,更新源库位失败");
  705 + }
  706 + containerService.updateLocationCodeAndStatus(containerCode, QuantityConstant.EMPTY_STRING,
  707 + QuantityConstant.STATUS_CONTAINER_EMPTY, warehouseCode);
  708 + if(!success) {
  709 + throw new ServiceException("完成整盘出库任务,更新容器失败");
  710 + }
  711 + } else if(taskType == QuantityConstant.TASK_TYPE_SORTINGSHIPMENT) {
  712 + success = locationService.updateContainerCodeAndStatus(
  713 + fromLocationCode, QuantityConstant.EMPTY_STRING, QuantityConstant.STATUS_LOCATION_EMPTY, warehouseCode);
  714 + if(!success) {
  715 + throw new ServiceException("完成分拣出库任务,更新源库位失败");
  716 + }
  717 + success = locationService.updateContainerCodeAndStatus(
  718 + toLocationCode, containerCode, QuantityConstant.STATUS_LOCATION_EMPTY, warehouseCode);
  719 + if(!success) {
  720 + throw new ServiceException("完成分拣出库任务,更新目标库位失败");
  721 + }
  722 + success = containerService.updateLocationCodeAndStatus(
  723 + containerCode, toLocationCode, containerStatus, warehouseCode);
  724 + if(!success) {
  725 + throw new ServiceException("完成分拣出库任务,更新容器失败");
  726 + }
  727 + }
  728 + ShipmentContainerHeader shipmentContainerHeader = shipmentContainerHeaderService
  729 + .getById(taskHeader.getShipmentContainerHeaderId());
  730 + if(shipmentContainerHeader == null) {
  731 + throw new ServiceException("完成出库任务,获取出库组盘头失败");
  732 + }
  733 + shipmentContainerHeader.setStatus(QuantityConstant.SHIPMENT_CONTAINER_FINISHED);
  734 + success = shipmentContainerHeaderService.updateById(shipmentContainerHeader);
  735 + if(!success) {
  736 + throw new ServiceException("完成出库任务,更新出库组盘头失败");
  737 + }
  738 + if(inventoryDetailList.size() != 0) {
  739 + if(!combineInventoryDetail(taskHeader)) {
  740 + throw new ServiceException("合并入库库存失败");
  741 + }
  742 + }
  743 + shipmentIdList = shipmentIdList.stream().distinct().collect(Collectors.toList());
  744 + for(Integer shipmentId : shipmentIdList) {
  745 + shipmentHeaderService.updateShipmentHeaderStatus(shipmentId);
  746 + }
  747 + return Result.ok("完成出库任务");
  748 + }
563 749 }
... ...
jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/resources/application.yml
... ... @@ -2,4 +2,4 @@ spring:
2 2 application:
3 3 name: jeecg-system
4 4 profiles:
5   - active: @profile.name@
6 5 \ No newline at end of file
  6 + active: dev
... ...