From bfb82adb6532ba1ee5a6d87cbf08c4bcad2046af Mon Sep 17 00:00:00 2001 From: "15989082884@163.com" <15989082884@163.com> Date: Mon, 17 Jun 2024 15:24:00 +0800 Subject: [PATCH] =?UTF-8?q?BIR=E5=AE=A1=E6=89=B9=E8=BE=85=E5=8A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qs/serve/common/config/MyBatisConfig.java | 3 +- .../com/qs/serve/common/util/DateUtils.java | 6 + .../qs/serve/common/util/SqlServerUtil.java | 157 +++++ .../modules/base/ErpDataBaseService.java | 42 ++ .../bir/controller/BirRoiRateController.java | 22 +- .../modules/bir/entity/BirBudgetTarget.java | 79 ++- .../modules/bir/entity/BirCityTargetView.java | 227 +++++++ .../bir/entity/so/BirBudgetTargetSo.java | 4 + .../mapper/BirActivityCenterGoodsMapper.java | 2 +- .../bir/mapper/BirBudgetTargetMapper.java | 8 + .../bir/mapper/BirCityTargetViewMapper.java | 14 + .../service/BirBudgetTargetImportService.java | 24 + .../bir/service/BirCityTargetViewService.java | 14 + .../BirBudgetTargetImportServiceImpl.java | 586 ++++++++++++++++++ .../impl/BirBudgetTargetServiceImpl.java | 81 ++- .../impl/BirCityTargetViewServiceImpl.java | 22 + .../erp/entity/dto/ErpDispatchSumVo.java | 2 + .../erp/mapper/ErpDispatchDataMapper.java | 9 + .../java/com/qs/serve/task/BirRateTask.java | 29 + .../bir/BirActivityCenterGoodsMapper.xml | 46 ++ .../mapper/bir/BirBudgetTargetMapper.xml | 139 +++-- .../mapper/erp/ErpDispatchDataMapper.xml | 15 + 22 files changed, 1439 insertions(+), 92 deletions(-) create mode 100644 src/main/java/com/qs/serve/common/util/SqlServerUtil.java create mode 100644 src/main/java/com/qs/serve/modules/base/ErpDataBaseService.java create mode 100644 src/main/java/com/qs/serve/modules/bir/entity/BirCityTargetView.java create mode 100644 src/main/java/com/qs/serve/modules/bir/mapper/BirCityTargetViewMapper.java create mode 100644 src/main/java/com/qs/serve/modules/bir/service/BirBudgetTargetImportService.java create mode 100644 src/main/java/com/qs/serve/modules/bir/service/BirCityTargetViewService.java create mode 100644 src/main/java/com/qs/serve/modules/bir/service/impl/BirBudgetTargetImportServiceImpl.java create mode 100644 src/main/java/com/qs/serve/modules/bir/service/impl/BirCityTargetViewServiceImpl.java create mode 100644 src/main/java/com/qs/serve/task/BirRateTask.java diff --git a/src/main/java/com/qs/serve/common/config/MyBatisConfig.java b/src/main/java/com/qs/serve/common/config/MyBatisConfig.java index 453b0bf7..5dc0761a 100644 --- a/src/main/java/com/qs/serve/common/config/MyBatisConfig.java +++ b/src/main/java/com/qs/serve/common/config/MyBatisConfig.java @@ -46,7 +46,8 @@ public class MyBatisConfig { "wx_app", "sys_menu", "sys_menu_permit", - "sys_request_log" + "sys_request_log", + "bir_budget_target" }; SysTenantHandler sysTenantHandler = new SysTenantHandler(ignoreTable); return new TenantLineInnerInterceptor(sysTenantHandler); diff --git a/src/main/java/com/qs/serve/common/util/DateUtils.java b/src/main/java/com/qs/serve/common/util/DateUtils.java index cbb0f05e..86bf67a9 100644 --- a/src/main/java/com/qs/serve/common/util/DateUtils.java +++ b/src/main/java/com/qs/serve/common/util/DateUtils.java @@ -118,4 +118,10 @@ public class DateUtils { + value); } + public static int getQuarter(int month) { + if (month >= 1 && month <= 3) return 1; + else if (month >= 4 && month <= 6) return 2; + else if (month >= 7 && month <= 9) return 3; + else return 4; + } } diff --git a/src/main/java/com/qs/serve/common/util/SqlServerUtil.java b/src/main/java/com/qs/serve/common/util/SqlServerUtil.java new file mode 100644 index 00000000..46b94ceb --- /dev/null +++ b/src/main/java/com/qs/serve/common/util/SqlServerUtil.java @@ -0,0 +1,157 @@ +package com.qs.serve.common.util; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.microsoft.sqlserver.jdbc.SQLServerBulkCopy; +import com.microsoft.sqlserver.jdbc.SQLServerBulkCopyOptions; +import com.sun.rowset.CachedRowSetImpl; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.type.JdbcType; +import org.springframework.beans.factory.annotation.Value; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.sql.*; +import java.util.List; + +/** + * SQL Server工具类 + * @author Trouble + * @version 1.0 + * @since 2024-04-25 15:00 + */ +@Slf4j +public class SqlServerUtil { + + /** + * 批量插入数据库 + * + * @param connectionUrl 数据库连接地址 + * @param list 要保存的对象集 + * @throws SQLException 插入对象失败 + */ + public static void batchInsert(String connectionUrl, List list) throws SQLException, IllegalAccessException { + long start = System.currentTimeMillis(); + String tableName = null; + //获取表名 + for (T t : list) { + TableName tableNameAnnotation = t.getClass().getAnnotation(TableName.class); + tableName = tableNameAnnotation.value(); + break; + } + + CachedRowSetImpl crs = getCachedRowSet(connectionUrl, tableName); + // 将对象转化为行数据 + for (Object obj : list) { + // 以动指针到插入行(虚拟行) + crs.moveToInsertRow(); + // 设置虚拟行相应的字段与数值;注意:字符串中的字段名与类型要与数据表中的一致 + Field[] declaredFields = obj.getClass().getDeclaredFields(); + for (Field field : declaredFields) { + + if(field.getName().equals("serialVersionUID")){ + continue; + } + + field.setAccessible(true); + + TableField tableField = field.getAnnotation(TableField.class); + String fieldName; + // 如果字段名不存在,则跳过 + // 如果字段名为空,则使用默认字段名称 + if (tableField != null) { + if (!tableField.exist()) { + continue; + } + fieldName = tableField.value(); + } else { + fieldName = field.getName(); + } + Object fieldValue = field.get(obj); + + if (tableField != null && tableField.jdbcType().equals(JdbcType.FLOAT)) { + crs.updateBigDecimal(fieldName, (BigDecimal) fieldValue); + } + else { + crs.updateObject(fieldName, fieldValue); + } + } + // 将虚拟行插入缓存 + crs.insertRow(); + // 将指针移动到当前行 + crs.moveToCurrentRow(); + } + saveRows(connectionUrl, tableName, crs, list.size()); + long end = System.currentTimeMillis(); + log.info("批量插入数据表{}成功,数量:{}条,耗时:{}ms", tableName, list.size(), end - start); + } + + /** + * 获取数据表的结构 + * + * @param url 链接对象 + * @param tableName 表名字 + * @return 数据表字段初始化的数据对象 + * @throws SQLException 数据表字段初始化失败 + */ + public static CachedRowSetImpl getCachedRowSet(String url, String tableName) throws SQLException { + // 链接方式固定(配置) + Connection con = connection(url); + String sql = String.format("select * from %s where 1 = 0", tableName); + // 执行sql语句封装 + PreparedStatement ps = con.prepareStatement(sql); + // 执行语句 + ResultSet rs = ps.executeQuery(); + // 创建行操作对象 + CachedRowSetImpl crs = new CachedRowSetImpl(); + // 设置表字段 + crs.populate(rs); + // 关闭流资源 + rs.close(); + // 关闭数据库链接 + con.close(); + // 返回含有表字段的行操作对象 + return crs; + } + + /** + * 连接数据库 + * + * @param connectionUrl 链接URL + * @return 链接对象 + * @throws SQLException 建立链接失败异常 + */ + public static Connection connection(String connectionUrl) throws SQLException { + return DriverManager.getConnection(connectionUrl); + } + + /** + * 将数据插入数据库 + * + * @param connectionUrl 数据库连接地址 + * @param tableName 数据表名称 + * @param crs 数据行操作对象 + * @param size 数据量 + * @throws SQLException 插入数据失败异常 + */ + public static void saveRows(String connectionUrl, String tableName, CachedRowSetImpl crs, int size) throws SQLException { + SQLServerBulkCopyOptions copyOptions = new SQLServerBulkCopyOptions(); + copyOptions.setKeepIdentity(true); + // 设置批量插入的数量 + copyOptions.setBatchSize(size); + // 开启事务 + copyOptions.setUseInternalTransaction(true); + // 配置url + SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(connectionUrl); + // 设置批量操作参数 + bulkCopy.setBulkCopyOptions(copyOptions); + // 设置要操作的表名 + bulkCopy.setDestinationTableName(tableName); + // 将数据保存到数据库 + bulkCopy.writeToServer(crs); + // 释放资源 + crs.close(); + // 释放资源 + bulkCopy.close(); + } +} diff --git a/src/main/java/com/qs/serve/modules/base/ErpDataBaseService.java b/src/main/java/com/qs/serve/modules/base/ErpDataBaseService.java new file mode 100644 index 00000000..80b0999a --- /dev/null +++ b/src/main/java/com/qs/serve/modules/base/ErpDataBaseService.java @@ -0,0 +1,42 @@ +package com.qs.serve.modules.base; + +import cn.hutool.crypto.digest.DigestUtil; +import com.qs.serve.common.util.HttpUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +/** + * @author YenHex + * @since 2024/1/26 + */ +@Slf4j +@Service +public class ErpDataBaseService { + + @Value("${spring.datasource.dynamic.datasource.qisheng.url}") + private String erpJslGroupDbUrl; + + @Value("${spring.datasource.dynamic.datasource.qisheng.username}") + private String erpJslGroupDbUsername; + + @Value("${spring.datasource.dynamic.datasource.qisheng.password}") + private String erpJslGroupDbPassword; + + + public static String erpJslGroupDbConnectionUrl; + + public static String getErpJslGroupDbConnectionUrl(){ + return erpJslGroupDbConnectionUrl; + } + + @PostConstruct + public void initErpJslGroupDbConnectionUrl() { + erpJslGroupDbConnectionUrl = this.erpJslGroupDbUrl + ";user=" + this.erpJslGroupDbUsername + ";password=" + this.erpJslGroupDbPassword; + } + +} diff --git a/src/main/java/com/qs/serve/modules/bir/controller/BirRoiRateController.java b/src/main/java/com/qs/serve/modules/bir/controller/BirRoiRateController.java index 20c9cad5..0e12fa7a 100644 --- a/src/main/java/com/qs/serve/modules/bir/controller/BirRoiRateController.java +++ b/src/main/java/com/qs/serve/modules/bir/controller/BirRoiRateController.java @@ -49,6 +49,7 @@ public class BirRoiRateController { private TbsActivityCenterMapper tbsActivityCenterMapper; private BirBaseActivityService birBaseActivityService; private BirBudgetTargetService birBudgetTargetService; + private BirBudgetTargetImportService birBudgetTargetImportService; /** * 测试 @@ -146,12 +147,31 @@ public class BirRoiRateController { * @return */ @RepeatSubmit - @PostMapping("/costYearMonthV2") + @GetMapping("/costYearMonthV2") public R> getCostRoiOfYearMonthV2(@RequestBody BirBudgetTargetSo query){ + boolean isRestBir = BirHttpUtil.isRestBir(); + if(isRestBir){ + return BirHttpUtil.get("/bir/roiRate/costYearMonthV2",query); + } List list = birBudgetTargetService.listVo(query); return R.ok(list); } + @PostMapping("/buildCustomerCost") + public R buildCustomerCost(){ + boolean isRestBir = BirHttpUtil.isRestBir(); + if(isRestBir){ + return BirHttpUtil.get("/bir/roiRate/buildCustomerCost"); + } + birBudgetTargetImportService.deleteAll(); + birBudgetTargetImportService.buildCustomerCost(); + birBudgetTargetImportService.buildCityCost(); + birBudgetTargetImportService.buildProCost(); + birBudgetTargetImportService.buildAreaCost(); + return R.ok(); + } + + /** * 获取成本中心费率 * @param costApplyId diff --git a/src/main/java/com/qs/serve/modules/bir/entity/BirBudgetTarget.java b/src/main/java/com/qs/serve/modules/bir/entity/BirBudgetTarget.java index ec0764fa..5310ba40 100644 --- a/src/main/java/com/qs/serve/modules/bir/entity/BirBudgetTarget.java +++ b/src/main/java/com/qs/serve/modules/bir/entity/BirBudgetTarget.java @@ -28,65 +28,102 @@ public class BirBudgetTarget implements Serializable { private static final long serialVersionUID = 1L; /** id */ - @TableId(type = IdType.AUTO) + @TableId(type = IdType.INPUT) private Long id; /** 搜索维度:0-客户;1-城市;2-省级经理;3-大区经理 */ + @TableField(value = "search_type") private Integer searchType; - /** 年份 */ + // 年份 + @TableField(value = "year_num") private Integer yearNum; - /** 季度 */ + // 季度 + @TableField(value = "quarter_num") private Integer quarterNum; - /** 月份 */ + // 月份 + @TableField(value = "month_num") private Integer monthNum; - /** 销售目标 */ + // 销售目标 + @TableField(value = "target_amt") private BigDecimal targetAmt; - /** 预算金额 */ + // 预算金额 + @TableField(value = "budget_amt") private BigDecimal budgetAmt; - /** 实际发货 */ + // 实际发货 + @TableField(value = "dispatch_amt") private BigDecimal dispatchAmt; - /** 去年同期发货 */ + // 去年同期发货 + @TableField(value = "last_year_dispatch_amt") private BigDecimal lastYearDispatchAmt; - /** 城+省费用 */ + // 城+省费用 + @TableField(value = "province_city_amt") private BigDecimal provinceCityAmt; - /** 城+省+区费用 */ + // 城+省+区费用 + @TableField(value = "province_city_region_amt") private BigDecimal provinceCityRegionAmt; - /** 实际总费用 */ + // 实际总费用 + @TableField(value = "total_real_amt") private BigDecimal totalRealAmt; + // 品牌ID + @TableField(value = "brand_id") private String brandId; - /** 品牌编码 */ - @Length(max = 255,message = "品牌编码长度不能超过255字") + // 品牌编码 + @TableField(value = "brand_code") + @Length(max = 255, message = "品牌编码长度不能超过255字") private String brandCode; - /** 品牌 */ - @Length(max = 255,message = "品牌长度不能超过255字") + // 品牌名称 + @TableField(value = "brand_name") + @Length(max = 255, message = "品牌长度不能超过255字") private String brandName; - /** 成本中心类型:saleRegion; bizRegion; costCenter; supplier */ - @Length(max = 255,message = "成本中心类型:saleRegion; bizRegion; costCenter; supplier长度不能超过255字") + // 客户ID + @TableField(value = "customer_id") + private String customerId; + + // 客户编码 + @TableField(value = "customer_code") + @Length(max = 255, message = "客户编码长度不能超过255字") + private String customerCode; + + // 客户名称 + @TableField(value = "customer_name") + @Length(max = 255, message = "客户长度不能超过255字") + private String customerName; + + // 成本中心类型:saleRegion; bizRegion; costCenter; supplier + @TableField(value = "center_type") + @Length(max = 255, message = "成本中心类型长度不能超过255字") private String centerType; + // 成本中心ID + @TableField(value = "center_id") private String centerId; - /** 成本中心编码 */ - @Length(max = 255,message = "成本中心编码长度不能超过255字") + // 成本中心编码 + @TableField(value = "center_code") + @Length(max = 255, message = "成本中心编码长度不能超过255字") private String centerCode; - /** 成本中心名 */ - @Length(max = 255,message = "成本中心名长度不能超过255字") + // 成本中心名称 + @TableField(value = "center_name") + @Length(max = 255, message = "成本中心名长度不能超过255字") private String centerName; + // 预算/目标 预算费用率 + @TableField(value = "rate") + private BigDecimal rate; } diff --git a/src/main/java/com/qs/serve/modules/bir/entity/BirCityTargetView.java b/src/main/java/com/qs/serve/modules/bir/entity/BirCityTargetView.java new file mode 100644 index 00000000..48798628 --- /dev/null +++ b/src/main/java/com/qs/serve/modules/bir/entity/BirCityTargetView.java @@ -0,0 +1,227 @@ +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-14 + */ +@Data +@TableName("bir_city_target_view") +public class BirCityTargetView implements Serializable { + + private static final long serialVersionUID = 1L; + + /** */ + @TableId(type = IdType.AUTO) + private Long id; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String region; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String regionProvince; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String regionCity; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String regionUser; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String regionUserId; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String regionProvinceUser; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String regionSales2Id; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String brand; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String category; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String m1; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String m2; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String m3; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String q1Target; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String m4; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String m5; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String m6; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String q2Target; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String m7; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String m8; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String m9; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String q3Target; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String m10; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String m11; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String m12; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String q4Target; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String yearTarget; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String q1Budget; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String q2Budget; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String q3Budget; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String q4Budget; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String yearBudget; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String yearRate; + + /** */ + private Long brandId; + + /** */ + private Long categoryId; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String regionId; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String cityId; + + /** */ + @Length(max = 255,message = "长度不能超过255字") + private String regionProvinceId; + + //0 city 1 省 2大区 + private Integer type; + + public static BirCityTargetView toNewObject(BirCityTargetView source){ + BirCityTargetView cityTargetView = new BirCityTargetView(); + cityTargetView.setId(source.getId()); + cityTargetView.setRegion(source.getRegion()); + cityTargetView.setRegionProvince(source.getRegionProvince()); + cityTargetView.setRegionCity(source.getRegionCity()); + cityTargetView.setRegionUser(source.getRegionUser()); + cityTargetView.setRegionUserId(source.getRegionUserId()); + cityTargetView.setRegionProvinceUser(source.getRegionProvinceUser()); + cityTargetView.setRegionSales2Id(source.getRegionSales2Id()); + cityTargetView.setBrand(source.getBrand()); + cityTargetView.setCategory(source.getCategory()); + cityTargetView.setM1(source.getM1()); + cityTargetView.setM2(source.getM2()); + cityTargetView.setM3(source.getM3()); + cityTargetView.setQ1Target(source.getQ1Target()); + cityTargetView.setM4(source.getM4()); + cityTargetView.setM5(source.getM5()); + cityTargetView.setM6(source.getM6()); + cityTargetView.setQ2Target(source.getQ2Target()); + cityTargetView.setM7(source.getM7()); + cityTargetView.setM8(source.getM8()); + cityTargetView.setM9(source.getM9()); + cityTargetView.setQ3Target(source.getQ3Target()); + cityTargetView.setM10(source.getM10()); + cityTargetView.setM11(source.getM11()); + cityTargetView.setM12(source.getM12()); + cityTargetView.setQ4Target(source.getQ4Target()); + cityTargetView.setYearTarget(source.getYearTarget()); + cityTargetView.setQ1Budget(source.getQ1Budget()); + cityTargetView.setQ2Budget(source.getQ2Budget()); + cityTargetView.setQ3Budget(source.getQ3Budget()); + cityTargetView.setQ4Budget(source.getQ4Budget()); + cityTargetView.setYearBudget(source.getYearBudget()); + cityTargetView.setYearRate(source.getYearRate()); + cityTargetView.setBrandId(source.getBrandId()); + cityTargetView.setCategoryId(source.getCategoryId()); + cityTargetView.setRegionId(source.getRegionId()); + cityTargetView.setCityId(source.getCityId()); + cityTargetView.setRegionProvinceId(source.getRegionProvinceId()); + return cityTargetView; + } + +} + diff --git a/src/main/java/com/qs/serve/modules/bir/entity/so/BirBudgetTargetSo.java b/src/main/java/com/qs/serve/modules/bir/entity/so/BirBudgetTargetSo.java index e5c1c1a6..42220dec 100644 --- a/src/main/java/com/qs/serve/modules/bir/entity/so/BirBudgetTargetSo.java +++ b/src/main/java/com/qs/serve/modules/bir/entity/so/BirBudgetTargetSo.java @@ -28,6 +28,10 @@ public class BirBudgetTargetSo { @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime yearMonthEnd; + private Integer yearStart; + private Integer yearEnd; + private Integer monthStart; + private Integer monthEnd; /** * 业务待定 */ 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 13af4519..f5fba225 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 @@ -38,7 +38,7 @@ public interface BirActivityCenterGoodsMapper extends BaseMapper listMonthCusCenterVo(@Param("query") BirMonthCusCenterSo param); - + List list4BirBudgetTarget(); } diff --git a/src/main/java/com/qs/serve/modules/bir/mapper/BirBudgetTargetMapper.java b/src/main/java/com/qs/serve/modules/bir/mapper/BirBudgetTargetMapper.java index b057cc21..fa11b816 100644 --- a/src/main/java/com/qs/serve/modules/bir/mapper/BirBudgetTargetMapper.java +++ b/src/main/java/com/qs/serve/modules/bir/mapper/BirBudgetTargetMapper.java @@ -1,10 +1,13 @@ package com.qs.serve.modules.bir.mapper; +import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.mybatisplus.annotation.InterceptorIgnore; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.qs.serve.common.model.consts.DSName; import com.qs.serve.modules.bir.entity.BirBudgetTarget; import com.qs.serve.modules.bir.entity.so.BirBudgetTargetSo; import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; import java.util.List; @@ -13,10 +16,15 @@ import java.util.List; * @author YenHex * @date 2024-06-04 */ +@DS(DSName.QiSheng) public interface BirBudgetTargetMapper extends BaseMapper { + @InterceptorIgnore(tenantLine = "1") List selectBirBudgetTargetList(@Param("query") BirBudgetTargetSo budgetTargetSo); + + @Update("truncate table bir_budget_target") + void deleteAllData(); } diff --git a/src/main/java/com/qs/serve/modules/bir/mapper/BirCityTargetViewMapper.java b/src/main/java/com/qs/serve/modules/bir/mapper/BirCityTargetViewMapper.java new file mode 100644 index 00000000..dd5bfaa5 --- /dev/null +++ b/src/main/java/com/qs/serve/modules/bir/mapper/BirCityTargetViewMapper.java @@ -0,0 +1,14 @@ +package com.qs.serve.modules.bir.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.qs.serve.modules.bir.entity.BirCityTargetView; + +/** + * Mapper + * @author YenHex + * @date 2024-06-14 + */ +public interface BirCityTargetViewMapper extends BaseMapper { + +} + diff --git a/src/main/java/com/qs/serve/modules/bir/service/BirBudgetTargetImportService.java b/src/main/java/com/qs/serve/modules/bir/service/BirBudgetTargetImportService.java new file mode 100644 index 00000000..2dc3a36c --- /dev/null +++ b/src/main/java/com/qs/serve/modules/bir/service/BirBudgetTargetImportService.java @@ -0,0 +1,24 @@ +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 BirBudgetTargetImportService extends IService { + + void buildCustomerCost(); + void buildCityCost(); + void buildProCost(); + void buildAreaCost(); + void deleteAll(); + +} + diff --git a/src/main/java/com/qs/serve/modules/bir/service/BirCityTargetViewService.java b/src/main/java/com/qs/serve/modules/bir/service/BirCityTargetViewService.java new file mode 100644 index 00000000..5c91b38b --- /dev/null +++ b/src/main/java/com/qs/serve/modules/bir/service/BirCityTargetViewService.java @@ -0,0 +1,14 @@ +package com.qs.serve.modules.bir.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.qs.serve.modules.bir.entity.BirCityTargetView; + +/** + * 服务接口 + * @author YenHex + * @date 2024-06-14 + */ +public interface BirCityTargetViewService extends IService { + +} + diff --git a/src/main/java/com/qs/serve/modules/bir/service/impl/BirBudgetTargetImportServiceImpl.java b/src/main/java/com/qs/serve/modules/bir/service/impl/BirBudgetTargetImportServiceImpl.java new file mode 100644 index 00000000..020c4dec --- /dev/null +++ b/src/main/java/com/qs/serve/modules/bir/service/impl/BirBudgetTargetImportServiceImpl.java @@ -0,0 +1,586 @@ +package com.qs.serve.modules.bir.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.qs.serve.common.util.*; +import com.qs.serve.modules.base.ErpDataBaseService; +import com.qs.serve.modules.bir.entity.BirActivityCenterGoods; +import com.qs.serve.modules.bir.entity.BirBudgetTarget; +import com.qs.serve.modules.bir.entity.BirCityTargetView; +import com.qs.serve.modules.bir.entity.so.BirBudgetTargetSo; +import com.qs.serve.modules.bir.entity.vo.BirBudgetTargetVo; +import com.qs.serve.modules.bir.mapper.BirActivityCenterGoodsMapper; +import com.qs.serve.modules.bir.mapper.BirBudgetTargetMapper; +import com.qs.serve.modules.bir.service.BirBudgetTargetImportService; +import com.qs.serve.modules.bir.service.BirBudgetTargetService; +import com.qs.serve.modules.bir.service.BirCityTargetViewService; +import com.qs.serve.modules.bms.entity.BmsRegion2; +import com.qs.serve.modules.bms.entity.BmsSupplier; +import com.qs.serve.modules.bms.service.BmsRegion2Service; +import com.qs.serve.modules.bms.service.BmsSupplierService; +import com.qs.serve.modules.erp.entity.dto.ErpDispatchSumVo; +import com.qs.serve.modules.erp.mapper.ErpDispatchDataMapper; +import com.qs.serve.modules.goods.entity.GoodsCategory; +import com.qs.serve.modules.goods.entity.GoodsSku; +import com.qs.serve.modules.goods.entity.GoodsSpu; +import com.qs.serve.modules.goods.service.GoodsCategoryService; +import com.qs.serve.modules.goods.service.GoodsSkuService; +import com.qs.serve.modules.goods.service.GoodsSpuService; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.sql.SQLException; +import java.time.LocalDateTime; +import java.time.temporal.TemporalAdjusters; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 服务实现类 + * @author YenHex + * @since 2024-06-04 + */ +@Slf4j +@Service +@AllArgsConstructor +public class BirBudgetTargetImportServiceImpl extends ServiceImpl implements BirBudgetTargetImportService { + + private BirActivityCenterGoodsMapper birActivityCenterGoodsMapper; + private GoodsSpuService goodsSpuService; + private GoodsSkuService goodsSkuService; + private GoodsCategoryService goodsCategoryService; + private ErpDispatchDataMapper erpDispatchDataMapper; + private BmsRegion2Service region2Service; + private BmsSupplierService bmsSupplierService; + private BirCityTargetViewService birCityTargetViewService; + + private BirBudgetTarget initTargetByBirCenterGoods(BirActivityCenterGoods item){ + BirBudgetTarget target = new BirBudgetTarget(); + target.setSearchType(0); + Integer keyNum = item.getKeyNum(); + initTargetDate(target,keyNum); + + //成本中心 + target.setCenterType(item.getCenterType()); + target.setCenterId(item.getCenterId()); + target.setCenterCode(item.getCenterCode()); + target.setCenterName(item.getCenterName()); + + //客户 + target.setCustomerId(item.getSupplierId()+""); + target.setCustomerCode(item.getSupplierCode()); + target.setCustomerName(item.getSupplierName()); + + + target.setTotalRealAmt(item.getSplitUsedAmount()); + + //品牌 + target.setBrandId(item.getTargetLevelPathIds()); + target.setBrandName(item.getTargetLevelPathNames()); + + target.setId(IdUtil.getSnowflakeNextId()); + + return target; + } + + private void initTargetDate(BirBudgetTarget target,Integer keyNum ){ + target.setYearNum(keyNum / 100); + target.setMonthNum(keyNum % 100); + target.setQuarterNum(DateUtils.getQuarter(target.getMonthNum())); + } + + public void buildCustomerCost() { + + List birActivityCenterGoodsList = birActivityCenterGoodsMapper.list4BirBudgetTarget(); + List targetList = birActivityCenterGoodsList.stream() + .map(item->initTargetByBirCenterGoods(item)).collect(Collectors.toList()); + + List brandIds = targetList.stream().map(a->a.getBrandId()).distinct().collect(Collectors.toList()); + + brandIds.stream().forEach(brandId->{ + LambdaQueryWrapper spuQueryWrapper = new LambdaQueryWrapper<>(); + spuQueryWrapper.select(GoodsSpu::getId); + spuQueryWrapper.eq(GoodsSpu::getCategoryFirst,brandId); + List goodsSpuList = goodsSpuService.list(spuQueryWrapper); + List spuIds = goodsSpuList.stream().map(a->a.getId()).collect(Collectors.toList()); + if(spuIds.size()==0){ + return; + } + LambdaQueryWrapper skuQueryWrapper = new LambdaQueryWrapper<>(); + skuQueryWrapper.in(GoodsSku::getSpuId,spuIds); + List goodsSkuList = goodsSkuService.list(skuQueryWrapper); + List skuCodes = goodsSkuList.stream().map(a->a.getSkuCode()).distinct().collect(Collectors.toList()); + List erpDispatchSumVos = erpDispatchDataMapper.querySumCost4BudgetTarger(skuCodes); + + Map erpDispatchSumMap = erpDispatchSumVos.stream() + .collect(Collectors.toMap( + vo -> vo.getYearMonth() + "_" + vo.getCustomerCode(), + ErpDispatchSumVo::getDispatchSumCost)); + + targetList.stream().forEach(item->{ + if(item.getBrandId().equals(brandId)){ + String key = (item.getYearNum()*100 + item.getMonthNum()) + "_" + item.getCustomerCode(); + if(erpDispatchSumMap.containsKey(key)){ + item.setDispatchAmt(erpDispatchSumMap.get(key)); + } + + String lastkey = ((item.getYearNum()-1)*100 + item.getMonthNum()) + "_" + item.getCustomerCode(); + if(erpDispatchSumMap.containsKey(lastkey)){ + item.setLastYearDispatchAmt(erpDispatchSumMap.get(lastkey)); + } + } + }); + }); + + try { + SqlServerUtil.batchInsert(ErpDataBaseService.getErpJslGroupDbConnectionUrl(),targetList); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + public void buildCityCost() { + + LambdaQueryWrapper supplierLambdaQueryWrapper = new LambdaQueryWrapper<>(); + supplierLambdaQueryWrapper.eq(BmsSupplier::getBookCode,"001"); + List bmsSupplierList = bmsSupplierService.list(supplierLambdaQueryWrapper); + + Map> supplierByRegionSec = bmsSupplierList.stream().filter(a->a.getRegion2Second()!=null) + .collect(Collectors.groupingBy(BmsSupplier::getRegion2Second)); + + List insertList = new ArrayList<>(); + + supplierByRegionSec.keySet().stream().forEach(region2Id->{ + + List supplierList = supplierByRegionSec.get(region2Id); + List customerIds = supplierList.stream().map(a->a.getId()).collect(Collectors.toList()); + //城市ID查目标 和 预算 + LambdaQueryWrapper cityTargetLambdaQueryWrapper = new LambdaQueryWrapper<>(); + cityTargetLambdaQueryWrapper.eq(BirCityTargetView::getCityId,region2Id); + cityTargetLambdaQueryWrapper.eq(BirCityTargetView::getType,0); + List birCityTagetList = birCityTargetViewService.list(cityTargetLambdaQueryWrapper); + if(birCityTagetList.size()==0){ + log.warn("没有找到城市,ID为"+region2Id); + return; + } + Map> cityTargetByBrand = + birCityTagetList.stream().collect(Collectors.groupingBy(BirCityTargetView::getBrandId)); + + cityTargetByBrand.keySet().stream().forEach(brandId->{ + List targetList = cityTargetByBrand.get(brandId); +// BigDecimal m1 = sumTargetData(targetList,"m1"); +// BigDecimal m2 = sumTargetData(targetList,"m2"); +// BigDecimal m3 = sumTargetData(targetList,"m3"); +// BigDecimal m4 = sumTargetData(targetList,"m4"); +// BigDecimal m5 = sumTargetData(targetList,"m5"); +// BigDecimal m6 = sumTargetData(targetList,"m6"); +// BigDecimal m7 = sumTargetData(targetList,"m7"); +// BigDecimal m8 = sumTargetData(targetList,"m8"); +// BigDecimal m9 = sumTargetData(targetList,"m9"); +// BigDecimal m10 = sumTargetData(targetList,"m10"); +// BigDecimal m11 = sumTargetData(targetList,"m11"); +// BigDecimal m12 = sumTargetData(targetList,"m12"); +// BigDecimal q1Budget = sumTargetData(targetList,"q1Budget"); +// BigDecimal q2Budget = sumTargetData(targetList,"q2Budget"); +// BigDecimal q3Budget = sumTargetData(targetList,"q3Budget"); +// BigDecimal q4Budget = sumTargetData(targetList,"q4Budget"); + BigDecimal yearTarget = sumTargetData(targetList,"yearTarget"); + BigDecimal yearBudget = sumTargetData(targetList,"yearBudget"); + BigDecimal yearRate; + if(yearTarget.compareTo(BigDecimal.ZERO)==0){ + yearRate = BigDecimal.ZERO; + }else{ + yearRate = yearBudget.divide(yearTarget, 4, BigDecimal.ROUND_HALF_UP); + } + + LambdaQueryWrapper birDataLambdaQueryWrapper = new LambdaQueryWrapper<>(); + birDataLambdaQueryWrapper.in(BirBudgetTarget::getCustomerId, customerIds); + birDataLambdaQueryWrapper.eq(BirBudgetTarget::getBrandId, brandId); + birDataLambdaQueryWrapper.eq(BirBudgetTarget::getYearNum, 2024); + birDataLambdaQueryWrapper.eq(BirBudgetTarget::getSearchType, 0); + + List data2024List = this.list(birDataLambdaQueryWrapper); + + Map> data2024MonMap = + data2024List.stream().collect(Collectors.groupingBy(BirBudgetTarget::getMonthNum)); + + data2024MonMap.keySet().stream().forEach(mon->{ +// for(int mon= 1;mon<=12;mon++) { + +// List dataList = this.list(birDataLambdaQueryWrapper); + List dataMonList = data2024MonMap.get(mon); + + Map> dataCenterMap = + dataMonList.stream().collect(Collectors.groupingBy(g->g.getCenterType()+"_"+g.getCenterId())); + + dataCenterMap.keySet().stream().forEach(centerKey->{ + List dataList = dataCenterMap.get(centerKey); + + BigDecimal dispatchAmt = dataList.stream().map(a -> a.getDispatchAmt()==null?BigDecimal.ZERO:a.getDispatchAmt()).reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal lastYearDispatchAmt = dataList.stream().map(a -> a.getLastYearDispatchAmt()==null?BigDecimal.ZERO:a.getLastYearDispatchAmt()).reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal totalRealAmt = dataList.stream().map(a -> a.getTotalRealAmt()==null?BigDecimal.ZERO:a.getTotalRealAmt()).reduce(BigDecimal.ZERO, BigDecimal::add); + BirBudgetTarget targetData = new BirBudgetTarget(); + + String[] centerType = centerKey.split("_"); + targetData.setCenterType(centerType[0]); + targetData.setCenterId(centerType[1]); + + targetData.setSearchType(1); + targetData.setId(IdUtil.getSnowflakeNextId()); + targetData.setBrandId(brandId + ""); + targetData.setYearNum(2024); + targetData.setMonthNum(mon); + targetData.setQuarterNum(DateUtils.getQuarter(mon)); + targetData.setDispatchAmt(dispatchAmt.setScale(2, RoundingMode.HALF_UP)); + targetData.setLastYearDispatchAmt(lastYearDispatchAmt.setScale(2, RoundingMode.HALF_UP)); + targetData.setTotalRealAmt(totalRealAmt.setScale(2, RoundingMode.HALF_UP)); + targetData.setTargetAmt(sumTargetData(targetList,"m"+mon).multiply(new BigDecimal(10000)).setScale(2, RoundingMode.HALF_UP)); + targetData.setBudgetAmt(sumTargetData(targetList,"q"+DateUtils.getQuarter(mon)+"Budget").multiply(new BigDecimal(10000)).setScale(2, RoundingMode.HALF_UP)); + targetData.setRate(yearRate); + targetData.setCustomerId(region2Id); + insertList.add(targetData); + }); + }); + }); + //得到品牌IDs 和 时间 + + //客户IDs和品牌IDs和 时间查实际费 + + }); + + try { + SqlServerUtil.batchInsert(ErpDataBaseService.getErpJslGroupDbConnectionUrl(),insertList); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + private BigDecimal sumTargetData(List targetList,String fieldName) { + if(targetList.size()==0){ + return BigDecimal.ZERO; + } + try { + Class clazz = targetList.get(0).getClass(); + Field field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + + BigDecimal target = targetList.stream().map(transaction -> { + try { + String fieldNameValue = (String) field.get(transaction); + if(fieldNameValue==null || !StringUtils.hasText(fieldNameValue)){ + return BigDecimal.ZERO; + } + return new BigDecimal(fieldNameValue); + } catch (NumberFormatException | IllegalAccessException e) { + e.printStackTrace(); + return BigDecimal.ZERO; + } + }).reduce(BigDecimal.ZERO, BigDecimal::add); + return target; + + } catch (NoSuchFieldException e) { + e.printStackTrace(); + return BigDecimal.ZERO; + } + } + + + public void buildProCost() { + + LambdaQueryWrapper supplierLambdaQueryWrapper = new LambdaQueryWrapper<>(); + supplierLambdaQueryWrapper.eq(BmsSupplier::getBookCode,"001"); + List bmsSupplierList = bmsSupplierService.list(supplierLambdaQueryWrapper); + + Map> supplierByRegionSec = bmsSupplierList.stream().filter(a->a.getRegionSecond()!=null) + .collect(Collectors.groupingBy(BmsSupplier::getRegionSecond)); + + List insertList = new ArrayList<>(); + + supplierByRegionSec.keySet().stream().forEach(region2Id->{ + + List supplierList = supplierByRegionSec.get(region2Id); + List customerIds = supplierList.stream().map(a->a.getId()).collect(Collectors.toList()); + //城市ID查目标 和 预算 + LambdaQueryWrapper cityTargetLambdaQueryWrapper = new LambdaQueryWrapper<>(); + cityTargetLambdaQueryWrapper.eq(BirCityTargetView::getRegionSales2Id,region2Id); + cityTargetLambdaQueryWrapper.eq(BirCityTargetView::getType,1); + List birCityTagetList = birCityTargetViewService.list(cityTargetLambdaQueryWrapper); + if(birCityTagetList.size()==0){ + log.warn("没有找到二级销售区域,ID为"+region2Id); + return; + } + Map> cityTargetByBrand = + birCityTagetList.stream().collect(Collectors.groupingBy(BirCityTargetView::getBrandId)); + + cityTargetByBrand.keySet().stream().forEach(brandId->{ + List targetList = cityTargetByBrand.get(brandId); +// BigDecimal m1 = sumTargetData(targetList,"m1"); +// BigDecimal m2 = sumTargetData(targetList,"m2"); +// BigDecimal m3 = sumTargetData(targetList,"m3"); +// BigDecimal m4 = sumTargetData(targetList,"m4"); +// BigDecimal m5 = sumTargetData(targetList,"m5"); +// BigDecimal m6 = sumTargetData(targetList,"m6"); +// BigDecimal m7 = sumTargetData(targetList,"m7"); +// BigDecimal m8 = sumTargetData(targetList,"m8"); +// BigDecimal m9 = sumTargetData(targetList,"m9"); +// BigDecimal m10 = sumTargetData(targetList,"m10"); +// BigDecimal m11 = sumTargetData(targetList,"m11"); +// BigDecimal m12 = sumTargetData(targetList,"m12"); +// BigDecimal q1Budget = sumTargetData(targetList,"q1Budget"); +// BigDecimal q2Budget = sumTargetData(targetList,"q2Budget"); +// BigDecimal q3Budget = sumTargetData(targetList,"q3Budget"); +// BigDecimal q4Budget = sumTargetData(targetList,"q4Budget"); + BigDecimal yearTarget = sumTargetData(targetList,"yearTarget"); + BigDecimal yearBudget = sumTargetData(targetList,"yearBudget"); + BigDecimal yearRate; + if(yearTarget.compareTo(BigDecimal.ZERO)==0){ + yearRate = BigDecimal.ZERO; + }else{ + yearRate = yearBudget.divide(yearTarget, 4, BigDecimal.ROUND_HALF_UP); + } + + LambdaQueryWrapper birDataLambdaQueryWrapper = new LambdaQueryWrapper<>(); + birDataLambdaQueryWrapper.in(BirBudgetTarget::getCustomerId, customerIds); + birDataLambdaQueryWrapper.eq(BirBudgetTarget::getBrandId, brandId); + birDataLambdaQueryWrapper.eq(BirBudgetTarget::getYearNum, 2024); + birDataLambdaQueryWrapper.eq(BirBudgetTarget::getSearchType, 0); + + List data2024List = this.list(birDataLambdaQueryWrapper); + + Map> data2024MonMap = + data2024List.stream().collect(Collectors.groupingBy(BirBudgetTarget::getMonthNum)); + + data2024MonMap.keySet().stream().forEach(mon->{ +// for(int mon= 1;mon<=12;mon++) { + +// List dataList = this.list(birDataLambdaQueryWrapper); + List dataMonList = data2024MonMap.get(mon); + + Map> dataCenterMap = + dataMonList.stream().collect(Collectors.groupingBy(g->g.getCenterType()+"_"+g.getCenterId())); + + dataCenterMap.keySet().stream().forEach(centerKey->{ + List dataList = dataCenterMap.get(centerKey); + + BigDecimal dispatchAmt = dataList.stream().map(a -> a.getDispatchAmt()==null?BigDecimal.ZERO:a.getDispatchAmt()).reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal lastYearDispatchAmt = dataList.stream().map(a -> a.getLastYearDispatchAmt()==null?BigDecimal.ZERO:a.getLastYearDispatchAmt()).reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal totalRealAmt = dataList.stream().map(a -> a.getTotalRealAmt()==null?BigDecimal.ZERO:a.getTotalRealAmt()).reduce(BigDecimal.ZERO, BigDecimal::add); + BirBudgetTarget targetData = new BirBudgetTarget(); + + String[] centerType = centerKey.split("_"); + targetData.setCenterType(centerType[0]); + targetData.setCenterId(centerType[1]); + + targetData.setSearchType(2); + targetData.setId(IdUtil.getSnowflakeNextId()); + targetData.setBrandId(brandId + ""); + targetData.setYearNum(2024); + targetData.setMonthNum(mon); + targetData.setQuarterNum(DateUtils.getQuarter(mon)); + targetData.setDispatchAmt(dispatchAmt.setScale(2, RoundingMode.HALF_UP)); + targetData.setLastYearDispatchAmt(lastYearDispatchAmt.setScale(2, RoundingMode.HALF_UP)); + targetData.setTotalRealAmt(totalRealAmt.setScale(2, RoundingMode.HALF_UP)); + targetData.setTargetAmt(sumTargetData(targetList,"m"+mon).multiply(new BigDecimal(10000)).setScale(2, RoundingMode.HALF_UP)); + targetData.setBudgetAmt(sumTargetData(targetList,"q"+DateUtils.getQuarter(mon)+"Budget").multiply(new BigDecimal(10000)).setScale(2, RoundingMode.HALF_UP)); + targetData.setRate(yearRate); + targetData.setCustomerId(region2Id); + insertList.add(targetData); + + LambdaUpdateWrapper birCustomerUpdateLambdaQueryWrapper = new LambdaUpdateWrapper<>(); + birCustomerUpdateLambdaQueryWrapper.set(BirBudgetTarget::getProvinceCityAmt,targetData.getTotalRealAmt()); + birCustomerUpdateLambdaQueryWrapper.eq(BirBudgetTarget::getYearNum,2024); + birCustomerUpdateLambdaQueryWrapper.eq(BirBudgetTarget::getMonthNum,mon); + birCustomerUpdateLambdaQueryWrapper.eq(BirBudgetTarget::getCenterType,centerType[0]); + birCustomerUpdateLambdaQueryWrapper.eq(BirBudgetTarget::getCenterId,centerType[1]); + birCustomerUpdateLambdaQueryWrapper.eq(BirBudgetTarget::getBrandId,brandId); + birCustomerUpdateLambdaQueryWrapper.eq(BirBudgetTarget::getSearchType,0); + birCustomerUpdateLambdaQueryWrapper.in(BirBudgetTarget::getCustomerId,customerIds); + this.update(birCustomerUpdateLambdaQueryWrapper); + }); + }); + }); + //得到品牌IDs 和 时间 + + //客户IDs和品牌IDs和 时间查实际费 + + }); + + try { + SqlServerUtil.batchInsert(ErpDataBaseService.getErpJslGroupDbConnectionUrl(),insertList); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + + public void buildAreaCost() { + + LambdaQueryWrapper supplierLambdaQueryWrapper = new LambdaQueryWrapper<>(); + supplierLambdaQueryWrapper.eq(BmsSupplier::getBookCode,"001"); + List bmsSupplierList = bmsSupplierService.list(supplierLambdaQueryWrapper); + + Map> supplierByRegionSec = bmsSupplierList.stream().filter(a->a.getRegionFirst()!=null) + .collect(Collectors.groupingBy(BmsSupplier::getRegionFirst)); + + List insertList = new ArrayList<>(); + + supplierByRegionSec.keySet().stream().forEach(region2Id->{ + + List supplierList = supplierByRegionSec.get(region2Id); + List customerIds = supplierList.stream().map(a->a.getId()).collect(Collectors.toList()); + //城市ID查目标 和 预算 + LambdaQueryWrapper cityTargetLambdaQueryWrapper = new LambdaQueryWrapper<>(); + cityTargetLambdaQueryWrapper.eq(BirCityTargetView::getRegionId,region2Id); + cityTargetLambdaQueryWrapper.eq(BirCityTargetView::getType,2); + List birCityTagetList = birCityTargetViewService.list(cityTargetLambdaQueryWrapper); + if(birCityTagetList.size()==0){ + log.warn("没有找到一级销售区域,ID为"+region2Id); + return; + } + Map> cityTargetByBrand = + birCityTagetList.stream().collect(Collectors.groupingBy(BirCityTargetView::getBrandId)); + + cityTargetByBrand.keySet().stream().forEach(brandId->{ + List targetList = cityTargetByBrand.get(brandId); +// BigDecimal m1 = sumTargetData(targetList,"m1"); +// BigDecimal m2 = sumTargetData(targetList,"m2"); +// BigDecimal m3 = sumTargetData(targetList,"m3"); +// BigDecimal m4 = sumTargetData(targetList,"m4"); +// BigDecimal m5 = sumTargetData(targetList,"m5"); +// BigDecimal m6 = sumTargetData(targetList,"m6"); +// BigDecimal m7 = sumTargetData(targetList,"m7"); +// BigDecimal m8 = sumTargetData(targetList,"m8"); +// BigDecimal m9 = sumTargetData(targetList,"m9"); +// BigDecimal m10 = sumTargetData(targetList,"m10"); +// BigDecimal m11 = sumTargetData(targetList,"m11"); +// BigDecimal m12 = sumTargetData(targetList,"m12"); +// BigDecimal q1Budget = sumTargetData(targetList,"q1Budget"); +// BigDecimal q2Budget = sumTargetData(targetList,"q2Budget"); +// BigDecimal q3Budget = sumTargetData(targetList,"q3Budget"); +// BigDecimal q4Budget = sumTargetData(targetList,"q4Budget"); + BigDecimal yearTarget = sumTargetData(targetList,"yearTarget"); + BigDecimal yearBudget = sumTargetData(targetList,"yearBudget"); + BigDecimal yearRate; + if(yearTarget.compareTo(BigDecimal.ZERO)==0){ + yearRate = BigDecimal.ZERO; + }else{ + yearRate = yearBudget.divide(yearTarget, 4, BigDecimal.ROUND_HALF_UP); + } + + LambdaQueryWrapper birDataLambdaQueryWrapper = new LambdaQueryWrapper<>(); + birDataLambdaQueryWrapper.in(BirBudgetTarget::getCustomerId, customerIds); + birDataLambdaQueryWrapper.eq(BirBudgetTarget::getBrandId, brandId); + birDataLambdaQueryWrapper.eq(BirBudgetTarget::getYearNum, 2024); + birDataLambdaQueryWrapper.eq(BirBudgetTarget::getSearchType, 0); + + List data2024List = this.list(birDataLambdaQueryWrapper); + + Map> data2024MonMap = + data2024List.stream().collect(Collectors.groupingBy(BirBudgetTarget::getMonthNum)); + + data2024MonMap.keySet().stream().forEach(mon->{ +// for(int mon= 1;mon<=12;mon++) { + +// List dataList = this.list(birDataLambdaQueryWrapper); + List dataMonList = data2024MonMap.get(mon); + + Map> dataCenterMap = + dataMonList.stream().collect(Collectors.groupingBy(g->g.getCenterType()+"_"+g.getCenterId())); + + dataCenterMap.keySet().stream().forEach(centerKey-> { + List dataList = dataCenterMap.get(centerKey); + + BigDecimal dispatchAmt = dataList.stream().map(a -> a.getDispatchAmt() == null ? BigDecimal.ZERO : a.getDispatchAmt()).reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal lastYearDispatchAmt = dataList.stream().map(a -> a.getLastYearDispatchAmt() == null ? BigDecimal.ZERO : a.getLastYearDispatchAmt()).reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal totalRealAmt = dataList.stream().map(a -> a.getTotalRealAmt() == null ? BigDecimal.ZERO : a.getTotalRealAmt()).reduce(BigDecimal.ZERO, BigDecimal::add); + BirBudgetTarget targetData = new BirBudgetTarget(); + + String[] centerType = centerKey.split("_"); + targetData.setCenterType(centerType[0]); + targetData.setCenterId(centerType[1]); + targetData.setSearchType(3); + targetData.setId(IdUtil.getSnowflakeNextId()); + targetData.setBrandId(brandId + ""); + targetData.setYearNum(2024); + targetData.setMonthNum(mon); + targetData.setQuarterNum(DateUtils.getQuarter(mon)); + targetData.setDispatchAmt(dispatchAmt.setScale(2, RoundingMode.HALF_UP)); + targetData.setLastYearDispatchAmt(lastYearDispatchAmt.setScale(2, RoundingMode.HALF_UP)); + targetData.setTotalRealAmt(totalRealAmt.setScale(2, RoundingMode.HALF_UP)); + targetData.setTargetAmt(sumTargetData(targetList, "m" + mon).multiply(new BigDecimal(10000)).setScale(2, RoundingMode.HALF_UP)); + targetData.setBudgetAmt(sumTargetData(targetList, "q" + DateUtils.getQuarter(mon) + "Budget").multiply(new BigDecimal(10000)).setScale(2, RoundingMode.HALF_UP)); + targetData.setRate(yearRate); + targetData.setCustomerId(region2Id); + insertList.add(targetData); + + LambdaUpdateWrapper birCustomerUpdateLambdaQueryWrapper = new LambdaUpdateWrapper<>(); + birCustomerUpdateLambdaQueryWrapper.set(BirBudgetTarget::getProvinceCityRegionAmt,targetData.getTotalRealAmt()); + birCustomerUpdateLambdaQueryWrapper.eq(BirBudgetTarget::getYearNum,2024); + birCustomerUpdateLambdaQueryWrapper.eq(BirBudgetTarget::getMonthNum,mon); + birCustomerUpdateLambdaQueryWrapper.eq(BirBudgetTarget::getCenterType,centerType[0]); + birCustomerUpdateLambdaQueryWrapper.eq(BirBudgetTarget::getCenterId,centerType[1]); + birCustomerUpdateLambdaQueryWrapper.eq(BirBudgetTarget::getBrandId,brandId); + birCustomerUpdateLambdaQueryWrapper.eq(BirBudgetTarget::getSearchType,0); + birCustomerUpdateLambdaQueryWrapper.in(BirBudgetTarget::getCustomerId,customerIds); + this.update(birCustomerUpdateLambdaQueryWrapper); + + }); + }); + }); + //得到品牌IDs 和 时间 + + //客户IDs和品牌IDs和 时间查实际费 + + }); + + try { + SqlServerUtil.batchInsert(ErpDataBaseService.getErpJslGroupDbConnectionUrl(),insertList); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + public void deleteAll(){ +// LambdaQueryWrapper birDataLambdaQueryWrapper = new LambdaQueryWrapper<>(); +// this.remove(birDataLambdaQueryWrapper); + this.getBaseMapper().deleteAllData(); + } + + public void setProviceCityAmt(){ + LambdaQueryWrapper birDataLambdaQueryWrapper = new LambdaQueryWrapper<>(); + birDataLambdaQueryWrapper.eq(BirBudgetTarget::getSearchType,2); + List proList = this.list(birDataLambdaQueryWrapper); + + Map> proMap = + proList.stream().collect(Collectors.groupingBy(BirBudgetTarget::getCustomerId)); + + proMap.keySet().stream().forEach(proCustomeId->{ + LambdaQueryWrapper cityTargetLambdaQueryWrapper = new LambdaQueryWrapper<>(); + cityTargetLambdaQueryWrapper.eq(BirCityTargetView::getRegionSales2Id,proCustomeId); + cityTargetLambdaQueryWrapper.eq(BirCityTargetView::getType,0); + List birCityTagetList = birCityTargetViewService.list(cityTargetLambdaQueryWrapper); + List cityIds = birCityTagetList.stream().map(a->a.getCityId()).distinct().collect(Collectors.toList()); + LambdaQueryWrapper birCityLambdaQueryWrapper = new LambdaQueryWrapper<>(); + birCityLambdaQueryWrapper.eq(BirBudgetTarget::getSearchType,1); + List cityList = this.list(birCityLambdaQueryWrapper); + }); + } +} \ No newline at end of file diff --git a/src/main/java/com/qs/serve/modules/bir/service/impl/BirBudgetTargetServiceImpl.java b/src/main/java/com/qs/serve/modules/bir/service/impl/BirBudgetTargetServiceImpl.java index 193fca36..19c7accb 100644 --- a/src/main/java/com/qs/serve/modules/bir/service/impl/BirBudgetTargetServiceImpl.java +++ b/src/main/java/com/qs/serve/modules/bir/service/impl/BirBudgetTargetServiceImpl.java @@ -4,6 +4,8 @@ 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 com.qs.serve.modules.bms.entity.BmsSupplier; +import com.qs.serve.modules.bms.service.BmsSupplierService; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -18,6 +20,7 @@ import java.time.LocalDateTime; import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalAdjusters; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -32,6 +35,8 @@ import java.util.stream.Collectors; @AllArgsConstructor public class BirBudgetTargetServiceImpl extends ServiceImpl implements BirBudgetTargetService { + private BmsSupplierService bmsSupplierService; + @Override public List listVo(BirBudgetTargetSo query) { query.setLoadType(query.getLoadType()+1); @@ -42,15 +47,37 @@ public class BirBudgetTargetServiceImpl extends ServiceImpl birBudgetTargets = baseMapper.selectBirBudgetTargetList(query); + query.setLoadType(0); + List birSupplierBudgetTargets = baseMapper.selectBirBudgetTargetList(query); + Map> listMap = birBudgetTargets.stream() .collect(Collectors.groupingBy(obj->obj.getYearNum()+"_"+obj.getMonthNum())); + Map> listSupplierMap = birSupplierBudgetTargets.stream() + .collect(Collectors.groupingBy(obj->obj.getYearNum()+"_"+obj.getMonthNum())); List budgetTargetVoList = new ArrayList<>(); @@ -66,14 +93,15 @@ public class BirBudgetTargetServiceImpl extends ServiceImpl endMonth.getMonthValue()){ continue; } - budgetTargetVoList.add(getBudgetTargetVo(listMap, m, y)); + budgetTargetVoList.add(getBudgetTargetVo(listMap,listSupplierMap, m, y)); } } return budgetTargetVoList; } - private BirBudgetTargetVo getBudgetTargetVo(Map> listMap, int month, int year) { + private BirBudgetTargetVo getBudgetTargetVo(Map> listMap,Map> listSupplierMap, int month, int year) { List mList = listMap.get(year +"_"+ month); + List sList = listSupplierMap.get(year +"_"+ month); BirBudgetTargetVo targetVo = new BirBudgetTargetVo(); targetVo.setYearNum(year); targetVo.setMonthNum(month); @@ -86,28 +114,47 @@ public class BirBudgetTargetServiceImpl extends ServiceImpla.getProvinceCityAmt()==null?BigDecimal.ZERO:a.getProvinceCityAmt()).reduce(BigDecimal.ZERO, BigDecimal::add); + targetVo.setProvinceCityAmt(cityRegionAmt); + BigDecimal provinceCityRegionAmt = sList.stream().map(a->a.getProvinceCityRegionAmt()==null?BigDecimal.ZERO:a.getProvinceCityRegionAmt()).reduce(BigDecimal.ZERO, BigDecimal::add); + targetVo.setProvinceCityRegionAmt(provinceCityRegionAmt); } //预算费率 = 预算费用/销售目标 - targetVo.setBudgetRate(targetVo.getBudgetAmt().divide(targetVo.getTargetAmt(),2, RoundingMode.DOWN)); - //发货达成率 = 实际发货/销售目标 - targetVo.setDispatchRate(targetVo.getDispatchAmt().divide(targetVo.getTargetAmt(),2, RoundingMode.DOWN)); + if(targetVo.getTargetAmt().compareTo(BigDecimal.ZERO)!=0) { + targetVo.setBudgetRate(targetVo.getBudgetAmt().divide(targetVo.getTargetAmt(), 2, RoundingMode.DOWN)); + //发货达成率 = 实际发货/销售目标 + targetVo.setDispatchRate(targetVo.getDispatchAmt().divide(targetVo.getTargetAmt(), 2, RoundingMode.DOWN)); + }else{ + targetVo.setBudgetRate(BigDecimal.ZERO); + targetVo.setDispatchRate(BigDecimal.ZERO); + } //(当前发货-去年同期发货)/去年同期发货 - targetVo.setLastYearGrowRate( - targetVo.getDispatchAmt() - .subtract(targetVo.getLastYearDispatchAmt()) - .divide(targetVo.getLastYearDispatchAmt(),2, RoundingMode.DOWN) - ); + if(targetVo.getLastYearDispatchAmt().compareTo(BigDecimal.ZERO)!=0) { + targetVo.setLastYearGrowRate( + targetVo.getDispatchAmt() + .subtract(targetVo.getLastYearDispatchAmt()) + .divide(targetVo.getLastYearDispatchAmt(), 2, RoundingMode.DOWN) + ); + }else{ + targetVo.setLastYearGrowRate(BigDecimal.ZERO); + } //实际费用率=实际费用/实际发货 - 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)); + if(targetVo.getDispatchAmt().compareTo(BigDecimal.ZERO)!=0) { + targetVo.setProvinceCityRate(targetVo.getProvinceCityAmt().divide(targetVo.getDispatchAmt(), 2, RoundingMode.DOWN)); + targetVo.setProvinceCityRegionRate(targetVo.getProvinceCityRegionAmt().divide(targetVo.getDispatchAmt(), 2, RoundingMode.DOWN)); + targetVo.setTotalRealRate(targetVo.getTotalRealAmt().divide(targetVo.getDispatchAmt(), 2, RoundingMode.DOWN)); + }else{ + targetVo.setProvinceCityRate(BigDecimal.ZERO); + targetVo.setProvinceCityRegionRate(BigDecimal.ZERO); + targetVo.setTotalRealRate(BigDecimal.ZERO); + } } return targetVo; } diff --git a/src/main/java/com/qs/serve/modules/bir/service/impl/BirCityTargetViewServiceImpl.java b/src/main/java/com/qs/serve/modules/bir/service/impl/BirCityTargetViewServiceImpl.java new file mode 100644 index 00000000..b9ce3fd1 --- /dev/null +++ b/src/main/java/com/qs/serve/modules/bir/service/impl/BirCityTargetViewServiceImpl.java @@ -0,0 +1,22 @@ +package com.qs.serve.modules.bir.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import com.qs.serve.modules.bir.entity.BirCityTargetView; +import com.qs.serve.modules.bir.service.BirCityTargetViewService; +import com.qs.serve.modules.bir.mapper.BirCityTargetViewMapper; + +/** + * 服务实现类 + * @author YenHex + * @since 2024-06-14 + */ +@Slf4j +@Service +@AllArgsConstructor +public class BirCityTargetViewServiceImpl extends ServiceImpl implements BirCityTargetViewService { + +} + diff --git a/src/main/java/com/qs/serve/modules/erp/entity/dto/ErpDispatchSumVo.java b/src/main/java/com/qs/serve/modules/erp/entity/dto/ErpDispatchSumVo.java index 362989f9..5b8f23f6 100644 --- a/src/main/java/com/qs/serve/modules/erp/entity/dto/ErpDispatchSumVo.java +++ b/src/main/java/com/qs/serve/modules/erp/entity/dto/ErpDispatchSumVo.java @@ -13,6 +13,8 @@ public class ErpDispatchSumVo { Integer yearMonth; + String customerCode; + BigDecimal dispatchSumCost; } diff --git a/src/main/java/com/qs/serve/modules/erp/mapper/ErpDispatchDataMapper.java b/src/main/java/com/qs/serve/modules/erp/mapper/ErpDispatchDataMapper.java index 6fa20428..e2258e3f 100644 --- a/src/main/java/com/qs/serve/modules/erp/mapper/ErpDispatchDataMapper.java +++ b/src/main/java/com/qs/serve/modules/erp/mapper/ErpDispatchDataMapper.java @@ -62,5 +62,14 @@ public interface ErpDispatchDataMapper extends BaseMapper { @Select("SELECT inv_code FROM `erp_dispatch_data` where `date` > #{lastTowMonth} and cus_code = #{cusCode}") List selectLast2MonthInvCode(@Param("lastTowMonth") LocalDate lastTowMonth,@Param("cusCode")String cusCode); + + /** + * 查询发货单合计 + * @param skuCodes + * @return + */ + @InterceptorIgnore(tenantLine = "1") + List querySumCost4BudgetTarger(@Param("skuCodes")List skuCodes); + } diff --git a/src/main/java/com/qs/serve/task/BirRateTask.java b/src/main/java/com/qs/serve/task/BirRateTask.java new file mode 100644 index 00000000..48c68298 --- /dev/null +++ b/src/main/java/com/qs/serve/task/BirRateTask.java @@ -0,0 +1,29 @@ +package com.qs.serve.task; + +import com.qs.serve.common.util.AuthContextUtils; +import com.qs.serve.modules.bir.mapper.BirReportAccountBookMapper; +import com.qs.serve.modules.bir.service.BirBudgetTargetImportService; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +/** + * @author YenHex + * @since 2023/7/14 + */ +@Slf4j +@Component +@AllArgsConstructor +@ConditionalOnProperty(value = "project.task", havingValue = "true") +public class BirRateTask { + + private final BirBudgetTargetImportService birBudgetTargetImportService; + + @Scheduled(cron="0 0 1 * * ?") + public void buildTempTable(){ + + } + +} diff --git a/src/main/resources/mapper/bir/BirActivityCenterGoodsMapper.xml b/src/main/resources/mapper/bir/BirActivityCenterGoodsMapper.xml index c4740025..1e609fd6 100644 --- a/src/main/resources/mapper/bir/BirActivityCenterGoodsMapper.xml +++ b/src/main/resources/mapper/bir/BirActivityCenterGoodsMapper.xml @@ -194,5 +194,51 @@ and key_num <=#{startDate} and key_num >=#{endDate} + + diff --git a/src/main/resources/mapper/bir/BirBudgetTargetMapper.xml b/src/main/resources/mapper/bir/BirBudgetTargetMapper.xml index dd9fd1da..c0cbd8dc 100644 --- a/src/main/resources/mapper/bir/BirBudgetTargetMapper.xml +++ b/src/main/resources/mapper/bir/BirBudgetTargetMapper.xml @@ -27,71 +27,108 @@ - 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` + 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 +