入库出库作业单调整

This commit is contained in:
秦鸿展
2026-04-27 09:47:32 +08:00
parent 4767cf986b
commit a76e9c4367
18 changed files with 553 additions and 185 deletions
@@ -106,7 +106,8 @@ public class BatchDetailApplicationService {
throw new ServiceException("获取物料规则信息失败");
}
MaterialGoodsRuleFeign materialGoodsRuleFeign = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), MaterialGoodsRuleFeign.class);
if (ObjectUtil.isNull(materialGoodsRuleFeign)){
if (ObjectUtil.isNull(materialGoodsRuleFeign) || materialGoodsRuleFeign.getBatchId() == null) {
// 未绑定批次时只返回空列表,不可按空 batchId 全表查 batch_detail
return new ArrayList<>();
}
return getBatchDetailListByBatchId(materialGoodsRuleFeign.getBatchId());
@@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* 批次管理详情
@@ -66,6 +67,10 @@ public class BatchDetailDomainService {
* 获取批次管理详情详细信息
*/
public List<BatchDetailPO> getBatchDetailListByBatchId(Long batchId) {
if (batchId == null) {
// batchId 为 null 时不能按 batchId 条件查询,否则 MyBatis 会略过 batch_id 条件导致整表全量
return new ArrayList<>();
}
BatchDetailDO batchDetailDO = new BatchDetailDO();
batchDetailDO.setBatchId(batchId);
return batchDetailService.queryList(batchDetailDO);
+4
View File
@@ -59,4 +59,8 @@ ALTER TABLE NGWL_TEST_WMS.PICKING_MATERIAL_DETAIL ADD IN_ORDER_NUMBER varchar(10
ALTER TABLE stock_receipt_order ADD oms_stock_in_order_id VARCHAR(64);
@@ -216,6 +216,10 @@ public class StockReceiptOrderApplicationService {
Map<Long, List<BatchDetailFeignPO>> batchDetailMap = new HashMap<>();
for (Long materialBaseInfoId : materialBaseInfoIdSet) {
try {
MaterialGoodsRulePO localGoodsRule = materialGoodsRuleService.getInfoByMaterialBaseInfoIds(materialBaseInfoId);
if (localGoodsRule == null || localGoodsRule.getBatchId() == null) {
continue;
}
AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId);
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
List<BatchDetailFeignPO> batchDetailFeignPOList = JSON.parseArray(
@@ -2328,6 +2328,9 @@ public class StockShelfOrderApplicationService {
}
}
}
if (materialMoreDetailList.isEmpty() && !CollectionUtils.isEmpty(existingList)) {
materialMoreDetailList.addAll(existingList);
}
shelfMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList);
log.info("物料明细 uniqueId={}, materialBaseInfoId={}, materialMoreDetailList大小={}",
shelfMaterialDetailPO.getUniqueId(), shelfMaterialDetailPO.getMaterialBaseInfoId(),
@@ -39,6 +39,8 @@ import com.mhd.wms.domain.materialInventory.entity.MaterialInventory;
import com.mhd.wms.domain.materialInventory.repository.facade.IMaterialInventoryService;
import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryDO;
import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper;
import com.mhd.wms.domain.materialGoodsRule.repository.facade.IMaterialGoodsRuleService;
import com.mhd.wms.domain.materialGoodsRule.repository.po.MaterialGoodsRulePO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -85,6 +87,8 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
@Autowired
private com.mhd.wms.domain.stockInOrder.repository.facade.IStockInOrderService stockInOrderService;
@Autowired
private IMaterialGoodsRuleService materialGoodsRuleService;
@Autowired
private MaterialInventoryMapper materialInventoryMapper;
/**
* 查询物料明细列表
@@ -244,6 +248,11 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
if (materialBaseInfoId == null) {
return result;
}
// 本库无商品规则或未绑定 batch_id 时,禁止调 System 拉批次属性(避免 System 对空规则误解析为 batchId=null 时全表查 batch_detail
MaterialGoodsRulePO goodsRule = materialGoodsRuleService.getInfoByMaterialBaseInfoIds(materialBaseInfoId);
if (goodsRule == null || goodsRule.getBatchId() == null) {
return result;
}
try {
AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId);
if (ajaxResult == null || !"200".equals(String.valueOf(ajaxResult.get("code")))) {
@@ -633,6 +642,10 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
private Map<Long, String> loadBatchDetailIdToFieldName(Long materialBaseInfoId) {
Map<Long, String> result = new HashMap<>();
MaterialGoodsRulePO gr = materialGoodsRuleService.getInfoByMaterialBaseInfoIds(materialBaseInfoId);
if (gr == null || gr.getBatchId() == null) {
return result;
}
try {
AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId);
if (ajaxResult == null || !"200".equals(String.valueOf(ajaxResult.get("code")))) {
@@ -1055,6 +1068,10 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
if (materialBaseInfoId == null) {
return result;
}
MaterialGoodsRulePO gr = materialGoodsRuleService.getInfoByMaterialBaseInfoIds(materialBaseInfoId);
if (gr == null || gr.getBatchId() == null) {
return result;
}
try {
AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId);
if (ajaxResult == null || !"200".equals(String.valueOf(ajaxResult.get("code")))) {
@@ -1,12 +1,8 @@
package com.mhd.wms.domain.shelfMaterialDetail.repository.persistence;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.SystemServiceFeign;
import com.mhd.system.api.model.LoginUser;
import com.mhd.wms.domain.inMaterialDetailSerialNumber.entity.InMaterialDetailSerialNumber;
import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.facade.IInMaterialDetailSerialNumberService;
@@ -23,14 +19,12 @@ import com.mhd.wms.domain.stockInOrder.repository.facade.IStockInOrderService;
import com.mhd.wms.domain.stockShelfOrder.repository.facade.IStockShelfOrderService;
import com.mhd.wms.domain.stockShelfOrder.repository.todo.StockShelfOrderDO;
import com.mhd.common.core.utils.StringUtils;
import com.mhd.system.api.domain.BatchDetailFeignPO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
@@ -51,8 +45,6 @@ public class ShelfMaterialDetailImpl extends ServiceImpl<ShelfMaterialDetailMapp
private ShelfMaterialDetailMapper shelfMaterialDetailMapper;
@Autowired
private IInMaterialDetailSerialNumberService inMaterialDetailSerialNumberService;
@Resource
private SystemServiceFeign systemServiceFeign;
@Autowired
private IMaterialMoreDetailService IMaterialMoreDetailService;
@@ -80,12 +72,8 @@ public class ShelfMaterialDetailImpl extends ServiceImpl<ShelfMaterialDetailMapp
? shelfMaterialDetailPO.getReceiptUniqueId() : shelfMaterialDetailPO.getUniqueId();
materialMoreDetailDO.setMaterialDetailUniqueId(materialDetailUniqueIdForQuery);
List<MaterialMoreDetailPO> materialMoreDetailList = IMaterialMoreDetailService.queryList(materialMoreDetailDO);
if (CollectionUtils.isEmpty(materialMoreDetailList)) {
AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(shelfMaterialDetailPO.getMaterialBaseInfoId());
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
List<BatchDetailFeignPO> batchList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class);
materialMoreDetailList = filterAndConvertToMaterialMoreDetail(batchList);
}
if (materialMoreDetailList == null) {
materialMoreDetailList = new ArrayList<>();
}
fillAttributeValueFromShelfMaterialDetail(shelfMaterialDetailPO, materialMoreDetailList);
shelfMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList);
@@ -112,12 +100,8 @@ public class ShelfMaterialDetailImpl extends ServiceImpl<ShelfMaterialDetailMapp
? childrenDetailPO.getReceiptUniqueId() : childrenDetailPO.getUniqueId();
materialMoreDetailDO.setMaterialDetailUniqueId(materialDetailUniqueIdForQuery);
List<MaterialMoreDetailPO> materialMoreDetailList = IMaterialMoreDetailService.queryList(materialMoreDetailDO);
if (CollectionUtils.isEmpty(materialMoreDetailList)) {
AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(childrenDetailPO.getMaterialBaseInfoId());
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
List<BatchDetailFeignPO> batchList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class);
materialMoreDetailList = filterAndConvertToMaterialMoreDetail(batchList);
}
if (materialMoreDetailList == null) {
materialMoreDetailList = new ArrayList<>();
}
fillAttributeValueFromShelfMaterialDetail(childrenDetailPO, materialMoreDetailList);
childrenDetailPO.setMaterialMoreDetailList(materialMoreDetailList);
@@ -210,13 +194,6 @@ public class ShelfMaterialDetailImpl extends ServiceImpl<ShelfMaterialDetailMapp
? row.getReceiptUniqueId() : row.getUniqueId();
materialMoreDetailDO.setMaterialDetailUniqueId(materialDetailUniqueIdForQuery);
List<MaterialMoreDetailPO> materialMoreDetailList = IMaterialMoreDetailService.queryList(materialMoreDetailDO);
if (CollectionUtils.isEmpty(materialMoreDetailList)) {
AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(row.getMaterialBaseInfoId());
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
List<BatchDetailFeignPO> batchList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class);
materialMoreDetailList = filterAndConvertToMaterialMoreDetail(batchList);
}
}
if (materialMoreDetailList == null) {
materialMoreDetailList = new ArrayList<>();
}
@@ -224,30 +201,6 @@ public class ShelfMaterialDetailImpl extends ServiceImpl<ShelfMaterialDetailMapp
row.setMaterialMoreDetailList(materialMoreDetailList);
}
/**
* 过滤 isDisplay=1 的批次属性并转换为 MaterialMoreDetailPO与收货/PC 端一致
*/
private List<MaterialMoreDetailPO> filterAndConvertToMaterialMoreDetail(List<BatchDetailFeignPO> batchList) {
List<MaterialMoreDetailPO> result = new ArrayList<>();
if (CollectionUtils.isEmpty(batchList)) {
return result;
}
for (BatchDetailFeignPO po : batchList) {
if (po.getIsDisplay() == null || po.getIsDisplay() != 1) {
continue;
}
MaterialMoreDetailPO mpo = new MaterialMoreDetailPO();
mpo.setBatchId(po.getBatchId());
mpo.setBatchDetailId(po.getBatchDetailId());
mpo.setBatchLabels(po.getBatchLabels());
mpo.setInputControl(po.getInputControl());
mpo.setAttributeFormat(po.getAttributeFormat());
mpo.setAttributeOption(po.getAttributeOption());
result.add(mpo);
}
return result;
}
/**
* 从上架明细中获取收货数量重量体积面积批次属性值并填充到 materialMoreDetailList attributeValue
*/
@@ -2,6 +2,7 @@ package com.mhd.wms.domain.stockInTaskOrder.repository.persistence;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mhd.common.core.constant.SnowFlakeConstants;
import com.mhd.common.core.utils.StringUtils;
import com.mhd.common.core.utils.uuid.IdGenerator;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
@@ -38,6 +39,11 @@ import java.util.List;
*/
@Service
public class StockInTaskOrderImpl extends ServiceImpl<StockInTaskOrderMapper, StockInTaskOrder> implements IStockInTaskOrderService{
/**
* 与收货侧同步写 remark 的约定前缀 StockReceiptOrderDomainService用于 PDA/PC 收货后回写 task_receipt_material_detail
*/
public static final String TASK_RECEIPT_REMARK_RUID_PREFIX = "__RUID__:";
@Autowired
private StockInTaskOrderMapper stockInTaskOrderMapper;
@Autowired
@@ -99,6 +105,7 @@ public class StockInTaskOrderImpl extends ServiceImpl<StockInTaskOrderMapper, St
taskReceiptMaterialDetailDO.setOrganizationName(loginUser.getUserPo().getOrganizationName());
taskReceiptMaterialDetailDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
taskReceiptMaterialDetailDO.setTaskNumber(stockInTaskOrderDO.getTaskNumber());
Long receiptLineUidForTaskRemark = taskReceiptMaterialDetailDO.getUniqueId();
taskReceiptMaterialDetailDO.setUniqueId(idGenerator.snowflakeId(SnowFlakeConstants.wmsId));
taskReceiptMaterialDetailDO.setCreateBy(loginUser.getUserid());
taskReceiptMaterialDetailDO.setCreateByName(loginUser.getUsername());
@@ -106,6 +113,7 @@ public class StockInTaskOrderImpl extends ServiceImpl<StockInTaskOrderMapper, St
TaskReceiptMaterialDetail taskReceiptMaterialDetail = new TaskReceiptMaterialDetail();
BeanUtils.copyProperties(taskReceiptMaterialDetailDO, taskReceiptMaterialDetail, "materialDetailId","createBy","createByName","createTime",
"updateBy","updateByName","updateTime");
mergeReceiptLineUniqueIdIntoTaskRemark(taskReceiptMaterialDetail, receiptLineUidForTaskRemark);
taskReceiptMaterialDetailList.add(taskReceiptMaterialDetail);
List<TaskReceiptMaterialDetailDO> taskReceiptMaterialDetailDOList = taskReceiptMaterialDetailDO.getChildren();
if (taskReceiptMaterialDetailDOList != null){
@@ -114,6 +122,7 @@ public class StockInTaskOrderImpl extends ServiceImpl<StockInTaskOrderMapper, St
materialDetailChildDO.setOrganizationName(loginUser.getUserPo().getOrganizationName());
materialDetailChildDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
materialDetailChildDO.setTaskNumber(stockInTaskOrderDO.getTaskNumber());
Long childReceiptLineUid = materialDetailChildDO.getUniqueId();
materialDetailChildDO.setUniqueId(idGenerator.snowflakeId(SnowFlakeConstants.wmsId));
materialDetailChildDO.setParentUniqueId(taskReceiptMaterialDetail.getUniqueId());
materialDetailChildDO.setCreateBy(loginUser.getUserid());
@@ -122,6 +131,7 @@ public class StockInTaskOrderImpl extends ServiceImpl<StockInTaskOrderMapper, St
TaskReceiptMaterialDetail taskReceiptMaterialDetailChildren = new TaskReceiptMaterialDetail();
BeanUtils.copyProperties(materialDetailChildDO, taskReceiptMaterialDetailChildren, "materialDetailId","createBy","createByName","createTime",
"updateBy","updateByName","updateTime");
mergeReceiptLineUniqueIdIntoTaskRemark(taskReceiptMaterialDetailChildren, childReceiptLineUid);
taskReceiptMaterialDetailList.add(taskReceiptMaterialDetailChildren);
//序列号
materialDetailSerialNumberList.addAll(genMaterialDetailSerialNumberByReceipt(taskReceiptMaterialDetailDO));
@@ -142,6 +152,38 @@ public class StockInTaskOrderImpl extends ServiceImpl<StockInTaskOrderMapper, St
return saveBatch(stockInTaskOrderList);
}
/**
* 在作业单明细 remark 中保留收货行 business uniqueId便于收货保存后按行回写 receipt_quantity 作业单行 unique_id 与收货行不同
*/
private static void mergeReceiptLineUniqueIdIntoTaskRemark(TaskReceiptMaterialDetail taskRow, Long receiptLineUniqueId) {
if (receiptLineUniqueId == null) {
return;
}
String link = TASK_RECEIPT_REMARK_RUID_PREFIX + receiptLineUniqueId;
String r = taskRow.getRemark();
if (StringUtils.isNotBlank(r) && !r.contains(link)) {
taskRow.setRemark(r + "|" + link);
} else if (StringUtils.isBlank(r)) {
taskRow.setRemark(link);
}
}
/**
* 上架作业单明细 remark 中保留 shelf_material_detail 业务行 uniqueId便于 PDA/PC 上架提交后回写 {@code shelves_quantity} 与收货侧 {@link #mergeReceiptLineUniqueIdIntoTaskRemark} 同前缀
*/
private static void mergeShelfLineUniqueIdIntoTaskRemark(TaskShelfMaterialDetail taskRow, Long shelfLineUniqueId) {
if (shelfLineUniqueId == null) {
return;
}
String link = TASK_RECEIPT_REMARK_RUID_PREFIX + shelfLineUniqueId;
String r = taskRow.getRemark();
if (StringUtils.isNotBlank(r) && !r.contains(link)) {
taskRow.setRemark(r + "|" + link);
} else if (StringUtils.isBlank(r)) {
taskRow.setRemark(link);
}
}
/**
* @description 生成上架作业单
* @author ZhouGY
@@ -161,6 +203,7 @@ public class StockInTaskOrderImpl extends ServiceImpl<StockInTaskOrderMapper, St
BeanUtils.copyProperties(stockInTaskOrderDO, stockInTaskOrder);
stockInTaskOrderList.add(stockInTaskOrder);
stockInTaskOrderDO.getTaskShelfMaterialDetailList().forEach(taskShelfMaterialDetailDO -> {
Long shelfLineBizUid = taskShelfMaterialDetailDO.getUniqueId();
TaskShelfMaterialDetail taskShelfMaterialDetail = new TaskShelfMaterialDetail();
BeanUtils.copyProperties(taskShelfMaterialDetailDO, taskShelfMaterialDetail, "materialDetailId","createBy","createByName","createTime",
"updateBy","updateByName","updateTime");
@@ -168,28 +211,33 @@ public class StockInTaskOrderImpl extends ServiceImpl<StockInTaskOrderMapper, St
taskShelfMaterialDetail.setOrganizationName(loginUser.getUserPo().getOrganizationName());
taskShelfMaterialDetail.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
taskShelfMaterialDetail.setTaskNumber(stockInTaskOrderDO.getTaskNumber());
mergeShelfLineUniqueIdIntoTaskRemark(taskShelfMaterialDetail, shelfLineBizUid);
taskShelfMaterialDetail.setUniqueId(idGenerator.snowflakeId(SnowFlakeConstants.wmsId));
taskShelfMaterialDetail.setCreateBy(loginUser.getUserid());
taskShelfMaterialDetail.setCreateByName(loginUser.getUsername());
taskShelfMaterialDetail.setCreateTime(new Date());
taskShelfMaterialDetailList.add(taskShelfMaterialDetail);
taskShelfMaterialDetailDO.getChildren().forEach(taskShelfMaterialDetailDOChildren -> {
TaskShelfMaterialDetail taskShelfMaterialDetailChildren = new TaskShelfMaterialDetail();
BeanUtils.copyProperties(taskShelfMaterialDetailDOChildren, taskShelfMaterialDetailChildren, "materialDetailId","createBy","createByName","createTime",
if (taskShelfMaterialDetailDO.getChildren() != null) {
taskShelfMaterialDetailDO.getChildren().forEach(taskShelfMaterialDetailDOChildren -> {
Long childShelfLineBizUid = taskShelfMaterialDetailDOChildren.getUniqueId();
TaskShelfMaterialDetail taskShelfMaterialDetailChildren = new TaskShelfMaterialDetail();
BeanUtils.copyProperties(taskShelfMaterialDetailDOChildren, taskShelfMaterialDetailChildren, "materialDetailId","createBy","createByName","createTime",
"updateBy","updateByName","updateTime");
taskShelfMaterialDetailChildren.setOrganizationId(loginUser.getUserPo().getOrganizationId());
taskShelfMaterialDetailChildren.setOrganizationName(loginUser.getUserPo().getOrganizationName());
taskShelfMaterialDetailChildren.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
taskShelfMaterialDetailChildren.setTaskNumber(stockInTaskOrderDO.getTaskNumber());
taskShelfMaterialDetailChildren.setUniqueId(idGenerator.snowflakeId(SnowFlakeConstants.wmsId));
taskShelfMaterialDetailChildren.setParentUniqueId(taskShelfMaterialDetail.getUniqueId());
taskShelfMaterialDetailChildren.setCreateBy(loginUser.getUserid());
taskShelfMaterialDetailChildren.setCreateByName(loginUser.getUsername());
taskShelfMaterialDetailChildren.setCreateTime(new Date());
taskShelfMaterialDetailList.add(taskShelfMaterialDetailChildren);
//序列号
materialDetailSerialNumberList.addAll(genMaterialDetailSerialNumberByShelf(taskShelfMaterialDetailDOChildren));
});
taskShelfMaterialDetailChildren.setOrganizationId(loginUser.getUserPo().getOrganizationId());
taskShelfMaterialDetailChildren.setOrganizationName(loginUser.getUserPo().getOrganizationName());
taskShelfMaterialDetailChildren.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
taskShelfMaterialDetailChildren.setTaskNumber(stockInTaskOrderDO.getTaskNumber());
mergeShelfLineUniqueIdIntoTaskRemark(taskShelfMaterialDetailChildren, childShelfLineBizUid);
taskShelfMaterialDetailChildren.setUniqueId(idGenerator.snowflakeId(SnowFlakeConstants.wmsId));
taskShelfMaterialDetailChildren.setParentUniqueId(taskShelfMaterialDetail.getUniqueId());
taskShelfMaterialDetailChildren.setCreateBy(loginUser.getUserid());
taskShelfMaterialDetailChildren.setCreateByName(loginUser.getUsername());
taskShelfMaterialDetailChildren.setCreateTime(new Date());
taskShelfMaterialDetailList.add(taskShelfMaterialDetailChildren);
//序列号
materialDetailSerialNumberList.addAll(genMaterialDetailSerialNumberByShelf(taskShelfMaterialDetailDOChildren));
});
}
//序列号
materialDetailSerialNumberList.addAll(genMaterialDetailSerialNumberByShelf(taskShelfMaterialDetailDO));
});
@@ -98,7 +98,7 @@ public class StockInTaskOrderPO extends BaseVOEntity {
private String operatorsName;
@ApiModelProperty("作业完成时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "作业完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date operatorsEndTime;
@@ -83,18 +83,20 @@ public class StockInTaskOrderDomainService {
if (stockInTaskOrderPO == null) {
return null;
}
if (Integer.valueOf(1).equals(stockInTaskOrderPO.getType())){
int taskType = resolveStockInTaskOrderType(stockInTaskOrderPO);
if (taskType == 1) {
// 收货作业优先按收货单号查询查不到再回退作业单号
List<TaskReceiptMaterialDetailPO> receiptDetails = getReceiptInfo(stockInTaskOrderPO.getReceiptOrderNumber());
if (CollectionUtils.isEmpty(receiptDetails)) {
receiptDetails = getReceiptInfo(stockInTaskOrderPO.getTaskNumber());
}
stockInTaskOrderPO.setTaskReceiptMaterialDetailList(receiptDetails);
} else if (Integer.valueOf(2).equals(stockInTaskOrderPO.getType())) {
// 上架作业优先按上架单号查询查不到再回退作业单号
List<TaskShelfMaterialDetailPO> shelfDetails = getShelfInfo(stockInTaskOrderPO.getShelfOrderNumber());
} else if (taskType == 2) {
// 上架作业task_shelf_material_detail.task_number 存的是作业单号 SHZY... genStockShelfTaskOrder
// 与上架单号 SJ 不一致须优先用作业单号再按上架单号兜底历史/异常数据
List<TaskShelfMaterialDetailPO> shelfDetails = getShelfInfo(stockInTaskOrderPO.getTaskNumber());
if (CollectionUtils.isEmpty(shelfDetails)) {
shelfDetails = getShelfInfo(stockInTaskOrderPO.getTaskNumber());
shelfDetails = getShelfInfo(stockInTaskOrderPO.getShelfOrderNumber());
}
stockInTaskOrderPO.setTaskShelfMaterialDetailList(shelfDetails);
} else {
@@ -104,15 +106,25 @@ public class StockInTaskOrderDomainService {
receiptDetails = getReceiptInfo(stockInTaskOrderPO.getTaskNumber());
}
stockInTaskOrderPO.setTaskReceiptMaterialDetailList(receiptDetails);
List<TaskShelfMaterialDetailPO> shelfDetails = getShelfInfo(stockInTaskOrderPO.getShelfOrderNumber());
List<TaskShelfMaterialDetailPO> shelfDetails = getShelfInfo(stockInTaskOrderPO.getTaskNumber());
if (CollectionUtils.isEmpty(shelfDetails)) {
shelfDetails = getShelfInfo(stockInTaskOrderPO.getTaskNumber());
shelfDetails = getShelfInfo(stockInTaskOrderPO.getShelfOrderNumber());
}
stockInTaskOrderPO.setTaskShelfMaterialDetailList(shelfDetails);
}
return stockInTaskOrderPO;
}
/** 兼容 Integer/Long/Byte 等 JDBC 映射,避免 2L 与 Integer(2) equals 为 false 导致走错分支。 */
private static int resolveStockInTaskOrderType(StockInTaskOrderPO po) {
if (po == null || po.getType() == null) {
return 0;
}
if (po.getType() instanceof Number) {
return ((Number) po.getType()).intValue();
}
return 0;
}
/**
* 获取入库收货作业单详细信息
@@ -143,7 +143,7 @@ public class StockOutTaskOrderPO extends BaseVOEntity {
private String operatorsName;
@ApiModelProperty("作业完成时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "作业完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date operatorsEndTime;
@@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.mhd.common.core.constant.SnowFlakeConstants;
@@ -40,6 +41,7 @@ import com.mhd.wms.domain.inventoryStandingReport.repository.facade.IInventorySt
import com.mhd.wms.domain.inventoryStandingReport.repository.todo.InventoryStandingReportDO;
import com.mhd.wms.domain.materialGoodsRule.entity.MaterialGoodsRule;
import com.mhd.wms.domain.materialGoodsRule.repository.facade.IMaterialGoodsRuleService;
import com.mhd.wms.domain.materialGoodsRule.repository.po.MaterialGoodsRulePO;
import com.mhd.wms.domain.materialMoreDetail.repository.facade.IMaterialMoreDetailService;
import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO;
import com.mhd.wms.domain.materialMoreDetail.repository.todo.MaterialMoreDetailDO;
@@ -68,6 +70,8 @@ import com.mhd.wms.domain.stockShelfOrder.repository.facade.IStockShelfOrderServ
import com.mhd.wms.domain.stockShelfOrder.repository.po.StockShelfOrderPO;
import com.mhd.wms.domain.stockShelfOrder.repository.todo.StockShelfOrderDO;
import com.mhd.wms.domain.stockShelfOrder.service.StockShelfOrderDomainService;
import com.mhd.wms.domain.taskReceiptMaterialDetail.entity.TaskReceiptMaterialDetail;
import com.mhd.wms.domain.taskReceiptMaterialDetail.repository.facade.ITaskReceiptMaterialDetailService;
import com.mhd.wms.domain.taskReceiptMaterialDetail.repository.todo.TaskReceiptMaterialDetailDO;
import com.mhd.wms.interfaces.dto.stockReceiptOrder.StockReceiptOrderDTO;
import io.swagger.annotations.ApiModelProperty;
@@ -80,6 +84,7 @@ import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
@@ -92,6 +97,9 @@ import java.util.stream.Collectors;
@Slf4j
public class StockReceiptOrderDomainService {
/** 与 {@link com.mhd.wms.domain.stockInTaskOrder.repository.persistence.StockInTaskOrderImpl#TASK_RECEIPT_REMARK_RUID_PREFIX} 一致,用于在作业单 remark 中关联收货行 uniqueId。 */
private static final String TASK_RECEIPT_REMARK_RUID_PREFIX = "__RUID__:";
@Autowired
private IStockReceiptOrderService stockReceiptOrderService;
@Autowired
@@ -99,6 +107,8 @@ public class StockReceiptOrderDomainService {
@Autowired
private IStockInTaskOrderService stockInTaskOrderService;
@Autowired
private ITaskReceiptMaterialDetailService taskReceiptMaterialDetailService;
@Autowired
private IInOrderAbnormalService iInOrderAbnormalService;
@Autowired
private StockShelfOrderDomainService stockShelfOrderDomainService;
@@ -297,6 +307,11 @@ public class StockReceiptOrderDomainService {
if (materialBaseInfoId == null) {
return materialMoreDetailPOList;
}
// queryListChildren buildMaterialMoreDetailListByMaterialBinding 一致无商品规则或未绑 batch_id 不调 System
MaterialGoodsRulePO goodsRule = materialGoodsRuleService.getInfoByMaterialBaseInfoIds(materialBaseInfoId);
if (goodsRule == null || goodsRule.getBatchId() == null) {
return materialMoreDetailPOList;
}
try {
AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId);
if (ajaxResult == null || !"200".equals(String.valueOf(ajaxResult.get("code")))) {
@@ -445,6 +460,8 @@ public class StockReceiptOrderDomainService {
genInventoryStandingReport(stockReceiptOrderPO, stockReceiptOrderDO);
//修改物料明细信息
receiptMaterialDetailService.batchReceiptUpdate(stockReceiptOrderDO);
// 与收货单明细一致同步更新已下发的收货入库作业单 task_receipt_material_detailPDA/PC 每次提交收货均刷新
syncTaskReceiptMaterialDetailsWithReceiptLines(stockReceiptOrderDO);
// 同步更新入库单明细的收货数量入库单 totalNetWeight/totalGrossWeight/totalVolume/totalArea 不因收货改库 sync 内注释
syncUpdateInMaterialDetailFromReceipt(stockReceiptOrderDO, stockReceiptOrderPO);
// 收货类入库作业单在任务下发时生成此处不再生成 type=1 作业单
@@ -459,6 +476,160 @@ public class StockReceiptOrderDomainService {
}
/**
* 收货保存后将收货单明细中的实收数量/状态同步到已生成的收货类入库作业单明细task_receipt_material_detail
* 关联键生成作业单时在 {@link com.mhd.wms.domain.stockInTaskOrder.repository.persistence.StockInTaskOrderImpl#genStockReceiptTaskOrder}
* 写入 remark {@value #TASK_RECEIPT_REMARK_RUID_PREFIX} + 收货行 business uniqueId
*/
private void syncTaskReceiptMaterialDetailsWithReceiptLines(StockReceiptOrderDO stockReceiptOrderDO) {
if (stockReceiptOrderDO == null || CollectionUtils.isEmpty(stockReceiptOrderDO.getMaterialDetailList())) {
return;
}
String receiptOrderNumber = stockReceiptOrderDO.getReceiptOrderNumber();
if (StringUtils.isBlank(receiptOrderNumber)) {
ReceiptMaterialDetailDO head = stockReceiptOrderDO.getMaterialDetailList().get(0);
if (head != null) {
receiptOrderNumber = head.getReceiptOrderNumber();
}
}
if (StringUtils.isBlank(receiptOrderNumber)) {
return;
}
String taskNumber = resolveReceiptTypeTaskNumber(receiptOrderNumber);
if (StringUtils.isBlank(taskNumber)) {
return;
}
List<TaskReceiptMaterialDetail> taskRows = taskReceiptMaterialDetailService.list(
new LambdaQueryWrapper<TaskReceiptMaterialDetail>()
.eq(TaskReceiptMaterialDetail::getTaskNumber, taskNumber)
.eq(TaskReceiptMaterialDetail::getDelFlag, 1));
if (CollectionUtils.isEmpty(taskRows)) {
return;
}
Map<Long, TaskReceiptMaterialDetail> taskByReceiptLineUid = new HashMap<>();
for (TaskReceiptMaterialDetail tr : taskRows) {
Long uid = extractReceiptLineUniqueIdFromTaskRemark(tr.getRemark());
if (uid != null && !taskByReceiptLineUid.containsKey(uid)) {
taskByReceiptLineUid.put(uid, tr);
}
}
LoginUser loginUser = SecurityUtils.getLoginUser();
Date now = new Date();
String userRealName = resolveUserRealNameForTaskSync(loginUser);
applyReceiptLineToTaskDetails(
stockReceiptOrderDO.getMaterialDetailList(), taskRows, taskByReceiptLineUid, loginUser, userRealName, now);
}
private static String resolveUserRealNameForTaskSync(LoginUser loginUser) {
if (loginUser == null) {
return null;
}
if (loginUser.getUserPo() != null && StringUtils.isNotBlank(loginUser.getUserPo().getUserName())) {
return loginUser.getUserPo().getUserName().trim();
}
if (StringUtils.isNotBlank(loginUser.getRealname())) {
return loginUser.getRealname().trim();
}
return loginUser.getUsername();
}
/**
* 本单收货类入库作业单type=1作业单号无则未下发或已删
*/
private String resolveReceiptTypeTaskNumber(String receiptOrderNumber) {
if (StringUtils.isBlank(receiptOrderNumber)) {
return null;
}
List<StockInTaskOrder> rows = stockInTaskOrderService.list(
new LambdaQueryWrapper<StockInTaskOrder>()
.eq(StockInTaskOrder::getReceiptOrderNumber, receiptOrderNumber)
.eq(StockInTaskOrder::getType, 1)
.eq(StockInTaskOrder::getDelFlag, 1)
.orderByDesc(StockInTaskOrder::getInTaskOrderId)
.last("LIMIT 1"));
if (CollectionUtils.isEmpty(rows)) {
return null;
}
return rows.get(0).getTaskNumber();
}
private void applyReceiptLineToTaskDetails(List<ReceiptMaterialDetailDO> lines,
List<TaskReceiptMaterialDetail> allTaskRows,
Map<Long, TaskReceiptMaterialDetail> taskByReceiptLineUid,
LoginUser loginUser, String userRealName, Date now) {
if (CollectionUtils.isEmpty(lines)) {
return;
}
for (ReceiptMaterialDetailDO line : lines) {
if (line == null) {
continue;
}
if (line.getUniqueId() != null) {
TaskReceiptMaterialDetail tr = taskByReceiptLineUid.get(line.getUniqueId());
if (tr == null && allTaskRows != null) {
long uid = line.getUniqueId();
for (TaskReceiptMaterialDetail row : allTaskRows) {
if (row != null && remarkContainsRuidToken(row.getRemark(), uid)) {
tr = row;
break;
}
}
}
if (tr != null && tr.getMaterialDetailId() != null) {
BigDecimal syncQty = line.getAlreadyReceiptQuantity() != null
? line.getAlreadyReceiptQuantity()
: line.getReceiptQuantity();
TaskReceiptMaterialDetail patch = new TaskReceiptMaterialDetail();
patch.setMaterialDetailId(tr.getMaterialDetailId());
patch.setReceiptQuantity(syncQty);
patch.setReceiptStatus(line.getReceiptStatus());
if (loginUser != null) {
patch.setUpdateBy(loginUser.getUserid());
}
patch.setUpdateByName(userRealName);
patch.setUpdateTime(now);
taskReceiptMaterialDetailService.updateById(patch);
}
}
if (!CollectionUtils.isEmpty(line.getChildren())) {
applyReceiptLineToTaskDetails(line.getChildren(), allTaskRows, taskByReceiptLineUid, loginUser, userRealName, now);
}
}
}
private static boolean remarkContainsRuidToken(String remark, long uid) {
if (remark == null) {
return false;
}
return Pattern.compile(TASK_RECEIPT_REMARK_RUID_PREFIX + uid + "(?!\\d)").matcher(remark).find();
}
/**
* 从作业单 remark 中解析首个__RUID__:数字对应的收货行 business id receipt_material_detail.unique_id 一致
*/
private static Long extractReceiptLineUniqueIdFromTaskRemark(String remark) {
if (StringUtils.isBlank(remark)) {
return null;
}
int i = remark.indexOf(TASK_RECEIPT_REMARK_RUID_PREFIX);
if (i < 0) {
return null;
}
int j = i + TASK_RECEIPT_REMARK_RUID_PREFIX.length();
int k = j;
while (k < remark.length() && Character.isDigit(remark.charAt(k))) {
k++;
}
if (k == j) {
return null;
}
try {
return Long.parseLong(remark.substring(j, k));
} catch (NumberFormatException e) {
return null;
}
}
private void saveAmount(StockReceiptOrderDO stockReceiptOrderDO) {
Long receiptOrderId = stockReceiptOrderDO.getReceiptOrderId();
receiptOrderAccountService.remove(new QueryWrapper<ReceiptOrderAccount>().lambda().eq(ReceiptOrderAccount::getOrderId, receiptOrderId));
@@ -70,11 +70,14 @@ import com.mhd.wms.domain.stockInOrder.entity.StockInOrder;
import com.mhd.wms.domain.stockInOrder.repository.facade.IStockInOrderService;
import com.mhd.wms.domain.stockInTaskOrder.entity.StockInTaskOrder;
import com.mhd.wms.domain.stockInTaskOrder.repository.facade.IStockInTaskOrderService;
import com.mhd.wms.domain.stockInTaskOrder.repository.persistence.StockInTaskOrderImpl;
import com.mhd.wms.domain.stockInTaskOrder.repository.todo.StockInTaskOrderDO;
import com.mhd.wms.domain.stockShelfOrder.entity.StockShelfOrder;
import com.mhd.wms.domain.stockShelfOrder.repository.facade.IStockShelfOrderService;
import com.mhd.wms.domain.stockShelfOrder.repository.po.StockShelfOrderPO;
import com.mhd.wms.domain.stockShelfOrder.repository.todo.StockShelfOrderDO;
import com.mhd.wms.domain.taskShelfMaterialDetail.entity.TaskShelfMaterialDetail;
import com.mhd.wms.domain.taskShelfMaterialDetail.repository.facade.ITaskShelfMaterialDetailService;
import com.mhd.wms.domain.taskShelfMaterialDetail.repository.todo.TaskShelfMaterialDetailDO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -85,6 +88,7 @@ import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
@@ -116,6 +120,8 @@ public class StockShelfOrderDomainService {
@Autowired
private IStockInTaskOrderService stockInTaskOrderService;
@Autowired
private ITaskShelfMaterialDetailService taskShelfMaterialDetailService;
@Autowired
private IInventoryStandingDetailService inventoryStandingDetailService;
@Autowired
private IDeliveTaskService deliveTaskService;
@@ -359,6 +365,8 @@ public class StockShelfOrderDomainService {
userRealNameUpShelf);
//同步更新入库单明细的上架数量/上架状态
syncShelvesQuantityToInMaterialDetail(stockShelfOrderDO);
// 同步已下发的上架入库作业单明细 task_shelf_material_detail与收货侧回写 task_receipt 一致
syncTaskShelfMaterialDetailsWithShelfLines(stockShelfOrderDO);
// 上架类入库作业单 type=2PDA 已在收货完成时生成若尚未生成 PC 路径则在本环节补生成
if (countShelfTypeInTaskOrder(stockShelfOrderPO.getShelfOrderNumber()) == 0) {
genStockShelfTaskOrderByUpShelf(stockShelfOrderDO);
@@ -572,7 +580,154 @@ public class StockShelfOrderDomainService {
log.info("完成同步更新入库单【{}】的明细", inOrderNumber);
}
/**
* 上架每次提交/完成时 shelf_material_detail 的累计上架数量上架状态写回已下发的 type=2 作业单明细 task_shelf_material_detail
* 行关联{@link StockInTaskOrderImpl#genStockShelfTaskOrder} remark 中写入 <code>__RUID__:</code>+上架行 business uniqueId remark 的旧数据按 in_unique_id+receipt_unique_id+level+物料 匹配
*/
private void syncTaskShelfMaterialDetailsWithShelfLines(StockShelfOrderDO stockShelfOrderDO) {
if (stockShelfOrderDO == null || StringUtils.isBlank(stockShelfOrderDO.getShelfOrderNumber())) {
return;
}
String taskNumber = resolveShelfTypeTaskNumberByShelfOrderNumber(stockShelfOrderDO.getShelfOrderNumber());
if (StringUtils.isBlank(taskNumber)) {
return;
}
List<TaskShelfMaterialDetail> taskRows = taskShelfMaterialDetailService.list(
new LambdaQueryWrapper<TaskShelfMaterialDetail>()
.eq(TaskShelfMaterialDetail::getTaskNumber, taskNumber)
.eq(TaskShelfMaterialDetail::getDelFlag, 1));
if (CollectionUtils.isEmpty(taskRows)) {
return;
}
Map<Long, TaskShelfMaterialDetail> taskByShelfLineUid = new HashMap<>();
for (TaskShelfMaterialDetail tr : taskRows) {
Long uid = extractShelfLineUniqueIdFromTaskRemark(tr.getRemark());
if (uid != null && !taskByShelfLineUid.containsKey(uid)) {
taskByShelfLineUid.put(uid, tr);
}
}
ShelfMaterialDetailDO smq = new ShelfMaterialDetailDO();
smq.setShelfOrderNumber(stockShelfOrderDO.getShelfOrderNumber());
List<ShelfMaterialDetailPO> shelfLines = shelfMaterialDetailService.queryList(smq);
if (CollectionUtils.isEmpty(shelfLines)) {
return;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
Date now = new Date();
String userRealName = resolveUserRealNameForShelf(loginUser);
for (ShelfMaterialDetailPO line : shelfLines) {
if (line == null) {
continue;
}
TaskShelfMaterialDetail tr = null;
if (line.getUniqueId() != null) {
tr = taskByShelfLineUid.get(line.getUniqueId());
if (tr == null) {
long uid = line.getUniqueId();
for (TaskShelfMaterialDetail row : taskRows) {
if (row != null && remarkContainsShelfRuidToken(row.getRemark(), uid)) {
tr = row;
break;
}
}
}
}
if (tr == null) {
tr = findTaskShelfMaterialDetailByFallback(taskRows, line);
}
if (tr == null || tr.getMaterialDetailId() == null) {
continue;
}
BigDecimal syncQty = line.getAlreadyShelvesQuantity() != null
? line.getAlreadyShelvesQuantity()
: line.getShelvesQuantity();
TaskShelfMaterialDetail patch = new TaskShelfMaterialDetail();
patch.setMaterialDetailId(tr.getMaterialDetailId());
patch.setShelvesQuantity(syncQty);
patch.setShelvesStatus(line.getShelvesStatus());
if (loginUser != null) {
patch.setUpdateBy(loginUser.getUserid());
}
patch.setUpdateByName(userRealName);
patch.setUpdateTime(now);
taskShelfMaterialDetailService.updateById(patch);
}
}
private String resolveShelfTypeTaskNumberByShelfOrderNumber(String shelfOrderNumber) {
if (StringUtils.isBlank(shelfOrderNumber)) {
return null;
}
List<StockInTaskOrder> rows = stockInTaskOrderService.list(
new LambdaQueryWrapper<StockInTaskOrder>()
.eq(StockInTaskOrder::getShelfOrderNumber, shelfOrderNumber)
.eq(StockInTaskOrder::getType, 2)
.eq(StockInTaskOrder::getDelFlag, 1)
.orderByDesc(StockInTaskOrder::getInTaskOrderId)
.last("LIMIT 1"));
if (CollectionUtils.isEmpty(rows)) {
return null;
}
return rows.get(0).getTaskNumber();
}
private static Long extractShelfLineUniqueIdFromTaskRemark(String remark) {
if (StringUtils.isBlank(remark)) {
return null;
}
int i = remark.indexOf(StockInTaskOrderImpl.TASK_RECEIPT_REMARK_RUID_PREFIX);
if (i < 0) {
return null;
}
int j = i + StockInTaskOrderImpl.TASK_RECEIPT_REMARK_RUID_PREFIX.length();
int k = j;
while (k < remark.length() && Character.isDigit(remark.charAt(k))) {
k++;
}
if (k == j) {
return null;
}
try {
return Long.parseLong(remark.substring(j, k));
} catch (NumberFormatException e) {
return null;
}
}
private static boolean remarkContainsShelfRuidToken(String remark, long uid) {
if (remark == null) {
return false;
}
return Pattern.compile(StockInTaskOrderImpl.TASK_RECEIPT_REMARK_RUID_PREFIX + uid + "(?!\\d)").matcher(remark).find();
}
private static TaskShelfMaterialDetail findTaskShelfMaterialDetailByFallback(
List<TaskShelfMaterialDetail> all, ShelfMaterialDetailPO line) {
if (CollectionUtils.isEmpty(all) || line == null) {
return null;
}
for (TaskShelfMaterialDetail tr : all) {
if (tr == null) {
continue;
}
if (!Objects.equals(tr.getInUniqueId(), line.getInUniqueId())) {
continue;
}
if (!Objects.equals(tr.getReceiptUniqueId(), line.getReceiptUniqueId())) {
continue;
}
if (!Objects.equals(tr.getLevel(), line.getLevel())) {
continue;
}
if (line.getMaterialBaseInfoId() != null && tr.getMaterialBaseInfoId() != null
&& !Objects.equals(tr.getMaterialBaseInfoId(), line.getMaterialBaseInfoId())) {
continue;
}
return tr;
}
return null;
}
/**
* @description 设置上架单上架需要更新的数据数据
@@ -700,6 +855,9 @@ public class StockShelfOrderDomainService {
}
String userRealNameComplete = resolveUserRealNameForShelf(loginUser);
updateShelfMaterialDetailShelvesStatusWhenOrderCompleted(stockShelfOrderPO, loginUser, userRealNameComplete);
StockShelfOrderDO taskDetailSync = new StockShelfOrderDO();
taskDetailSync.setShelfOrderNumber(stockShelfOrderPO.getShelfOrderNumber());
syncTaskShelfMaterialDetailsWithShelfLines(taskDetailSync);
markShelfTypeStockInTaskOrderOnComplete(stockShelfOrderPO.getShelfOrderNumber(), loginUser, userRealNameComplete);
//推送业务数据到BMS系统
// pushSyncBmsDomainService.pushInShelfOrder(stockShelfOrderPO.getInOrderNumber());
@@ -708,6 +866,27 @@ public class StockShelfOrderDomainService {
return true;
}
/**
* 上架单整单完成时回写上架类入库作业单type=2的作业人作业完成时间
* {@link com.mhd.wms.domain.stockReceiptOrder.service.StockReceiptOrderDomainService#markReceiptTypeStockInTaskOrderOnComplete} 对收货类作业单一致
*/
private void markShelfTypeStockInTaskOrderOnComplete(String shelfOrderNumber, LoginUser loginUser, String userRealName) {
if (StringUtils.isBlank(shelfOrderNumber) || loginUser == null) {
return;
}
Date now = new Date();
stockInTaskOrderService.update(null, new UpdateWrapper<StockInTaskOrder>().lambda()
.set(StockInTaskOrder::getOperatorsBy, loginUser.getUserid())
.set(StockInTaskOrder::getOperatorsName, userRealName)
.set(StockInTaskOrder::getOperatorsEndTime, now)
.set(StockInTaskOrder::getUpdateBy, loginUser.getUserid())
.set(StockInTaskOrder::getUpdateByName, userRealName)
.set(StockInTaskOrder::getUpdateTime, now)
.eq(StockInTaskOrder::getShelfOrderNumber, shelfOrderNumber)
.eq(StockInTaskOrder::getType, 2)
.eq(StockInTaskOrder::getDelFlag, 1));
}
/**
* 分批/单次上架提交后按主行+子行汇总累计已上架与主行计划量比较刷新各明细 shelves_status待上 1 / 上中 2 / 3 / 5
*/
@@ -920,26 +1099,6 @@ public class StockShelfOrderDomainService {
return loginUser.getUsername() != null ? loginUser.getUsername() : "";
}
/**
* 上架实际完成时回写上架类入库作业单type=2的作业人作业完成时间下发/生成时不下发填写
*/
private void markShelfTypeStockInTaskOrderOnComplete(String shelfOrderNumber, LoginUser loginUser, String userRealName) {
if (StringUtils.isBlank(shelfOrderNumber) || loginUser == null) {
return;
}
Date now = new Date();
stockInTaskOrderService.update(null, new UpdateWrapper<StockInTaskOrder>().lambda()
.set(StockInTaskOrder::getOperatorsBy, loginUser.getUserid())
.set(StockInTaskOrder::getOperatorsName, userRealName)
.set(StockInTaskOrder::getOperatorsEndTime, now)
.set(StockInTaskOrder::getUpdateBy, loginUser.getUserid())
.set(StockInTaskOrder::getUpdateByName, userRealName)
.set(StockInTaskOrder::getUpdateTime, now)
.eq(StockInTaskOrder::getShelfOrderNumber, shelfOrderNumber)
.eq(StockInTaskOrder::getType, 2)
.eq(StockInTaskOrder::getDelFlag, 1));
}
private synchronized void stockIn(List<ShelfMaterialDetail> shelfMaterialDetailDOList, StockShelfOrderDO stockReceiptOrderDO) {
for (ShelfMaterialDetail shelfMaterialDetail : shelfMaterialDetailDOList) {
Long materialBaseInfoId = shelfMaterialDetail.getMaterialBaseInfoId();
@@ -1460,102 +1619,73 @@ public class StockShelfOrderDomainService {
stockInTaskOrderDO.setSerialNumber(OrderSequence.getOrderCode("SHZYLS"));
stockInTaskOrderDO.setTaskNumber(OrderSequence.getOrderCode("SHZY"));
stockInTaskOrderDO.setType(2);//上架
stockInTaskOrderDO.setOperatorsBy(null);
stockInTaskOrderDO.setOperatorsName(null);
stockInTaskOrderDO.setOperatorsEndTime(null);
// 作业单作业数量对应 stock_in_task_order.actual_quantity上架单汇总在 receipt_quantity字段名不一致不会从 copyProperties 带入需按实际收货量赋值
BigDecimal workQty = stockInTaskOrderDO.getActualQuantity();
if (workQty == null || workQty.compareTo(BigDecimal.ZERO) == 0) {
workQty = stockShelfOrderDO.getReceiptQuantity();
}
if ((workQty == null || workQty.compareTo(BigDecimal.ZERO) == 0)
&& !CollectionUtils.isEmpty(stockShelfOrderDO.getMaterialDetailList())) {
workQty = sumShelfMaterialDetailQuantities(stockShelfOrderDO.getMaterialDetailList());
}
stockInTaskOrderDO.setActualQuantity(workQty != null ? workQty : BigDecimal.ZERO);
List<TaskShelfMaterialDetailDO> taskReceiptMaterialDetailDOList = stockShelfOrderDO.getMaterialDetailList().stream()
.map(shelfMaterialDetailDO -> JSONUtil.toBean(JSONUtil.toJsonStr(shelfMaterialDetailDO), TaskShelfMaterialDetailDO.class))
.collect(Collectors.toList());
for (TaskShelfMaterialDetailDO d : taskReceiptMaterialDetailDOList) {
if (d.getChildren() == null) {
d.setChildren(new ArrayList<>());
}
}
stockInTaskOrderDO.setTaskShelfMaterialDetailList(taskReceiptMaterialDetailDOList);
return stockInTaskOrderService.genStockShelfTaskOrder(Collections.singletonList(stockInTaskOrderDO));
}
/** 汇总上架明细计划数量(与收货实际量一致),含子行树 */
private static BigDecimal sumShelfMaterialDetailQuantities(List<ShelfMaterialDetailDO> lines) {
if (CollectionUtils.isEmpty(lines)) {
return BigDecimal.ZERO;
}
BigDecimal sum = BigDecimal.ZERO;
for (ShelfMaterialDetailDO line : lines) {
if (line == null) {
continue;
}
if (line.getQuantity() != null) {
sum = sum.add(line.getQuantity());
}
if (!CollectionUtils.isEmpty(line.getChildren())) {
sum = sum.add(sumShelfMaterialDetailQuantities(line.getChildren()));
}
}
return sum;
}
private long countShelfTypeInTaskOrder(String shelfOrderNumber) {
/**
* 该上架单下是否已存在 type=2上架入库作业单
*/
private int countShelfTypeInTaskOrder(String shelfOrderNumber) {
if (StringUtils.isBlank(shelfOrderNumber)) {
return 0L;
return 0;
}
return stockInTaskOrderService.count(new LambdaQueryWrapper<StockInTaskOrder>()
return (int) stockInTaskOrderService.count(new QueryWrapper<StockInTaskOrder>().lambda()
.eq(StockInTaskOrder::getShelfOrderNumber, shelfOrderNumber)
.eq(StockInTaskOrder::getType, 2)
.eq(StockInTaskOrder::getDelFlag, 1));
.eq(StockInTaskOrder::getType, 2));
}
/**
* PDA 收货完成已生成上架单后落库上架入库作业单type=2 {@link #genStockShelfTaskOrderByUpShelf} 同结构避免在上架操作时再生成一条上架环节仅在上尚未存在时补生成 PC 使用
* PDA 收货完成若该收货单对应上架单尚未生成 type=2 上架入库作业单则补生成 {@link #upShelf} 中补生成策略一致
*/
@Transactional(rollbackFor = Exception.class)
public void tryGenStockShelfInTaskOrderAfterPdaReceiptComplete(String receiptOrderNumber) {
if (StringUtils.isBlank(receiptOrderNumber)) {
return;
}
List<StockShelfOrder> rows = stockShelfOrderService.list(new LambdaQueryWrapper<StockShelfOrder>()
.eq(StockShelfOrder::getReceiptOrderNumber, receiptOrderNumber)
.eq(StockShelfOrder::getDelFlag, 1));
if (CollectionUtils.isEmpty(rows)) {
StockShelfOrderDO query = new StockShelfOrderDO();
query.setReceiptOrderNumber(receiptOrderNumber);
List<StockShelfOrderPO> shelfList = stockShelfOrderService.queryList(query);
if (CollectionUtils.isEmpty(shelfList)) {
log.warn("PDA 收货完成补生成上架作业单:未找到收货单号对应上架单,receiptOrderNumber={}", receiptOrderNumber);
return;
}
rows.sort(Comparator.comparing(StockShelfOrder::getShelfOrderId, Comparator.nullsLast(Comparator.naturalOrder())).reversed());
StockShelfOrder head = rows.get(0);
if (countShelfTypeInTaskOrder(head.getShelfOrderNumber()) > 0) {
return;
for (StockShelfOrderPO shelfPO : shelfList) {
if (shelfPO == null || StringUtils.isBlank(shelfPO.getShelfOrderNumber())) {
continue;
}
if (countShelfTypeInTaskOrder(shelfPO.getShelfOrderNumber()) > 0) {
continue;
}
StockShelfOrderDO shelfDO = buildStockShelfOrderDOForGenShelfTask(shelfPO);
if (shelfDO == null || CollectionUtils.isEmpty(shelfDO.getMaterialDetailList())) {
log.warn("PDA 收货完成补生成上架作业单:上架单无明细,shelfOrderNumber={}", shelfPO.getShelfOrderNumber());
continue;
}
genStockShelfTaskOrderByUpShelf(shelfDO);
}
StockShelfOrderPO full = getInfo(head.getShelfOrderId());
if (full == null || CollectionUtils.isEmpty(full.getMaterialDetailList())) {
return;
}
private StockShelfOrderDO buildStockShelfOrderDOForGenShelfTask(StockShelfOrderPO shelfPO) {
StockShelfOrderDO shelfDO = new StockShelfOrderDO();
BeanUtils.copyProperties(shelfPO, shelfDO);
ShelfMaterialDetailDO detailQuery = new ShelfMaterialDetailDO();
detailQuery.setShelfOrderNumber(shelfPO.getShelfOrderNumber());
List<ShelfMaterialDetailPO> detailPOs = shelfMaterialDetailService.queryList(detailQuery);
if (CollectionUtils.isEmpty(detailPOs)) {
return null;
}
StockShelfOrderDO d = new StockShelfOrderDO();
BeanUtils.copyProperties(full, d);
List<ShelfMaterialDetailDO> dlist = full.getMaterialDetailList().stream()
.map(po -> {
ShelfMaterialDetailDO m = JSONUtil.toBean(JSONUtil.toJsonStr(po), ShelfMaterialDetailDO.class);
if (m.getChildren() == null && !CollectionUtils.isEmpty(po.getChildren())) {
m.setChildren(po.getChildren().stream()
.map(c -> JSONUtil.toBean(JSONUtil.toJsonStr(c), ShelfMaterialDetailDO.class))
.collect(Collectors.toList()));
}
if (m.getChildren() == null) {
m.setChildren(new ArrayList<>());
}
return m;
})
.collect(Collectors.toList());
d.setMaterialDetailList(dlist);
genStockShelfTaskOrderByUpShelf(d);
List<ShelfMaterialDetailDO> detailDOs = new ArrayList<>();
for (ShelfMaterialDetailPO po : detailPOs) {
ShelfMaterialDetailDO d = new ShelfMaterialDetailDO();
BeanUtils.copyProperties(po, d);
detailDOs.add(d);
}
shelfDO.setMaterialDetailList(detailDOs);
return shelfDO;
}
/**
@@ -236,11 +236,11 @@ public class TaskPickingMaterialDetailPO extends BaseVOEntity {
@TableField(exist = false)
private BigDecimal workQuantity;
@ApiModelProperty("是否抄码: 1-是 2-否(与物料主数据一致,查询时回填)")
@ApiModelProperty("是否抄码: 1-是 2-否")
@TableField(exist = false)
private Integer copyCode;
@ApiModelProperty("待拣抄码克重明细(来自 copy_code_reference;顺序与库存抄码 id 列表一致,已按 pickingQuantity 去掉已拣件,仅余待扫)")
@ApiModelProperty("待拣抄码克重明细")
@TableField(exist = false)
private List<CopyCodeReferencePO> weightList;
@@ -33,19 +33,39 @@ public class TaskShelfMaterialDetailImpl extends ServiceImpl<TaskShelfMaterialDe
public List<TaskShelfMaterialDetailPO> queryList(TaskShelfMaterialDetailDO taskShelfMaterialDetailDO)
{
List<TaskShelfMaterialDetailPO> taskShelfMaterialDetailPOList = taskShelfMaterialDetailMapper.queryList(taskShelfMaterialDetailDO);
// 获取查询的层级
List<TaskShelfMaterialDetailPO> askShelfMaterialDetailPOParentList = taskShelfMaterialDetailPOList
.stream().filter(e -> 1 == e.getLevel()).collect(Collectors.toList());
if (CollectionUtils.isEmpty(taskShelfMaterialDetailPOList)) {
return taskShelfMaterialDetailPOList;
}
// 主行level=1 Integer(1) 比较避免 level null 时拆箱 NPE
List<TaskShelfMaterialDetailPO> askShelfMaterialDetailPOParentList = taskShelfMaterialDetailPOList.stream()
.filter(e -> e != null && Integer.valueOf(1).equals(e.getLevel()))
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(askShelfMaterialDetailPOParentList)) {
// 无主行时以无父或 parent=0 为根仍无则整单平铺为根避免详情始终为空
askShelfMaterialDetailPOParentList = taskShelfMaterialDetailPOList.stream()
.filter(e -> e != null && (e.getParentUniqueId() == null || Long.valueOf(0L).equals(e.getParentUniqueId())))
.collect(Collectors.toList());
}
if (CollectionUtils.isEmpty(askShelfMaterialDetailPOParentList)) {
askShelfMaterialDetailPOParentList = new ArrayList<>(taskShelfMaterialDetailPOList);
}
// 递归查询子集
askShelfMaterialDetailPOParentList.forEach(materialDetailPO -> materialDetailPO.setChildren(getChildren(materialDetailPO.getUniqueId(), taskShelfMaterialDetailPOList, 2)));
askShelfMaterialDetailPOParentList.forEach(materialDetailPO -> materialDetailPO.setChildren(
getChildren(materialDetailPO.getUniqueId(), taskShelfMaterialDetailPOList, 2)));
return askShelfMaterialDetailPOParentList;
}
private List<TaskShelfMaterialDetailPO> getChildren(Long parentUniqueId, List<TaskShelfMaterialDetailPO> taskShelfMaterialDetailPOList, Integer maxLevel){
List<TaskShelfMaterialDetailPO> childrenCityList = taskShelfMaterialDetailPOList.stream().filter(materialDetailPO -> parentUniqueId.equals(materialDetailPO.getParentUniqueId())).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(childrenCityList)){
private List<TaskShelfMaterialDetailPO> getChildren(Long parentUniqueId, List<TaskShelfMaterialDetailPO> taskShelfMaterialDetailPOList, Integer maxLevel) {
if (parentUniqueId == null) {
return new ArrayList<>();
}
List<TaskShelfMaterialDetailPO> childrenCityList = taskShelfMaterialDetailPOList.stream()
.filter(materialDetailPO -> parentUniqueId.equals(materialDetailPO.getParentUniqueId()))
.collect(Collectors.toList());
if (!CollectionUtils.isEmpty(childrenCityList)) {
childrenCityList.forEach(childrenCity -> {
if (childrenCity.getLevel() < maxLevel){
Integer level = childrenCity.getLevel();
if (level == null || level < maxLevel) {
childrenCity.setChildren(getChildren(childrenCity.getUniqueId(), taskShelfMaterialDetailPOList, maxLevel));
}
});
@@ -93,7 +93,7 @@ public class StockInTaskOrderDTO extends BaseVOEntity {
private String operatorsName;
@ApiModelProperty("作业完成时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "作业完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date operatorsEndTime;
@@ -136,7 +136,7 @@ public class StockOutTaskOrderDTO extends BaseVOEntity {
private String operatorsName;
@ApiModelProperty("作业完成时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "作业完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date operatorsEndTime;
@@ -93,7 +93,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<where>
<include refid="selectStockInTaskOrderPo1"/>
</where>
-- 创建时间为空的排最后
order by a.create_time is null, a.create_time desc
-- 先按照作业时间来排序,创建时间为空的排最后
order by a.operators_end_time desc, a.create_time is null, a.create_time desc
</select>
</mapper>