|
|
@@ -1,10 +1,13 @@
|
|
|
package com.kingdee.eas.custom.wamke.syncdata.utils;
|
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
import java.sql.SQLException;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.HashMap;
|
|
|
+import java.util.HashSet;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.apache.log4j.Logger;
|
|
|
@@ -12,9 +15,19 @@ import com.kingdee.bos.BOSException;
|
|
|
import com.kingdee.bos.Context;
|
|
|
import com.kingdee.bos.metadata.bot.NumricRuleSegmentInfo;
|
|
|
import com.kingdee.bos.openapi.third.exception.BizException;
|
|
|
+import com.kingdee.bos.util.backport.Arrays;
|
|
|
import com.kingdee.eas.common.EASBizException;
|
|
|
+import com.kingdee.eas.util.ToolUtils;
|
|
|
import com.kingdee.eas.util.app.DbUtil;
|
|
|
import com.kingdee.jdbc.rowset.IRowSet;
|
|
|
+import com.kingdee.shr.compensation.CalSchemeCollection;
|
|
|
+import com.kingdee.shr.compensation.CalSchemeFactory;
|
|
|
+import com.kingdee.shr.compensation.CalSchemeInfo;
|
|
|
+import com.kingdee.shr.compensation.CalSchemeItemCollection;
|
|
|
+import com.kingdee.shr.compensation.CalSchemeItemFactory;
|
|
|
+import com.kingdee.shr.compensation.CalSchemeItemInfo;
|
|
|
+import com.kingdee.shr.compensation.ICalScheme;
|
|
|
+import com.kingdee.shr.compensation.ICalSchemeItem;
|
|
|
import com.kingdee.util.NumericException;
|
|
|
|
|
|
|
|
|
@@ -26,16 +39,34 @@ public class AttSalaryCalculator {
|
|
|
private static final Logger logger = Logger.getLogger(AttSalaryCalculator.class);
|
|
|
|
|
|
|
|
|
+ public void scheduledTask(Context ctx) throws BOSException{
|
|
|
+ ICalScheme calIns = CalSchemeFactory.getLocalInstance(ctx);
|
|
|
+ CalSchemeCollection calSchemeCollection = calIns.getCalSchemeCollection(" where state = 1 ") ;
|
|
|
+ for(int i = 0; i< calSchemeCollection.size() ;i ++){
|
|
|
+ CalSchemeInfo calSchemeInfo = calSchemeCollection.get(i);
|
|
|
+ calculateSalaryItems(ctx, null, calSchemeInfo.getId().toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 使用单次查询和内存计算的高效方法
|
|
|
* @throws BOSException
|
|
|
*/
|
|
|
- public int calculateSalaryItems (Context ctx,String filterSql) throws BOSException {
|
|
|
+ public int calculateSalaryItems (Context ctx,String filterSql,String calruleId ) throws BOSException {
|
|
|
try {
|
|
|
+
|
|
|
+ Map<String, List<String>> cFeild_attNum = SalaryItemCalculatorUtils.getFeild_attMap(ctx, calruleId);
|
|
|
+ //获取cFeild_attNum中的value;
|
|
|
+ List<String> attNumLists = new ArrayList();
|
|
|
+ for(Map.Entry<String, List<String>> entry : cFeild_attNum.entrySet()){
|
|
|
+ attNumLists.addAll(entry.getValue());
|
|
|
+ }
|
|
|
+ if(attNumLists.size() == 0){
|
|
|
+ return 0 ;
|
|
|
+ }
|
|
|
logger.info("开始高效计算工资项...");
|
|
|
// 一次性查询所有需要的数据
|
|
|
- StringBuilder sql = new StringBuilder(
|
|
|
+ StringBuilder dataSql = new StringBuilder(
|
|
|
"/*dialect*/ SELECT " +
|
|
|
" calc.FPersonID, " +
|
|
|
" calc.FPeriodYear, " +
|
|
|
@@ -47,22 +78,24 @@ public class AttSalaryCalculator {
|
|
|
" LEFT JOIN CT_SYN_AttFinalization att ON " +
|
|
|
" att.CFPersonID = calc.FPersonID AND " +
|
|
|
" att. CFAttendanceCycle = CONVERT(VARCHAR(6), calc.FPeriodYear * 100 + calc.FPeriodMonth) " +
|
|
|
- "WHERE calc.fislockothersysdata = 0 " );
|
|
|
+ "WHERE calc.fislockothersysdata = 0 and att.CFSalaryCode IN ("+ ToolUtils.aryToStr(attNumLists,true)+")" );
|
|
|
if(!StringUtils.isEmpty(filterSql)){
|
|
|
- sql.append( " AND calc.fid in ("+filterSql+") ");
|
|
|
-
|
|
|
+ dataSql.append( " AND calc.fid in ("+filterSql+") ");
|
|
|
+ }
|
|
|
+ if(!StringUtils.isEmpty(calruleId)){
|
|
|
+ dataSql.append( " AND calc.FCalSchemeID = '"+calruleId+"' ");
|
|
|
}
|
|
|
|
|
|
- sql.append( " GROUP BY calc.FPersonID, calc.FPeriodYear, calc.FPeriodMonth, att.CFSalaryCode " +
|
|
|
+ dataSql.append( " GROUP BY calc.FPersonID, calc.FPeriodYear, calc.FPeriodMonth, att.CFSalaryCode " +
|
|
|
"ORDER BY calc.FPersonID, calc.FPeriodYear DESC, calc.FPeriodMonth DESC ");
|
|
|
|
|
|
- IRowSet results = DbUtil.executeQuery(ctx, sql.toString()) ;
|
|
|
+ IRowSet results = DbUtil.executeQuery(ctx, dataSql.toString()) ;
|
|
|
|
|
|
// 在内存中组织更新数据
|
|
|
- Map<String, Map<String, Object>> updateData = organizeUpdateData(ctx,results);
|
|
|
+ Map<String, Map<String, Object>> updateData = organizeUpdateData(ctx,results, cFeild_attNum);
|
|
|
|
|
|
// 执行批量更新
|
|
|
- return executeBatchUpdates(ctx,updateData);
|
|
|
+ return executeBatchUpdates(ctx,updateData , cFeild_attNum);
|
|
|
// logger.error("工资项计算完成,处理了 {} 条记录", results.size());
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
@@ -75,7 +108,7 @@ public class AttSalaryCalculator {
|
|
|
* 更新数据
|
|
|
* @throws SQLException
|
|
|
*/
|
|
|
- private Map<String, Map<String, Object>> organizeUpdateData(Context ctx,IRowSet results) throws SQLException {
|
|
|
+ private Map<String, Map<String, Object>> organizeUpdateData(Context ctx,IRowSet results,Map<String,List<String>> com_attNum) throws SQLException {
|
|
|
Map<String, Map<String, Object>> updateMap = new HashMap<String, Map<String, Object>>();
|
|
|
|
|
|
while(results.next()){
|
|
|
@@ -104,32 +137,65 @@ public class AttSalaryCalculator {
|
|
|
personData.put("FPeriodMonth", month);
|
|
|
updateMap.put(key, personData);
|
|
|
}
|
|
|
-
|
|
|
- // 根据工资项编码设置对应的字段值
|
|
|
- String fieldName = getFieldName(ctx,salaryCode);
|
|
|
- if (fieldName != null) {
|
|
|
- personData.put(fieldName, totalValue);
|
|
|
- }
|
|
|
+ // 根据考勤编码设置对应的字段值
|
|
|
+ personData.put(salaryCode, totalValue);
|
|
|
+ //personData , key:value 考勤编码: 考勤值
|
|
|
}
|
|
|
|
|
|
- return updateMap;
|
|
|
+ //循环updateMap,整理personData中的数据,根据com_attNum整理拿到对应的考勤项
|
|
|
+ Map<String, Map<String, Object>> newUpdateMap = new HashMap<String, Map<String, Object>>();
|
|
|
+ for(Map.Entry<String, Map<String, Object>> entry : updateMap.entrySet()){
|
|
|
+ String key = entry.getKey();
|
|
|
+ Map<String, Object> personData = entry.getValue();
|
|
|
+ Map<String, Object> newPersonData = new HashMap<String, Object>();
|
|
|
+ // 保留基本信息
|
|
|
+ newPersonData.put("FPersonID", personData.get("FPersonID"));
|
|
|
+ newPersonData.put("FPeriodYear", personData.get("FPeriodYear"));
|
|
|
+ newPersonData.put("FPeriodMonth", personData.get("FPeriodMonth"));
|
|
|
+
|
|
|
+ // 处理考勤项
|
|
|
+ for(Map.Entry<String, List<String>> com_att : com_attNum.entrySet()){
|
|
|
+ BigDecimal value = calculateAttendanceValue(personData, com_att.getValue());
|
|
|
+ newPersonData.put(com_att.getKey(), value);
|
|
|
+ }
|
|
|
+ newUpdateMap.put(key, newPersonData);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ return newUpdateMap;
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+ // 提取的方法
|
|
|
+ private BigDecimal calculateAttendanceValue(Map<String, Object> personData, List<String> attNumList) {
|
|
|
+ BigDecimal result = BigDecimal.ZERO;
|
|
|
+ for(String attNum : attNumList) {
|
|
|
+ Object val = personData.get(attNum);
|
|
|
+ if(val != null) {
|
|
|
+ try {
|
|
|
+ result = result.add(new BigDecimal(val.toString()));
|
|
|
+ } catch(NumberFormatException e) {
|
|
|
+ // 忽略非数字值
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* 批量更新方法
|
|
|
* @throws SQLException
|
|
|
* @throws BOSException
|
|
|
*/
|
|
|
- private int executeBatchUpdates(Context ctx, Map<String, Map<String, Object>> updateData) throws BOSException, SQLException {
|
|
|
+ private int executeBatchUpdates(Context ctx, Map<String, Map<String, Object>> updateData, Map<String, List<String>> cFeild_attNum) throws BOSException, SQLException {
|
|
|
int allCount = 0;
|
|
|
// 为每个工资项字段分别执行批量更新
|
|
|
//先更新
|
|
|
- SalaryItemCalculator.addSalaryCodeMapping(ctx);
|
|
|
- Map<String, String> salaryCodeMapping = SalaryItemCalculator.getSalaryCodeMapping();
|
|
|
- for (Map.Entry<String, String> mapping : salaryCodeMapping.entrySet()) {
|
|
|
- String fieldName = mapping.getValue();
|
|
|
+// SalaryItemCalculator.addSalaryCodeMapping(ctx);
|
|
|
+// Map<String, String> salaryCodeMapping = SalaryItemCalculator.getSalaryCodeMapping();
|
|
|
+ for (Map.Entry<String, List<String>> mapping : cFeild_attNum.entrySet()) {
|
|
|
+ String feildName = mapping.getKey();
|
|
|
|
|
|
// 构建当前工资项的批量更新参数
|
|
|
List<Object[]> batchParams = new ArrayList<Object[]>();
|
|
|
@@ -138,7 +204,12 @@ public class AttSalaryCalculator {
|
|
|
String personId = (String) personData.get("FPersonID");
|
|
|
Integer year = (Integer) personData.get("FPeriodYear");
|
|
|
Integer month = (Integer) personData.get("FPeriodMonth");
|
|
|
- Object value = personData.get(fieldName);
|
|
|
+ Object value = personData.get(feildName);
|
|
|
+ //为0则清空
|
|
|
+ if (value == null || (value instanceof Number && ((Number) value).intValue() == 0)) {
|
|
|
+ value = null;
|
|
|
+ }
|
|
|
+
|
|
|
//可以清空
|
|
|
// if (value != null) {
|
|
|
// 参数顺序: 字段值, 人员ID, 年度, 月份
|
|
|
@@ -150,7 +221,7 @@ public class AttSalaryCalculator {
|
|
|
|
|
|
// 执行批量更新
|
|
|
if (!batchParams.isEmpty()) {
|
|
|
- String updateSql = "UPDATE T_HR_SCmpCalTable SET " + fieldName + " = ? " +
|
|
|
+ String updateSql = "UPDATE T_HR_SCmpCalTable SET " + feildName + " = ? " +
|
|
|
"WHERE FPersonID = ? AND FPeriodYear = ? AND FPeriodMonth = ?";
|
|
|
|
|
|
// 使用您现有的DBUtils批量更新方法
|
|
|
@@ -165,14 +236,5 @@ public class AttSalaryCalculator {
|
|
|
return allCount;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- /**
|
|
|
- * 根据工资项编码获取字段名
|
|
|
- */
|
|
|
- private String getFieldName(Context ctx,String salaryCode) {
|
|
|
- // 使用相同的映射配置
|
|
|
- SalaryItemCalculator.addSalaryCodeMapping(ctx);
|
|
|
- Map<String, String> salaryCodeMapping = SalaryItemCalculator.getSalaryCodeMapping();
|
|
|
- return salaryCodeMapping.get(salaryCode);
|
|
|
- }
|
|
|
+
|
|
|
}
|