|
|
@ -1,26 +1,34 @@ |
|
|
|
package com.qs.serve.modules.vtb.service.impl; |
|
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
|
|
|
import com.qs.serve.common.util.Assert; |
|
|
|
import com.qs.serve.common.util.CollectionUtil; |
|
|
|
import com.qs.serve.common.util.CopierUtil; |
|
|
|
import com.qs.serve.modules.bms.entity.BmsSubject; |
|
|
|
import com.qs.serve.modules.bms.service.BmsSubjectService; |
|
|
|
import com.qs.serve.modules.tbs.entity.TbsActivity; |
|
|
|
import com.qs.serve.modules.tbs.entity.TbsCostApply; |
|
|
|
import com.qs.serve.modules.tbs.service.TbsActivityService; |
|
|
|
import com.qs.serve.modules.tbs.service.TbsCostApplyService; |
|
|
|
import com.qs.serve.modules.tbs.entity.*; |
|
|
|
import com.qs.serve.modules.tbs.service.*; |
|
|
|
import com.qs.serve.modules.vtb.common.VtbFundFlowType; |
|
|
|
import com.qs.serve.modules.vtb.common.VtbVerificationState; |
|
|
|
import com.qs.serve.modules.vtb.entity.VtbFundFlow; |
|
|
|
import com.qs.serve.modules.vtb.entity.VtbVerification; |
|
|
|
import com.qs.serve.modules.vtb.entity.VtbVerificationSubject; |
|
|
|
import com.qs.serve.modules.vtb.entity.bo.VtbVerificationBo; |
|
|
|
import com.qs.serve.modules.vtb.entity.bo.VtbVerificationChannelBo; |
|
|
|
import com.qs.serve.modules.vtb.entity.bo.VtbVerificationChannelPointBo; |
|
|
|
import com.qs.serve.modules.vtb.entity.bo.VtbVerificationSubjectBo; |
|
|
|
import com.qs.serve.modules.vtb.mapper.VtbVerificationMapper; |
|
|
|
import com.qs.serve.modules.vtb.service.*; |
|
|
|
import lombok.AllArgsConstructor; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import com.qs.serve.modules.vtb.entity.VtbVerification; |
|
|
|
import com.qs.serve.modules.vtb.service.VtbVerificationService; |
|
|
|
import com.qs.serve.modules.vtb.mapper.VtbVerificationMapper; |
|
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
|
|
|
|
|
import java.math.BigDecimal; |
|
|
|
import java.util.List; |
|
|
|
import java.math.RoundingMode; |
|
|
|
import java.util.*; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
/** |
|
|
|
* 核销 服务实现类 |
|
|
@ -32,26 +40,72 @@ import java.util.List; |
|
|
|
@AllArgsConstructor |
|
|
|
public class VtbVerificationServiceImpl extends ServiceImpl<VtbVerificationMapper,VtbVerification> implements VtbVerificationService { |
|
|
|
|
|
|
|
private final TbsActivityService activityService; |
|
|
|
private final TbsCostApplyService costApplyService; |
|
|
|
private final TbsActivityService activityService; |
|
|
|
private final TbsActivitySubjectService activitySubjectService; |
|
|
|
private final TbsActivityCenterService activityCenterService; |
|
|
|
private final TbsActivityCenterGoodsService activityCenterGoodsService; |
|
|
|
|
|
|
|
private final BmsSubjectService subjectService; |
|
|
|
|
|
|
|
private final VtbVerificationChannelService verificationChannelService; |
|
|
|
private final VtbVerificationChannelPointService verificationChannelPointService; |
|
|
|
private final VtbVerificationSubjectService verificationSubjectService; |
|
|
|
private final VtbFundFlowService fundFlowService; |
|
|
|
|
|
|
|
@Override |
|
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
|
public void commit(VtbVerificationBo verificationBo) { |
|
|
|
TbsActivity activity = activityService.getById(verificationBo.getActivityId()); |
|
|
|
TbsCostApply costApply = costApplyService.getById(activity.getCostApplyId()); |
|
|
|
//todo 检测是否有拦截
|
|
|
|
//todo 结束的活动不支持核销
|
|
|
|
boolean hasRelease = fundFlowService.hasRelease(activity.getId()); |
|
|
|
if(hasRelease){ |
|
|
|
Assert.throwEx("费用已释放"); |
|
|
|
} |
|
|
|
boolean isCommitting = this.checkCommitting(activity.getId()); |
|
|
|
if(isCommitting){ |
|
|
|
Assert.throwEx("该活动核销中"); |
|
|
|
} |
|
|
|
VtbVerification verification = new VtbVerification(); |
|
|
|
verification.setId(verification.getId()); |
|
|
|
verification.setId(verificationBo.getId()); |
|
|
|
verification.setActivityId(verificationBo.getActivityId()); |
|
|
|
verification.setAttachIds(verificationBo.getAttachIds()); |
|
|
|
verification.setRemark(verificationBo.getRemark()); |
|
|
|
this.saveOrUpdate(verification); |
|
|
|
|
|
|
|
|
|
|
|
List<VtbVerificationChannelBo> channelBoList = verificationBo.getChannelList(); |
|
|
|
List<VtbVerificationChannelPointBo> pointBoList = verificationBo.getPointList(); |
|
|
|
if(CollectionUtil.isNotEmpty(channelBoList)){ |
|
|
|
|
|
|
|
}else if (CollectionUtil.isNotEmpty(pointBoList)){ |
|
|
|
|
|
|
|
} |
|
|
|
List<VtbVerificationSubject> verificationSubjects = validCreateVeriSubject(verificationBo, activity, costApply); |
|
|
|
//保存
|
|
|
|
this.saveOrUpdate(verification); |
|
|
|
//移除历史提交记录
|
|
|
|
if(verificationBo.getId()!=null){ |
|
|
|
verificationChannelService.removeByVerificationId(verificationBo.getId()); |
|
|
|
verificationChannelPointService.removeByVerificationId(verificationBo.getId()); |
|
|
|
verificationSubjectService.removeByVerificationId(verificationBo.getId()); |
|
|
|
} |
|
|
|
//保存科目费用
|
|
|
|
verificationSubjects.forEach(obj->obj.setVerificationId(verification.getId())); |
|
|
|
verificationSubjectService.saveBatch(verificationSubjects); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 校验和生成核销费用 |
|
|
|
* @param verificationBo |
|
|
|
* @param activity |
|
|
|
* @param costApply |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
private List<VtbVerificationSubject> validCreateVeriSubject(VtbVerificationBo verificationBo, TbsActivity activity, TbsCostApply costApply) { |
|
|
|
List<VtbVerificationSubject> verificationSubjects = new ArrayList<>(); |
|
|
|
List<TbsActivitySubject> activitySubjects = activitySubjectService.listByActivityId(activity.getId()); |
|
|
|
List<VtbFundFlow> existFundFlowList = fundFlowService.listByActivity(activity.getId(), VtbFundFlowType.Verification); |
|
|
|
//校验余额
|
|
|
|
Map<Long,List<VtbFundFlow>> funFlowListMap = existFundFlowList.stream().collect(Collectors.groupingBy(VtbFundFlow::getSubjectId)); |
|
|
|
List<VtbVerificationSubjectBo> subjectBoList = verificationBo.getSubjectList(); |
|
|
|
for (VtbVerificationSubjectBo subjectBo : subjectBoList) { |
|
|
|
//忽略金额为0的数据
|
|
|
@ -59,9 +113,27 @@ public class VtbVerificationServiceImpl extends ServiceImpl<VtbVerificationMappe |
|
|
|
continue; |
|
|
|
} |
|
|
|
BmsSubject subject = subjectService.getById(subjectBo.getSubjectId()); |
|
|
|
|
|
|
|
//判断是否超额
|
|
|
|
TbsActivitySubject currentActivitySubject = null; |
|
|
|
for (TbsActivitySubject activitySubject : activitySubjects) { |
|
|
|
if (activitySubject.getSubjectId().equals(subject.getId())) { |
|
|
|
currentActivitySubject = activitySubject; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
List<VtbFundFlow> subjectFundFlowItems = funFlowListMap.get(subject.getId()); |
|
|
|
BigDecimal totalSubjectUsedAmount = BigDecimal.ZERO; |
|
|
|
if (CollectionUtil.isNotEmpty(subjectFundFlowItems)) { |
|
|
|
for (VtbFundFlow subjectFundFlowItem : subjectFundFlowItems) { |
|
|
|
totalSubjectUsedAmount = totalSubjectUsedAmount.add(subjectFundFlowItem.getUsedAmount()); |
|
|
|
} |
|
|
|
} |
|
|
|
totalSubjectUsedAmount = totalSubjectUsedAmount.add(subjectBo.getAmount()); |
|
|
|
if (totalSubjectUsedAmount.compareTo(currentActivitySubject.getAmount()) > 0) { |
|
|
|
Assert.throwEx("费用类型[" + subject.getSubjectName() + "]超额"); |
|
|
|
} |
|
|
|
//保存费用结果
|
|
|
|
VtbVerificationSubject verificationSubject = new VtbVerificationSubject(); |
|
|
|
verificationSubject.setVerificationId(verification.getId()); |
|
|
|
verificationSubject.setCostApplyId(costApply.getId()); |
|
|
|
verificationSubject.setActivityId(activity.getId()); |
|
|
|
verificationSubject.setSubjectId(subject.getId()); |
|
|
@ -71,11 +143,110 @@ public class VtbVerificationServiceImpl extends ServiceImpl<VtbVerificationMappe |
|
|
|
verificationSubject.setCountPerson(subjectBo.getCountPerson()); |
|
|
|
verificationSubject.setCountSession(subjectBo.getCountSession()); |
|
|
|
verificationSubject.setRemark(subjectBo.getRemark()); |
|
|
|
verificationSubjects.add(verificationSubject); |
|
|
|
} |
|
|
|
return verificationSubjects; |
|
|
|
} |
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
|
public void successCommit(Long verificationId) { |
|
|
|
log.info("活动核销提交成功。verificationId:{}",verificationId); |
|
|
|
VtbVerification verification = this.getById(verificationId); |
|
|
|
List<VtbVerificationSubject> verificationSubjects = verificationSubjectService.listByVerificationId(verification.getId()); |
|
|
|
List<TbsActivityCenterGoods> activityCenterGoodsAllList = activityCenterGoodsService.listByActivityId(verification.getActivityId()); |
|
|
|
List<VtbFundFlow> addFundFlowList = new ArrayList<>(); |
|
|
|
//生成费用流水记录
|
|
|
|
Map<Long,List<TbsActivityCenterGoods>> centerGoodsMapBySubject = activityCenterGoodsAllList.stream() |
|
|
|
.collect(Collectors.groupingBy(TbsActivityCenterGoods::getSubjectId)); |
|
|
|
for (VtbVerificationSubject verificationSubject : verificationSubjects) { |
|
|
|
List<VtbFundFlow> addFundFlowListOfSubject = new ArrayList<>(); |
|
|
|
Long subjectId = verificationSubject.getSubjectId(); |
|
|
|
BigDecimal usedAmount = verificationSubject.getUsedAmount(); |
|
|
|
BigDecimal subtractAmount = verificationSubject.getUsedAmount(); |
|
|
|
List<TbsActivityCenterGoods> activityCenterGoodsOfSubject = centerGoodsMapBySubject.get(subjectId); |
|
|
|
//统计前面项合计金额
|
|
|
|
BigDecimal totalPrefixAmount = BigDecimal.ZERO; |
|
|
|
//统计不匹配金额
|
|
|
|
BigDecimal unMatchAmount = BigDecimal.ZERO; |
|
|
|
for (int i = 0; i < activityCenterGoodsOfSubject.size(); i++) { |
|
|
|
TbsActivityCenterGoods centerGoods = activityCenterGoodsOfSubject.get(i); |
|
|
|
BigDecimal currentTimeAmount; |
|
|
|
if(i==activityCenterGoodsOfSubject.size()-1){ |
|
|
|
currentTimeAmount = usedAmount.subtract(totalPrefixAmount); |
|
|
|
}else { |
|
|
|
currentTimeAmount = usedAmount.multiply(centerGoods.getCenterGoodsRate()) |
|
|
|
.multiply(centerGoods.getCenterRate()) |
|
|
|
//四舍五入保留两位小数
|
|
|
|
.divide(new BigDecimal(10000), RoundingMode.HALF_UP).setScale(2); |
|
|
|
//防止费率为0情况
|
|
|
|
if(currentTimeAmount.compareTo(BigDecimal.ZERO)==0){ |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
//可用金额
|
|
|
|
BigDecimal allowBalance = centerGoods.getCenterGoodsAmount().subtract(centerGoods.getUsedAmount()); |
|
|
|
if(allowBalance.compareTo(BigDecimal.ZERO)==0){ |
|
|
|
log.debug("统计不匹配金额allowBalance:{},currentTimeAmount:{}",allowBalance.doubleValue(),currentTimeAmount.doubleValue()); |
|
|
|
unMatchAmount.add(currentTimeAmount); |
|
|
|
continue; |
|
|
|
} |
|
|
|
BigDecimal tempBalance = BigDecimal.ZERO; |
|
|
|
//如果不够减
|
|
|
|
if(allowBalance.compareTo(currentTimeAmount)<1){ |
|
|
|
//统计不匹配金额
|
|
|
|
unMatchAmount = unMatchAmount.add(currentTimeAmount.subtract(allowBalance)); |
|
|
|
log.debug("统计不匹配金额allowBalance:{},currentTimeAmount:{}",allowBalance.doubleValue(),currentTimeAmount.doubleValue()); |
|
|
|
currentTimeAmount = allowBalance; |
|
|
|
}else { |
|
|
|
tempBalance = allowBalance.subtract(currentTimeAmount); |
|
|
|
} |
|
|
|
VtbFundFlow fundFlow = CopierUtil.copy(centerGoods,new VtbFundFlow()); |
|
|
|
fundFlow.setId(null); |
|
|
|
fundFlow.setUsedAmount(currentTimeAmount); |
|
|
|
fundFlow.setFundType(VtbFundFlowType.Release); |
|
|
|
fundFlow.setVerificationId(verificationId); |
|
|
|
fundFlow.setTempBalance(tempBalance); |
|
|
|
addFundFlowListOfSubject.add(fundFlow); |
|
|
|
} |
|
|
|
//todo 1400元 44次 33行
|
|
|
|
//打乱顺序,保存前平摊费用
|
|
|
|
Collections.shuffle(addFundFlowListOfSubject); |
|
|
|
for (VtbFundFlow fundFlow : addFundFlowListOfSubject) { |
|
|
|
if(unMatchAmount.compareTo(BigDecimal.ZERO)>0){ |
|
|
|
BigDecimal tmpBalance = fundFlow.getTempBalance(); |
|
|
|
if(tmpBalance.compareTo(BigDecimal.ZERO)>0){ |
|
|
|
if(tmpBalance.compareTo(unMatchAmount)>0){ |
|
|
|
BigDecimal resultBalance = fundFlow.getUsedAmount().add(unMatchAmount); |
|
|
|
fundFlow.setUsedAmount(resultBalance); |
|
|
|
break; |
|
|
|
}else { |
|
|
|
unMatchAmount = unMatchAmount.subtract(fundFlow.getTempBalance()); |
|
|
|
BigDecimal resultBalance = fundFlow.getUsedAmount().add(tmpBalance); |
|
|
|
fundFlow.setUsedAmount(resultBalance); |
|
|
|
} |
|
|
|
} |
|
|
|
}else { |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if(unMatchAmount.compareTo(BigDecimal.ZERO)>0){ |
|
|
|
log.error("异常数据,费用核销[{}]超额:{}",verificationId,unMatchAmount.doubleValue()); |
|
|
|
} |
|
|
|
addFundFlowList.addAll(addFundFlowListOfSubject); |
|
|
|
} |
|
|
|
fundFlowService.saveBatch(addFundFlowList); |
|
|
|
//更新已用费用记录
|
|
|
|
fundFlowService.flushActivityAmount(verification.getActivityId()); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
public boolean checkCommitting(Long activityId) { |
|
|
|
LambdaQueryWrapper<VtbVerification> lqw = new LambdaQueryWrapper<>(); |
|
|
|
lqw.eq(VtbVerification::getActivityId,activityId); |
|
|
|
lqw.eq(VtbVerification::getVerificationState, VtbVerificationState.Commit.getCode()); |
|
|
|
return this.count(lqw)>0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|