From 4e9d2b7b3ff49e3991eda4602d77e20ad35e1255 Mon Sep 17 00:00:00 2001 From: my_ong <429426262@qq.com> Date: Mon, 9 Dec 2024 15:57:23 +0800 Subject: [PATCH] =?UTF-8?q?:new:=20=E6=9F=A5=E7=9C=8B=E5=92=8C=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E7=9B=98=E7=82=B9=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../material/ApplyFormController.java | 78 +++++++++++++++---- .../ims/dto/response/ComparisonResDTO.java | 28 +++++++ .../ims/dto/response/StockDetailInfo.java | 36 +++++++++ .../ims/entity/material/ApplyForm.java | 1 + .../StocktakingScanExceptionalData.java | 18 ++++- .../StocktakingScanExceptionalDataMapper.java | 6 +- ...StocktakingScanExceptionalDataService.java | 3 + ...ktakingScanExceptionalDataServiceImpl.java | 8 ++ .../StocktakingScanExceptionalDataMapper.xml | 40 ++++++++++ .../StocktakingScanExceptionalDataMapper.xml | 12 +++ 10 files changed, 212 insertions(+), 18 deletions(-) create mode 100644 src/main/java/tech/riemann/ims/dto/response/ComparisonResDTO.java create mode 100644 src/main/java/tech/riemann/ims/dto/response/StockDetailInfo.java create mode 100644 src/main/resources/mapper/StocktakingScanExceptionalDataMapper.xml diff --git a/src/main/java/tech/riemann/ims/controller/platform/material/ApplyFormController.java b/src/main/java/tech/riemann/ims/controller/platform/material/ApplyFormController.java index fb26961..5edc648 100644 --- a/src/main/java/tech/riemann/ims/controller/platform/material/ApplyFormController.java +++ b/src/main/java/tech/riemann/ims/controller/platform/material/ApplyFormController.java @@ -13,6 +13,8 @@ import org.springframework.web.bind.annotation.*; import tech.riemann.ims.dto.request.ApplyInfo; import tech.riemann.ims.dto.request.AuditApplyInfo; import tech.riemann.ims.dto.response.ApplyDTO; +import tech.riemann.ims.dto.response.ComparisonResDTO; +import tech.riemann.ims.dto.response.StockDetailInfo; import tech.riemann.ims.entity.material.*; import tech.riemann.ims.enums.*; import tech.riemann.ims.service.material.*; @@ -63,7 +65,7 @@ public class ApplyFormController { @Parameter(description = "审核状态") @RequestParam(name = "reviewResults", required = false) List reviewResults) { return applyFormService.page(Page.of(page, size), Wrappers.lambdaQuery() .eq(auditType != null, ApplyForm::getAuditType, auditType) - .eq(ApplyForm::getType, ApplyTypeEnum.AUDIT) + .eq(ApplyForm::getType, ApplyTypeEnum.AUDIT) .eq(taker != null, ApplyForm::getTaker, taker) .eq(createDate != null, ApplyForm::getCreatedTime, createDate) .in(reviewResults != null && !reviewResults.isEmpty(), ApplyForm::getReviewResult, reviewResults) @@ -109,7 +111,7 @@ public class ApplyFormController { if (applyType == ApplyTypeEnum.PURCHASE_RECEIPT) { // 新增物料 - if(!applyInfo.getDetailList().isEmpty()){ + if (!applyInfo.getDetailList().isEmpty()) { applyInfo.getDetailList().forEach(detail -> { detail.setApplyId(applyInfo.getApplyForm().getId()); detail.setStatus(StockStatusEnum.IN); @@ -127,7 +129,7 @@ public class ApplyFormController { )); } else if (applyType == ApplyTypeEnum.LOAN_OUT) { //修改物料状态 - if(!applyInfo.getDetailList().isEmpty()){ + if (!applyInfo.getDetailList().isEmpty()) { applyInfo.getDetailList().forEach(detail -> materialStockDetailService.update(Wrappers.lambdaUpdate() .set(MaterialStockDetail::getStatus, StockStatusEnum.OUT) .eq(MaterialStockDetail::getBarcode, detail.getBarcode()))); @@ -142,7 +144,7 @@ public class ApplyFormController { )); } else if (applyType == ApplyTypeEnum.RETURN_RECEIPT) { //修改物料状态 - if(!applyInfo.getDetailList().isEmpty()){ + if (!applyInfo.getDetailList().isEmpty()) { applyInfo.getDetailList().forEach(detail -> materialStockDetailService.update(Wrappers.lambdaUpdate() .set(MaterialStockDetail::getStatus, StockStatusEnum.IN) .eq(MaterialStockDetail::getBarcode, detail.getBarcode()))); @@ -175,24 +177,70 @@ public class ApplyFormController { .quantity(material.getStock()) .build())); } + @PostMapping("scan-data/{applyId}") @Operation(summary = "提交盘点扫码数据") @Transactional(rollbackFor = Exception.class) public void saveScanData(@Parameter(description = "扫码数据列表") @RequestBody List scanData, - @Parameter(description = "申请单ID") @PathVariable(name = "applyId") Long applyId){ + @Parameter(description = "申请单ID") @PathVariable(name = "applyId") Long applyId) { //保存扫码数据 stocktakingScanDetailService.saveBatch(scanData); //修改状态 applyFormService.update(Wrappers.lambdaUpdate() - .set(ApplyForm::getReviewResult, ReviewResultEnum.WAIT_REVIEW) - .eq(ApplyForm::getId, applyId)); - new Thread(() -> { - comparisonData(scanData, applyId); - }).start(); + .set(ApplyForm::getReviewResult, ReviewResultEnum.WAIT_SUBMIT) + .eq(ApplyForm::getId, applyId)); + new Thread(() -> comparisonData(scanData, applyId)).start(); + } + + @GetMapping("comparison-result/{applyId}") + @Operation(summary = "获取盘点结果数据") + public ComparisonResDTO getComparisonRes(@Parameter(description = "申请单ID") @PathVariable(name = "applyId") String applyId) { + List applyDetails = applyDetailService.list(Wrappers.lambdaQuery().eq(ApplyDetail::getApplyId, applyId)); + List materialIds = applyDetails.stream().map(ApplyDetail::getMaterialId).toList(); + + List stockDetails = materialStockDetailService.list(Wrappers.lambdaQuery().in(MaterialStockDetail::getMaterialId, materialIds)); + Map stockMap = stockDetails.stream().collect(Collectors.groupingBy(MaterialStockDetail::getMaterialId, Collectors.counting())); + + List scanDetails = stocktakingScanDetailService.list(Wrappers.lambdaQuery().eq(StocktakingScanDetail::getApplyId, applyId)); + Map scanMap = scanDetails.stream().collect(Collectors.groupingBy(StocktakingScanDetail::getMaterialId, Collectors.counting())); + + List infoList = new ArrayList<>(); + materialIds.forEach(id -> { + Material material = materialService.getById(id); + infoList.add(StockDetailInfo.builder() + .materialId(material.getId()) + .materialName(material.getName()) + .materialCode(material.getCode()) + .stockTotal(material.getStock()) + .stockTotalScan(stockMap.getOrDefault(id, 0L)) + .stockReal(scanMap.getOrDefault(id, 0L)) + .build()); + }); + + List dataList = stocktakingScanExceptionalDataService.selectData(applyId); + + return ComparisonResDTO.builder() + .details(infoList) + .exceptionalData(dataList) + .build(); + } + + @PutMapping("handle-exceptional-data/{applyId}") + @Operation(summary = "处理盘点异常数据") + public void updateReviewResult(@Parameter(description = "申请单ID") @PathVariable(name = "applyId") String applyId, + @Parameter(description = "异常数据列表") @RequestBody List dataList) { + dataList.forEach(data -> stocktakingScanExceptionalDataService.update(Wrappers.lambdaUpdate() + .eq(StocktakingScanExceptionalData::getId, data.getId()) + .set(StocktakingScanExceptionalData::getExceptionHandle, data.getExceptionHandle()) + .set(StocktakingScanExceptionalData::getRemark, data.getRemark()))); + applyFormService.update(Wrappers.lambdaUpdate() + .set(ApplyForm::getReviewResult, ReviewResultEnum.WAIT_REVIEW) + .eq(ApplyForm::getId, applyId)); + } // 比较数据 生成差异数据 - public void comparisonData(List scanData, Long applyId){ + public void comparisonData(List scanData, Long applyId) { //生成map比较 Map> scanMap = scanData.stream().collect(Collectors.groupingBy(StocktakingScanDetail::getMaterialId, Collectors.mapping(StocktakingScanDetail::getBarcode, Collectors.toList()))); @@ -208,15 +256,17 @@ public class ApplyFormController { // 扫码和库存都存在,但是库存的状态不对 exceptionalDataList.add(StocktakingScanExceptionalData.builder() .barcode(detail.getBarcode()) + .applyId(applyId) .materialId(detail.getMaterialId()) .exceptionReason(StocktakingExceptonalStatusEnum.SOCK_OUT_BUT_SCAN_EXIST) .build()); } - if(!scanList.contains(detail.getBarcode()) && detail.getStatus() == StockStatusEnum.IN){ + if (!scanList.contains(detail.getBarcode()) && detail.getStatus() == StockStatusEnum.IN) { //库房存在,但扫码不存在 exceptionalDataList.add(StocktakingScanExceptionalData.builder() .barcode(detail.getBarcode()) .materialId(detail.getMaterialId()) + .applyId(applyId) .exceptionReason(StocktakingExceptonalStatusEnum.SOCK_IN_BUT_SCAN_NOT_EXIST) .build()); } @@ -228,6 +278,7 @@ public class ApplyFormController { exceptionalDataList.add(StocktakingScanExceptionalData.builder() .barcode(barcode) .materialId(k) + .applyId(applyId) .exceptionReason(StocktakingExceptonalStatusEnum.SOCK_NOT_EXIST_BUT_SCAN_EXIST) .build()); } @@ -236,11 +287,12 @@ public class ApplyFormController { // 保存差异数据 stocktakingScanExceptionalDataService.saveBatch(exceptionalDataList); } + // 盘点物料库存实际数据 private Map> getStockMap(Long applyId) { ApplyForm applyForm = applyFormService.getById(applyId); List materialIds = new ArrayList<>(); - if(applyForm.getAuditType() == AuditTypeEnum.PARTIAL){ + if (applyForm.getAuditType() == AuditTypeEnum.PARTIAL) { // 部分盘点 List applyDetails = applyDetailService.list(Wrappers.lambdaQuery().eq(ApplyDetail::getApplyId, applyId)); materialIds = applyDetails.stream().map(ApplyDetail::getMaterialId).toList(); diff --git a/src/main/java/tech/riemann/ims/dto/response/ComparisonResDTO.java b/src/main/java/tech/riemann/ims/dto/response/ComparisonResDTO.java new file mode 100644 index 0000000..2c0b22c --- /dev/null +++ b/src/main/java/tech/riemann/ims/dto/response/ComparisonResDTO.java @@ -0,0 +1,28 @@ +package tech.riemann.ims.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import tech.riemann.ims.entity.material.StocktakingScanExceptionalData; + +import java.util.List; + +/** + * @author mayong + * @since 2024/12/8 19:02 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ComparisonResDTO { + + @Schema(description = "差异数据") + private List exceptionalData; + + @Schema(description = "库存明细") + private List details; + +} diff --git a/src/main/java/tech/riemann/ims/dto/response/StockDetailInfo.java b/src/main/java/tech/riemann/ims/dto/response/StockDetailInfo.java new file mode 100644 index 0000000..488e977 --- /dev/null +++ b/src/main/java/tech/riemann/ims/dto/response/StockDetailInfo.java @@ -0,0 +1,36 @@ +package tech.riemann.ims.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author mayong + * @since 2024/12/8 19:08 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class StockDetailInfo { + + @Schema(description = "物料名称") + private Long materialId; + + @Schema(description = "物料编码") + private String materialCode; + + @Schema(description = "物料名称") + private String materialName; + + @Schema(description = "在存总数(物料表)") + private Integer stockTotal; + + @Schema(description = "实际库存(明细数据中统计来的)") + private Long stockReal; + + @Schema(description = "扫码数量") + private Long stockTotalScan; +} diff --git a/src/main/java/tech/riemann/ims/entity/material/ApplyForm.java b/src/main/java/tech/riemann/ims/entity/material/ApplyForm.java index e5d4b31..23e10f5 100644 --- a/src/main/java/tech/riemann/ims/entity/material/ApplyForm.java +++ b/src/main/java/tech/riemann/ims/entity/material/ApplyForm.java @@ -105,6 +105,7 @@ public class ApplyForm extends IdBaseEntity { @Schema(description = "处理摘要", requiredMode = Schema.RequiredMode.NOT_REQUIRED) @TableField("af_exception_handle") + @Column("af_exception_handle") @Comment("处理摘要") @ColDefine(type = ColType.VARCHAR, notNull = false, width = 128, precision = 0) diff --git a/src/main/java/tech/riemann/ims/entity/material/StocktakingScanExceptionalData.java b/src/main/java/tech/riemann/ims/entity/material/StocktakingScanExceptionalData.java index 4df123d..15e47b5 100644 --- a/src/main/java/tech/riemann/ims/entity/material/StocktakingScanExceptionalData.java +++ b/src/main/java/tech/riemann/ims/entity/material/StocktakingScanExceptionalData.java @@ -11,14 +11,13 @@ import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import lombok.experimental.FieldNameConstants; import lombok.experimental.SuperBuilder; -import org.nutz.dao.entity.annotation.ColDefine; -import org.nutz.dao.entity.annotation.Column; -import org.nutz.dao.entity.annotation.Comment; -import org.nutz.dao.entity.annotation.Table; +import org.nutz.dao.entity.annotation.*; import tech.riemann.ims.entity.IdBaseEntity; import tech.riemann.ims.enums.HandleEnum; import tech.riemann.ims.enums.StocktakingExceptonalStatusEnum; +import java.io.Serial; + /** * 扫码盘点异常数据表 * @@ -39,6 +38,7 @@ import tech.riemann.ims.enums.StocktakingExceptonalStatusEnum; @Schema(name = "StocktakingScanExceptionalData", description = "扫码盘点异常数据表") public class StocktakingScanExceptionalData extends IdBaseEntity{ + @Serial private static final long serialVersionUID = 1L; @Schema(description = "申请单id", requiredMode = RequiredMode.NOT_REQUIRED) @@ -55,6 +55,9 @@ public class StocktakingScanExceptionalData extends IdBaseEntity{ @ColDefine(notNull = false, width = 10, precision = 0) private Long materialId; + @TableField(exist = false) + private String materialName; + @Schema(description = "条码", requiredMode = RequiredMode.NOT_REQUIRED) @TableField("s_barcode") @Column("s_barcode") @@ -75,4 +78,11 @@ public class StocktakingScanExceptionalData extends IdBaseEntity{ @Comment("异常处理") @ColDefine(notNull = false, width = 128, precision = 0) private HandleEnum exceptionHandle; + + @Schema(description = "备注", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("s_remark") + @Column("s_remark") + @Comment("备注") + @ColDefine(type = ColType.TEXT) + private String remark; } \ No newline at end of file diff --git a/src/main/java/tech/riemann/ims/mapper/material/StocktakingScanExceptionalDataMapper.java b/src/main/java/tech/riemann/ims/mapper/material/StocktakingScanExceptionalDataMapper.java index f7d9ad6..e9e4cb3 100644 --- a/src/main/java/tech/riemann/ims/mapper/material/StocktakingScanExceptionalDataMapper.java +++ b/src/main/java/tech/riemann/ims/mapper/material/StocktakingScanExceptionalDataMapper.java @@ -1,7 +1,10 @@ package tech.riemann.ims.mapper.material; -import tech.riemann.ims.entity.material.StocktakingScanExceptionalData; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import tech.riemann.ims.entity.material.StocktakingScanExceptionalData; + +import java.util.List; /** * 扫码盘点异常数据表 Mapper 接口 @@ -12,4 +15,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; */ public interface StocktakingScanExceptionalDataMapper extends BaseMapper { + List selectData(@Param("applyId") String applyId); } diff --git a/src/main/java/tech/riemann/ims/service/material/IStocktakingScanExceptionalDataService.java b/src/main/java/tech/riemann/ims/service/material/IStocktakingScanExceptionalDataService.java index acad2bc..cacc7e9 100644 --- a/src/main/java/tech/riemann/ims/service/material/IStocktakingScanExceptionalDataService.java +++ b/src/main/java/tech/riemann/ims/service/material/IStocktakingScanExceptionalDataService.java @@ -4,6 +4,8 @@ import tech.riemann.ims.entity.material.StocktakingScanExceptionalData; import com.baomidou.mybatisplus.extension.service.IService; import org.nutz.spring.boot.service.interfaces.IdNameEntityService; +import java.util.List; + /** *

* 扫码盘点异常数据表 服务类 @@ -15,4 +17,5 @@ import org.nutz.spring.boot.service.interfaces.IdNameEntityService; */ public interface IStocktakingScanExceptionalDataService extends IService, IdNameEntityService { + List selectData(String applyId); } diff --git a/src/main/java/tech/riemann/ims/service/material/impl/StocktakingScanExceptionalDataServiceImpl.java b/src/main/java/tech/riemann/ims/service/material/impl/StocktakingScanExceptionalDataServiceImpl.java index fee6027..0664689 100644 --- a/src/main/java/tech/riemann/ims/service/material/impl/StocktakingScanExceptionalDataServiceImpl.java +++ b/src/main/java/tech/riemann/ims/service/material/impl/StocktakingScanExceptionalDataServiceImpl.java @@ -10,6 +10,8 @@ import lombok.RequiredArgsConstructor; import org.nutz.dao.Dao; import org.springframework.stereotype.Service; +import java.util.List; + /** *

* 扫码盘点异常数据表 服务实现类 @@ -24,6 +26,7 @@ import org.springframework.stereotype.Service; public class StocktakingScanExceptionalDataServiceImpl extends ServiceImpl implements IStocktakingScanExceptionalDataService { private final Dao dao; + private final StocktakingScanExceptionalDataMapper stocktakingScanExceptionalDataMapper; /** * @return @@ -42,4 +45,9 @@ public class StocktakingScanExceptionalDataServiceImpl extends ServiceImpl getEntityType() { return StocktakingScanExceptionalData.class; } + + @Override + public List selectData(String applyId) { + return stocktakingScanExceptionalDataMapper.selectData(applyId); + } } diff --git a/src/main/resources/mapper/StocktakingScanExceptionalDataMapper.xml b/src/main/resources/mapper/StocktakingScanExceptionalDataMapper.xml new file mode 100644 index 0000000..846a5aa --- /dev/null +++ b/src/main/resources/mapper/StocktakingScanExceptionalDataMapper.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + id, + created_time, + updated_time, + created_by, + updated_by, + s_apply_id, s_material_id, s_barcode, s_exception_reason, s_exception_handle + + + + \ No newline at end of file diff --git a/src/main/resources/mapper_/StocktakingScanExceptionalDataMapper.xml b/src/main/resources/mapper_/StocktakingScanExceptionalDataMapper.xml index c8fbbd8..22f113b 100644 --- a/src/main/resources/mapper_/StocktakingScanExceptionalDataMapper.xml +++ b/src/main/resources/mapper_/StocktakingScanExceptionalDataMapper.xml @@ -14,6 +14,7 @@ + @@ -24,4 +25,15 @@ updated_by, s_apply_id, s_material_id, s_barcode, s_exception_reason, s_exception_handle + + \ No newline at end of file