Index: ssts-diposablegoods/src/main/java/com/forgon/disinfectsystem/diposablegoods/service/DiposableGoodsManagerImpl.java =================================================================== diff -u -r14257 -r14386 --- ssts-diposablegoods/src/main/java/com/forgon/disinfectsystem/diposablegoods/service/DiposableGoodsManagerImpl.java (.../DiposableGoodsManagerImpl.java) (revision 14257) +++ ssts-diposablegoods/src/main/java/com/forgon/disinfectsystem/diposablegoods/service/DiposableGoodsManagerImpl.java (.../DiposableGoodsManagerImpl.java) (revision 14386) @@ -1688,6 +1688,18 @@ DisposableGoods.class.getSimpleName(), sql); return retList; } + public List joinFetchDisposableGoodsStockByDisposableGoodsIds(String warehouseID,Collection ids){ + if(ids == null || ids.size()==0){ + return null; + } + if(StringUtils.isBlank(warehouseID)){ + return null; + } + String queryString = String + .format(" from %s po inner join fetch po.goodsBatchs b inner join fetch b.identifications i where po.warehouseID=%s and (%s) ", + DisposableGoodsStock.class.getSimpleName(),warehouseID,SqlUtils.getStringFieldInCollectionsPredicate("po.disposableGoodsID", ids)); + return objectDao.findByHql(queryString); + } // 一次加载所有的一次性物品以及批次,标识号对象 public List getDisposableGoodsStockByBatchBarcodes(String warehouseID,Collection batchBarcodes){ if(batchBarcodes == null || batchBarcodes.size()==0){ @@ -1715,7 +1727,11 @@ // 此时获取的是按照id升序排列的 return objectDao.findBySql(DisposableGoodsStock.class.getSimpleName(),queryString); } - + public List getDisposableGoodsStockByDisposableGoodsId(String warehouseID,Long disposableGoodsId){ + List disposableGoodsIds = new ArrayList(); + disposableGoodsIds.add(disposableGoodsId); + return getDisposableGoodsStockByDisposableGoodsIDs(warehouseID, disposableGoodsIds); + } public List getDisposableGoodsStockByDisposableGoodsIDs(String warehouseID,Collection diposableGoodsIDsSet){ String getDisposableGoodsStockSql = String.format(" where %s and po.warehouseID=%s", SqlUtils.getStringFieldInCollectionsPredicate("po.disposableGoodsID", diposableGoodsIDsSet),warehouseID); Index: build.gradle =================================================================== diff -u -r14008 -r14386 --- build.gradle (.../build.gradle) (revision 14008) +++ build.gradle (.../build.gradle) (revision 14386) @@ -479,7 +479,7 @@ compile (project(":ssts-basedata")) compile (project(":ssts-tousse")) compile (project(":ssts-stockmanage")) - + compile (project(":ssts-diposablegoods")) compile (project(":ssts-wash")) compile (project(":ssts-expiration")) compile (project(":ssts-idcard")) Index: ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/dwr/table/PackingTableManager.java =================================================================== diff -u -r14356 -r14386 --- ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/dwr/table/PackingTableManager.java (.../PackingTableManager.java) (revision 14356) +++ ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/dwr/table/PackingTableManager.java (.../PackingTableManager.java) (revision 14386) @@ -441,10 +441,12 @@ json.addProperty("success", false); json.addProperty("type", "stockNotEnough"); json.addProperty("message", e.getMessage()); + e.printStackTrace(); } catch (Exception e) { json.addProperty("success", false); json.addProperty("type", "packingFailure"); json.addProperty("message", "装配失败"); + e.printStackTrace(); } return json.toString(); } Index: ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/service/PackingManagerImpl.java =================================================================== diff -u -r14362 -r14386 --- ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/service/PackingManagerImpl.java (.../PackingManagerImpl.java) (revision 14362) +++ ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/service/PackingManagerImpl.java (.../PackingManagerImpl.java) (revision 14386) @@ -53,9 +53,13 @@ import com.forgon.disinfectsystem.basedatamanager.toussedefinition.service.TousseInstanceUtils; import com.forgon.disinfectsystem.basedatamanager.warehouse.service.WareHouseManager; import com.forgon.disinfectsystem.common.CssdUtils; +import com.forgon.disinfectsystem.diposablegoods.service.DiposableGoodsManager; +import com.forgon.disinfectsystem.disposablegoods.service.DisposableGoodsServiceContext; import com.forgon.disinfectsystem.entity.assestmanagement.DiposableGoodsInstance; import com.forgon.disinfectsystem.entity.assestmanagement.DisposableGoods; +import com.forgon.disinfectsystem.entity.assestmanagement.DisposableGoodsBatchStock; import com.forgon.disinfectsystem.entity.assestmanagement.DisposableGoodsIdentification; +import com.forgon.disinfectsystem.entity.assestmanagement.DisposableGoodsStock; import com.forgon.disinfectsystem.entity.basedatamanager.container.Container; import com.forgon.disinfectsystem.entity.basedatamanager.materialdefinition.MaterialDefinition; import com.forgon.disinfectsystem.entity.basedatamanager.materialinstance.MaterialInstance; @@ -141,6 +145,8 @@ private TousseDefinitionManager tousseDefinitionManager; + private DiposableGoodsManager diposableGoodsManager; + private WashAndDisinfectRecordManager washAndDisinfectRecordManager; private TousseInstanceManager tousseInstanceManager; @@ -251,6 +257,10 @@ this.tousseDefinitionManager = tousseDefinitionManager; } + public void setDiposableGoodsManager(DiposableGoodsManager diposableGoodsManager) { + this.diposableGoodsManager = diposableGoodsManager; + } + public void setWashAndDisinfectRecordManager( WashAndDisinfectRecordManager washAndDisinfectRecordManager) { this.washAndDisinfectRecordManager = washAndDisinfectRecordManager; @@ -2324,13 +2334,10 @@ packingRecord.setPackTime(packingDate); String tousseName =tousseDefinition .getName(); - if (TousseDefinition.PACKAGE_TYPE_FOREIGN.equals(tousseDefinition.getTousseType())) { - tousseName = tousseDefinition - .getTousseDefinitionShowName(); - } packingRecord.setTousseName(tousseName); packingRecord.setTousseType(tousseDefinition .getTousseType()); + packingRecord.setTousseDefinitionId(tousseDefinition.getId()); // 如果装配的是消毒物品,取装配任务的数量作为装配记录的数量(会导致历史装配数量为该装配任务的数量,所以暂注释SYF20160506) /*if (TousseDefinition.PACKAGE_TYPE_DISINFECTION.equals(tousseDefinition.getTousseType())){ packingAmount = currentPackingTask.getAmount(); @@ -2347,26 +2354,6 @@ return packingRecord; } - /** - * 创建装配扣减库存明细 - * @param packingRecord - * @param packingRecordOutItemList - * @param diposableGoodsItemList - */ - private void createPackingRecordOutItemList(PackingRecord packingRecord , - List packingRecordOutItemList , List diposableGoodsItemList){ - if(CollectionUtils.isNotEmpty(packingRecordOutItemList) && CollectionUtils.isNotEmpty(diposableGoodsItemList)){ - for(PackingRecordOutItem packingRecordOutItem : packingRecordOutItemList){ - packingRecordOutItem.setPackingRecordId(packingRecord.getId()); - objectDao.saveOrUpdate(packingRecordOutItem); - } - for(DiposableGoodsItem diposableGoodsItem : diposableGoodsItemList){ - diposableGoodsItem.setPackingRecordId(packingRecord.getId()); - objectDao.saveOrUpdate(diposableGoodsItem); - } - } - } - private void updateTousseWorkloadStaticsAmount(TousseDefinition tousseDefinition) { int workloadAmount = tousseDefinitionManager.getWorkloadAmount(tousseDefinition); @@ -2400,6 +2387,171 @@ } return idToWashRecordMap; } + // 一次性物品装配信息 + private void summaryOutDisposableGoodsStockInfo(DisposableGoodsServiceContext context,Map disposableGoodsIdToAmount,DisposableGoods disposableGoods,Long outAmount){ + context.getDisposableGoodsIdsSet().add(disposableGoods.getId()); + Long disposableGoodsId = disposableGoods.getId(); + Long amount = disposableGoodsIdToAmount.get(disposableGoodsId); + if(amount == null){ + disposableGoodsIdToAmount.put(disposableGoodsId, outAmount); + }else{ + disposableGoodsIdToAmount.put(disposableGoodsId, amount + outAmount); + } + } + private void summaryOutDisposableGoodsStockInfo(Map> packingRecordToDisposableGoodsOutAmount,PackingRecord packingRecord,Map disposableGoodsIdToAmount){ + if(disposableGoodsIdToAmount == null){ + return; + } + if(packingRecordToDisposableGoodsOutAmount.containsKey(packingRecord)){ + throw new RuntimeException("装配记录对应的一次性物品扣减信息重复!"); + } + packingRecordToDisposableGoodsOutAmount.put(packingRecord, disposableGoodsIdToAmount); + } + private void outDisposableGoodsStock2(DisposableGoodsServiceContext disposableGoodsServiceContext,Map> packingRecordToDisposableGoodsOutAmount,SupplyRoomConfig config){ + if(packingRecordToDisposableGoodsOutAmount.isEmpty()){ + return; + } + WareHouse wareHouse = wareHouseManager.getDefaultWareHouseByUnitCode(AcegiHelper.getCurrentOrgUnitCode()); + if(wareHouse == null){ + throw new RuntimeException("未找到当前登录用户的仓库!"); + } + Long warehouseID = wareHouse.getId(); + // 锁定一次性物品 + diposableGoodsManager.lockAndGetDisposableGoodsResources(disposableGoodsServiceContext); + Map> disposableGoodsIdToDisposableGoodsStockListMap = new HashMap>(); + Map> disposableGoodsIdToIdentificationListMap = new HashMap>(); + + // 加载所有的物品库存,批次库存和标识号 + List disposableGoodsStockList = diposableGoodsManager.joinFetchDisposableGoodsStockByDisposableGoodsIds(warehouseID.toString(), disposableGoodsServiceContext.getDisposableGoodsIdsSet()); + if(disposableGoodsStockList != null){ + for (DisposableGoodsStock disposableGoodsStock : disposableGoodsStockList) { + Long disposableGoodsId = disposableGoodsStock.getDisposableGoodsID(); + if(disposableGoodsId != null){ + List disposableGoodsStocks = disposableGoodsIdToDisposableGoodsStockListMap.get(disposableGoodsId); + if(disposableGoodsStocks == null){ + disposableGoodsStocks = new LinkedList(); + disposableGoodsIdToDisposableGoodsStockListMap.put(disposableGoodsId, disposableGoodsStocks); + } + disposableGoodsStocks.add(disposableGoodsStock); + // + List identifications = disposableGoodsIdToIdentificationListMap.get(disposableGoodsId); + if(identifications == null){ + identifications = new LinkedList(); + disposableGoodsIdToIdentificationListMap.put(disposableGoodsId, identifications); + } + Set goodsBatchs = disposableGoodsStock.getGoodsBatchs(); + if(goodsBatchs != null){ + for (DisposableGoodsBatchStock disposableGoodsBatchStock : goodsBatchs) { + identifications.addAll(disposableGoodsBatchStock.getIdentifications()); + } + } + } + } + // 排序标识号 + if(!disposableGoodsIdToIdentificationListMap.isEmpty()){ + for (List identifications : disposableGoodsIdToIdentificationListMap.values()) { + Collections.sort(identifications);// 按失效期排序 + } + } + } + + Map idToDisposableGoodsMap = disposableGoodsServiceContext.getIdToDisposableGoodsMap(); + for (Map.Entry> entry : packingRecordToDisposableGoodsOutAmount.entrySet()) { + PackingRecord packingRecord = entry.getKey(); + Map disposableGoodsIdToAmount = entry.getValue(); + if(disposableGoodsIdToAmount.isEmpty()){ + continue; + } + for (Map.Entry entry2 : disposableGoodsIdToAmount.entrySet()) { + Long disposableGoodsId = entry2.getKey(); + Long totalOutAmount = entry2.getValue(); + outDisposableGoodsStock2(config, warehouseID, idToDisposableGoodsMap,disposableGoodsIdToDisposableGoodsStockListMap, + disposableGoodsIdToIdentificationListMap,packingRecord, disposableGoodsId, + totalOutAmount); + } + } + } + + private void outDisposableGoodsStock2(SupplyRoomConfig config, Long warehouseID, + Map idToDisposableGoodsMap,Map> disposableGoodsIdToDisposableGoodsStockListMap, + Map> disposableGoodsIdToIdentificationListMap, + PackingRecord packingRecord, + Long disposableGoodsId, Long totalOutAmount) { + DisposableGoods disposableGoods = idToDisposableGoodsMap.get(disposableGoodsId); + if(disposableGoods == null){ + throw new RuntimeException("物品定义已被删除!"); + } + String disposableGoodsName = disposableGoods.getShowName(); + List identifications = disposableGoodsIdToIdentificationListMap.get(disposableGoodsId); + if(identifications == null){ + throw new RuntimeException(disposableGoodsName + "库存不足,不能装配!"); + } + int amountAwaitingSent = totalOutAmount.intValue(); + + //扣减库存,成功后加入到扣减明细集合中 + PackingRecordOutItem outItem = new PackingRecordOutItem(); + outItem.setPackingRecordId(packingRecord.getId()); + outItem.setTousseDefinitionId(packingRecord.getTousseDefinitionId()); + outItem.setTousseName(packingRecord.getTousseName()); + outItem.setAmount(totalOutAmount.intValue()); + outItem.setDisposableGoodsId(disposableGoodsId); + outItem.setDisposableGoodsName(disposableGoodsName); + objectDao.saveOrUpdate(outItem); + double settlementPrice = 0.0; + + for (DisposableGoodsIdentification identification : identifications) { + Long amount = identification.getAmount(); + if (amount <= 0) { + continue; + } + Integer curAmount = 0; + if (amount < amountAwaitingSent) { + curAmount = (Integer)amount.intValue(); + } else { + curAmount = amountAwaitingSent; + } + amountAwaitingSent -= curAmount; + // 调整库存 + identification.adjustAmount(-curAmount); + // 更新库存 + objectDao.update(identification); + objectDao.update(identification.getBatchStock()); + objectDao.update(identification.getBatchStock().getDiposableGoods()); + Long disposableGoodsStockID = identification.getDisposableGoodsStockID(); + Long disposableGoodsBatchID = identification.getDisposableGoodsBatchID(); + Long disposableGoodsBatchStockID = identification.getBatchStock().getId(); + Long identificationID = identification.getId(); + Double price = identification.getPrice(); + String batchNumber = identification.getBatchStock().getBatchNumber(); + + DiposableGoodsItem diposableGoodsItem = new DiposableGoodsItem(); + diposableGoodsItem.setAmount(curAmount); + diposableGoodsItem.setPrice(identification.getPrice()); + diposableGoodsItem.setDisposableGoodsID(disposableGoodsId); + diposableGoodsItem.setBatch(batchNumber); + diposableGoodsItem.setDisposableGoodsStockID(disposableGoodsStockID); + diposableGoodsItem.setDisposableGoodsBatchID(disposableGoodsBatchID); + diposableGoodsItem.setDisposableGoodsBatchStockID(disposableGoodsBatchStockID); + diposableGoodsItem.setFluctuationPrice(config.getDiposablePriceFluctuation() * price); + diposableGoodsItem.setIdentificationID(identificationID); + diposableGoodsItem.setName(disposableGoodsName); + diposableGoodsItem.setPackingRecordOutItemId(outItem.getId()); + diposableGoodsItem.setPackingRecordId(packingRecord.getId()); + + settlementPrice += curAmount * diposableGoodsItem.getFluctuationPrice(); + + objectDao.saveOrUpdate(diposableGoodsItem); + // 如果待扣减的数量小于等于0时,跳出循环 + if(amountAwaitingSent <= 0){ + break; + } + } + outItem.setSettlementPrice(settlementPrice); + if(amountAwaitingSent > 0){ + throw new RuntimeException(disposableGoodsName + "库存不足,不能装配!"); + } + objectDao.update(outItem); + } /** * 装配时扣减材料(一次性物品)库存 * @param needPackingAmount 器械包装配数量 @@ -2544,7 +2696,8 @@ String washBasket = ""; JSONObject json = new JSONObject(); - + DisposableGoodsServiceContext disposableGoodsServiceContext = new DisposableGoodsServiceContext(); + Map> packingRecordToDisposableGoodsOutAmount = new HashMap>(); JSONArray toussesArray = new JSONArray(); LoginUserData loginUser = AcegiHelper.getLoginUser(); @@ -2710,8 +2863,8 @@ String tousseType = td.getTousseType(); String tousseName = tdName; - List packingRecordOutItemList = null; - List diposableGoodsItemList = null; + + Map disposableGoodsIdToAmount = null; /* * 先判断装配任务对应的器械包定义是否需要扣一次性物品库存(目前只针对普通器械包和敷料包进行扣减,后期在器械包定义的页界加以限制,其它类型的器械包定义的装配扣一次性物品库存的属性只能为否) */ @@ -2722,16 +2875,19 @@ //判断对应的各一次性是否库存数量是否够扣,如果够扣的话 List diposableGoodsItems = td.getDiposableGoodsItems(); if(CollectionUtils.isNotEmpty(diposableGoodsItems)){ - packingRecordOutItemList = new ArrayList(); - diposableGoodsItemList = new ArrayList(); + + disposableGoodsIdToAmount = new HashMap(); for(DiposableGoodsInstance diposableGoodsInstance : diposableGoodsItems){ //扣减库存 DisposableGoods disposableGoods = diposableGoodsInstance.getDiposableGoods(); Integer diposableGoodsAmount = diposableGoodsInstance.getAmount(); - if(disposableGoods != null && diposableGoodsAmount != null && diposableGoodsAmount > 0){ - json = outDisposableGoodsStock(needPackingAmount , td, disposableGoods , diposableGoodsAmount , supplyRoomConfigParams, - packingRecordOutItemList , diposableGoodsItemList); + if(disposableGoods == null){ + throw new RuntimeException(String.format("%s 有部分一次性物品材料未找到物品定义!", td.getName())); } + if(diposableGoodsAmount != null && diposableGoodsAmount > 0){ + Long outAmount = new Long(needPackingAmount*diposableGoodsAmount); + summaryOutDisposableGoodsStockInfo(disposableGoodsServiceContext, disposableGoodsIdToAmount, disposableGoods, outAmount); + } } } } @@ -2792,8 +2948,8 @@ PackingRecord packingRecord = createPackingRecord( inspector, operator, wrapper, orgUnitCoding, orgUnitName,taskGroup, sterilizerName, sterileFrequency, td, packingDate, currentPackAmount, currentPackingTask); - //创建装配扣减库存明细 - createPackingRecordOutItemList( packingRecord , packingRecordOutItemList , diposableGoodsItemList); + // 汇总装配记录对应的一次性物品扣减信息 + summaryOutDisposableGoodsStockInfo(packingRecordToDisposableGoodsOutAmount, packingRecord, disposableGoodsIdToAmount); packingSplitPackages(operator, operatorCode, reviewer, reviewerCode, sterilingType, sterilizerName, sterileFrequency, @@ -2858,8 +3014,8 @@ sterilizerName, sterileFrequency, td, packingDate, packingAmountForThisTask, currentPackingTask); - //创建装配扣减库存明细 - createPackingRecordOutItemList( packingRecord , packingRecordOutItemList , diposableGoodsItemList); + // 汇总装配记录对应的一次性物品扣减信息 + summaryOutDisposableGoodsStockInfo(packingRecordToDisposableGoodsOutAmount, packingRecord, disposableGoodsIdToAmount); JSONObject result = batchCreateTousseInstance( operator, operatorCode, reviewer,reviewerCode, packageType, @@ -3041,7 +3197,8 @@ batchLoadToVirtaulBasket = false;//器械包批量装入虚拟篮筐是否成功 batchLoadMsg = "装配任务id为空"; } - + // 扣减一次性物品库存 + outDisposableGoodsStock2(disposableGoodsServiceContext, packingRecordToDisposableGoodsOutAmount, supplyRoomConfigParams); if(!batchLoadToVirtaulBasket){ json.put("success", false); json.put("message", batchLoadMsg); Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/packing/PackingRecord.java =================================================================== diff -u -r14358 -r14386 --- ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/packing/PackingRecord.java (.../PackingRecord.java) (revision 14358) +++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/packing/PackingRecord.java (.../PackingRecord.java) (revision 14386) @@ -42,6 +42,8 @@ private String tousseName; //器械包名字 + private Long tousseDefinitionId; + private String tousseType; //器械包类型 private Integer amount; //数量(实际装配数量) @@ -100,6 +102,14 @@ this.tousseName = tousseName; } + public Long getTousseDefinitionId() { + return tousseDefinitionId; + } + + public void setTousseDefinitionId(Long tousseDefinitionId) { + this.tousseDefinitionId = tousseDefinitionId; + } + public String getTousseType() { return tousseType; } Index: ssts-diposablegoods/src/main/java/com/forgon/disinfectsystem/diposablegoods/service/DiposableGoodsManager.java =================================================================== diff -u -r14033 -r14386 --- ssts-diposablegoods/src/main/java/com/forgon/disinfectsystem/diposablegoods/service/DiposableGoodsManager.java (.../DiposableGoodsManager.java) (revision 14033) +++ ssts-diposablegoods/src/main/java/com/forgon/disinfectsystem/diposablegoods/service/DiposableGoodsManager.java (.../DiposableGoodsManager.java) (revision 14386) @@ -105,10 +105,12 @@ public List getDisposableGoodsBySql_ForUpdate(String sql); + public List joinFetchDisposableGoodsStockByDisposableGoodsIds(String warehouseID,Collection ids); public List getDisposableGoodsStockByBatchBarcodes(String warehouseID,Collection barcodes); public List getDisposableGoodsStockByDisposableGoodsStockIDs(Collection ids); + public List getDisposableGoodsStockByDisposableGoodsId(String warehouseID,Long disposableGoodsID); public List getDisposableGoodsStockByDisposableGoodsIDs(String warehouseID,Collection ids); public List getDisposableGoodsBatchStocksByDisposableGoodsStockID(Long disposableGoodsID);