Index: ssts-invoice/src/main/java/com/forgon/disinfectsystem/invoicemanager/service/InvoiceManagerImpl.java =================================================================== diff -u -r35375 -r35383 --- ssts-invoice/src/main/java/com/forgon/disinfectsystem/invoicemanager/service/InvoiceManagerImpl.java (.../InvoiceManagerImpl.java) (revision 35375) +++ ssts-invoice/src/main/java/com/forgon/disinfectsystem/invoicemanager/service/InvoiceManagerImpl.java (.../InvoiceManagerImpl.java) (revision 35383) @@ -3354,8 +3354,8 @@ @Override public SubmitInvoiceContext disposableGoodsCustomBatchInvoice(JSONObject params){ //性能测试用的语句 - /*long start = System.currentTimeMillis(); - long startTimeMillis = start;*/ +// long start = System.currentTimeMillis(); +// long startTimeMillis = start; SubmitInvoiceContext submitInvoiceContext = new SubmitInvoiceContext(); Map departCodeToInvoiceRemarkMap = new HashMap(); //为了便于后面clone对象,改为声明成HashMap实现类类型的变量 @@ -4177,6 +4177,46 @@ JSONObject params,Map departCodeToOrgUnitMap,Map departCodeToDefaultWarehouseMap, List disposableGoodsStorageAdjustVoTotalList){ if(MapUtils.isNotEmpty(departCodeToDgIdToIdentificationToAmountMapMapMap)){ + //根据定义id及批次定义id查找相应的库存及批次库存对象(加锁) + List sourceStockList = + objectDao.getBySql_ForUpdate2(DisposableGoodsStock.class.getSimpleName(), + String.format("where warehouseID=%s and %s", + params.optLong("sourceWarehouseId"), + SqlUtils.getNonStringFieldInLargeCollectionsPredicate("disposableGoodsID", idToDisposableGoodsMap.keySet()))); + //源仓库的一次性物品库存的相关对象 + //一次性物品定义id对应的源发货仓库的库存对象 + Map dgIdToSourceDisposableGoodsStockMap = new HashMap(); + //用于更新库存扣减的map对象,key为一次性物品库存id,value为扣减的数量(最后的批量update库存逻辑移至循环体之后) + Map disaposableGoodsStockIdToDecreaseAmountUpdateMap = new HashMap(); + sourceStockList.stream().forEach(stock -> { + dgIdToSourceDisposableGoodsStockMap.put(stock.getDisposableGoodsID(), stock); + }); + //各一次性物品库存id对应已匹配的需要发货扣减的数量(遍历完各科室后,需将数量叠加) + Map stockIdToTotalDeductionMap = new HashMap(); + + + //源仓库的批次库存的相关对象 + //一次性物品批次定义id对应的源发货仓库的库存对象 + Map batchIdToSourceDisposableGoodsBatchStockMap = new HashMap(); + //用于更新库存扣减的map对象,key为一次性物品库存id,value为扣减的数量(最后的批量update库存逻辑移至循环体之后) + Map disaposableGoodsBatchStockIdToDecreaseAmountUpdateMap = new HashMap(); + List sourceBatchStockList = + objectDao.getBySql_ForUpdate2(DisposableGoodsBatchStock.class.getSimpleName(), + String.format("where warehouseID=%s and %s", + params.optLong("sourceWarehouseId"), + SqlUtils.getNonStringFieldInLargeCollectionsPredicate("disposableGoodsBatchId", idToDisposableGoodsBatchMap.keySet()))); + sourceBatchStockList.stream().forEach(batchStock -> { + batchIdToSourceDisposableGoodsBatchStockMap.put(batchStock.getDisposableGoodsBatchId(), batchStock); + }); + //各一次性物品批次库存id对应已匹配的需要发货扣减的数量(遍历完各科室后,需将数量叠加) + Map batchStockIdToTotalDeductionMap = new HashMap(); + + //目标仓库:一次性物品批次库存需要新增的库存数量map + Map disaposableGoodsStockIdToIncreaseAmountUpdateMap = new HashMap(); + //目标仓库:一次性物品批次库存需要新增的库存数量map + Map disaposableGoodsBatchStockIdToIncreaseAmountUpdateMap = new HashMap(); + + //第1层循环:遍历科室 for(Entry>> entryDepart : departCodeToDgIdToIdentificationToAmountMapMapMap.entrySet()){ //源科室的标识数据数量调整集合 @@ -4216,117 +4256,35 @@ } dgIdToAmountMap.put(dgId, adjustAmountOfDg); } - //根据定义id及批次定义id查找相应的库存及批次库存对象(加锁) - List sourceStockList = - objectDao.getBySql_ForUpdate2(DisposableGoodsStock.class.getSimpleName(), - String.format("where warehouseID=%s and %s", - params.optLong("sourceWarehouseId"), - SqlUtils.getNonStringFieldInLargeCollectionsPredicate("disposableGoodsID", dgIdToAmountMap.keySet()))); - List dgIdList = sourceStockList.stream().map(DisposableGoodsStock::getDisposableGoodsID).collect(Collectors.toList()); //如果未找到相关物品的源发货仓库的库存对象时,则进行提示 - dgIdToAmountMap.keySet().stream().forEach(dgId -> { - if(!dgIdList.contains(dgId)){ + for(Entry entry : dgIdToAmountMap.entrySet()) { + Long dgId = entry.getKey(); + DisposableGoods dg = idToDisposableGoodsMap.get(dgId); + DisposableGoodsStock stock = dgIdToSourceDisposableGoodsStockMap.get(dgId); + if(stock == null){ throw new SystemException(String.format("未找到%s的%s库存定义", - idToDisposableGoodsMap.get(dgId).getShowName(),params.optString("sourceWarehouseName"))); + dg.getShowName(),params.optString("sourceWarehouseName"))); } - }); - List> disaposableGoodsStockDecreaseUpdateMapList = new ArrayList>(); - sourceStockList.stream().forEach(stock -> { - Long dgId = stock.getDisposableGoodsID(); - Long adjustAmount = MathTools.sub(stock.getAmount(), dgIdToAmountMap.get(dgId)).longValue(); - if(adjustAmount < 0){ - throw new SystemException(String.format("%s的%s库存数量为%s,需要发货的数量为%s,库存不足,发货失败。", - idToDisposableGoodsMap.get(dgId).getShowName(),params.optString("sourceWarehouseName"), - stock.getAmount(),dgIdToAmountMap.get(dgId))); + //本科室的该一次性需发货的数量 + Integer sendAmount = entry.getValue(); + //判断一次性物品库存对象是否有足够的库存数给当前所发的科室进行扣减,不足时进行提示 + stockIdToTotalDeductionMap.put(dgId, MathTools.add(stockIdToTotalDeductionMap.get(dgId), sendAmount).longValue()); + //比较该一次性物品源仓库的库存对象的库存数量已经划定发货给已遍历的各科室的要扣减数量之和,如果小于时,进行提示 + if(stockIdToTotalDeductionMap.get(dgId) > stock.getAmount()){ + throw new SystemException(String.format("%s的%s库存数量为%s,需要发货的数量已经达到或超过%s,库存不足,发货失败。", + dg.getShowName(),params.optString("sourceWarehouseName"), + stock.getAmount(),stockIdToTotalDeductionMap.get(dgId))); } - Map map = new HashMap(); - map.put("amount", adjustAmount); - map.put("id", stock.getId()); - disaposableGoodsStockDecreaseUpdateMapList.add(map); - }); - //更新库存表数据(减小数量) - if(CollectionUtils.isNotEmpty(disaposableGoodsStockDecreaseUpdateMapList)){ - String updateDisposableGoodsStockDecreaseBatchSql = String.format( - "update %s set amount=? where id=?", - DisposableGoodsStock.class.getSimpleName()); - jdbcTemplate.batchUpdate(updateDisposableGoodsStockDecreaseBatchSql, new BatchPreparedStatementSetter() { - - @Override - public void setValues(PreparedStatement ps, int i) throws SQLException { - Map map = disaposableGoodsStockDecreaseUpdateMapList.get(i); - ps.setLong(1, (Long)map.get("amount")); - ps.setLong(2, (Long)map.get("id")); - } - - @Override - public int getBatchSize() { - // TODO Auto-generated method stub - return disaposableGoodsStockDecreaseUpdateMapList.size(); - } - }); - //执行完后需要hibernate刷新源库存对象,便于接下来的科室进行库存数量扣减(用hibernate的refresh导致大量的数据查询,效率低下) - /*sourceStockList.stream().forEach(stock -> { - objectDao.refresh(stock); - });*/ - //改成重新查询的方式 - sourceStockList = objectDao.findByIds(DisposableGoodsStock.class.getSimpleName(), sourceStockList.stream().map(DisposableGoodsStock::getId).collect(Collectors.toList())); + disaposableGoodsStockIdToDecreaseAmountUpdateMap.put(stock.getId(), stockIdToTotalDeductionMap.get(dgId)); } - List sourceBatchStockList = - objectDao.getBySql_ForUpdate2(DisposableGoodsBatchStock.class.getSimpleName(), - String.format("where warehouseID=%s and %s", - params.optLong("sourceWarehouseId"), - SqlUtils.getNonStringFieldInLargeCollectionsPredicate("disposableGoodsBatchId", batchIdToAmountMap.keySet()))); - List batchIdList = sourceBatchStockList.stream().map(DisposableGoodsBatchStock::getDisposableGoodsBatchId).collect(Collectors.toList()); - //如果未找到相关物品的源发货仓库的批次库存对象时,则进行提示 - batchIdToAmountMap.keySet().stream().forEach(batchId -> { - if(!batchIdList.contains(batchId)){ - DisposableGoodsBatch batch = idToDisposableGoodsBatchMap.get(batchId); - throw new SystemException(String.format("未找到批次号为%s的%s的%s库存定义", - batch.getBatchNumber(),batch.getDiposableGoods().getShowName(),params.optString("sourceWarehouseName"))); - } - }); - List> disaposableGoodsBatchStockDecreaseUpdateMapList = new ArrayList>(); - sourceBatchStockList.stream().forEach(batchStock -> { - Long batchId = batchStock.getDisposableGoodsBatchId(); - DisposableGoodsBatch batch = idToDisposableGoodsBatchMap.get(batchId); - Long adjustAmount = MathTools.sub(batchStock.getStorage(), batchIdToAmountMap.get(batchId)).longValue(); - if(adjustAmount < 0){ - throw new SystemException(String.format("批次号为%s的%s的%s库存数量为%s,需要发货的数量为%s,库存不足,发货失败。", - batch.getBatchNumber(),batch.getDiposableGoods().getShowName(),params.optString("sourceWarehouseName"), - batchStock.getStorage(),batchIdToAmountMap.get(batchId))); - } - Map map = new HashMap(); - map.put("amount", adjustAmount); - map.put("id", batchStock.getId()); - disaposableGoodsBatchStockDecreaseUpdateMapList.add(map); - }); - //更新批次库存表数据(减小数量) - if(CollectionUtils.isNotEmpty(disaposableGoodsBatchStockDecreaseUpdateMapList)){ - String updateDisposableGoodsStockDecreaseBatchSql = String.format( - "update %s set storage=? where id=?", - DisposableGoodsBatchStock.class.getSimpleName()); - jdbcTemplate.batchUpdate(updateDisposableGoodsStockDecreaseBatchSql, new BatchPreparedStatementSetter() { - - @Override - public void setValues(PreparedStatement ps, int i) throws SQLException { - Map map = disaposableGoodsBatchStockDecreaseUpdateMapList.get(i); - ps.setLong(1, (Long)map.get("amount")); - ps.setLong(2, (Long)map.get("id")); - } - - @Override - public int getBatchSize() { - // TODO Auto-generated method stub - return disaposableGoodsBatchStockDecreaseUpdateMapList.size(); - } - }); - //执行完后需要hibernate刷新源库存对象,便于接下来的科室进行库存数量扣减(用hibernate的refresh导致大量的数据查询,效率低下) - /*sourceBatchStockList.stream().forEach(batchStock -> { - objectDao.refresh(batchStock); - });*/ - //改成重新查询的方式 - sourceBatchStockList = objectDao.findByIds(DisposableGoodsBatchStock.class.getSimpleName(), sourceBatchStockList.stream().map(DisposableGoodsBatchStock::getId).collect(Collectors.toList())); + for(Entry entry : batchIdToAmountMap.entrySet()) { + Long batchId = entry.getKey(); + Integer deductionAmount = batchIdToAmountMap.get(batchId); + DisposableGoodsBatchStock batchStock = batchIdToSourceDisposableGoodsBatchStockMap.get(batchId); + Long batchStockId = batchStock.getId(); + batchStockIdToTotalDeductionMap.put(batchStockId,MathTools.add(batchStockIdToTotalDeductionMap.get(batchStockId), deductionAmount).longValue()); + disaposableGoodsBatchStockIdToDecreaseAmountUpdateMap.put(batchStockId, batchStockIdToTotalDeductionMap.get(batchStockId)); } //供应室发货给自己时扣减物品的库存,默认值为true(值为true:则供应室发货给自己时,要扣减该发货物品的库存 ;值为false或者没有配置:则供应室发货给自己时,该物品的库存保持不变) @@ -4344,14 +4302,13 @@ /*targetStockList.stream().forEach(ts -> { objectDao.refresh(ts); });*/ - //改成重新查询的方式 - targetStockList = objectDao.findByIds(DisposableGoodsStock.class.getSimpleName(), targetStockList.stream().map(DisposableGoodsStock::getId).collect(Collectors.toList())); + //改成重新查询的方式(暂时不用加这句,因为如果是前面新插入的数据,则前面就已经可以查出来) + //targetStockList = objectDao.findByIds(DisposableGoodsStock.class.getSimpleName(), targetStockList.stream().map(DisposableGoodsStock::getId).collect(Collectors.toList())); } /* * 1.对有找到相关物品的目标收货仓库的库存对象进行update更新 * 2.对未找到相关物品的目标收货仓库的库存对象进行insert新增 */ - List> disaposableGoodsStockIncreaseUpdateMapList = new ArrayList>(); List needInsertStockDgIdList = new ArrayList(); Set allDgIdSet = dgIdToAmountMap.keySet(); if(CollectionUtils.isNotEmpty(targetStockList)){ @@ -4364,32 +4321,10 @@ }); //如果需要增加库存时,则增加 if(needIncreaseTargetOrgUnitDgStock){ - targetStockList.stream().forEach(stock -> { - Map map = new HashMap(); + for(DisposableGoodsStock stock : targetStockList) { Long dgId = stock.getDisposableGoodsID(); - Long adjustAmount = MathTools.add(stock.getAmount(), dgIdToAmountMap.get(dgId)).longValue(); - map.put("amount", adjustAmount); - map.put("id", stock.getId()); - disaposableGoodsStockIncreaseUpdateMapList.add(map); - }); - String updateDisposableGoodsStockIncreaseBatchSql = String.format( - "update %s set amount=? where id=?", - DisposableGoodsStock.class.getSimpleName()); - jdbcTemplate.batchUpdate(updateDisposableGoodsStockIncreaseBatchSql, new BatchPreparedStatementSetter() { - - @Override - public void setValues(PreparedStatement ps, int i) throws SQLException { - Map map = disaposableGoodsStockIncreaseUpdateMapList.get(i); - ps.setLong(1, (Long)map.get("amount")); - ps.setLong(2, (Long)map.get("id")); - } - - @Override - public int getBatchSize() { - // TODO Auto-generated method stub - return disaposableGoodsStockIncreaseUpdateMapList.size(); - } - }); + disaposableGoodsStockIdToIncreaseAmountUpdateMap.put(stock.getId(),new Long(dgIdToAmountMap.get(dgId))); + } } }else{ needInsertStockDgIdList.addAll(allDgIdSet); @@ -4519,14 +4454,13 @@ /*targetBatchStockList.stream().forEach(tbs -> { objectDao.refresh(tbs); });*/ - //改成重新查询的方式 - targetBatchStockList = objectDao.findByIds(DisposableGoodsBatchStock.class.getSimpleName(), targetBatchStockList.stream().map(DisposableGoodsBatchStock::getId).collect(Collectors.toList())); + //改成重新查询的方式(暂时不用加这句,因为如果是前面新插入的数据,则前面就已经可以查出来) + //targetBatchStockList = objectDao.findByIds(DisposableGoodsBatchStock.class.getSimpleName(), targetBatchStockList.stream().map(DisposableGoodsBatchStock::getId).collect(Collectors.toList())); } /* * 1.对未找到相关物品的目标收货仓库的批次库存对象进行insert新增 * 2.对有找到相关物品的目标收货仓库的批次库存对象进行update更新 */ - List> disaposableGoodsBatchStockIncreaseUpdateMapList = new ArrayList>(); Set allBatchIdSet = batchIdToAmountMap.keySet(); List needInsertBatchStockBatchIdList = new ArrayList(); if(CollectionUtils.isEmpty(targetBatchStockList)){ @@ -4540,32 +4474,11 @@ needInsertBatchStockBatchIdList.add(batchId); } }); - targetBatchStockList.stream().forEach(batchStock -> { - Map map = new HashMap(); + for(DisposableGoodsBatchStock batchStock : targetBatchStockList) { Long batchId = batchStock.getDisposableGoodsBatchId(); - Long adjustAmount = MathTools.add(batchStock.getStorage(), batchIdToAmountMap.get(batchId)).longValue(); - map.put("storage", adjustAmount); - map.put("id", batchStock.getId()); - disaposableGoodsBatchStockIncreaseUpdateMapList.add(map); - }); - String updateDisposableGoodsStockIncreaseBatchSql = String.format( - "update %s set storage=? where id=?", - DisposableGoodsBatchStock.class.getSimpleName()); - jdbcTemplate.batchUpdate(updateDisposableGoodsStockIncreaseBatchSql, new BatchPreparedStatementSetter() { - - @Override - public void setValues(PreparedStatement ps, int i) throws SQLException { - Map map = disaposableGoodsBatchStockIncreaseUpdateMapList.get(i); - ps.setLong(1, (Long)map.get("storage")); - ps.setLong(2, (Long)map.get("id")); - } - - @Override - public int getBatchSize() { - // TODO Auto-generated method stub - return disaposableGoodsBatchStockIncreaseUpdateMapList.size(); - } - }); + Integer increaseAmount = batchIdToAmountMap.get(batchId); + disaposableGoodsBatchStockIdToIncreaseAmountUpdateMap.put(batchStock.getId(),new Long(increaseAmount)); + } } } //如果有需要插入库存新数据时 @@ -4680,8 +4593,6 @@ /*targetBatchStockList.stream().forEach(tbs -> { objectDao.refresh(tbs); });*/ - //改成重新查询的方式 - targetBatchStockList = objectDao.findByIds(DisposableGoodsBatchStock.class.getSimpleName(), targetBatchStockList.stream().map(DisposableGoodsBatchStock::getId).collect(Collectors.toList())); } } if(CollectionUtils.isNotEmpty(allIdentiToAmountEntryListOfDepart)){ @@ -4838,6 +4749,105 @@ sourceStockList, sourceBatchStockList, targetStockList, targetBatchStockList, targetIdentificationList, disposableGoodsStorageAdjustVoTotalList); } + + //1.循环所有科室的一次性物品发货数据后,统一更新库存表数据(减小供应室库存数量)-一次性物品定义的库存级 + if(MapUtils.isNotEmpty(disaposableGoodsStockIdToDecreaseAmountUpdateMap)){ + String updateDisposableGoodsStockDecreaseBatchSql = String.format( + "update %s set amount=amount-? where id=?", + DisposableGoodsStock.class.getSimpleName()); + jdbcTemplate.batchUpdate(updateDisposableGoodsStockDecreaseBatchSql, new BatchPreparedStatementSetter() { + + @Override + public void setValues(PreparedStatement ps, int i) throws SQLException { + Entry entry = CollectionUtils.get(disaposableGoodsStockIdToDecreaseAmountUpdateMap, i); + ps.setLong(1, entry.getValue()); + ps.setLong(2, entry.getKey()); + } + + @Override + public int getBatchSize() { + // TODO Auto-generated method stub + return disaposableGoodsStockIdToDecreaseAmountUpdateMap.size(); + } + }); + //执行完后需要hibernate刷新源库存对象,便于接下来的科室进行库存数量扣减(用hibernate的refresh导致大量的数据查询,效率低下) + /*sourceStockList.stream().forEach(stock -> { + objectDao.refresh(stock); + });*/ + //改成重新查询的方式(冒似并没有取到前面的jdbcTemplate的update之后的最后库存值,还是修改前的数量,更新前后数据不一致,因此不可用) + //sourceStockList = objectDao.findByIds(DisposableGoodsStock.class.getSimpleName(), sourceStockList.stream().map(DisposableGoodsStock::getId).collect(Collectors.toList())); + } + + //2.循环所有科室的一次性物品发货数据后,更新批次库存表数据(减小供应室库存数量)-一次性物品批次库存级 + if(MapUtils.isNotEmpty(disaposableGoodsBatchStockIdToDecreaseAmountUpdateMap)){ + String updateDisposableGoodsStockDecreaseBatchSql = String.format( + "update %s set storage=storage-? where id=?", + DisposableGoodsBatchStock.class.getSimpleName()); + jdbcTemplate.batchUpdate(updateDisposableGoodsStockDecreaseBatchSql, new BatchPreparedStatementSetter() { + + @Override + public void setValues(PreparedStatement ps, int i) throws SQLException { + Entry entry = CollectionUtils.get(disaposableGoodsBatchStockIdToDecreaseAmountUpdateMap, i); + ps.setLong(1, entry.getValue()); + ps.setLong(2, entry.getKey()); + } + + @Override + public int getBatchSize() { + // TODO Auto-generated method stub + return disaposableGoodsBatchStockIdToDecreaseAmountUpdateMap.size(); + } + }); + //执行完后需要hibernate刷新源库存对象,便于接下来的科室进行库存数量扣减(用hibernate的refresh导致大量的数据查询,效率低下) + /*sourceBatchStockList.stream().forEach(batchStock -> { + objectDao.refresh(batchStock); + });*/ + //改成重新查询的方式(冒似并没有取到前面的jdbcTemplate的update之后的最后库存值,还是修改前的数量,更新前后数据不一致,因此不可用) + //sourceBatchStockList = objectDao.findByIds(DisposableGoodsBatchStock.class.getSimpleName(), sourceBatchStockList.stream().map(DisposableGoodsBatchStock::getId).collect(Collectors.toList())); + } + + //3.循环所有科室的一次性物品发货数据后,更新批次库存表数据(增加各临床科室库存数量)-一次性物品定义的库存级 + if(MapUtils.isNotEmpty(disaposableGoodsStockIdToIncreaseAmountUpdateMap)){ + String updateDisposableGoodsStockIncreaseBatchSql = String.format( + "update %s set amount=amount+? where id=?", + DisposableGoodsStock.class.getSimpleName()); + jdbcTemplate.batchUpdate(updateDisposableGoodsStockIncreaseBatchSql, new BatchPreparedStatementSetter() { + + @Override + public void setValues(PreparedStatement ps, int i) throws SQLException { + Entry entry = CollectionUtils.get(disaposableGoodsStockIdToIncreaseAmountUpdateMap,i); + ps.setLong(1, entry.getValue()); + ps.setLong(2, entry.getKey()); + } + + @Override + public int getBatchSize() { + // TODO Auto-generated method stub + return disaposableGoodsStockIdToIncreaseAmountUpdateMap.size(); + } + }); + } + + //4.循环所有科室的一次性物品发货数据后,更新批次库存表数据(增加各临床科室库存数量)-一次性物品批次批次库存、标识三层 + if(MapUtils.isNotEmpty(disaposableGoodsBatchStockIdToIncreaseAmountUpdateMap)){ + String updateDisposableGoodsBatchStockIncreaseBatchSql = String.format("update %s set storage=storage+? where id=?", + DisposableGoodsBatchStock.class.getSimpleName()); + jdbcTemplate.batchUpdate(updateDisposableGoodsBatchStockIncreaseBatchSql, new BatchPreparedStatementSetter() { + + @Override + public void setValues(PreparedStatement ps, int i) throws SQLException { + Entry entry = CollectionUtils.get(disaposableGoodsBatchStockIdToIncreaseAmountUpdateMap, i); + ps.setLong(1, entry.getValue()); + ps.setLong(2, entry.getKey()); + } + + @Override + public int getBatchSize() { + // TODO Auto-generated method stub + return disaposableGoodsBatchStockIdToIncreaseAmountUpdateMap.size(); + } + }); + } } }