opt:优化倒扣

This commit is contained in:
zhangzq
2026-08-04 10:51:59 +08:00
parent 2d0225bc09
commit b8355e723e
9 changed files with 155 additions and 33 deletions

View File

@@ -4,6 +4,9 @@ import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import org.nl.wms.ext_manage.mes.service.MesReportService;
import org.nl.wms.ext_manage.mes.service.dto.WorkReportParam;
import org.nl.wms.system_manage.service.logserver.lucene.BaseCode;
import org.nl.wms.system_manage.service.logserver.lucene.LuceneAppender;
import org.slf4j.MDC;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
@@ -20,6 +23,13 @@ public class WorkReportConsumer {
public void consume(String param, Channel channel,
@Header(AmqpHeaders.DELIVERY_TAG) long tag) {
System.out.println("======WorkReportConsumer======"+tag);
mesReportService.workReportReturn(JSONObject.parseObject(param,WorkReportParam.class));
try {
LuceneAppender.traceIdTL.set(BaseCode.intToChars(org.nl.common.utils.IdUtil.getLongId()));
mesReportService.workReportReturn(JSONObject.parseObject(param,WorkReportParam.class));
}finally {
LuceneAppender.traceIdTL.remove();
MDC.clear();
}
}
}

View File

@@ -1,8 +1,10 @@
package org.nl.wms.ext_manage.mes.mq.producer;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.nl.wms.ext_manage.mes.service.MesReportService;
import org.nl.wms.ext_manage.mes.service.dto.WorkReportParam;
import org.nl.wms.warehouse_manage.stockReturn.receiveOutRetur.dao.ReceiveOutReturn;
import org.nl.wms.warehouse_manage.stockReturn.receiveOutRetur.service.IReceiveOutReturnService;
@@ -15,14 +17,12 @@ public class WorkReportProducer {
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private MesReportService mesReportService;
@Autowired
private IReceiveOutReturnService receiveOutReturnService;
public void send(WorkReportParam param) {
if (!StringUtils.isEmpty(param.getSn())){
ReceiveOutReturn one = receiveOutReturnService.getOne(new LambdaQueryWrapper<ReceiveOutReturn>()
.eq(ReceiveOutReturn::getSn, param.getSn()));
if (one != null) return;//已存在跳过
}
rabbitTemplate.convertAndSend("Mes", "workReport", JSON.toJSONString(param));
mesReportService.workReportReturn(param);
// rabbitTemplate.convertAndSend("Mes", "workReport", JSON.toJSONString(param));
}
}

View File

@@ -3,6 +3,7 @@ package org.nl.wms.ext_manage.mes.service.impl;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nl.common.exception.BadRequestException;
import org.nl.common.utils.SecurityUtils;
@@ -24,6 +25,7 @@ import java.math.BigDecimal;
import java.time.LocalDate;
@Service
@Slf4j
public class MesReportServiceImpl implements MesReportService {
@Autowired
@@ -38,11 +40,21 @@ public class MesReportServiceImpl implements MesReportService {
@Override
public void workReportReturn(WorkReportParam workReportParam) {
try {
if (!StringUtils.isEmpty(workReportParam.getSn())){
int count = iReceiveOutReturnService.count(new LambdaQueryWrapper<ReceiveOutReturn>()
.eq(ReceiveOutReturn::getSn, workReportParam.getSn()));
if (count > 0) {
throw new BadRequestException("报工倒扣同步失败SN码重复");
}
}
String SrcBillNo = workReportParam.getSrcBillNo();
BigDecimal qty = workReportParam.getReportedQty();
if (StringUtils.isEmpty(SrcBillNo)||qty == null){
if (StringUtils.isEmpty(SrcBillNo)){
throw new BadRequestException("报工倒扣同步失败ERP源单号不存在为空");
}
if (qty == null ||qty.intValue() <=0 ){
throw new BadRequestException("报工倒扣同步失败,报工数量不正确");
}
//TODO: 查询哪些是大件哪些是小件
//workAreag根据功能做区域查看对于的库区工作区域与库区编码一直
final SchBaseRegion region = iSchBaseRegionService.getOne(new LambdaQueryWrapper<SchBaseRegion>()
@@ -72,6 +84,7 @@ public class MesReportServiceImpl implements MesReportService {
sideDto.setWorkArea(workReportParam.getWorkArea());
pdaIosOutService.directConfirm(sideDto);
}catch (Exception ex){
log.error("报工回传异常:{}",ex);
ReceiveOutReturn entity = new ReceiveOutReturn();
entity.setOrgno(workReportParam.getOrgNo());
entity.setSn(workReportParam.getSn());

View File

@@ -290,12 +290,14 @@ public class PdaIosOutServiceImpl implements PdaIosOutService {
entry.setSrcbillno(param.getSrcBillNo());
entry.setSrcbillid(param.getSrcBillId());
entry.setSrcbillentryid(bomItem.getItemId());
if (qty.compareTo(actualQty) > 0) {
if (bomQty.intValue() == 0 || qty.compareTo(actualQty) > 0) {
status = StockReturnStatusEnum.FAIL.getCode();
entry.setStatus(StockReturnStatusEnum.FAIL.getCode());
entry.setRemark(materialCode+"WMS库存不足:当前" + actualQty + "需求" + qty.intValue());
if (entry.getBaseqty().compareTo(BigDecimal.ZERO) == 0){
if (bomQty.intValue() == 0 ){
entry.setRemark("bom数量为0");
entry.setStatus(StockReturnStatusEnum.IGNORE.getCode());
}else {
entry.setStatus(StockReturnStatusEnum.FAIL.getCode());
entry.setRemark("WMS库存不足:当前" + actualQty + "需求" + qty.intValue());
}
entrys.add(entry);
}else {

View File

@@ -1,6 +1,7 @@
package org.nl.wms.warehouse_manage.stockReturn.receiveOutRetur.controller;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import org.nl.common.base.ResponseData;
import org.nl.common.domain.query.PageQuery;
import org.nl.common.logging.annotation.Log;
@@ -9,6 +10,9 @@ import org.nl.wms.ext_manage.api.EasApi;
import org.nl.wms.ext_manage.api.request.QueryEasStockRequest;
import org.nl.wms.ext_manage.api.response.QueryEasStockResponse;
import org.nl.wms.ext_manage.service.WmsToErpService;
import org.nl.wms.warehouse_manage.inventory.IStInventoryService;
import org.nl.wms.warehouse_manage.inventory.dto.StInventoryDto;
import org.nl.wms.warehouse_manage.inventory.dto.StInventoryQuery;
import org.nl.wms.warehouse_manage.stockReturn.receiveOutRetur.dao.ReceiveOutReturn;
import org.nl.wms.warehouse_manage.stockReturn.receiveOutRetur.dto.ReceiveOutReturnDto;
import org.nl.wms.warehouse_manage.stockReturn.receiveOutRetur.dto.ReceiveOutReturnQuery;
@@ -20,6 +24,8 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
@@ -30,6 +36,10 @@ public class ReceiveOutReturnController {
@Resource
private IReceiveOutReturnService receiveOutReturnService;
@Resource
private IStInventoryService iStInventoryService;
@Resource
private EasApi easApi;
@@ -87,5 +97,32 @@ public class ReceiveOutReturnController {
.sum(); }
return ResponseData.build(MapOf.of("qty",totalQty));
}
@GetMapping("/allStock")
public ResponseEntity<Object> allStock(String warehouseno,String materialno) {
QueryEasStockRequest easRequest = new QueryEasStockRequest();
easRequest.setOrgno("01.09.14");
easRequest.setWarehouseno(warehouseno);
easRequest.setMaterialno(materialno);
List<QueryEasStockResponse> easStocks = easApi.queryStock(easRequest);
int totalQty = 0;
if (!CollectionUtils.isEmpty(easStocks)){
totalQty = easStocks.stream()
.mapToInt(item -> Integer.parseInt(item.getQty()))
.sum();
}
String result;
result="EAS:"+totalQty;
final List<StInventoryDto> stInventoryDtos = iStInventoryService.queryInventory(StInventoryQuery.builder()
.materialCode(materialno)
.sectCode(Arrays.asList(warehouseno)).build());
int wmsTotalQty = 0;
if (!CollectionUtils.isEmpty(stInventoryDtos)){
wmsTotalQty = stInventoryDtos.stream()
.mapToInt(item -> item.getQty().intValue())
.sum();
}
result=result+",WMS:"+wmsTotalQty;
return ResponseData.build(result);
}
}

View File

@@ -10,6 +10,8 @@ public class ReceiveOutReturnDto {
private Long id;
private String orgno;
private String sn;
private String trackNo;
private String workArea;
private String billno;
private String biztype;
private String invscheme;

View File

@@ -251,6 +251,8 @@ public class ReceiveOutReturnServiceImpl extends ServiceImpl<ReceiveOutReturnMap
dto.setId(entity.getId());
dto.setOrgno(entity.getOrgno());
dto.setSn(entity.getSn());
dto.setTrackNo(entity.getTrackNo());
dto.setWorkArea(entity.getWorkArea());
dto.setBillno(entity.getBillno());
dto.setBiztype(entity.getBiztype());
dto.setInvscheme(entity.getInvscheme());

View File

@@ -49,6 +49,16 @@
>
回传EAS
</el-button>
<el-button
slot="right"
class="filter-item"
type="sucess"
icon="el-icon-position"
size="mini"
@click="deductionOrderSync"
>
重新提交报工
</el-button>
</crudOperation>
<el-table ref="table" v-loading="crud.loading" :data="crud.data" size="mini" style="width: 100%" @selection-change="crud.selectionChangeHandler" @current-change="handleCurrentChange" @select="handleSelectionChange">
<el-table-column type="selection" width="55" />
@@ -62,20 +72,16 @@
<el-link type="primary" @click="toView(scope.row)">{{ scope.row.billno }}</el-link>
</template>
</el-table-column>
<el-table-column prop="requestId" label="出入库单号" min-width="140" />
<el-table-column prop="sn" label="序列码" min-width="140" />
<el-table-column prop="trackNo" label="跟踪号" min-width="100" />
<el-table-column prop="workArea" label="产线" min-width="100" />
<el-table-column prop="status" label="回传状态" width="100">
<template slot-scope="scope">
<el-tag :type="statusTagType(scope.row.status)" size="mini">{{ statusLabel(scope.row.status) }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="remark" label="回传备注" min-width="180" show-overflow-tooltip />
<el-table-column prop="orgno" label="机构编号" min-width="120" />
<el-table-column prop="biztype" label="业务类型" min-width="100" />
<el-table-column prop="invscheme" label="库存方案" min-width="100" />
<el-table-column prop="trackNo" label="跟踪号" min-width="100" />
<el-table-column prop="workArea" label="产线" min-width="100" />
<el-table-column prop="transtype" label="交易类型" min-width="100" />
<el-table-column prop="remark" label="备注" min-width="180" show-overflow-tooltip />
<el-table-column prop="requestId" label="出入库单号" min-width="140" />
<el-table-column prop="biztime" label="业务时间" min-width="160" />
<el-table-column prop="createTime" label="创建时间" min-width="160" />
<el-table-column prop="reportParam" label="报工参数" min-width="200" show-overflow-tooltip />
@@ -87,8 +93,9 @@
<el-form ref="form" :model="form" :rules="rules" size="mini" label-width="110px" label-suffix=":" style="border: 1px solid #cfe0df;margin-top: 10px;padding: 10px;">
<el-row>
<el-col :span="12"><el-form-item label="工单号" prop="billno"><el-input v-model.trim="form.billno" style="width: 300px;" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="出入库单号" prop="requestId"><el-input v-model.trim="form.requestId" style="width: 300px;" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="序列码" prop="sn"><el-input v-model.trim="form.sn" style="width: 300px;" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="跟踪号" prop="sn"><el-input v-model.trim="form.trackNo" style="width: 300px;" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="产线" prop="sn"><el-input v-model.trim="form.workArea" style="width: 300px;" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="机构编号" prop="orgno"><el-input v-model.trim="form.orgno" style="width: 300px;" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="业务类型" prop="biztype"><el-input v-model.trim="form.biztype" style="width: 300px;" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="库存方案" prop="invscheme"><el-input v-model.trim="form.invscheme" style="width: 300px;" /></el-form-item></el-col>
@@ -101,6 +108,7 @@
<el-col :span="12"><el-form-item label="回传状态" prop="status"><el-select v-model="form.status" style="width: 300px;"><el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" /></el-select></el-form-item></el-col>
<el-col :span="24"><el-form-item label="备注" prop="comment"><el-input v-model.trim="form.comment" type="textarea" :rows="2" style="width: 740px;" /></el-form-item></el-col>
<el-col :span="24"><el-form-item label="回传备注" prop="remark"><el-input v-model.trim="form.remark" type="textarea" :rows="2" style="width: 740px;" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="出入库单号" prop="requestId"><el-input v-model.trim="form.requestId" style="width: 300px;" /></el-form-item></el-col>
<el-col :span="24"><el-form-item label="报工参数" prop="remark"><el-input v-model.trim="form.reportParam" type="textarea" :rows="2" style="width: 740px;" /></el-form-item></el-col>
</el-row>
</el-form>
@@ -110,17 +118,20 @@
<el-dialog :visible.sync="viewShow" title="倒扣回传详情" width="1200px" :close-on-click-modal="false">
<el-descriptions :column="2" border size="mini">
<el-descriptions-item label="工单号">{{ currentRow.billno }}</el-descriptions-item>
<el-descriptions-item label="出入库单号">{{ currentRow.requestId }}</el-descriptions-item>
<el-descriptions-item label="序列码">{{ currentRow.sn }}</el-descriptions-item>
<el-descriptions-item label="跟踪号">{{ currentRow.trackNo }}</el-descriptions-item>
<el-descriptions-item label="产线">{{ currentRow.workArea }}</el-descriptions-item>
<el-descriptions-item label="备注">{{ currentRow.comment }}</el-descriptions-item>
<el-descriptions-item label="回传状态">{{ statusLabel(currentRow.status) }}</el-descriptions-item>
<el-descriptions-item label="备注" :span="2">{{ currentRow.comment }}</el-descriptions-item>
<el-descriptions-item label="回传备注" :span="2">{{ currentRow.remark }}</el-descriptions-item>
<el-descriptions-item label="机构编号">{{ currentRow.orgno }}</el-descriptions-item>
<el-descriptions-item label="业务类型">{{ currentRow.biztype }}</el-descriptions-item>
<el-descriptions-item label="库存方案">{{ currentRow.invscheme }}</el-descriptions-item>
<el-descriptions-item label="交易类型">{{ currentRow.transtype }}</el-descriptions-item>
<el-descriptions-item label="业务时间">{{ currentRow.biztime }}</el-descriptions-item>
<el-descriptions-item label="创建时间">{{ currentRow.createTime }}</el-descriptions-item>
<el-descriptions-item label="回传备注" :span="2">{{ currentRow.remark }}</el-descriptions-item>
<el-descriptions-item label="出入库单号">{{ currentRow.requestId }}</el-descriptions-item>
<el-descriptions-item label=""></el-descriptions-item>
<el-descriptions-item label="报工参数" :span="2">{{ currentRow.reportParam }}</el-descriptions-item>
</el-descriptions>
<el-table :data="pagedDetails" size="mini" style="width: 100%; margin-top: 12px;">
@@ -135,15 +146,12 @@
<el-table-column prop="qty" label="工单扣减数量" min-width="100" />
<el-table-column prop="baseqty" label="bom数量" min-width="100" />
<el-table-column prop="warehouseno" label="仓库编号" min-width="120" />
<el-table-column prop="easQty" label="eas库存" min-width="120" />
<el-table-column prop="updateTime" label="更新时间" min-width="120" />
<el-table-column prop="remark" label="说明" min-width="120" />
<el-table-column prop="srcbillno" label="源单据编号" min-width="140" />
<el-table-column prop="srcbillno" label="源单据编号" min-width="140" />
<el-table-column prop="lotnumber" label="批号" min-width="100" />
<el-table-column prop="tracknumber" label="追踪号" min-width="120" />
<!-- 新增操作列 -->
<el-table-column label="操作" width="140" align="center" fixed="right">
<el-table-column label="操作" width="210" align="center" fixed="right">
<template slot-scope="scope">
<el-button
size="mini"
@@ -151,7 +159,7 @@
plain
@click="handleSyncEasStock(scope.row)"
>
EAS库存
{{ scope.row.easQty || '库存查询' }}
</el-button>
</template>
</el-table-column>
@@ -182,6 +190,8 @@ import { uploadReceiveOut } from './receiveOutReturn'
const createDefaultForm = () => ({
id: null,
orgno: '',
trackNo: '',
workArea: '',
sn: '',
billno: '',
biztype: '',
@@ -295,11 +305,10 @@ export default {
this.$message.warning('仓库编号不能为空')
return
}
crudReceiveOutReturn.easStock({ 'warehouseno': row.warehouseno, 'materialno': row.materialno }).then(res => {
crudReceiveOutReturn.allStock({ 'warehouseno': row.warehouseno, 'materialno': row.materialno }).then(res => {
if (res.code === 200) {
// 显示同步结果
const qty = res.data.qty
this.$message.success(`EAS当前库存数量${qty}`)
const qty = res.data
// 可选:在行中显示查询到的库存数量
this.$set(row, 'easQty', qty)
} else {
@@ -339,6 +348,38 @@ export default {
}
doUpload()
},
deductionOrderSync() {
const rows = this.crud.selections || []
if (rows.length < 1) {
this.crud.notify('请选择一条记录', CRUD.NOTIFICATION_TYPE.INFO)
return
}
if (rows.length > 1) {
this.crud.notify('只能选择一条记录', CRUD.NOTIFICATION_TYPE.INFO)
return
}
const row = rows[0]
const doUpload = () => {
this.fullscreenLoading = true
crudReceiveOutReturn.deductionOrderSync(JSON.parse(row.reportParam)).then(() => {
this.crud.notify('单据重新报工成功!', CRUD.NOTIFICATION_TYPE.SUCCESS)
this.crud.toQuery()
}).finally(() => {
this.fullscreenLoading = false
})
}
if (String(row.status) === '1') {
this.$confirm('该单据已回传成功,是否继续回传?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(doUpload).catch(() => {
this.$message({ type: 'info', message: '已取消回传' })
})
return
}
doUpload()
},
statusLabel(status) {
const target = this.statusOptions.find(item => String(item.value) === String(status))
return target ? target.label : status

View File

@@ -37,6 +37,13 @@ export function easStock(param) {
params: param
})
}
export function allStock(param) {
return request({
url: '/api/receiveOutReturn/allStock',
method: 'get',
params: param
})
}
export function uploadReceiveOut(data) {
return request({
url: '/api/receiveOutReturn/upload',
@@ -44,4 +51,12 @@ export function uploadReceiveOut(data) {
data
})
}
export default { add, edit, del, get, easStock, uploadReceiveOut }
export function deductionOrderSync(data) {
return request({
url: '/app/restful/api/v3/wms/deductionOrderSync',
method: 'post',
data
})
}
export default { add, edit, del, get, easStock, uploadReceiveOut, allStock, deductionOrderSync }