实现自定义的回写策略

业务场景中有很多单据,报表,上下游业务需要彼此关联修改数据,更多时候对接第三方业务,需要自己去实现业务逻辑。因此将数量的回写进行业务抽取。

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回滚回写结果

posted on 2018-05-31 15:11  张洪波IDEA  阅读(374)  评论(0编辑  收藏  举报