1、防水涂料应收方法
This commit is contained in:
parent
d298fbbdf5
commit
933c7f83d4
Binary file not shown.
@ -96,17 +96,17 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
// sql += " AND F_SFNBJY ='否'";
|
// sql += " AND F_SFNBJY ='否'";
|
||||||
// }
|
// }
|
||||||
sql += " GROUP BY FCUSTNAME,XSZZ";
|
sql += " GROUP BY FCUSTNAME,XSZZ";
|
||||||
List<RowMap> customerMaps = DBSql.getMaps(sql);
|
// List<RowMap> customerMaps = DBSql.getMaps(sql);
|
||||||
// List<RowMap> customerMaps = new ArrayList<>();
|
List<RowMap> customerMaps = new ArrayList<>();
|
||||||
// HashMap<String, Object> hashMap = new HashMap<>();
|
HashMap<String, Object> hashMap = new HashMap<>();
|
||||||
// hashMap.put("QYGS","北方区域公司");
|
hashMap.put("QYGS","北方区域公司");
|
||||||
// hashMap.put("FCUSTNAME","大连红太阳防水保温工程有限公司");
|
hashMap.put("FCUSTNAME","大连红太阳防水保温工程有限公司");
|
||||||
// hashMap.put("FPROVINCE","辽宁省");
|
hashMap.put("FPROVINCE","辽宁省");
|
||||||
// hashMap.put("FCITY","大连市");
|
hashMap.put("FCITY","大连市");
|
||||||
// hashMap.put("FDISTRICT","");
|
hashMap.put("FDISTRICT","");
|
||||||
// hashMap.put("XSZZ","北新禹王防水科技集团有限公司");
|
hashMap.put("XSZZ","北新禹王防水科技集团有限公司");
|
||||||
// RowMap map = new RowMap(hashMap);
|
RowMap map = new RowMap(hashMap);
|
||||||
// customerMaps.add(map);
|
customerMaps.add(map);
|
||||||
|
|
||||||
if (customerMaps == null || customerMaps.isEmpty()) {
|
if (customerMaps == null || customerMaps.isEmpty()) {
|
||||||
LOGGER.warn("{}板块未查询到销售组织和客户数据", sectionName);
|
LOGGER.warn("{}板块未查询到销售组织和客户数据", sectionName);
|
||||||
@ -117,6 +117,9 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
|
|
||||||
// 分批次处理客户数据
|
// 分批次处理客户数据
|
||||||
int totalCustomers = customerMaps.size();
|
int totalCustomers = customerMaps.size();
|
||||||
|
// 预加载所有客户的历史余额数据
|
||||||
|
Map<String, Map<String, Double>> historicalBalanceData = preloadAllHistoricalBalanceData(customerMaps);
|
||||||
|
LOGGER.info("成功预加载 {} 个客户的历史余额数据", historicalBalanceData.size());
|
||||||
for (int i = 0; i < totalCustomers; i += CUSTOMER_BATCH_SIZE) {
|
for (int i = 0; i < totalCustomers; i += CUSTOMER_BATCH_SIZE) {
|
||||||
int endIndex = Math.min(i + CUSTOMER_BATCH_SIZE, totalCustomers);
|
int endIndex = Math.min(i + CUSTOMER_BATCH_SIZE, totalCustomers);
|
||||||
List<RowMap> batchCustomers = customerMaps.subList(i, endIndex);
|
List<RowMap> batchCustomers = customerMaps.subList(i, endIndex);
|
||||||
@ -124,7 +127,7 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
LOGGER.info("{}板块正在处理第 {} 批客户,进度: {}/{}",
|
LOGGER.info("{}板块正在处理第 {} 批客户,进度: {}/{}",
|
||||||
sectionName, (i / CUSTOMER_BATCH_SIZE) + 1, endIndex, totalCustomers);
|
sectionName, (i / CUSTOMER_BATCH_SIZE) + 1, endIndex, totalCustomers);
|
||||||
|
|
||||||
boolean batchSuccess = processCustomerBatch(section, batchCustomers, startDate, endDate);
|
boolean batchSuccess = processCustomerBatch(section, batchCustomers, startDate, endDate, historicalBalanceData);
|
||||||
if (!batchSuccess) {
|
if (!batchSuccess) {
|
||||||
LOGGER.error("{}板块第 {} 批客户处理失败", sectionName, (i / CUSTOMER_BATCH_SIZE) + 1);
|
LOGGER.error("{}板块第 {} 批客户处理失败", sectionName, (i / CUSTOMER_BATCH_SIZE) + 1);
|
||||||
return false;
|
return false;
|
||||||
@ -140,11 +143,154 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预加载所有客户的历史余额数据
|
||||||
|
*/
|
||||||
|
private Map<String, Map<String, Double>> preloadAllHistoricalBalanceData(List<RowMap> customerMaps) {
|
||||||
|
Map<String, Map<String, Double>> historicalBalanceData = new HashMap<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 提取所有销售组织和客户名称
|
||||||
|
List<String> saleOrgUnits = customerMaps.stream()
|
||||||
|
.map(row -> row.getString("XSZZ"))
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
List<String> custNames = customerMaps.stream()
|
||||||
|
.map(row -> row.getString("FCUSTNAME"))
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 批量查询所有客户的历史余额数据
|
||||||
|
List<RowMap> allBalanceData = batchQueryAllHistoricalBalanceData(saleOrgUnits, custNames);
|
||||||
|
|
||||||
|
// 按销售组织和客户名称组织数据
|
||||||
|
for (RowMap row : allBalanceData) {
|
||||||
|
String saleOrgUnit = row.getString("XSZZ");
|
||||||
|
String custName = row.getString("FCUSTNAME");
|
||||||
|
String period = row.getString("period");
|
||||||
|
String key = saleOrgUnit + "_" + custName;
|
||||||
|
if (!historicalBalanceData.containsKey(key)) {
|
||||||
|
historicalBalanceData.put(key, new HashMap<>());
|
||||||
|
}
|
||||||
|
BigDecimal totalYsAmount = BigDecimal.ZERO;
|
||||||
|
BigDecimal totalSkAmount = BigDecimal.ZERO;
|
||||||
|
BigDecimal totalSktkAmount = BigDecimal.ZERO;
|
||||||
|
String ysamount = StringUtils.isNotBlank(row.getString("ys")) ? row.getString("ys") : "0.00";
|
||||||
|
String skamount = StringUtils.isNotBlank(row.getString("sk")) ? row.getString("sk") : "0.00";
|
||||||
|
String tkamount = StringUtils.isNotBlank(row.getString("tk")) ? row.getString("tk") : "0.00";
|
||||||
|
totalYsAmount = new BigDecimal(ysamount);
|
||||||
|
totalSkAmount = new BigDecimal(skamount);
|
||||||
|
totalSktkAmount = new BigDecimal(tkamount);
|
||||||
|
// 计算公式:累计应收金额 - (累计收款金额 - 累计收款退款金额)
|
||||||
|
BigDecimal balance = totalYsAmount.subtract(totalSkAmount.subtract(totalSktkAmount));
|
||||||
|
LOGGER.info("totalYsAmount:{},totalSkAmount:{},totalSktkAmount:{},balance:{}",totalYsAmount,totalSkAmount,totalSktkAmount,balance);
|
||||||
|
historicalBalanceData.get(key).put(period, balance.doubleValue());
|
||||||
|
}
|
||||||
|
// 确保所有客户的所有期间都有值
|
||||||
|
ensureAllCustomersHaveAllPeriods(historicalBalanceData, customerMaps);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("预加载所有客户历史余额数据时发生错误", e);
|
||||||
|
}
|
||||||
|
return historicalBalanceData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确保所有客户的所有期间都有值
|
||||||
|
*/
|
||||||
|
private void ensureAllCustomersHaveAllPeriods(Map<String, Map<String, Double>> historicalBalanceData,
|
||||||
|
List<RowMap> customerMaps) {
|
||||||
|
String[] periods = {"60天", "1年", "2年", "3年", "4年", "5年", "5年以上"};
|
||||||
|
for (RowMap customer : customerMaps) {
|
||||||
|
String saleOrgUnit = customer.getString("XSZZ");
|
||||||
|
String custName = customer.getString("FCUSTNAME");
|
||||||
|
String key = saleOrgUnit + "_" + custName;
|
||||||
|
if (!historicalBalanceData.containsKey(key)) {
|
||||||
|
historicalBalanceData.put(key, new HashMap<>());
|
||||||
|
}
|
||||||
|
Map<String, Double> balanceMap = historicalBalanceData.get(key);
|
||||||
|
for (String period : periods) {
|
||||||
|
balanceMap.putIfAbsent(period, 0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量查询所有客户的历史余额数据
|
||||||
|
*/
|
||||||
|
private List<RowMap> batchQueryAllHistoricalBalanceData(List<String> saleOrgUnits, List<String> custNames) {
|
||||||
|
try {
|
||||||
|
String inSaleOrgs = buildInCondition(saleOrgUnits);
|
||||||
|
String inCustNames = buildInCondition(custNames);
|
||||||
|
|
||||||
|
String sql = "SELECT XSZZ, FCUSTNAME, period, SUM(ys) AS ys, SUM(sk) AS sk, SUM(tk) AS tk\n" +
|
||||||
|
" FROM ( SELECT XSZZ, FCUSTNAME,\n" +
|
||||||
|
" CASE\n" +
|
||||||
|
" WHEN DZRQ >= DATE_SUB(NOW(), INTERVAL 60 DAY) THEN '60天'\n" +
|
||||||
|
" WHEN DZRQ >= DATE_SUB(NOW(), INTERVAL 1 YEAR) THEN '1年'\n" +
|
||||||
|
" WHEN DZRQ >= DATE_SUB(NOW(), INTERVAL 2 YEAR) THEN '2年'\n" +
|
||||||
|
" WHEN DZRQ >= DATE_SUB(NOW(), INTERVAL 3 YEAR) THEN '3年'\n" +
|
||||||
|
" WHEN DZRQ >= DATE_SUB(NOW(), INTERVAL 4 YEAR) THEN '4年'\n" +
|
||||||
|
" WHEN DZRQ >= DATE_SUB(NOW(), INTERVAL 5 YEAR) THEN '5年'\n" +
|
||||||
|
" ELSE '5年以上'\n" +
|
||||||
|
" END AS period, SSJERMB AS ys, 0 AS sk, 0 AS tk\n" +
|
||||||
|
" FROM BO_EU_SALESDATA_SKD\n" +
|
||||||
|
" WHERE FCUSTNAME IS NOT NULL AND FCUSTNAME != '' AND XSZZ IS NOT NULL\n" +
|
||||||
|
" AND XSZZ IN (" + inSaleOrgs + ") AND FCUSTNAME IN (" + inCustNames + ")\n" +
|
||||||
|
" UNION ALL\n" +
|
||||||
|
" SELECT FSALEORGUNIT AS XSZZ, FCUSTNAME,\n" +
|
||||||
|
" CASE\n" +
|
||||||
|
" WHEN FBILLDATE >= DATE_SUB(NOW(), INTERVAL 60 DAY) THEN '60天'\n" +
|
||||||
|
" WHEN FBILLDATE >= DATE_SUB(NOW(), INTERVAL 1 YEAR) THEN '1年'\n" +
|
||||||
|
" WHEN FBILLDATE >= DATE_SUB(NOW(), INTERVAL 2 YEAR) THEN '2年'\n" +
|
||||||
|
" WHEN FBILLDATE >= DATE_SUB(NOW(), INTERVAL 3 YEAR) THEN '3年'\n" +
|
||||||
|
" WHEN FBILLDATE >= DATE_SUB(NOW(), INTERVAL 4 YEAR) THEN '4年'\n" +
|
||||||
|
" WHEN FBILLDATE >= DATE_SUB(NOW(), INTERVAL 5 YEAR) THEN '5年'\n" +
|
||||||
|
" ELSE '5年以上'\n" +
|
||||||
|
" END AS period, 0 AS ys, FSALEAMOUNTRMB AS sk, 0 AS tk\n" +
|
||||||
|
" FROM BO_EU_FS_SALESDATA_SKD\n" +
|
||||||
|
" WHERE FCUSTNAME IS NOT NULL AND FCUSTNAME != '' AND FSALEORGUNIT IS NOT NULL\n" +
|
||||||
|
" AND FSALEORGUNIT IN (" + inSaleOrgs + ") AND FCUSTNAME IN (" + inCustNames + ")\n" +
|
||||||
|
" UNION ALL\n" +
|
||||||
|
" SELECT FSALEORGUNIT AS XSZZ, FCUSTNAME,\n" +
|
||||||
|
" CASE\n" +
|
||||||
|
" WHEN FBILLDATE >= DATE_SUB(NOW(), INTERVAL 60 DAY) THEN '60天'\n" +
|
||||||
|
" WHEN FBILLDATE >= DATE_SUB(NOW(), INTERVAL 1 YEAR) THEN '1年'\n" +
|
||||||
|
" WHEN FBILLDATE >= DATE_SUB(NOW(), INTERVAL 2 YEAR) THEN '2年'\n" +
|
||||||
|
" WHEN FBILLDATE >= DATE_SUB(NOW(), INTERVAL 3 YEAR) THEN '3年'\n" +
|
||||||
|
" WHEN FBILLDATE >= DATE_SUB(NOW(), INTERVAL 4 YEAR) THEN '4年'\n" +
|
||||||
|
" WHEN FBILLDATE >= DATE_SUB(NOW(), INTERVAL 5 YEAR) THEN '5年'\n" +
|
||||||
|
" ELSE '5年以上'\n" +
|
||||||
|
" END AS period, 0 AS ys, 0 AS sk, FSALEAMOUNTRMB AS tk\n" +
|
||||||
|
" FROM BO_EU_SALESDATA_SKTKD\n" +
|
||||||
|
" WHERE FCUSTNAME IS NOT NULL AND FCUSTNAME != '' AND FSALEORGUNIT IS NOT NULL\n" +
|
||||||
|
" AND FSALEORGUNIT IN (" + inSaleOrgs + ") AND FCUSTNAME IN (" + inCustNames + ")\n" +
|
||||||
|
" ) AS combined_data\n" +
|
||||||
|
" GROUP BY XSZZ, FCUSTNAME, period\n" +
|
||||||
|
" ORDER BY XSZZ, FCUSTNAME,\n" +
|
||||||
|
" CASE period\n" +
|
||||||
|
" WHEN '60天' THEN 1\n" +
|
||||||
|
" WHEN '1年' THEN 2\n" +
|
||||||
|
" WHEN '2年' THEN 3\n" +
|
||||||
|
" WHEN '3年' THEN 4\n" +
|
||||||
|
" WHEN '4年' THEN 5\n" +
|
||||||
|
" WHEN '5年' THEN 6\n" +
|
||||||
|
" WHEN '5年以上' THEN 7\n" +
|
||||||
|
" END";
|
||||||
|
|
||||||
|
return DBSql.getMaps(sql);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("批量查询所有客户历史余额数据时发生错误", e);
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理一批客户数据
|
* 处理一批客户数据
|
||||||
*/
|
*/
|
||||||
private boolean processCustomerBatch(Section section, List<RowMap> customerBatch,
|
private boolean processCustomerBatch(Section section, List<RowMap> customerBatch,
|
||||||
LocalDate startDate, LocalDate endDate) {
|
LocalDate startDate, LocalDate endDate,Map<String, Map<String, Double>> historicalBalanceData) {
|
||||||
try {
|
try {
|
||||||
// 提取销售组织和客户名称列表
|
// 提取销售组织和客户名称列表
|
||||||
List<String> saleOrgUnits = customerBatch.stream()
|
List<String> saleOrgUnits = customerBatch.stream()
|
||||||
@ -164,7 +310,7 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
|
|
||||||
// 批量预加载所有需要的数据
|
// 批量预加载所有需要的数据
|
||||||
Map<String, BigDecimal> preloadedResults = preloadAllData(
|
Map<String, BigDecimal> preloadedResults = preloadAllData(
|
||||||
section, saleOrgUnits, custNames, monthEndDates);
|
section, saleOrgUnits, custNames, monthEndDates, historicalBalanceData);
|
||||||
|
|
||||||
// 批量处理数据
|
// 批量处理数据
|
||||||
List<BO> allRecords = new ArrayList<>();
|
List<BO> allRecords = new ArrayList<>();
|
||||||
@ -191,7 +337,7 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
Map<String, BigDecimal> zlfx = new HashMap<>();
|
Map<String, BigDecimal> zlfx = new HashMap<>();
|
||||||
for (String zlfxKey : Arrays.asList("ZLFX0_60", "ZLFX60_1", "ZLFX1_2", "ZLFX2_3", "ZLFX3_4", "ZLFX4_5", "ZLFX5")) {
|
for (String zlfxKey : Arrays.asList("ZLFX0_60", "ZLFX60_1", "ZLFX1_2", "ZLFX2_3", "ZLFX3_4", "ZLFX4_5", "ZLFX5")) {
|
||||||
BigDecimal value = getPreloadedValue(preloadedResults, keyPrefix + zlfxKey + "_" + monthEndDate);
|
BigDecimal value = getPreloadedValue(preloadedResults, keyPrefix + zlfxKey + "_" + monthEndDate);
|
||||||
zlfx.put(zlfxKey, value);
|
zlfx.put(zlfxKey, value.subtract(qcye));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建记录
|
// 创建记录
|
||||||
@ -242,7 +388,8 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
* 预加载所有需要的数据
|
* 预加载所有需要的数据
|
||||||
*/
|
*/
|
||||||
private Map<String, BigDecimal> preloadAllData(Section section,
|
private Map<String, BigDecimal> preloadAllData(Section section,
|
||||||
List<String> saleOrgUnits, List<String> custNames, List<LocalDate> monthEndDates) {
|
List<String> saleOrgUnits, List<String> custNames,
|
||||||
|
List<LocalDate> monthEndDates,Map<String, Map<String, Double>> historicalBalanceData) {
|
||||||
LOGGER.info("预加载数据开始");
|
LOGGER.info("预加载数据开始");
|
||||||
Map<String, BigDecimal> results = new HashMap<>();
|
Map<String, BigDecimal> results = new HashMap<>();
|
||||||
|
|
||||||
@ -261,9 +408,9 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
// 批量查询收款退款单数据
|
// 批量查询收款退款单数据
|
||||||
Map<String, BigDecimal> sktkData = batchQuerySKTKDData(section, saleOrgUnits, custNames, extendedMonthEndDates);
|
Map<String, BigDecimal> sktkData = batchQuerySKTKDData(section, saleOrgUnits, custNames, extendedMonthEndDates);
|
||||||
// 批量查询历史余额数据
|
// 批量查询历史余额数据
|
||||||
Map<String, BigDecimal> historyData = batchQueryHistoryBalance(section, saleOrgUnits, custNames, extendedMonthEndDates);
|
// Map<String, BigDecimal> historyData = batchQueryHistoryBalance(section, saleOrgUnits, custNames, extendedMonthEndDates);
|
||||||
// 计算所有需要的指标
|
// 计算所有需要的指标
|
||||||
calculateAllMetrics(results, ysData, skData, sktkData, historyData, saleOrgUnits, custNames, monthEndDates,extendedMonthEndDates);
|
calculateAllMetrics(results, ysData, skData, sktkData, historicalBalanceData, saleOrgUnits, custNames, monthEndDates,extendedMonthEndDates);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.error("预加载数据时发生错误", e);
|
LOGGER.error("预加载数据时发生错误", e);
|
||||||
}
|
}
|
||||||
@ -453,7 +600,7 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
*/
|
*/
|
||||||
private Map<String, BigDecimal> batchQueryHistoryBalance(Section section, List<String> saleOrgUnits,
|
private Map<String, BigDecimal> batchQueryHistoryBalance(Section section, List<String> saleOrgUnits,
|
||||||
List<String> custNames, List<LocalDate> monthEndDates) {
|
List<String> custNames, List<LocalDate> monthEndDates) {
|
||||||
|
List<String> arrayList = new ArrayList<>();
|
||||||
Map<String, BigDecimal> result = new HashMap<>();
|
Map<String, BigDecimal> result = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -490,7 +637,8 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
*/
|
*/
|
||||||
private void calculateAllMetrics(Map<String, BigDecimal> results,
|
private void calculateAllMetrics(Map<String, BigDecimal> results,
|
||||||
Map<String, BigDecimal> ysData, Map<String, BigDecimal> skData,
|
Map<String, BigDecimal> ysData, Map<String, BigDecimal> skData,
|
||||||
Map<String, BigDecimal> sktkData, Map<String, BigDecimal> historyData,
|
Map<String, BigDecimal> sktkData,
|
||||||
|
Map<String, Map<String, Double>> historicalBalanceData, // 新增参数
|
||||||
List<String> saleOrgUnits, List<String> custNames, List<LocalDate> monthEndDates,
|
List<String> saleOrgUnits, List<String> custNames, List<LocalDate> monthEndDates,
|
||||||
List<LocalDate> extendedMonthEndDates) {
|
List<LocalDate> extendedMonthEndDates) {
|
||||||
|
|
||||||
@ -521,7 +669,7 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
BigDecimal ysye = qcye.add(ljxs).subtract(ljhk);
|
BigDecimal ysye = qcye.add(ljxs).subtract(ljhk);
|
||||||
|
|
||||||
// 计算账龄分析
|
// 计算账龄分析
|
||||||
Map<String, BigDecimal> zlfx = calculateAgingAnalysis(historyData, saleOrgUnit, custName, monthEndDate, ysye);
|
Map<String, BigDecimal> zlfx = calculateAgingAnalysis(historicalBalanceData, saleOrgUnit, custName, monthEndDate, qcye);
|
||||||
|
|
||||||
// 存储计算结果
|
// 存储计算结果
|
||||||
results.put(keyPrefix + "QCYE_" + monthEndDate, qcye);
|
results.put(keyPrefix + "QCYE_" + monthEndDate, qcye);
|
||||||
@ -532,9 +680,9 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
// LOGGER.info("计算{}:{}",keyPrefix + "LJXS_" + monthEndDate, ljxs);
|
// LOGGER.info("计算{}:{}",keyPrefix + "LJXS_" + monthEndDate, ljxs);
|
||||||
// LOGGER.info("计算{}:{}",keyPrefix + "LJHK_" + monthEndDate, ljhk);
|
// LOGGER.info("计算{}:{}",keyPrefix + "LJHK_" + monthEndDate, ljhk);
|
||||||
// LOGGER.info("计算{}:{}",keyPrefix + "YSYE_" + monthEndDate, ysye);
|
// LOGGER.info("计算{}:{}",keyPrefix + "YSYE_" + monthEndDate, ysye);
|
||||||
|
|
||||||
for (Map.Entry<String, BigDecimal> entry : zlfx.entrySet()) {
|
for (Map.Entry<String, BigDecimal> entry : zlfx.entrySet()) {
|
||||||
results.put(keyPrefix + entry.getKey() + "_" + monthEndDate, entry.getValue());
|
results.put(keyPrefix + entry.getKey() + "_" + monthEndDate, entry.getValue());
|
||||||
|
LOGGER.info("KEY:{},value:{}",keyPrefix + entry.getKey() + "_" + monthEndDate,entry.getValue());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.error("计算指标时发生错误,销售组织: {}, 客户: {}, 日期: {}",
|
LOGGER.error("计算指标时发生错误,销售组织: {}, 客户: {}, 日期: {}",
|
||||||
@ -589,37 +737,38 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
/**
|
/**
|
||||||
* 计算账龄分析
|
* 计算账龄分析
|
||||||
*/
|
*/
|
||||||
private Map<String, BigDecimal> calculateAgingAnalysis(Map<String, BigDecimal> historyData,
|
private Map<String, BigDecimal> calculateAgingAnalysis(Map<String, Map<String, Double>> historicalBalanceData,
|
||||||
String saleOrgUnit, String custName, LocalDate currentDate, BigDecimal currentBalance) {
|
String saleOrgUnit, String custName, LocalDate currentDate, BigDecimal openingBalance) {
|
||||||
|
|
||||||
Map<String, BigDecimal> result = new HashMap<>();
|
Map<String, BigDecimal> result = new HashMap<>();
|
||||||
String keyPrefix = saleOrgUnit + "_" + custName + "_";
|
String key = saleOrgUnit + "_" + custName;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 计算各个时间点的历史余额
|
// 从预加载的历史余额数据中获取该客户的数据
|
||||||
LocalDate date60DaysAgo = currentDate.minusDays(60);
|
Map<String, Double> balanceMap = historicalBalanceData.get(key);
|
||||||
LocalDate date1YearAgo = currentDate.minusYears(1);
|
|
||||||
LocalDate date2YearsAgo = currentDate.minusYears(2);
|
if (balanceMap == null) {
|
||||||
LocalDate date3YearsAgo = currentDate.minusYears(3);
|
LOGGER.warn("未找到客户 {} 的历史余额数据", key);
|
||||||
LocalDate date4YearsAgo = currentDate.minusYears(4);
|
balanceMap = new HashMap<>();
|
||||||
LocalDate date5YearsAgo = currentDate.minusYears(5);
|
}
|
||||||
|
|
||||||
// 查找历史余额
|
// 查找历史余额
|
||||||
BigDecimal balance60DaysAgo = findHistoricalBalance(historyData, keyPrefix, date60DaysAgo);
|
BigDecimal balance60DaysAgo = BigDecimal.valueOf(balanceMap.get("60天"));
|
||||||
BigDecimal balance1YearAgo = findHistoricalBalance(historyData, keyPrefix, date1YearAgo);
|
BigDecimal balance1YearAgo = BigDecimal.valueOf(balanceMap.get("1年"));
|
||||||
BigDecimal balance2YearsAgo = findHistoricalBalance(historyData, keyPrefix, date2YearsAgo);
|
BigDecimal balance2YearsAgo = BigDecimal.valueOf(balanceMap.get("2年"));
|
||||||
BigDecimal balance3YearsAgo = findHistoricalBalance(historyData, keyPrefix, date3YearsAgo);
|
BigDecimal balance3YearsAgo = BigDecimal.valueOf(balanceMap.get("3年"));
|
||||||
BigDecimal balance4YearsAgo = findHistoricalBalance(historyData, keyPrefix, date4YearsAgo);
|
BigDecimal balance4YearsAgo = BigDecimal.valueOf(balanceMap.get("4年"));
|
||||||
BigDecimal balance5YearsAgo = findHistoricalBalance(historyData, keyPrefix, date5YearsAgo);
|
BigDecimal balance5YearsAgo = BigDecimal.valueOf(balanceMap.get("5年"));
|
||||||
|
BigDecimal balance5YearsLastAgo = BigDecimal.valueOf(balanceMap.get("5年以上"));
|
||||||
|
|
||||||
// 计算各账龄段金额
|
// 计算各账龄段金额
|
||||||
result.put("ZLFX0_60", currentBalance.subtract(balance60DaysAgo.max(BigDecimal.ZERO)));
|
result.put("ZLFX0_60", balance60DaysAgo.subtract(openingBalance));
|
||||||
result.put("ZLFX60_1", balance60DaysAgo.subtract(balance1YearAgo.max(BigDecimal.ZERO)));
|
result.put("ZLFX60_1", balance1YearAgo.subtract(balance60DaysAgo).subtract(openingBalance));
|
||||||
result.put("ZLFX1_2", balance1YearAgo.subtract(balance2YearsAgo.max(BigDecimal.ZERO)));
|
result.put("ZLFX1_2", balance2YearsAgo.subtract(balance1YearAgo).subtract(openingBalance));
|
||||||
result.put("ZLFX2_3", balance2YearsAgo.subtract(balance3YearsAgo.max(BigDecimal.ZERO)));
|
result.put("ZLFX2_3", balance3YearsAgo.subtract(balance2YearsAgo).subtract(openingBalance));
|
||||||
result.put("ZLFX3_4", balance3YearsAgo.subtract(balance4YearsAgo.max(BigDecimal.ZERO)));
|
result.put("ZLFX3_4", balance4YearsAgo.subtract(balance3YearsAgo).subtract(openingBalance));
|
||||||
result.put("ZLFX4_5", balance4YearsAgo.subtract(balance5YearsAgo.max(BigDecimal.ZERO)));
|
result.put("ZLFX4_5", balance5YearsAgo.subtract(balance4YearsAgo).subtract(openingBalance));
|
||||||
result.put("ZLFX5", balance5YearsAgo.max(BigDecimal.ZERO));
|
result.put("ZLFX5", balance5YearsLastAgo);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.error("计算账龄分析时发生错误,销售组织: {}, 客户: {}", saleOrgUnit, custName, e);
|
LOGGER.error("计算账龄分析时发生错误,销售组织: {}, 客户: {}", saleOrgUnit, custName, e);
|
||||||
@ -636,18 +785,6 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 查找历史余额
|
|
||||||
*/
|
|
||||||
private BigDecimal findHistoricalBalance(Map<String, BigDecimal> historyData, String keyPrefix, LocalDate targetDate) {
|
|
||||||
// 调整为目标月份的月末日期
|
|
||||||
LocalDate monthEndDate = targetDate.withDayOfMonth(targetDate.lengthOfMonth());
|
|
||||||
String dateKey = monthEndDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
|
||||||
String fullKey = keyPrefix + dateKey;
|
|
||||||
|
|
||||||
return historyData.getOrDefault(fullKey, BigDecimal.ZERO);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建IN查询条件
|
* 构建IN查询条件
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user