1、销售拉明细增加家装面材产品类型等
2、销售bi汇总销量销额增加工厂简称,维护经纬度 3、修改计算判断 4、修改防水涂料应收
This commit is contained in:
parent
9b3a659a6e
commit
d612cf8311
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -18,6 +18,7 @@ import org.json.JSONObject;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
@ -193,8 +194,10 @@ public class DataLinkUpController {
|
|||||||
}
|
}
|
||||||
if (tablename.equals("应收表")){
|
if (tablename.equals("应收表")){
|
||||||
LOGGER.info("开始执行应收的明细汇总");
|
LOGGER.info("开始执行应收的明细汇总");
|
||||||
syncService.querySourceDataYS(ccId, tableName, timeField, startDate, endDate, partitionField,
|
if ((!bkgs.equals("北新防水")) || (!bkgs.equals("北新涂料"))) {
|
||||||
fieldMappings, targetTable, jezd);
|
syncService.querySourceDataYS(ccId, tableName, timeField, startDate, endDate, partitionField,
|
||||||
|
fieldMappings, targetTable, jezd);
|
||||||
|
}
|
||||||
}else {
|
}else {
|
||||||
syncService.querySourceData(ccId, tableName, timeField, startDate, endDate, partitionField,
|
syncService.querySourceData(ccId, tableName, timeField, startDate, endDate, partitionField,
|
||||||
fieldMappings, targetTable, jezd);
|
fieldMappings, targetTable, jezd);
|
||||||
@ -266,7 +269,10 @@ public class DataLinkUpController {
|
|||||||
}else if ("采购".equals(ssyw)){
|
}else if ("采购".equals(ssyw)){
|
||||||
summaryService = new PurchaseDataSummaryServiceImpl();
|
summaryService = new PurchaseDataSummaryServiceImpl();
|
||||||
LOGGER.info("采购业务检测到,创建summaryService实例");
|
LOGGER.info("采购业务检测到,创建summaryService实例");
|
||||||
}else {
|
} else if ("运营".equals(ssyw)) {
|
||||||
|
// summaryService = new ProductionDataSyncServiceImpl();
|
||||||
|
LOGGER.info("运营业务检测到,创建summaryService实例");
|
||||||
|
} else {
|
||||||
LOGGER.error("{}没有汇总类",ssyw);
|
LOGGER.error("{}没有汇总类",ssyw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +289,7 @@ public class DataLinkUpController {
|
|||||||
summaryService.calculateSummary(dateRange, bo);
|
summaryService.calculateSummary(dateRange, bo);
|
||||||
LOGGER.info("完成一体化-销售数据汇总计算,BKGS: {}", bo.get("BKGS"));
|
LOGGER.info("完成一体化-销售数据汇总计算,BKGS: {}", bo.get("BKGS"));
|
||||||
|
|
||||||
saleCountDimension = new SaleCountDimensionImpl();
|
// saleCountDimension = new SaleCountDimensionImpl();
|
||||||
LOGGER.info("开始执行销售数据多维度汇总计算,BKGS: {}", bo.get("BKGS"));
|
LOGGER.info("开始执行销售数据多维度汇总计算,BKGS: {}", bo.get("BKGS"));
|
||||||
saleCountDimension.calculateSummary(dateRange, bo);
|
saleCountDimension.calculateSummary(dateRange, bo);
|
||||||
LOGGER.info("完成销售数据多维度汇总计算,BKGS: {}", bo.get("BKGS"));
|
LOGGER.info("完成销售数据多维度汇总计算,BKGS: {}", bo.get("BKGS"));
|
||||||
@ -343,7 +349,10 @@ public class DataLinkUpController {
|
|||||||
LocalDate date = LocalDate.parse(formattedDate, dateFormatter);
|
LocalDate date = LocalDate.parse(formattedDate, dateFormatter);
|
||||||
LocalDateTime startDateTime = date.atStartOfDay(); // 当天00:00:00
|
LocalDateTime startDateTime = date.atStartOfDay(); // 当天00:00:00
|
||||||
Date startDate = Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant());
|
Date startDate = Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant());
|
||||||
LOGGER.info("时间范围:{}-{}",startDate,endDate);
|
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
String startDateStr = simpleDateFormat.format(startDate)+" 00:00:00";
|
||||||
|
String endDateStr = simpleDateFormat.format(endDate)+" 23:59:59";
|
||||||
|
LOGGER.info("时间范围:{}-{}",startDateStr,endDateStr);
|
||||||
|
|
||||||
JSONArray configArray = new JSONArray(dataStr);
|
JSONArray configArray = new JSONArray(dataStr);
|
||||||
// 2. 转换为BO对象列表
|
// 2. 转换为BO对象列表
|
||||||
@ -370,12 +379,6 @@ public class DataLinkUpController {
|
|||||||
hzb = "BO_EU_BNBM_DATALINKUP_XS_YSL";
|
hzb = "BO_EU_BNBM_DATALINKUP_XS_YSL";
|
||||||
}
|
}
|
||||||
LOGGER.info("汇总板块数据——销售的接口");
|
LOGGER.info("汇总板块数据——销售的接口");
|
||||||
} else if ("运营".equals(ssyw)) {
|
|
||||||
dataSyncService = new ProductionDataSyncServiceImpl();
|
|
||||||
if ("原材料".equals(tablename)){
|
|
||||||
hzb = "BO_EU_DWS_ORDER_YCLXH_HZ";
|
|
||||||
}
|
|
||||||
LOGGER.info("汇总板块数据——运营的接口");
|
|
||||||
} else if ("采购".equals(ssyw)){
|
} else if ("采购".equals(ssyw)){
|
||||||
dataSyncService = new PurchaseDataSyncServiceImpl();
|
dataSyncService = new PurchaseDataSyncServiceImpl();
|
||||||
if ("采购单".equals(tablename)){
|
if ("采购单".equals(tablename)){
|
||||||
@ -388,11 +391,23 @@ public class DataLinkUpController {
|
|||||||
hzb = "BO_EU_CG_WLD_HZ";
|
hzb = "BO_EU_CG_WLD_HZ";
|
||||||
} else if ("入库单".equals(tablename)){
|
} else if ("入库单".equals(tablename)){
|
||||||
hzb = "BO_EU_DWD_ORDER_RKD_HZ";
|
hzb = "BO_EU_DWD_ORDER_RKD_HZ";
|
||||||
}else {
|
} else {
|
||||||
LOGGER.error("当前表没有汇总表");
|
LOGGER.error("当前表没有汇总表");
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
LOGGER.info("汇总板块数据——采购的接口");
|
LOGGER.info("汇总板块数据——采购的接口");
|
||||||
}else {
|
} else if ("运营".equals(ssyw)) {
|
||||||
|
dataSyncService = new ProductionDataSyncServiceImpl();
|
||||||
|
if ("生产入库".equals(tablename)) {
|
||||||
|
hzb = "BO_EU_BNBM_SCRK_HZ";
|
||||||
|
} else if ("生产出库".equals(tablename)) {
|
||||||
|
hzb = "BO_EU_BNBM_SCCK_HZ";
|
||||||
|
}else {
|
||||||
|
LOGGER.error("当前表没有汇总表");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
LOGGER.info("汇总板块数据——运营的接口");
|
||||||
|
} else {
|
||||||
LOGGER.error("{}当前表没有汇总表",ssyw);
|
LOGGER.error("{}当前表没有汇总表",ssyw);
|
||||||
return ro.err(ssyw+"当前表没有汇总表");
|
return ro.err(ssyw+"当前表没有汇总表");
|
||||||
}
|
}
|
||||||
@ -420,7 +435,7 @@ public class DataLinkUpController {
|
|||||||
String deleteSql = "DELETE FROM "+hzb+" WHERE BKGS = '"+bkgs+"'";
|
String deleteSql = "DELETE FROM "+hzb+" WHERE BKGS = '"+bkgs+"'";
|
||||||
int deletedCount = DBSql.update(deleteSql);
|
int deletedCount = DBSql.update(deleteSql);
|
||||||
LOGGER.info("已删除目标表["+hzb+"]中{}条数据(时间范围: {} - {}),耗时:{}ms",
|
LOGGER.info("已删除目标表["+hzb+"]中{}条数据(时间范围: {} - {}),耗时:{}ms",
|
||||||
deletedCount, startDate, endDate, System.currentTimeMillis() - deleteStartTime);
|
deletedCount, startDateStr, endDateStr, System.currentTimeMillis() - deleteStartTime);
|
||||||
}
|
}
|
||||||
// 根据时间范围增加数据分页查询数据存储到BO_EU_BNBM_DATALINKUP_XS_XSL_HZ
|
// 根据时间范围增加数据分页查询数据存储到BO_EU_BNBM_DATALINKUP_XS_XSL_HZ
|
||||||
// 全量分页迁移数据到汇总表
|
// 全量分页迁移数据到汇总表
|
||||||
@ -440,10 +455,11 @@ public class DataLinkUpController {
|
|||||||
// 按时间范围删除
|
// 按时间范围删除
|
||||||
for (String bkgs : bkgsArr) {
|
for (String bkgs : bkgsArr) {
|
||||||
String deleteSql = "DELETE FROM " + hzb +
|
String deleteSql = "DELETE FROM " + hzb +
|
||||||
" WHERE BKGS = '"+bkgs+"' AND " + targetTimeField + " BETWEEN ? AND ?";
|
" WHERE BKGS = '"+bkgs+"' AND " + targetTimeField + " >= ? ";
|
||||||
int deletedCount = DBSql.update(deleteSql, new Object[]{startDate, endDate});
|
LOGGER.info("deleteSql:{}",deleteSql);
|
||||||
|
int deletedCount = DBSql.update(deleteSql, new Object[]{startDateStr});
|
||||||
LOGGER.info("已删除目标表["+hzb+"]中{}条数据(时间范围: {} - {})",
|
LOGGER.info("已删除目标表["+hzb+"]中{}条数据(时间范围: {} - {})",
|
||||||
deletedCount, startDate, endDate);
|
deletedCount, startDateStr, endDateStr);
|
||||||
}
|
}
|
||||||
// 根据时间范围增加数据分页查询数据存储到BO_EU_BNBM_DATALINKUP_XS_XSL_HZ
|
// 根据时间范围增加数据分页查询数据存储到BO_EU_BNBM_DATALINKUP_XS_XSL_HZ
|
||||||
// 按时间范围分页迁移数据到汇总表
|
// 按时间范围分页迁移数据到汇总表
|
||||||
|
|||||||
@ -22,7 +22,7 @@ import java.util.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @ClassName: WaterproofPaintAccountsReceivableJob
|
* @ClassName: WaterproofPaintAccountsReceivableJob
|
||||||
* @Description: 防水涂料计算应收单 - 多线程版本
|
* @Description: 防水涂料计算应收单 - 每月最大日期版本(月末按昨天查询)
|
||||||
* @date: 2025/8/29 16:38
|
* @date: 2025/8/29 16:38
|
||||||
* @Blog: https://
|
* @Blog: https://
|
||||||
*/
|
*/
|
||||||
@ -34,8 +34,6 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
private static final String DEFAULT_BKGS_FS = "北新防水";
|
private static final String DEFAULT_BKGS_FS = "北新防水";
|
||||||
private static final String DEFAULT_BKGS_TL = "北新涂料";
|
private static final String DEFAULT_BKGS_TL = "北新涂料";
|
||||||
private static final int BATCH_SIZE = 1000;
|
private static final int BATCH_SIZE = 1000;
|
||||||
private static final int THREAD_POOL_SIZE = 2; // 线程池大小,根据需求调整
|
|
||||||
// 板块配置
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(JobExecutionContext job) throws JobExecutionException {
|
public void execute(JobExecutionContext job) throws JobExecutionException {
|
||||||
@ -52,6 +50,7 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
startDate = nowDate.minusYears(1).withDayOfYear(1);
|
startDate = nowDate.minusYears(1).withDayOfYear(1);
|
||||||
}
|
}
|
||||||
LOGGER.info("开始执行防水涂料应收单计算任务,时间范围:{} 到 {}", startDate, nowDate);
|
LOGGER.info("开始执行防水涂料应收单计算任务,时间范围:{} 到 {}", startDate, nowDate);
|
||||||
|
|
||||||
// 依次处理防水和涂料两个板块
|
// 依次处理防水和涂料两个板块
|
||||||
boolean allSuccess = true;
|
boolean allSuccess = true;
|
||||||
for (Section section : Section.values()) {
|
for (Section section : Section.values()) {
|
||||||
@ -64,13 +63,14 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
if (!allSuccess) {
|
if (!allSuccess) {
|
||||||
throw new JobExecutionException("部分板块处理失败");
|
throw new JobExecutionException("部分板块处理失败");
|
||||||
}
|
}
|
||||||
LOGGER.info("防水涂料应收单计算任务完成,共处理 {} 天数据", nowDate.toEpochDay() - startDate.toEpochDay() + 1);
|
LOGGER.info("防水涂料应收单计算任务完成");
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.error("执行防水涂料应收单计算任务时发生错误", e);
|
LOGGER.error("执行防水涂料应收单计算任务时发生错误", e);
|
||||||
throw new JobExecutionException("任务执行失败", e);
|
throw new JobExecutionException("任务执行失败", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理单个板块的数据
|
* 处理单个板块的数据
|
||||||
* @param section 板块配置
|
* @param section 板块配置
|
||||||
@ -82,24 +82,17 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
String sectionName = section.getName();
|
String sectionName = section.getName();
|
||||||
LOGGER.info("开始处理{}板块数据,时间范围:{} 到 {}", sectionName, startDate, nowDate);
|
LOGGER.info("开始处理{}板块数据,时间范围:{} 到 {}", sectionName, startDate, nowDate);
|
||||||
|
|
||||||
// 每个板块使用独立的缓存
|
|
||||||
Map<String, Map<LocalDate, BigDecimal>> historicalBalanceCache = new HashMap<>();
|
|
||||||
// 新增缓存用于存储每日的累计值
|
|
||||||
Map<String, BigDecimal> previousLjxsCache = new HashMap<>(); // 缓存前一天的累计销售
|
|
||||||
Map<String, BigDecimal> previousLjhkCache = new HashMap<>(); // 缓存前一天的累计还款
|
|
||||||
Map<String, BigDecimal> qcyeCache = new HashMap<>(); // 缓存期初余额(每个客户只需计算一次)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 开始清理开始时间到结束时间的数据后再进行计算更新数据
|
// 开始清理开始时间到结束时间的数据后再进行计算更新数据
|
||||||
String startDateFormat = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
String startDateFormat = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 00:00:00";
|
||||||
String nowDateFormat = nowDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
String nowDateFormat = nowDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 23:59:59";
|
||||||
int delete = DBSql.update("DELETE FROM " + section.getTargetTable() +
|
int delete = DBSql.update("DELETE FROM " + section.getTargetTable() +
|
||||||
" WHERE RQ BETWEEN '" + startDateFormat + "' AND '" + nowDateFormat + "'");
|
" WHERE RQ >= '" + startDateFormat + "' ");
|
||||||
LOGGER.info("已删除目标表[{}]中{}条数据(时间范围: {} - {})",
|
LOGGER.info("已删除目标表[{}]中{}条数据(时间范围: {} )",
|
||||||
section.getTargetTable(), delete, startDateFormat, nowDateFormat);
|
section.getTargetTable(), delete, startDateFormat);
|
||||||
|
|
||||||
// 查询销售组织和客户分组信息
|
// 查询销售组织和客户分组信息
|
||||||
List<RowMap> maps = DBSql.getMaps("SELECT QYGS, FCUSTNAME, SQ AS FPROVINCE,CS AS FCITY FROM " +
|
List<RowMap> maps = DBSql.getMaps("SELECT QYGS, FCUSTNAME, SQ AS FPROVINCE,CS AS FCITY,QY AS FDISTRICT ,XSZZ FROM " +
|
||||||
section.getYsdTable() + " WHERE QYGS IS NOT NULL GROUP BY QYGS, FCUSTNAME, SQ,CS");
|
section.getYsdTable() + " WHERE QYGS IS NOT NULL GROUP BY QYGS, FCUSTNAME, SQ,CS");
|
||||||
|
|
||||||
if (maps == null || maps.isEmpty()) {
|
if (maps == null || maps.isEmpty()) {
|
||||||
@ -113,80 +106,60 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
List<BO> batchData = new ArrayList<>();
|
List<BO> batchData = new ArrayList<>();
|
||||||
int processedCount = 0;
|
int processedCount = 0;
|
||||||
|
|
||||||
// 遍历日期范围
|
// 获取每个月的最大日期(月末日期)
|
||||||
for (LocalDate currentDate = startDate; !currentDate.isAfter(nowDate); currentDate = currentDate.plusDays(1)) {
|
List<LocalDate> monthEndDates = getMonthEndDates(startDate, nowDate);
|
||||||
LOGGER.debug("{}板块正在处理日期: {}", sectionName, currentDate);
|
LOGGER.info("{}板块将处理 {} 个月末日期", sectionName, monthEndDates.size());
|
||||||
|
|
||||||
|
// 遍历每个月末日期
|
||||||
|
for (LocalDate monthEndDate : monthEndDates) {
|
||||||
|
LOGGER.info("{}板块正在处理月末日期: {}", sectionName, monthEndDate);
|
||||||
|
|
||||||
|
// 计算该月的日期范围(月初到月末或昨天)
|
||||||
|
LocalDate monthStartDate = monthEndDate.withDayOfMonth(1);
|
||||||
|
LocalDate monthEnd = monthEndDate;
|
||||||
|
int i =0;
|
||||||
// 遍历每个销售组织-客户组合
|
// 遍历每个销售组织-客户组合
|
||||||
for (RowMap row : maps) {
|
for (RowMap row : maps) {
|
||||||
|
if (i==1){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
try {
|
try {
|
||||||
String manageRegionName = row.getString("QYGS");
|
String manageRegionName = row.getString("QYGS");
|
||||||
String saleOrgUnit = row.getString("XSZZ");
|
String saleOrgUnit = row.getString("XSZZ");
|
||||||
String custName = row.getString("FCUSTNAME");
|
String custName = row.getString("FCUSTNAME");
|
||||||
|
// LOGGER.info("manageRegionName:{};saleOrgUnit:{},custName:{}",manageRegionName,saleOrgUnit,custName);
|
||||||
|
|
||||||
// 查询省市区信息
|
// 查询省市区信息
|
||||||
String province = row != null ? row.getString("FPROVINCE") : "";
|
String province = row != null ? row.getString("FPROVINCE") : "";
|
||||||
String city = row != null ? row.getString("FCITY") : "";
|
String city = row != null ? row.getString("FCITY") : "";
|
||||||
String district = row != null ? row.getString("FDISTRICT")!=null ? row.getString("FDISTRICT"):"": "";
|
String district = row != null ? row.getString("FDISTRICT")!=null ? row.getString("FDISTRICT"):"": "";
|
||||||
|
|
||||||
String cacheKey = saleOrgUnit + "_" + custName;
|
// 计算期初余额(上一年度)
|
||||||
|
LocalDate previousYearStart = monthStartDate.minusYears(1).withDayOfYear(1);
|
||||||
|
LocalDate previousYearEnd = monthStartDate.minusYears(1).withDayOfYear(365);
|
||||||
|
BigDecimal qcye = calculateInitialBalance(section, saleOrgUnit, custName, previousYearStart, previousYearEnd);
|
||||||
|
|
||||||
// 计算期初余额(上一年度)- 每个客户只需计算一次
|
// 计算累计销售(本年年初到查询截止日期)
|
||||||
BigDecimal qcye;
|
LocalDate yearStart = monthStartDate.withDayOfYear(1);
|
||||||
if (currentDate.equals(startDate)) {
|
BigDecimal ljxs = calculateTotalSales(section, saleOrgUnit, custName, monthEndDate, monthEnd);
|
||||||
LocalDate previousYearStart = currentDate.minusYears(1).withDayOfYear(1);
|
|
||||||
LocalDate previousYearEnd = currentDate.minusYears(1).withDayOfYear(365);
|
|
||||||
qcye = calculateInitialBalance(section, saleOrgUnit, custName, previousYearStart, previousYearEnd);
|
|
||||||
qcyeCache.put(cacheKey, qcye);
|
|
||||||
} else {
|
|
||||||
qcye = qcyeCache.get(cacheKey);
|
|
||||||
if (qcye == null) {
|
|
||||||
// 如果缓存中没有,说明之前没有计算过,则计算并缓存
|
|
||||||
LocalDate previousYearStart = currentDate.minusYears(1).withDayOfYear(1);
|
|
||||||
LocalDate previousYearEnd = currentDate.minusYears(1).withDayOfYear(365);
|
|
||||||
qcye = calculateInitialBalance(section, saleOrgUnit, custName, previousYearStart, previousYearEnd);
|
|
||||||
qcyeCache.put(cacheKey, qcye);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算当日销售
|
// 计算累计还款(本年年初到查询截止日期)
|
||||||
BigDecimal dailySales = calculateTotalSales(section, saleOrgUnit, custName, currentDate, currentDate);
|
BigDecimal ljhk = calculateTotalRepayment(section, saleOrgUnit, custName, monthEndDate, monthEnd);
|
||||||
// 计算当日还款
|
|
||||||
BigDecimal dailyRepayment = calculateTotalRepayment(section, saleOrgUnit, custName, currentDate, currentDate);
|
|
||||||
|
|
||||||
// 计算累计销售(本年年初到当前日期)- 使用增量方式
|
|
||||||
BigDecimal ljxs;
|
|
||||||
if (currentDate.equals(startDate)) {
|
|
||||||
// 第一天直接使用当日销售
|
|
||||||
ljxs = dailySales;
|
|
||||||
} else {
|
|
||||||
// 后续天数:前一天的累计销售 + 当日销售
|
|
||||||
BigDecimal previousLjxs = previousLjxsCache.getOrDefault(cacheKey, BigDecimal.ZERO);
|
|
||||||
ljxs = previousLjxs.add(dailySales);
|
|
||||||
}
|
|
||||||
previousLjxsCache.put(cacheKey, ljxs);
|
|
||||||
|
|
||||||
// 计算累计还款(本年年初到当前日期)- 使用增量方式
|
|
||||||
BigDecimal ljhk;
|
|
||||||
if (currentDate.equals(startDate)) {
|
|
||||||
// 第一天直接使用当日还款
|
|
||||||
ljhk = dailyRepayment;
|
|
||||||
} else {
|
|
||||||
// 后续天数:前一天的累计还款 + 当日还款
|
|
||||||
BigDecimal previousLjhk = previousLjhkCache.getOrDefault(cacheKey, BigDecimal.ZERO);
|
|
||||||
ljhk = previousLjhk.add(dailyRepayment);
|
|
||||||
}
|
|
||||||
previousLjhkCache.put(cacheKey, ljhk);
|
|
||||||
|
|
||||||
// 计算应收余额
|
// 计算应收余额
|
||||||
BigDecimal ysye = qcye.add(ljxs).subtract(ljhk);
|
BigDecimal ysye = qcye.add(ljxs).subtract(ljhk);
|
||||||
|
// LOGGER.info("计算应收余额={}",ysye.doubleValue());
|
||||||
|
|
||||||
// 计算账龄分析
|
// 计算账龄分析(需要查询历史数据)
|
||||||
Map<String, BigDecimal> zlfx = calculateAgingAnalysis(historicalBalanceCache, saleOrgUnit, custName, currentDate, ysye);
|
Map<String, BigDecimal> zlfx = calculateMonthlyAgingAnalysis(section, saleOrgUnit, custName, monthEndDate, ysye);
|
||||||
|
// for (String key: zlfx.keySet()){
|
||||||
|
// LOGGER.info("账龄-{}={}",key,zlfx.get(key));
|
||||||
|
// }
|
||||||
|
|
||||||
// 创建数据记录
|
// 创建数据记录(记录日期仍使用月末日期)
|
||||||
BO record = createRecord(
|
BO record = createRecord(
|
||||||
section, manageRegionName, saleOrgUnit, currentDate, custName,
|
section, manageRegionName, saleOrgUnit, monthEndDate, custName,
|
||||||
province, city, district, qcye, ljxs, ljhk, ysye, zlfx
|
province, city, district, qcye, ljxs, ljhk, ysye, zlfx
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -198,9 +171,6 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
batchData.clear();
|
batchData.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新历史余额缓存,用于后续账龄分析
|
|
||||||
updateHistoricalBalanceCache(historicalBalanceCache, saleOrgUnit, custName, currentDate, ysye);
|
|
||||||
|
|
||||||
// 更新处理计数
|
// 更新处理计数
|
||||||
processedCount++;
|
processedCount++;
|
||||||
if (processedCount % 1000 == 0) {
|
if (processedCount % 1000 == 0) {
|
||||||
@ -208,8 +178,8 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.error("{}板块处理销售组织 {} 客户 {} 日期 {} 时发生错误",
|
LOGGER.error("{}板块处理销售组织 {} 客户 {} 月末日期 {} 时发生错误",
|
||||||
sectionName, row.getString("FSaleOrgUnit"), row.getString("FCustName"), currentDate, e);
|
sectionName, row.getString("XSZZ"), row.getString("FCUSTNAME"), monthEndDate, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,18 +198,65 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为当前月月末
|
||||||
|
* @param monthEndDate 月末日期
|
||||||
|
* @param nowDate 当前日期
|
||||||
|
* @return 是否为当前月月末
|
||||||
|
*/
|
||||||
|
private boolean isCurrentMonthEnd(LocalDate monthEndDate, LocalDate nowDate) {
|
||||||
|
// 判断是否为当前月的月末,并且月末日期大于或等于当前日期
|
||||||
|
return monthEndDate.getMonth() == nowDate.getMonth() &&
|
||||||
|
monthEndDate.getYear() == nowDate.getYear() &&
|
||||||
|
monthEndDate.getDayOfMonth() == monthEndDate.lengthOfMonth() &&
|
||||||
|
monthEndDate.isAfter(nowDate.minusDays(1)); // 确保是当前月月末
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取时间范围内的所有月末日期
|
||||||
|
*/
|
||||||
|
private List<LocalDate> getMonthEndDates(LocalDate startDate, LocalDate endDate) {
|
||||||
|
List<LocalDate> monthEndDates = new ArrayList<>();
|
||||||
|
LocalDate current = startDate.withDayOfMonth(1);
|
||||||
|
while (!current.isAfter(endDate)) {
|
||||||
|
// 如果当前月份与endDate不是同年同月
|
||||||
|
if (current.getYear() != endDate.getYear() || current.getMonth() != endDate.getMonth()) {
|
||||||
|
LocalDate monthEnd = current.withDayOfMonth(current.lengthOfMonth());
|
||||||
|
// 确保月末日期在时间范围内
|
||||||
|
if (!monthEnd.isBefore(startDate) && !monthEnd.isAfter(endDate)) {
|
||||||
|
monthEndDates.add(monthEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果当前月份与endDate是同年同月
|
||||||
|
else {
|
||||||
|
LocalDate dayBeforeEnd = endDate.minusDays(1);
|
||||||
|
// 确保前一天在时间范围内
|
||||||
|
if (!dayBeforeEnd.isBefore(startDate)) {
|
||||||
|
monthEndDates.add(dayBeforeEnd);
|
||||||
|
}
|
||||||
|
break; // 遇到同年同月后就可以结束循环了
|
||||||
|
}
|
||||||
|
current = current.plusMonths(1);
|
||||||
|
}
|
||||||
|
return monthEndDates;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算期初余额
|
* 计算期初余额
|
||||||
*/
|
*/
|
||||||
private BigDecimal calculateInitialBalance(Section section, String saleOrgUnit, String custName,
|
private BigDecimal calculateInitialBalance(Section section, String saleOrgUnit, String custName,
|
||||||
LocalDate startDate, LocalDate endDate) {
|
LocalDate startDate, LocalDate endDate) {
|
||||||
|
String startDateStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 00:00:00";
|
||||||
|
String endDateStr = endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 23:59:59";
|
||||||
try {
|
try {
|
||||||
// 查询应收单总额
|
// 查询应收单总额
|
||||||
RowMap ysResult = DBSql.getMap(
|
RowMap ysResult = DBSql.getMap(
|
||||||
"SELECT SUM(SSJERMB) as total FROM " + section.getYsdTable() +
|
"SELECT SUM(SSJERMB) as total FROM " + section.getYsdTable() +
|
||||||
" WHERE XSZZ = ? AND FCUSTNAME = ? AND DZRQ BETWEEN ? AND ?",
|
" WHERE XSZZ = ? AND FCUSTNAME = ? AND DZRQ >= ? AND DZRQ< ?",
|
||||||
saleOrgUnit, custName, java.sql.Date.valueOf(startDate), java.sql.Date.valueOf(endDate)
|
saleOrgUnit, custName, startDateStr, endDateStr
|
||||||
);
|
);
|
||||||
|
LOGGER.info("期初余额-应收单总额sql:SELECT SUM(SSJERMB) as total FROM " + section.getYsdTable() +
|
||||||
|
" WHERE XSZZ = "+saleOrgUnit+" AND FCUSTNAME = "+custName+" AND DZRQ >= "+startDateStr+" AND DZRQ< "+endDateStr+"");
|
||||||
|
|
||||||
BigDecimal ysTotal = ysResult != null && ysResult.get("total") != null ?
|
BigDecimal ysTotal = ysResult != null && ysResult.get("total") != null ?
|
||||||
new BigDecimal(ysResult.get("total").toString()) : BigDecimal.ZERO;
|
new BigDecimal(ysResult.get("total").toString()) : BigDecimal.ZERO;
|
||||||
@ -247,9 +264,11 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
// 查询收款单总额
|
// 查询收款单总额
|
||||||
RowMap skResult = DBSql.getMap(
|
RowMap skResult = DBSql.getMap(
|
||||||
"SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSkdTable() +
|
"SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSkdTable() +
|
||||||
" WHERE FSALEORGUNIT = ? AND FCUSTNAME = ? AND FBILLDATE BETWEEN ? AND ?",
|
" WHERE FSALEORGUNIT = ? AND FCUSTNAME = ? AND FBILLDATE >= ? AND FBILLDATE < ?",
|
||||||
saleOrgUnit, custName, java.sql.Date.valueOf(startDate), java.sql.Date.valueOf(endDate)
|
saleOrgUnit, custName, startDateStr, endDateStr
|
||||||
);
|
);
|
||||||
|
LOGGER.info("期初余额-收款单总额sql:SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSkdTable() +
|
||||||
|
" WHERE FSALEORGUNIT = "+saleOrgUnit+" AND FCUSTNAME = "+custName+" AND FBILLDATE >= "+startDateStr+" AND FBILLDATE< "+endDateStr+"");
|
||||||
|
|
||||||
BigDecimal skTotal = skResult != null && skResult.get("total") != null ?
|
BigDecimal skTotal = skResult != null && skResult.get("total") != null ?
|
||||||
new BigDecimal(skResult.get("total").toString()) : BigDecimal.ZERO;
|
new BigDecimal(skResult.get("total").toString()) : BigDecimal.ZERO;
|
||||||
@ -257,13 +276,16 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
// 查询收款退款单总额
|
// 查询收款退款单总额
|
||||||
RowMap sktkResult = DBSql.getMap(
|
RowMap sktkResult = DBSql.getMap(
|
||||||
"SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSktkdTable() +
|
"SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSktkdTable() +
|
||||||
" WHERE FSALEORGUNIT = ? AND FCUSTNAME = ? AND FBILLDATE BETWEEN ? AND ?",
|
" WHERE FSALEORGUNIT = ? AND FCUSTNAME = ? AND FBILLDATE >= ? AND FBILLDATE < ?",
|
||||||
saleOrgUnit, custName, java.sql.Date.valueOf(startDate), java.sql.Date.valueOf(endDate)
|
saleOrgUnit, custName, startDateStr, endDateStr
|
||||||
);
|
);
|
||||||
|
LOGGER.info("期初余额-收款退款单总额sql:SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSktkdTable() +
|
||||||
|
" WHERE FSALEORGUNIT = "+saleOrgUnit+" AND FCUSTNAME = "+custName+" AND FBILLDATE >= "+startDateStr+" AND FBILLDATE< "+endDateStr+"");
|
||||||
|
|
||||||
BigDecimal sktkTotal = sktkResult != null && sktkResult.get("total") != null ?
|
BigDecimal sktkTotal = sktkResult != null && sktkResult.get("total") != null ?
|
||||||
new BigDecimal(sktkResult.get("total").toString()) : BigDecimal.ZERO;
|
new BigDecimal(sktkResult.get("total").toString()) : BigDecimal.ZERO;
|
||||||
|
|
||||||
|
LOGGER.info("期初余额:{}",sktkTotal.doubleValue());
|
||||||
// 期初余额 = 应收单总额 - 收款单总额 + 收款退款单总额
|
// 期初余额 = 应收单总额 - 收款单总额 + 收款退款单总额
|
||||||
return ysTotal.subtract(skTotal).add(sktkTotal);
|
return ysTotal.subtract(skTotal).add(sktkTotal);
|
||||||
|
|
||||||
@ -278,13 +300,19 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
*/
|
*/
|
||||||
private BigDecimal calculateTotalSales(Section section, String saleOrgUnit, String custName,
|
private BigDecimal calculateTotalSales(Section section, String saleOrgUnit, String custName,
|
||||||
LocalDate startDate, LocalDate endDate) {
|
LocalDate startDate, LocalDate endDate) {
|
||||||
|
String startDateStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 00:00:00";
|
||||||
|
String endDateStr = endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 23:59:59";
|
||||||
try {
|
try {
|
||||||
RowMap result = DBSql.getMap(
|
RowMap result = DBSql.getMap(
|
||||||
"SELECT SUM(SSJERMB) as total FROM " + section.getYsdTable() +
|
"SELECT SUM(SSJERMB) as total FROM " + section.getYsdTable() +
|
||||||
" WHERE XSZZ = ? AND FCUSTNAME = ? AND DZRQ BETWEEN ? AND ?",
|
" WHERE XSZZ = ? AND FCUSTNAME = ? AND DZRQ >= ? AND DZRQ < ?",
|
||||||
saleOrgUnit, custName, java.sql.Date.valueOf(startDate), java.sql.Date.valueOf(endDate)
|
saleOrgUnit, custName, startDateStr, endDateStr
|
||||||
);
|
);
|
||||||
|
// LOGGER.info("计算累计销售:SELECT SUM(SSJERMB) as total FROM " + section.getYsdTable() +
|
||||||
|
// " WHERE XSZZ = "+saleOrgUnit+" AND FCUSTNAME = "+custName+" AND DZRQ >= "+startDateStr+" AND DZRQ < "+endDateStr+"");
|
||||||
|
|
||||||
|
// LOGGER.info("累计销售={}",result != null && result.get("total") != null ?
|
||||||
|
// new BigDecimal(result.get("total").toString()) : BigDecimal.ZERO);
|
||||||
return result != null && result.get("total") != null ?
|
return result != null && result.get("total") != null ?
|
||||||
new BigDecimal(result.get("total").toString()) : BigDecimal.ZERO;
|
new BigDecimal(result.get("total").toString()) : BigDecimal.ZERO;
|
||||||
|
|
||||||
@ -299,13 +327,17 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
*/
|
*/
|
||||||
private BigDecimal calculateTotalRepayment(Section section, String saleOrgUnit, String custName,
|
private BigDecimal calculateTotalRepayment(Section section, String saleOrgUnit, String custName,
|
||||||
LocalDate startDate, LocalDate endDate) {
|
LocalDate startDate, LocalDate endDate) {
|
||||||
|
String startDateStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 00:00:00";
|
||||||
|
String endDateStr = endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 23:59:59";
|
||||||
try {
|
try {
|
||||||
// 查询收款单总额
|
// 查询收款单总额
|
||||||
RowMap skResult = DBSql.getMap(
|
RowMap skResult = DBSql.getMap(
|
||||||
"SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSkdTable() +
|
"SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSkdTable() +
|
||||||
" WHERE FSALEORGUNIT = ? AND FCUSTNAME = ? AND FBILLDATE BETWEEN ? AND ?",
|
" WHERE FSALEORGUNIT = ? AND FCUSTNAME = ? AND FBILLDATE >= ? AND FBILLDATE < ?",
|
||||||
saleOrgUnit, custName, java.sql.Date.valueOf(startDate), java.sql.Date.valueOf(endDate)
|
saleOrgUnit, custName, startDateStr, endDateStr
|
||||||
);
|
);
|
||||||
|
// LOGGER.info("计算累计还款:SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSkdTable() +
|
||||||
|
// " WHERE FSALEORGUNIT = "+saleOrgUnit+" AND FCUSTNAME = "+custName+" AND FBILLDATE >= "+startDateStr+" AND FBILLDATE < "+endDateStr+"");
|
||||||
|
|
||||||
BigDecimal skTotal = skResult != null && skResult.get("total") != null ?
|
BigDecimal skTotal = skResult != null && skResult.get("total") != null ?
|
||||||
new BigDecimal(skResult.get("total").toString()) : BigDecimal.ZERO;
|
new BigDecimal(skResult.get("total").toString()) : BigDecimal.ZERO;
|
||||||
@ -313,13 +345,15 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
// 查询收款退款单总额
|
// 查询收款退款单总额
|
||||||
RowMap sktkResult = DBSql.getMap(
|
RowMap sktkResult = DBSql.getMap(
|
||||||
"SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSktkdTable() +
|
"SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSktkdTable() +
|
||||||
" WHERE FSALEORGUNIT = ? AND FCUSTNAME = ? AND FBILLDATE BETWEEN ? AND ?",
|
" WHERE FSALEORGUNIT = ? AND FCUSTNAME = ? AND FBILLDATE >= ? AND FBILLDATE < ?",
|
||||||
saleOrgUnit, custName, java.sql.Date.valueOf(startDate), java.sql.Date.valueOf(endDate)
|
saleOrgUnit, custName, startDateStr, endDateStr
|
||||||
);
|
);
|
||||||
|
// LOGGER.info("计算累计还款:SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSktkdTable() +
|
||||||
|
// " WHERE FSALEORGUNIT = "+saleOrgUnit+" AND FCUSTNAME = "+custName+" AND FBILLDATE >= "+startDateStr+" AND FBILLDATE < "+endDateStr+"");
|
||||||
|
|
||||||
BigDecimal sktkTotal = sktkResult != null && sktkResult.get("total") != null ?
|
BigDecimal sktkTotal = sktkResult != null && sktkResult.get("total") != null ?
|
||||||
new BigDecimal(sktkResult.get("total").toString()) : BigDecimal.ZERO;
|
new BigDecimal(sktkResult.get("total").toString()) : BigDecimal.ZERO;
|
||||||
|
// LOGGER.info("累计还款={}",skTotal.subtract(sktkTotal).doubleValue());
|
||||||
// 累计还款 = 收款单总额 - 收款退款单总额
|
// 累计还款 = 收款单总额 - 收款退款单总额
|
||||||
return skTotal.subtract(sktkTotal);
|
return skTotal.subtract(sktkTotal);
|
||||||
|
|
||||||
@ -330,17 +364,13 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算账龄分析
|
* 计算月度账龄分析
|
||||||
*/
|
*/
|
||||||
private Map<String, BigDecimal> calculateAgingAnalysis(Map<String, Map<LocalDate, BigDecimal>> historicalBalanceCache,
|
private Map<String, BigDecimal> calculateMonthlyAgingAnalysis(Section section, String saleOrgUnit, String custName,
|
||||||
String saleOrgUnit, String custName,
|
LocalDate currentDate, BigDecimal currentBalance) {
|
||||||
LocalDate currentDate, BigDecimal currentBalance) {
|
|
||||||
Map<String, BigDecimal> result = new HashMap<>();
|
Map<String, BigDecimal> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String key = saleOrgUnit + "_" + custName;
|
|
||||||
Map<LocalDate, BigDecimal> customerHistory = historicalBalanceCache.getOrDefault(key, new HashMap<>());
|
|
||||||
|
|
||||||
// 计算各个时间点的应收余额
|
// 计算各个时间点的应收余额
|
||||||
LocalDate date60DaysAgo = currentDate.minusDays(60);
|
LocalDate date60DaysAgo = currentDate.minusDays(60);
|
||||||
LocalDate date1YearAgo = currentDate.minusYears(1);
|
LocalDate date1YearAgo = currentDate.minusYears(1);
|
||||||
@ -349,21 +379,22 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
LocalDate date4YearsAgo = currentDate.minusYears(4);
|
LocalDate date4YearsAgo = currentDate.minusYears(4);
|
||||||
LocalDate date5YearsAgo = currentDate.minusYears(5);
|
LocalDate date5YearsAgo = currentDate.minusYears(5);
|
||||||
|
|
||||||
BigDecimal balance60DaysAgo = findClosestBalance(customerHistory, date60DaysAgo);
|
// 查询历史月末的应收余额
|
||||||
BigDecimal balance1YearAgo = findClosestBalance(customerHistory, date1YearAgo);
|
BigDecimal balance60DaysAgo = findMonthlyBalance(section, saleOrgUnit, custName, date60DaysAgo);
|
||||||
BigDecimal balance2YearsAgo = findClosestBalance(customerHistory, date2YearsAgo);
|
BigDecimal balance1YearAgo = findMonthlyBalance(section, saleOrgUnit, custName, date1YearAgo);
|
||||||
BigDecimal balance3YearsAgo = findClosestBalance(customerHistory, date3YearsAgo);
|
BigDecimal balance2YearsAgo = findMonthlyBalance(section, saleOrgUnit, custName, date2YearsAgo);
|
||||||
BigDecimal balance4YearsAgo = findClosestBalance(customerHistory, date4YearsAgo);
|
BigDecimal balance3YearsAgo = findMonthlyBalance(section, saleOrgUnit, custName, date3YearsAgo);
|
||||||
BigDecimal balance5YearsAgo = findClosestBalance(customerHistory, date5YearsAgo);
|
BigDecimal balance4YearsAgo = findMonthlyBalance(section, saleOrgUnit, custName, date4YearsAgo);
|
||||||
|
BigDecimal balance5YearsAgo = findMonthlyBalance(section, saleOrgUnit, custName, date5YearsAgo);
|
||||||
|
|
||||||
// 计算各账龄段金额
|
// 计算各账龄段金额
|
||||||
result.put("ZLFX0_60", currentBalance.subtract(balance60DaysAgo));
|
result.put("ZLFX0_60", currentBalance.subtract(balance60DaysAgo.max(BigDecimal.ZERO)));
|
||||||
result.put("ZLFX60_1", balance60DaysAgo.subtract(balance1YearAgo));
|
result.put("ZLFX60_1", balance60DaysAgo.subtract(balance1YearAgo.max(BigDecimal.ZERO)));
|
||||||
result.put("ZLFX1_2", balance1YearAgo.subtract(balance2YearsAgo));
|
result.put("ZLFX1_2", balance1YearAgo.subtract(balance2YearsAgo.max(BigDecimal.ZERO)));
|
||||||
result.put("ZLFX2_3", balance2YearsAgo.subtract(balance3YearsAgo));
|
result.put("ZLFX2_3", balance2YearsAgo.subtract(balance3YearsAgo.max(BigDecimal.ZERO)));
|
||||||
result.put("ZLFX3_4", balance3YearsAgo.subtract(balance4YearsAgo));
|
result.put("ZLFX3_4", balance3YearsAgo.subtract(balance4YearsAgo.max(BigDecimal.ZERO)));
|
||||||
result.put("ZLFX4_5", balance4YearsAgo.subtract(balance5YearsAgo));
|
result.put("ZLFX4_5", balance4YearsAgo.subtract(balance5YearsAgo.max(BigDecimal.ZERO)));
|
||||||
result.put("ZLFX5", balance5YearsAgo);
|
result.put("ZLFX5", balance5YearsAgo.max(BigDecimal.ZERO));
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.error("计算账龄分析时发生错误,销售组织: {}, 客户: {}", saleOrgUnit, custName, e);
|
LOGGER.error("计算账龄分析时发生错误,销售组织: {}, 客户: {}", saleOrgUnit, custName, e);
|
||||||
@ -381,27 +412,29 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找最接近日期的应收余额
|
* 查找指定月末的应收余额
|
||||||
*/
|
*/
|
||||||
private BigDecimal findClosestBalance(Map<LocalDate, BigDecimal> history, LocalDate targetDate) {
|
private BigDecimal findMonthlyBalance(Section section, String saleOrgUnit, String custName, LocalDate targetDate) {
|
||||||
if (history.isEmpty()) {
|
// 调整为目标月份的月末日期
|
||||||
|
LocalDate monthEndDate = targetDate.withDayOfMonth(targetDate.lengthOfMonth());
|
||||||
|
String dateStr = monthEndDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 23:59:59";
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 查询目标表中该月末的应收余额
|
||||||
|
RowMap result = DBSql.getMap(
|
||||||
|
"SELECT YSYE FROM " + section.getTargetTable() +
|
||||||
|
" WHERE XSZZ = ? AND KH = ? AND RQ = ?",
|
||||||
|
saleOrgUnit, custName, dateStr
|
||||||
|
);
|
||||||
|
|
||||||
|
return result != null && result.get("YSYE") != null ?
|
||||||
|
new BigDecimal(result.get("YSYE").toString()) : BigDecimal.ZERO;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.debug("未找到{}板块销售组织 {} 客户 {} 日期 {} 的历史余额,使用默认值0",
|
||||||
|
section.getName(), saleOrgUnit, custName, monthEndDate);
|
||||||
return BigDecimal.ZERO;
|
return BigDecimal.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 首先尝试精确匹配
|
|
||||||
if (history.containsKey(targetDate)) {
|
|
||||||
return history.get(targetDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果没有精确匹配,查找最接近的日期
|
|
||||||
LocalDate closestDate = null;
|
|
||||||
for (LocalDate date : history.keySet()) {
|
|
||||||
if (date.isBefore(targetDate) && (closestDate == null || date.isAfter(closestDate))) {
|
|
||||||
closestDate = date;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return closestDate != null ? history.get(closestDate) : BigDecimal.ZERO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -451,16 +484,4 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
LOGGER.error("批量插入{}板块数据到表{}时发生错误", section.getName(), section.getTargetTable(), e);
|
LOGGER.error("批量插入{}板块数据到表{}时发生错误", section.getName(), section.getTargetTable(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新历史余额缓存
|
|
||||||
*/
|
|
||||||
private void updateHistoricalBalanceCache(Map<String, Map<LocalDate, BigDecimal>> historicalBalanceCache,
|
|
||||||
String saleOrgUnit, String custName,
|
|
||||||
LocalDate date, BigDecimal balance) {
|
|
||||||
String key = saleOrgUnit + "_" + custName;
|
|
||||||
historicalBalanceCache
|
|
||||||
.computeIfAbsent(key, k -> new HashMap<>())
|
|
||||||
.put(date, balance);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -698,8 +698,10 @@ public class ProductionDataSyncServiceImpl implements DataSyncService {
|
|||||||
String tablename = mainConfig.getString("TABLENAME");//同步表名
|
String tablename = mainConfig.getString("TABLENAME");//同步表名
|
||||||
String hzb = "";
|
String hzb = "";
|
||||||
try {
|
try {
|
||||||
if ("原材料".equals(tablename)){
|
if ("生产入库".equals(tablename)) {
|
||||||
hzb = "BO_EU_DWS_ORDER_YCLXH_HZ";
|
hzb = "BO_EU_BNBM_SCRK_HZ";
|
||||||
|
} else if ("生产出库".equals(tablename)) {
|
||||||
|
hzb = "BO_EU_BNBM_SCCK_HZ";
|
||||||
}else {
|
}else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -409,6 +409,19 @@ public class SaleCountDimensionImpl implements DataSummaryService {
|
|||||||
),
|
),
|
||||||
(existing, replacement) -> existing
|
(existing, replacement) -> existing
|
||||||
));
|
));
|
||||||
|
// 获取公司简称
|
||||||
|
List<RowMap> gsjcList = DBSql.getMaps("SELECT GSMC,JC FROM BO_EU_BNBM_ZZWHB");
|
||||||
|
Map<String, String> gsjcMap = gsjcList.stream()
|
||||||
|
.filter(row -> {
|
||||||
|
String gsmc = row.getString("GSMC");
|
||||||
|
String jc = row.getString("JC");
|
||||||
|
return gsmc != null && jc != null;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
row -> row.getString("GSMC"),
|
||||||
|
row -> row.getString("JC"),
|
||||||
|
(existing, replacement) -> existing // 处理重复key
|
||||||
|
));
|
||||||
|
|
||||||
String querySql = "SELECT DZRQ,QYGS, KCZZ, " +
|
String querySql = "SELECT DZRQ,QYGS, KCZZ, " +
|
||||||
" CASE " +
|
" CASE " +
|
||||||
@ -492,6 +505,9 @@ public class SaleCountDimensionImpl implements DataSummaryService {
|
|||||||
bo.set("ISOEM", gzjzStrings[4]);//是否OEM板
|
bo.set("ISOEM", gzjzStrings[4]);//是否OEM板
|
||||||
// bo.set("SNTQXE", map.getString("sntqxe"));
|
// bo.set("SNTQXE", map.getString("sntqxe"));
|
||||||
bo.set("BHSYYSR", ssjermb);
|
bo.set("BHSYYSR", ssjermb);
|
||||||
|
if (gsjcMap.containsKey(gc)) {
|
||||||
|
bo.set("GCJC", gsjcMap.get(gc));
|
||||||
|
}
|
||||||
bos.add(bo);
|
bos.add(bo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import com.actionsoft.sdk.local.SDK;
|
|||||||
import com.actionsoft.sdk.local.api.cc.RDSAPI;
|
import com.actionsoft.sdk.local.api.cc.RDSAPI;
|
||||||
import com.awspaas.user.apps.bnbm.datalinkup.entity.DateRange;
|
import com.awspaas.user.apps.bnbm.datalinkup.entity.DateRange;
|
||||||
import com.awspaas.user.apps.bnbm.datalinkup.service.DataSyncService;
|
import com.awspaas.user.apps.bnbm.datalinkup.service.DataSyncService;
|
||||||
|
import com.awspaas.user.apps.bnbm.datalinkup.util.SaleUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -140,13 +141,13 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
|
|||||||
// 按时间范围删除
|
// 按时间范围删除
|
||||||
deleteTargetData(targetTable, targetTimeField, startDate, endDate);
|
deleteTargetData(targetTable, targetTimeField, startDate, endDate);
|
||||||
}
|
}
|
||||||
// 查询源表数据(跨库查询)
|
// 查询源表数据(跨库查询)
|
||||||
querySourceData(ccId, tableName, timeField, startDate, endDate, partitionField,
|
|
||||||
fieldMappings, targetTable,jezd);
|
|
||||||
if (tablename.equals("应收表")){
|
if (tablename.equals("应收表")){
|
||||||
LOGGER.info("开始执行应收的明细汇总");
|
LOGGER.info("开始执行应收的明细汇总");
|
||||||
querySourceDataYS(ccId, tableName, timeField, startDate, endDate, partitionField,
|
if ((!bkgs.equals("北新防水")) || (!bkgs.equals("北新涂料"))) {
|
||||||
fieldMappings, targetTable, jezd);
|
querySourceDataYS(ccId, tableName, timeField, startDate, endDate, partitionField,
|
||||||
|
fieldMappings, targetTable, jezd);
|
||||||
|
}
|
||||||
}else {
|
}else {
|
||||||
querySourceData(ccId, tableName, timeField, startDate, endDate, partitionField,
|
querySourceData(ccId, tableName, timeField, startDate, endDate, partitionField,
|
||||||
fieldMappings, targetTable, jezd);
|
fieldMappings, targetTable, jezd);
|
||||||
@ -560,6 +561,7 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
|
|||||||
*/
|
*/
|
||||||
public int processAndInsertData(List<RowMap> sourceData,
|
public int processAndInsertData(List<RowMap> sourceData,
|
||||||
List<BO> mappings, String targetTable) {
|
List<BO> mappings, String targetTable) {
|
||||||
|
List<BO> gzjzList = SDK.getBOAPI().query("BO_EU_DATALINKUP_CPJZGZJCMC").desc().list();
|
||||||
String bkgs = "";
|
String bkgs = "";
|
||||||
Set<String> bkgsSet = null;
|
Set<String> bkgsSet = null;
|
||||||
if (sourceData.isEmpty()) {
|
if (sourceData.isEmpty()) {
|
||||||
@ -578,8 +580,20 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
|
|||||||
try {
|
try {
|
||||||
// 字段映射转换
|
// 字段映射转换
|
||||||
BO targetData = convertFields(record, mappings);
|
BO targetData = convertFields(record, mappings);
|
||||||
|
// 匹配公装家装类别,如果未匹配到,则默认未其他
|
||||||
|
if ("BO_EU_BNBM_DATALINKUP_XS_XSL_JBL,BO_EU_BNBM_DATALINKUP_XS_XSL,BO_EU_TL_SALESDATA_SKD,BO_EU_SALESDATA_SKD,BO_EU_BNBM_DATALINKUP_XS_XSL_TS".contains(targetTable)) {
|
||||||
|
String[] gzjzStrings = SaleUtil.matchSingleField(targetData.getString("BKGS"), targetData.getString("LB_1"),
|
||||||
|
targetData.getString("LB_2"), targetData.getString("LB_3"), gzjzList, "其他", "其他", "其他");
|
||||||
|
targetData.set("MC_JC", gzjzStrings[1]);//面材/基材
|
||||||
|
targetData.set("JZ_GZ", gzjzStrings[0]);//家装/工装
|
||||||
|
targetData.set("PROD_CAT", gzjzStrings[2]);//产品类型
|
||||||
|
targetData.set("PBGNB", gzjzStrings[3]);//普板/功能板
|
||||||
|
targetData.set("ISOEM", gzjzStrings[4]);//是否OEM板
|
||||||
|
// bo.set("SNTQXE", map.getString("sntqxe"));
|
||||||
|
}
|
||||||
batchList.add(targetData);
|
batchList.add(targetData);
|
||||||
|
|
||||||
|
|
||||||
// 批量插入条件:达到批处理大小或最后一条
|
// 批量插入条件:达到批处理大小或最后一条
|
||||||
if (batchList.size() >= PAGE_SIZE || i == totalCount - 1) {
|
if (batchList.size() >= PAGE_SIZE || i == totalCount - 1) {
|
||||||
// 使用管理员权限批量插入
|
// 使用管理员权限批量插入
|
||||||
@ -593,7 +607,7 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 增加详细日志输出:共处理多少条,成功同步多少条
|
// 增加详细日志输出:共处理多少条,成功同步多少条
|
||||||
bkgs = Arrays.toString(bkgsSet.toArray());
|
bkgs = bkgsSet.stream().collect(Collectors.joining(", "));
|
||||||
LOGGER.info("同步板块为:{};落地表为:{},本次处理{}条数据,成功同步{}条数据到表[{}]",
|
LOGGER.info("同步板块为:{};落地表为:{},本次处理{}条数据,成功同步{}条数据到表[{}]",
|
||||||
bkgs,targetTable,processedCount, successCount, targetTable);
|
bkgs,targetTable,processedCount, successCount, targetTable);
|
||||||
return successCount;
|
return successCount;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user