diff --git a/src/main/java/com/glxp/api/entity/basic/BasicSkPrescribeDiEntity.java b/src/main/java/com/glxp/api/entity/basic/BasicSkPrescribeDiEntity.java index ac449c3f9..2adfe62ce 100644 --- a/src/main/java/com/glxp/api/entity/basic/BasicSkPrescribeDiEntity.java +++ b/src/main/java/com/glxp/api/entity/basic/BasicSkPrescribeDiEntity.java @@ -132,7 +132,7 @@ public class BasicSkPrescribeDiEntity implements Serializable { /** - * 处方赋码状态 1:未赋码;2:部分赋码;3:已赋码 + * 处方赋码状态 1:未赋码;2:部分赋码;3:已赋码 ;6:拆零未赋码 */ @TableField(value = "tagStatus") private Integer tagStatus; diff --git a/src/main/java/com/glxp/api/entity/collect/IoCollectOrder.java b/src/main/java/com/glxp/api/entity/collect/IoCollectOrder.java index 0b54021df..cb4ddb51c 100644 --- a/src/main/java/com/glxp/api/entity/collect/IoCollectOrder.java +++ b/src/main/java/com/glxp/api/entity/collect/IoCollectOrder.java @@ -161,7 +161,7 @@ public class IoCollectOrder implements Serializable { @ApiModelProperty(value = "更新人") private Long updateUser; /** - * 赋码状态 0:原始单据未处理,1:已分配工位待处理;2:处理中;3:已完成;4:处理异常,-1:草稿,挂起状态,5:库存不足 + * 赋码状态 0:原始单据未处理,1:已分配工位待处理;2:处理中;3:已完成;4:处理异常,-1:草稿,挂起状态,5:库存不足;6:拆零未赋码 */ @TableField(value = "tagStatus") private Integer tagStatus; diff --git a/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBackup.java b/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBackup.java index 782acd3b4..d6d816707 100644 --- a/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBackup.java +++ b/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBackup.java @@ -135,7 +135,7 @@ public class IoCollectOrderBackup implements Serializable { @ApiModelProperty(value = "更新人") private Long updateUser; /** - * 赋码状态 0:原始单据未处理,1:已分配工位待处理;2:处理中;3:已完成;4:处理异常,-1:草稿,挂起状态,5:库存不足 + * 赋码状态 0:原始单据未处理,1:已分配工位待处理;2:处理中;3:已完成;4:处理异常,-1:草稿,挂起状态,5:库存不足 ;6:拆零未赋码 */ @TableField(value = "tagStatus") private Integer tagStatus; diff --git a/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBiz.java b/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBiz.java index ae8a23a23..b67208e60 100644 --- a/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBiz.java +++ b/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBiz.java @@ -149,7 +149,7 @@ public class IoCollectOrderBiz implements Serializable { private String measureUnit; /** - * 单据明细赋码状态 1:未赋码;2:部分赋码;3:已赋码 + * 单据明细赋码状态 1:未赋码;2:部分赋码;3:已赋码 ;6:拆零未赋码 */ @TableField(value = "tagStatus") @ApiModelProperty(value = "单据明细赋码状态 1:未赋码;2:部分赋码;3:已赋码;4:无需赋码") diff --git a/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBizBackup.java b/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBizBackup.java index 2dfadd718..153970168 100644 --- a/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBizBackup.java +++ b/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBizBackup.java @@ -141,7 +141,7 @@ public class IoCollectOrderBizBackup implements Serializable { private String measureUnit; /** - * 单据明细赋码状态 1:未赋码;2:部分赋码;3:已赋码 + * 单据明细赋码状态 1:未赋码;2:部分赋码;3:已赋码 ;6:拆零未赋码 */ @TableField(value = "tagStatus") @ApiModelProperty(value = "单据明细赋码状态 1:未赋码;2:部分赋码;3:已赋码") diff --git a/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBizOrigin.java b/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBizOrigin.java index f9772ad79..abb391f73 100644 --- a/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBizOrigin.java +++ b/src/main/java/com/glxp/api/entity/collect/IoCollectOrderBizOrigin.java @@ -149,7 +149,7 @@ public class IoCollectOrderBizOrigin implements Serializable { private String measureUnit; /** - * 单据明细赋码状态 1:未赋码;2:部分赋码;3:已赋码 + * 单据明细赋码状态 1:未赋码;2:部分赋码;3:已赋码 ;6:拆零未赋码 */ @TableField(value = "tagStatus") @ApiModelProperty(value = "单据明细赋码状态 1:未赋码;2:部分赋码;3:已赋码") diff --git a/src/main/java/com/glxp/api/entity/collect/IoCollectOrderOrigin.java b/src/main/java/com/glxp/api/entity/collect/IoCollectOrderOrigin.java index 546af6651..e1c87a275 100644 --- a/src/main/java/com/glxp/api/entity/collect/IoCollectOrderOrigin.java +++ b/src/main/java/com/glxp/api/entity/collect/IoCollectOrderOrigin.java @@ -131,7 +131,7 @@ public class IoCollectOrderOrigin implements Serializable { * 赋码状态 0:原始单据未处理,1:已分配工位待处理;2:处理中;3:已完成;4:处理异常 */ @TableField(value = "tagStatus") - @ApiModelProperty(value="赋码状态 0:原始单据未处理,1:已分配工位待处理;2:处理中;3:已完成;4:处理异常") + @ApiModelProperty(value="赋码状态 0:原始单据未处理,1:已分配工位待处理;2:处理中;3:已完成;4:处理异常;6:拆零未赋码") private Integer tagStatus; /** diff --git a/src/main/java/com/glxp/api/entity/collect/IoCollectSet.java b/src/main/java/com/glxp/api/entity/collect/IoCollectSet.java index 05c8556d3..6b3dfb09e 100644 --- a/src/main/java/com/glxp/api/entity/collect/IoCollectSet.java +++ b/src/main/java/com/glxp/api/entity/collect/IoCollectSet.java @@ -109,7 +109,6 @@ public class IoCollectSet implements Serializable { private Integer ipcMaxCount; - @TableField(value = "fixedCount") @ApiModelProperty(value = "高拍仪扫码数量") private Integer fixedCount; @@ -126,6 +125,11 @@ public class IoCollectSet implements Serializable { @ApiModelProperty(value = "是否允许取药整单确认") private Boolean drugDealConfirm; + @TableField(value = "delayTageCode") + @ApiModelProperty(value = "是否启用后置赋码:1:是;0:否") + private Boolean delayTageCode; + + private static final long serialVersionUID = 1L; @TableField(exist = false) diff --git a/src/main/java/com/glxp/api/req/collect/IoCollectOrderUploadVo.java b/src/main/java/com/glxp/api/req/collect/IoCollectOrderUploadVo.java index 44fac7de0..379f97aa7 100644 --- a/src/main/java/com/glxp/api/req/collect/IoCollectOrderUploadVo.java +++ b/src/main/java/com/glxp/api/req/collect/IoCollectOrderUploadVo.java @@ -178,7 +178,7 @@ public class IoCollectOrderUploadVo { @ColumnWidth(30) private Long updateUser; /** - * 赋码状态 0:原始单据未处理,1:已分配工位待处理;2:处理中;3:已完成;4:处理异常,-1:草稿,挂起状态,5:库存不足 + * 赋码状态 0:原始单据未处理,1:已分配工位待处理;2:处理中;3:已完成;4:处理异常,-1:草稿,挂起状态,5:库存不足 ;6:拆零未赋码 */ @TableField(value = "tagStatus") @ExcelProperty("赋码状态") diff --git a/src/main/java/com/glxp/api/service/collect/IoCollectOrderService.java b/src/main/java/com/glxp/api/service/collect/IoCollectOrderService.java index 04f329f21..fa59fa6b8 100644 --- a/src/main/java/com/glxp/api/service/collect/IoCollectOrderService.java +++ b/src/main/java/com/glxp/api/service/collect/IoCollectOrderService.java @@ -740,6 +740,10 @@ public class IoCollectOrderService extends ServiceImpl codeList = codeService.findByOrderId(orderEntity.getBillNo()); fifoInvService.insertInv(codeList, orderEntity); diff --git a/src/main/java/com/glxp/api/service/inout/IoSplitCodeService.java b/src/main/java/com/glxp/api/service/inout/IoSplitCodeService.java index e2daf264b..c02f96628 100644 --- a/src/main/java/com/glxp/api/service/inout/IoSplitCodeService.java +++ b/src/main/java/com/glxp/api/service/inout/IoSplitCodeService.java @@ -31,6 +31,7 @@ import com.glxp.api.util.IntUtil; import com.glxp.api.util.OrderNoTypeBean; import com.glxp.api.util.StringUtils; import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -72,10 +73,13 @@ public class IoSplitCodeService extends ServiceImpl filterList(IoSplitCodeRequest splitCodeRequest) { if (splitCodeRequest == null) { @@ -128,7 +132,6 @@ public class IoSplitCodeService extends ServiceImpl 0 ? count : 0).reCount(unCount).build()); if (count > 0) { ioSplitCodeEntity.setRemainCount(count); unCount = 0; @@ -140,6 +143,7 @@ public class IoSplitCodeService extends ServiceImpl 0 ? count : 0).reCount(unCount).build()); splitCodeMapper.updateById(ioSplitCodeEntity); } @@ -364,7 +368,7 @@ public class IoSplitCodeService extends ServiceImpl collectOrderCodeManList, IoCollectOrder collectOrder) { for (IoCollectOrderCodeMan collectOrderCodeMan : collectOrderCodeManList) { @@ -411,61 +415,248 @@ public class IoSplitCodeService extends ServiceImpl splitFifoCodeEntitys = splitFifoCodeService.findByRelId(workPlaceCode, codeEntity.getRelId(), codeEntity.getBatchNo(), null); -// if (CollUtil.isEmpty(splitFifoCodeEntitys)) { -// throw new JsonException(500, "工位库存不足!"); -// } + /** + * 工位退货扫码与自动赋码冲突解决方案 + */ + public void workReturnReplace(IoCodeEntity codeEntity, Long workPlaceCode) { + + IoSplitFifoCodeEntity ioSplitFifoCodeEntity = splitFifoCodeService.findByCode(codeEntity.getCode(), workPlaceCode); + if (ioSplitFifoCodeEntity == null) { + // 1.判断工位库存是否足够 + // 2.工位库存足够的话,判断已完成单是否存在, + // 3.存在的话,判断已完成单是否已上传医保 + // 4.已上传医保的话,调用医保删除接口 + + List splitFifoCodeEntitys = splitFifoCodeService.findByRelId(workPlaceCode, codeEntity.getRelId(), codeEntity.getBatchNo(), null); + if (CollUtil.isEmpty(splitFifoCodeEntitys)) { + throw new JsonException(500, "工位库存不足!"); + } // ioSplitFifoCodeEntity = splitFifoCodeEntitys.get(0); -// -// List collectCodeBackups = collectCodeBackMapper.selectList(new LambdaQueryWrapper().eq(IoCollectCodeBackup::getCode, ioSplitFifoCodeEntity.getCode())); -// if (CollUtil.isNotEmpty(collectCodeBackups)) { -// IoCollectCodeBackup collectCodeBackup = collectCodeBackups.get(0); -// -// if (IntUtil.value(collectCodeBackup.getFifoSplit()) == 3) { -// throw new JsonException(500, collectCodeBackup.getCode() + "重复扫码,请盘查后重试!"); -// } -// -// IoCollectOrderBackup collectOrderBackup = collectOrderBackupMapper.selectOne(new LambdaQueryWrapper().eq(IoCollectOrderBackup::getBillNo, collectCodeBackup.getBillNo())); -// // 单据已被上传至医保 -// if (IntUtil.value(collectOrderBackup.getUploadStatus()) == 2) { -// IoSplitFifoCodeEntity splitFifoCodeEntity = removeInvByCode(collectOrderCodeMan, collectOrder.getWorkPlaceCode()); -// if (splitFifoCodeEntity == null) { -// throw new JsonException(500, "工位存量不足!"); -// } -// IoCollectErrorLog ioCollectErrorLog = IoCollectErrorLog.builder().orderId(codeEntity.getOrderId()).autoCode(splitFifoCodeEntity.getCode()).manuCode(ioSplitFifoCodeEntity.getCode()).type(4) //已上传医保替换码 -// .updateTime(new Date()).build(); -// collectErrorLogMapper.insert(ioCollectErrorLog); -// collectCodeBackup.setCode(splitFifoCodeEntity.getCode()); -// collectCodeBackMapper.updateById(collectCodeBackup); -// -// } else { -// //单据未上传医保,上传医保失败 -// IoSplitFifoCodeEntity splitFifoCodeEntity = removeInvByCode(collectOrderCodeMan, collectOrder.getWorkPlaceCode()); -// if (splitFifoCodeEntity == null) { -// throw new JsonException(500, "工位存量不足!"); -// } -// IoCollectErrorLog ioCollectErrorLog = IoCollectErrorLog.builder().orderId(collectOrder.getId()).autoCode(splitFifoCodeEntity.getCode()).manuCode(collectOrderCodeMan.getUdiCode()).type(3) //未上传医保替换码 -// .updateTime(new Date()).build(); -// collectErrorLogMapper.insert(ioCollectErrorLog); -// //替换已完成单据的码 -// collectCodeBackup.setCode(splitFifoCodeEntity.getCode()); -// collectCodeBackMapper.updateById(collectCodeBackup); -// } -// } -// -// } -// -// } + List collectCodeBackups = collectCodeBackMapper.selectList(new LambdaQueryWrapper().eq(IoCollectCodeBackup::getCode, ioSplitFifoCodeEntity.getCode())); + if (CollUtil.isNotEmpty(collectCodeBackups)) { + IoCollectCodeBackup collectCodeBackup = collectCodeBackups.get(0); + + if (IntUtil.value(collectCodeBackup.getFifoSplit()) == 3) { + throw new JsonException(500, collectCodeBackup.getCode() + "重复扫码,请盘查后重试!"); + } + + IoCollectOrderBackup collectOrderBackup = collectOrderBackupMapper.selectOne(new LambdaQueryWrapper().eq(IoCollectOrderBackup::getBillNo, collectCodeBackup.getBillNo())); + + if (IntUtil.value(collectOrderBackup.getUploadStatus()) == 2) { + // 单据已被上传至医保 ---- 取当前库存的码替换至已完成单的码,并退库,以当前的码为退库单的码,并生成替换日志 + IoSplitFifoCodeEntity splitFifoCodeEntity = removeInvByCode(ioSplitFifoCodeEntity); + if (splitFifoCodeEntity == null) { + throw new JsonException(500, "工位存量不足!"); + } + + + IoCollectErrorLog ioCollectErrorLog = IoCollectErrorLog.builder().orderId(codeEntity.getOrderId()).autoCode(splitFifoCodeEntity.getCode()).manuCode(ioSplitFifoCodeEntity.getCode()).type(4) //退货已上传医保替换码 + .updateTime(new Date()).build(); + collectErrorLogMapper.insert(ioCollectErrorLog); + collectCodeBackup.setCode(splitFifoCodeEntity.getCode()); + collectCodeBackMapper.updateById(collectCodeBackup); + + // 若已完成单已上传医保,则当前已完成单的码就与医保实际已上传的码不匹配; + // 解决方案1: 调用医保接口删除当前单据,并重新把最新的单据上传; + + + // 解决方案2: 不管,保留替换记录 + + } else { + //单据未上传医保,上传医保失败 + IoSplitFifoCodeEntity splitFifoCodeEntity = removeInvByCode(ioSplitFifoCodeEntity); + if (splitFifoCodeEntity == null) { + throw new JsonException(500, "工位存量不足!"); + } + IoCollectErrorLog ioCollectErrorLog = IoCollectErrorLog.builder().orderId(codeEntity.getOrderId()).autoCode(splitFifoCodeEntity.getCode()).manuCode(codeEntity.getCode()).type(3) //退货未上传医保替换码 + .updateTime(new Date()).build(); + collectErrorLogMapper.insert(ioCollectErrorLog); + //替换已完成单据的码 + collectCodeBackup.setCode(splitFifoCodeEntity.getCode()); + collectCodeBackMapper.updateById(collectCodeBackup); + } + } + + } + + } + + + /** + * 后置拆零问题-1:校验是否需要后置拆零,更改单据状态 + */ + public void delaySplitVail(IoCollectOrderBackup collectOrder) { + List collectOrderBizBackups = ioCollectOrderBizBackupService.listByBillNo(collectOrder.getBillNo()); + for (IoCollectOrderBizBackup collectOrderBizBackup : collectOrderBizBackups) { + int unTagCount = collectOrderBizBackup.getUnTagCount(); + int remainder = 0; + FilterUdiRelRequest filterUdiRelRequest = new FilterUdiRelRequest(); + filterUdiRelRequest.setId(collectOrderBizBackup.getRelId()); + filterUdiRelRequest.setPackLevel("1"); + UdiRelevanceResponse udiRelevanceResponse = udiRelevanceService.selectOneUdi(filterUdiRelRequest); + + if (IntUtil.value(udiRelevanceResponse.getBhxjsl()) != 0) { + remainder = unTagCount % IntUtil.value(udiRelevanceResponse.getBhxjsl()); + if (remainder > 0) { + collectOrder.setTagStatus(6); //拆零未赋码 + } + break; + } + } + collectOrderBackupService.updateByBillNo(collectOrder); + } + + /** + * 后置拆零问题-2:后置拆零赋码 + */ + public void delaySplitTagCode() { + List collectOrderBackups = collectOrderBackupMapper.selectList(new LambdaQueryWrapper().eq(IoCollectOrderBackup::getTagStatus, 6)); + for (IoCollectOrderBackup collectOrderBackup : collectOrderBackups) { + List collectOrderBizBackups = ioCollectOrderBizBackupService.listByBillNo(collectOrderBackup.getBillNo()); + Boolean isFullTag = true; + for (IoCollectOrderBizBackup collectOrderBizBackup : collectOrderBizBackups) { + int unTagCount = IntUtil.value(collectOrderBizBackup.getUnTagCount()); + int remainder = 0; + FilterUdiRelRequest filterUdiRelRequest = new FilterUdiRelRequest(); + filterUdiRelRequest.setId(collectOrderBizBackup.getRelId()); + filterUdiRelRequest.setPackLevel("1"); + UdiRelevanceResponse udiRelevanceResponse = udiRelevanceService.selectOneUdi(filterUdiRelRequest); + + if (IntUtil.value(udiRelevanceResponse.getBhxjsl()) != 0) { + remainder = unTagCount % IntUtil.value(udiRelevanceResponse.getBhxjsl()); + if (remainder > 0) { + splitTagCode(collectOrderBizBackup, collectOrderBackup, null, false, null); + } + } + remainder = IntUtil.value(collectOrderBizBackup.getUnTagCount()) % IntUtil.value(udiRelevanceResponse.getBhxjsl()); + if (remainder != 0) { + isFullTag = false; + } + } + if (isFullTag) { + collectOrderBackup.setTagStatus(3); + collectOrderBackup.setTagMsg("赋码完成!"); + collectOrderBackupMapper.updateById(collectOrderBackup); + } + } + + } + + public void splitTagCode(IoCollectOrderBizBackup collectOrderBiz, IoCollectOrderBackup collectOrder, Long putWorkPlaceCode, Boolean isAuto, String confirmSplitCode) { + //1.按照先进先出原则,查询拆零表,获取拆零表ID + List ioSplitCodeEntities = findSplitCodes(collectOrderBiz.getRelId(), collectOrderBiz.getBatchNo(), putWorkPlaceCode); + List codeAutoList = new ArrayList<>(); + //2.如果拆零表为空,则自动从预出库队列中获拉取数据 + if (CollUtil.isEmpty(ioSplitCodeEntities)) { + addFifoCode(collectOrderBiz.getRelId(), collectOrderBiz.getBatchNo(), IntUtil.value(collectOrderBiz.getUnTagCount()), putWorkPlaceCode, confirmSplitCode); + ioSplitCodeEntities = findSplitCodes(collectOrderBiz.getRelId(), collectOrderBiz.getBatchNo(), putWorkPlaceCode); + } + //3.如果拆零表不为空,则开始扣除数量 + int count = 0; + int unCount = 0; //剩余未扣减数量 + unCount = IntUtil.value(collectOrderBiz.getUnTagCount()); + for (IoSplitCodeEntity ioSplitCodeEntity : ioSplitCodeEntities) { + count = IntUtil.value(ioSplitCodeEntity.getRemainCount()) - unCount; + if (count > 0) { + ioSplitCodeEntity.setRemainCount(count); + unCount = 0; + splitCodeMapper.updateById(ioSplitCodeEntity); + } else if (count == 0) { + ioSplitCodeEntity.setRemainCount(0); + unCount = 0; + } else { + ioSplitCodeEntity.setRemainCount(0); + unCount = -count; + } + IoCollectOrderCodeAuto collectOrderCodeAuto = IoCollectOrderCodeAuto.builder().codeIdFk(ioSplitCodeEntity.getId()).udiCode(ioSplitCodeEntity.getCode()).orderIdFk(collectOrder.getBillNo()).batchNo(ioSplitCodeEntity.getBatchNo()).productDate(ioSplitCodeEntity.getProduceDate()).expireDate(ioSplitCodeEntity.getExpireDate()).serialNo(ioSplitCodeEntity.getSerialNo()).relId(collectOrderBiz.getRelId()).bizIdFk(collectOrderBiz.getId()).fifoSplit(1).createTime(new Date()).updateTime(new Date()).count(count > 0 ? count : 0).reCount(unCount).build(); + collectOrderCodeAutoService.save(collectOrderCodeAuto); + codeAutoList.add(collectOrderCodeAuto); + splitCodeMapper.updateById(ioSplitCodeEntity); + } + + if (unCount > 0) { + //4.拆零表数量不足,则从预出库队列中获取数据 + Integer fifoCount = addFifoCode(collectOrderBiz.getRelId(), collectOrderBiz.getBatchNo(), unCount, putWorkPlaceCode, confirmSplitCode); + if (fifoCount == 0) { + //预出库队列数量不足 + collectOrderBiz.setTagStatus(2); + collectOrderBiz.setTagMsg("预出库队列码数量不足,赋码失败!"); + if (isAuto) + throw new JsonException(500, "提交失败," + collectOrderBiz.getCpmctymc() + "工位库存数量不足!"); + else return; + + } else { + //再次执行赋码 + ioSplitCodeEntities = findSplitCodes(collectOrderBiz.getRelId(), collectOrderBiz.getBatchNo(), putWorkPlaceCode); + for (IoSplitCodeEntity ioSplitCodeEntity : ioSplitCodeEntities) { + if (IntUtil.value(ioSplitCodeEntity.getRemainCount()) > 0) { + count = IntUtil.value(ioSplitCodeEntity.getRemainCount()) - unCount; + IoCollectOrderCodeAuto collectOrderCodeAuto = IoCollectOrderCodeAuto.builder().codeIdFk(ioSplitCodeEntity.getId()).udiCode(ioSplitCodeEntity.getCode()).orderIdFk(collectOrder.getBillNo()).batchNo(ioSplitCodeEntity.getBatchNo()).productDate(ioSplitCodeEntity.getProduceDate()).expireDate(ioSplitCodeEntity.getExpireDate()).serialNo(ioSplitCodeEntity.getSerialNo()).relId(collectOrderBiz.getRelId()).bizIdFk(collectOrderBiz.getId()).fifoSplit(count > 0 ? count : 0).reCount(count).createTime(new Date()).updateTime(new Date()).build(); + collectOrderCodeAutoService.save(collectOrderCodeAuto); + codeAutoList.add(collectOrderCodeAuto); + if (count > 0) { + ioSplitCodeEntity.setRemainCount(count); + splitCodeMapper.updateById(ioSplitCodeEntity); + unCount = 0; + break; + } else if (count == 0) { + ioSplitCodeEntity.setRemainCount(0); + unCount = 0; + splitCodeMapper.updateById(ioSplitCodeEntity); + } else { + ioSplitCodeEntity.setRemainCount(0); + splitCodeMapper.updateById(ioSplitCodeEntity); + unCount = -count; + } + } + } + if (unCount > 0) { + collectOrderBiz.setTagStatus(2); + collectOrderBiz.setTagMsg("预出库队列码数量不足,赋码失败!"); + if (isAuto) throw new JsonException(500, "工位库存数量不足!"); + else return; + } else { + collectOrderBiz.setTagStatus(3); + collectOrderBiz.setTagMsg("赋码完成!"); + } + } + } else { + collectOrderBiz.setTagStatus(3); + collectOrderBiz.setTagMsg("赋码完成!"); + } + collectOrderBiz.setUnTagCount(unCount); + ioCollectOrderBizBackupService.updateById(collectOrderBiz); + if (CollUtil.isNotEmpty(codeAutoList)) { + saveSplitCode(codeAutoList, collectOrder); + } + + } + + public void saveSplitCode(List codeAutoList, IoCollectOrderBackup collectOrder) { + if (CollUtil.isEmpty(codeAutoList)) + return; + List ioCollectCodes = new ArrayList<>(); + for (IoCollectOrderCodeAuto collectOrderCodeAuto : codeAutoList) { + UdiRelevanceResponse udiRelevanceResponse = udiRelevanceService.selectByRelId(collectOrderCodeAuto.getRelId() + ""); + ioCollectCodes.add(IoCollectCodeBackup.builder().code(collectOrderCodeAuto.getUdiCode()) + .fromType(collectOrder.getFromType()) + .busType(collectOrder.getBusType()) + .billNo(collectOrder.getBillNo()) + .fromCorp(collectOrder.getFromCorp()) + .operTime(collectOrder.getUpdateTime()) + .operUser(collectOrder.getCreateUser()) + .fifoSplit(1) + .relId(collectOrderCodeAuto.getRelId()) + .workPlaceCode(collectOrder.getWorkPlaceCode()) + .remark(collectOrder.getRemark()) + .purType(udiRelevanceResponse.getPurType()) + .inBatchNo(System.currentTimeMillis()) + .reCount(collectOrderCodeAuto.getReCount()) + .build()); + } + collectCodeBackService.saveBatch(ioCollectCodes); + } @Resource IoCollectErrorLogMapper collectErrorLogMapper; diff --git a/src/main/java/com/glxp/api/task/DelaySplitTagTask.java b/src/main/java/com/glxp/api/task/DelaySplitTagTask.java new file mode 100644 index 000000000..76a1fdaf5 --- /dev/null +++ b/src/main/java/com/glxp/api/task/DelaySplitTagTask.java @@ -0,0 +1,91 @@ +package com.glxp.api.task; + +import cn.hutool.core.thread.ThreadUtil; +import com.glxp.api.dao.schedule.ScheduledDao; +import com.glxp.api.entity.collect.IoCollectSet; +import com.glxp.api.entity.system.ScheduledEntity; +import com.glxp.api.req.system.ScheduledRequest; +import com.glxp.api.service.collect.IoCollectSetService; +import com.glxp.api.service.inout.IoSplitCodeService; +import com.glxp.api.util.IntUtil; +import com.glxp.api.util.RedisUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.SchedulingConfigurer; +import org.springframework.scheduling.config.ScheduledTaskRegistrar; +import org.springframework.scheduling.support.CronTrigger; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.concurrent.ExecutorService; + +@Component +@EnableScheduling +@Slf4j +public class DelaySplitTagTask implements SchedulingConfigurer { + + @Resource + protected ScheduledDao scheduledDao; + @Resource + IoSplitCodeService ioSplitCodeService; + @Resource + RedisUtil redisUtil; + @Resource + IoCollectSetService collectSetService; + + private volatile ExecutorService executor; + + private ExecutorService getExecutor() { + if (null == executor) { + synchronized (this) { + executor = ThreadUtil.newExecutor(5, 10, 60); + } + } + return executor; + } + + + @Override + public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { + + scheduledTaskRegistrar.addTriggerTask(() -> process(), triggerContext -> { + ScheduledRequest scheduledRequest = new ScheduledRequest(); + scheduledRequest.setCronName("delaySplitTagTask"); + ScheduledEntity scheduledEntity = scheduledDao.findScheduled(scheduledRequest); + if (scheduledEntity != null) { + String cron = scheduledEntity.getCron(); + if (cron.isEmpty()) { + log.error("cron is null"); + } + return new CronTrigger(cron).nextExecutionTime(triggerContext); + } else return null; + + }); + } + + private void process() { + String lockKey = "delaySplitTagTask_lock"; + IoCollectSet collectSet = collectSetService.getSet(); + if (IntUtil.value(collectSet.getDelayTageCode())) { + try { + // 尝试获取分布式锁,设置20*60秒超时 + boolean locked = (Boolean) redisUtil.get(lockKey); + if (locked) { + log.info("延迟分标定时任务已在其他节点执行中"); + return; + } + redisUtil.set(lockKey, true); + getExecutor().submit(() -> { + ioSplitCodeService.delaySplitTagCode(); + redisUtil.set(lockKey, false); + }); + } finally { + // 释放分布式锁 + redisUtil.set(lockKey, false); + log.info("延迟分标定时任务执行结束,已释放锁"); + } + } + + } +} diff --git a/src/main/java/com/glxp/api/task/SyncHeartService.java b/src/main/java/com/glxp/api/task/SyncHeartService.java index 00a813458..6e78a67ce 100644 --- a/src/main/java/com/glxp/api/task/SyncHeartService.java +++ b/src/main/java/com/glxp/api/task/SyncHeartService.java @@ -5,6 +5,7 @@ import com.glxp.api.constant.BasicExportTypeEnum; import com.glxp.api.dao.system.SyncDataSetDao; import com.glxp.api.entity.system.SyncDataSetEntity; import com.glxp.api.service.sync.HeartService; +import com.glxp.api.util.DateUtil; import com.glxp.api.util.RedisUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; @@ -59,6 +60,8 @@ public class SyncHeartService { } }); redisUtil.set("SPS_SYNC_UPLOAD_DATA", curTime1); + } else { + log.info("当前时间{},上次上传时间{},间隔时间{},不需要上传数据", DateUtil.formatDate(curTime1, "yyyy-MM-dd HH:mm:ss"), DateUtil.formatDate(lastTime1, "yyyy-MM-dd HH:mm:ss"), timeInterval1); } } catch (Exception e) { log.error(ExceptionUtils.getStackTrace(e)); diff --git a/src/main/java/com/glxp/api/task/SyncHeartTask.java b/src/main/java/com/glxp/api/task/SyncHeartTask.java index 91bce03e0..1a57344c5 100644 --- a/src/main/java/com/glxp/api/task/SyncHeartTask.java +++ b/src/main/java/com/glxp/api/task/SyncHeartTask.java @@ -1,11 +1,14 @@ package com.glxp.api.task; +import cn.hutool.core.thread.ThreadUtil; import com.glxp.api.dao.schedule.ScheduledDao; import com.glxp.api.dao.system.SyncDataSetDao; +import com.glxp.api.entity.collect.IoCollectSet; import com.glxp.api.entity.system.ScheduledEntity; import com.glxp.api.entity.system.SyncDataSetEntity; import com.glxp.api.req.system.ScheduledRequest; import com.glxp.api.service.sync.HeartService; +import com.glxp.api.util.IntUtil; import com.glxp.api.util.RedisUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.EnableScheduling; @@ -15,6 +18,7 @@ import org.springframework.scheduling.support.CronTrigger; import org.springframework.stereotype.Component; import javax.annotation.Resource; +import java.util.concurrent.ExecutorService; @Slf4j @Component @@ -31,6 +35,16 @@ public class SyncHeartTask implements SchedulingConfigurer { HeartService heartService; @Resource private SyncDataSetDao syncDataSetDao; + private volatile ExecutorService executor; + + private ExecutorService getExecutor() { + if (null == executor) { + synchronized (this) { + executor = ThreadUtil.newExecutor(10, 100, Integer.MAX_VALUE); + } + } + return executor; + } @Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { @@ -50,7 +64,29 @@ public class SyncHeartTask implements SchedulingConfigurer { private void process() { - syncHeartService.syncProcess(); + + + String lockKey = "syncProcessTask_lock"; + try { + // 尝试获取分布式锁,设置20*60秒超时 + boolean locked = (Boolean) redisUtil.get(lockKey); + if (locked) { + log.info("延迟分标定时任务已在其他节点执行中"); + return; + } + redisUtil.set(lockKey, true); + getExecutor().submit(() -> { + syncHeartService.syncProcess(); + redisUtil.set(lockKey, false); + }); + + } finally { + // 释放分布式锁 + redisUtil.set(lockKey, false); + log.info("延迟分标定时任务执行结束,已释放锁"); + } + + } diff --git a/src/main/resources/schemas/schema_v2.4.sql b/src/main/resources/schemas/schema_v2.4.sql index 83aa86cd6..abcf94a11 100644 --- a/src/main/resources/schemas/schema_v2.4.sql +++ b/src/main/resources/schemas/schema_v2.4.sql @@ -5269,13 +5269,13 @@ ALTER TABLE rel_code_batch CALL Pro_Temp_ColumnWork('io_code_temp', 'bizId', - 'bigint DEFAULT NULL COMMENT ''biz表主键''', - 1); + 'bigint DEFAULT NULL COMMENT ''biz表主键''', + 1); CALL Pro_Temp_ColumnWork('io_code_lost', 'bizId', - 'bigint DEFAULT NULL COMMENT ''biz表主键''', - 1); + 'bigint DEFAULT NULL COMMENT ''biz表主键''', + 1); CALL Pro_Temp_ColumnWork('basic_corp', 'aliEntId', 'varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT ''阿里供应商ID''', @@ -5443,14 +5443,12 @@ CALL Pro_Temp_ColumnWork('io_order', 'fifoSplitTag', - CALL Pro_Temp_ColumnWork('io_collect_set', 'drugDealConfirm', ' tinyint NULL DEFAULT b''0''COMMENT ''是否允许取药整单确认''', 1); - CALL Pro_Temp_ColumnWork('basic_udirel', 'manuReview', 'tinyint NULL DEFAULT b''0'' COMMENT ''是否已人工审核''', 1); @@ -5471,23 +5469,30 @@ CALL Pro_Temp_ColumnWork('basic_udirel', 'hangingNetType', ' tinyint DEFAULT NULL COMMENT ''是否挂网 0 否 1 是''', 1); -CREATE TABLE IF NOT EXISTS `yb_not_code` ( - `ybbm` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '国家医保目录编码', +CREATE TABLE IF NOT EXISTS `yb_not_code` +( + `ybbm` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '国家医保目录编码', `organizationCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '机构编码', - `notCodeType` tinyint DEFAULT NULL COMMENT '无码类型 0、默认不是无码类型;1、部分早期未赋予追溯码;5、最小包装无追溯码;6、无追溯码;7、其他原因', + `notCodeType` tinyint DEFAULT NULL COMMENT '无码类型 0、默认不是无码类型;1、部分早期未赋予追溯码;5、最小包装无追溯码;6、无追溯码;7、其他原因', PRIMARY KEY (`ybbm`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='医保无码信息表'; - +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE = utf8mb4_0900_ai_ci COMMENT ='医保无码信息表'; -CREATE TABLE IF NOT EXISTS `io_collect_set_bustype` ( - `id` int NOT NULL AUTO_INCREMENT, - `setCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, - `busType` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, - `updateTime` datetime NULL DEFAULT NULL, - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '自动设置单据类型配置' ROW_FORMAT = Dynamic; +CREATE TABLE IF NOT EXISTS `io_collect_set_bustype` +( + `id` int NOT NULL AUTO_INCREMENT, + `setCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `busType` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, + `updateTime` datetime NULL DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB + AUTO_INCREMENT = 4 + CHARACTER SET = utf8mb4 + COLLATE = utf8mb4_0900_ai_ci COMMENT = '自动设置单据类型配置' + ROW_FORMAT = Dynamic; INSERT IGNORE INTO sys_scheduled(`id`, `cronName`, `cron`, `customerId`, `remark`) @@ -5506,25 +5511,28 @@ CALL Pro_Temp_ColumnWork('io_collect_order_code_man', 'autoCode', - - CALL Pro_Temp_ColumnWork('io_collect_order_backup', 'uploadYbTime', ' datetime DEFAULT NULL COMMENT ''医保上传时间''', 1); -CREATE TABLE IF NOT EXISTS `io_collect_error_log` ( - `id` int NOT NULL AUTO_INCREMENT, - `orderId` bigint NULL DEFAULT NULL COMMENT '单据号', - `autoCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '自动赋码', - `manuCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '手动赋码', - `type` int NULL DEFAULT NULL COMMENT '错误类型:1:未上传医保替换码;2:已上传替换码', - `updateTime` datetime NULL DEFAULT NULL COMMENT '更新时间', - `updateUser` datetime NULL DEFAULT NULL COMMENT '更新人', - `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic COMMENT='手动扫码冲突替换码信息'; +CREATE TABLE IF NOT EXISTS `io_collect_error_log` +( + `id` int NOT NULL AUTO_INCREMENT, + `orderId` bigint NULL DEFAULT NULL COMMENT '单据号', + `autoCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '自动赋码', + `manuCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '手动赋码', + `type` int NULL DEFAULT NULL COMMENT '错误类型:1:未上传医保替换码;2:已上传替换码', + `updateTime` datetime NULL DEFAULT NULL COMMENT '更新时间', + `updateUser` datetime NULL DEFAULT NULL COMMENT '更新人', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB + AUTO_INCREMENT = 1 + CHARACTER SET = utf8mb4 + COLLATE = utf8mb4_0900_ai_ci + ROW_FORMAT = Dynamic COMMENT ='手动扫码冲突替换码信息'; CALL Pro_Temp_ColumnWork('inv_product_batch', 'status', 'int NULL DEFAULT NULL COMMENT ''状态(1:正常,0:已清空)''', @@ -5532,29 +5540,34 @@ CALL Pro_Temp_ColumnWork('inv_product_batch', 'status', -CREATE TABLE IF NOT EXISTS `inv_product_record` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', - `productId` bigint NULL DEFAULT NULL COMMENT '产品ID', - `warehouseId` bigint NULL DEFAULT NULL COMMENT '仓库ID', - `inBatchNo` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '内部批号', - `batchNo` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '批次号', - `orderId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '关联单据号', - `orderType` tinyint NULL DEFAULT NULL COMMENT '单据类型(1:入库,2:出库)', - `quantity` decimal(10, 2) NULL DEFAULT NULL COMMENT '操作数量', - `unitPrice` decimal(10, 2) NULL DEFAULT NULL COMMENT '单价', - `beforeQuantity` decimal(10, 2) NULL DEFAULT NULL COMMENT '操作前数量', - `afterQuantity` decimal(10, 2) NULL DEFAULT NULL COMMENT '操作后数量', - `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', - `creator` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建人', - `createTime` datetime NULL DEFAULT NULL COMMENT '创建时间', - `updateTime` datetime NULL DEFAULT NULL COMMENT '更新时间', - `updater` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '更新人', - `tenantId` bigint NULL DEFAULT NULL COMMENT '租户ID', - PRIMARY KEY (`id`) USING BTREE, - INDEX `idx_productId`(`productId` ASC) USING BTREE, - INDEX `idx_orderId`(`orderId` ASC) USING BTREE, - INDEX `idx_createTime`(`createTime` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '库存流水表' ROW_FORMAT = DYNAMIC; +CREATE TABLE IF NOT EXISTS `inv_product_record` +( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `productId` bigint NULL DEFAULT NULL COMMENT '产品ID', + `warehouseId` bigint NULL DEFAULT NULL COMMENT '仓库ID', + `inBatchNo` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '内部批号', + `batchNo` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '批次号', + `orderId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '关联单据号', + `orderType` tinyint NULL DEFAULT NULL COMMENT '单据类型(1:入库,2:出库)', + `quantity` decimal(10, 2) NULL DEFAULT NULL COMMENT '操作数量', + `unitPrice` decimal(10, 2) NULL DEFAULT NULL COMMENT '单价', + `beforeQuantity` decimal(10, 2) NULL DEFAULT NULL COMMENT '操作前数量', + `afterQuantity` decimal(10, 2) NULL DEFAULT NULL COMMENT '操作后数量', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `creator` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建人', + `createTime` datetime NULL DEFAULT NULL COMMENT '创建时间', + `updateTime` datetime NULL DEFAULT NULL COMMENT '更新时间', + `updater` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '更新人', + `tenantId` bigint NULL DEFAULT NULL COMMENT '租户ID', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_productId` (`productId` ASC) USING BTREE, + INDEX `idx_orderId` (`orderId` ASC) USING BTREE, + INDEX `idx_createTime` (`createTime` ASC) USING BTREE +) ENGINE = InnoDB + AUTO_INCREMENT = 8 + CHARACTER SET = utf8mb4 + COLLATE = utf8mb4_0900_ai_ci COMMENT = '库存流水表' + ROW_FORMAT = DYNAMIC; CALL Pro_Temp_ColumnWork('io_collect_order_origin', 'summaryNo', @@ -5568,6 +5581,15 @@ CALL Pro_Temp_ColumnWork('io_collect_order_backup', 'summaryNo', 1); +INSERT IGNORE INTO `sys_scheduled` (`id`, `cronName`, `cron`, `customerId`, `remark`) +VALUES (3021, 'delaySplitTagTask', '0 */1 * * * ?', NULL, '后置拆零赋码定时任务'); + + +CALL Pro_Temp_ColumnWork('io_collect_set', 'delayTageCode', + 'tinyint NULL DEFAULT NULL COMMENT ''是否启用后置赋码:1:是;0:否''', + 1); + + CREATE TABLE IF NOT EXISTS `yb_uploading_log` ( `id` int NOT NULL AUTO_INCREMENT, `ybParam` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '医保入参',