diff --git a/src/main/java/com/qs/serve/modules/bir/entity/BirActivityCenterGoods.java b/src/main/java/com/qs/serve/modules/bir/entity/BirActivityCenterGoods.java index 49e785d4..2f95c6c4 100644 --- a/src/main/java/com/qs/serve/modules/bir/entity/BirActivityCenterGoods.java +++ b/src/main/java/com/qs/serve/modules/bir/entity/BirActivityCenterGoods.java @@ -19,7 +19,7 @@ import javax.validation.constraints.NotBlank; /** * 实体类 * @author YenHex - * @since 2023-07-06 + * @since 2023-07-07 */ @Data @TableName("bir_activity_center_goods") @@ -80,6 +80,15 @@ public class BirActivityCenterGoods implements Serializable { @Length(max = 30,message = "活动编码长度不能超过30字") private String activityCode; + /** 活动总金额 */ + private BigDecimal activityTotalAmount; + + /** 活动总核销金额 */ + private BigDecimal activityTotalCheckAmount; + + /** 活动完成主题 */ + private Integer activityFinishedFlag; + /** 科目id */ @NotNull(message = "科目id不能为空") private Long subjectId; @@ -264,6 +273,9 @@ public class BirActivityCenterGoods implements Serializable { activityCenterGoods.setCostApplyId(source.getCostApplyId()); activityCenterGoods.setActivityId(source.getActivityId()); activityCenterGoods.setActivityCode(source.getActivityCode()); + activityCenterGoods.setActivityTotalAmount(source.getActivityTotalAmount()); + activityCenterGoods.setActivityTotalCheckAmount(source.getActivityTotalCheckAmount()); + activityCenterGoods.setActivityFinishedFlag(source.getActivityFinishedFlag()); activityCenterGoods.setSubjectId(source.getSubjectId()); activityCenterGoods.setSubjectCode(source.getSubjectCode()); activityCenterGoods.setSubjectName(source.getSubjectName()); diff --git a/src/main/java/com/qs/serve/modules/bir/entity/dto/BirCenterGoodSplitDTO.java b/src/main/java/com/qs/serve/modules/bir/entity/dto/BirCenterGoodSplitDTO.java new file mode 100644 index 00000000..961fe7bc --- /dev/null +++ b/src/main/java/com/qs/serve/modules/bir/entity/dto/BirCenterGoodSplitDTO.java @@ -0,0 +1,20 @@ +package com.qs.serve.modules.bir.entity.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author YenHex + * @since 2023/7/7 + */ +@Data +public class BirCenterGoodSplitDTO { + + //当前CenterGoods分割项金额 + BigDecimal currentSplitAmount; + + //当前CenterGoods分割项核销金额(粗略计算) + BigDecimal currentSplitCheckAmount; + +} diff --git a/src/main/java/com/qs/serve/modules/bir/mapper/BirActivityCenterGoodsMapper.java b/src/main/java/com/qs/serve/modules/bir/mapper/BirActivityCenterGoodsMapper.java index f91b9a49..87091173 100644 --- a/src/main/java/com/qs/serve/modules/bir/mapper/BirActivityCenterGoodsMapper.java +++ b/src/main/java/com/qs/serve/modules/bir/mapper/BirActivityCenterGoodsMapper.java @@ -2,6 +2,11 @@ package com.qs.serve.modules.bir.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.qs.serve.modules.bir.entity.BirActivityCenterGoods; +import com.qs.serve.modules.tbs.entity.TbsActivityCenterGoods; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDate; +import java.util.List; /** * Mapper @@ -10,6 +15,14 @@ import com.qs.serve.modules.bir.entity.BirActivityCenterGoods; */ public interface BirActivityCenterGoodsMapper extends BaseMapper { + /** + * 查询出异动的记录 + * @param startDate + * @param endDate + * @return + */ + List selectChangeCenterGoods(@Param("startDate") LocalDate startDate, + @Param("endDate")LocalDate endDate); } diff --git a/src/main/java/com/qs/serve/modules/bir/service/BirActivityCenterGoodsService.java b/src/main/java/com/qs/serve/modules/bir/service/BirActivityCenterGoodsService.java index d41782fb..3b9a99fa 100644 --- a/src/main/java/com/qs/serve/modules/bir/service/BirActivityCenterGoodsService.java +++ b/src/main/java/com/qs/serve/modules/bir/service/BirActivityCenterGoodsService.java @@ -10,5 +10,12 @@ import com.qs.serve.modules.bir.entity.BirActivityCenterGoods; */ public interface BirActivityCenterGoodsService extends IService { + /** + * 创建分割统计表 + * @param year + * @param month + */ + void buildReport(int year, int month); + } diff --git a/src/main/java/com/qs/serve/modules/bir/service/impl/BirActivityCenterGoodsServiceImpl.java b/src/main/java/com/qs/serve/modules/bir/service/impl/BirActivityCenterGoodsServiceImpl.java index 32ed1938..c475ec3e 100644 --- a/src/main/java/com/qs/serve/modules/bir/service/impl/BirActivityCenterGoodsServiceImpl.java +++ b/src/main/java/com/qs/serve/modules/bir/service/impl/BirActivityCenterGoodsServiceImpl.java @@ -1,16 +1,37 @@ package com.qs.serve.modules.bir.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.qs.serve.common.model.dto.DateSplitDTO; +import com.qs.serve.common.util.DateSplitUtil; +import com.qs.serve.modules.bir.entity.BirBaseActivity; +import com.qs.serve.modules.bir.entity.dto.BirCenterGoodSplitDTO; +import com.qs.serve.modules.bms.entity.BmsCostCenter; +import com.qs.serve.modules.bms.entity.BmsRegion; +import com.qs.serve.modules.bms.entity.BmsRegion2; +import com.qs.serve.modules.bms.mapper.BmsCostCenterMapper; +import com.qs.serve.modules.bms.mapper.BmsRegion2Mapper; +import com.qs.serve.modules.bms.mapper.BmsRegionMapper; import com.qs.serve.modules.tbs.entity.TbsActivity; import com.qs.serve.modules.tbs.entity.TbsActivityCenter; +import com.qs.serve.modules.tbs.entity.TbsActivityCenterGoods; import com.qs.serve.modules.tbs.service.TbsActivityCenterGoodsService; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; import org.springframework.stereotype.Service; import com.qs.serve.modules.bir.entity.BirActivityCenterGoods; import com.qs.serve.modules.bir.service.BirActivityCenterGoodsService; import com.qs.serve.modules.bir.mapper.BirActivityCenterGoodsMapper; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + /** * 服务实现类 * @author YenHex @@ -21,10 +42,254 @@ import com.qs.serve.modules.bir.mapper.BirActivityCenterGoodsMapper; @AllArgsConstructor public class BirActivityCenterGoodsServiceImpl extends ServiceImpl implements BirActivityCenterGoodsService { - private TbsActivityCenterGoodsService centerGoodsService; + private final TbsActivityCenterGoodsService centerGoodsService; + + private final BmsCostCenterMapper costCenterMapper; + + private final BmsRegionMapper regionMapper; + + private final BmsRegion2Mapper region2Mapper; + + @Override + public void buildReport(int year, int month) { + LocalDate startDate = LocalDate.of(year,month,1); + int lastDayNum2 = startDate.lengthOfMonth(); + LocalDate endDate = LocalDate.of(year,month,lastDayNum2); + //加载所有异动的数据 + List activityCenterGoodsAllList = this.baseMapper.selectChangeCenterGoods(startDate,endDate); + if(activityCenterGoodsAllList.size()<1){ + return; + } + // 删除历史数据 + List activityIds = activityCenterGoodsAllList.stream().filter(a->a.getId()!=null) + .map(TbsActivityCenterGoods::getActivityId).collect(Collectors.toList()); + LambdaQueryWrapper birBaseActivityLqw = new LambdaQueryWrapper<>(); + birBaseActivityLqw.in(BirActivityCenterGoods::getActivityId,activityIds); + this.remove(birBaseActivityLqw); + + //加载所有自定义成本中心 + List costCenterList = costCenterMapper.selectList(new QueryWrapper<>()); + + // 按活动id分组 + Map> collectMap = activityCenterGoodsAllList.stream() + .collect(Collectors.groupingBy(TbsActivityCenterGoods::getActivityId)); + + for (Long activityId : collectMap.keySet()) { + //用于保存的对象列表 + List bacgList = new ArrayList<>(); + //创建对象列表 + List activityCenterGoodsList = collectMap.get(activityId); + for (TbsActivityCenterGoods activityCenterGoods : activityCenterGoodsList) { + LocalDate actStartDate = activityCenterGoods.getPreStartDate(); + LocalDate actEndDate = activityCenterGoods.getPreEndDate(); + int currentActDays = (int) (actEndDate.toEpochDay()-actStartDate.toEpochDay()+1); + List dateSplitList = DateSplitUtil.getSplitDto(actStartDate,actEndDate); + if(dateSplitList.size()>1){ + for (DateSplitDTO currDateSplit : dateSplitList) { + //获取该项分割金额对象 + BirCenterGoodSplitDTO goodSplitDTO = this.buildSplitAmount(activityCenterGoods, + dateSplitList, currDateSplit,currentActDays); + //创建底表对象 + BirActivityCenterGoods entity = createBirActivityCenterGoodsEntity(costCenterList, + activityCenterGoods, currentActDays, currDateSplit, goodSplitDTO); + bacgList.add(entity); + } + } + } + this.saveBatch(bacgList); + } + //TODO 更新区域类型的名称和编码 + + } + + /** + * 创建底表对象 + * @param costCenterList + * @param activityCenterGoods + * @param currentActDays + * @param currDateSplit + * @param goodSplitDTO + * @return + */ + @NotNull + private BirActivityCenterGoods createBirActivityCenterGoodsEntity(List costCenterList, + TbsActivityCenterGoods activityCenterGoods, + Integer currentActDays, + DateSplitDTO currDateSplit, + BirCenterGoodSplitDTO goodSplitDTO) { + BirActivityCenterGoods entity = new BirActivityCenterGoods(); + entity.setActivityCenterGoodsId(activityCenterGoods.getId()); + entity.setYearMonth(currDateSplit.getYearMonth()); + entity.setDays(currentActDays); + entity.setStarDate(currDateSplit.getStartDate()); + entity.setEndDate(currDateSplit.getEndDate()); + entity.setSplitAmount(goodSplitDTO.getCurrentSplitAmount()); + entity.setSplitUsedAmount(goodSplitDTO.getCurrentSplitCheckAmount()); + entity.setCenterGoodsCode(activityCenterGoods.getCenterGoodsCode()); + entity.setCostApplyId(activityCenterGoods.getCostApplyId()); + entity.setActivityId(activityCenterGoods.getActivityId()); + entity.setActivityCode(activityCenterGoods.getActivityCode()); + entity.setActivityTotalAmount(activityCenterGoods.getActivityAmt()); + entity.setActivityTotalCheckAmount(activityCenterGoods.getActivityCheckAmt()); + entity.setActivityFinishedFlag(activityCenterGoods.getActivityFinishedFlag()); + entity.setSubjectId(activityCenterGoods.getSubjectId()); + entity.setSubjectCode(activityCenterGoods.getSubjectCode()); + entity.setSubjectName(activityCenterGoods.getSubjectName()); + entity.setCenterType(activityCenterGoods.getCenterType()); + entity.setCenterId(activityCenterGoods.getCenterId()); + entity.setCenterCode(activityCenterGoods.getCenterCode()); + entity.setCenterName(activityCenterGoods.getCenterName()); + entity.setCenterAmount(activityCenterGoods.getCenterAmount()); + entity.setCenterRate(activityCenterGoods.getCenterRate()); + entity.setCenterGoodsAmount(activityCenterGoods.getCenterGoodsAmount()); + entity.setCenterGoodsRate(activityCenterGoods.getCenterGoodsRate()); + entity.setUsedAmount(activityCenterGoods.getUsedAmount()); + entity.setTargetType(activityCenterGoods.getTargetType()); + entity.setTargetId(activityCenterGoods.getTargetId()); + entity.setTargetCode(activityCenterGoods.getTargetCode()); + entity.setTargetName(activityCenterGoods.getTargetName()); + entity.setTargetLevelPathIds(activityCenterGoods.getTargetLevelPathIds()); + entity.setTargetLevelPathNames(activityCenterGoods.getTargetLevelPathNames()); + //递归初始化成本中心 + this.initializeCostCenterInfo(entity, costCenterList); + entity.setActStartDate(activityCenterGoods.getActStartDate()); + entity.setActEndDate(activityCenterGoods.getActEndDate()); + entity.setPreStartDate(activityCenterGoods.getPreStartDate()); + entity.setPreEndDate(activityCenterGoods.getPreEndDate()); + entity.setPreCheckDate(activityCenterGoods.getPreCheckDate()); + entity.setSupplierId(activityCenterGoods.getSupplierId()); + entity.setSupplierCode(activityCenterGoods.getSupplierCode()); + entity.setSupplierName(activityCenterGoods.getSupplierName()); + return entity; + } + + + /** + * 递归初始化成本中心 + * @param entity + * @param costCenterList + */ + private void initializeCostCenterInfo(BirActivityCenterGoods entity,List costCenterList) { + String centerId = entity.getCenterId(); + String centerType = entity.getCenterType(); + String centerCode = entity.getCenterCode(); + String centerName = entity.getCenterName(); + if("center".equals(centerType)){ + for (BmsCostCenter costCenter : costCenterList) { + if(centerId.equals(costCenter.getId().toString())){ + if(costCenter.getPid().equals(0L)){ + entity.setCenterLv1Id(costCenter.getId().toString()); + entity.setCenterLv1Code(costCenter.getCode()); + entity.setCenterLv1Name(costCenter.getName()); + }else { + //递归设置成本中心 + this.recursionInitCenter(entity, costCenterList, costCenter,6); + } + } + } + }else if ("bizRegion".equals(centerType)){ + BmsRegion region = regionMapper.selectById(centerId); + String[] regionIds = region.getPathIds().split("_"); + entity.setCenterLv1Id(regionIds[0]); + if(regionIds.length>1){ + entity.setCenterLv2Id(regionIds[1]); + } + }else if ("saleRegion".equals(centerType)){ + BmsRegion2 region = region2Mapper.selectById(centerId); + String[] regionIds = region.getPathIds().split("_"); + entity.setCenterLv1Id(regionIds[0]); + if(regionIds.length>1){ + entity.setCenterLv2Id(regionIds[1]); + } + }else{ + entity.setCenterLv1Id(centerId); + entity.setCenterLv1Code(centerCode); + entity.setCenterLv1Name(centerName); + } + } + + /** + * 递归设置成本中心 + * @param entity + * @param costCenterList + * @param costCenter + * @param maxLevel 循环最大层级 + */ + private void recursionInitCenter(BirActivityCenterGoods entity, + List costCenterList, + BmsCostCenter costCenter, + Integer maxLevel) { + maxLevel--; + for (BmsCostCenter nextTopCenter : costCenterList) { + if(nextTopCenter.getPid().equals(0L)){ + entity.setCenterLv1Id(nextTopCenter.getId().toString()); + entity.setCenterLv1Code(nextTopCenter.getCode()); + entity.setCenterLv1Name(nextTopCenter.getName()); + entity.setCenterLv2Id(costCenter.getId().toString()); + entity.setCenterLv2Code(costCenter.getCode()); + entity.setCenterLv2Name(costCenter.getName()); + return; + }else { + if(maxLevel<0){ + return; + } + this.recursionInitCenter(entity,costCenterList,nextTopCenter,maxLevel); + } + } + } + /** + * 获取项分割对象 + * @param activityCenterGoods + * @param dateSplitList + * @param currDateSplit + * @param currentActDays + * @param activityCheckAmt + * @return + */ + private BirCenterGoodSplitDTO buildSplitAmount(TbsActivityCenterGoods activityCenterGoods, + List dateSplitList , + DateSplitDTO currDateSplit, + Integer currentActDays){ + //活动相关 + BigDecimal activityAmt = activityCenterGoods.getActivityAmt(); + BigDecimal activityCheckAmt = activityCenterGoods.getActivityCheckAmt(); + //当前CenterGoods项金额 + BigDecimal centerGoodsAmount = activityCenterGoods.getCenterGoodsAmount(); + //当前CenterGoods分割项金额 + BigDecimal currentSplitAmount = activityCenterGoods.getCenterGoodsAmount(); + //当前CenterGoods项核销金额(粗略计算) + BigDecimal currentCheckAmount = activityCheckAmt + .multiply(activityCenterGoods.getCenterRate()) + .multiply(activityCenterGoods.getCenterGoodsRate()) + .divide(new BigDecimal("10000"),BigDecimal.ROUND_DOWN); + //当前CenterGoods分割项核销金额(粗略计算) + BigDecimal currentSplitCheckAmount = currentSplitAmount; + //日期占比 + BigDecimal dayRate = new BigDecimal(currDateSplit.getDays() + "") + .divide(new BigDecimal(currentActDays + ""), 2, BigDecimal.ROUND_HALF_DOWN); + // sort==size 最后一个节点 + if (currDateSplit.getSort().equals(dateSplitList.size())) { + for (DateSplitDTO splitDTO : dateSplitList) { + //跳过当前年月 + if (splitDTO.getYearMonth().equals(currDateSplit.getYearMonth())) { + continue; + } + currentSplitAmount = currentSplitAmount.subtract(centerGoodsAmount.multiply(dayRate)); + currentSplitCheckAmount = currentSplitCheckAmount.subtract(currentCheckAmount.multiply(dayRate)); + break; + } + } else { + currentSplitAmount = centerGoodsAmount.multiply(dayRate); + currentSplitCheckAmount = currentCheckAmount.multiply(dayRate); + } + BirCenterGoodSplitDTO goodSplitDTO = new BirCenterGoodSplitDTO(); + goodSplitDTO.setCurrentSplitAmount(currentSplitAmount); + goodSplitDTO.setCurrentSplitCheckAmount(currentSplitCheckAmount); + return goodSplitDTO; + } } diff --git a/src/main/java/com/qs/serve/modules/tbs/entity/TbsActivityCenterGoods.java b/src/main/java/com/qs/serve/modules/tbs/entity/TbsActivityCenterGoods.java index 0d5e79a6..30df6321 100644 --- a/src/main/java/com/qs/serve/modules/tbs/entity/TbsActivityCenterGoods.java +++ b/src/main/java/com/qs/serve/modules/tbs/entity/TbsActivityCenterGoods.java @@ -238,6 +238,17 @@ public class TbsActivityCenterGoods implements Serializable { @TableField(exist = false) private Long scheduleItemBudgetId; + /** 后台参数:用于生成BIR */ + @TableField(exist = false) + private BigDecimal activityAmt; + + /** 后台参数:用于生成BIR */ + @TableField(exist = false) + private BigDecimal activityCheckAmt; + + /** 后台参数:用于生成BIR */ + @TableField(exist = false) + private Integer activityFinishedFlag; public TbsBudgetCostItem toBudgetCostItem(){ TbsBudgetCostItem budgetCostItem = CopierUtil.copy(this,new TbsBudgetCostItem()); diff --git a/src/main/resources/mapper/bir/BirActivityCenterGoodsMapper.xml b/src/main/resources/mapper/bir/BirActivityCenterGoodsMapper.xml new file mode 100644 index 00000000..b1097f53 --- /dev/null +++ b/src/main/resources/mapper/bir/BirActivityCenterGoodsMapper.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + tbs_activity_center_goods.`id`, + tbs_activity_center_goods.`center_goods_code`, + tbs_activity_center_goods.`cost_apply_id`, + tbs_activity_center_goods.`activity_id`, + tbs_activity_center_goods.`activity_code`, + tbs_activity_center_goods.`subject_id`, + tbs_activity_center_goods.`subject_code`, + tbs_activity_center_goods.`subject_name`, + tbs_activity_center_goods.`center_type`, + tbs_activity_center_goods.`center_id`, + tbs_activity_center_goods.`center_code`, + tbs_activity_center_goods.`center_name`, + tbs_activity_center_goods.`center_amount`, + tbs_activity_center_goods.`center_rate`, + tbs_activity_center_goods.`center_goods_amount`, + tbs_activity_center_goods.`center_goods_rate`, + tbs_activity_center_goods.`used_amount`, + tbs_activity_center_goods.`target_type`, + tbs_activity_center_goods.`target_id`, + tbs_activity_center_goods.`target_code`, + tbs_activity_center_goods.`target_name`, + tbs_activity_center_goods.`target_level_path_ids`, + tbs_activity_center_goods.`target_level_path_names`, + tbs_activity_center_goods.`remark`, + tbs_activity_center_goods.`create_time`, + tbs_activity_center_goods.`update_time`, + tbs_activity_center_goods.`tenant_id`, + tbs_activity_center_goods.`create_by`, + tbs_activity_center_goods.`update_by`, + tbs_activity_center_goods.`del_flag`, + tbs_activity_center_goods.`act_start_date`, + tbs_activity_center_goods.`act_end_date`, + tbs_activity_center_goods.`pre_start_date`, + tbs_activity_center_goods.`pre_end_date`, + tbs_activity_center_goods.`pre_check_date`, + tbs_activity_center_goods.`tmp_uk`, + tbs_activity_center_goods.`supplier_id`, + tbs_activity_center_goods.`supplier_code`, + tbs_activity_center_goods.`supplier_name` + + + + + + +