From 65ae591f8693567976cf246bf57711d48078e35d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=A6=E9=B8=BF=E5=B1=95?= <18031053041@163.com> Date: Tue, 7 Apr 2026 10:53:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=8D=E6=A0=B8=E9=A1=B5=E9=9D=A2=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReviewOrderApplicationService.java | 66 +++++ .../service/PickingOrderDomainService.java | 6 + .../entity/ReviewMaterialDetail.java | 87 ++++++ .../reviewOrder/entity/ReviewOrder.java | 56 ++++ .../mapper/ReviewMaterialDetailMapper.java | 10 + .../repository/mapper/ReviewOrderMapper.java | 41 +++ .../repository/po/ReviewMaterialDetailPO.java | 131 +++++++++ .../repository/po/ReviewOrderPO.java | 76 ++++++ .../repository/todo/ReviewOrderDO.java | 51 ++++ .../service/ReviewOrderDomainService.java | 214 +++++++++++++++ .../reviewOrder/ReviewOrderAssembler.java | 20 ++ .../dto/reviewOrder/ReviewOrderDTO.java | 51 ++++ .../dto/reviewOrder/ReviewOrderDetailDTO.java | 26 ++ .../facadeApi/reviewOrder/ReviewOrderApi.java | 54 ++++ .../mapper/reviewOrder/ReviewOrderMapper.xml | 249 ++++++++++++++++++ 15 files changed, 1138 insertions(+) create mode 100644 mhd_wms/src/main/java/com/mhd/wms/application/service/reviewOrder/ReviewOrderApplicationService.java create mode 100644 mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/entity/ReviewMaterialDetail.java create mode 100644 mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/entity/ReviewOrder.java create mode 100644 mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/mapper/ReviewMaterialDetailMapper.java create mode 100644 mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/mapper/ReviewOrderMapper.java create mode 100644 mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/po/ReviewMaterialDetailPO.java create mode 100644 mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/po/ReviewOrderPO.java create mode 100644 mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/todo/ReviewOrderDO.java create mode 100644 mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/service/ReviewOrderDomainService.java create mode 100644 mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/reviewOrder/ReviewOrderAssembler.java create mode 100644 mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/reviewOrder/ReviewOrderDTO.java create mode 100644 mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/reviewOrder/ReviewOrderDetailDTO.java create mode 100644 mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/reviewOrder/ReviewOrderApi.java create mode 100644 mhd_wms/src/main/resources/mapper/reviewOrder/ReviewOrderMapper.xml diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/reviewOrder/ReviewOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/reviewOrder/ReviewOrderApplicationService.java new file mode 100644 index 000000000..6881c0b0d --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/reviewOrder/ReviewOrderApplicationService.java @@ -0,0 +1,66 @@ +package com.mhd.wms.application.service.reviewOrder; + +import com.mhd.common.core.exception.ServiceException; +import com.mhd.common.core.utils.StringUtils; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.model.LoginUser; +import com.mhd.wms.domain.reviewOrder.repository.mapper.ReviewOrderMapper; +import com.mhd.wms.domain.reviewOrder.repository.po.ReviewMaterialDetailPO; +import com.mhd.wms.domain.reviewOrder.repository.po.ReviewOrderPO; +import com.mhd.wms.domain.reviewOrder.repository.todo.ReviewOrderDO; +import com.mhd.wms.interfaces.dto.reviewOrder.ReviewOrderDetailDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 复核单应用服务:列表、详情 + */ +@Service +public class ReviewOrderApplicationService { + + @Autowired + private ReviewOrderMapper reviewOrderMapper; + + public List queryList(ReviewOrderDO query) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser != null && loginUser.getUserPo() != null) { + Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); + if (topOrganizationId != null && topOrganizationId != 1L) { + query.setTopOrganizationId(topOrganizationId); + } + } + return reviewOrderMapper.queryList(query); + } + + public ReviewOrderDetailDTO getDetailByReviewOrderId(Long reviewOrderId) { + if (reviewOrderId == null) { + throw new ServiceException("复核单ID不能为空"); + } + ReviewOrderPO header = reviewOrderMapper.selectHeaderByReviewOrderId(reviewOrderId); + if (header == null) { + throw new ServiceException("复核单不存在或已删除"); + } + List details = reviewOrderMapper.queryDetailByReviewOrderId(reviewOrderId); + ReviewOrderDetailDTO result = new ReviewOrderDetailDTO(); + result.setHeader(header); + result.setDetails(details); + return result; + } + + public ReviewOrderDetailDTO getDetailByReviewOrderNumber(String reviewOrderNumber) { + if (StringUtils.isEmpty(reviewOrderNumber)) { + throw new ServiceException("复核单号不能为空"); + } + ReviewOrderPO header = reviewOrderMapper.selectHeaderByReviewOrderNumber(reviewOrderNumber); + if (header == null) { + throw new ServiceException("复核单不存在或已删除"); + } + List details = reviewOrderMapper.queryDetailByReviewOrderNumber(reviewOrderNumber); + ReviewOrderDetailDTO result = new ReviewOrderDetailDTO(); + result.setHeader(header); + result.setDetails(details); + return result; + } +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/pickingOrder/service/PickingOrderDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/pickingOrder/service/PickingOrderDomainService.java index 239db1567..7fb17582d 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/pickingOrder/service/PickingOrderDomainService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/pickingOrder/service/PickingOrderDomainService.java @@ -43,6 +43,7 @@ import com.mhd.wms.domain.pickingOrder.repository.facade.IPickingOrderService; import com.mhd.wms.domain.pickingOrder.repository.po.PickingOrderPO; import com.mhd.wms.domain.pickingOrder.repository.todo.PickingOrderDO; import com.mhd.wms.domain.pushSyncBms.PushSyncBmsDomainService; +import com.mhd.wms.domain.reviewOrder.service.ReviewOrderDomainService; import com.mhd.wms.domain.stockInOrder.repository.todo.StockInOrderDO; import com.mhd.wms.domain.stockInOrder.service.StockInOrderDomainService; import com.mhd.wms.domain.stockOutOrder.entity.StockOutOrder; @@ -91,6 +92,9 @@ public class PickingOrderDomainService { private IWaveOrderService waveOrderService; @Autowired private IWaveOutOrderService waveOutOrderService; + + @Autowired + private ReviewOrderDomainService reviewOrderDomainService; @Autowired private IHandoverTaskOrderService handoverTaskOrderService; @Autowired @@ -661,6 +665,8 @@ public class PickingOrderDomainService { if (pickingOrderPO.getReview() != null && pickingOrderPO.getReview() == 2) { genHandoverTaskOrder(pickingOrderPO); } + // 需要复核且本出库下拣货全部完成时生成复核单,并将出库单置为复核中(8) + reviewOrderDomainService.tryGenerateReviewOrderAfterPickingComplete(pickingOrderPO, stockOutOrder); } //同步BMS结算系统,生成业务单据 //这里只有不需要复核的时候才推送,需要复核的在复核流程推送 diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/entity/ReviewMaterialDetail.java b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/entity/ReviewMaterialDetail.java new file mode 100644 index 000000000..b3d1f3a7a --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/entity/ReviewMaterialDetail.java @@ -0,0 +1,87 @@ +package com.mhd.wms.domain.reviewOrder.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.mhd.common.core.web.domain.BaseVOEntity; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 复核单明细 review_material_detail + */ +@Data +@TableName("review_material_detail") +public class ReviewMaterialDetail extends BaseVOEntity { + + @TableId(type = IdType.AUTO) + private Long reviewMaterialDetailId; + + private Long reviewOrderId; + + private String reviewOrderNumber; + + private String outOrderNumber; + + private Long outUniqueId; + + private Long materialDetailId; + + private Long materialBaseInfoId; + + private String materialCode; + + private String materialName; + + private String barCode; + + private String unitCode; + + private String unitName; + + private BigDecimal pendingReviewQty; + + private BigDecimal reviewedQty; + + private BigDecimal cancelQty; + + private String receiptOrderNumber; + + private String lotNo; + + private String batchNumber; + + private Date productionDate; + + private Date expiryDate; + + private Date inventoryDate; + + private String batchRefNo; + + private String sheetRefNo; + + private String boxPalletNo; + + private String extAttr1; + + private String extAttr2; + + private Date extAttr3; + + private Date extAttr4; + + private BigDecimal reviewQtyEa; + + private BigDecimal netWeightKg; + + private BigDecimal grossWeightKg; + + private BigDecimal volumeCbm; + + private BigDecimal areaSqm; + + private String remark; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/entity/ReviewOrder.java b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/entity/ReviewOrder.java new file mode 100644 index 000000000..c1de19f4f --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/entity/ReviewOrder.java @@ -0,0 +1,56 @@ +package com.mhd.wms.domain.reviewOrder.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.mhd.common.core.web.domain.BaseVOEntity; +import lombok.Data; + +import java.util.Date; + +/** + * 复核单主表 review_order + */ +@Data +@TableName("review_order") +public class ReviewOrder extends BaseVOEntity { + + @TableId(type = IdType.AUTO) + private Long reviewOrderId; + + private String reviewOrderNumber; + + private Long outOrderId; + + private String outOrderNumber; + + private Long organizationId; + + private String organizationName; + + private Long topOrganizationId; + + /** 复核状态:1-待复核 2-复核中 3-已复核 */ + private Integer reviewStatus; + + /** 复核下发:0-否 1-是 */ + private String issuedFlag; + + private Date issuedTime; + + private Long warehouseId; + + private String warehouseCode; + + private String warehouseName; + + private Long customerId; + + private String customerCode; + + private String customerName; + + private Date receiveTime; + + private String remark; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/mapper/ReviewMaterialDetailMapper.java b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/mapper/ReviewMaterialDetailMapper.java new file mode 100644 index 000000000..ec2488222 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/mapper/ReviewMaterialDetailMapper.java @@ -0,0 +1,10 @@ +package com.mhd.wms.domain.reviewOrder.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.mhd.wms.domain.reviewOrder.entity.ReviewMaterialDetail; + +/** + * 复核单明细持久化 + */ +public interface ReviewMaterialDetailMapper extends BaseMapper { +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/mapper/ReviewOrderMapper.java b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/mapper/ReviewOrderMapper.java new file mode 100644 index 000000000..7b566a279 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/mapper/ReviewOrderMapper.java @@ -0,0 +1,41 @@ +package com.mhd.wms.domain.reviewOrder.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.mhd.wms.domain.reviewOrder.entity.ReviewOrder; +import com.mhd.wms.domain.reviewOrder.repository.po.ReviewMaterialDetailPO; +import com.mhd.wms.domain.reviewOrder.repository.po.ReviewOrderPO; +import com.mhd.wms.domain.reviewOrder.repository.todo.ReviewOrderDO; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 复核单:列表、详情头、明细 + MyBatis-Plus 基础 CRUD + */ +public interface ReviewOrderMapper extends BaseMapper { + + /** + * 复核单列表(PC 列表页) + */ + List queryList(ReviewOrderDO query); + + /** + * 详情-主表(按主键) + */ + ReviewOrderPO selectHeaderByReviewOrderId(@Param("reviewOrderId") Long reviewOrderId); + + /** + * 详情-主表(按复核单号) + */ + ReviewOrderPO selectHeaderByReviewOrderNumber(@Param("reviewOrderNumber") String reviewOrderNumber); + + /** + * 详情-明细行(按复核单主键) + */ + List queryDetailByReviewOrderId(@Param("reviewOrderId") Long reviewOrderId); + + /** + * 详情-明细行(按复核单号,明细表冗余字段,可不关联主表) + */ + List queryDetailByReviewOrderNumber(@Param("reviewOrderNumber") String reviewOrderNumber); +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/po/ReviewMaterialDetailPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/po/ReviewMaterialDetailPO.java new file mode 100644 index 000000000..fc9be41e4 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/po/ReviewMaterialDetailPO.java @@ -0,0 +1,131 @@ +package com.mhd.wms.domain.reviewOrder.repository.po; + +import com.mhd.common.core.web.domain.BaseVOEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 复核单明细(review_material_detail) + */ +@Data +@ApiModel(value = "复核单明细", description = "复核/取消复核明细行") +public class ReviewMaterialDetailPO extends BaseVOEntity { + + @ApiModelProperty("明细主键") + private Long reviewMaterialDetailId; + + @ApiModelProperty("复核单ID") + private Long reviewOrderId; + + @ApiModelProperty("复核单号") + private String reviewOrderNumber; + + @ApiModelProperty("出库单号") + private String outOrderNumber; + + @ApiModelProperty("出库明细 unique_id") + private Long outUniqueId; + + @ApiModelProperty("出库物料明细表主键") + private Long materialDetailId; + + @ApiModelProperty("物料基础信息ID") + private Long materialBaseInfoId; + + @ApiModelProperty("物料编码") + private String materialCode; + + @ApiModelProperty("物料名称") + private String materialName; + + @ApiModelProperty("物料条码") + private String barCode; + + @ApiModelProperty("单位代码") + private String unitCode; + + @ApiModelProperty("单位名称") + private String unitName; + + @ApiModelProperty("待复核数量") + private BigDecimal pendingReviewQty; + + @ApiModelProperty("已复核数量") + private BigDecimal reviewedQty; + + @ApiModelProperty("取消复核数量") + private BigDecimal cancelQty; + + @ApiModelProperty("入库单号") + private String receiptOrderNumber; + + @ApiModelProperty("LOT编号") + private String lotNo; + + @ApiModelProperty("批次号") + private String batchNumber; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("生产日期") + private Date productionDate; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("过期日期") + private Date expiryDate; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("存货日期") + private Date inventoryDate; + + @ApiModelProperty("Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("扩展属性1") + private String extAttr1; + + @ApiModelProperty("扩展属性2") + private String extAttr2; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("扩展属性3") + private Date extAttr3; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("扩展属性4") + private Date extAttr4; + + @ApiModelProperty("复核数量EA") + private BigDecimal reviewQtyEa; + + @ApiModelProperty("净重KG") + private BigDecimal netWeightKg; + + @ApiModelProperty("毛重KG") + private BigDecimal grossWeightKg; + + @ApiModelProperty("体积CBM") + private BigDecimal volumeCbm; + + @ApiModelProperty("面积SQM") + private BigDecimal areaSqm; + + @ApiModelProperty("备注") + private String remark; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/po/ReviewOrderPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/po/ReviewOrderPO.java new file mode 100644 index 000000000..67371213a --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/po/ReviewOrderPO.java @@ -0,0 +1,76 @@ +package com.mhd.wms.domain.reviewOrder.repository.po; + +import com.mhd.common.core.web.domain.BaseVOEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +/** + * 复核单主表列表/详情头(review_order) + */ +@Data +@ApiModel(value = "复核单主表", description = "复核单主表展示") +public class ReviewOrderPO extends BaseVOEntity { + + @ApiModelProperty("复核单主键") + private Long reviewOrderId; + + @ApiModelProperty("复核单号") + private String reviewOrderNumber; + + @ApiModelProperty("出库单ID") + private Long outOrderId; + + @ApiModelProperty("出库单号") + private String outOrderNumber; + + @ApiModelProperty("组织ID") + private Long organizationId; + + @ApiModelProperty("组织名称") + private String organizationName; + + @ApiModelProperty("一级组织ID") + private Long topOrganizationId; + + @ApiModelProperty("复核状态:1-待复核 2-复核中 3-已复核") + private Integer reviewStatus; + + @ApiModelProperty("复核下发 0否 1是") + private String issuedFlag; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("复核下发时间") + private Date issuedTime; + + @ApiModelProperty("仓库ID") + private Long warehouseId; + + @ApiModelProperty("仓库编码") + private String warehouseCode; + + @ApiModelProperty("仓库名称") + private String warehouseName; + + @ApiModelProperty("客户ID") + private Long customerId; + + @ApiModelProperty("客户编码") + private String customerCode; + + @ApiModelProperty("客户名称") + private String customerName; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("任务接收时间") + private Date receiveTime; + + @ApiModelProperty("备注") + private String remark; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/todo/ReviewOrderDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/todo/ReviewOrderDO.java new file mode 100644 index 000000000..8cc171098 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/repository/todo/ReviewOrderDO.java @@ -0,0 +1,51 @@ +package com.mhd.wms.domain.reviewOrder.repository.todo; + +import com.mhd.common.core.web.domain.BaseVOEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 复核单列表查询条件(对应表 review_order) + */ +@Data +public class ReviewOrderDO extends BaseVOEntity { + + @ApiModelProperty("复核单主键") + private Long reviewOrderId; + + @ApiModelProperty("复核单号(模糊)") + private String reviewOrderNumber; + + @ApiModelProperty("出库单号(模糊)") + private String outOrderNumber; + + @ApiModelProperty("复核状态:1-待复核 2-复核中 3-已复核") + private Integer reviewStatus; + + @ApiModelProperty("复核下发:0-否 1-是") + private String issuedFlag; + + @ApiModelProperty("组织ID") + private Long organizationId; + + @ApiModelProperty("一级组织ID") + private Long topOrganizationId; + + @ApiModelProperty("仓库ID") + private Long warehouseId; + + @ApiModelProperty("客户名称(模糊)") + private String customerName; + + @ApiModelProperty("创建时间起(字符串,格式与库一致即可,如 yyyy-MM-dd)") + private String createTimeStart; + + @ApiModelProperty("创建时间止") + private String createTimeEnd; + + @ApiModelProperty("接收时间起") + private String receiveTimeStart; + + @ApiModelProperty("接收时间止") + private String receiveTimeEnd; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/service/ReviewOrderDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/service/ReviewOrderDomainService.java new file mode 100644 index 000000000..a4bbe8b91 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/reviewOrder/service/ReviewOrderDomainService.java @@ -0,0 +1,214 @@ +package com.mhd.wms.domain.reviewOrder.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.mhd.common.core.exception.ServiceException; +import com.mhd.common.core.utils.OrderSequence; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.model.LoginUser; +import com.mhd.wms.domain.outMaterialDetail.entity.OutMaterialDetail; +import com.mhd.wms.domain.outMaterialDetail.repository.mapper.OutMaterialDetailMapper; +import com.mhd.wms.domain.pickingMaterialDetail.entity.PickingMaterialDetail; +import com.mhd.wms.domain.pickingMaterialDetail.repository.facade.IPickingMaterialDetailService; +import com.mhd.wms.domain.pickingOrder.entity.PickingOrder; +import com.mhd.wms.domain.pickingOrder.repository.po.PickingOrderPO; +import com.mhd.wms.domain.pickingOrder.repository.facade.IPickingOrderService; +import com.mhd.wms.domain.reviewOrder.entity.ReviewMaterialDetail; +import com.mhd.wms.domain.reviewOrder.entity.ReviewOrder; +import com.mhd.wms.domain.reviewOrder.repository.mapper.ReviewMaterialDetailMapper; +import com.mhd.wms.domain.reviewOrder.repository.mapper.ReviewOrderMapper; +import com.mhd.wms.domain.stockOutOrder.entity.StockOutOrder; +import com.mhd.wms.domain.stockOutOrder.repository.facade.IStockOutOrderService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * 复核单领域:拣货完成后生成复核单等 + */ +@Service +@Slf4j +public class ReviewOrderDomainService { + + @Autowired + private ReviewOrderMapper reviewOrderMapper; + + @Autowired + private ReviewMaterialDetailMapper reviewMaterialDetailMapper; + + @Autowired + private IPickingOrderService pickingOrderService; + + @Autowired + private IPickingMaterialDetailService pickingMaterialDetailService; + + @Autowired + private OutMaterialDetailMapper outMaterialDetailMapper; + + @Autowired + private IStockOutOrderService stockOutOrderService; + + /** + * 拣货全部完成后,若出库单需要复核,则生成复核单头+明细,并将出库单状态置为「复核中」(8)。 + * 仅处理普通拣货单(type=1);波次拣货(type=2)暂不生成,避免一单多出库口径不一致。 + */ + @Transactional(rollbackFor = Exception.class) + public void tryGenerateReviewOrderAfterPickingComplete(PickingOrderPO pickingOrderPO, StockOutOrder stockOutOrder) { + if (pickingOrderPO == null || stockOutOrder == null) { + return; + } + if (!Integer.valueOf(1).equals(pickingOrderPO.getReview())) { + return; + } + if (!Integer.valueOf(1).equals(pickingOrderPO.getType())) { + return; + } + String outOrderNumber = pickingOrderPO.getOrderNumber(); + if (outOrderNumber == null) { + return; + } + + List pickingOrders = pickingOrderService.list(new LambdaQueryWrapper() + .eq(PickingOrder::getOrderNumber, outOrderNumber) + .eq(PickingOrder::getType, 1) + .eq(PickingOrder::getDelFlag, 1)); + if (pickingOrders.isEmpty()) { + return; + } + boolean allPickingFinished = pickingOrders.stream() + .allMatch(p -> p.getStatus() != null && p.getStatus() == 3); + if (!allPickingFinished) { + return; + } + + long exists = reviewOrderMapper.selectCount(new LambdaQueryWrapper() + .eq(ReviewOrder::getOutOrderNumber, outOrderNumber) + .eq(ReviewOrder::getDelFlag, 1)); + if (exists > 0) { + log.debug("复核单已存在,跳过生成 outOrderNumber={}", outOrderNumber); + return; + } + + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser == null) { + throw new ServiceException("登录信息失效,无法生成复核单"); + } + + String reviewOrderNumber = OrderSequence.getOrderCode("FH"); + Date now = new Date(); + + ReviewOrder header = new ReviewOrder(); + header.setReviewOrderNumber(reviewOrderNumber); + header.setOutOrderId(stockOutOrder.getOutOrderId()); + header.setOutOrderNumber(stockOutOrder.getOutOrderNumber()); + header.setOrganizationId(stockOutOrder.getOrganizationId()); + header.setOrganizationName(stockOutOrder.getOrganizationName()); + header.setTopOrganizationId(stockOutOrder.getTopOrganizationId()); + header.setReviewStatus(1); + header.setIssuedFlag("0"); + header.setWarehouseId(stockOutOrder.getWarehouseId()); + header.setWarehouseCode(stockOutOrder.getWarehouseCode()); + header.setWarehouseName(stockOutOrder.getWarehouseName()); + header.setCustomerId(stockOutOrder.getCustomerId()); + header.setCustomerCode(stockOutOrder.getCustomerCode()); + header.setCustomerName(stockOutOrder.getCustomerName()); + header.setDelFlag(1); + header.setCreateBy(loginUser.getUserid()); + header.setCreateByName(loginUser.getUsername()); + header.setCreateTime(now); + header.setUpdateBy(loginUser.getUserid()); + header.setUpdateByName(loginUser.getUsername()); + header.setUpdateTime(now); + + reviewOrderMapper.insert(header); + Long reviewOrderId = header.getReviewOrderId(); + if (reviewOrderId == null) { + throw new ServiceException("复核单主表保存失败"); + } + + for (PickingOrder po : pickingOrders) { + List lines = pickingMaterialDetailService.list(new LambdaQueryWrapper() + .eq(PickingMaterialDetail::getPickingOrderNumber, po.getPickingOrderNumber()) + .eq(PickingMaterialDetail::getDelFlag, 1)); + for (PickingMaterialDetail line : lines) { + ReviewMaterialDetail row = buildDetailFromPicking(line, reviewOrderId, reviewOrderNumber, outOrderNumber, loginUser, now); + reviewMaterialDetailMapper.insert(row); + } + } + + StockOutOrder statusUpdate = new StockOutOrder(); + statusUpdate.setStatus(8); + statusUpdate.setUpdateBy(loginUser.getUserid()); + statusUpdate.setUpdateByName(loginUser.getUsername()); + statusUpdate.setUpdateTime(now); + stockOutOrderService.update(statusUpdate, new LambdaQueryWrapper() + .eq(StockOutOrder::getOutOrderNumber, outOrderNumber)); + + log.info("拣货完成已生成复核单 reviewOrderNumber={} outOrderNumber={}", reviewOrderNumber, outOrderNumber); + } + + private ReviewMaterialDetail buildDetailFromPicking(PickingMaterialDetail line, Long reviewOrderId, String reviewOrderNumber, + String outOrderNumber, LoginUser loginUser, Date now) { + ReviewMaterialDetail d = new ReviewMaterialDetail(); + d.setReviewOrderId(reviewOrderId); + d.setReviewOrderNumber(reviewOrderNumber); + d.setOutOrderNumber(outOrderNumber); + d.setOutUniqueId(line.getOutUniqueId()); + d.setMaterialBaseInfoId(line.getMaterialBaseInfoId()); + d.setMaterialCode(line.getMaterialCode()); + d.setMaterialName(line.getMaterialName()); + d.setBarCode(line.getBarCode()); + d.setUnitCode(line.getUnitCode()); + d.setUnitName(line.getUnitName()); + + BigDecimal pending = line.getPickingQuantity() != null ? line.getPickingQuantity() : line.getQuantity(); + if (pending == null) { + pending = BigDecimal.ZERO; + } + d.setPendingReviewQty(pending); + d.setReviewedQty(BigDecimal.ZERO); + d.setCancelQty(BigDecimal.ZERO); + d.setBatchNumber(line.getBatchNumber()); + d.setProductionDate(line.getProductionDate()); + d.setExpiryDate(line.getExpiryDate()); + d.setInventoryDate(line.getInventoryDate()); + d.setBatchRefNo(line.getBatchRefNo()); + d.setSheetRefNo(line.getSheetRefNo()); + d.setBoxPalletNo(line.getBoxPalletNo()); + d.setExtAttr1(line.getExtAttr1()); + d.setExtAttr2(line.getExtAttr2()); + d.setExtAttr3(line.getExtAttr3()); + d.setExtAttr4(line.getExtAttr4()); + d.setReviewQtyEa(pending); + d.setNetWeightKg(line.getTotalNetWeight()); + d.setGrossWeightKg(line.getTotalGrossWeight()); + d.setVolumeCbm(line.getTotalVolume()); + d.setAreaSqm(line.getTotalArea()); + d.setRemark(line.getRemark()); + d.setDelFlag(1); + d.setCreateBy(loginUser.getUserid()); + d.setCreateByName(loginUser.getUsername()); + d.setCreateTime(now); + d.setUpdateBy(loginUser.getUserid()); + d.setUpdateByName(loginUser.getUsername()); + d.setUpdateTime(now); + + if (line.getOutUniqueId() != null) { + OutMaterialDetail outMd = outMaterialDetailMapper.selectOne(new LambdaQueryWrapper() + .eq(OutMaterialDetail::getUniqueId, line.getOutUniqueId()) + .eq(OutMaterialDetail::getDelFlag, 1)); + if (outMd == null) { + outMd = outMaterialDetailMapper.selectOne(new LambdaQueryWrapper() + .eq(OutMaterialDetail::getUniqueId, line.getOutUniqueId())); + } + if (outMd != null) { + d.setMaterialDetailId(outMd.getMaterialDetailId()); + } + } + return d; + } +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/reviewOrder/ReviewOrderAssembler.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/reviewOrder/ReviewOrderAssembler.java new file mode 100644 index 000000000..6595edb1a --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/reviewOrder/ReviewOrderAssembler.java @@ -0,0 +1,20 @@ +package com.mhd.wms.interfaces.assember.reviewOrder; + +import com.mhd.common.core.utils.IgnoreNullUtil; +import com.mhd.common.core.utils.bean.BeanUtils; +import com.mhd.wms.domain.reviewOrder.repository.todo.ReviewOrderDO; +import com.mhd.wms.interfaces.dto.reviewOrder.ReviewOrderDTO; +import org.springframework.stereotype.Component; + +/** + * 复核单 DTO ↔ DO + */ +@Component +public class ReviewOrderAssembler { + + public ReviewOrderDO toDO(ReviewOrderDTO dto) { + ReviewOrderDO reviewOrderDO = new ReviewOrderDO(); + BeanUtils.copyProperties(dto, reviewOrderDO, IgnoreNullUtil.getNullPropertyNames(dto)); + return reviewOrderDO; + } +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/reviewOrder/ReviewOrderDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/reviewOrder/ReviewOrderDTO.java new file mode 100644 index 000000000..6f86d5b0e --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/reviewOrder/ReviewOrderDTO.java @@ -0,0 +1,51 @@ +package com.mhd.wms.interfaces.dto.reviewOrder; + +import com.mhd.common.core.web.domain.BaseVOEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 复核单查询/入参 DTO(列表条件与主键) + */ +@Data +public class ReviewOrderDTO extends BaseVOEntity { + + @ApiModelProperty("复核单主键") + private Long reviewOrderId; + + @ApiModelProperty("复核单号(模糊)") + private String reviewOrderNumber; + + @ApiModelProperty("出库单号(模糊)") + private String outOrderNumber; + + @ApiModelProperty("复核状态:1-待复核 2-复核中 3-已复核") + private Integer reviewStatus; + + @ApiModelProperty("复核下发:0-否 1-是") + private String issuedFlag; + + @ApiModelProperty("组织ID") + private Long organizationId; + + @ApiModelProperty("一级组织ID") + private Long topOrganizationId; + + @ApiModelProperty("仓库ID") + private Long warehouseId; + + @ApiModelProperty("客户名称(模糊)") + private String customerName; + + @ApiModelProperty("创建时间起 yyyy-MM-dd") + private String createTimeStart; + + @ApiModelProperty("创建时间止 yyyy-MM-dd") + private String createTimeEnd; + + @ApiModelProperty("接收时间起 yyyy-MM-dd") + private String receiveTimeStart; + + @ApiModelProperty("接收时间止 yyyy-MM-dd") + private String receiveTimeEnd; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/reviewOrder/ReviewOrderDetailDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/reviewOrder/ReviewOrderDetailDTO.java new file mode 100644 index 000000000..2cb5f96f0 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/reviewOrder/ReviewOrderDetailDTO.java @@ -0,0 +1,26 @@ +package com.mhd.wms.interfaces.dto.reviewOrder; + +import com.mhd.wms.domain.reviewOrder.repository.po.ReviewMaterialDetailPO; +import com.mhd.wms.domain.reviewOrder.repository.po.ReviewOrderPO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 复核单详情:主表 + 明细行 + */ +@Data +@ApiModel("复核单详情") +public class ReviewOrderDetailDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("复核单头") + private ReviewOrderPO header; + + @ApiModelProperty("复核明细列表") + private List details; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/reviewOrder/ReviewOrderApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/reviewOrder/ReviewOrderApi.java new file mode 100644 index 000000000..f2076713f --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/reviewOrder/ReviewOrderApi.java @@ -0,0 +1,54 @@ +package com.mhd.wms.interfaces.facadeApi.reviewOrder; + +import com.mhd.common.core.web.controller.BaseController; +import com.mhd.common.core.web.domain.AjaxResult; +import com.mhd.common.core.web.page.TableDataInfo; +import com.mhd.wms.application.service.reviewOrder.ReviewOrderApplicationService; +import com.mhd.wms.domain.reviewOrder.repository.po.ReviewOrderPO; +import com.mhd.wms.domain.reviewOrder.repository.todo.ReviewOrderDO; +import com.mhd.wms.interfaces.assember.reviewOrder.ReviewOrderAssembler; +import com.mhd.wms.interfaces.dto.reviewOrder.ReviewOrderDTO; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +/** + * PC 复核单接口:列表、详情(头+明细) + */ +@RestController +@RequestMapping("/reviewOrderApi") +public class ReviewOrderApi extends BaseController { + + @Autowired + private ReviewOrderApplicationService reviewOrderApplicationService; + + @Resource + private ReviewOrderAssembler reviewOrderAssembler; + + @ApiOperation("复核单分页列表") + @GetMapping("/list") + public TableDataInfo list(ReviewOrderDTO reviewOrderDTO) { + ReviewOrderDO query = reviewOrderAssembler.toDO(reviewOrderDTO); + startPage(); + List list = reviewOrderApplicationService.queryList(query); + return getDataTable(list); + } + + @ApiOperation("复核单详情(按主键,含明细)") + @GetMapping("/detail/{reviewOrderId}") + public AjaxResult detail(@PathVariable("reviewOrderId") Long reviewOrderId) { + return AjaxResult.success(reviewOrderApplicationService.getDetailByReviewOrderId(reviewOrderId)); + } + + @ApiOperation("复核单详情(按复核单号,含明细)") + @GetMapping("/detailByNumber/{reviewOrderNumber}") + public AjaxResult detailByNumber(@PathVariable("reviewOrderNumber") String reviewOrderNumber) { + return AjaxResult.success(reviewOrderApplicationService.getDetailByReviewOrderNumber(reviewOrderNumber)); + } +} diff --git a/mhd_wms/src/main/resources/mapper/reviewOrder/ReviewOrderMapper.xml b/mhd_wms/src/main/resources/mapper/reviewOrder/ReviewOrderMapper.xml new file mode 100644 index 000000000..0f9fca7aa --- /dev/null +++ b/mhd_wms/src/main/resources/mapper/reviewOrder/ReviewOrderMapper.xml @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + a.review_order_id, + a.review_order_number, + a.out_order_id, + a.out_order_number, + a.organization_id, + a.organization_name, + a.top_organization_id, + a.review_status, + a.issued_flag, + a.issued_time, + a.warehouse_id, + a.warehouse_code, + a.warehouse_name, + a.customer_id, + a.customer_code, + a.customer_name, + a.receive_time, + a.remark, + a.create_by, + a.create_by_name, + a.create_time, + a.update_by, + a.update_by_name, + a.update_time, + a.del_flag + + + + + and a.review_order_id = #{reviewOrderId} + + + and a.review_order_number like concat('%', #{reviewOrderNumber}, '%') + + + and a.out_order_number like concat('%', #{outOrderNumber}, '%') + + + and a.review_status = #{reviewStatus} + + + and a.issued_flag = #{issuedFlag} + + + and a.organization_id = #{organizationId} + + + and a.top_organization_id = #{topOrganizationId} + + + and a.warehouse_id = #{warehouseId} + + + and a.customer_name like concat('%', #{customerName}, '%') + + + and date_format(a.create_time, '%Y-%m-%d') >= #{createTimeStart} + + + and date_format(a.create_time, '%Y-%m-%d') <= #{createTimeEnd} + + + and date_format(a.receive_time, '%Y-%m-%d') >= #{receiveTimeStart} + + + and date_format(a.receive_time, '%Y-%m-%d') <= #{receiveTimeEnd} + + + + and a.del_flag = #{delFlag} + + + and a.del_flag = 1 + + + + + + + + + + + + + + + d.review_material_detail_id, + d.review_order_id, + d.review_order_number, + d.out_order_number, + d.out_unique_id, + d.material_detail_id, + d.material_base_info_id, + d.material_code, + d.material_name, + d.bar_code, + d.unit_code, + d.unit_name, + d.pending_review_qty, + d.reviewed_qty, + d.cancel_qty, + d.receipt_order_number, + d.lot_no, + d.batch_number, + d.production_date, + d.expiry_date, + d.inventory_date, + d.batch_ref_no, + d.sheet_ref_no, + d.box_pallet_no, + d.ext_attr_1, + d.ext_attr_2, + d.ext_attr_3, + d.ext_attr_4, + d.review_qty_ea, + d.net_weight_kg, + d.gross_weight_kg, + d.volume_cbm, + d.area_sqm, + d.remark, + d.create_by, + d.create_by_name, + d.create_time, + d.update_by, + d.update_by_name, + d.update_time, + d.del_flag + + + + + + + +