SalaryBag2EditHandler.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. package com.kingdee.customer.salary.handler;
  2. import java.math.BigDecimal;
  3. import java.math.RoundingMode;
  4. import java.sql.SQLException;
  5. import java.text.ParseException;
  6. import java.text.SimpleDateFormat;
  7. import java.util.ArrayList;
  8. import java.util.Calendar;
  9. import java.util.Date;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Locale;
  13. import java.util.Map;
  14. import javax.servlet.http.HttpServletRequest;
  15. import javax.servlet.http.HttpServletResponse;
  16. import org.apache.commons.lang3.StringUtils;
  17. import org.apache.log4j.Logger;
  18. import org.springframework.ui.ModelMap;
  19. import com.kingdee.bos.BOSException;
  20. import com.kingdee.bos.Context;
  21. import com.kingdee.bos.dao.IObjectPK;
  22. import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
  23. import com.kingdee.eas.common.EASBizException;
  24. import com.kingdee.eas.custom.bill.salary.ISalaryBag;
  25. import com.kingdee.eas.custom.bill.salary.SalaryBagEntryCollection;
  26. import com.kingdee.eas.custom.bill.salary.SalaryBagEntryInfo;
  27. import com.kingdee.eas.custom.bill.salary.SalaryBagFactory;
  28. import com.kingdee.eas.custom.bill.salary.SalaryBagInfo;
  29. import com.kingdee.eas.framework.CoreBaseInfo;
  30. import com.kingdee.eas.hr.affair.EmpEnrollBizBillEntryInfo;
  31. import com.kingdee.eas.hr.base.HRBillStateEnum;
  32. import com.kingdee.eas.util.app.DbUtil;
  33. import com.kingdee.jdbc.rowset.IRowSet;
  34. import com.kingdee.shr.base.syssetting.app.io.fileImport.ImportException;
  35. import com.kingdee.shr.base.syssetting.context.SHRContext;
  36. import com.kingdee.shr.base.syssetting.exception.SHRWebException;
  37. import com.kingdee.shr.base.syssetting.exception.ShrWebBizException;
  38. import com.kingdee.shr.base.syssetting.util.MetaDataUtil;
  39. import com.kingdee.shr.base.syssetting.web.handler.EditHandler;
  40. import com.kingdee.shr.base.syssetting.web.json.JSONUtils;
  41. import com.kingdee.shr.compensation.CmpItemInfo;
  42. /**
  43. * 工资包编辑处理器
  44. * @author issuser
  45. *
  46. */
  47. public class SalaryBag2EditHandler extends EditHandler {
  48. private static Logger logger =
  49. Logger.getLogger("com.kingdee.customer.salary.handler.SalaryBagEditHandler");
  50. /**
  51. * 生成工资包的数据明细
  52. * @param request HTTP请求对象,包含前端传来的工资包信息
  53. * @param response HTTP响应对象,用于向前端返回结果
  54. * @param modelMap ModelMap对象,用于在请求处理过程中传递数据
  55. */
  56. public void createEntryDetailAction(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) {
  57. // 从HTTP请求中获取开始日期、结束日期、补发日期、总金额、工资包ID等参数
  58. String startDateStr = request.getParameter("startDate");
  59. String endDateStr = request.getParameter("endDate");
  60. String reissueDateStr = request.getParameter("reissueDate");
  61. String money = request.getParameter("money");
  62. String billId = request.getParameter("billId");
  63. // 获取业务上下文
  64. Context ctx = SHRContext.getInstance().getContext();
  65. try {
  66. // 构建查询SQL语句,用于获取指定工资包ID的相关信息
  67. String selectSql = "SELECT b.fid as personId,b.FNAME_l2 as personName,"
  68. + " c.FID as cmpItemId ,c.FNAME_l2 as cmpItemName,a.CFPaycurrency,a.CFendDate "
  69. + " FROM CT_SAL_SalaryBag a "
  70. + " left join t_bd_person b on a.CFPersonID = b.FID "
  71. + " left join T_HR_SCmpItem c on a.CFCmpItemID = c.fid "
  72. + " where a.fid = '" + billId + "'";
  73. System.out.println("工资包变更sql=========" + selectSql);
  74. // 执行查询操作
  75. IRowSet rs = DbUtil.executeQuery(ctx, selectSql.toString());
  76. String cmpItemId = null;
  77. String cmpItemName = null;
  78. String paycurrency = null;
  79. Date soureEndDate = null;
  80. if (rs.next()) {
  81. // 从查询结果中取出相关信息
  82. cmpItemId = rs.getString("cmpItemId");
  83. cmpItemName = rs.getString("cmpItemName");
  84. paycurrency = rs.getString("CFPaycurrency");
  85. soureEndDate = rs.getDate("CFendDate");
  86. }
  87. // 创建日期格式化对象
  88. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  89. // 解析前端传来的结束日期和补发日期
  90. Date endDate = sdf.parse(endDateStr);
  91. Date reissueDate = sdf.parse(reissueDateStr);
  92. // 验证结束日期是否早于原始文档的过期日期
  93. if (soureEndDate.after(endDate)) {
  94. throw new ImportException("新的过期日期不能早于原始文档的过期日期");
  95. }
  96. // 获取月份明细列表,即从开始日期到结束日期之间的所有月份
  97. List<Date> monthList = getMonthDetail(startDateStr, endDateStr);
  98. System.out.println("月份=========" + monthList.size());
  99. // 创建结果列表,用于存储每个月份的工资包明细
  100. List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
  101. // 创建总金额对象,并将其转换为BigDecimal类型
  102. BigDecimal moneyAmount = new BigDecimal(money);
  103. // 设置保留的小数位数为两位,并根据金额大小选择合适的取整模式
  104. int scale = 2; // 保留两位小数
  105. RoundingMode roundingMode = (moneyAmount.compareTo(BigDecimal.ZERO) < 0)
  106. ? RoundingMode.HALF_DOWN // 负数时向下取整
  107. : RoundingMode.HALF_UP; // 正数时四舍五入
  108. // 计算平均分配到每个月的金额
  109. BigDecimal avgAmount = moneyAmount.divide(BigDecimal.valueOf(monthList.size()), scale, roundingMode);
  110. // 初始化已生成额度的金额和补发月应发金额
  111. BigDecimal remainder = new BigDecimal(0);
  112. BigDecimal amountPayable = new BigDecimal(0);
  113. // 遍历每个月份,生成相应的工资包明细
  114. for (int i = 0; i < monthList.size(); i++) {
  115. Map<String, Object> entryMap = new HashMap<String, Object>();
  116. // 获取当前月份
  117. Date months = monthList.get(i);
  118. // 将月份信息和其他相关数据放入entryMap中
  119. entryMap.put("months", months);
  120. entryMap.put("paycurrency", paycurrency);
  121. entryMap.put("cmpItemId", cmpItemId);
  122. entryMap.put("cmpItemName", cmpItemName);
  123. // 如果不是最后一个月,则将平均金额加到已生成额度的金额中
  124. if (monthList.size() - i > 1) {
  125. remainder = remainder.add(avgAmount);
  126. } else {
  127. // 如果是最后一个月,则计算最后一个月的实际金额
  128. avgAmount = moneyAmount.subtract(remainder);
  129. }
  130. // 将平均金额放入entryMap中
  131. entryMap.put("moneys", avgAmount);
  132. // 获取变更前的金额
  133. BigDecimal beforeAmount = getBeforeAmount(billId, sdf.format(months));
  134. // 将变更前的金额放入entryMap中
  135. entryMap.put("beforeAmount", beforeAmount);
  136. // 根据当前月份与补发日期的关系,计算应发金额和补发金额
  137. if (monthList.get(i).equals(reissueDate)) {
  138. // 如果当前月份等于补发日期,不应发补发金额,应发金额为平均金额
  139. entryMap.put("reissueAmount", 0);
  140. entryMap.put("amountPayable", amountPayable.add(avgAmount));
  141. } else if (monthList.get(i).after(reissueDate)) {
  142. // 如果当前月份晚于补发日期,不应发补发金额,应发金额为平均金额
  143. entryMap.put("amountPayable", avgAmount);
  144. entryMap.put("reissueAmount", 0);
  145. } else {
  146. // 如果当前月份早于补发日期,应发金额为0,补发金额为平均金额减去变更前金额
  147. entryMap.put("amountPayable", 0);
  148. entryMap.put("reissueAmount", avgAmount.subtract(beforeAmount));
  149. // 更新总应发差额
  150. amountPayable = amountPayable.add(avgAmount.subtract(beforeAmount));
  151. }
  152. // 输出当前月份的工资包明细
  153. System.out.println("月份result=========" + entryMap);
  154. // 将entryMap添加到结果列表中
  155. resultList.add(entryMap);
  156. }
  157. // 将结果列表以JSON格式写入HTTP响应中,返回给前端
  158. JSONUtils.writeJson(response, resultList);
  159. } catch (BOSException e) {
  160. // 捕获并打印业务异常信息
  161. e.printStackTrace();
  162. } catch (ParseException e) {
  163. // 捕获并打印日期解析异常信息
  164. e.printStackTrace();
  165. } catch (SHRWebException e) {
  166. // 捕获并打印Web异常信息
  167. e.printStackTrace();
  168. } catch (SQLException e) {
  169. // 捕获并打印SQL异常信息
  170. e.printStackTrace();
  171. }
  172. }
  173. /**
  174. * 获取指定工资包ID和月份的变更前金额
  175. * @param billId 工资包ID
  176. * @param months 指定月份
  177. * @return 变更前的金额
  178. * @throws BOSException 业务异常
  179. * @throws SQLException SQL异常
  180. */
  181. private BigDecimal getBeforeAmount(String billId, String months) throws BOSException, SQLException {
  182. // 获取业务上下文
  183. Context ctx = SHRContext.getInstance().getContext();
  184. // 初始化变更前的金额为0
  185. BigDecimal beforeAmount = new BigDecimal(0);
  186. // 构建查询SQL语句,用于获取指定工资包ID和月份的变更前金额
  187. String selectSql = "SELECT CFMoneys FROM CT_SAL_SalaryBagEntry where FBillID = '" + billId + "' and to_char(CFMonths,'yyyy-MM-dd') = '" + months + "'";
  188. System.out.println("查找变更前金额=========" + selectSql);
  189. // 执行查询操作
  190. IRowSet rs = DbUtil.executeQuery(ctx, selectSql.toString());
  191. if (rs.next()) {
  192. // 从查询结果中取出变更前的金额
  193. beforeAmount = rs.getBigDecimal("CFMoneys");
  194. }
  195. // 返回变更前的金额
  196. return beforeAmount;
  197. }
  198. /**
  199. * 根据开始日期和结束日期,生成月份明细列表
  200. * @param startDateStr 开始日期字符串
  201. * @param endDateStr 结束日期字符串
  202. * @return 月份明细列表
  203. * @throws ParseException 日期解析异常
  204. */
  205. private List<Date> getMonthDetail(String startDateStr, String endDateStr) throws ParseException {
  206. // 创建日期格式化对象,只提取年月信息
  207. SimpleDateFormat sdfMonth = new SimpleDateFormat("yyyy-MM");
  208. // 解析开始日期和结束日期
  209. Date startDate = sdfMonth.parse(startDateStr);
  210. Date endDate = sdfMonth.parse(endDateStr);
  211. Date currentDate = startDate;
  212. // 创建月份列表
  213. List<Date> monthList = new ArrayList<Date>();
  214. // 创建Calendar实例,用于月份计算
  215. Calendar calendar = Calendar.getInstance();
  216. // 当前日期小于等于结束日期时,继续循环
  217. while (endDate.after(currentDate) || currentDate.equals(endDate)) {
  218. // 将当前日期添加到月份列表中
  219. monthList.add(currentDate);
  220. // 设置Calendar的时间为当前日期
  221. calendar.setTime(currentDate);
  222. // 将Calendar的时间增加一个月
  223. calendar.add(Calendar.MONTH, 1);
  224. // 更新当前日期为增加一个月后的日期
  225. currentDate = calendar.getTime();
  226. }
  227. // 返回月份明细列表
  228. return monthList;
  229. }
  230. }