99 changed files with 2511 additions and 214 deletions
@ -0,0 +1,92 @@ |
|||||
|
package com.qs.serve.modules.bir.entity; |
||||
|
|
||||
|
import java.time.LocalDate; |
||||
|
import java.io.Serializable; |
||||
|
import java.math.BigDecimal; |
||||
|
import java.time.LocalDateTime; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.annotation.*; |
||||
|
import com.fasterxml.jackson.annotation.JsonFormat; |
||||
|
import com.fasterxml.jackson.annotation.JsonIgnore; |
||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
|
import lombok.Data; |
||||
|
import org.hibernate.validator.constraints.Length; |
||||
|
import org.springframework.format.annotation.DateTimeFormat; |
||||
|
|
||||
|
import javax.validation.constraints.NotNull; |
||||
|
import javax.validation.constraints.NotBlank; |
||||
|
|
||||
|
/** |
||||
|
* 实体类 |
||||
|
* @author YenHex |
||||
|
* @since 2024-06-05 |
||||
|
*/ |
||||
|
@Data |
||||
|
@TableName("bir_budget_target") |
||||
|
public class BirBudgetTarget implements Serializable { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** id */ |
||||
|
@TableId(type = IdType.AUTO) |
||||
|
private Long id; |
||||
|
|
||||
|
/** 搜索维度:0-客户;1-城市;2-省级经理;3-大区经理 */ |
||||
|
private Integer searchType; |
||||
|
|
||||
|
/** 年份 */ |
||||
|
private Integer yearNum; |
||||
|
|
||||
|
/** 季度 */ |
||||
|
private Integer quarterNum; |
||||
|
|
||||
|
/** 月份 */ |
||||
|
private Integer monthNum; |
||||
|
|
||||
|
/** 销售目标 */ |
||||
|
private BigDecimal targetAmt; |
||||
|
|
||||
|
/** 预算金额 */ |
||||
|
private BigDecimal budgetAmt; |
||||
|
|
||||
|
/** 实际发货 */ |
||||
|
private BigDecimal dispatchAmt; |
||||
|
|
||||
|
/** 去年同期发货 */ |
||||
|
private BigDecimal lastYearDispatchAmt; |
||||
|
|
||||
|
/** 城+省费用 */ |
||||
|
private BigDecimal provinceCityAmt; |
||||
|
|
||||
|
/** 城+省+区费用 */ |
||||
|
private BigDecimal provinceCityRegionAmt; |
||||
|
|
||||
|
/** 实际总费用 */ |
||||
|
private BigDecimal totalRealAmt; |
||||
|
|
||||
|
private String brandId; |
||||
|
|
||||
|
/** 品牌编码 */ |
||||
|
@Length(max = 255,message = "品牌编码长度不能超过255字") |
||||
|
private String brandCode; |
||||
|
|
||||
|
/** 品牌 */ |
||||
|
@Length(max = 255,message = "品牌长度不能超过255字") |
||||
|
private String brandName; |
||||
|
|
||||
|
/** 成本中心类型:saleRegion; bizRegion; costCenter; supplier */ |
||||
|
@Length(max = 255,message = "成本中心类型:saleRegion; bizRegion; costCenter; supplier长度不能超过255字") |
||||
|
private String centerType; |
||||
|
|
||||
|
private String centerId; |
||||
|
|
||||
|
/** 成本中心编码 */ |
||||
|
@Length(max = 255,message = "成本中心编码长度不能超过255字") |
||||
|
private String centerCode; |
||||
|
|
||||
|
/** 成本中心名 */ |
||||
|
@Length(max = 255,message = "成本中心名长度不能超过255字") |
||||
|
private String centerName; |
||||
|
|
||||
|
} |
||||
|
|
@ -0,0 +1,71 @@ |
|||||
|
package com.qs.serve.modules.bir.entity.so; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonFormat; |
||||
|
import lombok.Data; |
||||
|
import org.springframework.format.annotation.DateTimeFormat; |
||||
|
|
||||
|
import java.time.LocalDate; |
||||
|
import java.time.LocalDateTime; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2024/6/4 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class BirBudgetTargetSo { |
||||
|
|
||||
|
/** 搜索维度:0-客户;1-城市;2-省级经理;3-大区经理 */ |
||||
|
private Integer loadType; |
||||
|
|
||||
|
/** |
||||
|
* 开始时间 |
||||
|
*/ |
||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") |
||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
||||
|
private LocalDateTime yearMonthStart; |
||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") |
||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
||||
|
private LocalDateTime yearMonthEnd; |
||||
|
|
||||
|
/** |
||||
|
* 业务待定 |
||||
|
*/ |
||||
|
private String supplierId; |
||||
|
|
||||
|
/** |
||||
|
* 成本中心 |
||||
|
*/ |
||||
|
private List<CostInfo> centerList; |
||||
|
|
||||
|
/**品牌 */ |
||||
|
private List<String> brandIds; |
||||
|
|
||||
|
/** |
||||
|
* 减少xml条件 |
||||
|
*/ |
||||
|
private Integer selectCenterFlag; |
||||
|
|
||||
|
/**成本中心编码 */ |
||||
|
private List<String> centerIds; |
||||
|
|
||||
|
/**行政区域-成本中心编码 */ |
||||
|
private List<String> bizRegionIds; |
||||
|
|
||||
|
/**销售区域-成本中心编码 */ |
||||
|
private List<String> saleRegionIds; |
||||
|
|
||||
|
/**客户-成本中心编码 */ |
||||
|
private List<String> supplierIds; |
||||
|
|
||||
|
@Data |
||||
|
public static class CostInfo{ |
||||
|
/** |
||||
|
* center,saleRegion,bizRegion,supplier |
||||
|
*/ |
||||
|
private String costType; |
||||
|
|
||||
|
private String costId; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,61 @@ |
|||||
|
package com.qs.serve.modules.bir.entity.vo; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
import org.hibernate.validator.constraints.Length; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2024/6/4 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class BirBudgetTargetVo { |
||||
|
|
||||
|
/** 年份 */ |
||||
|
private Integer yearNum; |
||||
|
|
||||
|
/** 月份 */ |
||||
|
private Integer monthNum; |
||||
|
|
||||
|
/** 销售目标 */ |
||||
|
private BigDecimal targetAmt; |
||||
|
|
||||
|
/** 预算金额 */ |
||||
|
private BigDecimal budgetAmt; |
||||
|
|
||||
|
/** 实际发货 */ |
||||
|
private BigDecimal dispatchAmt; |
||||
|
|
||||
|
/** 实际总费用 */ |
||||
|
private BigDecimal totalRealAmt; |
||||
|
|
||||
|
/** 去年同期发货 */ |
||||
|
private BigDecimal lastYearDispatchAmt; |
||||
|
|
||||
|
/** 城+省费用 */ |
||||
|
private BigDecimal provinceCityAmt; |
||||
|
|
||||
|
/** 城+省+区费用 */ |
||||
|
private BigDecimal provinceCityRegionAmt; |
||||
|
|
||||
|
|
||||
|
/** 预算费用率 */ |
||||
|
private BigDecimal budgetRate; |
||||
|
|
||||
|
/** 发货达成率 */ |
||||
|
private BigDecimal dispatchRate; |
||||
|
|
||||
|
/** 同期成长率*/ |
||||
|
private BigDecimal lastYearGrowRate; |
||||
|
|
||||
|
/** 城+省费用率 */ |
||||
|
private BigDecimal provinceCityRate; |
||||
|
|
||||
|
/** 城+省+区费用率 */ |
||||
|
private BigDecimal provinceCityRegionRate; |
||||
|
|
||||
|
/** 实际总费用率 */ |
||||
|
private BigDecimal totalRealRate; |
||||
|
|
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
package com.qs.serve.modules.bir.mapper; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.annotation.InterceptorIgnore; |
||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
|
import com.qs.serve.modules.bir.entity.BirBudgetTarget; |
||||
|
import com.qs.serve.modules.bir.entity.so.BirBudgetTargetSo; |
||||
|
import org.apache.ibatis.annotations.Param; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* Mapper |
||||
|
* @author YenHex |
||||
|
* @date 2024-06-04 |
||||
|
*/ |
||||
|
public interface BirBudgetTargetMapper extends BaseMapper<BirBudgetTarget> { |
||||
|
|
||||
|
@InterceptorIgnore(tenantLine = "1") |
||||
|
List<BirBudgetTarget> selectBirBudgetTargetList(@Param("query") BirBudgetTargetSo budgetTargetSo); |
||||
|
|
||||
|
} |
||||
|
|
@ -0,0 +1,20 @@ |
|||||
|
package com.qs.serve.modules.bir.service; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.extension.service.IService; |
||||
|
import com.qs.serve.modules.bir.entity.BirBudgetTarget; |
||||
|
import com.qs.serve.modules.bir.entity.so.BirBudgetTargetSo; |
||||
|
import com.qs.serve.modules.bir.entity.vo.BirBudgetTargetVo; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 服务接口 |
||||
|
* @author YenHex |
||||
|
* @date 2024-06-04 |
||||
|
*/ |
||||
|
public interface BirBudgetTargetService extends IService<BirBudgetTarget> { |
||||
|
|
||||
|
List<BirBudgetTargetVo> listVo(BirBudgetTargetSo query); |
||||
|
|
||||
|
} |
||||
|
|
@ -0,0 +1,116 @@ |
|||||
|
package com.qs.serve.modules.bir.service.impl; |
||||
|
|
||||
|
import cn.hutool.core.collection.CollUtil; |
||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
||||
|
import com.qs.serve.modules.bir.entity.so.BirBudgetTargetSo; |
||||
|
import com.qs.serve.modules.bir.entity.vo.BirBudgetTargetVo; |
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import com.qs.serve.modules.bir.entity.BirBudgetTarget; |
||||
|
import com.qs.serve.modules.bir.service.BirBudgetTargetService; |
||||
|
import com.qs.serve.modules.bir.mapper.BirBudgetTargetMapper; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.math.RoundingMode; |
||||
|
import java.time.LocalDate; |
||||
|
import java.time.LocalDateTime; |
||||
|
import java.time.temporal.TemporalAdjuster; |
||||
|
import java.time.temporal.TemporalAdjusters; |
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
/** |
||||
|
* 服务实现类 |
||||
|
* @author YenHex |
||||
|
* @since 2024-06-04 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
@Service |
||||
|
@AllArgsConstructor |
||||
|
public class BirBudgetTargetServiceImpl extends ServiceImpl<BirBudgetTargetMapper,BirBudgetTarget> implements BirBudgetTargetService { |
||||
|
|
||||
|
@Override |
||||
|
public List<BirBudgetTargetVo> listVo(BirBudgetTargetSo query) { |
||||
|
query.setLoadType(query.getLoadType()+1); |
||||
|
LocalDateTime endMonth = query.getYearMonthEnd(); |
||||
|
LocalDateTime startMonth = query.getYearMonthStart(); |
||||
|
//格式化
|
||||
|
startMonth = startMonth.withDayOfMonth(1).toLocalDate().atTime(0,0,0); |
||||
|
endMonth = endMonth.with(TemporalAdjusters.lastDayOfMonth()).toLocalDate().atTime(23,59,59); |
||||
|
query.setYearMonthStart(startMonth); |
||||
|
query.setYearMonthEnd(endMonth); |
||||
|
query.setSelectCenterFlag(0); |
||||
|
if(CollUtil.isNotEmpty(query.getCenterList())){ |
||||
|
query.setSelectCenterFlag(1); |
||||
|
} |
||||
|
|
||||
|
List<BirBudgetTarget> birBudgetTargets = baseMapper.selectBirBudgetTargetList(query); |
||||
|
|
||||
|
Map<String,List<BirBudgetTarget>> listMap = birBudgetTargets.stream() |
||||
|
.collect(Collectors.groupingBy(obj->obj.getYearNum()+"_"+obj.getMonthNum())); |
||||
|
|
||||
|
List<BirBudgetTargetVo> budgetTargetVoList = new ArrayList<>(); |
||||
|
|
||||
|
|
||||
|
//12个月
|
||||
|
final int TOTAL_MONTH = 12; |
||||
|
for (int y = startMonth.getYear(); y <= endMonth.getYear(); y++) { |
||||
|
for (int m = 1; m <= TOTAL_MONTH; m++) { |
||||
|
//防止多空白行
|
||||
|
if(y == startMonth.getYear() && m < startMonth.getMonthValue()){ |
||||
|
continue; |
||||
|
} |
||||
|
if(y == endMonth.getYear() && m > endMonth.getMonthValue()){ |
||||
|
continue; |
||||
|
} |
||||
|
budgetTargetVoList.add(getBudgetTargetVo(listMap, m, y)); |
||||
|
} |
||||
|
} |
||||
|
return budgetTargetVoList; |
||||
|
} |
||||
|
|
||||
|
private BirBudgetTargetVo getBudgetTargetVo(Map<String, List<BirBudgetTarget>> listMap, int month, int year) { |
||||
|
List<BirBudgetTarget> mList = listMap.get(year +"_"+ month); |
||||
|
BirBudgetTargetVo targetVo = new BirBudgetTargetVo(); |
||||
|
targetVo.setYearNum(year); |
||||
|
targetVo.setMonthNum(month); |
||||
|
targetVo.setTargetAmt(BigDecimal.ZERO); |
||||
|
targetVo.setBudgetAmt(BigDecimal.ZERO); |
||||
|
targetVo.setDispatchAmt(BigDecimal.ZERO); |
||||
|
targetVo.setTotalRealAmt(BigDecimal.ZERO); |
||||
|
targetVo.setLastYearDispatchAmt(BigDecimal.ZERO); |
||||
|
targetVo.setProvinceCityAmt(BigDecimal.ZERO); |
||||
|
targetVo.setProvinceCityRegionAmt(BigDecimal.ZERO); |
||||
|
if(CollUtil.isNotEmpty(mList)){ |
||||
|
for (BirBudgetTarget target : mList) { |
||||
|
targetVo.setTargetAmt(targetVo.getTargetAmt().add(target.getTargetAmt())); |
||||
|
targetVo.setBudgetAmt(targetVo.getBudgetAmt().add(target.getBudgetAmt())); |
||||
|
targetVo.setDispatchAmt(targetVo.getDispatchAmt().add(target.getDispatchAmt())); |
||||
|
targetVo.setTotalRealAmt(targetVo.getTotalRealAmt().add(target.getTotalRealAmt())); |
||||
|
targetVo.setLastYearDispatchAmt(targetVo.getLastYearDispatchAmt().add(target.getLastYearDispatchAmt())); |
||||
|
targetVo.setProvinceCityAmt(targetVo.getProvinceCityAmt().add(target.getProvinceCityAmt())); |
||||
|
targetVo.setProvinceCityRegionAmt(targetVo.getProvinceCityRegionAmt().add(target.getProvinceCityRegionAmt())); |
||||
|
} |
||||
|
//预算费率 = 预算费用/销售目标
|
||||
|
targetVo.setBudgetRate(targetVo.getBudgetAmt().divide(targetVo.getTargetAmt(),2, RoundingMode.DOWN)); |
||||
|
//发货达成率 = 实际发货/销售目标
|
||||
|
targetVo.setDispatchRate(targetVo.getDispatchAmt().divide(targetVo.getTargetAmt(),2, RoundingMode.DOWN)); |
||||
|
//(当前发货-去年同期发货)/去年同期发货
|
||||
|
targetVo.setLastYearGrowRate( |
||||
|
targetVo.getDispatchAmt() |
||||
|
.subtract(targetVo.getLastYearDispatchAmt()) |
||||
|
.divide(targetVo.getLastYearDispatchAmt(),2, RoundingMode.DOWN) |
||||
|
); |
||||
|
//实际费用率=实际费用/实际发货
|
||||
|
targetVo.setProvinceCityRate(targetVo.getProvinceCityAmt().divide(targetVo.getDispatchAmt(),2, RoundingMode.DOWN)); |
||||
|
targetVo.setProvinceCityRegionRate(targetVo.getProvinceCityRate().divide(targetVo.getDispatchAmt(),2, RoundingMode.DOWN)); |
||||
|
targetVo.setTotalRealRate(targetVo.getTotalRealAmt().divide(targetVo.getDispatchAmt(),2, RoundingMode.DOWN)); |
||||
|
} |
||||
|
return targetVo; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
@ -0,0 +1,22 @@ |
|||||
|
package com.qs.serve.modules.tbs.entity.dto; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2024/6/3 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class TbsBudgetCheckingWithAmount { |
||||
|
|
||||
|
private String type; |
||||
|
private String tarId; |
||||
|
private String tarCode; |
||||
|
private String tarTitle; |
||||
|
private String totalAmount; |
||||
|
private String supplierCode; |
||||
|
private String supplierName; |
||||
|
private String userCode; |
||||
|
private String userName; |
||||
|
|
||||
|
} |
@ -0,0 +1,494 @@ |
|||||
|
package com.qs.serve.modules.tbs.service; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||
|
import com.qs.serve.common.util.CollectionUtil; |
||||
|
import com.qs.serve.common.util.CopierUtil; |
||||
|
import com.qs.serve.common.util.StringUtils; |
||||
|
import com.qs.serve.modules.tbs.entity.*; |
||||
|
import com.qs.serve.modules.tbs.mapper.*; |
||||
|
import com.qs.serve.modules.vtb.entity.VtbVerification; |
||||
|
import com.qs.serve.modules.vtb.entity.VtbVerificationSubject; |
||||
|
import com.qs.serve.modules.vtb.mapper.VtbVerificationMapper; |
||||
|
import com.qs.serve.modules.vtb.mapper.VtbVerificationSubjectMapper; |
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.jetbrains.annotations.NotNull; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.math.RoundingMode; |
||||
|
import java.util.ArrayList; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2024/5/25 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
@Service |
||||
|
@AllArgsConstructor |
||||
|
public class TbsActivityDebugApplicationService { |
||||
|
|
||||
|
private TbsActivityMapper activityMapper; |
||||
|
private TbsActivitySubjectService activitySubjectService; |
||||
|
private TbsActivitySubjectMapper activitySubjectMapper; |
||||
|
private TbsActivityCenterService activityCenterService; |
||||
|
private TbsActivityCenterGoodsService activityCenterGoodsService; |
||||
|
private TbsBudgetLogService budgetLogService; |
||||
|
private VtbVerificationMapper verificationMapper; |
||||
|
private TbsCostApplyMapper tbsCostApplyMapper; |
||||
|
|
||||
|
public String reset(Long activityId){ |
||||
|
|
||||
|
BigDecimal n100 = new BigDecimal("100"); |
||||
|
|
||||
|
QueryWrapper wrapper = new QueryWrapper(); |
||||
|
wrapper.eq("activity_id",activityId); |
||||
|
|
||||
|
TbsActivity activity = activityMapper.selectById(activityId); |
||||
|
|
||||
|
//TbsCostApply costApply = tbsCostApplyMapper.selectById(activity.getCostApplyId());
|
||||
|
// if(costApply.getPolicyItemId()!=null){
|
||||
|
// log.warn("随货折让不支持该方法");
|
||||
|
// return "随货折让不支持该方法";
|
||||
|
// }
|
||||
|
// //过滤 CA SHX YX06 PortalOfCostApplication.createCostProcess()
|
||||
|
// if(StringUtils.hasText(costApply.getBillNumber())||StringUtils.hasText(costApply.getDisCode())){
|
||||
|
// log.warn("方法仅支持普通订单");
|
||||
|
// return "方法仅支持普通订单";
|
||||
|
// }
|
||||
|
|
||||
|
BigDecimal checkeAmt = activity.getUsedAmount(); |
||||
|
if(activity.getReleaseFlag().equals(1)){ |
||||
|
checkeAmt = checkeAmt.add(activity.getReleaseAmount()); |
||||
|
} |
||||
|
if(checkeAmt.compareTo(activity.getTotalAmount())>0){ |
||||
|
log.warn("活动自身金额异常"); |
||||
|
return "活动自身金额异常"; |
||||
|
} |
||||
|
|
||||
|
Long unMatchNum = activitySubjectMapper.checkActAndSubjectAmt(activityId); |
||||
|
if(unMatchNum!=null&&unMatchNum>0){ |
||||
|
log.warn("活动科目金额异常"); |
||||
|
return "活动科目金额异常"; |
||||
|
} |
||||
|
|
||||
|
//校验核销金额,错误则不执行
|
||||
|
BigDecimal totalVerificationAmt = verificationMapper.getActivityVerificationAmt(activityId); |
||||
|
if(totalVerificationAmt==null){ |
||||
|
totalVerificationAmt = BigDecimal.ZERO; |
||||
|
} |
||||
|
if(activity.getUsedAmount().compareTo(BigDecimal.ZERO)!=0 |
||||
|
&&activity.getUsedAmount().compareTo(totalVerificationAmt)!=0){ |
||||
|
return "核销金额异常"; |
||||
|
} |
||||
|
|
||||
|
// subject是和activity的 申请金额和核销金额一致,不进行更新
|
||||
|
List<TbsActivitySubject> activitySubjectList = activitySubjectService.list(wrapper); |
||||
|
List<TbsActivityCenter> activityCenterList = activityCenterService.list(wrapper); |
||||
|
List<TbsActivityCenterGoods> activityCenterGoodsList = activityCenterGoodsService.list(wrapper); |
||||
|
|
||||
|
Map<Long,List<TbsActivityCenterGoods>> activityCenterGoodsListMap = activityCenterGoodsList.stream() |
||||
|
.collect(Collectors.groupingBy(TbsActivityCenterGoods::getSubjectId)); |
||||
|
|
||||
|
Map<Long,List<TbsActivityCenter>> activityCenterListMap = activityCenterList.stream() |
||||
|
.collect(Collectors.groupingBy(TbsActivityCenter::getSubjectId)); |
||||
|
|
||||
|
boolean updateSubject = false; |
||||
|
for (TbsActivitySubject activitySubject : activitySubjectList) { |
||||
|
Long subjectId = activitySubject.getSubjectId(); |
||||
|
List<TbsActivityCenter> subjectCenterList = activityCenterListMap.get(subjectId); |
||||
|
BigDecimal totalCenterRate = BigDecimal.ZERO; |
||||
|
BigDecimal totalCenterAmt = BigDecimal.ZERO; |
||||
|
BigDecimal totalCenterUsedAmt = BigDecimal.ZERO; |
||||
|
|
||||
|
BigDecimal subjectUsedAmt = activitySubject.getUsedAmount(); |
||||
|
BigDecimal subjectAmt = activitySubject.getAmount(); |
||||
|
for (TbsActivityCenter activityCenter : subjectCenterList) { |
||||
|
if(activityCenter.getCenterRate().compareTo(BigDecimal.ZERO)>=0){ |
||||
|
totalCenterRate = totalCenterRate.add(activityCenter.getCenterRate()); |
||||
|
} |
||||
|
if(activityCenter.getCenterAmount().compareTo(BigDecimal.ZERO)>=0){ |
||||
|
totalCenterAmt = totalCenterAmt.add(activityCenter.getCenterAmount()); |
||||
|
} |
||||
|
totalCenterUsedAmt = totalCenterUsedAmt.add(activityCenter.getUsedAmount()); |
||||
|
} |
||||
|
if(n100.compareTo(totalCenterRate)!=0){ |
||||
|
log.info("重新分配TbsActivityCenter的比例"); |
||||
|
BigDecimal centerRate = n100; |
||||
|
for (int i = 0; i < subjectCenterList.size(); i++) { |
||||
|
TbsActivityCenter activityCenter = subjectCenterList.get(i); |
||||
|
if(i+1 == subjectCenterList.size()){ |
||||
|
activityCenter.setCenterRate(centerRate); |
||||
|
}else { |
||||
|
if(activityCenter.getCenterRate().compareTo(BigDecimal.ZERO)<0){ |
||||
|
activityCenter.setCenterRate(BigDecimal.ZERO); |
||||
|
} |
||||
|
centerRate = centerRate.subtract(activityCenter.getCenterRate()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 更新subject的已用金额
|
||||
|
if(subjectUsedAmt==null || totalCenterUsedAmt.compareTo(subjectUsedAmt)!=0){ |
||||
|
log.info("成本中心和科目已用金额不匹配"); |
||||
|
BigDecimal totalUsedOnCenter = BigDecimal.ZERO; |
||||
|
for (TbsActivityCenter center : activityCenterList) { |
||||
|
totalUsedOnCenter = totalUsedOnCenter.add(center.getUsedAmount()); |
||||
|
} |
||||
|
if(0 == totalUsedOnCenter.compareTo(activity.getUsedAmount())){ |
||||
|
log.info("通过center更新subject金额"); |
||||
|
subjectUsedAmt = BigDecimal.ZERO; |
||||
|
for (TbsActivityCenter center : subjectCenterList) { |
||||
|
subjectUsedAmt = subjectUsedAmt.add(center.getUsedAmount()); |
||||
|
} |
||||
|
activitySubject.setUsedAmount(subjectUsedAmt); |
||||
|
updateSubject = true; |
||||
|
}else if (activitySubjectList.size()==1){ |
||||
|
subjectUsedAmt = activity.getUsedAmount(); |
||||
|
activitySubject.setUsedAmount(subjectUsedAmt); |
||||
|
log.info("更新TbsActivityCenter的已用金额"); |
||||
|
BigDecimal totalCenterSubjectRate = BigDecimal.ZERO; |
||||
|
for (TbsActivityCenter center : subjectCenterList) { |
||||
|
totalCenterSubjectRate = totalCenterSubjectRate.add(center.getCenterRate()); |
||||
|
} |
||||
|
if(totalCenterSubjectRate.compareTo(n100)!=0){ |
||||
|
log.info("更新TbsActivityCenter的比率"); |
||||
|
BigDecimal avgRate = n100.divide(new BigDecimal(subjectCenterList.size()),2,RoundingMode.DOWN); |
||||
|
BigDecimal addRate = BigDecimal.ZERO; |
||||
|
for (int i = 0; i < subjectCenterList.size(); i++) { |
||||
|
TbsActivityCenter center = subjectCenterList.get(i); |
||||
|
if(i+1 == subjectCenterList.size()){ |
||||
|
center.setCenterRate(n100.subtract(addRate)); |
||||
|
}else { |
||||
|
center.setCenterRate(avgRate); |
||||
|
addRate = avgRate.add(avgRate); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
BigDecimal totalUsed11 = BigDecimal.ZERO; |
||||
|
for (int i = 0; i < subjectCenterList.size(); i++) { |
||||
|
log.info("更新TbsActivityCenter的已用"); |
||||
|
TbsActivityCenter center = subjectCenterList.get(i); |
||||
|
if(i+1 == subjectCenterList.size()){ |
||||
|
center.setUsedAmount(subjectUsedAmt.subtract(totalUsed11)); |
||||
|
}else { |
||||
|
BigDecimal curAmt = subjectUsedAmt.multiply(center.getCenterRate()).divide(n100,2,RoundingMode.DOWN); |
||||
|
center.setUsedAmount(curAmt); |
||||
|
totalUsed11 = totalUsed11.add(curAmt); |
||||
|
} |
||||
|
} |
||||
|
}else { |
||||
|
log.info("成本中心和科目已用金额不匹配,而且活动金额也不匹配"); |
||||
|
return "成本中心和科目已用金额不匹配,而且活动金额也不匹配"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 分配center的占用金额和已用金额
|
||||
|
if(totalCenterAmt.compareTo(activitySubject.getAmount())!=0){ |
||||
|
log.info("重新分配TbsActivityCenter的CenterAmount"); |
||||
|
BigDecimal centerAmt = subjectAmt; |
||||
|
BigDecimal centerUsedAmt = subjectUsedAmt; |
||||
|
for (int i = 0; i < subjectCenterList.size(); i++) { |
||||
|
TbsActivityCenter activityCenter = subjectCenterList.get(i); |
||||
|
if(i+1 == subjectCenterList.size()){ |
||||
|
activityCenter.setCenterAmount(centerAmt); |
||||
|
}else { |
||||
|
BigDecimal currAmt = subjectAmt |
||||
|
.multiply(activityCenter.getCenterRate()) |
||||
|
.divide(n100, 2,RoundingMode.DOWN); |
||||
|
centerAmt = centerAmt.subtract(currAmt); |
||||
|
activityCenter.setCenterAmount(currAmt); |
||||
|
} |
||||
|
//设置已用金额
|
||||
|
if(subjectAmt.compareTo(subjectUsedAmt)==0){ |
||||
|
activityCenter.setUsedAmount(activityCenter.getCenterAmount()); |
||||
|
}else { |
||||
|
if(i+1 == subjectCenterList.size()){ |
||||
|
activityCenter.setUsedAmount(centerUsedAmt); |
||||
|
}else { |
||||
|
BigDecimal currAmt = subjectUsedAmt |
||||
|
.multiply(activityCenter.getCenterRate()) |
||||
|
.divide(n100, 2,RoundingMode.DOWN); |
||||
|
centerUsedAmt = centerUsedAmt.subtract(currAmt); |
||||
|
activityCenter.setUsedAmount(centerAmt); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
List<TbsActivityCenterGoods> activityCenterGoodsListOfSubject = activityCenterGoodsListMap.get(subjectId); |
||||
|
|
||||
|
for (TbsActivityCenter center : subjectCenterList) { |
||||
|
List<TbsActivityCenterGoods> goodsList = activityCenterGoodsListOfSubject.stream() |
||||
|
.filter(a->a.getCenterId().equals(center.getCenterId())&&a.getCenterType().equals(center.getCenterType())) |
||||
|
.collect(Collectors.toList()); |
||||
|
if(goodsList.size()==0){ |
||||
|
if(subjectCenterList.size()==1 && activityCenterGoodsListOfSubject.size()==1){ |
||||
|
TbsActivityCenterGoods centerGoods = activityCenterGoodsListOfSubject.get(0); |
||||
|
centerGoods.setCenterType(center.getCenterType()); |
||||
|
centerGoods.setCenterId(center.getCenterId()); |
||||
|
centerGoods.setCenterName(center.getCenterName()); |
||||
|
goodsList = new ArrayList<>(); |
||||
|
goodsList.add(centerGoods); |
||||
|
}else { |
||||
|
log.error("商品数据缺失"); |
||||
|
return "商品数据缺失"; |
||||
|
} |
||||
|
} |
||||
|
final BigDecimal centerUsed = center.getUsedAmount(); |
||||
|
final BigDecimal centerAmt = center.getCenterAmount(); |
||||
|
|
||||
|
BigDecimal totalGoodRate = BigDecimal.ZERO; |
||||
|
for (TbsActivityCenterGoods goods : goodsList) { |
||||
|
BigDecimal rate = goods.getCenterGoodsRate(); |
||||
|
if(rate.compareTo(BigDecimal.ZERO)>0){ |
||||
|
totalGoodRate = totalGoodRate.add(rate); |
||||
|
} |
||||
|
} |
||||
|
//重新分配比率
|
||||
|
if(totalGoodRate.compareTo(n100)!=0){ |
||||
|
log.info("重新分配申请Rate"); |
||||
|
BigDecimal avgRate = n100.divide(new BigDecimal(goodsList.size()),2,RoundingMode.DOWN); |
||||
|
BigDecimal addRate = BigDecimal.ZERO; |
||||
|
for (int i = 0; i < goodsList.size(); i++) { |
||||
|
TbsActivityCenterGoods goods = goodsList.get(i); |
||||
|
if(i+1 == goodsList.size()){ |
||||
|
goods.setCenterGoodsRate(n100.subtract(addRate)); |
||||
|
}else { |
||||
|
goods.setCenterGoodsRate(avgRate); |
||||
|
addRate = addRate.add(avgRate); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//分配申请金额
|
||||
|
BigDecimal centerAmt3 = centerAmt; |
||||
|
log.info("重新分配申请金额"); |
||||
|
for (int i = 0; i < goodsList.size(); i++) { |
||||
|
TbsActivityCenterGoods goods = goodsList.get(i); |
||||
|
if(i+1 == goodsList.size()){ |
||||
|
goods.setCenterGoodsAmount(centerAmt3); |
||||
|
}else { |
||||
|
BigDecimal currentAmt = centerAmt |
||||
|
.multiply(goods.getCenterGoodsRate()) |
||||
|
.divide(n100,2,RoundingMode.DOWN); |
||||
|
goods.setCenterGoodsAmount(currentAmt); |
||||
|
centerAmt3 = centerAmt3.subtract(currentAmt); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//分配TbsActivityCenterGoods已用金额
|
||||
|
BigDecimal centerUsed2 = centerUsed; |
||||
|
log.info("重新分配已用金额"); |
||||
|
for (int i = 0; i < goodsList.size(); i++) { |
||||
|
TbsActivityCenterGoods goods = goodsList.get(i); |
||||
|
if(i+1 == goodsList.size()){ |
||||
|
goods.setUsedAmount(centerUsed2); |
||||
|
}else { |
||||
|
BigDecimal currentAmt = centerUsed |
||||
|
.multiply(goods.getCenterGoodsRate()) |
||||
|
.divide(n100,2,RoundingMode.DOWN); |
||||
|
goods.setUsedAmount(currentAmt); |
||||
|
centerUsed2 = centerUsed2.subtract(currentAmt); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//二次校验
|
||||
|
BigDecimal totalSubjectAmt = BigDecimal.ZERO; |
||||
|
BigDecimal totalSubjectUsedAmt = BigDecimal.ZERO; |
||||
|
BigDecimal totalAllCenterUsedAmt = BigDecimal.ZERO; |
||||
|
for (TbsActivitySubject activitySubject : activitySubjectList) { |
||||
|
Long subjectId = activitySubject.getSubjectId(); |
||||
|
List<TbsActivityCenter> subjectCenterList = activityCenterListMap.get(subjectId); |
||||
|
BigDecimal totalCenterRate = BigDecimal.ZERO; |
||||
|
BigDecimal totalCenterAmt = BigDecimal.ZERO; |
||||
|
BigDecimal totalCenterUsedAmt = BigDecimal.ZERO; |
||||
|
|
||||
|
BigDecimal subjectUsedAmt = activitySubject.getUsedAmount(); |
||||
|
BigDecimal subjectAmt = activitySubject.getAmount(); |
||||
|
totalSubjectAmt = totalSubjectAmt.add(subjectAmt); |
||||
|
totalSubjectUsedAmt = totalSubjectUsedAmt.add(activitySubject.getUsedAmount()); |
||||
|
|
||||
|
for (TbsActivityCenter activityCenter : subjectCenterList) { |
||||
|
totalCenterRate = totalCenterRate.add(activityCenter.getCenterRate()); |
||||
|
totalCenterAmt = totalCenterAmt.add(activityCenter.getCenterAmount()); |
||||
|
totalCenterUsedAmt = totalCenterUsedAmt.add(activityCenter.getUsedAmount()); |
||||
|
} |
||||
|
totalAllCenterUsedAmt = totalAllCenterUsedAmt.add(totalCenterUsedAmt); |
||||
|
if(totalCenterAmt.compareTo(subjectAmt)!=0){ |
||||
|
log.error("合计totalCenterAmt金额异常:{}",activityId); |
||||
|
return "合计totalCenterAmt金额异常"; |
||||
|
} |
||||
|
if(totalCenterUsedAmt.compareTo(subjectUsedAmt)!=0){ |
||||
|
log.error("合计totalCenterUsedAmt金额异常,将重新分配活动的成本中心金额:{}",activityId); |
||||
|
return "合计totalCenterUsedAmt金额异常"; |
||||
|
} |
||||
|
if(n100.compareTo(totalCenterRate)!=0){ |
||||
|
log.error("centerRate不为100:{}",activityId); |
||||
|
return "centerRate不为100"; |
||||
|
} |
||||
|
List<TbsActivityCenterGoods> activityCenterGoodsListOfSubject = activityCenterGoodsListMap.get(subjectId); |
||||
|
|
||||
|
for (TbsActivityCenter center : subjectCenterList) { |
||||
|
List<TbsActivityCenterGoods> goodsList = activityCenterGoodsListOfSubject.stream() |
||||
|
.filter(a->a.getCenterId().equals(center.getCenterId())&&a.getCenterType().equals(center.getCenterType())) |
||||
|
.collect(Collectors.toList()); |
||||
|
final BigDecimal centerUsed = center.getUsedAmount(); |
||||
|
final BigDecimal centerAmt = center.getCenterAmount(); |
||||
|
|
||||
|
BigDecimal totalGoodRate = BigDecimal.ZERO; |
||||
|
BigDecimal totalGoodUsed = BigDecimal.ZERO; |
||||
|
BigDecimal totalGoodAmt = BigDecimal.ZERO; |
||||
|
for (TbsActivityCenterGoods goods : goodsList) { |
||||
|
BigDecimal rate = goods.getCenterGoodsRate(); |
||||
|
totalGoodRate = totalGoodRate.add(rate); |
||||
|
totalGoodAmt = totalGoodAmt.add(goods.getCenterGoodsAmount()); |
||||
|
totalGoodUsed = totalGoodUsed.add(goods.getUsedAmount()); |
||||
|
} |
||||
|
//重新分配比率
|
||||
|
if(totalGoodRate.compareTo(n100)!=0){ |
||||
|
log.error("totalGoodRate不为100:{}",activityId); |
||||
|
return "totalGoodRate不为100"; |
||||
|
} |
||||
|
|
||||
|
if(totalGoodAmt.compareTo(centerAmt)!=0){ |
||||
|
log.error("totalGoodAmt:{}",activityId); |
||||
|
return "totalGoodAmt错误"; |
||||
|
} |
||||
|
if(totalGoodUsed.compareTo(centerUsed)!=0){ |
||||
|
log.error("totalGoodUsed:{}",activityId); |
||||
|
return "totalGoodUsed错误"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
if(activity.getUsedAmount().compareTo(totalSubjectUsedAmt)!=0){ |
||||
|
log.error("活动和totalSubjectUsedAmt匹对金额异常:{}",activityId); |
||||
|
return "活动和totalSubjectUsedAmt匹对金额异常"; |
||||
|
} |
||||
|
if(totalSubjectUsedAmt.compareTo(totalAllCenterUsedAmt)!=0){ |
||||
|
log.error("活动和totalAllCenterUsedAmt匹对金额异常:{}",activityId); |
||||
|
return "活动和totalAllCenterUsedAmt匹对金额异常"; |
||||
|
} |
||||
|
if(activity.getTotalAmount().compareTo(totalSubjectAmt)!=0){ |
||||
|
log.error("科目和活动的申请金额不匹配"); |
||||
|
return "科目和活动的申请金额不匹配"; |
||||
|
} |
||||
|
// 处理预算占用
|
||||
|
List<TbsBudgetLog> actBudgetLogs = budgetLogService.list(wrapper); |
||||
|
|
||||
|
List<TbsBudgetLog> applyLogs = actBudgetLogs.stream().filter(a-> a.getOptType()!=4).collect(Collectors.toList()); |
||||
|
|
||||
|
List<TbsBudgetLog> releaseLogs = actBudgetLogs.stream().filter(a-> a.getOptType()==4).collect(Collectors.toList()); |
||||
|
|
||||
|
BigDecimal applyAmt = totalBudgetLogAmount(applyLogs); |
||||
|
|
||||
|
BigDecimal releaseAmt = totalBudgetLogAmount(releaseLogs); |
||||
|
|
||||
|
//检查下占用预算和释放
|
||||
|
if(applyAmt.negate().compareTo(activity.getTotalAmount())!=0){ |
||||
|
log.info("历史预算占用金额异常"); |
||||
|
} |
||||
|
|
||||
|
if(activity.getReleaseAmount()!=null && releaseAmt.compareTo(activity.getReleaseAmount())!=0){ |
||||
|
log.info("历史预算释放金额异常"); |
||||
|
} |
||||
|
|
||||
|
List<TbsBudgetLog> newApplyLogList = new ArrayList<>(); |
||||
|
List<TbsBudgetLog> newReleaseLogList = new ArrayList<>(); |
||||
|
|
||||
|
for (TbsActivityCenterGoods goods : activityCenterGoodsList) { |
||||
|
|
||||
|
List<TbsBudgetLog> goodApplyLogs = actBudgetLogs.stream().filter(a-> |
||||
|
a.getSubjectId().equals(goods.getSubjectId()) |
||||
|
&&a.getCenterType().equals(goods.getCenterType()) |
||||
|
&&a.getCenterId().equals(goods.getCenterId()) |
||||
|
&&a.getOptType()!=4 |
||||
|
).collect(Collectors.toList()); |
||||
|
|
||||
|
List<TbsBudgetLog> goodReleaseLogs = actBudgetLogs.stream().filter(a-> |
||||
|
a.getSubjectId().equals(goods.getSubjectId()) |
||||
|
&&a.getCenterType().equals(goods.getCenterType()) |
||||
|
&&a.getCenterId().equals(goods.getCenterId()) |
||||
|
&&a.getOptType()==4 |
||||
|
).collect(Collectors.toList()); |
||||
|
|
||||
|
if(goodApplyLogs.size()==0 && goodReleaseLogs.size() ==0 |
||||
|
&&goods.getCenterGoodsAmount().equals(goods.getUsedAmount())){ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if(goodApplyLogs.size()==0){ |
||||
|
return "缺失费用申请log"; |
||||
|
} |
||||
|
|
||||
|
// 新log
|
||||
|
TbsBudgetLog newApplyLog = CopierUtil.copy(goodApplyLogs.get(0),new TbsBudgetLog()); |
||||
|
newApplyLog.setId(null); |
||||
|
newApplyLog.setAmount(goods.getCenterGoodsAmount().negate()); |
||||
|
newApplyLog.setOptType(1); |
||||
|
newApplyLogList.add(newApplyLog); |
||||
|
|
||||
|
if(goodReleaseLogs.size()>0){ |
||||
|
TbsBudgetLog newReleaseLog = CopierUtil.copy(goodReleaseLogs.get(0),new TbsBudgetLog()); |
||||
|
newReleaseLog.setId(null); |
||||
|
newReleaseLog.setAmount(goods.getCenterGoodsAmount().subtract(goods.getUsedAmount())); |
||||
|
newReleaseLog.setOptType(4); |
||||
|
newReleaseLogList.add(newReleaseLog); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
BigDecimal newApplyAmt = totalBudgetLogAmount(newApplyLogList); |
||||
|
BigDecimal newReleaseAmt = totalBudgetLogAmount(newReleaseLogList); |
||||
|
|
||||
|
if(newApplyAmt.negate().compareTo(activity.getTotalAmount())!=0){ |
||||
|
log.error("预算占用金额异常"); |
||||
|
return "预算占用金额异常"; |
||||
|
} |
||||
|
|
||||
|
if(activity.getReleaseAmount()!=null && newReleaseAmt.compareTo(activity.getReleaseAmount())!=0){ |
||||
|
log.error("预算释放金额异常 activity{},.getReleaseAmount():{} newReleaseAmt:{}",activityId,activity.getReleaseAmount(),newReleaseAmt); |
||||
|
return "预算释放金额异常"; |
||||
|
} |
||||
|
|
||||
|
if(updateSubject){ |
||||
|
activitySubjectService.updateBatchById(activitySubjectList); |
||||
|
} |
||||
|
activityCenterService.updateBatchById(activityCenterList); |
||||
|
activityCenterGoodsService.updateBatchById(activityCenterGoodsList); |
||||
|
List<Long> logIds = actBudgetLogs.stream().map(a->a.getId()).collect(Collectors.toList()); |
||||
|
if(!newApplyLogList.isEmpty()){ |
||||
|
budgetLogService.saveBatch(newApplyLogList); |
||||
|
} |
||||
|
if(CollectionUtil.isNotEmpty(newReleaseLogList)){ |
||||
|
budgetLogService.saveBatch(newReleaseLogList); |
||||
|
} |
||||
|
if(CollectionUtil.isNotEmpty(logIds)){ |
||||
|
budgetLogService.removeBatchByIds(logIds); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private BigDecimal totalBudgetLogAmount(List<TbsBudgetLog> releaseLogs) { |
||||
|
BigDecimal amt = BigDecimal.ZERO; |
||||
|
if(releaseLogs!=null){ |
||||
|
for (TbsBudgetLog reLog : releaseLogs) { |
||||
|
amt = amt.add(reLog.getAmount()); |
||||
|
} |
||||
|
} |
||||
|
return amt; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,206 @@ |
|||||
|
package com.qs.serve.modules.tbs.service; |
||||
|
|
||||
|
import cn.hutool.core.collection.CollUtil; |
||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
|
import com.qs.serve.common.model.enums.BudgetLogOptFlag; |
||||
|
import com.qs.serve.common.util.CollectionUtil; |
||||
|
import com.qs.serve.modules.sys.entity.SysUser; |
||||
|
import com.qs.serve.modules.tbs.common.util.TbsBudgetLogBuildUtil; |
||||
|
import com.qs.serve.modules.tbs.entity.*; |
||||
|
import com.qs.serve.modules.vtb.common.VtbFundFlowType; |
||||
|
import com.qs.serve.modules.vtb.entity.VtbFundFlow; |
||||
|
import com.qs.serve.modules.vtb.mapper.VtbFundFlowMapper; |
||||
|
import com.qs.serve.modules.vtb.service.VtbFundFlowService; |
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2024/5/28 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
@Service |
||||
|
@AllArgsConstructor |
||||
|
public class TbsBudgetReleaseApplicationService { |
||||
|
|
||||
|
private final VtbFundFlowService fundFlowService; |
||||
|
private final VtbFundFlowMapper vtbFundFlowMapper; |
||||
|
private final TbsBudgetService budgetService; |
||||
|
private final TbsBudgetLogService budgetLogService; |
||||
|
private final TbsBudgetCostItemService budgetCostItemService; |
||||
|
private final TbsActivityService activityService; |
||||
|
private final TbsActivityCenterGoodsService activityCenterGoodsService; |
||||
|
private final TbsCostApplyService costApplyService; |
||||
|
private final TbsActivityPayConditionService activityPayConditionService; |
||||
|
private final TbsScheduleItemBudgetService tbsScheduleItemBudgetService; |
||||
|
|
||||
|
public void initHis(Long activityId){ |
||||
|
TbsBudget budget = budgetService.getById("1669"); |
||||
|
TbsScheduleItemBudget scheduleItemBudget = tbsScheduleItemBudgetService.getById("4896"); |
||||
|
TbsActivity activity = activityService.getById(activityId); |
||||
|
TbsCostApply costApply = costApplyService.getById(activity.getCostApplyId()); |
||||
|
SysUser sysUser = new SysUser(); |
||||
|
sysUser.setId("0"); |
||||
|
sysUser.setName("系统执行"); |
||||
|
sysUser.setCode("0"); |
||||
|
|
||||
|
List<TbsBudgetLog> budgetLogList = new ArrayList<>(); |
||||
|
List<TbsActivityCenterGoods> centerGoodsList = activityCenterGoodsService.listByActivityId(activityId); |
||||
|
for (TbsActivityCenterGoods centerGoods : centerGoodsList) { |
||||
|
BigDecimal amount = centerGoods.getCenterGoodsAmount(); |
||||
|
|
||||
|
TbsBudgetCostItem costItem = new TbsBudgetCostItem(); |
||||
|
costItem.setCenterGoodsCode(centerGoods.getCenterGoodsCode()); |
||||
|
costItem.setCostApplyId(centerGoods.getCostApplyId()); |
||||
|
costItem.setActivityId(centerGoods.getActivityId()); |
||||
|
costItem.setActivityCode(centerGoods.getActivityCode()); |
||||
|
costItem.setSupplierId(centerGoods.getSupplierId()); |
||||
|
costItem.setSupplierCode(centerGoods.getSupplierCode()); |
||||
|
costItem.setSupplierName(centerGoods.getSupplierName()); |
||||
|
costItem.setSubjectId(centerGoods.getSubjectId()); |
||||
|
costItem.setSubjectCode(centerGoods.getSubjectCode()); |
||||
|
costItem.setSubjectName(centerGoods.getSubjectName()); |
||||
|
costItem.setCenterType(centerGoods.getCenterType()); |
||||
|
costItem.setCenterId(centerGoods.getCenterId()); |
||||
|
costItem.setCenterCode(centerGoods.getCenterCode()); |
||||
|
costItem.setCenterName(centerGoods.getCenterName()); |
||||
|
costItem.setCenterAmount(centerGoods.getCenterAmount()); |
||||
|
costItem.setCenterRate(centerGoods.getCenterRate()); |
||||
|
costItem.setCenterGoodsAmount(centerGoods.getCenterGoodsAmount()); |
||||
|
costItem.setCenterGoodsRate(centerGoods.getCenterGoodsRate()); |
||||
|
costItem.setTargetType(centerGoods.getTargetType()); |
||||
|
costItem.setTargetId(centerGoods.getTargetId()); |
||||
|
costItem.setTargetCode(centerGoods.getTargetCode()); |
||||
|
costItem.setTargetName(centerGoods.getTargetName()); |
||||
|
costItem.setTargetLevelPathIds(centerGoods.getTargetLevelPathIds()); |
||||
|
costItem.setTargetLevelPathNames(centerGoods.getTargetLevelPathNames()); |
||||
|
costItem.setActStartDate(centerGoods.getActStartDate()); |
||||
|
costItem.setActEndDate(centerGoods.getActEndDate()); |
||||
|
costItem.setPreStartDate(centerGoods.getPreStartDate()); |
||||
|
costItem.setPreEndDate(centerGoods.getPreEndDate()); |
||||
|
costItem.setPreCheckDate(centerGoods.getPreCheckDate()); |
||||
|
costItem.setCenterGoodItemId(centerGoods.getId()); |
||||
|
|
||||
|
TbsBudgetLog budgetLog = TbsBudgetLogBuildUtil.buildTbsBudgetLog(BudgetLogOptFlag.State_1,sysUser,costApply,costItem ,budget,amount,activity); |
||||
|
budgetLog.setBudgetId(budget.getId()); |
||||
|
|
||||
|
budgetLog.setScheduleItemBudgetId(scheduleItemBudget.getId()); |
||||
|
budgetLog.setScheduleId(scheduleItemBudget.getScheduleId()); |
||||
|
budgetLog.setScheduleItemId(scheduleItemBudget.getScheduleItemId()); |
||||
|
budgetLog.setItemName(scheduleItemBudget.getItemName()); |
||||
|
|
||||
|
budgetLogList.add(budgetLog); |
||||
|
} |
||||
|
//移除历史记录
|
||||
|
budgetLogService.remove(new LambdaQueryWrapper<TbsBudgetLog>() |
||||
|
.eq(TbsBudgetLog::getCostApplyId,activity.getCostApplyId()) |
||||
|
.eq(TbsBudgetLog::getOptType, BudgetLogOptFlag.State_1.getCode()) |
||||
|
.eq(TbsBudgetLog::getActivityId,activity.getId())); |
||||
|
//重新保存
|
||||
|
if(CollectionUtil.isNotEmpty(budgetLogList)){ |
||||
|
budgetLogService.saveBatch(budgetLogList); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 依据剩余预算刷新释放金额 |
||||
|
*/ |
||||
|
public void check(Long actId){ |
||||
|
//校验活动的核销金额是否匹配,不匹配则中断
|
||||
|
//查询需要补偿释放的活动ID
|
||||
|
//List<Long> activityIds = vtbFundFlowMapper.listMissReleaseActivityId();
|
||||
|
Long[] activityIds = new Long[]{actId}; |
||||
|
for (Long activityId : activityIds) { |
||||
|
TbsActivity activity = activityService.getById(activityId); |
||||
|
TbsCostApply costApply = costApplyService.getById(activity.getCostApplyId()); |
||||
|
|
||||
|
//保存预算日志
|
||||
|
List<TbsActivityCenterGoods> centerGoodsList = activityCenterGoodsService.listByActivityId(activityId); |
||||
|
LambdaQueryWrapper<TbsBudgetCostItem> itemLqw = new LambdaQueryWrapper<>(); |
||||
|
itemLqw.eq(TbsBudgetCostItem::getActivityId,activityId); |
||||
|
List<TbsBudgetCostItem> budgetCostItemList = budgetCostItemService.list(itemLqw); |
||||
|
List<Long> budgetIds = budgetCostItemList.stream().map(TbsBudgetCostItem::getBudgetId).collect(Collectors.toList()); |
||||
|
if(CollUtil.isEmpty(budgetIds)){ |
||||
|
continue; |
||||
|
} |
||||
|
List<TbsBudget> budgetLIst = budgetService.listByIds(budgetIds); |
||||
|
List<TbsBudgetLog> budgetLogList = new ArrayList<>(); |
||||
|
for (TbsActivityCenterGoods centerGoods : centerGoodsList) { |
||||
|
if(centerGoods.getCenterGoodsAmount().compareTo(centerGoods.getUsedAmount())<1){ |
||||
|
continue; |
||||
|
} |
||||
|
TbsBudgetCostItem currCostItem = null; |
||||
|
TbsBudget currentBudget = null; |
||||
|
for (TbsBudgetCostItem costItem : budgetCostItemList) { |
||||
|
if(centerGoods.getId().equals(costItem.getCenterGoodItemId())){ |
||||
|
currCostItem = costItem; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
for (TbsBudget budget : budgetLIst) { |
||||
|
if (currCostItem.getBudgetId().equals(budget.getId())){ |
||||
|
currentBudget = budget; |
||||
|
} |
||||
|
} |
||||
|
BigDecimal amount = centerGoods.getCenterGoodsAmount().subtract(centerGoods.getUsedAmount()); |
||||
|
SysUser sysUser = new SysUser(); |
||||
|
sysUser.setId("0"); |
||||
|
sysUser.setName("系统执行"); |
||||
|
sysUser.setCode("0"); |
||||
|
TbsBudgetLog budgetLog = TbsBudgetLogBuildUtil.buildTbsBudgetLog(BudgetLogOptFlag.State_4,sysUser,costApply,currCostItem,currentBudget,amount,activity); |
||||
|
budgetLogList.add(budgetLog); |
||||
|
} |
||||
|
|
||||
|
//TODO 二次校验,释放金额是否一致
|
||||
|
|
||||
|
|
||||
|
//移除历史记录
|
||||
|
fundFlowService.remove( |
||||
|
new LambdaQueryWrapper<VtbFundFlow>() |
||||
|
.eq(VtbFundFlow::getFundType, VtbFundFlowType.Release) |
||||
|
.eq(VtbFundFlow::getCostApplyId,activity.getCostApplyId()) |
||||
|
.eq(VtbFundFlow::getActivityId,activity.getId()) |
||||
|
); |
||||
|
VtbFundFlow fundFlow = new VtbFundFlow(); |
||||
|
fundFlow.setFundType(VtbFundFlowType.Release); |
||||
|
fundFlow.setVerificationId(0L); |
||||
|
fundFlow.setCenterGoodsCode(activity.getActivityCode()+"_00"); |
||||
|
fundFlow.setCostApplyId(activity.getCostApplyId()); |
||||
|
fundFlow.setActivityId(activity.getId()); |
||||
|
fundFlow.setUsedAmount(activity.getReleaseAmount()); |
||||
|
fundFlow.setSupplierId(activity.getSupplierId()); |
||||
|
fundFlow.setSupplierCode(activity.getSupplierCode()); |
||||
|
fundFlow.setSupplierName(activity.getSupplierName()); |
||||
|
fundFlowService.save(fundFlow); |
||||
|
|
||||
|
//移除历史记录
|
||||
|
budgetLogService.remove(new LambdaQueryWrapper<TbsBudgetLog>() |
||||
|
.eq(TbsBudgetLog::getCostApplyId,activity.getCostApplyId()) |
||||
|
.eq(TbsBudgetLog::getOptType, BudgetLogOptFlag.State_4.getCode()) |
||||
|
.eq(TbsBudgetLog::getActivityId,activity.getId())); |
||||
|
|
||||
|
//更新付款条件状态
|
||||
|
LambdaQueryWrapper<TbsActivityPayCondition> updLqw = new LambdaQueryWrapper<>(); |
||||
|
updLqw.eq(TbsActivityPayCondition::getActivityId,activityId); |
||||
|
TbsActivityPayCondition payCondition = new TbsActivityPayCondition(); |
||||
|
payCondition.setFinishedFlag(1); |
||||
|
activityPayConditionService.update(payCondition,updLqw); |
||||
|
|
||||
|
//重新保存
|
||||
|
if(CollectionUtil.isNotEmpty(budgetLogList)){ |
||||
|
budgetLogService.saveBatch(budgetLogList); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,66 @@ |
|||||
|
package com.qs.serve.modules.tbs.service; |
||||
|
|
||||
|
import cn.hutool.core.collection.CollUtil; |
||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
||||
|
import com.qs.serve.modules.tbs.common.TbsActivityState; |
||||
|
import com.qs.serve.modules.tbs.entity.TbsActivity; |
||||
|
import com.qs.serve.modules.tbs.entity.TbsActivityPayCondition; |
||||
|
import com.qs.serve.modules.tbs.entity.TbsCostApply; |
||||
|
import com.qs.serve.modules.tbs.mapper.TbsActivityPayConditionMapper; |
||||
|
import com.qs.serve.modules.vtb.service.VtbVerificationService; |
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2024/5/28 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
@Service |
||||
|
@AllArgsConstructor |
||||
|
public class TbsCostContractApplication { |
||||
|
|
||||
|
private final TbsBudgetReleaseApplicationService tbsBudgetReleaseApplicationService; |
||||
|
private final TbsActivityPayConditionMapper activityPayConditionMapper; |
||||
|
private final TbsActivityPayConditionService activityPayConditionService; |
||||
|
private final TbsActivityService tbsActivityService; |
||||
|
private final TbsCostApplyService tbsCostApplyService; |
||||
|
private final VtbVerificationService verificationService; |
||||
|
|
||||
|
public void resetState(){ |
||||
|
//更新遗漏的已完成费用申请
|
||||
|
List<Long> costIds = activityPayConditionMapper.getFinishedCostId(); |
||||
|
if(CollUtil.isNotEmpty(costIds)){ |
||||
|
List<TbsCostApply> costApplyList = tbsCostApplyService.listByIds(costIds); |
||||
|
for (TbsCostApply costApply : costApplyList) { |
||||
|
costApply.setChargeState(3); |
||||
|
costApply.setCheckState(1); |
||||
|
} |
||||
|
tbsCostApplyService.updateBatchById(costApplyList); |
||||
|
//更新状态
|
||||
|
activityPayConditionService.update(new LambdaUpdateWrapper<TbsActivityPayCondition>() |
||||
|
.set(TbsActivityPayCondition::getFinishedFlag,1) |
||||
|
.in(TbsActivityPayCondition::getCostApplyId,costIds)); |
||||
|
List<TbsActivity> activityList = tbsActivityService.list(new LambdaQueryWrapper<TbsActivity>() |
||||
|
.in(TbsActivity::getCostApplyId,costIds)); |
||||
|
for (TbsActivity activity : activityList) { |
||||
|
if(activity.getUsedAmount().compareTo(activity.getTotalAmount())==0){ |
||||
|
activity.setActivityState(TbsActivityState.STATE_1_Finished); |
||||
|
}else { |
||||
|
//不进行直接释放,通过补充释放,最终一次性修复
|
||||
|
activity.setReleaseFlag(1); |
||||
|
activity.setReleaseAmount(activity.getTotalAmount().subtract(activity.getUsedAmount())); |
||||
|
activity.setActivityState(TbsActivityState.STATE_4_Release); |
||||
|
tbsBudgetReleaseApplicationService.check(activity.getId()); |
||||
|
} |
||||
|
} |
||||
|
tbsActivityService.updateBatchById(activityList); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,101 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<!DOCTYPE mapper |
||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="com.qs.serve.modules.bir.mapper.BirBudgetTargetMapper"> |
||||
|
|
||||
|
<resultMap id="birBudgetTargetMap" type="com.qs.serve.modules.bir.entity.BirBudgetTarget" > |
||||
|
<result property="id" column="id"/> |
||||
|
<result property="searchType" column="search_type"/> |
||||
|
<result property="yearNum" column="year_num"/> |
||||
|
<result property="quarterNum" column="quarter_num"/> |
||||
|
<result property="monthNum" column="month_num"/> |
||||
|
<result property="targetAmt" column="target_amt"/> |
||||
|
<result property="budgetAmt" column="budget_amt"/> |
||||
|
<result property="dispatchAmt" column="dispatch_amt"/> |
||||
|
<result property="lastYearDispatchAmt" column="last_year_dispatch_amt"/> |
||||
|
<result property="provinceCityAmt" column="province_city_amt"/> |
||||
|
<result property="provinceCityRegionAmt" column="province_city_region_amt"/> |
||||
|
<result property="totalRealAmt" column="total_real_amt"/> |
||||
|
<result property="brandId" column="brand_id"/> |
||||
|
<result property="brandCode" column="brand_code"/> |
||||
|
<result property="brandName" column="brand_name"/> |
||||
|
<result property="centerType" column="center_type"/> |
||||
|
<result property="centerId" column="center_id"/> |
||||
|
<result property="centerCode" column="center_code"/> |
||||
|
<result property="centerName" column="center_name"/> |
||||
|
</resultMap> |
||||
|
|
||||
|
<sql id="birBudgetTargetSql"> |
||||
|
bir_budget_target.`id`, |
||||
|
bir_budget_target.`search_type`, |
||||
|
bir_budget_target.`year_num`, |
||||
|
bir_budget_target.`quarter_num`, |
||||
|
bir_budget_target.`month_num`, |
||||
|
bir_budget_target.`target_amt`, |
||||
|
bir_budget_target.`budget_amt`, |
||||
|
bir_budget_target.`dispatch_amt`, |
||||
|
bir_budget_target.`last_year_dispatch_amt`, |
||||
|
bir_budget_target.`province_city_amt`, |
||||
|
bir_budget_target.`province_city_region_amt`, |
||||
|
bir_budget_target.`total_real_amt`, |
||||
|
bir_budget_target.`brand_id`, |
||||
|
bir_budget_target.`brand_code`, |
||||
|
bir_budget_target.`brand_name`, |
||||
|
bir_budget_target.`center_type`, |
||||
|
bir_budget_target.`center_id`, |
||||
|
bir_budget_target.`center_code`, |
||||
|
bir_budget_target.`center_name` </sql> |
||||
|
|
||||
|
<select id="selectBirBudgetTargetList" parameterType="com.qs.serve.modules.bir.entity.BirBudgetTarget" resultMap="birBudgetTargetMap"> |
||||
|
SELECT <include refid="birBudgetTargetSql"/> FROM `bir_budget_target` `bir_budget_target` |
||||
|
<where> |
||||
|
<if test="query.loadType != null"> and `bir_budget_target`.`search_type` = #{query.loadType}</if> |
||||
|
<if test="query.yearMonthStart != null"> and `bir_budget_target`.`row_date` >= #{query.yearMonthStart}</if> |
||||
|
<if test="query.yearMonthEnd != null"> and `bir_budget_target`.`row_date` <= #{query.yearMonthEnd}</if> |
||||
|
|
||||
|
<if test="query.brandIds!=null and query.brandIds.size > 0"> |
||||
|
and `bir_budget_target`.`brand_id` in |
||||
|
<foreach collection="query.brandIds" item="selectId" index="i" open="(" close=")" separator=","> |
||||
|
#{selectId} |
||||
|
</foreach> |
||||
|
</if> |
||||
|
|
||||
|
<if test="query.selectCenterFlag=1"> |
||||
|
and ( |
||||
|
1=0 |
||||
|
<if test="query.supplierIds!=null and query.supplierIds.size > 0"> |
||||
|
or (`bir_budget_target`.`center_type` = 'supplier' and `bir_budget_target`.center_id in |
||||
|
<foreach collection="query.supplierIds" item="selectId" index="i" open="(" close=")" separator=","> |
||||
|
#{selectId} |
||||
|
</foreach> |
||||
|
) |
||||
|
</if> |
||||
|
<if test="query.saleRegionIds!=null and query.saleRegionIds.size > 0"> |
||||
|
or (`bir_budget_target`.`center_type` = 'saleRegion' and `bir_budget_target`.center_id in |
||||
|
<foreach collection="query.saleRegionIds" item="selectId" index="i" open="(" close=")" separator=","> |
||||
|
#{selectId} |
||||
|
</foreach> |
||||
|
) |
||||
|
</if> |
||||
|
<if test="query.bizRegionIds!=null and query.bizRegionIds.size > 0"> |
||||
|
or (`bir_budget_target`.`center_type` = 'bizRegion' and `bir_budget_target`.center_id in |
||||
|
<foreach collection="query.bizRegionIds" item="selectId" index="i" open="(" close=")" separator=","> |
||||
|
#{selectId} |
||||
|
</foreach> |
||||
|
) |
||||
|
</if> |
||||
|
<if test="query.centerIds!=null and query.centerIds.size > 0"> |
||||
|
or (`bir_budget_target`.`center_type` = 'costCenter' and `bir_budget_target`.center_id in |
||||
|
<foreach collection="query.centerIds" item="selectId" index="i" open="(" close=")" separator=","> |
||||
|
#{selectId} |
||||
|
</foreach> |
||||
|
) |
||||
|
</if> |
||||
|
) |
||||
|
</if> |
||||
|
|
||||
|
</where> |
||||
|
</select> |
||||
|
|
||||
|
</mapper> |
Loading…
Reference in new issue