10 changed files with 506 additions and 13 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) { |
|||
|
|||
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,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