From 8f1e9b705c653f97c73f70d4d69de9b7aa5be615 Mon Sep 17 00:00:00 2001 From: yewj Date: Wed, 26 Mar 2025 19:12:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=B9=E9=87=8F=E6=89=AB=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inout/IoCodeTempController.java | 318 +++-- .../glxp/api/dao/basic/UdiRelevanceDao.java | 7 + .../api/req/basic/FilterUdiRelRequest.java | 6 +- .../service/basic/UdiRelevanceService.java | 43 +- .../api/service/inout/AddCoodeService.java | 1175 +++++++++++++++++ .../api/service/inout/IoCodeTempService.java | 68 + src/main/resources/application-dev.yml | 4 +- .../mybatis/mapper/basic/UdiRelevanceDao.xml | 75 ++ 8 files changed, 1577 insertions(+), 119 deletions(-) create mode 100644 src/main/java/com/glxp/api/service/inout/AddCoodeService.java diff --git a/src/main/java/com/glxp/api/controller/inout/IoCodeTempController.java b/src/main/java/com/glxp/api/controller/inout/IoCodeTempController.java index f75bd452c..8a8b9b08f 100644 --- a/src/main/java/com/glxp/api/controller/inout/IoCodeTempController.java +++ b/src/main/java/com/glxp/api/controller/inout/IoCodeTempController.java @@ -48,6 +48,7 @@ import com.glxp.api.util.*; import com.glxp.api.util.udi.FilterUdiUtils; import com.glxp.api.util.udi.UdiCalCountUtil; import com.glxp.api.vo.basic.InvProductNewVo; +import groovy.util.logging.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -57,8 +58,13 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.stream.Collectors; +@lombok.extern.slf4j.Slf4j +@Slf4j @RestController public class IoCodeTempController extends BaseController { @@ -407,6 +413,9 @@ public class IoCodeTempController extends BaseController { } + @Resource + AddCoodeService addCoodeService; + @RepeatSubmit() @AuthRuleAnnotation("") @PostMapping("warehouse/inout/batchAddCode") @@ -417,10 +426,27 @@ public class IoCodeTempController extends BaseController { if (bindingResult.hasErrors()) { return ResultVOUtils.error(ResultEnum.PARAM_VERIFY_FALL, bindingResult.getFieldError().getDefaultMessage()); } + + AuthAdmin authAdmin = getUser(); AddCodeResult addCodeResult = new AddCodeResult(); List codeList = addOrderCodeRequest.getCodeList(); if (CollUtil.isEmpty(codeList)) return ResultVOUtils.error(500, "追溯码不能为空"); + + // 获取第一个码判断类型,如果是药品类型则使用批量处理方法 + if (!codeList.isEmpty()) { + String firstCode = codeList.get(0); + if (firstCode.endsWith("\u001D")) { + firstCode = firstCode.replace("\u001D", ""); + } + UdiEntity firstUdiEntity = FilterUdiUtils.getUdi(firstCode); + if (firstUdiEntity != null && IntUtil.value(firstUdiEntity.getProductType()) == 2) { + // 药品类型,使用批量处理方法 + return addCoodeService.batchProcessDrugCodes(addOrderCodeRequest, authAdmin); + } + } + + // 原有处理逻辑,处理非药品或空列表情况 List vailCodeResultResponses = new ArrayList<>(); Integer groupNumber = getMaxGroupNumber() == null ? 1 : getMaxGroupNumber() + 1; for (String code : codeList) { @@ -451,8 +477,6 @@ public class IoCodeTempController extends BaseController { if (StrUtil.isNotEmpty(addOrderRequest.getSerialNo())) { udiEntity.setSerialNo(addOrderRequest.getSerialNo()); } - - AuthAdmin authAdmin = getUser(); addOrderRequest.setInvCode(authAdmin.getLocInvCode()); if (IntUtil.value(addOrderCodeRequest.getInoutType()) == 2) { addOrderRequest.setAction(ConstantType.SPLIT_RETURN); @@ -1232,15 +1256,22 @@ public class IoCodeTempController extends BaseController { // @Transactional(rollbackFor = Exception.class) public BaseResponse addDrugOrder(AddOrderRequest addOrderRequest, UdiEntity udiEntity, String code, Integer groupNumber) { + long startTime = System.currentTimeMillis(); AddCodeResult addCodeResult = new AddCodeResult(); - InvWarehouseEntity invWarehouseEntity = invWarehouseService.findByInvSubByCode(addOrderRequest.getInvCode()); - UdiRelevanceResponse udiRelevanceResponse = udiRelevanceService.selectByNameCode(udiEntity.getUdi()); + // 检查码是否空 + if (udiEntity == null) { + return ResultVOUtils.error(500, "无效条码"); + } - //批次号校验 - //判断此产品是否开启允许无批次号 - UdiProductEntity udiInfoEntity = udiProductService.findByNameCode(udiEntity.getUdi()); - if (udiInfoEntity == null) { + // 1. 批量查询业务类型和药品信息,减少数据库查询次数 + BasicBussinessTypeEntity bussinessTypeEntity = basicBussinessTypeService.findByAction(addOrderRequest.getAction()); + if (bussinessTypeEntity == null) { + return ResultVOUtils.error(500, "业务类型不存在"); + } + + UdiRelevanceResponse udiRelevanceResponse = udiRelevanceService.selectByNameCode(udiEntity.getUdi()); + if (udiRelevanceResponse == null) { return ResultVOUtils.error(500, "药品字典不存在此产品!"); } @@ -1248,7 +1279,7 @@ public class IoCodeTempController extends BaseController { return ResultVOUtils.error(500, "当前为无码类型产品,无需扫码!"); } - + // 2. 将批次号查询移至此处统一处理 if (StrUtil.isEmpty(udiEntity.getBatchNo())) { IoCodeLostEntity codeLostEntity = codeLostService.findByCode(addOrderRequest.getCode()); if (codeLostEntity != null) { @@ -1257,63 +1288,74 @@ public class IoCodeTempController extends BaseController { udiEntity.setExpireDate(codeLostEntity.getExpireDate()); } } + String orderId = addOrderRequest.getBillNo(); - //过期提醒: - BasicBussinessTypeEntity bussinessTypeEntity = basicBussinessTypeService.findByAction(addOrderRequest.getAction()); + // 3. 合并校验流程,减少方法调用 + // 过期校验 int checkExpire = IntUtil.value(bussinessTypeEntity.getCheckExpire()); - BaseResponse response = checkExpireDate(checkExpire, udiEntity, addOrderRequest); - if (response.getCode() != 20000) { - return response; + if (checkExpire > 0) { + BaseResponse response = checkExpireDate(checkExpire, udiEntity, addOrderRequest); + if (response.getCode() != 20000) { + return response; + } } - //判断层级标识是否正确 + // 层级标识校验 + boolean packLevelValid; if (bussinessTypeEntity.isUse()) { - if (!isPackLevelValid(udiRelevanceResponse.getUseMaxLevel(), IntUtil.value(udiRelevanceResponse.getPackLevel()), udiRelevanceResponse.getUseLevel())) { - return ResultVOUtils.error(500, "当前产品不支持采集该包装层级追溯码!"); - } + packLevelValid = isPackLevelValid(udiRelevanceResponse.getUseMaxLevel(), + IntUtil.value(udiRelevanceResponse.getPackLevel()), + udiRelevanceResponse.getUseLevel()); } else { - if (!isPackLevelValid(udiRelevanceResponse.getDistributeMaxLevel(), IntUtil.value(udiRelevanceResponse.getPackLevel()), udiRelevanceResponse.getDistributeLevel())) { - return ResultVOUtils.error(500, "当前产品不支持采集该包装层级追溯码!"); - } + packLevelValid = isPackLevelValid(udiRelevanceResponse.getDistributeMaxLevel(), + IntUtil.value(udiRelevanceResponse.getPackLevel()), + udiRelevanceResponse.getDistributeLevel()); } + if (!packLevelValid) { + return ResultVOUtils.error(500, "当前产品不支持采集该包装层级追溯码!"); + } - //近效期提醒 + // 近效期提醒 BaseResponse checkResponse = checkIsExpired(udiRelevanceResponse, udiEntity, addOrderRequest, bussinessTypeEntity); if (checkResponse.getCode() == 505) { return checkResponse; } - //------工位上货相关-----校验工位存量是否存在---- + // 工位上货相关校验 BaseResponse handleSplitOutAndSplitReturnResponse = handleSplitOutAndSplitReturn(code, udiEntity, bussinessTypeEntity); if (handleSplitOutAndSplitReturnResponse.getCode() != 20000) { return handleSplitOutAndSplitReturnResponse; } - if (addOrderRequest.getFromCorp() == null || StrUtil.isNotEmpty(addOrderRequest.getSickerAdNum())) { String fromCorp = ioAddInoutService.updateCorp(bussinessTypeEntity, addOrderRequest.getFromCorp(), addOrderRequest.getSickerAdNum()); addOrderRequest.setFromCorp(fromCorp); } - //先生成扫码单据 + + // 4. 优化订单处理流程 + InvWarehouseEntity invWarehouseEntity = invWarehouseService.findByInvSubByCode(addOrderRequest.getInvCode()); IoOrderEntity orderEntity = orderService.findByBillNo(orderId); String inBatch = ""; if (StringUtils.isBlank(orderId) || orderEntity == null) { String orderNo = gennerOrderUtils.createScOrderNo(new OrderNoTypeBean(Constant.SCAN_ORDER + StrUtil.trimToEmpty(bussinessTypeEntity.getPrefix()), "yyyyMMdd")); orderId = orderNo; + inBatch = orderId.substring((Constant.SCAN_ORDER + StrUtil.trimToEmpty(bussinessTypeEntity.getPrefix())).length()); + } else { + inBatch = orderId.substring((Constant.SCAN_ORDER + StrUtil.trimToEmpty(bussinessTypeEntity.getPrefix())).length()); } - inBatch = orderId.substring((Constant.SCAN_ORDER + StrUtil.trimToEmpty(bussinessTypeEntity.getPrefix())).length()); + // 5. 提前获取码信息,减少重复查询 List codeEnttitys = codeTempService.findByOrderId(orderId); IoCodeTempEntity exitLocalEntity = null; IoCodeTempEntity genDetaiEntity = new IoCodeTempEntity(); - List udiRelevanceResponses = null; - - if (codeEnttitys.size() > 0) { + // 6. 优化已存在码的处理逻辑 + if (!codeEnttitys.isEmpty()) { exitLocalEntity = isExitLocal(code, codeEnttitys); if (exitLocalEntity != null) { + // 处理已存在码的情况 if (StrUtil.isEmpty(exitLocalEntity.getSupId()) || exitLocalEntity.getRelId() == null) { return ResultVOUtils.error(500, "当前药品追溯码已存在,且存在异常未处理!"); } @@ -1322,95 +1364,40 @@ public class IoCodeTempController extends BaseController { return ResultVOUtils.error(500, "重复扫码!"); } - udiRelevanceResponses = udiRelevanceService.selectGroupByNameCode(exitLocalEntity.getNameCode(), null); + // 获取udiRelevanceResponses数据,共用前面查询的udiRelevanceResponse + List udiRelevanceResponses = new ArrayList<>(); + udiRelevanceResponses.add(udiRelevanceResponse); + BeanUtils.copyProperties(exitLocalEntity, genDetaiEntity); genDetaiEntity.setCount(1); + // 处理数量计算 if (bussinessTypeEntity.isUse()) { - genDetaiEntity.setReCount(udiCalCountUtil.getUseActCount(udiRelevanceResponses.get(0))); - } else { - genDetaiEntity.setReCount(udiCalCountUtil.getCirActCount(udiRelevanceResponses.get(0))); - } - - exitLocalEntity.setCount(exitLocalEntity.getMyCount() + 1); - - if (bussinessTypeEntity.isUse()) { - exitLocalEntity.setReCount(exitLocalEntity.getMyReCount() * udiCalCountUtil.getUseActCount(udiRelevanceResponses.get(0))); + genDetaiEntity.setReCount(udiCalCountUtil.getUseActCount(udiRelevanceResponse)); + exitLocalEntity.setCount(exitLocalEntity.getMyCount() + 1); + exitLocalEntity.setReCount(exitLocalEntity.getMyReCount() * udiCalCountUtil.getUseActCount(udiRelevanceResponse)); } else { - exitLocalEntity.setReCount(exitLocalEntity.getMyReCount() * udiCalCountUtil.getCirActCount(udiRelevanceResponses.get(0))); + genDetaiEntity.setReCount(udiCalCountUtil.getCirActCount(udiRelevanceResponse)); + exitLocalEntity.setCount(exitLocalEntity.getMyCount() + 1); + exitLocalEntity.setReCount(exitLocalEntity.getMyReCount() * udiCalCountUtil.getCirActCount(udiRelevanceResponse)); } - - //匹配biz + // 匹配biz并缓存结果 IoOrderDetailCodeEntity byRelId = ioOrderDetailCodeService.findByRelNameCode(addOrderRequest.getBillNo(), udiEntity.getUdi(), udiEntity.getBatchNo()); if (byRelId != null) { exitLocalEntity.setBizId(byRelId.getId()); } - - //校验库存 - BaseResponse invRes = null; - if (IntUtil.value(bussinessTypeEntity.getUseDyCount()) == 2) { - if (bussinessTypeEntity.isScanPreIn() && checkDiAttribute(bussinessTypeEntity, udiRelevanceResponse, 2)) { //校验预验收库存 - invRes = checkInvService.checkPreInInv(bussinessTypeEntity, genDetaiEntity, false); - } - if (bussinessTypeEntity.isAdvancePreIn() && checkDiAttribute(bussinessTypeEntity, udiRelevanceResponse, 3)) { //校验寄售库存 - invRes = checkInvService.checkPreInv(bussinessTypeEntity, genDetaiEntity, false); - } - if (bussinessTypeEntity.isVailInv() && checkDiAttribute(bussinessTypeEntity, udiRelevanceResponse, 1)) { - invRes = checkInvService.checkInv(bussinessTypeEntity, genDetaiEntity, false); - } - } else { - if (bussinessTypeEntity.isScanPreIn()) { //校验预验收库存 - invRes = checkInvService.checkPreInInv(bussinessTypeEntity, genDetaiEntity, false); - } else if (bussinessTypeEntity.isAdvancePreIn()) { //校验寄售库存 - invRes = checkInvService.checkPreInv(bussinessTypeEntity, genDetaiEntity, false); - } else { - invRes = checkInvService.checkInv(bussinessTypeEntity, genDetaiEntity, false); - } - } - + // 优化库存校验流程 + BaseResponse invRes = checkInventory(bussinessTypeEntity, udiRelevanceResponse, genDetaiEntity); if (invRes != null) { return invRes; } - if (bussinessTypeEntity.getCheckWebNew() == 1 && bussinessTypeEntity.isCheckEnable()) { - String errMsg = ioCheckInoutService.checkCode(genDetaiEntity); - if (errMsg != null) { - return ResultVOUtils.error(500, errMsg); - } else - codeTempService.updateById(exitLocalEntity); - } else if (bussinessTypeEntity.getCheckWebNew() == 2 && bussinessTypeEntity.isCheckEnable()) { - String errMsg = ioCheckInoutService.checkNoPiCode(genDetaiEntity); - if (errMsg != null) { - return ResultVOUtils.error(500, errMsg); - } else - codeTempService.updateById(exitLocalEntity); - } else { - boolean update = true; - String priceFifo = systemParamConfigService.selectValueByParamKey("price_fifo"); - if (IntUtil.value(priceFifo) > 0) { - if (bussinessTypeEntity.getMainAction().equals(ConstantType.TYPE_OUT)) { - //1.获取当前批次已出库数量 - Integer outCount = invProductServiceNew.selectCountByInBatch(exitLocalEntity.getRelId() + "", exitLocalEntity.getBatchNo(), bussinessTypeEntity, exitLocalEntity.getInBatchNo(), exitLocalEntity.getInvCode(), ConstantType.TYPE_OUT); - //2.获取当前批次入库数量 - Integer inCount = invProductServiceNew.selectCountByInBatch(exitLocalEntity.getRelId() + "", exitLocalEntity.getBatchNo(), bussinessTypeEntity, exitLocalEntity.getInBatchNo(), exitLocalEntity.getInvCode(), ConstantType.TYPE_PUT); - if ((IntUtil.value(inCount) - IntUtil.value(outCount) - IntUtil.value(exitLocalEntity.getReCount())) < 0) { - InvProductNewVo nextInvProduct = invProductServiceNew.selectNextInBatch(bussinessTypeEntity, exitLocalEntity.getRelId() + "", exitLocalEntity.getBatchNo(), exitLocalEntity.getInvCode(), ConstantType.TYPE_PUT, exitLocalEntity.getInBatchNo()); - if (nextInvProduct != null) { - genDetaiEntity.setPrice(nextInvProduct.getPrice()); - genDetaiEntity.setInBatchNo(nextInvProduct.getInBatchNo()); - codeTempService.insert(genDetaiEntity); - update = false; - } - } - - } - } - if (update) { - codeTempService.updateById(exitLocalEntity); - } - + // 优化校验和更新流程 + boolean updated = handleCodeCheckAndUpdate(bussinessTypeEntity, genDetaiEntity, exitLocalEntity, inBatch, codeEnttitys); + if (!updated) { + return ResultVOUtils.error(500, "更新码信息失败"); } } } @@ -1494,11 +1481,11 @@ public class IoCodeTempController extends BaseController { } else if (StrUtil.isNotEmpty(addOrderRequest.getSelectSupId())) { unitFk = addOrderRequest.getSelectSupId(); } - //产品是否禁用 - udiRelevanceResponses = udiRelevanceService.selectGroupByNameCode(codeEnttity.getNameCode(), false); + // 获取产品列表 - 使用前面查询的单个产品 + List productList = Collections.singletonList(udiRelevanceResponse); - if (udiRelevanceResponses.size() >= 1) { + if (productList.size() >= 1) { if (udiRelevanceResponse == null) { return ResultVOUtils.error(500, "该产品信息未维护!"); } else if (!udiRelevanceResponse.getUseDy() && udiRelevanceResponse.getDiType() == ConstantStatus.DITYPE_SYDY) { @@ -1517,18 +1504,19 @@ public class IoCodeTempController extends BaseController { return ResultVOUtils.error(500, bussinessTypeEntity.getName() + "单只允许录入非集采产品!"); } - //计算实际数量 + // 直接使用传入的udiRelevanceResponse计算数量 if (bussinessTypeEntity.isUse()) { - codeEnttity.setReCount(codeEnttity.getMyReCount() + udiCalCountUtil.getUseActCount(udiRelevanceResponses.get(0))); + codeEnttity.setReCount(codeEnttity.getMyReCount() + udiCalCountUtil.getUseActCount(udiRelevanceResponse)); } else { - codeEnttity.setReCount(codeEnttity.getMyReCount() + udiCalCountUtil.getCirActCount(udiRelevanceResponses.get(0))); + codeEnttity.setReCount(codeEnttity.getMyReCount() + udiCalCountUtil.getCirActCount(udiRelevanceResponse)); } - } else if (udiRelevanceResponses.size() == 0) { + } else { if (unitFk == null) return ResultVOUtils.error(500, "耗材字典不存在此产品!"); else return ResultVOUtils.error(500, "当前供应商不存在此配送产品!"); } + if (!(bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_RETURN) || bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_OUT))) { //校验供应商是否配送此产品 BaseResponse corpResponse = checkCorp(codeEnttity, bussinessTypeEntity, unitFk); @@ -1835,12 +1823,6 @@ public class IoCodeTempController extends BaseController { } - public Integer getMaxGroupNumber() { - Integer groupNumber = codeTempService.selectMaxGroupNumber(); - return groupNumber; - } - - public void updateRelCode(BasicBussinessTypeEntity bussinessTypeEntity, String code) { if (!(bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_OUT) || bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_RETURN))) relCodeBatchService.threadUpdateIoCodeTempEntity(code); @@ -3106,5 +3088,111 @@ public class IoCodeTempController extends BaseController { return ResultVOUtils.success(); } + /** + * 校验库存情况 + * + * @param bussinessTypeEntity 业务类型 + * @param udiRelevanceResponse UDI关联响应 + * @param codeEntity 码实体 + * @return 校验结果 + */ + private BaseResponse checkInventory(BasicBussinessTypeEntity bussinessTypeEntity, UdiRelevanceResponse udiRelevanceResponse, IoCodeTempEntity codeEntity) { + BaseResponse invRes = null; + if (IntUtil.value(bussinessTypeEntity.getUseDyCount()) == 2) { + if (bussinessTypeEntity.isScanPreIn() && checkDiAttribute(bussinessTypeEntity, udiRelevanceResponse, 2)) { //校验预验收库存 + invRes = checkInvService.checkPreInInv(bussinessTypeEntity, codeEntity, false); + } + if (bussinessTypeEntity.isAdvancePreIn() && checkDiAttribute(bussinessTypeEntity, udiRelevanceResponse, 3)) { //校验寄售库存 + invRes = checkInvService.checkPreInv(bussinessTypeEntity, codeEntity, false); + } + if (bussinessTypeEntity.isVailInv() && checkDiAttribute(bussinessTypeEntity, udiRelevanceResponse, 1)) { + invRes = checkInvService.checkInv(bussinessTypeEntity, codeEntity, false); + } + } else { + if (bussinessTypeEntity.isScanPreIn()) { //校验预验收库存 + invRes = checkInvService.checkPreInInv(bussinessTypeEntity, codeEntity, false); + } else if (bussinessTypeEntity.isAdvancePreIn()) { //校验寄售库存 + invRes = checkInvService.checkPreInv(bussinessTypeEntity, codeEntity, false); + } else { + invRes = checkInvService.checkInv(bussinessTypeEntity, codeEntity, false); + } + } + + return invRes; + } + + + public Integer getMaxGroupNumber() { + Integer groupNumber = codeTempService.selectMaxGroupNumber(); + return groupNumber; + } + + + /** + * 处理码校验和更新 + * + * @param bussinessTypeEntity 业务类型 + * @param genDetaiEntity 生成的明细实体 + * @param exitLocalEntity 已存在的实体 + * @param inBatch 批次号 + * @param codeEnttitys 码实体列表 + * @return 是否处理成功 + */ + private boolean handleCodeCheckAndUpdate(BasicBussinessTypeEntity bussinessTypeEntity, + IoCodeTempEntity genDetaiEntity, + IoCodeTempEntity exitLocalEntity, + String inBatch, + List codeEnttitys) { + try { + if (bussinessTypeEntity.getCheckWebNew() == 1 && bussinessTypeEntity.isCheckEnable()) { + String errMsg = ioCheckInoutService.checkCode(genDetaiEntity); + if (errMsg != null) { + return false; + } else { + codeTempService.updateById(exitLocalEntity); + } + } else if (bussinessTypeEntity.getCheckWebNew() == 2 && bussinessTypeEntity.isCheckEnable()) { + String errMsg = ioCheckInoutService.checkNoPiCode(genDetaiEntity); + if (errMsg != null) { + return false; + } else { + codeTempService.updateById(exitLocalEntity); + } + } else { + boolean update = true; + String priceFifo = systemParamConfigService.selectValueByParamKey("price_fifo"); + if (IntUtil.value(priceFifo) > 0) { + if (bussinessTypeEntity.getMainAction().equals(ConstantType.TYPE_OUT)) { + //1.获取当前批次已出库数量 + Integer outCount = invProductServiceNew.selectCountByInBatch(exitLocalEntity.getRelId() + "", + exitLocalEntity.getBatchNo(), bussinessTypeEntity, exitLocalEntity.getInBatchNo(), + exitLocalEntity.getInvCode(), ConstantType.TYPE_OUT); + //2.获取当前批次入库数量 + Integer inCount = invProductServiceNew.selectCountByInBatch(exitLocalEntity.getRelId() + "", + exitLocalEntity.getBatchNo(), bussinessTypeEntity, exitLocalEntity.getInBatchNo(), + exitLocalEntity.getInvCode(), ConstantType.TYPE_PUT); + if ((IntUtil.value(inCount) - IntUtil.value(outCount) - IntUtil.value(exitLocalEntity.getReCount())) < 0) { + InvProductNewVo nextInvProduct = invProductServiceNew.selectNextInBatch(bussinessTypeEntity, + exitLocalEntity.getRelId() + "", exitLocalEntity.getBatchNo(), exitLocalEntity.getInvCode(), + ConstantType.TYPE_PUT, exitLocalEntity.getInBatchNo()); + if (nextInvProduct != null) { + genDetaiEntity.setPrice(nextInvProduct.getPrice()); + genDetaiEntity.setInBatchNo(nextInvProduct.getInBatchNo()); + codeTempService.insert(genDetaiEntity); + update = false; + } + } + } + } + if (update) { + codeTempService.updateById(exitLocalEntity); + } + } + return true; + } catch (Exception e) { + log.error("处理码校验和更新异常:{}", e.getMessage(), e); + return false; + } + } } diff --git a/src/main/java/com/glxp/api/dao/basic/UdiRelevanceDao.java b/src/main/java/com/glxp/api/dao/basic/UdiRelevanceDao.java index b5f477c7c..52d9e4f33 100644 --- a/src/main/java/com/glxp/api/dao/basic/UdiRelevanceDao.java +++ b/src/main/java/com/glxp/api/dao/basic/UdiRelevanceDao.java @@ -109,4 +109,11 @@ public interface UdiRelevanceDao extends BaseMapperPlus selectProductByRelIds(@Param("relIds")List relIds); List getProductsEntitiesByNameCode(String nameCode); + + /** + * 批量查询追溯码信息 + * @param filterUdiRelRequest 包含追溯码列表的请求 + * @return 追溯码信息列表 + */ + List batchSelectByNameCodes(FilterUdiRelRequest filterUdiRelRequest); } diff --git a/src/main/java/com/glxp/api/req/basic/FilterUdiRelRequest.java b/src/main/java/com/glxp/api/req/basic/FilterUdiRelRequest.java index ec97ae8e7..df5f0c46c 100644 --- a/src/main/java/com/glxp/api/req/basic/FilterUdiRelRequest.java +++ b/src/main/java/com/glxp/api/req/basic/FilterUdiRelRequest.java @@ -126,6 +126,10 @@ public class FilterUdiRelRequest extends ListPageRequest { private String keyWords; private List filterNameCodes; - + + /** + * 批量查询的追溯码列表 + */ + private List nameCodes; } diff --git a/src/main/java/com/glxp/api/service/basic/UdiRelevanceService.java b/src/main/java/com/glxp/api/service/basic/UdiRelevanceService.java index 2b71e3613..a2212ce92 100644 --- a/src/main/java/com/glxp/api/service/basic/UdiRelevanceService.java +++ b/src/main/java/com/glxp/api/service/basic/UdiRelevanceService.java @@ -420,7 +420,10 @@ public class UdiRelevanceService extends ServiceImpl selectGroupByNameCode(String nameCode, Boolean isDisable) { - return udiRelevanceDao.selectGroupByNameCode(nameCode, isDisable); + FilterUdiRelRequest filterUdiRelRequest = new FilterUdiRelRequest(); + filterUdiRelRequest.setUniqueNameCode(nameCode); + filterUdiRelRequest.setIsDisable(isDisable); + return udiRelevanceDao.filterUdiGp(filterUdiRelRequest); } public UdiRelevanceResponse selectOneUdi(FilterUdiRelRequest filterUdiRelRequest) { @@ -478,5 +481,43 @@ public class UdiRelevanceService extends ServiceImpl batchSelectByNameCodes(List nameCodes) { + if (CollUtil.isEmpty(nameCodes)) { + return new HashMap<>(); + } + + Map resultMap = new HashMap<>(); + + // 对大批量数据进行分批处理,每次处理500个 + int batchSize = 500; + for (int i = 0; i < nameCodes.size(); i += batchSize) { + int endIndex = Math.min(i + batchSize, nameCodes.size()); + List batchCodes = nameCodes.subList(i, endIndex); + + // 使用IN查询一次性获取多个码的信息 + FilterUdiRelRequest filterUdiRelRequest = new FilterUdiRelRequest(); + filterUdiRelRequest.setNameCodes(batchCodes); + List batchResponses = udiRelevanceDao.batchSelectByNameCodes(filterUdiRelRequest); + + if (CollUtil.isNotEmpty(batchResponses)) { + for (UdiRelevanceResponse response : batchResponses) { + if (response != null && StrUtil.isNotEmpty(response.getNameCode())) { + resultMap.put(response.getNameCode(), response); + } + } + } + } + + return resultMap; + } + + + } diff --git a/src/main/java/com/glxp/api/service/inout/AddCoodeService.java b/src/main/java/com/glxp/api/service/inout/AddCoodeService.java new file mode 100644 index 000000000..94e526ead --- /dev/null +++ b/src/main/java/com/glxp/api/service/inout/AddCoodeService.java @@ -0,0 +1,1175 @@ +package com.glxp.api.service.inout; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.glxp.api.common.res.BaseResponse; +import com.glxp.api.common.util.ResultVOUtils; +import com.glxp.api.constant.Constant; +import com.glxp.api.constant.ConstantStatus; +import com.glxp.api.constant.ConstantType; +import com.glxp.api.entity.auth.AuthAdmin; +import com.glxp.api.entity.auth.InvWarehouseEntity; +import com.glxp.api.entity.auth.SysWorkplace; +import com.glxp.api.entity.basic.BasicBussinessTypeEntity; +import com.glxp.api.entity.basic.SysWorkplaceFreight; +import com.glxp.api.entity.basic.SysWorkplaceQueue; +import com.glxp.api.entity.basic.UdiEntity; +import com.glxp.api.entity.collect.IoCollectOrderCodeMan; +import com.glxp.api.entity.collect.IoCollectSet; +import com.glxp.api.entity.collect.RelCodeDetail; +import com.glxp.api.entity.inout.*; +import com.glxp.api.req.basic.CompanyProductRelevanceRequest; +import com.glxp.api.req.inout.AddOrderCodeRequest; +import com.glxp.api.req.inout.AddOrderRequest; +import com.glxp.api.res.basic.UdiRelevanceResponse; +import com.glxp.api.res.basic.UdiRlSupResponse; +import com.glxp.api.res.collect.RelCodeDetailResponse; +import com.glxp.api.res.inout.AddCodeResult; +import com.glxp.api.res.inout.VailCodeResultResponse; +import com.glxp.api.service.auth.InvWarehouseService; +import com.glxp.api.service.auth.SysWorkplaceService; +import com.glxp.api.service.basic.*; +import com.glxp.api.service.collect.*; +import com.glxp.api.service.inout.impl.IoCodeService; +import com.glxp.api.service.inv.InvPreinProductDetailService; +import com.glxp.api.service.inv.impl.InvProductServiceNew; +import com.glxp.api.service.system.SystemParamConfigService; +import com.glxp.api.util.GennerOrderUtils; +import com.glxp.api.util.IntUtil; +import com.glxp.api.util.MsDateUtil; +import com.glxp.api.util.OrderNoTypeBean; +import com.glxp.api.util.udi.FilterUdiUtils; +import com.glxp.api.util.udi.UdiCalCountUtil; +import com.glxp.api.vo.basic.InvProductNewVo; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; + + +@Slf4j +@Service +public class AddCoodeService { + + @Autowired + private IoOrderService orderService; + @Autowired + private IBasicBussinessTypeService basicBussinessTypeService; + @Autowired + IoAddInoutService transInoutService; + @Autowired + private SystemParamConfigService systemParamConfigService; + @Autowired + UdiRelevanceService udiRelevanceService; + @Autowired + private IoCodeTempService codeTempService; + @Autowired + IoCodeLostService codeLostService; + @Autowired + IoCheckInoutService ioCheckInoutService; + @Autowired + RelCodeBatchService relCodeBatchService; + @Autowired + IoSplitFifoCodeService ioSplitFifoCodeService; + @Autowired + IoAddInoutService ioAddInoutService; + @Autowired + InvWarehouseService invWarehouseService; + @Autowired + UdiCalCountUtil udiCalCountUtil; + @Autowired + GennerOrderUtils gennerOrderUtils; + @Autowired + IoCheckInvService checkInvService; + @Autowired + UdiProductService udiProductService; + @Autowired + BasicCorpService basicUnitMaintainService; + @Autowired + UdiRlSupService udiRlSupService; + @Autowired + InvPreinProductDetailService invPreinProductDetailService; + @Autowired + InvProductServiceNew invProductServiceNew; + @Autowired + IoOrderDetailBizService orderDetailBizService; + @Autowired + IoCodeService codeService; + @Autowired + IoOrderDetailCodeService ioOrderDetailCodeService; + @Autowired + IoSplitFifoCodeService splitFifoCodeService; + @Autowired + IoCollectOriginService collectOriginService; + @Autowired + IoCollectOrderBizOriginService collectOrderBizOriginService; + @Autowired + IoCollectOrderBizService collectOrderBizService; + @Autowired + IoCollectOrderOriginService collectOrderOriginService; + @Autowired + IoCollectOrderService collectOrderService; + @Autowired + IoCollectCodeService ioCollectCodeService; + @Autowired + IoSplitFifoInvService ioSplitFifoInvService; + @Autowired + SysWorkplaceQueueService sysWorkplaceQueueService; + @Autowired + IoCollectOrderBackupService ioCollectOrderBackupService; + @Autowired + IoCollectSetService collectSetService; + @Autowired + SysWorkplaceFreightService sysWorkplaceFreightService; + @Autowired + IoCollectOrderCodeManService ioCollectOrderCodeManService; + @Autowired + SysWorkplaceService sysWorkplaceService; + @Resource + SysOrderLedService sysOrderLedService; + + @Autowired + IoCollectOrderCodeManService collectOrderCodeManService; + + @Autowired + RelCodeDetailService relCodeDetailService; + + @Autowired + IoSplitFifoCodeService fifoCodeService; + @Autowired + IoSplitCodeService splitCodeService; + + /** + * 药品批量扫码 + */ + public BaseResponse batchProcessDrugCodes(AddOrderCodeRequest addOrderCodeRequest, AuthAdmin authAdmin) { + long startTime = System.currentTimeMillis(); + AddCodeResult addCodeResult = new AddCodeResult(); + List codeList = addOrderCodeRequest.getCodeList(); + List vailCodeResultResponses = new ArrayList<>(); + + if (CollUtil.isEmpty(codeList)) { + return ResultVOUtils.error(500, "追溯码不能为空"); + } + log.info("批量处理药品码开始,共{}个", codeList.size()); + // 1. 预处理:标准化追溯码列表 + List processedCodes = codeList.stream() + .filter(StringUtils::isNotBlank) + .map(String::trim) + .map(code -> code.endsWith("\u001D") ? code.replace("\u001D", "") : code) + .collect(Collectors.toList()); + + // 2. 批量解析UDI实体 + Map udiEntityMap = new HashMap<>(); + Map nameCodes = new HashMap<>(); + + for (String code : processedCodes) { + UdiEntity udiEntity = FilterUdiUtils.getUdi(code); + if (udiEntity != null) { + udiEntityMap.put(code, udiEntity); + nameCodes.put(code, udiEntity.getUdi()); + } else { + VailCodeResultResponse invalidResponse = new VailCodeResultResponse(); + invalidResponse.setCode(code); + invalidResponse.setStatus(2); + invalidResponse.setErrMsg("无效条码"); + vailCodeResultResponses.add(invalidResponse); + } + } + + if (udiEntityMap.isEmpty()) { + addCodeResult.setVailCodeResultResponses(vailCodeResultResponses); + return ResultVOUtils.success(addCodeResult); + } + + // 3. 批量获取共享数据 + // 获取订单信息 + IoOrderEntity ioOrderEntity = orderService.findCorpOrderId(addOrderCodeRequest.getCorpOrderId()); + String orderId = ioOrderEntity != null ? ioOrderEntity.getBillNo() : null; + + // 获取业务类型 + String action = ioOrderEntity.getAction(); + if (action == null) { + if (IntUtil.value(addOrderCodeRequest.getInoutType()) == 2) { + action = ConstantType.SPLIT_RETURN; + } else { + action = ConstantType.SPLIT_OUT; + } + } + BasicBussinessTypeEntity bussinessTypeEntity = basicBussinessTypeService.findByAction(action); + if (bussinessTypeEntity == null) { + return ResultVOUtils.error(500, "业务类型不存在"); + } + // 获取仓库信息 + String invCode = authAdmin.getLocInvCode(); + + // 批量获取UDI相关信息 + List udiCodes = new ArrayList<>(nameCodes.values()); + Map udiRelevanceMap = udiRelevanceService.batchSelectByNameCodes(udiCodes); + if (udiRelevanceMap == null) { + return ResultVOUtils.error(500, "药品字典不存在此产品!"); + } + + + // 获取已存在的码记录 + Map existingCodesMap = new HashMap<>(); + if (StringUtils.isNotBlank(orderId)) { + existingCodesMap = codeTempService.batchCheckCodesExistence(processedCodes, orderId); + } + for (Map.Entry entry : existingCodesMap.entrySet()) { + IoCodeTempEntity codeTempEntity = entry.getValue(); + if (codeTempEntity != null) { + VailCodeResultResponse invalidResponse = new VailCodeResultResponse(); + invalidResponse.setCode(codeTempEntity.getCode()); + invalidResponse.setStatus(2); + invalidResponse.setErrMsg("重复扫码"); + vailCodeResultResponses.add(invalidResponse); + } + } + // 4. 获取组编号 + Integer groupNumber = getMaxGroupNumber() == null ? 1 : getMaxGroupNumber() + 1; + // 5. 配置线程池 + int processors = Runtime.getRuntime().availableProcessors(); + ExecutorService executor = Executors.newFixedThreadPool(Math.min(processors * 2, 10)); + try { + // 创建异步任务 + List> futures = udiEntityMap.entrySet().stream() + .map(entry -> { + String code = entry.getKey(); + UdiEntity udiEntity = entry.getValue(); + return CompletableFuture.supplyAsync(() -> { + VailCodeResultResponse resultResponse = new VailCodeResultResponse(); + resultResponse.setCode(code); + try { + // 准备请求参数 + AddOrderRequest addOrderRequest = new AddOrderRequest(); + BeanUtils.copyProperties(addOrderCodeRequest, addOrderRequest); + addOrderRequest.setBillNo(orderId); + addOrderRequest.setCode(code); + addOrderRequest.setInvCode(invCode); + + if (IntUtil.value(addOrderCodeRequest.getInoutType()) == 2) { + addOrderRequest.setAction(ConstantType.SPLIT_RETURN); + } else { + addOrderRequest.setAction(ConstantType.SPLIT_OUT); + } + addOrderRequest.setFromCorp(ConstantType.SPLIT_CORP); + + // 设置批次信息 + if (StrUtil.isNotEmpty(addOrderRequest.getBatchNo())) { + udiEntity.setBatchNo(addOrderRequest.getBatchNo()); + } + if (StrUtil.isNotEmpty(addOrderRequest.getProduceDate())) { + udiEntity.setProduceDate(addOrderRequest.getProduceDate()); + } + if (StrUtil.isNotEmpty(addOrderRequest.getExpireDate())) { + udiEntity.setExpireDate(addOrderRequest.getExpireDate()); + } + if (StrUtil.isNotEmpty(addOrderRequest.getSerialNo())) { + udiEntity.setSerialNo(addOrderRequest.getSerialNo()); + } + // 处理药品追溯码 + BaseResponse baseResponse = addDrugOrder(addOrderRequest, udiEntity, code, groupNumber, bussinessTypeEntity, udiRelevanceMap.get(udiEntity.getUdi()), authAdmin); + // 处理结果 + if (baseResponse.getCode() == 20000) { + resultResponse.setStatus(1); + resultResponse.setErrMsg("正确"); + AddCodeResult temp = (AddCodeResult) baseResponse.getData(); + // 使用同步块保证线程安全 + synchronized (addCodeResult) { + if (StringUtils.isBlank(addCodeResult.getOrderId())) { + addCodeResult.setOrderId(temp.getOrderId()); + } + } + } else { + resultResponse.setStatus(2); + resultResponse.setErrMsg(baseResponse.getMessage()); + } + } catch (Exception e) { + log.error("处理追溯码异常: {}, 码值: {}", e.getMessage(), code); + resultResponse.setStatus(2); + resultResponse.setErrMsg("处理异常: " + e.getMessage()); + } + + return resultResponse; + }, executor); + }) + .collect(Collectors.toList()); + + // 收集结果 + CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); + futures.stream() + .map(CompletableFuture::join) + .forEach(vailCodeResultResponses::add); + } finally { + executor.shutdown(); + } + addCodeResult.setVailCodeResultResponses(vailCodeResultResponses); + log.info("批量处理药品追溯码完成,共{}个,耗时{}ms", codeList.size(), (System.currentTimeMillis() - startTime)); + return ResultVOUtils.success(addCodeResult); + } + + + /** + * 药品扫码添加校验 + */ + public BaseResponse addDrugOrder(AddOrderRequest addOrderRequest, UdiEntity udiEntity, String code, Integer groupNumber, + BasicBussinessTypeEntity bussinessTypeEntity, UdiRelevanceResponse udiRelevanceResponse, AuthAdmin authAdmin) { + long startTime = System.currentTimeMillis(); + AddCodeResult addCodeResult = new AddCodeResult(); + + // 检查码是否空 + if (udiEntity == null) { + return ResultVOUtils.error(500, "无效条码"); + } + + if (IntUtil.value(udiRelevanceResponse.getNotCodeType()) != 0) { + return ResultVOUtils.error(500, "当前为无码类型产品,无需扫码!"); + } + + // 2. 将批次号查询移至此处统一处理 + if (StrUtil.isEmpty(udiEntity.getBatchNo())) { + IoCodeLostEntity codeLostEntity = codeLostService.findByCode(addOrderRequest.getCode()); + if (codeLostEntity != null) { + udiEntity.setBatchNo(codeLostEntity.getBatchNo()); + udiEntity.setProduceDate(codeLostEntity.getProduceDate()); + udiEntity.setExpireDate(codeLostEntity.getExpireDate()); + } + } + String orderId = addOrderRequest.getBillNo(); + + // 3. 合并校验流程,减少方法调用 + // 过期校验 + int checkExpire = IntUtil.value(bussinessTypeEntity.getCheckExpire()); + if (checkExpire > 0) { + BaseResponse response = checkExpireDate(checkExpire, udiEntity, addOrderRequest); + if (response.getCode() != 20000) { + return response; + } + } + // 层级标识校验 + boolean packLevelValid; + if (bussinessTypeEntity.isUse()) { + packLevelValid = isPackLevelValid(udiRelevanceResponse.getUseMaxLevel(), + IntUtil.value(udiRelevanceResponse.getPackLevel()), + udiRelevanceResponse.getUseLevel()); + } else { + packLevelValid = isPackLevelValid(udiRelevanceResponse.getDistributeMaxLevel(), + IntUtil.value(udiRelevanceResponse.getPackLevel()), + udiRelevanceResponse.getDistributeLevel()); + } + if (!packLevelValid) { + return ResultVOUtils.error(500, "当前产品不支持采集该包装层级追溯码!"); + } + + // 近效期提醒 + BaseResponse checkResponse = checkIsExpired(udiRelevanceResponse, udiEntity, addOrderRequest, bussinessTypeEntity); + if (checkResponse.getCode() == 505) { + return checkResponse; + } + // 工位上货相关校验 + BaseResponse handleSplitOutAndSplitReturnResponse = handleSplitOutAndSplitReturn(code, udiEntity, bussinessTypeEntity); + if (handleSplitOutAndSplitReturnResponse.getCode() != 20000) { + return handleSplitOutAndSplitReturnResponse; + } + + if (addOrderRequest.getFromCorp() == null || StrUtil.isNotEmpty(addOrderRequest.getSickerAdNum())) { + String fromCorp = ioAddInoutService.updateCorp(bussinessTypeEntity, addOrderRequest.getFromCorp(), addOrderRequest.getSickerAdNum()); + addOrderRequest.setFromCorp(fromCorp); + } + // 4. 优化订单处理流程 + InvWarehouseEntity invWarehouseEntity = invWarehouseService.findByInvSubByCode(addOrderRequest.getInvCode()); + IoOrderEntity orderEntity = orderService.findByBillNo(orderId); + String inBatch = ""; + if (StringUtils.isBlank(orderId) || orderEntity == null) { + String orderNo = gennerOrderUtils.createScOrderNo(new OrderNoTypeBean(Constant.SCAN_ORDER + StrUtil.trimToEmpty(bussinessTypeEntity.getPrefix()), "yyyyMMdd")); + orderId = orderNo; + inBatch = orderId.substring((Constant.SCAN_ORDER + StrUtil.trimToEmpty(bussinessTypeEntity.getPrefix())).length()); + } else { + inBatch = orderId.substring((Constant.SCAN_ORDER + StrUtil.trimToEmpty(bussinessTypeEntity.getPrefix())).length()); + } + + // 5. 提前获取码信息,减少重复查询 + List codeEnttitys = codeTempService.findByOrderId(orderId); + IoCodeTempEntity exitLocalEntity = null; + IoCodeTempEntity genDetaiEntity = new IoCodeTempEntity(); + + // 6. 优化已存在码的处理逻辑 + if (!codeEnttitys.isEmpty()) { + exitLocalEntity = isExitLocal(code, codeEnttitys); + if (exitLocalEntity != null) { + // 处理已存在码的情况 + if (StrUtil.isEmpty(exitLocalEntity.getSupId()) || exitLocalEntity.getRelId() == null) { + return ResultVOUtils.error(500, "当前药品追溯码已存在,且存在异常未处理!"); + } + + if (StringUtils.isNotBlank(exitLocalEntity.getSerialNo())) { + return ResultVOUtils.error(500, "重复扫码!"); + } + + // 获取udiRelevanceResponses数据,共用前面查询的udiRelevanceResponse + List udiRelevanceResponses = new ArrayList<>(); + udiRelevanceResponses.add(udiRelevanceResponse); + + BeanUtils.copyProperties(exitLocalEntity, genDetaiEntity); + genDetaiEntity.setCount(1); + + // 处理数量计算 + if (bussinessTypeEntity.isUse()) { + genDetaiEntity.setReCount(udiCalCountUtil.getUseActCount(udiRelevanceResponse)); + exitLocalEntity.setCount(exitLocalEntity.getMyCount() + 1); + exitLocalEntity.setReCount(exitLocalEntity.getMyReCount() * udiCalCountUtil.getUseActCount(udiRelevanceResponse)); + } else { + genDetaiEntity.setReCount(udiCalCountUtil.getCirActCount(udiRelevanceResponse)); + exitLocalEntity.setCount(exitLocalEntity.getMyCount() + 1); + exitLocalEntity.setReCount(exitLocalEntity.getMyReCount() * udiCalCountUtil.getCirActCount(udiRelevanceResponse)); + } + + // 匹配biz并缓存结果 + IoOrderDetailCodeEntity byRelId = ioOrderDetailCodeService.findByRelNameCode(addOrderRequest.getBillNo(), udiEntity.getUdi(), udiEntity.getBatchNo()); + if (byRelId != null) { + exitLocalEntity.setBizId(byRelId.getId()); + } + + // 优化库存校验流程 + BaseResponse invRes = checkInventory(bussinessTypeEntity, udiRelevanceResponse, genDetaiEntity); + if (invRes != null) { + return invRes; + } + + // 优化校验和更新流程 + boolean updated = handleCodeCheckAndUpdate(bussinessTypeEntity, genDetaiEntity, exitLocalEntity, inBatch, codeEnttitys); + if (!updated) { + return ResultVOUtils.error(500, "更新码信息失败"); + } + } + } + + if (exitLocalEntity == null) { + if (codeTempService.ieExitRel(code, orderId)) { + return ResultVOUtils.error(500, "当前追溯码已上传关联关系,请勿重复扫码!"); + } + UdiRelevanceResponse udiRelevanceResponse1 = udiRelevanceService.selectByNameCode(udiEntity.getUdi()); + // 只要是一单的话就用同一个 虚拟槽位 加载orderQueueCode !!!! + IoOrderEntity byBillNo = orderService.findByBillNo(orderId); + String queueCode = ""; + if (bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_OUT) || bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_RETURN)) { + if (StrUtil.isBlank(addOrderRequest.getWorkPlaceQueueCode())) { + if (byBillNo != null && !StrUtil.isBlank(byBillNo.getWorkPlaceQueueCode())) { + queueCode = byBillNo.getWorkPlaceQueueCode(); + } else { + // userId 没有什么用 设置为1 问题不大 避免空指针 + queueCode = ioSplitFifoInvService.setQueueCode(addOrderRequest.getWorkPlaceCode(), 1 + "", udiRelevanceResponse1.getRelId()); + addCodeResult.setQueueCode(queueCode); + } + } else { + queueCode = addOrderRequest.getWorkPlaceQueueCode(); + } + } + IoCodeTempEntity codeEnttity = new IoCodeTempEntity(); + codeEnttity.setCode(code); + codeEnttity.setOrderId(orderId); + codeEnttity.setCorpOrderId(addOrderRequest.getCorpOrderId()); + codeEnttity.setCreateTime(new Date()); + codeEnttity.setUpdateTime(new Date()); + codeEnttity.setMainAction(bussinessTypeEntity.getMainAction()); + codeEnttity.setAction(bussinessTypeEntity.getAction()); + codeEnttity.setNameCode(udiEntity.getUdi()); + codeEnttity.setBatchNo(udiEntity.getBatchNo()); + codeEnttity.setProduceDate(udiEntity.getProduceDate()); + codeEnttity.setExpireDate(udiEntity.getExpireDate()); + codeEnttity.setSerialNo(udiEntity.getSerialNo()); + codeEnttity.setDeptCode(invWarehouseEntity.getParentId()); + codeEnttity.setInvCode(addOrderRequest.getInvCode()); + codeEnttity.setWarehouseCode(addOrderRequest.getCurSpaceCode()); + codeEnttity.setPreSpaceCode(addOrderRequest.getPreCurSpaceCode()); + codeEnttity.setPreInSpaceCode(addOrderRequest.getCheckPreInSpaceCode()); + codeEnttity.setRelId(addOrderRequest.getRelId()); + codeEnttity.setFifoSplit(addOrderRequest.getFifoSplit()); + codeEnttity.setPrice(udiRelevanceResponse.getPrice()); + codeEnttity.setProductType(2); + codeEnttity.setCount(1); + codeEnttity.setGroupNumber(groupNumber); + codeEnttity.setQueueCode(queueCode); + + //匹配biz + IoOrderDetailCodeEntity byRelId = ioOrderDetailCodeService.findByRelNameCode(addOrderRequest.getBillNo(), udiEntity.getUdi(), udiEntity.getBatchNo()); + if (byRelId != null) { + codeEnttity.setBizId(byRelId.getId()); + } + + //如果是阿里拉的单据会有批次号 + IoCollectOrderCodeMan codeMan = ioCollectOrderCodeManService.getOne(new LambdaQueryWrapper().eq(IoCollectOrderCodeMan::getUdiCode, code)); + if (codeMan != null) { + codeEnttity.setBatchNo(codeMan.getBatchNo()); + codeEnttity.setProduceDate(codeMan.getProductDate()); + codeEnttity.setExpireDate(codeMan.getExpireDate()); + } + + RelCodeDetailResponse codeRelEntity = relCodeDetailService.findByCode(code); + if (codeRelEntity != null) { + codeEnttity.setParentCode(codeRelEntity.getParentCode()); + RelCodeDetail relCodeDetail = relCodeDetailService.getOneByCode(codeRelEntity.getParentCode()); + if (relCodeDetail != null) { + codeEnttity.setGrantPaCode(relCodeDetail.getParentCode()); + } + codeEnttity.setBatchNo(codeRelEntity.getBatchNo()); + codeEnttity.setProduceDate(MsDateUtil.formatDate(codeRelEntity.getMadeDate(), "yyMMdd")); + codeEnttity.setExpireDate(MsDateUtil.formatDate(codeRelEntity.getValidateDate(), "yyMMdd")); + } + + String unitFk = null; + if (bussinessTypeEntity.getCorpType() == ConstantStatus.CORP_TYPE_OUT) { + unitFk = addOrderRequest.getFromCorp(); + } else if (StrUtil.isNotEmpty(addOrderRequest.getSelectSupId())) { + unitFk = addOrderRequest.getSelectSupId(); + } + + // 获取产品列表 - 使用前面查询的单个产品 + List productList = Collections.singletonList(udiRelevanceResponse); + + if (productList.size() >= 1) { + if (udiRelevanceResponse == null) { + return ResultVOUtils.error(500, "该产品信息未维护!"); + } else if (!udiRelevanceResponse.getUseDy() && udiRelevanceResponse.getDiType() == ConstantStatus.DITYPE_SYDY) { + return ResultVOUtils.error(500, "该产品不允许以使用单元入库!"); + } + + if (bussinessTypeEntity.isVailDispatch() && !udiRelevanceResponse.isDispatch()) { + return ResultVOUtils.error(500, "该产品不可配送,请联系院方!"); + } + + if (bussinessTypeEntity.getVailGroupBuy() == 1 && !udiRelevanceResponse.isGroupBuy()) { //只采集集采产品 + return ResultVOUtils.error(500, bussinessTypeEntity.getName() + "单只允许录入集采产品!"); + } + + if (bussinessTypeEntity.getVailGroupBuy() == 2 && udiRelevanceResponse.isGroupBuy()) { //只采集非集采产品 + return ResultVOUtils.error(500, bussinessTypeEntity.getName() + "单只允许录入非集采产品!"); + } + + // 直接使用传入的udiRelevanceResponse计算数量 + if (bussinessTypeEntity.isUse()) { + codeEnttity.setReCount(codeEnttity.getMyReCount() + udiCalCountUtil.getUseActCount(udiRelevanceResponse)); + } else { + codeEnttity.setReCount(codeEnttity.getMyReCount() + udiCalCountUtil.getCirActCount(udiRelevanceResponse)); + } + } else { + if (unitFk == null) + return ResultVOUtils.error(500, "耗材字典不存在此产品!"); + else + return ResultVOUtils.error(500, "当前供应商不存在此配送产品!"); + } + + if (!(bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_RETURN) || bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_OUT))) { + //校验供应商是否配送此产品 + BaseResponse corpResponse = checkCorp(codeEnttity, bussinessTypeEntity, unitFk); + if (corpResponse != null) { + return corpResponse; + } + } + + IoOrderEntity isExit = orderService.findByBillNo(orderId); + if (isExit == null) { + orderEntity = new IoOrderEntity(); + orderEntity.setBillNo(orderId); + orderEntity.setCorpOrderId(addOrderRequest.getCorpOrderId()); + orderEntity.setMainAction(bussinessTypeEntity.getMainAction()); + orderEntity.setAction(bussinessTypeEntity.getAction()); + orderEntity.setFromCorp(addOrderRequest.getFromCorp()); + if (StrUtil.isNotEmpty(addOrderRequest.getFromInvCode())) { + InvWarehouseEntity invWarehouseEntity1 = invWarehouseService.findByInvSubByCode(addOrderRequest.getFromInvCode()); + orderEntity.setFromDeptCode(invWarehouseEntity1.getParentId()); + } + orderEntity.setFromInvCode(addOrderRequest.getFromInvCode()); + orderEntity.setFromType(ConstantStatus.FROM_WEBNEW); + orderEntity.setStatus(ConstantStatus.ORDER_STATUS_TEMP_SAVE); + orderEntity.setDealStatus(ConstantStatus.ORDER_DEAL_DRAFT); + orderEntity.setCreateUser(authAdmin.getId() + ""); + orderEntity.setCreateTime(new Date()); + orderEntity.setUpdateUser(authAdmin.getId() + ""); + orderEntity.setUpdateTime(new Date()); + orderEntity.setCustomerId(authAdmin.getCustomerId() + ""); + orderEntity.setDeptCode(invWarehouseEntity.getParentId()); + orderEntity.setCheckPreInOrders(addOrderRequest.getCheckPreInOrders()); + orderEntity.setInvCode(addOrderRequest.getInvCode()); + orderEntity.setOrderType(addOrderRequest.getOrderType()); + orderEntity.setBusType(bussinessTypeEntity.getBusType()); + orderEntity.setSickerAdNum(addOrderRequest.getSickerAdNum()); + orderEntity.setWorkPlaceCode(addOrderRequest.getWorkPlaceCode()); + orderEntity.setSplitBusType(addOrderRequest.getSplitBusType()); + orderEntity.setFifoSplit(addOrderRequest.getFifoSplit()); + orderEntity.setSplitBusType(addOrderRequest.getSplitBusType()); + orderEntity.setWorkPlaceQueueCode(queueCode); + orderEntity.setProductType(2); + orderEntity.setFifoSplitTag(addOrderRequest.getFifoSplitTag()); + orderService.insertOrder(orderEntity); + } + + if (bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_OUT)) { + //工位上货 只允许上货一个产品 开关以及控制 + IoCollectSet collectSet = collectSetService.getSet(); + // 判断货位里面是否有相同产品 + if (orderEntity != null && StrUtil.isNotEmpty(orderEntity.getWorkPlaceQueueCode())) { + SysWorkplace sysWorkplace = sysWorkplaceService.getOne(new LambdaQueryWrapper().eq(SysWorkplace::getWorkplaceId, addOrderRequest.getWorkPlaceCode())); + if (sysWorkplace.getQueueStatus() == 1) { + SysWorkplaceQueue workplaceQueue = sysWorkplaceQueueService.getOne(new LambdaQueryWrapper() + .eq(SysWorkplaceQueue::getCode, orderEntity.getWorkPlaceQueueCode())); + if (workplaceQueue != null) { + //判断槽位产品是否一样 + if (StrUtil.isNotBlank(workplaceQueue.getRelId())) { + if (!udiRelevanceResponse.getId().equals(Long.parseLong(workplaceQueue.getRelId()))) { +// orderService.deleteByBillNo(orderId); + UdiRelevanceResponse udiRelevanceResponse2 = udiRelevanceService.selectByRelId(workplaceQueue.getRelId()); + return ResultVOUtils.error(507, "上货产品不符!" + "当前取货槽已被" + udiRelevanceResponse2.getCpmctymc() + "使用"); + } + } else { + //判断产品是否已经绑定其他槽位 + SysWorkplaceQueue workplaceQueue1 = sysWorkplaceQueueService.getOne(new LambdaQueryWrapper().eq(SysWorkplaceQueue::getRelId, udiRelevanceResponse.getId())); + if (workplaceQueue1 != null) { + String freightCode = workplaceQueue1.getFreightCode(); + SysWorkplaceFreight one = sysWorkplaceFreightService.getOne(new LambdaQueryWrapper().eq(SysWorkplaceFreight::getCode, freightCode)); + Integer isSingQueue = one.getIsSingQueue(); + if (workplaceQueue1 != null && isSingQueue == 1) { + if (!orderEntity.getWorkPlaceQueueCode().equals(workplaceQueue1.getCode())) { + return ResultVOUtils.error(507, "当前货架已启用单品种槽位且产品已绑定在" + workplaceQueue1.getCode() + "取货槽"); + } + } + } + } + } else { + return ResultVOUtils.error(500, "取货槽位不存在!"); + } + } + //校验完成 获取当前槽位 绑定产品 + + + SysWorkplaceQueue sysWorkplaceQueue = sysWorkplaceQueueService.getOne(new LambdaQueryWrapper() + .eq(SysWorkplaceQueue::getCode, orderEntity.getWorkPlaceQueueCode())); + if (sysWorkplaceQueue.getRelId() == null) { + //虚拟槽位这个时候就要设置 + if (sysWorkplace.getQueueStatus() == 0) { + sysWorkplaceQueue.setMaxDrugCount(100); + } + sysWorkplaceQueue.setRelId(udiRelevanceResponse.getId() + ""); + sysWorkplaceQueueService.updateById(sysWorkplaceQueue); + } + if (orderEntity != null && CollUtil.isNotEmpty(codeEnttitys)) { + boolean isSame = false; + for (IoCodeTempEntity ioOrderDetailCodeEntity : codeEnttitys) { + if (ioOrderDetailCodeEntity.getRelId().equals(udiRelevanceResponse.getId())) { + isSame = true; + } + } + if (!isSame) + return ResultVOUtils.error(507, "当前单据下只允许上货单一产品!"); + } + } else if (orderEntity != null && CollUtil.isNotEmpty(codeEnttitys) && IntUtil.value(collectSet.getSplitOutOnlyProductSwitch())) { + for (IoCodeTempEntity ioOrderDetailCodeEntity : codeEnttitys) { + //开启了 只允许上货一个产品开关 + if (!ioOrderDetailCodeEntity.getRelId().equals(udiRelevanceResponse.getId())) { + return ResultVOUtils.error(507, "当前单据下只允许上货单一产品!"); + } + } + + } + + } + + if (IntUtil.value(addOrderRequest.getOrderType()) == ConstantStatus.ORDER_TYPE_NORMAL && bussinessTypeEntity.isCheckEnable() && bussinessTypeEntity.getCheckWebNew() != 0) { + + boolean isBillExit = orderDetailBizService.isExit(orderEntity.getBillNo()); + if (!isBillExit) { + orderService.deleteByBillNo(orderEntity.getBillNo()); + return ResultVOUtils.error(500, "请先录入业务详情"); + } + } + + BaseResponse baseResponse = checkDrugRelId(codeEnttity, unitFk); + if (baseResponse != null) { + deleteEmptyBillNo(orderEntity); + } + genDetaiEntity = codeEnttity; + if (baseResponse == null) { + baseResponse = checkSupId(bussinessTypeEntity, codeEnttity, unitFk); + if (baseResponse != null) + return baseResponse; + } else { + if (baseResponse.getCode() == 501) { + return baseResponse; + } else if (baseResponse.getCode() == 502) { + return baseResponse; + } + checkSupId(bussinessTypeEntity, codeEnttity, unitFk); + return baseResponse; + } + + + if (IntUtil.value(bussinessTypeEntity.getUseDyCount()) == 2) { + if (bussinessTypeEntity.isScanPreIn() && checkDiAttribute(bussinessTypeEntity, udiRelevanceResponse.getId(), 2)) { //校验预验收库存 + BaseResponse invRes = checkInvService.checkPreInInv(bussinessTypeEntity, codeEnttity, false); + if (invRes != null) { + deleteEmptyBillNo(orderEntity); + return invRes; + } + } + if (bussinessTypeEntity.isAdvancePreIn() && checkDiAttribute(bussinessTypeEntity, udiRelevanceResponse.getId(), 3)) { //校验寄售库存 + BaseResponse invRes = checkInvService.checkPreInv(bussinessTypeEntity, codeEnttity, false); + if (invRes != null) { + deleteEmptyBillNo(orderEntity); + return invRes; + } + } + if (bussinessTypeEntity.isVailInv() && checkDiAttribute(bussinessTypeEntity, udiRelevanceResponse.getId(), 1)) { + BaseResponse invRes = checkInvService.checkInv(bussinessTypeEntity, codeEnttity, false); + if (invRes != null) { + deleteEmptyBillNo(orderEntity); + return invRes; + } + } + } else { + if (bussinessTypeEntity.isScanPreIn()) { //校验预验收库存 + BaseResponse invRes = checkInvService.checkPreInInv(bussinessTypeEntity, codeEnttity, false); + if (invRes != null) { + deleteEmptyBillNo(orderEntity); + return invRes; + } + } else if (bussinessTypeEntity.isAdvancePreIn()) { //校验寄售库存 + BaseResponse invRes = checkInvService.checkPreInv(bussinessTypeEntity, codeEnttity, false); + if (invRes != null) { + deleteEmptyBillNo(orderEntity); + return invRes; + } + } else { + BaseResponse invRes = checkInvService.checkInv(bussinessTypeEntity, codeEnttity, false); + if (invRes != null) { + deleteEmptyBillNo(orderEntity); + return invRes; + } + } + } + + + //是否边扫边校验 + if (bussinessTypeEntity.getCheckWebNew() == 1 && bussinessTypeEntity.isCheckEnable()) { + String errMsg = ioCheckInoutService.checkCode(codeEnttity); + if (errMsg != null) { + return ResultVOUtils.error(500, errMsg); + } else + codeTempService.insert(codeEnttity); + // 查询是否存在药品关联信息 后将结果更新至 temp表 + updateRelCode(bussinessTypeEntity, code); +// relCodeBatchService.threadUpdateIoCodeTempEntity(code); +// } else if (bussinessTypeEntity.getCheckWebNew() == 2 && bussinessTypeEntity.isCheckEnable()) { + } else if ((bussinessTypeEntity.getCheckWebNew() == 2 || bussinessTypeEntity.getCheckWebNew() == 2) && bussinessTypeEntity.isCheckEnable()) { + String errMsg = ioCheckInoutService.checkDrugNoPiCode(codeEnttity); + if (errMsg != null) { + return ResultVOUtils.error(500, errMsg); + } else + codeTempService.insert(codeEnttity); + // 异步调用 查询是否存在药品关联信息 后将结果更新至 temp表 + updateRelCode(bussinessTypeEntity, code); +// relCodeBatchService.threadUpdateIoCodeTempEntity(code); + } else { + checkPrice(codeEnttity, bussinessTypeEntity, inBatch, codeEnttitys); + codeTempService.insert(codeEnttity); + updateRelCode(bussinessTypeEntity, code); + + // 查询是否存在药品关联信息 后将结果更新至 temp表 +// relCodeBatchService.threadUpdateIoCodeTempEntity(code); + } + } + addCodeResult.setOrderId(orderId); + transInoutService.genOrderDetailCode(orderEntity, genDetaiEntity); + return ResultVOUtils.success(addCodeResult); + } + + public Integer getMaxGroupNumber() { + Integer groupNumber = codeTempService.selectMaxGroupNumber(); + return groupNumber; + } + + + private BaseResponse checkExpireDate(int checkExpire, UdiEntity udiEntity, AddOrderRequest addOrderRequest) { + if (StrUtil.isNotEmpty(udiEntity.getExpireDate())) { + String expireDate = "20" + udiEntity.getExpireDate(); + long expireTime = MsDateUtil.parseDateExpire(expireDate); + long currentTimeMillis = System.currentTimeMillis(); + if (expireTime < currentTimeMillis) { + if (checkExpire == 1 && !addOrderRequest.isIgnoreExpire()) { + return ResultVOUtils.error(504, "当前产品已过期,是否确定继续添加?"); + } else if (checkExpire == 2) { + return ResultVOUtils.error(604, "当前产品已过期,无法添加!"); + } + } + } + return ResultVOUtils.success(); + } + + private boolean isPackLevelValid(Integer maxLevel, Integer packLevel, Integer compareLevel) { + //maxLevel 当业务使用单据类型的时候 为使用允许采集最大层级 不适用的时候 为流通允许采集的最大层级 + //compareLevel 当业务类型使用单据类型的时候 为使用层级 不使用的为流通 + //packLevel 包装层级 + + if (maxLevel != null && packLevel > maxLevel) { + return false; + } + if (maxLevel == null && packLevel > 1) { + return false; + } + + return packLevel >= compareLevel; + } + + + public void updateRelCode(BasicBussinessTypeEntity bussinessTypeEntity, String code) { + if (!(bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_OUT) || bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_RETURN))) + relCodeBatchService.threadUpdateIoCodeTempEntity(code); + } + + + private BaseResponse checkIsExpired(UdiRelevanceResponse udiRelevanceResponse, UdiEntity udiEntity, AddOrderRequest addOrderRequest, BasicBussinessTypeEntity bussinessTypeEntity) { + long recent = udiRelevanceResponse.getRecentDateTime() != null ? udiRelevanceResponse.getRecentDateTime().longValue() : 0; + if (IntUtil.value(bussinessTypeEntity.getCheckVailDate()) == 1 && recent > 0 && !addOrderRequest.isIgnoreRecentExpire()) { + if (StrUtil.isNotEmpty(udiEntity.getExpireDate())) { + String expireDate = "20" + udiEntity.getExpireDate(); + long expireTime = MsDateUtil.parseDateExpire(expireDate); + long recentTime = Math.abs(recent * 24 * 60 * 60 * 1000); + long resultTime = expireTime - System.currentTimeMillis(); + if (resultTime > 0 && resultTime < recentTime) { + long time = udiRelevanceResponse.getIsDateBy() == 2 + ? resultTime / (60 * 60 * 1000) // 单位:小时 + : resultTime / (24 * 60 * 60 * 1000); // 单位:天 + String unit = udiRelevanceResponse.getIsDateBy() == 2 ? "时" : "天"; + return ResultVOUtils.error(505, "当前产品临近过期,距过期还剩" + time + unit + ",是否确定继续添加?"); + } + } + } + return ResultVOUtils.success(); + } + + private BaseResponse handleSplitOutAndSplitReturn(String code, UdiEntity udiEntity, BasicBussinessTypeEntity bussinessTypeEntity) { + IoSplitFifoCodeEntity fifoCodeEntity = fifoCodeService.findByCode(code, null); + IoSplitCodeEntity splitCodeEntity = splitCodeService.findByCode(code); + //校验码表是否已经存在追溯码 io_code_temp + IoCodeTempEntity codeTempEntity = codeTempService.selectByCode(code, udiEntity.getBatchNo(), bussinessTypeEntity.getAction()); + if (bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_OUT)) { + if (fifoCodeEntity != null && StrUtil.isNotEmpty(fifoCodeEntity.getSerialNo())) { + return ResultVOUtils.error(533, "当前追溯码已存在!"); + } + if (splitCodeEntity != null) {//&& StrUtil.isNotEmpty(splitCodeEntity.getSerialNo()) + return ResultVOUtils.error(533, "当前追溯码已存在拆零库存!"); + } + if (codeTempEntity != null) { + return ResultVOUtils.error(533, "扫码重复!"); + } + } else if (bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_RETURN)) { + if (fifoCodeEntity == null) { + return ResultVOUtils.error(500, "当前追溯码未上货或已出库完毕!"); + } + if (splitCodeEntity != null) {//&& StrUtil.isNotEmpty(splitCodeEntity.getSerialNo()) + return ResultVOUtils.error(533, "当前追溯码已经拆零,无法退货!"); + } + if (codeTempEntity != null) { + return ResultVOUtils.error(533, "扫码重复!"); + } + } + return ResultVOUtils.success(); + } + + + /** + * 判断本单是否存在 + * + * @param code + * @param codeEnttityList + * @return + */ + public IoCodeTempEntity isExitLocal(String code, List codeEnttityList) { + List codeTempEntities = isExitLocalList(code, codeEnttityList); + if (CollUtil.isNotEmpty(codeTempEntities)) { + return codeTempEntities.get(0); + } + return null; + } + + + public List isExitLocalList(String code, List codeEnttityList) { + UdiEntity udiEntity = FilterUdiUtils.getUdi(code); + List codeTempEntities = codeEnttityList.stream() + .filter(item -> { + if (item.getCode().equals(code)) { + if (StrUtil.emptyIfNull(item.getSerialNo()).equals(StrUtil.emptyIfNull(udiEntity.getSerialNo()))) { + return true; + } + if (!StrUtil.emptyIfNull(item.getNameCode()).equals(StrUtil.emptyIfNull(udiEntity.getUdi()))) { + return false; + } + if (!StrUtil.emptyIfNull(item.getBatchNo()).toUpperCase(Locale.ROOT).equals(StrUtil.emptyIfNull(udiEntity.getBatchNo()).toUpperCase(Locale.ROOT))) { + return false; + } + if (!StrUtil.emptyIfNull(item.getProduceDate()).equals(StrUtil.emptyIfNull(udiEntity.getProduceDate()))) { + return false; + } + if (!StrUtil.emptyIfNull(item.getExpireDate()).equals(StrUtil.emptyIfNull(udiEntity.getExpireDate()))) { + return false; + } + if (!StrUtil.emptyIfNull(item.getSerialNo()).equals(StrUtil.emptyIfNull(udiEntity.getSerialNo()))) { + return false; + } + return true; + } + return false; + }).sorted(Comparator.comparing(IoCodeTempEntity::getInBatchNo)).collect(Collectors.toList()); + Collections.reverse(codeTempEntities); + return codeTempEntities; + } + + /** + * 校验库存情况 + * + * @param bussinessTypeEntity 业务类型 + * @param udiRelevanceResponse UDI关联响应 + * @param codeEntity 码实体 + * @return 校验结果 + */ + private BaseResponse checkInventory(BasicBussinessTypeEntity bussinessTypeEntity, UdiRelevanceResponse udiRelevanceResponse, IoCodeTempEntity codeEntity) { + BaseResponse invRes = null; + + if (IntUtil.value(bussinessTypeEntity.getUseDyCount()) == 2) { + if (bussinessTypeEntity.isScanPreIn() && checkDiAttribute(bussinessTypeEntity, udiRelevanceResponse, 2)) { //校验预验收库存 + invRes = checkInvService.checkPreInInv(bussinessTypeEntity, codeEntity, false); + } + if (bussinessTypeEntity.isAdvancePreIn() && checkDiAttribute(bussinessTypeEntity, udiRelevanceResponse, 3)) { //校验寄售库存 + invRes = checkInvService.checkPreInv(bussinessTypeEntity, codeEntity, false); + } + if (bussinessTypeEntity.isVailInv() && checkDiAttribute(bussinessTypeEntity, udiRelevanceResponse, 1)) { + invRes = checkInvService.checkInv(bussinessTypeEntity, codeEntity, false); + } + } else { + if (bussinessTypeEntity.isScanPreIn()) { //校验预验收库存 + invRes = checkInvService.checkPreInInv(bussinessTypeEntity, codeEntity, false); + } else if (bussinessTypeEntity.isAdvancePreIn()) { //校验寄售库存 + invRes = checkInvService.checkPreInv(bussinessTypeEntity, codeEntity, false); + } else { + invRes = checkInvService.checkInv(bussinessTypeEntity, codeEntity, false); + } + } + + return invRes; + } + + /** + * @param purType 1:入账库;2:预验收库;3:寄售库 + */ + public boolean checkDiAttribute(BasicBussinessTypeEntity bussinessTypeEntity, UdiRelevanceResponse + udiRelevanceEntity, Integer purType) { + if (bussinessTypeEntity.getUseDyCount() == 2) { + if (IntUtil.value(udiRelevanceEntity.getPurType()) == IntUtil.value(purType)) { + return true; + } else + return false; + } + return true; + } + + + /** + * 检验药品ID唯一性 + * + * @param codeEnttity + * @param unitFk + * @return + */ + public BaseResponse checkDrugRelId(IoCodeTempEntity codeEnttity, String unitFk) { + + List udiRelevanceEntities = udiRelevanceService.selectDrugsByNameCode(codeEnttity, unitFk); + if (udiRelevanceEntities != null && udiRelevanceEntities.size() > 1 && codeEnttity.getRelId() == null) {//同一个DI绑定多个产品西信息 + String code = ";"; + for (UdiRelevanceResponse udiRelevanceResponse : udiRelevanceEntities) { + code = code + udiRelevanceResponse.getMainId() + ";"; + } + BaseResponse baseResponse = ResultVOUtils.error(502, "层级编码绑定多个第三方产品ID" + code.substring(1) + ",请检查后重试"); + baseResponse.setData(codeEnttity); + return baseResponse; + } else if (udiRelevanceEntities == null || udiRelevanceEntities.size() == 0) {//未找到产品信息,一般不会出现 + codeEnttity.setRelId(null); + codeEnttity.setStatus(2); + return ResultVOUtils.error(501, "耗材字典不存在此产品!"); + } else { + codeEnttity.setStatus(0); + if (codeEnttity.getRelId() == null) + codeEnttity.setRelId(udiRelevanceEntities.get(0).getId()); + } + + return null; + } + + + //校验供应商是否配送此产品 + public BaseResponse checkCorp(IoCodeTempEntity codeEnttity, BasicBussinessTypeEntity + bussinessTypeEntity, String unitFk) { + CompanyProductRelevanceRequest companyProductRelevanceRequest = new CompanyProductRelevanceRequest(); + UdiEntity udiEntity = FilterUdiUtils.getUdi(codeEnttity.getCode()); + companyProductRelevanceRequest.setNameCode(udiEntity.getUdi()); + companyProductRelevanceRequest.setProductsType(codeEnttity.getProductType()); + if (bussinessTypeEntity.getCorpType() == ConstantStatus.CORP_TYPE_OUT) { + companyProductRelevanceRequest.setUnitFk(unitFk); + List datas = udiRlSupService.filterUdiGp(companyProductRelevanceRequest); + if (datas.size() <= 0) { + return ResultVOUtils.error(500, "当前供应商不存在此配送产品!"); + } + } else { + List datas = udiRlSupService.filterUdiGp(companyProductRelevanceRequest); + if (datas.size() <= 0) { + return ResultVOUtils.error(500, "此产品无指定供应商,请检查后添加!"); + } + } + return null; + } + + + /** + * 处理码校验和更新 + * + * @param bussinessTypeEntity 业务类型 + * @param genDetaiEntity 生成的明细实体 + * @param exitLocalEntity 已存在的实体 + * @param inBatch 批次号 + * @param codeEnttitys 码实体列表 + * @return 是否处理成功 + */ + private boolean handleCodeCheckAndUpdate(BasicBussinessTypeEntity bussinessTypeEntity, + IoCodeTempEntity genDetaiEntity, + IoCodeTempEntity exitLocalEntity, + String inBatch, + List codeEnttitys) { + try { + if (bussinessTypeEntity.getCheckWebNew() == 1 && bussinessTypeEntity.isCheckEnable()) { + String errMsg = ioCheckInoutService.checkCode(genDetaiEntity); + if (errMsg != null) { + return false; + } else { + codeTempService.updateById(exitLocalEntity); + } + } else if (bussinessTypeEntity.getCheckWebNew() == 2 && bussinessTypeEntity.isCheckEnable()) { + String errMsg = ioCheckInoutService.checkNoPiCode(genDetaiEntity); + if (errMsg != null) { + return false; + } else { + codeTempService.updateById(exitLocalEntity); + } + } else { + boolean update = true; + String priceFifo = systemParamConfigService.selectValueByParamKey("price_fifo"); + if (IntUtil.value(priceFifo) > 0) { + if (bussinessTypeEntity.getMainAction().equals(ConstantType.TYPE_OUT)) { + //1.获取当前批次已出库数量 + Integer outCount = invProductServiceNew.selectCountByInBatch(exitLocalEntity.getRelId() + "", + exitLocalEntity.getBatchNo(), bussinessTypeEntity, exitLocalEntity.getInBatchNo(), + exitLocalEntity.getInvCode(), ConstantType.TYPE_OUT); + //2.获取当前批次入库数量 + Integer inCount = invProductServiceNew.selectCountByInBatch(exitLocalEntity.getRelId() + "", + exitLocalEntity.getBatchNo(), bussinessTypeEntity, exitLocalEntity.getInBatchNo(), + exitLocalEntity.getInvCode(), ConstantType.TYPE_PUT); + if ((IntUtil.value(inCount) - IntUtil.value(outCount) - IntUtil.value(exitLocalEntity.getReCount())) < 0) { + InvProductNewVo nextInvProduct = invProductServiceNew.selectNextInBatch(bussinessTypeEntity, + exitLocalEntity.getRelId() + "", exitLocalEntity.getBatchNo(), exitLocalEntity.getInvCode(), + ConstantType.TYPE_PUT, exitLocalEntity.getInBatchNo()); + if (nextInvProduct != null) { + genDetaiEntity.setPrice(nextInvProduct.getPrice()); + genDetaiEntity.setInBatchNo(nextInvProduct.getInBatchNo()); + codeTempService.insert(genDetaiEntity); + update = false; + } + } + } + } + if (update) { + codeTempService.updateById(exitLocalEntity); + } + } + return true; + } catch (Exception e) { + log.error("处理码校验和更新异常:{}", e.getMessage(), e); + return false; + } + } + + public void deleteEmptyBillNo(IoOrderEntity orderEntity) { + boolean r1 = orderDetailBizService.isExit(orderEntity.getBillNo()); + boolean r2 = ioOrderDetailCodeService.isExit(orderEntity.getBillNo()); + boolean r3 = codeTempService.isExit(orderEntity.getBillNo()); + if (!r1 && !r2 && !r3) { + orderService.deleteByBillNo(orderEntity.getBillNo()); + } + } + + //校验供应商唯一性 + public BaseResponse checkSupId(BasicBussinessTypeEntity bussinessTypeEntity, IoCodeTempEntity + codeEnttity, String unitFk) { + + if ((bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_OUT) || bussinessTypeEntity.getAction().equals(ConstantType.SPLIT_RETURN))) + return null; + String originSupId = unitFk; + if (originSupId != null) { + codeEnttity.setSupId(originSupId); + } else { + IoCodeEntity ioCodeEntity = new IoCodeEntity(); + BeanUtils.copyProperties(codeEnttity, ioCodeEntity); + String supId = transInoutService.checkExitSup(codeEnttity); + if (supId == null) { + codeEnttity.setSupId(null); + BaseResponse baseResponse = ResultVOUtils.error(503, "该产品未绑定供应商,请指定对应的供应商"); + baseResponse.setData(codeEnttity); + return baseResponse; + } else if ("MUTI".equals(supId)) { + codeEnttity.setSupId(null); + BaseResponse baseResponse = ResultVOUtils.error(503, "该产品绑定多个供应商,请指定对应的供应商"); + baseResponse.setData(codeEnttity); + return baseResponse; + } else { + codeEnttity.setSupId(supId); + } + } + codeTempService.updateById(codeEnttity); + return null; + } + + public void checkPrice(IoCodeTempEntity codeTempEntity, BasicBussinessTypeEntity bussinessTypeEntity, String + inBatch, List codeTempEntities) { + String priceFifo = systemParamConfigService.selectValueByParamKey("price_fifo"); + if (IntUtil.value(priceFifo) > 0) { + //入库时添加入库批号 + if (bussinessTypeEntity.getMainAction().equals(ConstantType.TYPE_PUT)) { + codeTempEntity.setInBatchNo(inBatch); + codeTempService.updateById(codeTempEntity); + } else { + ioAddInoutService.checkPrice(codeTempEntity, bussinessTypeEntity, codeTempEntities); + } + } + } + + + /** + * + */ + public boolean checkDiAttribute(BasicBussinessTypeEntity bussinessTypeEntity, Long relId, Integer purType) { + if (bussinessTypeEntity.getUseDyCount() == 2) { + if (udiRelevanceService.findPurType(relId) == IntUtil.value(purType)) { + return true; + } else + return false; + } + return true; + } + +} diff --git a/src/main/java/com/glxp/api/service/inout/IoCodeTempService.java b/src/main/java/com/glxp/api/service/inout/IoCodeTempService.java index eb7a70eac..725b80b30 100644 --- a/src/main/java/com/glxp/api/service/inout/IoCodeTempService.java +++ b/src/main/java/com/glxp/api/service/inout/IoCodeTempService.java @@ -46,6 +46,8 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.HashMap; @Service @Transactional(rollbackFor = Exception.class) @@ -517,4 +519,70 @@ public class IoCodeTempService { addEnterCodeResponse.setGgxh(checkUdi.getGgxh()); return addEnterCodeResponse; } + + /** + * 批量插入码信息 + * @param entities 码信息实体列表 + * @return 是否成功 + */ + public boolean batchInsert(List entities) { + if (CollUtil.isEmpty(entities)) { + return true; + } + + // 分批插入,每批最多500条 + int batchSize = 500; + int totalSize = entities.size(); + boolean result = true; + + for (int i = 0; i < totalSize; i += batchSize) { + int end = Math.min(i + batchSize, totalSize); + List batch = entities.subList(i, end); + result = result && ioCodeTempDao.insertBatch(batch); + } + + return result; + } + + /** + * 批量更新码信息 + * @param entities 码信息实体列表 + * @return 受影响的行数 + */ + public int batchUpdate(List entities) { + if (CollUtil.isEmpty(entities)) { + return 0; + } + + int updatedRows = 0; + for (IoCodeTempEntity entity : entities) { + updatedRows += ioCodeTempDao.updateById(entity); + } + + return updatedRows; + } + + /** + * 批量检查码是否存在 + * @param codes 码列表 + * @param orderId 订单ID + * @return 存在的码实体映射 + */ + public Map batchCheckCodesExistence(List codes, String orderId) { + if (CollUtil.isEmpty(codes) || StrUtil.isEmpty(orderId)) { + return new HashMap<>(); + } + + List existingEntities = selectByCodes(codes, orderId); + if (CollUtil.isEmpty(existingEntities)) { + return new HashMap<>(); + } + + Map codeToEntityMap = new HashMap<>(); + for (IoCodeTempEntity entity : existingEntities) { + codeToEntityMap.put(entity.getCode(), entity); + } + + return codeToEntityMap; + } } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 6524e6bd2..1cbd17a16 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -4,9 +4,9 @@ server: spring: datasource: driver-class-name: com.p6spy.engine.spy.P6SpyDriver - jdbc-url: jdbc:p6spy:mysql://127.0.0.1:3306/udi_wms_cl?allowMultiQueries=true&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true + jdbc-url: jdbc:p6spy:mysql://192.168.0.206:3306/udiwms81?allowMultiQueries=true&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true username: root - password: 123456 + password: Glxp@6066 hikari: connection-timeout: 60000 maximum-pool-size: 20 diff --git a/src/main/resources/mybatis/mapper/basic/UdiRelevanceDao.xml b/src/main/resources/mybatis/mapper/basic/UdiRelevanceDao.xml index 9c2996608..2b1eb57ab 100644 --- a/src/main/resources/mybatis/mapper/basic/UdiRelevanceDao.xml +++ b/src/main/resources/mybatis/mapper/basic/UdiRelevanceDao.xml @@ -2036,4 +2036,79 @@ ON bu.uuid = basic_products.uuid where basic_products.nameCode = #{nameCode} + + +