Merge remote-tracking branch 'origin/test' into test

This commit is contained in:
FCL
2026-03-09 11:21:02 +08:00
7 changed files with 104 additions and 76 deletions

View File

@@ -48,7 +48,7 @@ public class MaterialInventoryInboundController implements BusinessControllerMar
return success(materialInventoryInboundService.createMaterialInventoryInbound(createReqVO)); return success(materialInventoryInboundService.createMaterialInventoryInbound(createReqVO));
} }
@DeleteMapping("/delete") // @DeleteMapping("/delete")
@Operation(summary = "删除入库") @Operation(summary = "删除入库")
@Parameter(name = "id", description = "编号", required = true) @Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('qms:material-inventory-inbound:delete')") @PreAuthorize("@ss.hasPermission('qms:material-inventory-inbound:delete')")
@@ -57,7 +57,7 @@ public class MaterialInventoryInboundController implements BusinessControllerMar
return success(true); return success(true);
} }
@DeleteMapping("/delete-list") // @DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true) @Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除入库") @Operation(summary = "批量删除入库")
@PreAuthorize("@ss.hasPermission('qms:material-inventory-inbound:delete')") @PreAuthorize("@ss.hasPermission('qms:material-inventory-inbound:delete')")

View File

@@ -53,14 +53,14 @@ public class MaterialBatchRespVO {
@ExcelProperty("批次编号") @ExcelProperty("批次编号")
private String batchNo; private String batchNo;
@Schema(description = "初始总数量")
@ExcelProperty("初始总数量")
private BigDecimal initialQuantity;
@Schema(description = "总数量") @Schema(description = "总数量")
@ExcelProperty("总数量") @ExcelProperty("总数量")
private BigDecimal inboundQuantity; private BigDecimal inboundQuantity;
@Schema(description = "可用数量")
@ExcelProperty("可用数量")
private BigDecimal remaineQuantity;
@Schema(description = "退货数量") @Schema(description = "退货数量")
@ExcelProperty("退货数量") @ExcelProperty("退货数量")
private BigDecimal returnQuantity; private BigDecimal returnQuantity;

View File

@@ -48,16 +48,16 @@ public class MaterialBatchDO extends BusinessBaseDO {
*/ */
@TableField("BAT_NO") @TableField("BAT_NO")
private String batchNo; private String batchNo;
/**
* 初始总数量
*/
@TableField("INIT_QTY")
private BigDecimal initialQuantity;
/** /**
* 总数量 * 总数量
*/ */
@TableField("INB_QTY") @TableField("INB_QTY")
private BigDecimal inboundQuantity; private BigDecimal inboundQuantity;
/**
* 可用数量
*/
@TableField("RMNE_QTY")
private BigDecimal remaineQuantity;
/** /**
* 退货数量 * 退货数量
*/ */
@@ -73,6 +73,11 @@ public class MaterialBatchDO extends BusinessBaseDO {
*/ */
@TableField("INB_END_QTY") @TableField("INB_END_QTY")
private BigDecimal inboundEndQuantity; private BigDecimal inboundEndQuantity;
/**
* 检定/校准数量
*/
@TableField("VRFN_QTY")
private BigDecimal verificationQuantity;
/** /**
* 锁定数量 * 锁定数量
*/ */

View File

@@ -101,7 +101,7 @@ public interface MaterialBatchService {
* *
* @param gongDO 批次工段信息 * @param gongDO 批次工段信息
*/ */
void updateMaterialBatchInbEndQty(MaterialBatchDO gongDO); void updateById(MaterialBatchDO gongDO);
/** /**
* 更新批次工段验收状态 * 更新批次工段验收状态
@@ -174,4 +174,12 @@ public interface MaterialBatchService {
* @param lockType 锁定类型 * @param lockType 锁定类型
*/ */
void lockBatchVerifyCalibrateCount(List<MaterialLifecycleDetailDO> batches, LockType lockType); void lockBatchVerifyCalibrateCount(List<MaterialLifecycleDetailDO> batches, LockType lockType);
/**
* 更新批次检定数量
*
* @param batches 批次信息
* @param adjustType 调整类型
*/
void updateBatchVerifyCalibrateCount(List<MaterialLifecycleDetailDO> batches, AdjustType adjustType);
} }

View File

@@ -1,8 +1,6 @@
package com.zt.plat.module.qms.resource.material.service; package com.zt.plat.module.qms.resource.material.service;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zt.plat.framework.common.exception.ServiceException; import com.zt.plat.framework.common.exception.ServiceException;
import com.zt.plat.framework.common.pojo.CommonResult; import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.pojo.PageResult;
@@ -11,7 +9,6 @@ import com.zt.plat.framework.security.core.LoginUser;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils; import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.module.qms.common.dic.controller.vo.DictionaryBusinessRespVO; import com.zt.plat.module.qms.common.dic.controller.vo.DictionaryBusinessRespVO;
import com.zt.plat.module.qms.common.dic.service.DictionaryBusinessService; import com.zt.plat.module.qms.common.dic.service.DictionaryBusinessService;
import com.zt.plat.module.qms.core.code.SequenceUtil;
import com.zt.plat.module.qms.core.constant.CommonConstant; import com.zt.plat.module.qms.core.constant.CommonConstant;
import com.zt.plat.module.qms.core.constant.DataTypeConstant; import com.zt.plat.module.qms.core.constant.DataTypeConstant;
import com.zt.plat.module.qms.resource.material.constant.MaterialConstants; import com.zt.plat.module.qms.resource.material.constant.MaterialConstants;
@@ -22,9 +19,7 @@ import com.zt.plat.module.qms.resource.material.controller.vo.MaterialInventoryI
import com.zt.plat.module.qms.resource.material.dal.dataobject.*; import com.zt.plat.module.qms.resource.material.dal.dataobject.*;
import com.zt.plat.module.qms.resource.material.dal.mapper.MaterialInventoryInboundMapper; import com.zt.plat.module.qms.resource.material.dal.mapper.MaterialInventoryInboundMapper;
import com.zt.plat.module.qms.resource.material.enums.MaterialAcceptStatus; import com.zt.plat.module.qms.resource.material.enums.MaterialAcceptStatus;
import com.zt.plat.module.qms.resource.material.enums.MaterialInfomationOrigin;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.jspecify.annotations.NonNull;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -32,7 +27,6 @@ import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -89,29 +83,14 @@ public class MaterialInventoryInboundServiceImpl implements MaterialInventoryInb
if (!MaterialAcceptStatus.accepted.name().equals(gongDO.getAcceptanceStatus())) if (!MaterialAcceptStatus.accepted.name().equals(gongDO.getAcceptanceStatus()))
throw new ServiceException(1_032_160_000, "工段未验收,不能入库"); throw new ServiceException(1_032_160_000, "工段未验收,不能入库");
// 2. 计算已入库总量并校验 // 2. 校验入库数量不超过工段可用数量(考虑锁定数量)
List<MaterialInventoryInboundDO> inboundDOS = materialInventoryInboundMapper.selectList(Wrappers.lambdaQuery(MaterialInventoryInboundDO.class) BigDecimal availableQuantity = gongDO.getRemaineQuantity().subtract(gongDO.getLockQuantity());
.eq(MaterialInventoryInboundDO::getGongduanId, gongduanId)); if (reqQuantity.compareTo(availableQuantity) > 0)
BigDecimal existingQuantity = inboundDOS.stream() throw new ServiceException(1_032_160_000, "入库数量不能大于批次工段可用数量");
.map(MaterialInventoryInboundDO::getQuantity)
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal totalQuantity = existingQuantity.add(reqQuantity);
// 校验入库数量不超过工段未入库数量
if (totalQuantity.compareTo(gongDO.getInboundQuantity()) > 0) {
throw new ServiceException(1_032_160_000, "入库数量不能大于批次工段未入库数量");
}
// 校验入库数量不超过工段可用数量(考虑锁定数量)
if (gongDO.getLockQuantity().compareTo(BigDecimal.ZERO) > 0) {
BigDecimal availableQuantity = gongDO.getInboundQuantity().subtract(gongDO.getLockQuantity());
if (totalQuantity.compareTo(availableQuantity) > 0) {
throw new ServiceException(1_032_160_000, "入库数量不能大于批次工段可用数量");
}
}
// 3.保存入库记录 // 3.保存入库记录
MaterialInventoryInboundDO inbound = saveInbound(createReqVO, gongDO); MaterialInventoryInboundDO inbound = getInbound(createReqVO, gongDO);
materialInventoryInboundMapper.insert(inbound);
// 4.生成物料实例 // 4.生成物料实例
Long productId = gongDO.getProductId(); Long productId = gongDO.getProductId();
MaterialProductDO product = materialProductService.getMaterialProduct(productId); MaterialProductDO product = materialProductService.getMaterialProduct(productId);
@@ -124,9 +103,14 @@ public class MaterialInventoryInboundServiceImpl implements MaterialInventoryInb
List<MaterialInfomationDO> infomationDOS = materialInfomationService.saveMaterialInfomationsByBatInb(locationId, reqQuantity, gongduanId, product, batch); List<MaterialInfomationDO> infomationDOS = materialInfomationService.saveMaterialInfomationsByBatInb(locationId, reqQuantity, gongduanId, product, batch);
// 5.保存入库明细 // 5.保存入库明细
materialInventoryInboundDetailService.saveInboundDetails(infomationDOS, inbound, batchId, gongduanId); materialInventoryInboundDetailService.saveInboundDetails(infomationDOS, inbound, batchId, gongduanId);
// 更新工段已入库数量 // 更新工段已入库数量和可用数量
gongDO.setInboundEndQuantity(gongDO.getInboundEndQuantity().add(reqQuantity)); gongDO.setInboundEndQuantity(gongDO.getInboundEndQuantity().add(reqQuantity));
materialBatchService.updateMaterialBatchInbEndQty(gongDO); gongDO.setRemaineQuantity(gongDO.getRemaineQuantity().subtract(reqQuantity));
materialBatchService.updateById(gongDO);
// 更新批次已入库数量和可用数量
batch.setInboundEndQuantity(batch.getInboundEndQuantity().add(reqQuantity));
batch.setRemaineQuantity(batch.getRemaineQuantity().subtract(reqQuantity));
materialBatchService.updateById(batch);
// 更新物料大类预警级别 // 更新物料大类预警级别
materialProductService.updateMaterialProductAlarmLevel(Collections.singletonList(productId)); materialProductService.updateMaterialProductAlarmLevel(Collections.singletonList(productId));
// 返回 // 返回
@@ -137,7 +121,7 @@ public class MaterialInventoryInboundServiceImpl implements MaterialInventoryInb
return respVO; return respVO;
} }
private MaterialInventoryInboundDO saveInbound(MaterialInventoryInboundSaveReqVO createReqVO, MaterialBatchDO gongDO) { private MaterialInventoryInboundDO getInbound(MaterialInventoryInboundSaveReqVO createReqVO, MaterialBatchDO gongDO) {
MaterialInventoryInboundDO inbound = BeanUtils.toBean(createReqVO, MaterialInventoryInboundDO.class); MaterialInventoryInboundDO inbound = BeanUtils.toBean(createReqVO, MaterialInventoryInboundDO.class);
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser(); LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
if (loginUser == null) throw exception(USER_NOT_EXISTS); if (loginUser == null) throw exception(USER_NOT_EXISTS);
@@ -146,7 +130,6 @@ public class MaterialInventoryInboundServiceImpl implements MaterialInventoryInb
.setApplyDepartment(loginUser.getVisitDeptName()).setApplyDepartmentId(loginUser.getVisitDeptId()) .setApplyDepartment(loginUser.getVisitDeptName()).setApplyDepartmentId(loginUser.getVisitDeptId())
.setApplyTime(LocalDateTime.now()) .setApplyTime(LocalDateTime.now())
.setRemark(gongDO.getRemark()); .setRemark(gongDO.getRemark());
materialInventoryInboundMapper.insert(inbound);
return inbound; return inbound;
} }

View File

@@ -219,12 +219,12 @@ public class MaterialLifecycleServiceImpl implements MaterialLifecycleService ,
// 删除原来的明细 // 删除原来的明细
materialLifecycleDetailService.deleteLifecycleDetailListByLfcId(reqId); materialLifecycleDetailService.deleteLifecycleDetailListByLfcId(reqId);
List<MaterialLifecycleDetailDO> oriDetailList = materialLifecycleDetailService.getDetailListByLfcId(reqId); List<MaterialLifecycleDetailDO> oriDetailList = materialLifecycleDetailService.getDetailListByLfcId(reqId);
// 退换货 // 释放原来退换货资源
boolean isReturnExchangeMaterial = MaterialFlowType.return_material.getName().equals(mtrlLfc.getBusinessType()) boolean isReturnExchangeMaterial = MaterialFlowType.return_material.getName().equals(mtrlLfc.getBusinessType())
|| MaterialFlowType.exchange_material.getName().equals(mtrlLfc.getBusinessType()); || MaterialFlowType.exchange_material.getName().equals(mtrlLfc.getBusinessType());
if (isReturnExchangeMaterial) if (isReturnExchangeMaterial)
lockReturnExchangeResources(oriDetailList, LockType.unlock); lockReturnExchangeResources(oriDetailList, LockType.unlock);
// 物料检定 // 释放原理啊物料检定资源
boolean isVerifyCalibrate = MaterialFlowType.verify_calibrate.getName().equals(mtrlLfc.getBusinessType()); boolean isVerifyCalibrate = MaterialFlowType.verify_calibrate.getName().equals(mtrlLfc.getBusinessType());
if (isVerifyCalibrate) lockVerifyCalibrateResources(oriDetailList, LockType.unlock); if (isVerifyCalibrate) lockVerifyCalibrateResources(oriDetailList, LockType.unlock);
List<MaterialLifecycleDetailDO> detailDOS = getLifecycleDetailDOSByBusinessType(detailList, mtrlLfc); List<MaterialLifecycleDetailDO> detailDOS = getLifecycleDetailDOSByBusinessType(detailList, mtrlLfc);
@@ -311,9 +311,9 @@ public class MaterialLifecycleServiceImpl implements MaterialLifecycleService ,
for (MaterialLifecycleDetailSaveReqVO reqDetail : reqDetails) { for (MaterialLifecycleDetailSaveReqVO reqDetail : reqDetails) {
MaterialBatchDO batchDO = batchDOMapById.get(reqDetail.getBatchId()); MaterialBatchDO batchDO = batchDOMapById.get(reqDetail.getBatchId());
// 可用数量 // 可用数量
BigDecimal availableQuantity = batchDO.getInboundQuantity().subtract(batchDO.getLockQuantity()); BigDecimal remaineQuantity = batchDO.getRemaineQuantity();
if (reqDetail.getInfluenceCount().compareTo(availableQuantity) > 0) if (reqDetail.getInfluenceCount().compareTo(remaineQuantity) > 0)
throw new ServiceException(1_032_160_000, String.format("检定数量超过了批次【%s】可用数量【%s】", batchDO.getBatchNo(), availableQuantity)); throw new ServiceException(1_032_160_000, String.format("检定数量超过了批次【%s】可用数量【%s】", batchDO.getBatchNo(), remaineQuantity));
} }
return reqDetails.stream().map(detail -> { return reqDetails.stream().map(detail -> {
@@ -364,14 +364,9 @@ public class MaterialLifecycleServiceImpl implements MaterialLifecycleService ,
Map<Long, MaterialBatchDO> gongsMapById = gongs.stream().collect(Collectors.toMap(MaterialBatchDO::getId, Function.identity())); Map<Long, MaterialBatchDO> gongsMapById = gongs.stream().collect(Collectors.toMap(MaterialBatchDO::getId, Function.identity()));
for (MaterialLifecycleDetailSaveReqVO reqGong : reqGongs) { for (MaterialLifecycleDetailSaveReqVO reqGong : reqGongs) {
MaterialBatchDO gong = gongsMapById.get(reqGong.getBatchGongduanId()); MaterialBatchDO gong = gongsMapById.get(reqGong.getBatchGongduanId());
BigDecimal inboundQuantity = gong.getInboundQuantity(); BigDecimal remaine = gong.getRemaineQuantity();
BigDecimal returnQuantity = gong.getReturnQuantity();
BigDecimal replaceQuantity = gong.getReplaceQuantity();
BigDecimal inboundEndQuantity = gong.getInboundEndQuantity();
BigDecimal remaine = inboundQuantity.subtract(returnQuantity).subtract(replaceQuantity).subtract(inboundEndQuantity);
if (reqGong.getInfluenceCount().compareTo(remaine) > 0) if (reqGong.getInfluenceCount().compareTo(remaine) > 0)
throw new ServiceException(1_032_160_000, String.format("退换货数量超过了批次工段【%s-%s】剩余", throw new ServiceException(1_032_160_000, String.format("退换货数量超过了批次工段【%s-%s】可用数",
gongsMapById.get(reqGong.getBatchGongduanId()).getBatchNo(), gongsMapById.get(reqGong.getBatchGongduanId()).getBatchNo(),
gongsMapById.get(reqGong.getBatchGongduanId()).getAssignDepartmentName())); gongsMapById.get(reqGong.getBatchGongduanId()).getAssignDepartmentName()));
} }
@@ -393,9 +388,9 @@ public class MaterialLifecycleServiceImpl implements MaterialLifecycleService ,
} }
Map<Long, MaterialBatchDO> batchesMapById = batches.stream().collect(Collectors.toMap(MaterialBatchDO::getId, Function.identity())); Map<Long, MaterialBatchDO> batchesMapById = batches.stream().collect(Collectors.toMap(MaterialBatchDO::getId, Function.identity()));
for (MaterialLifecycleDetailSaveReqVO reqBatch : reqBatches) { for (MaterialLifecycleDetailSaveReqVO reqBatch : reqBatches) {
BigDecimal inboundQuantity = batchesMapById.get(reqBatch.getBatchId()).getInboundQuantity(); BigDecimal remaineQuantity = batchesMapById.get(reqBatch.getBatchId()).getRemaineQuantity();
if (reqBatch.getInfluenceCount().compareTo(inboundQuantity) > 0) if (reqBatch.getInfluenceCount().compareTo(remaineQuantity) > 0)
throw new ServiceException(1_032_160_000, String.format("退换货数量超过了批次【%s】数量", batchesMapById.get(reqBatch.getBatchId()).getBatchNo())); throw new ServiceException(1_032_160_000, String.format("退换货数量超过了批次【%s】可用数量【%s】", batchesMapById.get(reqBatch.getBatchId()).getBatchNo(), remaineQuantity));
} }
} }
@@ -538,11 +533,11 @@ public class MaterialLifecycleServiceImpl implements MaterialLifecycleService ,
case verify_calibrate -> { case verify_calibrate -> {
// 检定需要发起检定流程 // 检定需要发起检定流程
this.createProcessInstance(lifecycleDO); this.createProcessInstance(lifecycleDO);
// TODO 释放锁定的资源 // 释放锁定的资源
List<MaterialLifecycleDetailDO> detailList = materialLifecycleDetailService.getDetailListByLfcId(id); List<MaterialLifecycleDetailDO> detailList = materialLifecycleDetailService.getDetailListByLfcId(id);
this.lockVerifyCalibrateResources(detailList, LockType.unlock); this.lockVerifyCalibrateResources(detailList, LockType.unlock);
// TODO 更新批次数量 // 更新批次相关数量
// this.updateVerifyCalibrateResources(detailList, AdjustType.add); this.updateVerifyCalibrateResources(detailList, AdjustType.add);
} }
} }
@@ -551,6 +546,15 @@ public class MaterialLifecycleServiceImpl implements MaterialLifecycleService ,
return true; return true;
} }
private void updateVerifyCalibrateResources(List<MaterialLifecycleDetailDO> detailList, AdjustType adjustType) {
// 批次
List<MaterialLifecycleDetailDO> batches = detailList.stream().filter(detail -> detail.getBatchId() != null).toList();
if (CollUtil.isNotEmpty(batches)) {
materialBatchService.updateBatchVerifyCalibrateCount(batches, adjustType);
}
}
@Override @Override
public PageResult<MaterialLifecycleRespVO> getMaterialLifecycleRespVOPage(MaterialLifecyclePageReqVO pageReqVO) { public PageResult<MaterialLifecycleRespVO> getMaterialLifecycleRespVOPage(MaterialLifecyclePageReqVO pageReqVO) {
PageResult<MaterialLifecycleDO> lifecyclePage = getMaterialLifecyclePage(pageReqVO); PageResult<MaterialLifecycleDO> lifecyclePage = getMaterialLifecyclePage(pageReqVO);