PDA抄码拣货修改

This commit is contained in:
秦鸿展
2026-04-21 16:52:12 +08:00
parent f394f03dd9
commit 4b79294168
8 changed files with 118 additions and 37 deletions
@@ -237,6 +237,8 @@ public class StockOutTaskOrderApplicationService {
returnTaskPickingMaterialDetailDO.setTotalGrossWeight(taskPickingMaterialDetailDO.getTotalGrossWeight());
returnTaskPickingMaterialDetailDO.setTotalVolume(taskPickingMaterialDetailDO.getTotalVolume());
returnTaskPickingMaterialDetailDO.setTotalArea(taskPickingMaterialDetailDO.getTotalArea());
// 抄码拣货:PDA 提交的抄码 id 需透传,assembleParam 从 DB 重建 DO 时否则会丢失
returnTaskPickingMaterialDetailDO.setPickedCopyCodeReferenceIds(taskPickingMaterialDetailDO.getPickedCopyCodeReferenceIds());
//是否开启了序列号管理
if (taskPickingMaterialDetailPO.getSerialNumberManage() == 1){
if (CollectionUtils.isEmpty(taskPickingMaterialDetailDO.getMaterialDetailSerialNumberList())){
@@ -15,8 +15,8 @@ public class CopyCodeReferencePO extends BaseVOEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("id")
private Integer id;
@ApiModelProperty("抄码对照主键 idPDA 提交 pickedCopyCodeReferenceIds 用)")
private Long id;
@ApiModelProperty("序号")
private Integer serialNumber;
@@ -1,11 +1,13 @@
package com.mhd.wms.domain.pickingMaterialDetail.repository.persistence;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
import com.mhd.wms.domain.copyCodeReference.service.CopyCodeReferenceDomainService;
import com.mhd.wms.domain.copyCodeReference.entity.CopyCodeReference;
import com.mhd.wms.domain.copyCodeReference.repository.facade.ICopyCodeReferenceService;
import com.mhd.wms.domain.outMaterialDetail.repository.mapper.OutMaterialDetailMapper;
@@ -339,6 +341,36 @@ public class PickingMaterialDetailImpl extends ServiceImpl<PickingMaterialDetail
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean addQuantity(PickingMaterialDetailDOByUpdate pickingMaterialDetailDOByUpdate){
// 与库中已有 picked_copy_code_reference_ids 再合并一次,避免多次拣货提交时仅带本批 id 覆盖历史已拣 id
List<PickingMaterialDetailDO> pmdList = pickingMaterialDetailDOByUpdate.getPickingMaterialDetailList();
if (!CollectionUtils.isEmpty(pmdList)) {
List<Long> uniqueIds = pmdList.stream()
.map(PickingMaterialDetailDO::getUniqueId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (!uniqueIds.isEmpty()) {
List<PickingMaterialDetail> rows = list(new LambdaQueryWrapper<PickingMaterialDetail>()
.in(PickingMaterialDetail::getUniqueId, uniqueIds)
.eq(PickingMaterialDetail::getDelFlag, 1));
// HashMap.merge 不允许 value 为 nullpicked_copy_code_reference_ids 未拣过时可能为 null
Map<Long, String> pickedInDb = rows.stream()
.filter(r -> r.getUniqueId() != null)
.collect(Collectors.toMap(
PickingMaterialDetail::getUniqueId,
r -> Objects.toString(r.getPickedCopyCodeReferenceIds(), ""),
(a, b) -> a));
for (PickingMaterialDetailDO item : pmdList) {
if (item.getUniqueId() == null) {
continue;
}
String dbCsv = pickedInDb.get(item.getUniqueId());
String merged = CopyCodeReferenceDomainService.mergeCommaSeparatedUniqueIds(
dbCsv, item.getPickedCopyCodeReferenceIds());
item.setPickedCopyCodeReferenceIds(merged);
}
}
}
int count = pickingMaterialDetailMapper.addQuantity(pickingMaterialDetailDOByUpdate);
if (count == 0){
throw new ServiceException("更新拣货单拣货数量失败");
@@ -10,11 +10,18 @@ import com.mhd.system.api.model.LoginUser;
import com.mhd.wms.domain.stockOutTaskOrder.repository.todo.StockOutTaskOrderDO;
import com.mhd.wms.domain.taskPickingMaterialDetail.repository.todo.TaskPickingMaterialDetailDO;
import com.mhd.wms.interfaces.dto.stockOutTaskOrder.StockOutTaskOrderDTO;
import com.mhd.wms.interfaces.dto.stockOutTaskOrder.TaskMaterialDTO;
import com.mhd.wms.interfaces.dto.stockOutTaskOrder.TaskStorageDTO;
import com.mhd.wms.interfaces.dto.taskPickingMaterialDetail.TaskPickingMaterialDetailDTO;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 拣货作业单Assembler
@@ -81,41 +88,63 @@ public class StockOutTaskOrderAssembler {
}
/**
* 按库位拣货 转换实体
* 提交拣货:按库位、按物料共用。从 taskStorageList、taskMaterialList 扁平化拣货任务明细(含抄码 id)。
*/
public StockOutTaskOrderDO toDOPickingByStorageLocation(StockOutTaskOrderDTO stockOutTaskOrderDTO) {
public StockOutTaskOrderDO toDOPicking(StockOutTaskOrderDTO stockOutTaskOrderDTO) {
StockOutTaskOrderDO stockOutTaskOrderDO = new StockOutTaskOrderDO();
// 拷贝
BeanUtils.copyProperties(stockOutTaskOrderDTO, stockOutTaskOrderDO, IgnoreNullUtil.getNullPropertyNames(stockOutTaskOrderDTO));
List<TaskPickingMaterialDetailDO> taskPickingMaterialDetailList = new ArrayList<>();
stockOutTaskOrderDTO.getTaskStorageList().forEach(taskStorageDTO -> {
taskStorageDTO.getTaskPickingMaterialDetailList().forEach(taskPickingMaterialDetailDTO -> {
TaskPickingMaterialDetailDO taskPickingMaterialDetailDO = new TaskPickingMaterialDetailDO();
BeanUtils.copyProperties(taskPickingMaterialDetailDTO, taskPickingMaterialDetailDO, IgnoreNullUtil.getNullPropertyNames(taskPickingMaterialDetailDTO));
taskPickingMaterialDetailList.add(taskPickingMaterialDetailDO);
});
});
stockOutTaskOrderDO.setTaskPickingMaterialDetailList(taskPickingMaterialDetailList);
stockOutTaskOrderDO.setTaskPickingMaterialDetailList(collectTaskPickingMaterialDetailDOList(stockOutTaskOrderDTO));
return stockOutTaskOrderDO;
}
private List<TaskPickingMaterialDetailDO> collectTaskPickingMaterialDetailDOList(StockOutTaskOrderDTO dto) {
List<TaskPickingMaterialDetailDO> out = new ArrayList<>();
if (!CollectionUtils.isEmpty(dto.getTaskStorageList())) {
for (TaskStorageDTO taskStorage : dto.getTaskStorageList()) {
if (taskStorage == null || CollectionUtils.isEmpty(taskStorage.getTaskPickingMaterialDetailList())) {
continue;
}
for (TaskPickingMaterialDetailDTO row : taskStorage.getTaskPickingMaterialDetailList()) {
out.add(toTaskPickingMaterialDetailDO(row));
}
}
}
if (!CollectionUtils.isEmpty(dto.getTaskMaterialList())) {
for (TaskMaterialDTO taskMaterial : dto.getTaskMaterialList()) {
if (taskMaterial == null || CollectionUtils.isEmpty(taskMaterial.getTaskPickingMaterialDetailList())) {
continue;
}
for (TaskPickingMaterialDetailDTO row : taskMaterial.getTaskPickingMaterialDetailList()) {
out.add(toTaskPickingMaterialDetailDO(row));
}
}
}
return out;
}
private static TaskPickingMaterialDetailDO toTaskPickingMaterialDetailDO(TaskPickingMaterialDetailDTO taskPickingMaterialDetailDTO) {
TaskPickingMaterialDetailDO taskPickingMaterialDetailDO = new TaskPickingMaterialDetailDO();
BeanUtils.copyProperties(taskPickingMaterialDetailDTO, taskPickingMaterialDetailDO, IgnoreNullUtil.getNullPropertyNames(taskPickingMaterialDetailDTO));
applyPickedCopyCodeReferenceIds(taskPickingMaterialDetailDTO, taskPickingMaterialDetailDO);
return taskPickingMaterialDetailDO;
}
/**
* 按物料拣货 转换实体
* 保证抄码 id 进入 DO:显式覆盖 BeanUtils 遗漏;未传时从 weightList[].id 拼接。
*/
public StockOutTaskOrderDO toDOPickingByMaterial(StockOutTaskOrderDTO stockOutTaskOrderDTO) {
StockOutTaskOrderDO stockOutTaskOrderDO = new StockOutTaskOrderDO();
// 拷贝
BeanUtils.copyProperties(stockOutTaskOrderDTO, stockOutTaskOrderDO, IgnoreNullUtil.getNullPropertyNames(stockOutTaskOrderDTO));
List<TaskPickingMaterialDetailDO> taskPickingMaterialDetailList = new ArrayList<>();
stockOutTaskOrderDTO.getTaskMaterialList().forEach(taskMaterialDTO -> {
taskMaterialDTO.getTaskPickingMaterialDetailList().forEach(taskPickingMaterialDetailDTO -> {
TaskPickingMaterialDetailDO taskPickingMaterialDetailDO = new TaskPickingMaterialDetailDO();
BeanUtils.copyProperties(taskPickingMaterialDetailDTO, taskPickingMaterialDetailDO, IgnoreNullUtil.getNullPropertyNames(taskPickingMaterialDetailDTO));
taskPickingMaterialDetailList.add(taskPickingMaterialDetailDO);
});
});
stockOutTaskOrderDO.setTaskPickingMaterialDetailList(taskPickingMaterialDetailList);
return stockOutTaskOrderDO;
private static void applyPickedCopyCodeReferenceIds(TaskPickingMaterialDetailDTO src, TaskPickingMaterialDetailDO dest) {
String picked = src.getPickedCopyCodeReferenceIds();
if (!StringUtils.hasText(picked) && src.getWeightList() != null && !src.getWeightList().isEmpty()) {
picked = src.getWeightList().stream()
.filter(Objects::nonNull)
.map(m -> m.get("id"))
.filter(Objects::nonNull)
.map(Object::toString)
.collect(Collectors.joining(","));
}
if (StringUtils.hasText(picked)) {
dest.setPickedCopyCodeReferenceIds(picked);
}
}
}
@@ -1,6 +1,7 @@
package com.mhd.wms.interfaces.dto.taskPickingMaterialDetail;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.mhd.common.core.annotation.Excel;
@@ -12,6 +13,7 @@ import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
* 拣货作业单物料明细对象 task_picking_material_detail
@@ -229,4 +231,14 @@ public class TaskPickingMaterialDetailDTO extends BaseVOEntity {
@ApiModelProperty("总面积(SQM)")
private BigDecimal totalArea;
@JsonAlias({"picked_copy_code_reference_ids"})
@ApiModelProperty("本次已拣抄码对照id(逗号分隔,抄码拣货提交必填,对应拣货单明细 picked_copy_code_reference_ids")
private String pickedCopyCodeReferenceIds;
/**
* 与 getInfoByMaterial 回显结构一致;若未传 pickedCopyCodeReferenceIds,服务端可从每项 id 拼成逗号串。
*/
@ApiModelProperty("抄码待拣/已选列表(可选,用于从 id 推导 pickedCopyCodeReferenceIds")
private List<Map<String, Object>> weightList;
}
@@ -63,9 +63,7 @@ public class stockOutTaskOrderAppApi extends BaseController {
@PostMapping("/pickingByStorageLocation")
public AjaxResult pickingByStorageLocation(@RequestBody StockOutTaskOrderDTO stockOutTaskOrderDTO)
{
//转换实体
StockOutTaskOrderDO stockOutTaskOrderDO = stockOutTaskOrderAssembler.toDOPickingByStorageLocation(stockOutTaskOrderDTO);
//拆成最小颗粒
StockOutTaskOrderDO stockOutTaskOrderDO = stockOutTaskOrderAssembler.toDOPicking(stockOutTaskOrderDTO);
return AjaxResult.success(stockOutTaskOrderApplicationService.pickingByMaterial(stockOutTaskOrderDO));
}
@@ -86,9 +84,7 @@ public class stockOutTaskOrderAppApi extends BaseController {
@PostMapping("/pickingByMaterial")
public AjaxResult pickingByMaterial(@RequestBody StockOutTaskOrderDTO stockOutTaskOrderDTO)
{
//转换实体
StockOutTaskOrderDO stockOutTaskOrderDO = stockOutTaskOrderAssembler.toDOPickingByMaterial(stockOutTaskOrderDTO);
//拆成最小颗粒
StockOutTaskOrderDO stockOutTaskOrderDO = stockOutTaskOrderAssembler.toDOPicking(stockOutTaskOrderDTO);
return AjaxResult.success(stockOutTaskOrderApplicationService.pickingByMaterial(stockOutTaskOrderDO));
}
@@ -5,6 +5,9 @@ import com.mhd.common.core.web.controller.BaseController;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.core.web.page.TableDataInfoApi;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.domain.cache.AssociationWarehouseCacheDO;
import com.mhd.system.api.domain.cache.SystemServiceCacheUtil;
import com.mhd.system.api.model.LoginUser;
import com.mhd.wms.application.service.stockReceiptOrder.StockReceiptOrderApplicationService;
import com.mhd.wms.domain.receiptMaterialDetail.repository.po.ReceiptMaterialDetailPO;
import com.mhd.wms.domain.stockReceiptOrder.repository.po.StockReceiptOrderPO;
@@ -54,7 +57,14 @@ public class StockReceiptOrderAppApi extends BaseController {
//转换实体
StockReceiptOrderDO stockReceiptOrderDO = stockReceiptOrderAssembler.toDO(stockReceiptOrderDTO);
startPage();
stockReceiptOrderDO.setOperatorsBy(SecurityUtils.getLoginUser().getUserPo().getUserId());
LoginUser loginUser = SecurityUtils.getLoginUser();
stockReceiptOrderDO.setOperatorsBy(loginUser.getUserPo().getUserId());
// 与 PDA 出库复核列表一致:按当前用户关联仓库过滤(见 StockOutOrderAppApi#list
AssociationWarehouseCacheDO associationWarehouseCacheDO =
SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid());
if (associationWarehouseCacheDO != null) {
stockReceiptOrderDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId());
}
List<StockReceiptOrderPO> list = stockReceiptOrderApplicationService.queryList(stockReceiptOrderDO);
return getDataTableApi(list);
}
@@ -114,7 +114,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
a.SPECIFICATION_MODEL, a.SKU_CODE, a.INVOICE_NO, a.LITER, a.DIMENSIONS, a.DECLARATION_UNIT, a.BATCH_REF_NO, a.SHEET_REF_NO,
a.ORIGIN_COUNTRY, a.BOX_PALLET_NO, a.CURRENCY, a.UNIT, a.DECLARED_QUANTITY, a.BOX_COUNT, a.PIECE_COUNT, a.INBOUND_QUANTITY,
a.TOTAL_NET_WEIGHT, a.TOTAL_GROSS_WEIGHT, a.TOTAL_VOLUME, a.TOTAL_AREA, a.TOTAL_PRICE,
a.PRODUCTION_DATE, a.EXPIRY_DATE, a.INVENTORY_DATE, a.EXT_ATTR_1, a.EXT_ATTR_2, a.EXT_ATTR_3, a.EXT_ATTR_4
a.PRODUCTION_DATE, a.EXPIRY_DATE, a.INVENTORY_DATE, a.EXT_ATTR_1, a.EXT_ATTR_2, a.EXT_ATTR_3, a.EXT_ATTR_4,
a.OMS_IN_MATERIAL_DETAIL
,CASE
WHEN (a.quantity - a.receipt_quantity) &lt; 0 THEN 0