Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/materialerrordamage/MaterialErrorDamageDetail.java =================================================================== diff -u -r28972 -r29590 --- ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/materialerrordamage/MaterialErrorDamageDetail.java (.../MaterialErrorDamageDetail.java) (revision 28972) +++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/materialerrordamage/MaterialErrorDamageDetail.java (.../MaterialErrorDamageDetail.java) (revision 29590) @@ -53,6 +53,7 @@ public static String LINKTYPE_RECYCLINGRECORDERROR= "回收丢失"; public static String LINKTYPE_USERECORD= "使用记录"; + public static String LINKTYPE_PACK= "装配环节"; public static final String TYPE_ERROR = "回收误差"; public static final String TYPE_DAMAGE = "器械报损"; Index: ssts-recyclingrecord/src/main/java/com/forgon/disinfectsystem/recyclingrecord/service/RecyclingRecordManagerImpl.java =================================================================== diff -u -r29335 -r29590 --- ssts-recyclingrecord/src/main/java/com/forgon/disinfectsystem/recyclingrecord/service/RecyclingRecordManagerImpl.java (.../RecyclingRecordManagerImpl.java) (revision 29335) +++ ssts-recyclingrecord/src/main/java/com/forgon/disinfectsystem/recyclingrecord/service/RecyclingRecordManagerImpl.java (.../RecyclingRecordManagerImpl.java) (revision 29590) @@ -747,8 +747,33 @@ splitErrorDamageDetail(record, confirmation); } } - /** + * 设置丢失报损数量 + * @param errorDamage 丢失报损 + * @param updateAmount 修改数量 + * @param updateErrorDamageMap 丢失报损记录id对应的修改数量的Map 用于修改丢失报损参数中丢失报损的数量 + * @return + */ + private int setErrorDamageAmount(List errorDamage, int updateAmount, Map updateErrorDamageMap){ + if(CollectionUtils.isNotEmpty(errorDamage)){ + for (MaterialErrorDamageDetail item : errorDamage) { + if(updateAmount == 0){//修改量为0,不需要再遍历 + break; + } + if(item.getAmount() + updateAmount > 0){ + item.setAmount(item.getAmount() + updateAmount); + updateErrorDamageMap.put(item.getId(), item.getAmount()); + updateAmount = 0; + }else{ + updateAmount += item.getAmount(); + item.setAmount(0); + updateErrorDamageMap.put(item.getId(), 0); + } + } + } + return updateAmount; + } + /** * 将丢失报损明细拆按包实例拆成一条一条的 * @param record * @param confirmation @@ -1824,28 +1849,159 @@ // throw new RuntimeException("测试"); } /** - * 重现调整前台传的丢失报损信息 + * 重新调整前台传的丢失报损信息 * @param errorDamageDetailArr */ private void reSetErrorDamageDetailArr(JSONArray errorDamageDetailArr){ if(CollectionUtils.isEmpty(errorDamageDetailArr)){ return; } - for (int i = 0; i < errorDamageDetailArr.size(); i++) { - JSONObject obj = (JSONObject)errorDamageDetailArr.get(i); + //需要减少丢失报损数量的丢失报损记录 key:包定义id_材料定义id_丢失报损类型itemType的值 value:修改量 + Map reduceErrorDamageMap = new HashMap(); + Iterator it = errorDamageDetailArr.iterator(); + while(it.hasNext()){ + JSONObject obj = it.next(); Long detailId = obj.optLong("detailId"); Integer unconfirmedAmount = obj.optInt("unconfirmedAmount"); obj.remove("unconfirmedAmount"); if(DatabaseUtil.isPoIdValid(detailId)){ continue; } - if(unconfirmedAmount == null || unconfirmedAmount <= 0){ - continue; + int amount = obj.optInt("amount"); + if(amount < 0){//amount小于0说明是扣减数量,要按指定顺序扣减丢失报损 + Long tousseDefinitionID = obj.optLong("tousseDefinitionID"); + if(!DatabaseUtil.isPoIdValid(tousseDefinitionID)){ + throw new RuntimeException("tousseDefinitionID参数异常,值为"+tousseDefinitionID); + } + Long materialDefinitionId = obj.optLong("materialDefinitionId"); + if(!DatabaseUtil.isPoIdValid(materialDefinitionId)){ + throw new RuntimeException("materialDefinitionId参数异常,值为"+materialDefinitionId); + } + String itemType = obj.optString("itemType"); + if(StringUtils.isBlank(itemType)){ + throw new RuntimeException("itemType参数异常,值为空"); + } + String key = tousseDefinitionID + "_" + materialDefinitionId + "_" + itemType; + if(!reduceErrorDamageMap.containsKey(key)){ + reduceErrorDamageMap.put(key, amount); + } + it.remove();//获取信息后,移除掉amount为负数的丢失报损参数 + }else{ + if(unconfirmedAmount == null || unconfirmedAmount <= 0){ + continue; + } + obj.put("amount", unconfirmedAmount);//方便前台,走到这里的参数unconfirmedAmount赋值给amount使用 } - obj.put("amount", unconfirmedAmount); } + if(MapUtils.isNotEmpty(reduceErrorDamageMap)){//说明有丢失报损扣减要处理 + for (Entry entry : reduceErrorDamageMap.entrySet()) { + String key = entry.getKey(); + String[] splitArr = key.split("_"); + Long tousseDefinitionID = Long.valueOf(splitArr[0]); + Long materialDefinitionId = Long.valueOf(splitArr[1]); + String itemType = splitArr[2]; + Integer reduceAmount = entry.getValue();//修改量,为负数 + //未确认的丢失报损记录,消耗修改量优先级最高 + List unconfirmedMaterialErrorDamageDetails = new ArrayList(); + //环节为使用记录的丢失报损记录,消耗修改量优先级降低 + List useRecordMaterialErrorDamageDetails = new ArrayList(); + //环节为回收丢失或者回收报损的丢失报损记录,消耗修改量优先级降低 + List recyclingMaterialErrorDamageDetails = new ArrayList(); + //环节为装配环节的丢失报损记录,消耗修改量优先级降低 + List packMaterialErrorDamageDetails = new ArrayList(); + //其他的丢失报损记录,消耗修改量优先级降低最低 + List otherErrorDamageDetails = new ArrayList(); + for (int i = 0; i < errorDamageDetailArr.size(); i++) { + JSONObject obj = (JSONObject)errorDamageDetailArr.get(i); + Long detailId = obj.optLong("detailId"); + if(!DatabaseUtil.isPoIdValid(detailId)){ + continue; + } + Long tousseDefinitionIDOfObj = obj.optLong("tousseDefinitionID"); + if(!DatabaseUtil.isPoIdValid(tousseDefinitionIDOfObj) || tousseDefinitionID.longValue() != tousseDefinitionIDOfObj.longValue()){ + continue; + } + Long materialDefinitionIdOfObj = obj.optLong("materialDefinitionId"); + if(!DatabaseUtil.isPoIdValid(materialDefinitionIdOfObj) || materialDefinitionId.longValue() != materialDefinitionIdOfObj.longValue()){ + continue; + } + String itemTypeOfObj = obj.optString("itemType"); + if(!itemType.equals(itemTypeOfObj)){ + continue; + } + MaterialErrorDamageDetail detail = materialErrorDamageDetailManager.get(detailId); + if(detail == null){ + continue; + } + if(MaterialErrorDamageDetail.STATUS_TWO.equals(detail.getStatus())){ + unconfirmedMaterialErrorDamageDetails.add(detail); + }else if(MaterialErrorDamageDetail.LINKTYPE_USERECORD.equals(detail.getLinkType())){ + useRecordMaterialErrorDamageDetails.add(detail); + }else if(MaterialErrorDamageDetail.LINKTYPE_RECYCLINGRECORDERROR.equals(detail.getLinkType()) || + MaterialErrorDamageDetail.LINKTYPE_RECYCLINGRECORD.equals(detail.getLinkType())){ + recyclingMaterialErrorDamageDetails.add(detail); + }else if(MaterialErrorDamageDetail.LINKTYPE_PACK.equals(detail.getLinkType())){ + packMaterialErrorDamageDetails.add(detail); + }else{ + otherErrorDamageDetails.add(detail); + } + } + Map updateErrorDamageMap = new HashMap(); + reduceAmount = setErrorDamageAmount(unconfirmedMaterialErrorDamageDetails, reduceAmount, updateErrorDamageMap); + if(reduceAmount == 0){//说明修改量消耗完了 + reduceErrorDamageAmount(updateErrorDamageMap, errorDamageDetailArr); + continue; + } + reduceAmount = setErrorDamageAmount(useRecordMaterialErrorDamageDetails, reduceAmount, updateErrorDamageMap); + if(reduceAmount == 0){ + reduceErrorDamageAmount(updateErrorDamageMap, errorDamageDetailArr); + continue; + } + reduceAmount = setErrorDamageAmount(recyclingMaterialErrorDamageDetails, reduceAmount, updateErrorDamageMap); + if(reduceAmount == 0){ + reduceErrorDamageAmount(updateErrorDamageMap, errorDamageDetailArr); + continue; + } + reduceAmount = setErrorDamageAmount(packMaterialErrorDamageDetails, reduceAmount, updateErrorDamageMap); + if(reduceAmount == 0){ + reduceErrorDamageAmount(updateErrorDamageMap, errorDamageDetailArr); + continue; + } + reduceAmount = setErrorDamageAmount(otherErrorDamageDetails, reduceAmount, updateErrorDamageMap); + if(reduceAmount != 0){//修改量最后都没有消耗完,说明扣减数量过多不合理。 + TousseDefinition td = tousseDefinitionManager.get(tousseDefinitionID); + if(td == null){ + throw new RuntimeException(tousseDefinitionID + "对应的包定义不存在"); + } + MaterialDefinition md = materialDefinitionManager.get(materialDefinitionId); + if(md == null){ + throw new RuntimeException(materialDefinitionId + "对应的材料定义不存在"); + } + String typeStr = MaterialErrorDamageDetail.TYPE_ERROR.equals(itemType)?"丢失":"报损"; + throw new RuntimeException(String.format("包[%s]%s的材料[%s]减少数量超过最大值。", td.getName(),typeStr,md.getNameSpecification())); + } + } + } } /** + * 减少丢失报损参数中丢失报损的数量 + * @param updateErrorDamageMap + * @param errorDamageDetailArr + */ + private void reduceErrorDamageAmount(Map updateErrorDamageMap, JSONArray errorDamageDetailArr){ + if(MapUtils.isNotEmpty(updateErrorDamageMap)){ + //减少丢失报损的数量 + for (int i = 0; i < errorDamageDetailArr.size(); i++) { + JSONObject obj = (JSONObject)errorDamageDetailArr.get(i); + Long detailId = obj.optLong("detailId"); + if(!updateErrorDamageMap.containsKey(detailId)){ + continue; + } + obj.put("amount", updateErrorDamageMap.get(detailId)); + } + } + } + /** * 验证回收时的包定义 * @param record 回收记录 * @param tousseDefIds 包定义id