实现自定义的回写策略
业务场景中有很多单据,报表,上下游业务需要彼此关联修改数据,更多时候对接第三方业务,需要自己去实现业务逻辑。因此将数量的回写进行业务抽取。
1.首先定义回写的策略:
import com.pangu.mss.domain.mongo.MongoBase; import com.pangu.mss.validation.annotation.DataValidate; import io.swagger.annotations.ApiModelProperty; import org.springframework.data.mongodb.core.index.Indexed; import org.springframework.data.mongodb.core.mapping.Document; import java.util.ArrayList; import java.util.List; /** * 回写数量的策略 * @author liumingquan * */ @Document(collection = "Strategy.BackWriteQuantityStrategy") public class BackWriteQuantityStrategy extends MongoBase { public final static String tableName = "Strategy.BackWriteQuantityStrategy"; public final static String tableChineseName = "单据数量回写策略"; @Indexed @DataValidate(description = "唯一标识", nullable = false) @ApiModelProperty(value = "唯一标识",example="采购单回写") String key; @Indexed @DataValidate(description = "组织机构ID", nullable = true) @ApiModelProperty(value = "组织机构ID") private String organizationId; @Indexed @DataValidate(description = "运算符", nullable = false) @ApiModelProperty(value = "运算符",example="+") private String operator; //匹配策略,按顺序匹配(第1维数组是匹配顺序,第2维数组是匹配对象的属性名) //比如:[["reluuid"],["code","duty_price","tax"]] @DataValidate(description = "匹配策略,按顺序匹配", nullable = false) @ApiModelProperty(value = "匹配策略组",example="[[\"relUuid-uuid\"],[\"code\",\"duty_price\",\"tax\"]]") ArrayList<List<String>> matchPropertyNameStrategy; //回写数量的对象的属性名:比如: @DataValidate(description = "当前明细需要回写的字段的属性名", nullable = false) @ApiModelProperty(value = "当前明细需要回写的字段的属性名",example="quantity") String currentBackWriteValuePropertyName; //回写数量的对象的属性名:比如: @DataValidate(description = "回写数量的对象的属性名", nullable = false) @ApiModelProperty(value = "回写数量的对象的属性名",example="finishQuantity") String backWritePropertyName; //不能超过回写数量的对象的属性名 @DataValidate(description = "不能超过回写数量的对象的属性名", nullable = true) @ApiModelProperty(value = "不能超过回写数量的对象的属性名",example="planQuantity") String maxBackWritePropertyName; @DataValidate(description = "组织机构类型") @ApiModelProperty(value = "组织机构类型", example = "组织机构类型") private String organizationType; @DataValidate(description = "组织机构名称") @ApiModelProperty(value = "组织机构名称", example = "组织机构名称") private String organizationName; //备注:reluuid:关联uuid,code:商品编码。。。 String note; public ArrayList<List<String>> getMatchPropertyNameStrategy() { return matchPropertyNameStrategy; } public void setMatchPropertyNameStrategy(ArrayList<List<String>> matchPropertyNameStrategy) { this.matchPropertyNameStrategy = matchPropertyNameStrategy; } public String getCurrentBackWriteValuePropertyName() { return currentBackWriteValuePropertyName; } public void setCurrentBackWriteValuePropertyName(String currentBackWriteValuePropertyName) { this.currentBackWriteValuePropertyName = currentBackWriteValuePropertyName; } public String getBackWritePropertyName() { return backWritePropertyName; } public void setBackWritePropertyName(String backWritePropertyName) { this.backWritePropertyName = backWritePropertyName; } public String getMaxBackWritePropertyName() { return maxBackWritePropertyName; } public void setMaxBackWritePropertyName(String maxBackWritePropertyName) { this.maxBackWritePropertyName = maxBackWritePropertyName; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } public String getOrganizationId() { return organizationId; } public void setOrganizationId(String organizationId) { this.organizationId = organizationId; } public String getNote() { return note; } public void setNote(String note) { this.note = note; } public String getOperator() { return operator; } public void setOperator(String operator) { this.operator = operator; } public String getOrganizationType() { return organizationType; } public void setOrganizationType(String organizationType) { this.organizationType = organizationType; } public String getOrganizationName() { return organizationName; } public void setOrganizationName(String organizationName) { this.organizationName = organizationName; } public void restoreByOriginal(BackWriteQuantityStrategy oldObject) { setCreateAt(oldObject.getCreateAt()); setKey(oldObject.getKey()); } }
2.编写公用的策略方法:
package com.pangu.mss.api.impl.basic; import com.alibaba.dubbo.config.annotation.Service; import com.pangu.mss.api.basic.BackWriteQuantityOfItemApi; import com.pangu.mss.api.utils.strategy.DecimalPrecisionStrategyApi; import com.pangu.mss.common.mongo.Mongo; import com.pangu.mss.domain.mongo.basic.BackWriteQuantityStrategy; import com.pangu.mss.domain.mongo.order.OrderMedicalNo; import com.pangu.mss.enums.ApiOutputCode; import com.pangu.mss.ibp.convert.Convert; import com.pangu.mss.response.ApiOutput; import com.pangu.mss.utils.ArithUtils; import com.pangu.mss.utils.BeanUtils; import com.pangu.mss.utils.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import javax.annotation.Resource; import java.util.*; @Service(version = "1.0.0") @org.springframework.stereotype.Service public class BackWriteQuantityOfItemApiImpl implements BackWriteQuantityOfItemApi { private Logger log = Logger.getLogger(this.getClass()); @Resource DecimalPrecisionStrategyApi decimalPrecisionStrategyApi; @Override public ApiOutput<LinkedHashSet<Object>> batchBackWrite(Object currentList, Object backWriteList, List<BackWriteQuantityStrategy> strategys, String id, Class<?> cls, String organizationId,boolean allowOverNum){ ApiOutput<LinkedHashSet<Object>> apiOutput = new ApiOutput<>(); if(!CollectionUtils.isNotEmpty(strategys)){ apiOutput.setFailMsg("数量回写失败。回写策略为空"); return apiOutput; } //用于存放当前回写对象 LinkedHashSet<Object> objects = new LinkedHashSet<>(); Set<String> feilds = new HashSet<>(); for (BackWriteQuantityStrategy strategy : strategys) { if(StringUtils.isNotBlank(strategy.getBackWritePropertyName())){ feilds.add(strategy.getBackWritePropertyName()); } ApiOutput<LinkedHashSet<Object>> linkedHashSetApiOutput = null; if(!CollectionUtils.isNotEmpty(objects)){ linkedHashSetApiOutput = this.backWriteReturn(currentList, backWriteList, strategy,allowOverNum); }else{ linkedHashSetApiOutput = this.backWriteReturn(currentList,objects,strategy,allowOverNum); } if(!linkedHashSetApiOutput.isSuccess()){ return linkedHashSetApiOutput; } objects = linkedHashSetApiOutput.getData(); } if(!CollectionUtils.isNotEmpty(feilds)){ apiOutput.setFailMsg("数量回写失败。数量回写字段为空"); return apiOutput; } if(!CollectionUtils.isNotEmpty(objects)){ apiOutput.setFailMsg("数量回写失败。回写明细为空"); return apiOutput; } for (Object orderMedicalNo : objects) { Criteria criteria1 = Criteria.where("_id").is(id); Criteria criteria2 = Criteria.where("orderMedicalNos.uuid").is(BeanUtils.getPropertyValue(orderMedicalNo,"uuid").toString()); Criteria criteria = Criteria.where("").andOperator(criteria1, criteria2); Query que = Query.query(criteria); Update update = new Update(); for (String feild : feilds) { Double quantity = Double.valueOf((BeanUtils.getPropertyValue(orderMedicalNo, feild)==null?0d:BeanUtils.getPropertyValue(orderMedicalNo, feild)).toString()); update.set("orderMedicalNos.$."+feild,decimalPrecisionStrategyApi.convertQuantity(quantity,organizationId)); } Mongo.buildMongo().getMongoOperations().updateMulti(que, update, cls); } apiOutput.setData(objects); return apiOutput; } @Override public ApiOutput<LinkedHashSet<Object>> batchBackWrite_overNum(Object currentList, Object backWriteList, List<BackWriteQuantityStrategy> strategys, String id, Class<?> cls, String organizationId, boolean allowOverNum) { ApiOutput<LinkedHashSet<Object>> apiOutput = new ApiOutput<>(); if (!CollectionUtils.isNotEmpty(strategys)) { apiOutput.setFailMsg("数量回写失败。回写策略为空"); return apiOutput; } LinkedHashSet<Object> objects = new LinkedHashSet<>(); Set<String> feilds = new HashSet<>(); for (BackWriteQuantityStrategy strategy : strategys) { if (StringUtils.isNotBlank(strategy.getBackWritePropertyName())) { feilds.add(strategy.getBackWritePropertyName()); } ApiOutput<LinkedHashSet<Object>> linkedHashSetApiOutput = null; if (!CollectionUtils.isNotEmpty(objects)) { linkedHashSetApiOutput = this.backWriteReturn_overNum(currentList, backWriteList, strategy,allowOverNum); } else { linkedHashSetApiOutput = this.backWriteReturn_overNum(currentList, objects, strategy,allowOverNum); } if (!linkedHashSetApiOutput.isSuccess()) { return linkedHashSetApiOutput; } objects = linkedHashSetApiOutput.getData(); } if (!CollectionUtils.isNotEmpty(feilds)) { apiOutput.setFailMsg("数量回写失败。数量回写字段为空"); return apiOutput; } if (!CollectionUtils.isNotEmpty(objects)) { apiOutput.setFailMsg("数量回写失败。回写明细为空"); return apiOutput; } for (Object orderMedicalNo : objects) { Criteria criteria1 = Criteria.where("_id").is(id); Criteria criteria2 = Criteria.where("orderMedicalNos.uuid").is(BeanUtils.getPropertyValue(orderMedicalNo, "uuid").toString()); Criteria criteria = Criteria.where("").andOperator(criteria1, criteria2); Query que = Query.query(criteria); Update update = new Update(); for (String feild : feilds) { Double quantity = Double.valueOf((BeanUtils.getPropertyValue(orderMedicalNo, feild) == null ? 0d : BeanUtils.getPropertyValue(orderMedicalNo, feild)).toString()); update.set("orderMedicalNos.$." + feild, decimalPrecisionStrategyApi.convertQuantity(quantity, organizationId)); } Mongo.buildMongo().getMongoOperations().updateMulti(que, update, cls); } apiOutput.setData(objects); return apiOutput; } /** * 此方法,不受最大可回写数量,不能扣减为负的限制 * @param currentList * @param backWriteList * @param backWriteQuantityStrategy * @param id * @param cls * @return */ public ApiOutput<LinkedHashSet<Object>> backWrite_Remain(Object currentList, Object backWriteList, BackWriteQuantityStrategy backWriteQuantityStrategy, String id, Class<?> cls) { ApiOutput<LinkedHashSet<Object>> apiOutput = new ApiOutput<>(); LinkedHashSet<Object> lastOrderMedicalNos = new LinkedHashSet<>(); LinkedHashSet<Object> currentOrderMedicalNoList = (LinkedHashSet<Object>) currentList; LinkedHashSet<Object> backWriteSet = (LinkedHashSet<Object>) backWriteList; List<Object> backWriteNos = new ArrayList<>(backWriteSet); Collections.reverse(backWriteNos); LinkedHashSet<Object> backWriteOrderMedicalNoList = new LinkedHashSet<>(); backWriteOrderMedicalNoList.addAll(backWriteNos); lastOrderMedicalNos.addAll(backWriteOrderMedicalNoList); Map<String, Double> residualMap = new HashMap<>();//key:商品名/value:剩余数量 Set<String> uuids = new LinkedHashSet<>();//已经回写了的明细 //1.匹配策略优先级,遍历,找到合适的条目。 for (Object currentOrderMedicalNo : currentOrderMedicalNoList) { //2.匹配后回写数量逻辑-获取值 反射获取 backWriteQuantityStrategy.getBackWritePropertyName().举例: Double currentBackWriteValue = (Double) (BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName())); Object backWriteOrderMedicalNo = getMatchOrderMedicalNoByStrategy(currentOrderMedicalNo, backWriteOrderMedicalNoList, backWriteQuantityStrategy, uuids); //剩余数量 Double residualQuantity = currentBackWriteValue; //剩余数量,回写数量,剩余的进入下一轮匹配回写。 int maxWhileNumber = 0;//保护措施,防止死循环导致,服务器挂掉 while (residualQuantity > 0 && backWriteOrderMedicalNo != null && maxWhileNumber < 9999) { maxWhileNumber++; Double backWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())); if ("+".equals(backWriteQuantityStrategy.getOperator())) { backWriteValue = ArithUtils.add(residualQuantity, backWriteValue); residualQuantity = 0d; uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, "uuid").toString()); } if ("-".equals(backWriteQuantityStrategy.getOperator())) { // Double ownVlue=(Double)(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())==null?0d:BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName())); //直接减去回写数量 backWriteValue = ArithUtils.subtract(backWriteValue, residualQuantity); residualQuantity = 0d; uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, "uuid").toString()); } BeanUtils.setProperty(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName(), backWriteValue); /** * 将数据写回去 */ Criteria criteria1 = Criteria.where("_id").is(id); Criteria criteria2 = Criteria.where("orderMedicalNos.uuid").is(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, "uuid").toString()); Criteria criteria = Criteria.where("").andOperator(criteria1, criteria2); Query que = Query.query(criteria); Update update = new Update(); update.set("orderMedicalNos.$." + backWriteQuantityStrategy.getBackWritePropertyName(), backWriteValue); Mongo.buildMongo().getMongoOperations().updateMulti(que, update, cls); if (residualQuantity > 0) { backWriteOrderMedicalNo = getMatchOrderMedicalNoByStrategy(currentOrderMedicalNo, backWriteOrderMedicalNoList, backWriteQuantityStrategy, uuids); } } if (maxWhileNumber > 9999) { throw new RuntimeException("residualQuantity maxWhileNumber:9999"); } if (residualQuantity > 0l) { residualMap.put((BeanUtils.getPropertyValue(currentOrderMedicalNo, "name") == null ? "" : BeanUtils.getPropertyValue(currentOrderMedicalNo, "name")).toString(), residualQuantity); } } /** * 再倒序回去 */ List<Object> returnNos = new ArrayList<>(backWriteOrderMedicalNoList); Collections.reverse(returnNos); LinkedHashSet<Object> returnList = new LinkedHashSet<>(); returnList.addAll(backWriteNos); apiOutput.setData(returnList); return apiOutput; } /** * 此方法,不受最大可回写数量,不能扣减为负的限制 * @param currentList * @param backWriteList * @param backWriteQuantityStrategy * @return */ public ApiOutput<LinkedHashSet<Object>> backWriteReturn_Remain(Object currentList, Object backWriteList, BackWriteQuantityStrategy backWriteQuantityStrategy) { ApiOutput<LinkedHashSet<Object>> apiOutput = new ApiOutput<>(); LinkedHashSet<Object> lastOrderMedicalNos = new LinkedHashSet<>(); LinkedHashSet<Object> currentOrderMedicalNoList = (LinkedHashSet<Object>) currentList; LinkedHashSet<Object> backWriteSet = (LinkedHashSet<Object>) backWriteList; List<Object> backWriteNos = new ArrayList<>(backWriteSet); Collections.reverse(backWriteNos); LinkedHashSet<Object> backWriteOrderMedicalNoList = new LinkedHashSet<>(); backWriteOrderMedicalNoList.addAll(backWriteNos); lastOrderMedicalNos.addAll(backWriteOrderMedicalNoList); Map<String, Double> residualMap = new HashMap<>();//key:商品名/value:剩余数量 Set<String> uuids = new LinkedHashSet<>();//已经回写了的明细 //1.匹配策略优先级,遍历,找到合适的条目。 for (Object currentOrderMedicalNo : currentOrderMedicalNoList) { //2.匹配后回写数量逻辑-获取值 反射获取 backWriteQuantityStrategy.getBackWritePropertyName().举例: Double currentBackWriteValue = (Double) (BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName())); Object backWriteOrderMedicalNo = getMatchOrderMedicalNoByStrategy(currentOrderMedicalNo, backWriteOrderMedicalNoList, backWriteQuantityStrategy, uuids); //剩余数量 Double residualQuantity = currentBackWriteValue; //剩余数量,回写数量,剩余的进入下一轮匹配回写。 int maxWhileNumber = 0;//保护措施,防止死循环导致,服务器挂掉 while (residualQuantity > 0 && backWriteOrderMedicalNo != null && maxWhileNumber < 9999) { maxWhileNumber++; Double backWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())); if ("+".equals(backWriteQuantityStrategy.getOperator())) { //3.匹配后回写数量逻辑-获取最大值 Double maxBackWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName())); backWriteValue = ArithUtils.add(residualQuantity, backWriteValue); residualQuantity = 0d; if (backWriteValue.equals(maxBackWriteValue)) { uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, "uuid").toString()); } } if ("-".equals(backWriteQuantityStrategy.getOperator())) { // Double ownVlue=(Double)(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())==null?0d:BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName())); //直接减去回写数量 backWriteValue = ArithUtils.subtract(backWriteValue, residualQuantity); residualQuantity = 0d; if (backWriteValue.equals(0d)) { uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, "uuid").toString()); } } BeanUtils.setProperty(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName(), backWriteValue); if (residualQuantity > 0) { backWriteOrderMedicalNo = getMatchOrderMedicalNoByStrategy(currentOrderMedicalNo, backWriteOrderMedicalNoList, backWriteQuantityStrategy, uuids); } } if (maxWhileNumber > 9999) { throw new RuntimeException("residualQuantity maxWhileNumber:9999"); } if (residualQuantity > 0l) { residualMap.put((BeanUtils.getPropertyValue(currentOrderMedicalNo, "name") == null ? "" : BeanUtils.getPropertyValue(currentOrderMedicalNo, "name")).toString(), residualQuantity); } } if (!residualMap.isEmpty()) { apiOutput.setFailMsg("商品:" + Convert.toJson(residualMap.keySet()) + "超出了上游单据可回写数量,请联系管理员"); apiOutput.setData(lastOrderMedicalNos);//将传入的参数返回,方式因使用方法不当造成的问题 return apiOutput; } /** * 再倒序回去 */ List<Object> returnNos = new ArrayList<>(backWriteOrderMedicalNoList); Collections.reverse(returnNos); LinkedHashSet<Object> returnList = new LinkedHashSet<>(); returnList.addAll(backWriteNos); apiOutput.setData(returnList); return apiOutput; } @Override public ApiOutput<LinkedHashSet<Object>> canBackWrite(Object currentList, Object backWriteList, BackWriteQuantityStrategy backWriteQuantityStrategy) { ApiOutput<LinkedHashSet<Object>> apiOutput = new ApiOutput<>(); LinkedHashSet<Object> lastOrderMedicalNos = new LinkedHashSet<>(); BackWriteQuantityStrategy hasNotUuidStrategy = new BackWriteQuantityStrategy(); org.springframework.beans.BeanUtils.copyProperties(backWriteQuantityStrategy,hasNotUuidStrategy); ArrayList<List<String>> matchPropertyNameStrategy = hasNotUuidStrategy.getMatchPropertyNameStrategy(); Iterator<List<String>> iterator = matchPropertyNameStrategy.iterator(); while (iterator.hasNext()){ List<String> next = iterator.next(); if(next.contains("relUuid-uuid")){ iterator.remove(); } } /** * 由于这里会直接对回写进行设值,所以只能拷贝出来做验证。 */ LinkedHashSet<Object> currentOrderMedicalNoList = (LinkedHashSet<Object>)currentList; LinkedHashSet<Object> backWritList = (LinkedHashSet<Object>)backWriteList; LinkedHashSet<Object> backWriteOrderMedicalNoList = new LinkedHashSet<>(); for (Object o : backWritList) { OrderMedicalNo orderMedicalNo = (OrderMedicalNo)o; backWriteOrderMedicalNoList.add(orderMedicalNo.deepClone()); } // lastOrderMedicalNos.addAll(backWriteOrderMedicalNoList); Map<String, Double> residualMap = new HashMap<>();//key:商品名/value:剩余数量 Set<String> uuids = new LinkedHashSet<>();//已经回写了的明细 //1.匹配策略优先级,遍历,找到合适的条目。 for (Object currentOrderMedicalNo : currentOrderMedicalNoList) { //2.匹配后回写数量逻辑-获取值 反射获取 backWriteQuantityStrategy.getBackWritePropertyName().举例: Double currentBackWriteValue = (Double) (BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName())); Object backWriteOrderMedicalNo = getMatchOrderMedicalNoByStrategy(currentOrderMedicalNo, backWriteOrderMedicalNoList, backWriteQuantityStrategy,uuids); Object ifMatch = getMatchOrderMedicalNoByStrategyMatch(currentOrderMedicalNo, backWriteOrderMedicalNoList, hasNotUuidStrategy); //剩余数量 Double residualQuantity = currentBackWriteValue; //剩余数量,回写数量,剩余的进入下一轮匹配回写。 int maxWhileNumber = 0;//保护措施,防止死循环导致,服务器挂掉 while (residualQuantity > 0 && backWriteOrderMedicalNo != null && maxWhileNumber < 9999) { maxWhileNumber++; Double backWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())); if ("+".equals(backWriteQuantityStrategy.getOperator())) { //3.匹配后回写数量逻辑-获取最大值 Double maxBackWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName())); //回写数量,不能超过最大值(采购)数量。举例:10|5|8 =》 10-(8-5)=7(residualQuantity) if (ArithUtils.add(residualQuantity,backWriteValue) > maxBackWriteValue) { //下一循环回写:剩余数量+回写数量-最大值 residualQuantity = ArithUtils.subtract(ArithUtils.add(residualQuantity,backWriteValue),maxBackWriteValue); backWriteValue = maxBackWriteValue; // throw new RuntimeException("超过数量"); } else { backWriteValue = ArithUtils.add(residualQuantity,backWriteValue); residualQuantity = 0d; } if(backWriteValue.equals(maxBackWriteValue)){ uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo,"uuid").toString()); } } if ("-".equals(backWriteQuantityStrategy.getOperator())) { // Double ownVlue=(Double)(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())==null?0d:BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName())); if (ArithUtils.subtract(backWriteValue,residualQuantity) < 0) { //回写会扣为负?多余的留到下一轮扣减(剩余数量-回写数量) residualQuantity = ArithUtils.subtract(residualQuantity,backWriteValue); backWriteValue = 0d; } else { //直接减去回写数量 backWriteValue = ArithUtils.subtract(backWriteValue,residualQuantity); residualQuantity = 0d; } if(backWriteValue.equals(0d)){ uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo,"uuid").toString()); } } BeanUtils.setProperty(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName(), backWriteValue); if(residualQuantity>0){ backWriteOrderMedicalNo = getMatchOrderMedicalNoByStrategy(currentOrderMedicalNo, backWriteOrderMedicalNoList, backWriteQuantityStrategy,uuids); } } if (maxWhileNumber > 9999) { throw new RuntimeException("residualQuantity maxWhileNumber:9999"); } if(null==ifMatch){ //税率。单价等属性不一致 apiOutput.setApiOutputCode(ApiOutputCode.回写失败); BeanUtils.setProperty(currentOrderMedicalNo,"attachmentsValidFlag",true); lastOrderMedicalNos.add(currentOrderMedicalNo); residualMap.put((BeanUtils.getPropertyValue(currentOrderMedicalNo, "name") == null ? "" : BeanUtils.getPropertyValue(currentOrderMedicalNo, "name")).toString(), residualQuantity); }else if (residualQuantity > 0l) { apiOutput.setApiOutputCode(ApiOutputCode.回写失败); BeanUtils.setProperty(currentOrderMedicalNo,"attachmentsValidFlag",false); lastOrderMedicalNos.add(currentOrderMedicalNo); residualMap.put((BeanUtils.getPropertyValue(currentOrderMedicalNo, "name")==null?"":BeanUtils.getPropertyValue(currentOrderMedicalNo, "name")).toString(), residualQuantity); } } if (!residualMap.isEmpty()) { StringBuilder stringBuilder = new StringBuilder(); String msg = null; if(CollectionUtils.isNotEmpty(residualMap.keySet())){ residualMap.keySet().forEach(name->{ stringBuilder.append(name+"、"); }); String s = stringBuilder.toString(); msg = s.substring(0, s.length() - 1); } apiOutput.setMsg(msg); apiOutput.setData(lastOrderMedicalNos);//将传入的参数返回,方式因使用方法不当造成的问题 return apiOutput; } apiOutput.setData(backWriteOrderMedicalNoList); return apiOutput; } @Override public ApiOutput<LinkedHashSet<Object>> backWrite(Object currentList, Object backWriteList, BackWriteQuantityStrategy backWriteQuantityStrategy,String id,Class<?> cls, boolean allowOverNum) { ApiOutput<LinkedHashSet<Object>> apiOutput = new ApiOutput<>(); LinkedHashSet<Object> lastOrderMedicalNos = new LinkedHashSet<>(); LinkedHashSet<Object> currentOrderMedicalNoList = (LinkedHashSet<Object>)currentList; LinkedHashSet<Object> remainOrderMedicalNoList = new LinkedHashSet<>(); LinkedHashSet<Object> backWriteOrderMedicalNoList = (LinkedHashSet<Object>)backWriteList; lastOrderMedicalNos.addAll(backWriteOrderMedicalNoList); Map<String, Double> residualMap = new HashMap<>();//key:商品名/value:剩余数量 Set<String> uuids = new LinkedHashSet<>();//已经回写了的明细 //1.匹配策略优先级,遍历,找到合适的条目。 for (Object currentOrderMedicalNo : currentOrderMedicalNoList) { //2.匹配后回写数量逻辑-获取值 反射获取 backWriteQuantityStrategy.getBackWritePropertyName().举例: Double currentBackWriteValue = (Double) (BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName())); Object backWriteOrderMedicalNo = getMatchOrderMedicalNoByStrategy(currentOrderMedicalNo, backWriteOrderMedicalNoList, backWriteQuantityStrategy,uuids); //剩余数量 Double residualQuantity = currentBackWriteValue; //剩余数量,回写数量,剩余的进入下一轮匹配回写。 int maxWhileNumber = 0;//保护措施,防止死循环导致,服务器挂掉 while (residualQuantity > 0 && backWriteOrderMedicalNo != null && maxWhileNumber < 9999) { maxWhileNumber++; Double backWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())); if ("+".equals(backWriteQuantityStrategy.getOperator())) { //3.匹配后回写数量逻辑-获取最大值 Double maxBackWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName())); //回写数量,不能超过最大值(采购)数量。举例:10|5|8 =》 10-(8-5)=7(residualQuantity) if (ArithUtils.add(residualQuantity,backWriteValue) > maxBackWriteValue) { //下一循环回写:剩余数量+回写数量-最大值 residualQuantity = ArithUtils.subtract(ArithUtils.add(residualQuantity,backWriteValue),maxBackWriteValue); backWriteValue = maxBackWriteValue; // throw new RuntimeException("超过数量"); } else { backWriteValue = ArithUtils.add(residualQuantity,backWriteValue); residualQuantity = 0d; } if(backWriteValue.equals(maxBackWriteValue)){ uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo,"uuid").toString()); } } if ("-".equals(backWriteQuantityStrategy.getOperator())) { // Double ownVlue=(Double)(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())==null?0d:BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName())); if (ArithUtils.subtract(backWriteValue,residualQuantity) < 0) { //回写会扣为负?多余的留到下一轮扣减(剩余数量-回写数量) residualQuantity = ArithUtils.subtract(residualQuantity,backWriteValue); backWriteValue = 0d; } else { //直接减去回写数量 backWriteValue = ArithUtils.subtract(backWriteValue,residualQuantity); residualQuantity = 0d; } if(backWriteValue.equals(0d)){ uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo,"uuid").toString()); } } BeanUtils.setProperty(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName(), backWriteValue); /** * 将数据写回去 */ Criteria criteria1 = Criteria.where("_id").is(id); Criteria criteria2 = Criteria.where("orderMedicalNos.uuid").is(BeanUtils.getPropertyValue(backWriteOrderMedicalNo,"uuid").toString()); Criteria criteria = Criteria.where("").andOperator(criteria1, criteria2); Query que = Query.query(criteria); Update update = new Update(); update.set("orderMedicalNos.$."+backWriteQuantityStrategy.getBackWritePropertyName(),backWriteValue); Mongo.buildMongo().getMongoOperations().updateMulti(que, update, cls); if(residualQuantity>0){ backWriteOrderMedicalNo = getMatchOrderMedicalNoByStrategy(currentOrderMedicalNo, backWriteOrderMedicalNoList, backWriteQuantityStrategy,uuids); } } if (maxWhileNumber > 9999) { throw new RuntimeException("residualQuantity maxWhileNumber:9999"); } if (residualQuantity > 0l) { residualMap.put((BeanUtils.getPropertyValue(currentOrderMedicalNo, "name")==null?"":BeanUtils.getPropertyValue(currentOrderMedicalNo, "name")).toString(), residualQuantity); remainOrderMedicalNoList.add(currentOrderMedicalNo); residualMap.put((BeanUtils.getPropertyValue(currentOrderMedicalNo, "name") == null ? "" : BeanUtils.getPropertyValue(currentOrderMedicalNo, "name")).toString(), residualQuantity); } } if (!residualMap.isEmpty()) { if(!allowOverNum) { apiOutput.setFailMsg("商品:" + Convert.toJson(residualMap.keySet()) + "超出了上游单据可回写数量,请联系管理员"); apiOutput.setData(lastOrderMedicalNos);//将传入的参数返回,方式因使用方法不当造成的问题 return apiOutput; }else{ return this.backWrite_Remain(remainOrderMedicalNoList,backWriteOrderMedicalNoList,backWriteQuantityStrategy,id,cls); } } apiOutput.setData(backWriteOrderMedicalNoList); return apiOutput; } @Override public ApiOutput<LinkedHashSet<Object>> backWrite_OverNum(Object currentList, Object backWriteList, BackWriteQuantityStrategy backWriteQuantityStrategy, String id, Class<?> cls, boolean allowOverNum) { ApiOutput<LinkedHashSet<Object>> apiOutput = new ApiOutput<>(); LinkedHashSet<Object> lastOrderMedicalNos = new LinkedHashSet<>(); LinkedHashSet<Object> currentOrderMedicalNoList = (LinkedHashSet<Object>) currentList; LinkedHashSet<Object> remainOrderMedicalNoList = new LinkedHashSet<>(); LinkedHashSet<Object> backWriteOrderMedicalNoList = (LinkedHashSet<Object>) backWriteList; lastOrderMedicalNos.addAll(backWriteOrderMedicalNoList); Map<String, Double> residualMap = new HashMap<>();//key:商品名/value:剩余数量 Set<String> uuids = new LinkedHashSet<>();//已经回写了的明细 //1.匹配策略优先级,遍历,找到合适的条目。 for (Object currentOrderMedicalNo : currentOrderMedicalNoList) { //2.匹配后回写数量逻辑-获取值 反射获取 backWriteQuantityStrategy.getBackWritePropertyName().举例: Double currentBackWriteValue = (Double) (BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName())); List<Object> backWriteOrderMedicalNos = getMatchOrderMedicalNoByStrategy_OverNum(currentOrderMedicalNo, backWriteOrderMedicalNoList, backWriteQuantityStrategy, uuids); //剩余数量 Double residualQuantity = currentBackWriteValue; //剩余数量,回写数量,剩余的进入下一轮匹配回写。 int maxWhileNumber = 0;//保护措施,防止死循环导致,服务器挂掉 // while (residualQuantity > 0 && !org.springframework.util.CollectionUtils.isEmpty(backWriteOrderMedicalNos) && maxWhileNumber < 9999) { int index = 0; for (Object backWriteOrderMedicalNo : backWriteOrderMedicalNos) { index++; maxWhileNumber++; Double backWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())); if ("+".equals(backWriteQuantityStrategy.getOperator())) { //3.匹配后回写数量逻辑-获取最大值 Double maxBackWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName())); //如果是最后一条,并且允许超收的场景,不限制,直接回写 if(index==backWriteOrderMedicalNos.size() && allowOverNum){ //回写数量,不能超过最大值(采购)数量。举例:10|5|8 =》 10-(8-5)=7(residualQuantity) backWriteValue = ArithUtils.add(residualQuantity, backWriteValue); residualQuantity = 0d; }else if (ArithUtils.add(residualQuantity, backWriteValue) > maxBackWriteValue) { //剩余数量-本次回写数量 residualQuantity = ArithUtils.subtract(residualQuantity,maxBackWriteValue); //本次回写数量+原有数量 backWriteValue = ArithUtils.add(maxBackWriteValue,backWriteValue); } else { backWriteValue = ArithUtils.add(residualQuantity, backWriteValue); residualQuantity = 0d; } if (backWriteValue.equals(maxBackWriteValue)) { uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, "uuid").toString()); } } if ("-".equals(backWriteQuantityStrategy.getOperator())) { //如果是最后一条,并且允许超收的场景,不限制直接回写 if(index==backWriteOrderMedicalNos.size() && allowOverNum){ //直接减去回写数量 backWriteValue = ArithUtils.subtract(backWriteValue, residualQuantity); residualQuantity = 0d; }else if (ArithUtils.subtract(backWriteValue, residualQuantity) < 0) { //回写会扣为负?多余的留到下一轮扣减(剩余数量-回写数量) residualQuantity = ArithUtils.subtract(residualQuantity, backWriteValue); backWriteValue = 0d; } else { //直接减去回写数量 backWriteValue = ArithUtils.subtract(backWriteValue, residualQuantity); residualQuantity = 0d; } if (backWriteValue.equals(0d)) { uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, "uuid").toString()); } } BeanUtils.setProperty(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName(), backWriteValue); /** * 将数据写回去 */ Criteria criteria1 = Criteria.where("_id").is(id); Criteria criteria2 = Criteria.where("orderMedicalNos.uuid").is(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, "uuid").toString()); Criteria criteria = Criteria.where("").andOperator(criteria1, criteria2); Query que = Query.query(criteria); Update update = new Update(); update.set("orderMedicalNos.$." + backWriteQuantityStrategy.getBackWritePropertyName(), backWriteValue); Mongo.buildMongo().getMongoOperations().updateMulti(que, update, cls); } // } if (maxWhileNumber > 9999) { throw new RuntimeException("residualQuantity maxWhileNumber:9999"); } if (residualQuantity > 0) { BeanUtils.setProperty(currentOrderMedicalNo,backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName(),residualQuantity); remainOrderMedicalNoList.add(currentOrderMedicalNo); residualMap.put((BeanUtils.getPropertyValue(currentOrderMedicalNo, "name") == null ? "" : BeanUtils.getPropertyValue(currentOrderMedicalNo, "name")).toString(), residualQuantity); } } if (!residualMap.isEmpty()) { if(!allowOverNum){ apiOutput.setFailMsg("商品:" + Convert.toJson(residualMap.keySet()) + "超出了上游单据可回写数量,请联系管理员"); apiOutput.setData(lastOrderMedicalNos);//将传入的参数返回,方式因使用方法不当造成的问题 return apiOutput; }else{ return this.backWrite_Remain(remainOrderMedicalNoList,backWriteOrderMedicalNoList,backWriteQuantityStrategy,id,cls); } } apiOutput.setData(backWriteOrderMedicalNoList); return apiOutput; } //匹配策略优先级,遍历,找到合适的条目。 private Object getMatchOrderMedicalNoByStrategy(Object currentOrderMedicalNo, LinkedHashSet<Object> backWriteOrderMedicalNoList, BackWriteQuantityStrategy backWriteQuantityStrategy,Set<String> uuids) { Object backWriteOrderMedicalNo = null; ////匹配策略,按顺序匹配(第1维数组是匹配顺序,第2维数组是匹配对象的属性名) for (List<String> matchpropertyNameStrategy : backWriteQuantityStrategy.getMatchPropertyNameStrategy()) {//第1维数组是匹配顺序 for (Object orderMedicalNo : backWriteOrderMedicalNoList) {//遍历匹配的目标商品列表,进行匹配。 ////回写数量,不能超过采购数量。(maxBackWritePropertyName:为空标识不限制,不为空边上限制),匹配时过滤掉,防止无线循环。 // Double backWriteValue =(Double)(BeanUtils.getPropertyValue(orderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())==null?0d:BeanUtils.getPropertyValue(orderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())); /** * 由于同时存在合并单据和拆分单据的情况,因此下面注释这段简单的判断是不对的。 */ /*Double backWriteValue = (Double) (BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName())); if (StringUtils.isNotBlank(backWriteQuantityStrategy.getMaxBackWritePropertyName())) { Double maxBackWriteValue = (Double) (BeanUtils.getPropertyValue(orderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(orderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName())); if ("+".equals(backWriteQuantityStrategy.getOperator())) { if (maxBackWriteValue < backWriteValue) { continue; } } if ("-".equals(backWriteQuantityStrategy.getOperator())) { Double ownVlue = (Double) (BeanUtils.getPropertyValue(orderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(orderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())); if (backWriteValue > ownVlue) { continue; } } }*/ boolean isMatch = true; for (String matchpropertyNameStrategyItem : matchpropertyNameStrategy) { //matchpropertyNameStrategyItem=\"reluuid-uuid\"; String currentOrderMedicalNoKey = null; String orderMedicalNoKey = null; if (matchpropertyNameStrategyItem.contains("-")) { String[] matchpropertyNameStrategyItemArray = matchpropertyNameStrategyItem.split("-"); currentOrderMedicalNoKey = matchpropertyNameStrategyItemArray[0]; orderMedicalNoKey = matchpropertyNameStrategyItemArray[1]; } else { currentOrderMedicalNoKey = matchpropertyNameStrategyItem; orderMedicalNoKey = matchpropertyNameStrategyItem; } Object currentOrderMedicalNomatchpropertyNameStrategyItemValue = BeanUtils.getPropertyValue(currentOrderMedicalNo, currentOrderMedicalNoKey); Object orderMedicalNomatchpropertyNameStrategyItemValue = BeanUtils.getPropertyValue(orderMedicalNo, orderMedicalNoKey); //只要有1个不满足,则不匹配,中断。 if (currentOrderMedicalNomatchpropertyNameStrategyItemValue == null || orderMedicalNomatchpropertyNameStrategyItemValue == null || !currentOrderMedicalNomatchpropertyNameStrategyItemValue.equals(orderMedicalNomatchpropertyNameStrategyItemValue)) { // backWriteOrderMedicalNo=orderMedicalNo; isMatch = false; break; } else { backWriteOrderMedicalNo = orderMedicalNo; } } if (backWriteOrderMedicalNo != null && isMatch && !uuids.contains(BeanUtils.getPropertyValue(backWriteOrderMedicalNo,"uuid"))) return backWriteOrderMedicalNo; } } return null; } //匹配策略优先级,遍历,找到合适的条目。_兼容数量超收的场景 private List<Object> getMatchOrderMedicalNoByStrategy_OverNum(Object currentOrderMedicalNo, LinkedHashSet<Object> backWriteOrderMedicalNoList, BackWriteQuantityStrategy backWriteQuantityStrategy, Set<String> uuids) { // Object backWriteOrderMedicalNo = null; List<Object> backWriteOrderMedicalNos = new ArrayList<>(); ////匹配策略,按顺序匹配(第1维数组是匹配顺序,第2维数组是匹配对象的属性名) //第1维数组是匹配顺序 for (List<String> matchpropertyNameStrategy : backWriteQuantityStrategy.getMatchPropertyNameStrategy()) { //遍历匹配的目标商品列表,进行匹配。 for (Object orderMedicalNo : backWriteOrderMedicalNoList) { int index = 0; for (String matchpropertyNameStrategyItem : matchpropertyNameStrategy) { index++; String currentOrderMedicalNoKey = null; String orderMedicalNoKey = null; if (matchpropertyNameStrategyItem.contains("-")) { String[] matchpropertyNameStrategyItemArray = matchpropertyNameStrategyItem.split("-"); currentOrderMedicalNoKey = matchpropertyNameStrategyItemArray[0]; orderMedicalNoKey = matchpropertyNameStrategyItemArray[1]; } else { currentOrderMedicalNoKey = matchpropertyNameStrategyItem; orderMedicalNoKey = matchpropertyNameStrategyItem; } Object currentOrderMedicalNomatchpropertyNameStrategyItemValue = BeanUtils.getPropertyValue(currentOrderMedicalNo, currentOrderMedicalNoKey); Object orderMedicalNomatchpropertyNameStrategyItemValue = BeanUtils.getPropertyValue(orderMedicalNo, orderMedicalNoKey); //只要有1个不满足,则不匹配,中断。 if (currentOrderMedicalNomatchpropertyNameStrategyItemValue == null || orderMedicalNomatchpropertyNameStrategyItemValue == null || !currentOrderMedicalNomatchpropertyNameStrategyItemValue.equals(orderMedicalNomatchpropertyNameStrategyItemValue)) { break; } else if(index == matchpropertyNameStrategy.size()){ backWriteOrderMedicalNos.add(orderMedicalNo); } } } if(backWriteOrderMedicalNos.size()>0){ return backWriteOrderMedicalNos; }else{ backWriteOrderMedicalNos.clear(); continue; } } return backWriteOrderMedicalNos; } //匹配策略优先级,遍历,找到合适的条目。 private Object getMatchOrderMedicalNoByStrategyMatch(Object currentOrderMedicalNo, LinkedHashSet<Object> backWriteOrderMedicalNoList, BackWriteQuantityStrategy backWriteQuantityStrategy) { Object backWriteOrderMedicalNo = null; ////匹配策略,按顺序匹配(第1维数组是匹配顺序,第2维数组是匹配对象的属性名) //第1维数组是匹配顺序 for (List<String> matchpropertyNameStrategy : backWriteQuantityStrategy.getMatchPropertyNameStrategy()) { //遍历匹配的目标商品列表,进行匹配。 for (Object orderMedicalNo : backWriteOrderMedicalNoList) { boolean thi = false; boolean isMatch = true; for (String matchpropertyNameStrategyItem : matchpropertyNameStrategy) { //matchpropertyNameStrategyItem=\"reluuid-uuid\"; String currentOrderMedicalNoKey = null; String orderMedicalNoKey = null; if (matchpropertyNameStrategyItem.contains("-")) { String[] matchpropertyNameStrategyItemArray = matchpropertyNameStrategyItem.split("-"); currentOrderMedicalNoKey = matchpropertyNameStrategyItemArray[0]; orderMedicalNoKey = matchpropertyNameStrategyItemArray[1]; } else { currentOrderMedicalNoKey = matchpropertyNameStrategyItem; orderMedicalNoKey = matchpropertyNameStrategyItem; } Object currentOrderMedicalNomatchpropertyNameStrategyItemValue = BeanUtils.getPropertyValue(currentOrderMedicalNo, currentOrderMedicalNoKey); Object orderMedicalNomatchpropertyNameStrategyItemValue = BeanUtils.getPropertyValue(orderMedicalNo, orderMedicalNoKey); //只要有1个不满足,则不匹配,中断。 if (currentOrderMedicalNomatchpropertyNameStrategyItemValue == null || orderMedicalNomatchpropertyNameStrategyItemValue == null || !currentOrderMedicalNomatchpropertyNameStrategyItemValue.equals(orderMedicalNomatchpropertyNameStrategyItemValue)) { // backWriteOrderMedicalNo=orderMedicalNo; isMatch = false; break; } else { backWriteOrderMedicalNo = orderMedicalNo; } } if (backWriteOrderMedicalNo != null && isMatch) return backWriteOrderMedicalNo; } } return null; } @Override public ApiOutput<LinkedHashSet<OrderMedicalNo>> backWriteRollBack(LinkedHashSet<OrderMedicalNo> currentOrderMedicalNoList, LinkedHashSet<OrderMedicalNo> backWriteOrderMedicalNoList, BackWriteQuantityStrategy backWriteQuantityStrategy) { // TODO Auto-generated method stub return null; } @Override public ApiOutput<LinkedHashSet<Object>> backWriteReturn(Object currentList, Object backWriteList, BackWriteQuantityStrategy backWriteQuantityStrategy,boolean allowOverNum) { ApiOutput<LinkedHashSet<Object>> apiOutput = new ApiOutput<>(); LinkedHashSet<Object> lastOrderMedicalNos = new LinkedHashSet<>(); LinkedHashSet<Object> currentOrderMedicalNoList = (LinkedHashSet<Object>)currentList; LinkedHashSet<Object> remainOrderMedicalNoList = new LinkedHashSet<>(); LinkedHashSet<Object> backWriteOrderMedicalNoList = (LinkedHashSet<Object>)backWriteList; lastOrderMedicalNos.addAll(backWriteOrderMedicalNoList); Map<String, Double> residualMap = new HashMap<>();//key:商品名/value:剩余数量 Set<String> uuids = new LinkedHashSet<>();//已经回写了的明细 //1.匹配策略优先级,遍历,找到合适的条目。 for (Object currentOrderMedicalNo : currentOrderMedicalNoList) { //2.匹配后回写数量逻辑-获取值 反射获取 backWriteQuantityStrategy.getBackWritePropertyName().举例: Double currentBackWriteValue = (Double) (BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName())); Object backWriteOrderMedicalNo = getMatchOrderMedicalNoByStrategy(currentOrderMedicalNo, backWriteOrderMedicalNoList, backWriteQuantityStrategy,uuids); //剩余数量 Double residualQuantity = currentBackWriteValue; //剩余数量,回写数量,剩余的进入下一轮匹配回写。 int maxWhileNumber = 0;//保护措施,防止死循环导致,服务器挂掉 while (residualQuantity > 0 && backWriteOrderMedicalNo != null && maxWhileNumber < 9999) { maxWhileNumber++; Double backWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())); if ("+".equals(backWriteQuantityStrategy.getOperator())) { //3.匹配后回写数量逻辑-获取最大值 Double maxBackWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName())); //回写数量,不能超过最大值(采购)数量。举例:10|5|8 =》 10-(8-5)=7(residualQuantity) if (ArithUtils.add(residualQuantity,backWriteValue) > maxBackWriteValue) { //下一循环回写:剩余数量+回写数量-最大值 residualQuantity = ArithUtils.subtract(ArithUtils.add(residualQuantity,backWriteValue),maxBackWriteValue); backWriteValue = maxBackWriteValue; // throw new RuntimeException("超过数量"); } else { backWriteValue = ArithUtils.add(residualQuantity,backWriteValue); residualQuantity = 0d; } if(backWriteValue.equals(maxBackWriteValue)){ uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo,"uuid").toString()); } } if ("-".equals(backWriteQuantityStrategy.getOperator())) { // Double ownVlue=(Double)(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())==null?0d:BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName())); if (ArithUtils.subtract(backWriteValue,residualQuantity) < 0) { //回写会扣为负?多余的留到下一轮扣减(剩余数量-回写数量) residualQuantity = ArithUtils.subtract(residualQuantity,backWriteValue); backWriteValue = 0d; } else { //直接减去回写数量 backWriteValue = ArithUtils.subtract(backWriteValue,residualQuantity); residualQuantity = 0d; } if(backWriteValue.equals(0d)){ uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo,"uuid").toString()); } } BeanUtils.setProperty(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName(), backWriteValue); if(residualQuantity>0){ backWriteOrderMedicalNo = getMatchOrderMedicalNoByStrategy(currentOrderMedicalNo, backWriteOrderMedicalNoList, backWriteQuantityStrategy,uuids); } } if (maxWhileNumber > 9999) { throw new RuntimeException("residualQuantity maxWhileNumber:9999"); } if (residualQuantity > 0l) { BeanUtils.setProperty(currentOrderMedicalNo,backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName(),residualQuantity); remainOrderMedicalNoList.add(currentOrderMedicalNo); residualMap.put((BeanUtils.getPropertyValue(currentOrderMedicalNo, "name")==null?"":BeanUtils.getPropertyValue(currentOrderMedicalNo, "name")).toString(), residualQuantity); } } if (!residualMap.isEmpty()) { if(!allowOverNum) { apiOutput.setFailMsg("商品:" + Convert.toJson(residualMap.keySet()) + "超出了上游单据可回写数量,请联系管理员"); apiOutput.setData(lastOrderMedicalNos);//将传入的参数返回,方式因使用方法不当造成的问题 return apiOutput; }else{ return this.backWriteReturn_Remain(remainOrderMedicalNoList,backWriteOrderMedicalNoList,backWriteQuantityStrategy); } } apiOutput.setData(backWriteOrderMedicalNoList); return apiOutput; } @Override public ApiOutput<LinkedHashSet<Object>> backWriteReturn_overNum(Object currentList, Object backWriteList, BackWriteQuantityStrategy backWriteQuantityStrategy, boolean allowOverNum) { ApiOutput<LinkedHashSet<Object>> apiOutput = new ApiOutput<>(); LinkedHashSet<Object> lastOrderMedicalNos = new LinkedHashSet<>(); LinkedHashSet<Object> currentOrderMedicalNoList = (LinkedHashSet<Object>) currentList; LinkedHashSet<Object> remainOrderMedicalNoList = new LinkedHashSet<>(); LinkedHashSet<Object> backWriteOrderMedicalNoList = (LinkedHashSet<Object>) backWriteList; lastOrderMedicalNos.addAll(backWriteOrderMedicalNoList); Map<String, Double> residualMap = new HashMap<>();//key:商品名/value:剩余数量 Set<String> uuids = new LinkedHashSet<>();//已经回写了的明细 //1.匹配策略优先级,遍历,找到合适的条目。 for (Object currentOrderMedicalNo : currentOrderMedicalNoList) { //2.匹配后回写数量逻辑-获取值 反射获取 backWriteQuantityStrategy.getBackWritePropertyName().举例: Double currentBackWriteValue = (Double) (BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName())); List<Object> backWriteOrderMedicalNos = getMatchOrderMedicalNoByStrategy_OverNum(currentOrderMedicalNo, backWriteOrderMedicalNoList, backWriteQuantityStrategy, uuids); //剩余数量 Double residualQuantity = currentBackWriteValue; //剩余数量,回写数量,剩余的进入下一轮匹配回写。 int maxWhileNumber = 0;//保护措施,防止死循环导致,服务器挂掉 // while (residualQuantity > 0 && !org.springframework.util.CollectionUtils.isEmpty(backWriteOrderMedicalNos) && maxWhileNumber < 9999) { int index = 0; for (Object backWriteOrderMedicalNo : backWriteOrderMedicalNos) { index++; maxWhileNumber++; Double backWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())); if ("+".equals(backWriteQuantityStrategy.getOperator())) { //3.匹配后回写数量逻辑-获取最大值 Double maxBackWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName())); //允许超额回写到,到最后1条数据。 if(index==backWriteOrderMedicalNos.size() && allowOverNum){ backWriteValue = ArithUtils.add(residualQuantity, backWriteValue); residualQuantity = 0d; //回写数量,不能超过最大值(采购)数量。举例:10|5|8 =》 10-(8-5)=7(residualQuantity) }else if (ArithUtils.add(residualQuantity, backWriteValue) > maxBackWriteValue) { //下一循环回写:剩余数量+回写数量-最大值 residualQuantity = ArithUtils.subtract(ArithUtils.add(residualQuantity, backWriteValue), maxBackWriteValue); backWriteValue = maxBackWriteValue; // throw new RuntimeException("超过数量"); } else { backWriteValue = ArithUtils.add(residualQuantity, backWriteValue); residualQuantity = 0d; } if (backWriteValue.equals(maxBackWriteValue)) { uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, "uuid").toString()); } } if ("-".equals(backWriteQuantityStrategy.getOperator())) { if(index==backWriteOrderMedicalNos.size() && allowOverNum){ //直接减去回写数量 backWriteValue = ArithUtils.subtract(backWriteValue, residualQuantity); residualQuantity = 0d; }else if (ArithUtils.subtract(backWriteValue, residualQuantity) < 0) { //回写会扣为负?多余的留到下一轮扣减(剩余数量-回写数量) residualQuantity = ArithUtils.subtract(residualQuantity, backWriteValue); backWriteValue = 0d; } else { //直接减去回写数量 backWriteValue = ArithUtils.subtract(backWriteValue, residualQuantity); residualQuantity = 0d; } if (backWriteValue.equals(0d)) { uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, "uuid").toString()); } } BeanUtils.setProperty(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName(), backWriteValue); } // } if (maxWhileNumber > 9999) { throw new RuntimeException("residualQuantity maxWhileNumber:9999"); } if (residualQuantity > 0l) { BeanUtils.setProperty(currentOrderMedicalNo,backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName(),residualQuantity); remainOrderMedicalNoList.add(currentOrderMedicalNo); residualMap.put((BeanUtils.getPropertyValue(currentOrderMedicalNo, "name") == null ? "" : BeanUtils.getPropertyValue(currentOrderMedicalNo, "name")).toString(), residualQuantity); } } if (!residualMap.isEmpty()) { if(!allowOverNum){ apiOutput.setFailMsg("商品:" + Convert.toJson(residualMap.keySet()) + "超出了上游单据可回写数量,请联系管理员"); apiOutput.setData(lastOrderMedicalNos);//将传入的参数返回,方式因使用方法不当造成的问题 return apiOutput; }else{ return this.backWriteReturn_Remain(remainOrderMedicalNoList,backWriteOrderMedicalNoList,backWriteQuantityStrategy); } } apiOutput.setData(backWriteOrderMedicalNoList); return apiOutput; } @Override public ApiOutput<LinkedHashSet<Object>> getBackWriteQuantity(Object currentList, Object backWriteList, BackWriteQuantityStrategy backWriteQuantityStrategy) { ApiOutput<LinkedHashSet<Object>> apiOutput = new ApiOutput<>(); LinkedHashSet<Object> lastOrderMedicalNos = new LinkedHashSet<>(); BackWriteQuantityStrategy hasNotUuidStrategy = new BackWriteQuantityStrategy(); org.springframework.beans.BeanUtils.copyProperties(backWriteQuantityStrategy, hasNotUuidStrategy); ArrayList<List<String>> matchPropertyNameStrategy = hasNotUuidStrategy.getMatchPropertyNameStrategy(); Iterator<List<String>> iterator = matchPropertyNameStrategy.iterator(); while (iterator.hasNext()) { List<String> next = iterator.next(); if (next.contains("relUuid-uuid")) { iterator.remove(); } } /** * 由于这里会直接对回写进行设值,所以只能拷贝出来做验证。 */ LinkedHashSet<Object> currentOrderMedicalNoList = (LinkedHashSet<Object>) currentList; LinkedHashSet<Object> backWritList = (LinkedHashSet<Object>) backWriteList; LinkedHashSet<Object> backWriteOrderMedicalNoList = new LinkedHashSet<>(); for (Object o : backWritList) { OrderMedicalNo orderMedicalNo = (OrderMedicalNo) o; backWriteOrderMedicalNoList.add(orderMedicalNo.deepClone()); } // lastOrderMedicalNos.addAll(backWriteOrderMedicalNoList); Map<String, Double> residualMap = new HashMap<>();//key:商品名/value:剩余数量 Set<String> uuids = new LinkedHashSet<>();//已经回写了的明细 //1.匹配策略优先级,遍历,找到合适的条目。 for (Object currentOrderMedicalNo : currentOrderMedicalNoList) { //2.匹配后回写数量逻辑-获取值 反射获取 backWriteQuantityStrategy.getBackWritePropertyName().举例: Double currentBackWriteValue = (Double) (BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName())); Object backWriteOrderMedicalNo = getMatchOrderMedicalNoByStrategy(currentOrderMedicalNo, backWriteOrderMedicalNoList, backWriteQuantityStrategy, uuids); Object ifMatch = getMatchOrderMedicalNoByStrategy(currentOrderMedicalNo, backWriteOrderMedicalNoList, hasNotUuidStrategy, uuids); //剩余数量 Double residualQuantity = currentBackWriteValue; //剩余数量,回写数量,剩余的进入下一轮匹配回写。 int maxWhileNumber = 0;//保护措施,防止死循环导致,服务器挂掉 while (residualQuantity > 0 && backWriteOrderMedicalNo != null && maxWhileNumber < 9999) { maxWhileNumber++; Double backWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())); if ("+".equals(backWriteQuantityStrategy.getOperator())) { //3.匹配后回写数量逻辑-获取最大值 Double maxBackWriteValue = (Double) (BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName()) == null ? 0d : BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName())); //回写数量,不能超过最大值(采购)数量。举例:10|5|8 =》 10-(8-5)=7(residualQuantity) if (ArithUtils.add(residualQuantity, backWriteValue) > maxBackWriteValue) { //下一循环回写:剩余数量+回写数量-最大值 residualQuantity = ArithUtils.subtract(ArithUtils.add(residualQuantity, backWriteValue), maxBackWriteValue); BeanUtils.setProperty(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName(), backWriteValue); backWriteValue = maxBackWriteValue; // throw new RuntimeException("超过数量"); } else { backWriteValue = ArithUtils.add(residualQuantity, backWriteValue); residualQuantity = 0d; } if (backWriteValue.equals(maxBackWriteValue)) { uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, "uuid").toString()); } } if ("-".equals(backWriteQuantityStrategy.getOperator())) { // Double ownVlue=(Double)(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName())==null?0d:BeanUtils.getPropertyValue(backWriteOrderMedicalNo, backWriteQuantityStrategy.getMaxBackWritePropertyName())); if (ArithUtils.subtract(backWriteValue, residualQuantity) < 0) { //回写会扣为负?多余的留到下一轮扣减(剩余数量-回写数量) residualQuantity = ArithUtils.subtract(residualQuantity, backWriteValue); //直接将上游单据数量,设置到本明细中 BeanUtils.setProperty(currentOrderMedicalNo, backWriteQuantityStrategy.getCurrentBackWriteValuePropertyName(), backWriteValue); backWriteValue = 0d; } else { //直接减去回写数量 backWriteValue = ArithUtils.subtract(backWriteValue, residualQuantity); residualQuantity = 0d; } if (backWriteValue.equals(0d)) { uuids.add(BeanUtils.getPropertyValue(backWriteOrderMedicalNo, "uuid").toString()); } } BeanUtils.setProperty(backWriteOrderMedicalNo, backWriteQuantityStrategy.getBackWritePropertyName(), backWriteValue); if (residualQuantity > 0) { backWriteOrderMedicalNo = getMatchOrderMedicalNoByStrategy(currentOrderMedicalNo, backWriteOrderMedicalNoList, backWriteQuantityStrategy, uuids); } } if (maxWhileNumber > 9999) { throw new RuntimeException("residualQuantity maxWhileNumber:9999"); } if (null == ifMatch) { //税率。单价等属性不一致 apiOutput.setApiOutputCode(ApiOutputCode.回写失败); BeanUtils.setProperty(currentOrderMedicalNo,"attachmentsValidFlag",true); lastOrderMedicalNos.add(currentOrderMedicalNo); residualMap.put((BeanUtils.getPropertyValue(currentOrderMedicalNo, "name") == null ? "" : BeanUtils.getPropertyValue(currentOrderMedicalNo, "name")).toString(), residualQuantity); } else if (residualQuantity > 0l) { apiOutput.setApiOutputCode(ApiOutputCode.回写失败); BeanUtils.setProperty(currentOrderMedicalNo,"attachmentsValidFlag",false); lastOrderMedicalNos.add(currentOrderMedicalNo); residualMap.put((BeanUtils.getPropertyValue(currentOrderMedicalNo, "name") == null ? "" : BeanUtils.getPropertyValue(currentOrderMedicalNo, "name")).toString(), residualQuantity); } } if (!residualMap.isEmpty()) { StringBuilder stringBuilder = new StringBuilder(); String msg = null; if (CollectionUtils.isNotEmpty(residualMap.keySet())) { residualMap.keySet().forEach(name -> { stringBuilder.append(name + "、"); }); String s = stringBuilder.toString(); msg = s.substring(0, s.length() - 1); } apiOutput.setMsg(msg); apiOutput.setData(currentOrderMedicalNoList);//将传入的参数返回,方式因使用方法不当造成的问题 return apiOutput; } apiOutput.setData(currentOrderMedicalNoList); return apiOutput; } }
3.接口说明:backWrite:回写数据;canBackWrite:是否能够回写;backWriteReturn回滚回写结果