1、防水涂料应收优化

This commit is contained in:
llllon 2025-09-09 17:51:52 +08:00
parent a432f19ca0
commit f2b56f4653
4 changed files with 51 additions and 28 deletions

View File

@ -35,29 +35,23 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
private static final String DEFAULT_BKGS_TL = "北新涂料";
private static final int BATCH_SIZE = 1000;
private static final int THREAD_POOL_SIZE = 2; // 线程池大小根据需求调整
// 板块配置
@Override
public void execute(JobExecutionContext job) throws JobExecutionException {
try {
String param = SDK.getJobAPI().getJobParameter(job);
int timeRange = StringUtils.isNotBlank(param)?Integer.parseInt(param):0;
// 获取当前时间
LocalDate nowDate = LocalDate.now();
LocalDate startDate;
if (timeRange > 0) {
startDate = nowDate.minusDays(timeRange);
} else {
// 默认计算去年第一天到现在的数据
startDate = nowDate.minusYears(1).withDayOfYear(1);
}
LOGGER.info("开始执行防水涂料应收单计算任务,时间范围:{} 到 {}", startDate, nowDate);
// 依次处理防水和涂料两个板块
boolean allSuccess = true;
for (Section section : Section.values()) {
@ -67,11 +61,9 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
LOGGER.error("{}板块处理失败", section.getName());
}
}
if (!allSuccess) {
throw new JobExecutionException("部分板块处理失败");
}
LOGGER.info("防水涂料应收单计算任务完成,共处理 {} 天数据", nowDate.toEpochDay() - startDate.toEpochDay() + 1);
} catch (Exception e) {
@ -92,6 +84,10 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
// 每个板块使用独立的缓存
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 {
// 开始清理开始时间到结束时间的数据后再进行计算更新数据
@ -102,14 +98,10 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
LOGGER.info("已删除目标表[{}]中{}条数据(时间范围: {} - {})",
section.getTargetTable(), delete, startDateFormat, nowDateFormat);
// 获取RDSAPI实例
// RDSAPI rdsapi = SDK.getCCAPI().getRDSAPI(RDS_ID);
// 查询销售组织和客户分组信息
List<RowMap> maps = DBSql.getMaps("SELECT QYGS, FCUSTNAME, SQ AS FPROVINCE,CS AS FCITY FROM " +
section.getYsdTable() + " GROUP BY QYGS, FCUSTNAME, SQ,CS");
if (maps == null || maps.isEmpty()) {
LOGGER.warn("{}板块未查询到销售组织和客户数据", sectionName);
return true; // 没有数据也算成功
@ -133,28 +125,58 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
String custName = row.getString("FCUSTNAME");
// 查询省市区信息
// RowMap locationInfo = rdsapi.getMap(
// "SELECT FProvince, FCity FROM " + section.getYsdTable() +
// " WHERE FSaleOrgUnit = ? AND FCustName = ? ",
// saleOrgUnit, custName
// );
String province = row != null ? row.getString("FPROVINCE") : "";
String city = row != null ? row.getString("FCITY") : "";
String district = row != null ? row.getString("FDISTRICT")!=null ? row.getString("FDISTRICT"):"": "";
// 计算期初余额上一年度
LocalDate previousYearStart = currentDate.minusYears(1).withDayOfYear(1);
LocalDate previousYearEnd = currentDate.minusYears(1).withDayOfYear(365);
String cacheKey = saleOrgUnit + "_" + custName;
BigDecimal qcye = calculateInitialBalance(section, saleOrgUnit, custName, previousYearStart, previousYearEnd);
// 计算期初余额上一年度- 每个客户只需计算一次
BigDecimal qcye;
if (currentDate.equals(startDate)) {
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);
}
}
// 计算累计销售本年年初到当前日期
LocalDate currentYearStart = currentDate.withDayOfYear(1);
BigDecimal ljxs = calculateTotalSales(section, saleOrgUnit, custName, currentYearStart, currentDate);
// 计算当日销售
BigDecimal dailySales = calculateTotalSales(section, saleOrgUnit, custName, currentDate, currentDate);
// 计算当日还款
BigDecimal dailyRepayment = calculateTotalRepayment(section, saleOrgUnit, custName, currentDate, currentDate);
// 计算累计还款本年年初到当前日期
BigDecimal ljhk = calculateTotalRepayment(section, saleOrgUnit, custName, currentYearStart, 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);

View File

@ -16,6 +16,7 @@ import java.sql.Array;
import java.sql.Connection;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
@ -171,7 +172,7 @@ public class SaleCountDimensionImpl implements DataSummaryService {
String xszz = map.getString("XSZZ");
String rq = map.getString("RQ");
BO bo = new BO();
bo.set("YEARMONTH", YEAR_MONTH_FORMAT.format(rq));
bo.set("YEARMONTH", rq.substring(0, 7));
bo.set("BKGS", bkgs);
bo.set("QYGS", map.getString("QYGS"));
bo.set("GC", xszz);