package com.glxp.api.service.inout ;
import cn.hutool.core.collection.CollUtil ;
import cn.hutool.core.util.IdUtil ;
import cn.hutool.core.util.StrUtil ;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper ;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper ;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper ;
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.dao.inout.IoOrderDetailCodeDao ;
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.apache.commons.lang3.exception.ExceptionUtils ;
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 ) {
IoCollectSet collectSet = collectSetService . getSet ( ) ;
long startTime = System . currentTimeMillis ( ) ;
AddCodeResult addCodeResult = new AddCodeResult ( ) ;
List < String > codeList = addOrderCodeRequest . getCodeList ( ) ;
List < VailCodeResultResponse > vailCodeResultResponses = new ArrayList < > ( ) ;
if ( CollUtil . isEmpty ( codeList ) ) {
return ResultVOUtils . error ( 500 , "追溯码不能为空" ) ;
}
log . info ( "批量处理药品码开始,共{}个" , codeList . size ( ) ) ;
// 1. 预处理:标准化追溯码列表
List < String > processedCodes = codeList . stream ( ) . filter ( StringUtils : : isNotBlank ) . map ( String : : trim ) . map ( code - > code . endsWith ( "\u001D" ) ? code . replace ( "\u001D" , "" ) : code ) . collect ( Collectors . toList ( ) ) ;
// 2. 批量解析UDI实体
Map < String , UdiEntity > udiEntityMap = new HashMap < > ( ) ;
Map < String , String > nameCodes = new HashMap < > ( ) ;
for ( String code : processedCodes ) {
UdiEntity udiEntity = FilterUdiUtils . getUdi ( code ) ;
if ( udiEntity ! = null & & StrUtil . isNotEmpty ( udiEntity . getUdi ( ) ) ) {
udiEntityMap . put ( code , udiEntity ) ;
nameCodes . put ( udiEntity . getUdi ( ) , code ) ;
} else {
VailCodeResultResponse invalidResponse = new VailCodeResultResponse ( ) ;
invalidResponse . setCode ( code ) ;
invalidResponse . setStatus ( 2 ) ;
invalidResponse . setErrMsg ( "无效条码" ) ;
vailCodeResultResponses . add ( invalidResponse ) ;
}
}
if ( udiEntityMap . isEmpty ( ) ) {
addCodeResult . setVailCodeResultResponses ( vailCodeResultResponses ) ;
addCodeResult . setOrderId ( addOrderCodeRequest . getBillNo ( ) ) ;
return ResultVOUtils . success ( addCodeResult ) ;
}
// 3. 批量获取共享数据
// 获取订单信息
IoOrderEntity ioOrderEntity = orderService . findCorpOrderId ( addOrderCodeRequest . getCorpOrderId ( ) ) ;
String orderId = ioOrderEntity ! = null ? ioOrderEntity . getBillNo ( ) : null ;
// 获取业务类型
String action = addOrderCodeRequest . 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 ;
if ( StrUtil . isNotEmpty ( addOrderCodeRequest . getInvCode ( ) ) ) {
invCode = addOrderCodeRequest . getInvCode ( ) ;
} else
// 获取仓库信息
invCode = authAdmin . getLocInvCode ( ) ;
if ( StrUtil . isEmpty ( addOrderCodeRequest . getFromCorp ( ) ) )
addOrderCodeRequest . setFromCorp ( ConstantType . SPLIT_CORP ) ;
// 批量获取UDI相关信息
List < String > udiCodes = new ArrayList < > ( ) ;
nameCodes . keySet ( ) . forEach ( code - > udiCodes . add ( code ) ) ;
Map < String , UdiRelevanceResponse > udiRelevanceMap = udiRelevanceService . batchSelectByNameCodes ( udiCodes ) ;
if ( udiRelevanceMap = = null | | udiRelevanceMap . size ( ) = = 0 ) {
return ResultVOUtils . error ( 500 , "药品字典不存在此产品!" ) ;
}
// 获取已存在的码记录
Map < String , IoCodeTempEntity > existingCodesMap = new HashMap < > ( ) ;
if ( StringUtils . isNotBlank ( orderId ) ) {
existingCodesMap = codeTempService . batchCheckCodesExistence ( processedCodes , orderId ) ;
}
for ( Map . Entry < String , IoCodeTempEntity > 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 ) ;
}
}
InvWarehouseEntity invWarehouseEntity = invWarehouseService . findByInvSubByCode ( invCode ) ;
// 4. 获取组编号
Integer groupNumber = getMaxGroupNumber ( ) = = null ? 1 : getMaxGroupNumber ( ) + 1 ;
// 5. 配置线程池
int processors = Runtime . getRuntime ( ) . availableProcessors ( ) ;
ExecutorService executor = Executors . newFixedThreadPool ( Math . min ( processors * 2 , 10 ) ) ;
// 准备请求参数
AddOrderRequest addOrderRequest = new AddOrderRequest ( ) ;
BeanUtils . copyProperties ( addOrderCodeRequest , addOrderRequest ) ;
addOrderRequest . setBillNo ( orderId ) ;
addOrderRequest . setInvCode ( invCode ) ;
IoOrderEntity isExit = orderService . findByBillNo ( orderId ) ;
IoOrderEntity orderEntity = new IoOrderEntity ( ) ;
if ( isExit = = null ) {
String orderNo = gennerOrderUtils . createScOrderNo ( new OrderNoTypeBean ( Constant . SCAN_ORDER + StrUtil . trimToEmpty ( bussinessTypeEntity . getPrefix ( ) ) , "yyyyMMdd" ) ) ;
orderEntity . setBillNo ( orderNo ) ;
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 ) ;
addOrderRequest . setBillNo ( orderNo ) ;
} else orderEntity = isExit ;
try {
// 创建异步任务
List < CompletableFuture < VailCodeResultResponse > > 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 . setCode ( code ) ;
if ( IntUtil . value ( addOrderCodeRequest . getInoutType ( ) ) = = 2 ) {
addOrderRequest . setAction ( ConstantType . SPLIT_RETURN ) ;
} else {
addOrderRequest . setAction ( ConstantType . SPLIT_OUT ) ;
}
// 设置批次信息
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 , invWarehouseEntity , collectSet ) ;
// 处理结果
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 ( "处理追溯码异常: {}, 码值: {}" , ExceptionUtils . getStackTrace ( e ) , 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 ( ) ;
}
List < String > successCodes = new ArrayList < > ( ) ;
vailCodeResultResponses . forEach ( vailCodeResultResponse - > {
if ( vailCodeResultResponse . getStatus ( ) = = 1 ) {
successCodes . add ( vailCodeResultResponse . getCode ( ) ) ;
}
} ) ;
if ( CollUtil . isNotEmpty ( successCodes ) ) {
List < IoCodeTempEntity > codeTempEntities = codeTempService . selectByCodes ( successCodes , orderEntity . getBillNo ( ) ) ;
genOrderDetailCodeBatch ( orderEntity , codeTempEntities ) ;
}
addCodeResult . setOrderId ( orderEntity . getBillNo ( ) ) ;
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 , InvWarehouseEntity invWarehouseEntity , IoCollectSet collectSet ) {
AddCodeResult addCodeResult = new AddCodeResult ( ) ;
// 检查码是否空
if ( udiEntity = = null ) {
return ResultVOUtils . error ( 500 , "无效条码" ) ;
}
if ( IntUtil . value ( collectSet . getNoCodeScan ( ) ) & & IntUtil . value ( udiRelevanceResponse . getNotCodeType ( ) ) ! = 0 & & ( bussinessTypeEntity . getAction ( ) . equals ( ConstantType . SPLIT_OUT ) | | bussinessTypeEntity . getAction ( ) . equals ( ConstantType . SPLIT_RETURN ) ) ) {
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 ;
}
if ( bussinessTypeEntity . getAction ( ) . equals ( ConstantType . SPLIT_OUT ) | | bussinessTypeEntity . getAction ( ) . equals ( ConstantType . SPLIT_RETURN ) ) {
// 工位上货相关校验
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. 优化订单处理流程
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 < IoCodeTempEntity > 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 < UdiRelevanceResponse > 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 ( ) ;
}
}
orderEntity . setWorkPlaceQueueCode ( queueCode ) ;
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 < IoCollectOrderCodeMan > ( ) . 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 < UdiRelevanceResponse > 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 ;
}
}
if ( bussinessTypeEntity . getAction ( ) . equals ( ConstantType . SPLIT_OUT ) ) {
//工位上货 只允许上货一个产品 开关以及控制
// IoCollectSet collectSet = collectSetService.getSet();
// 判断货位里面是否有相同产品
if ( orderEntity ! = null & & StrUtil . isNotEmpty ( orderEntity . getWorkPlaceQueueCode ( ) ) ) {
SysWorkplace sysWorkplace = sysWorkplaceService . getOne ( new LambdaQueryWrapper < SysWorkplace > ( ) . eq ( SysWorkplace : : getWorkplaceId , addOrderRequest . getWorkPlaceCode ( ) ) ) ;
if ( sysWorkplace . getQueueStatus ( ) = = 1 ) {
SysWorkplaceQueue workplaceQueue = sysWorkplaceQueueService . getOne ( new LambdaQueryWrapper < SysWorkplaceQueue > ( ) . 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 < SysWorkplaceQueue > ( ) . eq ( SysWorkplaceQueue : : getRelId , udiRelevanceResponse . getId ( ) ) ) ;
if ( workplaceQueue1 ! = null ) {
String freightCode = workplaceQueue1 . getFreightCode ( ) ;
SysWorkplaceFreight one = sysWorkplaceFreightService . getOne ( new LambdaQueryWrapper < SysWorkplaceFreight > ( ) . 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 < SysWorkplaceQueue > ( ) . eq ( SysWorkplaceQueue : : getCode , orderEntity . getWorkPlaceQueueCode ( ) ) . last ( "limit 1" ) ) ;
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 ) ;
}
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 ;
}
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, codeEnttity);
codeTempService . insert ( codeEnttity ) ;
updateRelCode ( bussinessTypeEntity , code ) ;
// 查询是否存在药品关联信息 后将结果更新至 temp表
// relCodeBatchService.threadUpdateIoCodeTempEntity(code);
}
}
orderService . update ( orderEntity ) ;
addCodeResult . setOrderId ( orderId ) ;
// genOrderDetailCode(orderEntity, genDetaiEntity);
return ResultVOUtils . success ( addCodeResult ) ;
}
@Resource
private IoOrderDetailCodeDao orderDetailCodeDao ;
/ * *
* 批 量 处 理 码 实 体 生 成 订 单 明 细 码
*
* @param orderEntity 订 单 实 体
* @param codeTempEntities 码 实 体 列 表
* @return 处 理 后 的 订 单 明 细 码 列 表
* /
public List < IoOrderDetailCodeEntity > genOrderDetailCodeBatch ( IoOrderEntity orderEntity , List < IoCodeTempEntity > codeTempEntities ) {
if ( CollUtil . isEmpty ( codeTempEntities ) ) {
return Collections . emptyList ( ) ;
}
// 按照关联ID和批次号分组码实体
Map < String , List < IoCodeTempEntity > > groupedTempEntities = codeTempEntities . stream ( ) . collect ( Collectors . groupingBy ( entity - > entity . getRelId ( ) + ":" + StrUtil . trimToEmpty ( entity . getBatchNo ( ) ) ) ) ;
// 使用synchronized块来保护关键部分
// 获取当前订单的所有明细码
// 处理每个分组
for ( Map . Entry < String , List < IoCodeTempEntity > > entry : groupedTempEntities . entrySet ( ) ) {
List < IoCodeTempEntity > group = entry . getValue ( ) ;
if ( CollUtil . isEmpty ( group ) ) {
continue ;
}
IoCodeTempEntity representative = group . get ( 0 ) ;
UdiRelevanceResponse udiRelevanceResponse = udiRelevanceService . selectSupGroupById ( representative . getRelId ( ) , representative . getSupId ( ) ) ;
// 计算该组的总数量
int totalCount = group . stream ( ) . mapToInt ( IoCodeTempEntity : : getMyCount ) . sum ( ) ;
int totalReCount = group . stream ( ) . mapToInt ( IoCodeTempEntity : : getMyReCount ) . sum ( ) ;
// 在数据库层面使用悲观锁或乐观锁查询现有记录
IoOrderDetailCodeEntity existingEntity = orderDetailCodeDao . selectOne ( new QueryWrapper < IoOrderDetailCodeEntity > ( ) . eq ( "orderIdFk" , orderEntity . getBillNo ( ) ) . eq ( "bindRlFk" , representative . getRelId ( ) ) . eq ( StrUtil . isNotEmpty ( representative . getBatchNo ( ) ) , "batchNo" , representative . getBatchNo ( ) ) . last ( "limit 1 FOR UPDATE" ) ) ; // 添加行级锁
IoOrderDetailCodeEntity resultDetailEntity ;
if ( existingEntity ! = null ) {
// 更新现有明细码的数量
existingEntity . setCount ( existingEntity . getCount ( ) + totalCount ) ;
existingEntity . setReCount ( existingEntity . getReCount ( ) + totalReCount ) ;
existingEntity . setUpdateTime ( new Date ( ) ) ;
orderDetailCodeDao . updateCount ( existingEntity ) ;
resultDetailEntity = existingEntity ;
} else {
// 创建新记录
resultDetailEntity = buildEntity ( orderEntity , representative , udiRelevanceResponse , totalCount , totalReCount ) ;
orderDetailCodeDao . insert ( resultDetailEntity ) ;
}
// 批量更新价格信息
List < IoCodeTempEntity > updateBatch = new ArrayList < > ( ) ;
for ( IoCodeTempEntity entity : group ) {
if ( entity . getPrice ( ) = = null & & udiRelevanceResponse ! = null & & udiRelevanceResponse . getPrice ( ) ! = null ) {
entity . setPrice ( udiRelevanceResponse . getPrice ( ) ) ;
}
entity . setBizId ( resultDetailEntity . getId ( ) ) ;
updateBatch . add ( entity ) ;
}
// 批量更新以提高性能
if ( ! updateBatch . isEmpty ( ) ) {
codeTempService . batchUpdate ( updateBatch ) ;
}
}
// 返回最新的明细码列表
return orderDetailCodeDao . selectList ( new QueryWrapper < IoOrderDetailCodeEntity > ( ) . select ( "id" , "count" , "reCount" , "bindRlFk" , "batchNo" , "price" ) . eq ( "orderIdFk" , orderEntity . getBillNo ( ) ) ) ;
}
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 ) ) {
IoCollectSet collectSet = collectSetService . getSet ( ) ;
if ( ! IntUtil . value ( collectSet . getConflictReturn ( ) ) ) {
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 < IoCodeTempEntity > codeEnttityList ) {
List < IoCodeTempEntity > codeTempEntities = isExitLocalList ( code , codeEnttityList ) ;
if ( CollUtil . isNotEmpty ( codeTempEntities ) ) {
return codeTempEntities . get ( 0 ) ;
}
return null ;
}
public List < IoCodeTempEntity > isExitLocalList ( String code , List < IoCodeTempEntity > codeEnttityList ) {
UdiEntity udiEntity = FilterUdiUtils . getUdi ( code ) ;
List < IoCodeTempEntity > 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 < UdiRelevanceResponse > 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 < UdiRlSupResponse > datas = udiRlSupService . filterUdiGp ( companyProductRelevanceRequest ) ;
if ( datas . size ( ) < = 0 ) {
return ResultVOUtils . error ( 500 , "当前供应商不存在此配送产品!" ) ;
}
} else {
List < UdiRlSupResponse > 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 < IoCodeTempEntity > 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 < IoCodeTempEntity > 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 ;
}
IoOrderDetailCodeEntity buildEntity ( IoOrderEntity orderEntity , IoCodeTempEntity codeTempEntity , UdiRelevanceResponse udiRelevanceResponse , int totalCount , int totalReCount ) {
IoOrderDetailCodeEntity ioOrderDetailCodeEntity = new IoOrderDetailCodeEntity ( ) ;
ioOrderDetailCodeEntity . setId ( IdUtil . getSnowflakeNextId ( ) ) ;
ioOrderDetailCodeEntity . setOrderIdFk ( orderEntity . getBillNo ( ) ) ;
ioOrderDetailCodeEntity . setBindRlFk ( udiRelevanceResponse . getId ( ) ) ;
ioOrderDetailCodeEntity . setUuidFk ( udiRelevanceResponse . getUuid ( ) ) ;
ioOrderDetailCodeEntity . setBatchNo ( codeTempEntity . getBatchNo ( ) ) ;
ioOrderDetailCodeEntity . setNameCode ( codeTempEntity . getNameCode ( ) ) ;
ioOrderDetailCodeEntity . setProductDate ( codeTempEntity . getProduceDate ( ) ) ;
ioOrderDetailCodeEntity . setExpireDate ( codeTempEntity . getExpireDate ( ) ) ;
ioOrderDetailCodeEntity . setCoName ( udiRelevanceResponse . getCpmctymc ( ) ) ;
ioOrderDetailCodeEntity . setCertCode ( udiRelevanceResponse . getZczbhhzbapzbh ( ) ) ;
ioOrderDetailCodeEntity . setYlqxzcrbarmc ( udiRelevanceResponse . getYlqxzcrbarmc ( ) ) ;
ioOrderDetailCodeEntity . setManufacturer ( udiRelevanceResponse . getManufactory ( ) ) ;
ioOrderDetailCodeEntity . setMeasname ( udiRelevanceResponse . getMeasname ( ) ) ;
if ( StrUtil . isEmpty ( udiRelevanceResponse . getGgxh ( ) ) ) {
ioOrderDetailCodeEntity . setSpec ( udiRelevanceResponse . getBzgg ( ) ) ;
} else ioOrderDetailCodeEntity . setSpec ( udiRelevanceResponse . getGgxh ( ) ) ;
if ( StrUtil . isEmpty ( udiRelevanceResponse . getMeasname ( ) ) ) {
ioOrderDetailCodeEntity . setMeasname ( udiRelevanceResponse . getUseLevelUnit ( ) ) ;
}
ioOrderDetailCodeEntity . setSupId ( codeTempEntity . getSupId ( ) ) ;
ioOrderDetailCodeEntity . setProductType ( codeTempEntity . getProductType ( ) ) ;
if ( codeTempEntity . getPrice ( ) = = null ) {
ioOrderDetailCodeEntity . setPrice ( udiRelevanceResponse . getPrice ( ) ) ;
codeTempEntity . setPrice ( udiRelevanceResponse . getPrice ( ) ) ;
codeTempService . updateById ( codeTempEntity ) ;
} else {
ioOrderDetailCodeEntity . setPrice ( codeTempEntity . getPrice ( ) ) ;
}
ioOrderDetailCodeEntity . setCount ( totalCount ) ;
ioOrderDetailCodeEntity . setReCount ( totalReCount ) ;
ioOrderDetailCodeEntity . setUpdateTime ( new Date ( ) ) ;
return ioOrderDetailCodeEntity ;
}
}