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