c7cccc9e34f5c1f68ac9cae9bc76432b97dd1475.svn-base 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213
  1. package com.kingdee.eas.custom.facade.leave;
  2. import com.grapecity.documents.excel.D;
  3. import com.kingdee.bos.dao.IObjectPK;
  4. import com.kingdee.bos.dao.ormapping.ObjectUuidPK;
  5. import com.kingdee.bos.util.BOSUuid;
  6. import com.kingdee.eas.basedata.org.AdminOrgUnitInfo;
  7. import com.kingdee.eas.basedata.org.CtrlUnitInfo;
  8. import com.kingdee.eas.basedata.org.HROrgUnitInfo;
  9. import com.kingdee.eas.basedata.org.PositionInfo;
  10. import com.kingdee.eas.basedata.person.PersonInfo;
  11. import com.kingdee.eas.custom.bd.param.ParamCollection;
  12. import com.kingdee.eas.custom.bd.param.ParamFactory;
  13. import com.kingdee.eas.hr.ats.*;
  14. import com.kingdee.eas.util.app.ContextUtil;
  15. import com.kingdee.util.DateTimeUtils;
  16. import org.apache.commons.lang3.StringUtils;
  17. import org.apache.log4j.Logger;
  18. import java.math.BigDecimal;
  19. import java.math.RoundingMode;
  20. import java.sql.SQLException;
  21. import java.sql.Timestamp;
  22. import java.text.ParseException;
  23. import java.text.SimpleDateFormat;
  24. import java.util.*;
  25. import com.kingdee.bos.*;
  26. //import com.kingdee.bos.metadata.entity.EntityViewInfo;
  27. //import com.kingdee.bos.dao.IObjectPK;
  28. import com.kingdee.eas.common.EASBizException;
  29. import com.kingdee.eas.framework.CoreBaseCollection;
  30. import com.kingdee.eas.util.app.DbUtil;
  31. import com.kingdee.jdbc.rowset.IRowSet;
  32. /**
  33. * 假期额度相关后台事务类
  34. * @author xiaoxin
  35. *
  36. */
  37. public class LeaveAllowanceFacadeControllerBean extends AbstractLeaveAllowanceFacadeControllerBean
  38. {
  39. private static Logger logger =
  40. Logger.getLogger("com.kingdee.eas.custom.facade.leave.LeaveAllowanceFacadeControllerBean");
  41. // 员工类别 General Administrative Staff
  42. private static final String WC_General_Administrative_Staff = "General Administrative Staff";
  43. // 员工类别 Professional Supervisory Staff
  44. private static final String WC_Professional_Supervisory_Staff = "Professional Supervisory Staff";
  45. // 员工类别 Senior Administrative Staff
  46. private static final String WC_Senior_Administrative_Staff = "Senior Administrative Staff";
  47. private static final String WC_Academic_Staff = "Academic Staff";
  48. private static final String WC_Others = "Others";
  49. // 年假初始值 General_Administrative_Staff
  50. private static final int IV_General_Administrative_Staff = 12;
  51. // 年假初始值 Professional_Supervisory_Staff
  52. private static final int IV_Professional_Supervisory_Staff = 15;
  53. // 年假初始值 Senior_Administrative_Staff
  54. private static final int IV_Senior_Administrative_Staff = 18;
  55. private static final int IV_Year = 2;
  56. private static final int IV_YearAddValue = 1;
  57. private static final int IV_MAXADD = 8;
  58. private static final int MONTH_NUM_12 = 12;
  59. // 年假折算方式
  60. private static final String PARAM_ANNUALLEAVE_CONVERSIONMETHOD = "param_001";
  61. // 年假取整方式
  62. private static final String PARAM_ANNUALLEAVE_INTEGERMETHOD = "param_002";
  63. // 年假取整精度
  64. private static final String PARAM_ANNUALLEAVE_INTEGERPERCISION = "param_003";
  65. // 年假结转日期
  66. private static final String PARAM_ANNUALLEAVE_CONVERTDATE = "param_004";
  67. // 生成下年度额度日期
  68. private static final String PARAM_ANNUALLEAVE_GENERATEDAY = "param_005";
  69. // 护理假额度
  70. private static final String PARAM_NURSINGLEAVE_LIMIT = "param_006";
  71. // 育儿假额度
  72. private static final String PARAM_PARENTALLEAVE_LIMIT = "param_007";
  73. // 护理育儿折算方式
  74. private static final String PARAM_NURSINGANDPARENTALLEAVE_CONVERSIONMETHOD = "param_008";
  75. // 护理育儿取整方式
  76. private static final String PARAM_NURSINGANDPARENTALLEAVE_INTEGERMETHOD = "param_009";
  77. // 护理育儿取整精度
  78. private static final String PARAM_NURSINGANDPARENTALLEAVE_INTEGERPERCISION = "param_010";
  79. // 育儿护理多段统计是否更新视图脚本
  80. private static final String PARAM_NURSINGANDPARENTALLEAVE_UPDATESQL = "param_011";
  81. // 折算方式 按日
  82. private static final String CONVERSIONMETHOD_BYDAY = "D";
  83. // 折算方式 按月
  84. private static final String CONVERSIONMETHOD_BYMONTH = "M";
  85. // 取整方式 向上
  86. private static final String INTEGERMETHOD_UP = "U";
  87. // 取整方式 向下
  88. private static final String INTEGERMETHOD_DOWN = "D";
  89. // 取整精度 0.5
  90. private static final double INTEGERPERCISION_HALF = 0.5;
  91. // 取整精度 1
  92. private static final double INTEGERPERCISION_ONE = 1;
  93. // 年假折算
  94. private static String annualLeaveConversionMethod;
  95. // 年假取整
  96. private static String annualLeaveIntegerMethod;
  97. // 年假取整精度
  98. private static double annualLeaveIntegerPrecision;
  99. // 结转日期
  100. private static String annualLeaveConvertDate;
  101. // 下年度额度生成
  102. private static String annualLeaveGenerateDay;
  103. // 育儿假额度
  104. private static int nursingLeaveLimit;
  105. // 护理假额度
  106. private static int parentalLeaveLimit;
  107. // 护理育儿折算
  108. private static String nursingAndParentalLeaveConversionMethod;
  109. // 护理育儿取整
  110. private static String nursingAndParentalLeaveIntegerMethod;
  111. // 护理育儿取整精度
  112. private static double nursingAndParentalLeaveIntegerPrecision;
  113. // 育儿护理多段统计是否更新视图脚本
  114. private static String nursingAndParentalLeaveUpdateSql;
  115. /**
  116. * 年假额度生成 JQLX000001Y
  117. */
  118. @Override
  119. protected void _createAnnualLeave(Context ctx, int year, String personNum) throws BOSException {
  120. try {
  121. // 初始化公共变量
  122. initialGlobalParam(ctx);
  123. // 是否生成下年年假额度
  124. Boolean isGenerateNextYearAnnualLeave = false;
  125. // 当前时间
  126. Date currentDate = new Date();
  127. if (year != 0) {
  128. currentDate = DateTimeUtils.parseDate(year + "-12-31");
  129. } else {
  130. year = DateTimeUtils.getYear(currentDate);
  131. Date annualLeaveGenerateDay = DateTimeUtils.parseDate(year + "-" + LeaveAllowanceFacadeControllerBean.annualLeaveGenerateDay);
  132. if (currentDate.getTime() >= annualLeaveGenerateDay.getTime()) {
  133. isGenerateNextYearAnnualLeave = true;
  134. }
  135. }
  136. // 年假额度生成
  137. generateAnnualLeave(ctx, year, personNum, currentDate);
  138. // 下年年假额度生成
  139. if (isGenerateNextYearAnnualLeave) {
  140. int nextYear = year + 1;
  141. Date nextYearCurrentDay = DateTimeUtils.addYear(currentDate, 1);
  142. generateAnnualLeave(ctx, nextYear, personNum, nextYearCurrentDay);
  143. }
  144. } catch (ParseException e) {
  145. throw new BOSException(e);
  146. }
  147. }
  148. /**
  149. * 年假额度生成
  150. * @param ctx
  151. * @param year
  152. * @param personNum
  153. * @throws BOSException
  154. */
  155. private void generateAnnualLeave(Context ctx, int year, String personNum, Date currentDate) throws BOSException {
  156. try {
  157. Date nowDate = new Date();
  158. // 考勤制度和年假id对应
  159. Map<String, String> holidayPolicyMap = new HashMap<String, String>();
  160. String holidayPolicySql = "select hps.FNUMBER, hp.fid from T_HR_ATS_HolidayPolicy hp left join T_HR_ATS_HolidayPolicySet hps on hp.FHOLIDAYPOLICYSETID = hps.fid where FHOLIDAYTYPEID = (select fid from T_HR_ATS_HolidayType where FNUMBER = 'JQLX000001Y')";
  161. IRowSet holidayPolicyRowSet = DbUtil.executeQuery(ctx, holidayPolicySql);
  162. while (holidayPolicyRowSet.next()) {
  163. holidayPolicyMap.put(holidayPolicyRowSet.getString("FNUMBER"), holidayPolicyRowSet.getString("fid"));
  164. }
  165. String currentDateStr = DateTimeUtils.format(currentDate, "yyyy-MM-dd");
  166. // 当前年份第一天
  167. Date yearFirstDay = DateTimeUtils.parseDate(DateTimeUtils.getYear(currentDate) + "-01-01");
  168. // 当前年份最后一天
  169. Date yearLastDay = DateTimeUtils.parseDate(DateTimeUtils.getYear(currentDate) + "-12-31");
  170. List<String> personNumberList = new ArrayList<String>();
  171. CoreBaseCollection addList = new CoreBaseCollection();
  172. CoreBaseCollection updateList = new CoreBaseCollection();
  173. List<String> deleteList = new ArrayList<>();
  174. // 重算列表
  175. List<Map<String, Object>> reCalList = new ArrayList<>();
  176. String personNumStr = "";
  177. if (StringUtils.isNotEmpty(personNum)) {
  178. String[] personNumArr = personNum.split(",");
  179. for (int i = 0; i < personNumArr.length; i++) {
  180. personNumberList.add("'" + personNumArr[i] + "'");
  181. }
  182. personNumStr = String.join(",",personNumberList);
  183. }
  184. String dbType = ContextUtil.getDbType(ctx);
  185. String sql = " /*dialect*/select * from (select row_number() over (partition by p.fid order by p.fid,eo.feffdt desc) as rn,p.fid,p.fnumber,eo.FADMINORGID,eo.FHRORGUNITID,eo.FPOSITIONID,p.cfftorptid fullOrPartId,fp.fnumber fullOrPartNumber, p.cffae annualleavelimit,case when rb.fid is null then eo.cfworkercategoryid else rbe.CFWcategoryID end workercategoryid,wc.fname_l2 workercategoryname,p.fhiredate, (to_char(to_date('"+currentDateStr+"','yyyy-MM-dd'),'yyyy') - to_char(p.fhiredate,'yyyy')+1)joinDateYear,case when rb.fid is null then null else rbe.FBIZDATE end leaveDate,l.fid limitId,coalesce(l.FADDORSUBLIMIT,0) FADDORSUBLIMIT,coalesce(l.FUSEDLIMIT,0) FUSEDLIMIT,coalesce(l.FREEZELIMIT,0) FREEZELIMIT,coalesce(l.cflastcarryforward,0) cflastcarryforward,coalesce(l.cfcarryforward,0) cfcarryforward,coalesce(l.CFEntitlementLimit,0) CFEntitlementLimit,coalesce(l.CFInitializedLimit,0) CFInitializedLimit, ebe.FPROBATION,ebe.FPLANFORMALDATE,hp.fid holidayPolicyId " +
  186. " from T_BD_Person p " +
  187. " left join T_HR_EmpOrgRelation eo on p.fid = eo.fpersonid " +
  188. " left join CT_MP_Fullorpart fp on fp.fid = p.cfftorptid " +
  189. " left join T_HR_ATS_AtsHolidayFile f on f.fproposerid = p.fid " +
  190. " left join T_HR_ATS_HolidayPolicySet hps on f.fholidaypolicysetid = hps.fid " +
  191. " left join T_HR_ATS_HolidayType ht on ht.FNUMBER = 'JQLX000001Y' " +
  192. " left join T_HR_ATS_HolidayPolicy hp on ht.fid = hp.FHOLIDAYTYPEID and hps.fid = hp.fholidaypolicysetid " +
  193. " left join T_HR_ATS_HolidayLimit l on hp.fid = l.FHOLIDAYPOLICYID and l.FPROPOSERID = p.fid and l.FCYCLEBEGINDATE >= p.fhiredate and l.FCYCLEBEGINDATE <= p.FLEFFDT and l.fyear = " + year +
  194. " left join T_HR_EmpEnrollBizBillEntry ebe on ebe.FPERSONID = p.fid and ebe.FBIZDATE = p.fhiredate " +
  195. " left join T_HR_EmpEnrollBizBill eb on ebe.FBILLID = eb.FID and eb.FBILLSTATE = 3 " +
  196. " left join T_HR_ResignBizBillEntry rbe on rbe.FPERSONID = p.fid and p.fhiredate = rbe.FENTERDATE " +
  197. " left join T_HR_ResignBizBill rb on rb.fid = rbe.FBILLID and rb.FBILLSTATE = 3 " +
  198. " left join CT_MP_WorkerCategory wc on (wc.fid = eo.cfworkercategoryid or wc.fid = rbe.CFWcategoryID) " +
  199. " where f.fattendfilestate = 1 and fp.fnumber = 'FULL' and eo.fassigntype = 1 and eo.feffdt <= to_date('"+currentDateStr+"','yyyy-MM-dd') and to_char(p.fhiredate, 'yyyy')<="+year+" and to_char(p.FLEFFDT,'yyyy')>="+year+" ";
  200. if (StringUtils.equalsIgnoreCase("MS SQL Server", dbType)) {
  201. sql = " /*dialect*/select * from (select row_number() over (partition by p.fid order by p.fid,eo.feffdt desc) as rn,p.fid,p.fnumber,eo.FADMINORGID,eo.FHRORGUNITID,eo.FPOSITIONID,p.cfftorptid fullOrPartId,fp.fnumber fullOrPartNumber, p.cffae annualleavelimit,case when rb.fid is null then eo.cfworkercategoryid else rbe.CFWcategoryID end workercategoryid,wc.fname_l2 workercategoryname,p.fhiredate, (year(cast('"+currentDateStr+"' as datetime)) - year(p.fhiredate)+1)joinDateYear,case when rb.fid is null then null else rbe.FBIZDATE end leaveDate,l.fid limitId,isnull(l.FADDORSUBLIMIT,0) FADDORSUBLIMIT,isnull(l.FUSEDLIMIT,0) FUSEDLIMIT,isnull(l.FREEZELIMIT,0) FREEZELIMIT,isnull(l.cflastcarryforward,0) cflastcarryforward,isnull(l.cfcarryforward,0) cfcarryforward,isnull(l.CFEntitlementLimit,0) CFEntitlementLimit,isnull(l.CFInitializedLimit,0) CFInitializedLimit,ebe.FPROBATION,ebe.FPLANFORMALDATE,hp.fid holidayPolicyId " +
  202. " from T_BD_Person p " +
  203. " left join T_HR_EmpOrgRelation eo on p.fid = eo.fpersonid " +
  204. " left join CT_MP_Fullorpart fp on fp.fid = p.cfftorptid " +
  205. " left join T_HR_ATS_AtsHolidayFile f on f.fproposerid = p.fid " +
  206. " left join T_HR_ATS_HolidayPolicySet hps on f.fholidaypolicysetid = hps.fid " +
  207. " left join T_HR_ATS_HolidayType ht on ht.FNUMBER = 'JQLX000001Y' " +
  208. " left join T_HR_ATS_HolidayPolicy hp on ht.fid = hp.FHOLIDAYTYPEID and hps.fid = hp.fholidaypolicysetid " +
  209. " left join T_HR_ATS_HolidayLimit l on hp.fid = l.FHOLIDAYPOLICYID and l.FPROPOSERID = p.fid and l.FCYCLEBEGINDATE >= p.fhiredate and l.FCYCLEBEGINDATE <= p.FLEFFDT and l.fyear = " + year +
  210. " left join T_HR_EmpEnrollBizBillEntry ebe on ebe.FPERSONID = p.fid and ebe.FBIZDATE = p.fhiredate " +
  211. " left join T_HR_EmpEnrollBizBill eb on ebe.FBILLID = eb.FID and eb.FBILLSTATE = 3 " +
  212. " left join T_HR_ResignBizBillEntry rbe on rbe.FPERSONID = p.fid and p.fhiredate = rbe.FENTERDATE " +
  213. " left join T_HR_ResignBizBill rb on rb.fid = rbe.FBILLID and rb.FBILLSTATE = 3 " +
  214. " left join CT_MP_WorkerCategory wc on (wc.fid = eo.cfworkercategoryid or wc.fid = rbe.CFWcategoryID) " +
  215. " where f.fattendfilestate = 1 and fp.fnumber = 'FULL' and eo.fassigntype = 1 and eo.feffdt <= cast('"+currentDateStr+"' as datetime) and year(p.fhiredate)<="+year+" and year(p.FLEFFDT)>="+year;
  216. }
  217. if (StringUtils.isNotEmpty(personNumStr)) {
  218. sql += " and p.fnumber in (" + personNumStr + ") ";
  219. }
  220. sql += " ) temp where temp.rn = 1 ";
  221. IRowSet iRowSet = DbUtil.executeQuery(ctx, sql);
  222. while (iRowSet.next()) {
  223. String holidayPolicyId = iRowSet.getString("holidayPolicyId");
  224. if (StringUtils.isEmpty(holidayPolicyId)) {
  225. holidayPolicyId = holidayPolicyMap.values().stream().findFirst().get();
  226. continue;
  227. }
  228. String limitId = iRowSet.getString("limitId");
  229. // 教师年假额度
  230. int annualleavelimit = iRowSet.getInt("annualleavelimit");
  231. // 员工类别
  232. String workercategoryname = iRowSet.getString("workercategoryname");
  233. // 司龄
  234. int joinDateYear = iRowSet.getInt("joinDateYear");
  235. // 入职日期
  236. Date joinDate = iRowSet.getDate("fhiredate");
  237. java.sql.Date fplanformaldate = iRowSet.getDate("FPLANFORMALDATE");
  238. // 离职日期
  239. java.sql.Date leaveDate = iRowSet.getDate("leaveDate");
  240. // 标准额度=额度规则(折算额度)+初始化额度+从去年结转-结转到明年
  241. BigDecimal standardLimit = BigDecimal.ZERO;
  242. // 折算标准额度
  243. BigDecimal convertedLimit = BigDecimal.ZERO;
  244. // 未折算标准额度
  245. BigDecimal entitlementLimit = BigDecimal.ZERO;
  246. // 实际额度
  247. BigDecimal realLimit = BigDecimal.ZERO;
  248. // 剩余额度
  249. BigDecimal remainLimit = BigDecimal.ZERO;
  250. // 未折算标准额度
  251. BigDecimal entitlementLimitOld = iRowSet.getBigDecimal("CFEntitlementLimit");
  252. // 初始化额度
  253. BigDecimal initializedLimit = iRowSet.getBigDecimal("CFInitializedLimit");
  254. // 从去年结转额度
  255. BigDecimal lastCarryforward = iRowSet.getBigDecimal("CFLastCarryforward");
  256. // 结转到明年
  257. BigDecimal carryforward = iRowSet.getBigDecimal("CFCarryforward");
  258. // 增减额度
  259. BigDecimal addOrSubLimit = iRowSet.getBigDecimal("FADDORSUBLIMIT");
  260. // 已用额度
  261. BigDecimal usedLimit = iRowSet.getBigDecimal("FUSEDLIMIT");
  262. // 在途额度
  263. BigDecimal freezeLimit = iRowSet.getBigDecimal("FreezeLimit");
  264. // 全职行政人员额度规则
  265. if (StringUtils.equalsIgnoreCase(workercategoryname, WC_General_Administrative_Staff)
  266. || StringUtils.equalsIgnoreCase(workercategoryname, WC_Professional_Supervisory_Staff)
  267. || StringUtils.equalsIgnoreCase(workercategoryname, WC_Senior_Administrative_Staff)) {
  268. if (annualleavelimit > 0) {
  269. // 如果员工信息-教师年假额度中数值>0,则取值员工信息-教师年假额度值,司龄每满两年加一天,最多加八天(最大值30天)
  270. convertedLimit = BigDecimal.valueOf(annualleavelimit + (joinDateYear - 1) / IV_Year * IV_YearAddValue);
  271. if (convertedLimit.compareTo(BigDecimal.valueOf(30)) > 0) {
  272. convertedLimit = BigDecimal.valueOf(30);
  273. }
  274. } else {
  275. // 员工类别=General Administrative Staff,则初始值为12,司龄每满两年加一天,最多加八天;
  276. if (StringUtils.equalsIgnoreCase(workercategoryname, WC_General_Administrative_Staff)) {
  277. convertedLimit = BigDecimal.valueOf(IV_General_Administrative_Staff + (joinDateYear - 1) / IV_Year * IV_YearAddValue);
  278. if (convertedLimit.compareTo(BigDecimal.valueOf(IV_General_Administrative_Staff + IV_MAXADD)) > 0) {
  279. convertedLimit = BigDecimal.valueOf(IV_General_Administrative_Staff + IV_MAXADD);
  280. }
  281. }
  282. // 员工类别=Professional Supervisory Staff,则初始值为15,司龄每满两年加一天,最多加八天;
  283. if (StringUtils.equalsIgnoreCase(workercategoryname, WC_Professional_Supervisory_Staff)) {
  284. convertedLimit = BigDecimal.valueOf(IV_Professional_Supervisory_Staff + (joinDateYear - 1) / IV_Year * IV_YearAddValue);
  285. if (convertedLimit.compareTo(BigDecimal.valueOf(IV_Professional_Supervisory_Staff + IV_MAXADD)) > 0) {
  286. convertedLimit = BigDecimal.valueOf(IV_Professional_Supervisory_Staff + IV_MAXADD);
  287. }
  288. }
  289. // 员工类别=Senior Administrative Staff,则初始值为18,司龄每满两年加一天,最多加八天;
  290. if (StringUtils.equalsIgnoreCase(workercategoryname, WC_Senior_Administrative_Staff)) {
  291. convertedLimit = BigDecimal.valueOf(IV_Senior_Administrative_Staff + (joinDateYear - 1) / IV_Year * IV_YearAddValue);
  292. if (convertedLimit.compareTo(BigDecimal.valueOf(IV_Senior_Administrative_Staff + IV_MAXADD)) > 0) {
  293. convertedLimit = BigDecimal.valueOf(IV_Senior_Administrative_Staff + IV_MAXADD);
  294. }
  295. }
  296. }
  297. } else if (StringUtils.equalsIgnoreCase(workercategoryname, WC_Academic_Staff)
  298. || StringUtils.equalsIgnoreCase(workercategoryname, WC_Others)) {
  299. // 全职学术人员和全职其他人员
  300. // 取值员工信息-教师年假额度字段
  301. convertedLimit = BigDecimal.valueOf(annualleavelimit);
  302. }
  303. // 未折算标准额度
  304. entitlementLimit = convertedLimit;
  305. // 入职折算
  306. if (DateTimeUtils.getYear(currentDate) == DateTimeUtils.getYear(joinDate) && leaveDate == null) {
  307. if (StringUtils.equals(CONVERSIONMETHOD_BYDAY, annualLeaveConversionMethod)) {
  308. // TODO 暂时使用按月折算的逻辑
  309. convertedLimit = convertedLimit.multiply(BigDecimal.valueOf(MONTH_NUM_12 - DateTimeUtils.getMonth(joinDate) + 1)).divide(BigDecimal.valueOf(MONTH_NUM_12), 10, BigDecimal.ROUND_HALF_UP);
  310. } else {
  311. convertedLimit = convertedLimit.multiply(BigDecimal.valueOf(MONTH_NUM_12 - DateTimeUtils.getMonth(joinDate) + 1)).divide(BigDecimal.valueOf(MONTH_NUM_12), 10, BigDecimal.ROUND_HALF_UP);
  312. }
  313. }
  314. // 离职折算
  315. if (leaveDate != null && DateTimeUtils.getYear(currentDate) == DateTimeUtils.getYear(leaveDate)) {
  316. if (StringUtils.equals(CONVERSIONMETHOD_BYDAY, annualLeaveConversionMethod)) {
  317. // TODO 暂时使按月折算的逻辑
  318. if (DateTimeUtils.getYear(currentDate) == DateTimeUtils.getYear(joinDate)) {
  319. convertedLimit = convertedLimit.multiply(BigDecimal.valueOf(DateTimeUtils.getMonth(leaveDate) - DateTimeUtils.getMonth(joinDate) + 1)).divide(BigDecimal.valueOf(MONTH_NUM_12), 10, BigDecimal.ROUND_HALF_UP);
  320. } else {
  321. convertedLimit = convertedLimit.multiply(BigDecimal.valueOf(DateTimeUtils.getMonth(leaveDate))).divide(BigDecimal.valueOf(MONTH_NUM_12), 10, BigDecimal.ROUND_HALF_UP);
  322. }
  323. } else {
  324. if (DateTimeUtils.getYear(currentDate) == DateTimeUtils.getYear(joinDate)) {
  325. convertedLimit = convertedLimit.multiply(BigDecimal.valueOf(DateTimeUtils.getMonth(leaveDate) - DateTimeUtils.getMonth(joinDate) + 1)).divide(BigDecimal.valueOf(MONTH_NUM_12), 10, BigDecimal.ROUND_HALF_UP);
  326. } else {
  327. convertedLimit = convertedLimit.multiply(BigDecimal.valueOf(DateTimeUtils.getMonth(leaveDate))).divide(BigDecimal.valueOf(MONTH_NUM_12), 10, BigDecimal.ROUND_HALF_UP);
  328. }
  329. }
  330. }
  331. // 年假取整
  332. // 整数部分
  333. BigDecimal standardLimitInteger = convertedLimit.setScale(0, RoundingMode.FLOOR);
  334. // 小数部分
  335. BigDecimal standardLimitDecimal = convertedLimit.subtract(standardLimitInteger);
  336. if (Double.doubleToLongBits(INTEGERPERCISION_HALF) == Double.doubleToLongBits(annualLeaveIntegerPrecision)) {
  337. if (StringUtils.equals(INTEGERMETHOD_UP, annualLeaveIntegerMethod)) {
  338. if (standardLimitDecimal.compareTo(BigDecimal.valueOf(0.5)) > 0) {
  339. convertedLimit = convertedLimit.setScale(0, RoundingMode.CEILING);
  340. } else if (standardLimitDecimal.compareTo(BigDecimal.ZERO) > 0){
  341. convertedLimit = standardLimitInteger.add(BigDecimal.valueOf(0.5));
  342. } else {
  343. convertedLimit = standardLimitInteger;
  344. }
  345. } else {
  346. if (standardLimitDecimal.compareTo(BigDecimal.valueOf(0.5)) > 0) {
  347. convertedLimit = standardLimitInteger.add(BigDecimal.valueOf(0.5));
  348. } else {
  349. convertedLimit = convertedLimit.setScale(0, RoundingMode.FLOOR);
  350. }
  351. }
  352. } else {
  353. if (StringUtils.equals(INTEGERMETHOD_UP, annualLeaveIntegerMethod)) {
  354. convertedLimit = convertedLimit.setScale(0, RoundingMode.CEILING);
  355. } else {
  356. convertedLimit = convertedLimit.setScale(0, RoundingMode.FLOOR);
  357. }
  358. }
  359. // 未折算标准额度
  360. if (entitlementLimit.compareTo(entitlementLimitOld) != 0 && year <= DateTimeUtils.getYear(nowDate)) {
  361. lastCarryforward = BigDecimal.ZERO;
  362. Map<String, Object> param = new HashMap<>();
  363. param.put("year", year);
  364. param.put("personNum", iRowSet.getString("fnumber"));
  365. reCalList.add(param);
  366. }
  367. // 标准额度 = 额度规则(折算额度)+初始化额度+从去年结转-结转到明年
  368. standardLimit = convertedLimit.add(initializedLimit).add(lastCarryforward).subtract(carryforward);
  369. // 实际额度 = 标准额度+增减额度
  370. realLimit = standardLimit.add(addOrSubLimit);
  371. // 剩余额度 = 实际额度-已用额度-在途额度
  372. remainLimit = realLimit.subtract(usedLimit).subtract(freezeLimit);
  373. if (StringUtils.isNotEmpty(limitId)) {
  374. HolidayLimitInfo holidayLimitInfo = new HolidayLimitInfo();
  375. holidayLimitInfo.setId(BOSUuid.read(limitId));
  376. // 标准额度
  377. holidayLimitInfo.setStandardLimit(standardLimit);
  378. // 折算标准额度
  379. holidayLimitInfo.setBigDecimal("convertedLimit", convertedLimit);
  380. // 未折算标准额度
  381. holidayLimitInfo.setBigDecimal("entitlementLimit", entitlementLimit);
  382. holidayLimitInfo.setRealLimit(realLimit);
  383. holidayLimitInfo.setRemainLimit(remainLimit);
  384. holidayLimitInfo.setBigDecimal("lastCarryforward", lastCarryforward);
  385. holidayLimitInfo.setBigDecimal("Carryforward", carryforward);
  386. // 默认值
  387. holidayLimitInfo.setCycleBeginDate(yearFirstDay);
  388. holidayLimitInfo.setCycleEndDate(yearLastDay);
  389. holidayLimitInfo.setEffectDate(yearFirstDay);
  390. holidayLimitInfo.setDelayDate(yearLastDay);
  391. // 入职情况
  392. if (DateTimeUtils.getYear(currentDate) == DateTimeUtils.getYear(joinDate)) {
  393. holidayLimitInfo.setCycleBeginDate(joinDate);
  394. int fprobation = iRowSet.getInt("FPROBATION");
  395. if (fprobation > 0) {
  396. holidayLimitInfo.setEffectDate(iRowSet.getDate("FPLANFORMALDATE"));
  397. } else {
  398. holidayLimitInfo.setEffectDate(holidayLimitInfo.getCycleBeginDate());
  399. }
  400. } else if ((fplanformaldate != null && DateTimeUtils.getYear(currentDate) == DateTimeUtils.getYear(fplanformaldate))) {
  401. int fprobation = iRowSet.getInt("FPROBATION");
  402. if (fprobation > 0) {
  403. holidayLimitInfo.setEffectDate(iRowSet.getDate("FPLANFORMALDATE"));
  404. } else {
  405. holidayLimitInfo.setEffectDate(holidayLimitInfo.getCycleBeginDate());
  406. }
  407. }
  408. // 离职情况
  409. if (leaveDate != null && DateTimeUtils.getYear(currentDate) == DateTimeUtils.getYear(leaveDate)) {
  410. holidayLimitInfo.setCycleEndDate(leaveDate);
  411. holidayLimitInfo.setDelayDate(leaveDate);
  412. }
  413. holidayLimitInfo.setLastUpdateUser(ContextUtil.getCurrentUserInfo(ctx));
  414. holidayLimitInfo.setLastUpdateTime(new Timestamp(nowDate.getTime()));
  415. // 如果假期额度在离职日期之后,不生成
  416. if (leaveDate != null && leaveDate.getTime() < holidayLimitInfo.getCycleEndDate().getTime()) {
  417. deleteList.add(limitId);
  418. continue;
  419. }
  420. updateList.add(holidayLimitInfo);
  421. } else {
  422. HolidayLimitInfo holidayLimitInfo = new HolidayLimitInfo();
  423. holidayLimitInfo.setStandardLimit(standardLimit);
  424. holidayLimitInfo.setBigDecimal("convertedLimit", convertedLimit);
  425. holidayLimitInfo.setBigDecimal("entitlementLimit", entitlementLimit);
  426. holidayLimitInfo.setRealLimit(realLimit);
  427. holidayLimitInfo.setRemainLimit(remainLimit);
  428. holidayLimitInfo.setFreezeLimit(BigDecimal.ZERO);
  429. holidayLimitInfo.setUsedLimit(BigDecimal.ZERO);
  430. holidayLimitInfo.setAddOrSubLimit(BigDecimal.ZERO);
  431. holidayLimitInfo.setPreOverdraftLimit(BigDecimal.ZERO);
  432. if (DateTimeUtils.getYear(currentDate) == DateTimeUtils.getYear(joinDate)) {
  433. holidayLimitInfo.setCycleBeginDate(joinDate);
  434. int fprobation = iRowSet.getInt("FPROBATION");
  435. if (fprobation > 0) {
  436. holidayLimitInfo.setEffectDate(iRowSet.getDate("FPLANFORMALDATE"));
  437. } else {
  438. holidayLimitInfo.setEffectDate(holidayLimitInfo.getCycleBeginDate());
  439. }
  440. } else if ((fplanformaldate != null && DateTimeUtils.getYear(currentDate) == DateTimeUtils.getYear(fplanformaldate))) {
  441. holidayLimitInfo.setCycleBeginDate(yearFirstDay);
  442. int fprobation = iRowSet.getInt("FPROBATION");
  443. if (fprobation > 0) {
  444. holidayLimitInfo.setEffectDate(iRowSet.getDate("FPLANFORMALDATE"));
  445. } else {
  446. holidayLimitInfo.setEffectDate(holidayLimitInfo.getCycleBeginDate());
  447. }
  448. } else {
  449. holidayLimitInfo.setCycleBeginDate(yearFirstDay);
  450. holidayLimitInfo.setEffectDate(holidayLimitInfo.getCycleBeginDate());
  451. }
  452. // 离职情况
  453. if (leaveDate != null && DateTimeUtils.getYear(currentDate) == DateTimeUtils.getYear(leaveDate)) {
  454. holidayLimitInfo.setCycleEndDate(leaveDate);
  455. holidayLimitInfo.setDelayDate(leaveDate);
  456. } else {
  457. holidayLimitInfo.setCycleEndDate(yearLastDay);
  458. holidayLimitInfo.setDelayDate(yearLastDay);
  459. }
  460. holidayLimitInfo.setYear(DateTimeUtils.getYear(yearFirstDay));
  461. HolidayPolicyInfo holidayPolicyInfo = new HolidayPolicyInfo();
  462. holidayPolicyInfo.setId(BOSUuid.read(holidayPolicyId));
  463. holidayLimitInfo.setHolidayPolicy(holidayPolicyInfo);
  464. holidayLimitInfo.setHolidayUnit(HolidayTypeUnitEnum.day);
  465. holidayLimitInfo.setEnableCycle(true);
  466. PersonInfo personInfo = new PersonInfo();
  467. personInfo.setId(BOSUuid.read(iRowSet.getString("fid")));
  468. holidayLimitInfo.setProposer(personInfo);
  469. holidayLimitInfo.setStatus(HolidayLimitStatus.audited);
  470. if (StringUtils.isNotEmpty(iRowSet.getString("FADMINORGID"))) {
  471. AdminOrgUnitInfo adminOrgUnitInfo = new AdminOrgUnitInfo();
  472. adminOrgUnitInfo.setId(BOSUuid.read(iRowSet.getString("FADMINORGID")));
  473. holidayLimitInfo.setAdminOrgUnit(adminOrgUnitInfo);
  474. }
  475. if (StringUtils.isNotEmpty(iRowSet.getString("FHRORGUNITID"))) {
  476. HROrgUnitInfo hrOrgUnitInfo = new HROrgUnitInfo();
  477. hrOrgUnitInfo.setId(BOSUuid.read(iRowSet.getString("FHRORGUNITID")));
  478. holidayLimitInfo.setHrOrgUnit(hrOrgUnitInfo);
  479. }
  480. if (StringUtils.isNotEmpty(iRowSet.getString("FPOSITIONID"))) {
  481. PositionInfo positionInfo = new PositionInfo();
  482. positionInfo.setId(BOSUuid.read(iRowSet.getString("FPOSITIONID")));
  483. holidayLimitInfo.setPosition(positionInfo);
  484. }
  485. CtrlUnitInfo ctrlUnitInfo = new CtrlUnitInfo();
  486. ctrlUnitInfo.setId(BOSUuid.read("00000000-0000-0000-0000-000000000000CCE7AED4"));
  487. holidayLimitInfo.setCU(ctrlUnitInfo);
  488. holidayLimitInfo.setCycleDate(yearLastDay);
  489. holidayLimitInfo.setCreator(ContextUtil.getCurrentUserInfo(ctx));
  490. holidayLimitInfo.setCreateTime(new Timestamp(nowDate.getTime()));
  491. holidayLimitInfo.setLastUpdateUser(ContextUtil.getCurrentUserInfo(ctx));
  492. holidayLimitInfo.setLastUpdateTime(new Timestamp(nowDate.getTime()));
  493. // 如果假期额度在离职日期之后,不生成
  494. if (leaveDate != null && leaveDate.getTime() < holidayLimitInfo.getCycleEndDate().getTime()) {
  495. continue;
  496. }
  497. addList.add(holidayLimitInfo);
  498. }
  499. }
  500. if (addList.size() > 0) {
  501. HolidayLimitFactory.getLocalInstance(ctx).addnewBatchData(addList);
  502. }
  503. if (updateList.size() > 0) {
  504. HolidayLimitFactory.getLocalInstance(ctx).updateBatchData(updateList);
  505. }
  506. if (deleteList.size() > 0) {
  507. IObjectPK[] iObjectPKS = new IObjectPK[deleteList.size()];
  508. for (int i = 0; i < deleteList.size(); i++) {
  509. iObjectPKS[i] = new ObjectUuidPK(deleteList.get(i));
  510. }
  511. HolidayLimitFactory.getLocalInstance(ctx).deleteBatchData(iObjectPKS);
  512. }
  513. if (reCalList.size() > 0) {
  514. for (int i = 0; i < reCalList.size(); i++) {
  515. int yearP = (int) reCalList.get(i).get("year");
  516. String personNumP = (String) reCalList.get(i).get("personNum");
  517. String lastYearSql = "/*dialect*/select p.fid,l.fid limitId,l.FSTANDARDLIMIT,l.FADDORSUBLIMIT,l.FUSEDLIMIT,l.FREEZELIMIT, coalesce(l.CFInitializedLimit, 0) CFInitializedLimit,coalesce(l.CFConvertedLimit, 0) CFConvertedLimit, coalesce(l.cflastcarryforward,0) cflastcarryforward,coalesce(l.cfcarryforward,0) cfcarryforward from t_bd_person p\n" +
  518. " left join T_HR_ATS_AtsHolidayFile f on f.fproposerid = p.fid \n" +
  519. " left join T_HR_ATS_HolidayPolicySet hps on f.fholidaypolicysetid = hps.fid \n" +
  520. " left join T_HR_ATS_HolidayType ht on ht.FNUMBER = 'JQLX000001Y' \n" +
  521. " left join T_HR_ATS_HolidayPolicy hp on ht.fid = hp.FHOLIDAYTYPEID and hps.fid = hp.fholidaypolicysetid \n" +
  522. " left join T_HR_ATS_HolidayLimit l on hp.fid = l.FHOLIDAYPOLICYID and l.FPROPOSERID = p.fid and l.FCYCLEBEGINDATE >= p.fhiredate and l.FCYCLEBEGINDATE <= p.FLEFFDT and l.fyear = "+(yearP-1)+"\n" +
  523. " where f.fattendfilestate = 1 and p.fnumber = '"+personNumP+"' and l.fid is not null ";
  524. if (StringUtils.equalsIgnoreCase("MS SQL Server", dbType)) {
  525. lastYearSql = "/*dialect*/select p.fid,l.fid limitId,l.FSTANDARDLIMIT,l.FADDORSUBLIMIT,l.FUSEDLIMIT,l.FREEZELIMIT, isnull(l.CFInitializedLimit, 0) CFInitializedLimit,isnull(l.CFConvertedLimit, 0) CFConvertedLimit, isnull(l.cflastcarryforward,0) cflastcarryforward,isnull(l.cfcarryforward,0) cfcarryforward from t_bd_person p\n" +
  526. " left join T_HR_ATS_AtsHolidayFile f on f.fproposerid = p.fid \n" +
  527. " left join T_HR_ATS_HolidayPolicySet hps on f.fholidaypolicysetid = hps.fid \n" +
  528. " left join T_HR_ATS_HolidayType ht on ht.FNUMBER = 'JQLX000001Y' \n" +
  529. " left join T_HR_ATS_HolidayPolicy hp on ht.fid = hp.FHOLIDAYTYPEID and hps.fid = hp.fholidaypolicysetid \n" +
  530. " left join T_HR_ATS_HolidayLimit l on hp.fid = l.FHOLIDAYPOLICYID and l.FPROPOSERID = p.fid and l.FCYCLEBEGINDATE >= p.fhiredate and l.FCYCLEBEGINDATE <= p.FLEFFDT and l.fyear = "+(yearP-1)+"\n" +
  531. " where f.fattendfilestate = 1 and p.fnumber = '"+personNumP+"' and l.fid is not null ";
  532. }
  533. IRowSet lastYearRowSet = DbUtil.executeQuery(ctx, lastYearSql);
  534. if (lastYearRowSet.next()) {
  535. HolidayLimitInfo lastYearHolidayLimitInfo = new HolidayLimitInfo();
  536. // 标准额度 = 额度规则(折算额度)+初始化额度+从去年结转-结转到明年
  537. BigDecimal lastYearConvertedLimit = lastYearRowSet.getBigDecimal("CFConvertedLimit");
  538. BigDecimal lastYearInitializedLimit = lastYearRowSet.getBigDecimal("CFInitializedLimit");
  539. BigDecimal lastYearLastCarryforward = lastYearRowSet.getBigDecimal("CFLastCarryforward");
  540. BigDecimal lastYearCarryforward = BigDecimal.ZERO;
  541. BigDecimal lastYearStandardLimit = lastYearConvertedLimit.add(lastYearInitializedLimit).add(lastYearLastCarryforward).subtract(lastYearCarryforward);
  542. lastYearHolidayLimitInfo.setId(BOSUuid.read(lastYearRowSet.getString("limitId")));
  543. lastYearHolidayLimitInfo.setStandardLimit(lastYearStandardLimit);
  544. lastYearHolidayLimitInfo.setRealLimit(lastYearHolidayLimitInfo.getStandardLimit().add(lastYearRowSet.getBigDecimal("FADDORSUBLIMIT")));
  545. lastYearHolidayLimitInfo.setRemainLimit(lastYearHolidayLimitInfo.getRealLimit().subtract(lastYearRowSet.getBigDecimal("FUSEDLIMIT")).subtract(lastYearRowSet.getBigDecimal("FreezeLimit")));
  546. lastYearHolidayLimitInfo.setBigDecimal("Carryforward", lastYearCarryforward);
  547. lastYearHolidayLimitInfo.setLastUpdateUser(ContextUtil.getCurrentUserInfo(ctx));
  548. lastYearHolidayLimitInfo.setLastUpdateTime(new Timestamp(nowDate.getTime()));
  549. HolidayLimitFactory.getLocalInstance(ctx).update(new ObjectUuidPK(lastYearHolidayLimitInfo.getId()), lastYearHolidayLimitInfo);
  550. LeaveAllowanceFacadeFactory.getLocalInstance(ctx).carryForwardLeave(yearP, true, personNumP);
  551. }
  552. }
  553. }
  554. } catch (SQLException e) {
  555. throw new BOSException(e);
  556. } catch (ParseException e) {
  557. throw new BOSException(e);
  558. } catch (EASBizException e) {
  559. throw new BOSException(e);
  560. }
  561. }
  562. private void initialGlobalParam(Context ctx) throws BOSException {
  563. // 全局变量
  564. Map<String, String> param = new HashMap<String, String>();
  565. ParamCollection paramCollection = ParamFactory.getLocalInstance(ctx).getParamCollection();
  566. for (int i = 0; i < paramCollection.size(); i++) {
  567. param.put(paramCollection.get(i).getNumber(), paramCollection.get(i).getValue());
  568. }
  569. // 年假折算
  570. annualLeaveConversionMethod = param.get(PARAM_ANNUALLEAVE_CONVERSIONMETHOD);
  571. // 年假取整
  572. annualLeaveIntegerMethod = param.get(PARAM_ANNUALLEAVE_INTEGERMETHOD);
  573. // 年假取整精度
  574. annualLeaveIntegerPrecision = Double.valueOf(param.get(PARAM_ANNUALLEAVE_INTEGERPERCISION));
  575. // 结转日期
  576. annualLeaveConvertDate = param.get(PARAM_ANNUALLEAVE_CONVERTDATE);
  577. // 下年度额度生成
  578. annualLeaveGenerateDay = param.get(PARAM_ANNUALLEAVE_GENERATEDAY);
  579. // 育儿假额度
  580. nursingLeaveLimit = Integer.parseInt(param.get(PARAM_NURSINGLEAVE_LIMIT));
  581. // 护理假额度
  582. parentalLeaveLimit = Integer.parseInt(param.get(PARAM_PARENTALLEAVE_LIMIT));
  583. // 护理育儿折算
  584. nursingAndParentalLeaveConversionMethod = param.get(PARAM_NURSINGANDPARENTALLEAVE_CONVERSIONMETHOD);
  585. // 护理育儿取整
  586. nursingAndParentalLeaveIntegerMethod = param.get(PARAM_NURSINGANDPARENTALLEAVE_INTEGERMETHOD);
  587. // 护理育儿取整精度
  588. nursingAndParentalLeaveIntegerPrecision = Double.valueOf(param.get(PARAM_NURSINGANDPARENTALLEAVE_INTEGERPERCISION));
  589. // 育儿护理多段统计是否更新视图脚本
  590. nursingAndParentalLeaveUpdateSql = param.get(PARAM_NURSINGANDPARENTALLEAVE_UPDATESQL);
  591. }
  592. /**
  593. * 设置司龄
  594. */
  595. @Override
  596. public void setSeniority(Context ctx) throws BOSException, EASBizException {
  597. String hisSql = "update T_HR_PersonPositionHis set FJOINCOMPANYYEARS=CEILING(FJOINCOMPANYYEARS) where year(FJOINDATE)<year(now())";
  598. logger.error("设置司龄SQL(HIS):"+hisSql);
  599. DbUtil.execute(ctx, hisSql);
  600. String sql = "update T_HR_PersonPosition set FJOINCOMPANYYEARS=CEILING(FJOINCOMPANYYEARS) where year(FJOINDATE)<year(now())";
  601. logger.error("设置司龄SQL:"+sql);
  602. DbUtil.execute(ctx, sql);
  603. }
  604. /**
  605. * 年假结转
  606. */
  607. @Override
  608. protected void _carryForwardLeave(Context ctx, int year, boolean isExecute, String personNum) throws BOSException, EASBizException {
  609. try {
  610. if (!isExecute) {
  611. return;
  612. }
  613. // 初始化公共变量
  614. initialGlobalParam(ctx);
  615. // 当前时间
  616. Date nowDate = new Date();
  617. Date currentDate = new Date();
  618. if (year != 0) {
  619. currentDate = DateTimeUtils.parseDate(year + "-12-31");
  620. } else {
  621. year = DateTimeUtils.getYear(currentDate);
  622. }
  623. List<String> personNumberList = new ArrayList<String>();
  624. CoreBaseCollection lastYearList = new CoreBaseCollection();
  625. CoreBaseCollection thisYearList = new CoreBaseCollection();
  626. String personNumStr = "";
  627. if (StringUtils.isNotEmpty(personNum)) {
  628. String[] personNumArr = personNum.split(",");
  629. for (int i = 0; i < personNumArr.length; i++) {
  630. personNumberList.add("'" + personNumArr[i] + "'");
  631. }
  632. personNumStr = String.join(",",personNumberList);
  633. }
  634. Date annualLeaveConvertDate = DateTimeUtils.parseDate(year + "-" + LeaveAllowanceFacadeControllerBean.annualLeaveConvertDate);
  635. if (currentDate.getTime() >= annualLeaveConvertDate.getTime()) {
  636. String sql = " /*dialect*/select thisL.fid thisLFid, lastL.fid lastLfID,thisL.FSTANDARDLIMIT, lastL.FREMAINLIMIT,ht.FNUMBER, " +
  637. " case when lastL.FREMAINLIMIT + thisL.CFEntitlementLimit <= 30 then coalesce(lastL.FREMAINLIMIT,0) else coalesce(30 - thisL.CFEntitlementLimit,0) end lastnextForward, " +
  638. " case when lastL.FREMAINLIMIT + thisL.CFEntitlementLimit <= 30 then coalesce(lastL.FREMAINLIMIT,0) else coalesce(30 - thisL.CFEntitlementLimit,0) end thislastforward, " +
  639. " lastL.FStandardLimit lFStandardLimit,coalesce(lastL.cfinitializedlimit,0) lcfinitializedlimit,coalesce(lastL.cfconvertedlimit,0) lcfconvertedlimit,lastL.FADDORSUBLIMIT lFADDORSUBLIMIT,lastL.FUSEDLIMIT lFUSEDLIMIT,lastL.FREEZELIMIT lFREEZELIMIT,coalesce(lastL.cflastcarryforward,0) lcflastcarryforward,coalesce(lastL.cfcarryforward,0) lcfcarryforward, " +
  640. " thisL.FStandardLimit tFStandardLimit,coalesce(thisL.cfinitializedlimit,0) tcfinitializedlimit,coalesce(thisL.cfconvertedlimit,0) tcfconvertedlimit,thisL.FADDORSUBLIMIT tFADDORSUBLIMIT,thisL.FUSEDLIMIT tFUSEDLIMIT,thisL.FREEZELIMIT tFREEZELIMIT,coalesce(thisL.cflastcarryforward,0) tcflastcarryforward,coalesce(thisL.cfcarryforward,0) tcfcarryforward " +
  641. " from t_bd_person p " +
  642. " left join T_HR_ATS_HolidayLimit lastL on p.fid = lastL.FPROPOSERID and lastL.FCYCLEBEGINDATE >= p.fhiredate and lastL.FCYCLEBEGINDATE <= p.FLEFFDT " +
  643. " left join T_HR_ATS_HolidayLimit thisL on thisL.FHOLIDAYPOLICYID = lastL.FHOLIDAYPOLICYID and thisL.FPROPOSERID = lastL.FPROPOSERID and thisL.FCYCLEBEGINDATE >= p.fhiredate and thisL.FCYCLEBEGINDATE <= p.FLEFFDT " +
  644. " left join T_HR_ATS_AtsHolidayFile hf on hf.fproposerid = p.fid " +
  645. " left join T_HR_ATS_HolidayPolicySet hps on hf.fholidaypolicysetid = hps.fid " +
  646. " left join T_HR_ATS_HolidayPolicy hp on hps.fid = hp.fholidaypolicysetid and thisL.FHOLIDAYPOLICYID = hp.fid " +
  647. " left join T_HR_ATS_HolidayType ht on ht.fid = hp.FHOLIDAYTYPEID and ht.FNUMBER = 'JQLX000001Y' " +
  648. " where hf.fattendfilestate = 1 and ht.FNUMBER = 'JQLX000001Y' and (lastL.cfcarryforward is null or lastL.cfcarryforward = 0) and thisL.FYEAR = "+year+" and lastL.fyear = "+(year-1)+"";
  649. String dbType = ContextUtil.getDbType(ctx);
  650. if (StringUtils.equalsIgnoreCase("MS SQL Server", dbType)) {
  651. sql = " /*dialect*/select thisL.fid thisLFid, lastL.fid lastLfID,thisL.FSTANDARDLIMIT, lastL.FREMAINLIMIT,ht.FNUMBER, " +
  652. " case when lastL.FREMAINLIMIT + thisL.CFEntitlementLimit <= 30 then isnull(lastL.FREMAINLIMIT,0) else isnull(30 - thisL.CFEntitlementLimit,0) end lastnextForward, " +
  653. " case when lastL.FREMAINLIMIT + thisL.CFEntitlementLimit <= 30 then isnull(lastL.FREMAINLIMIT,0) else isnull(30 - thisL.CFEntitlementLimit,0) end thislastforward, " +
  654. " lastL.FStandardLimit lFStandardLimit,isnull(lastL.cfinitializedlimit,0) lcfinitializedlimit,isnull(lastL.cfconvertedlimit,0) lcfconvertedlimit,lastL.FADDORSUBLIMIT lFADDORSUBLIMIT,lastL.FUSEDLIMIT lFUSEDLIMIT,lastL.FREEZELIMIT lFREEZELIMIT,isnull(lastL.cflastcarryforward,0) lcflastcarryforward,isnull(lastL.cfcarryforward,0) lcfcarryforward, " +
  655. " thisL.FStandardLimit tFStandardLimit,isnull(thisL.cfinitializedlimit,0) tcfinitializedlimit,isnull(thisL.cfconvertedlimit,0) tcfconvertedlimit,thisL.FADDORSUBLIMIT tFADDORSUBLIMIT,thisL.FUSEDLIMIT tFUSEDLIMIT,thisL.FREEZELIMIT tFREEZELIMIT,isnull(thisL.cflastcarryforward,0) tcflastcarryforward,isnull(thisL.cfcarryforward,0) tcfcarryforward " +
  656. " from t_bd_person p " +
  657. " left join T_HR_ATS_HolidayLimit lastL on p.fid = lastL.FPROPOSERID and lastL.FCYCLEBEGINDATE >= p.fhiredate and lastL.FCYCLEBEGINDATE <= p.FLEFFDT " +
  658. " left join T_HR_ATS_HolidayLimit thisL on thisL.FHOLIDAYPOLICYID = lastL.FHOLIDAYPOLICYID and thisL.FPROPOSERID = lastL.FPROPOSERID and thisL.FCYCLEBEGINDATE >= p.fhiredate and thisL.FCYCLEBEGINDATE <= p.FLEFFDT " +
  659. " left join T_HR_ATS_AtsHolidayFile hf on hf.fproposerid = p.fid " +
  660. " left join T_HR_ATS_HolidayPolicySet hps on hf.fholidaypolicysetid = hps.fid " +
  661. " left join T_HR_ATS_HolidayPolicy hp on hps.fid = hp.fholidaypolicysetid and thisL.FHOLIDAYPOLICYID = hp.fid " +
  662. " left join T_HR_ATS_HolidayType ht on ht.fid = hp.FHOLIDAYTYPEID and ht.FNUMBER = 'JQLX000001Y' " +
  663. " where hf.fattendfilestate = 1 and ht.FNUMBER = 'JQLX000001Y' and (lastL.cfcarryforward is null or lastL.cfcarryforward = 0) and thisL.FYEAR = "+year+" and lastL.fyear = "+(year-1)+"";
  664. }
  665. if (StringUtils.isNotEmpty(personNumStr)) {
  666. sql += " and p.fnumber in (" + personNumStr + ") ";
  667. }
  668. IRowSet rowSet = DbUtil.executeQuery(ctx, sql);
  669. while (rowSet.next()) {
  670. HolidayLimitInfo lastYearHolidayLimitInfo = new HolidayLimitInfo();
  671. lastYearHolidayLimitInfo.setId(BOSUuid.read(rowSet.getString("lastLfID")));
  672. lastYearHolidayLimitInfo.setBigDecimal("Carryforward", rowSet.getBigDecimal("lastnextForward"));
  673. // 去年 折算标准额度
  674. BigDecimal lastYearConvertedLimit = rowSet.getBigDecimal("lcfconvertedlimit");
  675. // 去年 初始化额度
  676. BigDecimal lastYearInitializedLimit = rowSet.getBigDecimal("lCFInitializedLimit");
  677. // 去年 从去年结转额度
  678. BigDecimal lastYearLastCarryforward = rowSet.getBigDecimal("lCFLastCarryforward");
  679. // 去年 标准额度 = 额度规则(折算额度)+初始化额度+从去年结转-结转到明年
  680. BigDecimal lastYearStandardLimit = lastYearConvertedLimit.add(lastYearInitializedLimit).add(lastYearLastCarryforward).subtract(lastYearHolidayLimitInfo.getBigDecimal("Carryforward"));
  681. lastYearHolidayLimitInfo.setStandardLimit(lastYearStandardLimit);
  682. lastYearHolidayLimitInfo.setRealLimit(lastYearHolidayLimitInfo.getStandardLimit().add(rowSet.getBigDecimal("LFADDORSUBLIMIT")));
  683. lastYearHolidayLimitInfo.setRemainLimit(lastYearHolidayLimitInfo.getRealLimit().subtract(rowSet.getBigDecimal("LFUSEDLIMIT")).subtract(rowSet.getBigDecimal("lFreezeLimit")));
  684. lastYearHolidayLimitInfo.setLastUpdateUser(ContextUtil.getCurrentUserInfo(ctx));
  685. lastYearHolidayLimitInfo.setLastUpdateTime(new Timestamp(nowDate.getTime()));
  686. lastYearList.add(lastYearHolidayLimitInfo);
  687. HolidayLimitInfo thisYearHolidayLimitInfo = new HolidayLimitInfo();
  688. thisYearHolidayLimitInfo.setId(BOSUuid.read(rowSet.getString("thisLFid")));
  689. thisYearHolidayLimitInfo.setBigDecimal("LastCarryforward", rowSet.getBigDecimal("thislastforward"));
  690. // 今年 折算标准额度
  691. BigDecimal thisYearConvertedLimit = rowSet.getBigDecimal("tcfconvertedlimit");
  692. // 今年 初始化额度
  693. BigDecimal thisYearInitializedLimit = rowSet.getBigDecimal("tCFInitializedLimit");
  694. // 今年 从去年结转额度 TODO xxx
  695. BigDecimal thisYearCarryforward = rowSet.getBigDecimal("tCFCarryforward");
  696. // 今年 标准额度 = 额度规则(折算额度)+初始化额度+从去年结转-结转到明年
  697. BigDecimal thisYearStandardLimit = thisYearConvertedLimit.add(thisYearInitializedLimit).add(thisYearHolidayLimitInfo.getBigDecimal("LastCarryforward")).subtract(thisYearCarryforward);
  698. thisYearHolidayLimitInfo.setStandardLimit(thisYearStandardLimit);
  699. thisYearHolidayLimitInfo.setRealLimit(thisYearHolidayLimitInfo.getStandardLimit().add(rowSet.getBigDecimal("tFADDORSUBLIMIT")));
  700. thisYearHolidayLimitInfo.setRemainLimit(thisYearHolidayLimitInfo.getRealLimit().subtract(rowSet.getBigDecimal("tFUSEDLIMIT")).subtract(rowSet.getBigDecimal("tFreezeLimit")));
  701. thisYearHolidayLimitInfo.setLastUpdateUser(ContextUtil.getCurrentUserInfo(ctx));
  702. thisYearHolidayLimitInfo.setLastUpdateTime(new Timestamp(nowDate.getTime()));
  703. thisYearList.add(thisYearHolidayLimitInfo);
  704. }
  705. }
  706. if (lastYearList.size() > 0) {
  707. HolidayLimitFactory.getLocalInstance(ctx).updateBatchData(lastYearList);
  708. }
  709. if (thisYearList.size() > 0) {
  710. HolidayLimitFactory.getLocalInstance(ctx).updateBatchData(thisYearList);
  711. }
  712. } catch (ParseException e) {
  713. throw new BOSException(e);
  714. } catch (SQLException e) {
  715. throw new BOSException(e);
  716. }
  717. }
  718. /**
  719. * 护理假额度生成 JQLX000016Y
  720. */
  721. @Override
  722. protected void _creareNursingLeave(Context ctx, int year, String personNum) throws BOSException {
  723. createNursingOrParentalLeave(ctx, year, personNum, "JQLX000016Y", nursingLeaveLimit, "P");
  724. }
  725. /**
  726. * 育儿假额度生成 JQLX000015Y
  727. */
  728. @Override
  729. protected void _creareParentalLeave(Context ctx, int year, String personNum) throws BOSException {
  730. createNursingOrParentalLeave(ctx, year, personNum, "JQLX000015Y", parentalLeaveLimit, "C");
  731. }
  732. private void createNursingOrParentalLeave(Context ctx, int year, String personNum, String policyNumber, int initialLimit,String cnLeave) throws BOSException {
  733. try {
  734. initialGlobalParam(ctx);
  735. String personFamilyTempTable = createPersonFamilyTempTable(ctx, cnLeave);
  736. // 当前时间
  737. Date nowDate = new Date();
  738. Date currentDate = new Date();
  739. if (year != 0) {
  740. currentDate = DateTimeUtils.parseDate(year + "-12-31");
  741. } else {
  742. year = DateTimeUtils.getYear(currentDate);
  743. }
  744. // 当前年份第一天
  745. String yearFirstDayStr = DateTimeUtils.getYear(currentDate) + "-01-01";
  746. Date yearFirstDay = DateTimeUtils.parseDate(yearFirstDayStr);
  747. // 当前年份最后一天
  748. String yearLastDayStr = DateTimeUtils.getYear(currentDate) + "-12-31";
  749. Date yearLastDay = DateTimeUtils.parseDate(yearLastDayStr);
  750. List<String> personNumberList = new ArrayList<String>();
  751. CoreBaseCollection addList = new CoreBaseCollection();
  752. CoreBaseCollection updateList = new CoreBaseCollection();
  753. String personNumStr = "";
  754. if (StringUtils.isNotEmpty(personNum)) {
  755. String[] personNumArr = personNum.split(",");
  756. for (int i = 0; i < personNumArr.length; i++) {
  757. personNumberList.add("'" + personNumArr[i] + "'");
  758. }
  759. personNumStr = String.join(",",personNumberList);
  760. }
  761. // 置空相关的假期额度
  762. String clearQuotaSql = " update T_HR_ATS_HolidayLimit set FStandardLimit = 0, FRealLimit = FAddOrSubLimit,FRemainLimit = FAddOrSubLimit-FUsedLimit-FreezeLimit where fid in ( " +
  763. " select l.fid from T_HR_ATS_HolidayLimit l " +
  764. " left join T_HR_ATS_HolidayPolicy hp on hp.fid = l.FHOLIDAYPOLICYID " +
  765. " left join T_HR_ATS_HolidayType ht on hp.FHOLIDAYTYPEID = ht.fid " +
  766. " left join t_bd_person p on p.fid = l.FPROPOSERID " +
  767. " where ht.FNUMBER = '"+policyNumber+"' and l.FYEAR = "+year+" and l.FCYCLEBEGINDATE >= p.fhiredate and l.FCYCLEBEGINDATE <= p.FLEFFDT ";
  768. if (StringUtils.isNotEmpty(personNumStr)) {
  769. clearQuotaSql += " and p.fnumber in (" + personNumStr + ")) ";
  770. } else {
  771. clearQuotaSql += " ) ";
  772. }
  773. DbUtil.execute(ctx, clearQuotaSql);
  774. // 清理空数据
  775. String deleteZeroQuotaSql = "delete from T_HR_ATS_HolidayLimit where FHOLIDAYPOLICYID in (select hp.fid from T_HR_ATS_HolidayPolicy hp " +
  776. "left join T_HR_ATS_HolidayType ht on hp.FHOLIDAYTYPEID = ht.fid where ht.FNUMBER = '"+policyNumber+"') and FYEAR = "+year+" and FStandardLimit = 0 and FRealLimit = 0 and FAddOrSubLimit = 0 and FRemainLimit = 0 and FUsedLimit = 0 and FreezeLimit = 0 ";
  777. if (StringUtils.isNotEmpty(personNumStr)) {
  778. deleteZeroQuotaSql += " and FProposerID in (select fid from t_bd_person where fnumber in ("+personNumStr+") ) ";
  779. }
  780. DbUtil.execute(ctx, deleteZeroQuotaSql);
  781. String sql = "/*dialect*/select f.FPERSONID,p.fnumber, case when to_char(f.CFStartTime,'yyyy') < "+ year +" then to_date('"+ year +"-01-01','yyyy-MM-dd') else f.CFStartTime end CFStartTime," +
  782. " case when f.CFEndTime is null or to_char(f.CFEndTime,'yyyy') > "+ year +" then to_date('"+ year +"-12-31','yyyy-MM-dd') else f.CFEndTime end CFEndTime ," +
  783. " case when rb.fid is null then null else rbe.FBIZDATE end leaveDate,p.fhiredate,hf.FADMINORGUNITID, hf.FHRORGUNITID ,hf.FPOSITIONID, l.fid limitId,ebe.FPROBATION,ebe.FPLANFORMALDATE,hp.fid holidayPolicyId,l.FADDORSUBLIMIT,l.FUSEDLIMIT,l.FREEZELIMIT,l.FCYCLEBEGINDATE,l.FCYCLEENDDATE from " + personFamilyTempTable + " f " +
  784. " left join t_bd_person p on p.fid = f.FPERSONID " +
  785. " left join T_HR_ATS_AtsHolidayFile hf on hf.fproposerid = f.FPERSONID " +
  786. " left join T_HR_ATS_HolidayPolicySet hps on hf.fholidaypolicysetid = hps.fid " +
  787. " left join T_HR_ATS_HolidayType ht on ht.FNUMBER = '"+policyNumber+"' " +
  788. " left join T_HR_ATS_HolidayPolicy hp on ht.fid = hp.FHOLIDAYTYPEID and hps.fid = hp.fholidaypolicysetid " +
  789. " left join T_HR_ATS_HolidayLimit l on hp.fid = l.FHOLIDAYPOLICYID and l.FPROPOSERID = f.FPERSONID and l.FYEAR = "+ year +" and f.CFStartTime<=l.FCYCLEBEGINDATE and f.CFEndTime>=l.FCYCLEBEGINDATE and l.FCYCLEBEGINDATE >= p.fhiredate and l.FCYCLEENDDATE >= p.fhiredate " +
  790. " left join T_HR_EmpEnrollBizBillEntry ebe on ebe.FPERSONID = f.FPERSONID and ebe.FBIZDATE = p.fhiredate " +
  791. " left join T_HR_EmpEnrollBizBill eb on ebe.FBILLID = eb.FID and eb.FBILLSTATE = 3 " +
  792. " left join T_HR_ResignBizBillEntry rbe on rbe.FPERSONID = f.FPERSONID and (p.fhiredate<=rbe.FBIZDATE or rbe.FBIZDATE is null)" +
  793. " left join T_HR_ResignBizBill rb on rb.fid = rbe.FBILLID and rb.FBILLSTATE = 3 " +
  794. " where hf.fattendfilestate = 1 and f.CFStartTime <= to_date('"+yearLastDayStr+"','yyyy-MM-dd') and (f.CFEndTime >= to_date('"+yearFirstDayStr+"','yyyy-MM-dd') or f.CFEndTime is null) and to_char(p.fhiredate,'yyyy')<="+year+" and to_char(p.FLEFFDT,'yyyy')>="+year;
  795. String dbType = ContextUtil.getDbType(ctx);
  796. if (StringUtils.equalsIgnoreCase("MS SQL Server", dbType)) {
  797. sql = "/*dialect*/ select f.FPERSONID,p.fnumber, case when year(f.CFStartTime) < "+ year +" then cast('"+ year +"-01-01' as datetime) else f.CFStartTime end CFStartTime," +
  798. " case when f.CFEndTime is null or year(f.CFEndTime) > "+ year +" then cast('"+ year +"-12-31' as datetime) else f.CFEndTime end CFEndTime ," +
  799. " case when rb.fid is null then null else rbe.FBIZDATE end leaveDate,p.fhiredate,hf.FADMINORGUNITID, hf.FHRORGUNITID ,hf.FPOSITIONID, l.fid limitId,ebe.FPROBATION,ebe.FPLANFORMALDATE,hp.fid holidayPolicyId,l.FADDORSUBLIMIT,l.FUSEDLIMIT,l.FREEZELIMIT,l.FCYCLEBEGINDATE,l.FCYCLEENDDATE from " + personFamilyTempTable + " f " +
  800. " left join t_bd_person p on p.fid = f.FPERSONID " +
  801. " left join T_HR_ATS_AtsHolidayFile hf on hf.fproposerid = f.FPERSONID " +
  802. " left join T_HR_ATS_HolidayPolicySet hps on hf.fholidaypolicysetid = hps.fid " +
  803. " left join T_HR_ATS_HolidayType ht on ht.FNUMBER = '"+policyNumber+"' " +
  804. " left join T_HR_ATS_HolidayPolicy hp on ht.fid = hp.FHOLIDAYTYPEID and hps.fid = hp.fholidaypolicysetid " +
  805. " left join T_HR_ATS_HolidayLimit l on hp.fid = l.FHOLIDAYPOLICYID and l.FPROPOSERID = f.FPERSONID and l.FYEAR = "+ year +" and f.CFStartTime<=l.FCYCLEBEGINDATE and f.CFEndTime>=l.FCYCLEBEGINDATE and l.FCYCLEBEGINDATE >= p.fhiredate and l.FCYCLEENDDATE >= p.fhiredate " +
  806. " left join T_HR_EmpEnrollBizBillEntry ebe on ebe.FPERSONID = f.FPERSONID and ebe.FBIZDATE = p.fhiredate " +
  807. " left join T_HR_EmpEnrollBizBill eb on ebe.FBILLID = eb.FID and eb.FBILLSTATE = 3 " +
  808. " left join T_HR_ResignBizBillEntry rbe on rbe.FPERSONID = f.FPERSONID and (p.fhiredate<=rbe.FBIZDATE or rbe.FBIZDATE is null) " +
  809. " left join T_HR_ResignBizBill rb on rb.fid = rbe.FBILLID and rb.FBILLSTATE = 3 " +
  810. " where hf.fattendfilestate = 1 and f.CFStartTime <= cast('"+yearLastDayStr+"' as datetime) and (f.CFEndTime >= cast('"+yearFirstDayStr+"' as datetime) or f.CFEndTime is null) and year(p.fhiredate)<="+year+" and year(p.FLEFFDT)>="+year ;
  811. }
  812. if (StringUtils.isNotEmpty(personNumStr)) {
  813. sql += " and p.fnumber in (" + personNumStr + ") ";
  814. }
  815. IRowSet iRowSet = DbUtil.executeQuery(ctx, sql);
  816. while (iRowSet.next()) {
  817. String holidayPolicyId = iRowSet.getString("holidayPolicyId");
  818. if (StringUtils.isEmpty(holidayPolicyId)) {
  819. continue;
  820. }
  821. BigDecimal standardLimit = BigDecimal.valueOf(initialLimit);
  822. String limitId = iRowSet.getString("limitId");
  823. // 入职日期
  824. java.sql.Date joinDate = iRowSet.getDate("fhiredate");
  825. java.sql.Date fplanformaldate = iRowSet.getDate("FPLANFORMALDATE");
  826. // 离职日期
  827. java.sql.Date leaveDate = iRowSet.getDate("leaveDate");
  828. // 开始日期
  829. java.sql.Date cfStartTime = iRowSet.getDate("CFStartTime");
  830. // 生效日期
  831. java.sql.Date effectDate = iRowSet.getDate("CFStartTime");
  832. // 结束日期
  833. java.sql.Date cfEndTime = iRowSet.getDate("CFEndTime");
  834. // 入职折算
  835. if (DateTimeUtils.getYear(joinDate) == DateTimeUtils.getYear(cfStartTime) && joinDate.getTime() > cfStartTime.getTime()) {
  836. cfStartTime = joinDate;
  837. effectDate = iRowSet.getDate("FPLANFORMALDATE") != null ? iRowSet.getDate("FPLANFORMALDATE") : joinDate;
  838. } else if (fplanformaldate != null && DateTimeUtils.getYear(fplanformaldate) == DateTimeUtils.getYear(cfStartTime) && fplanformaldate.getTime() > cfStartTime.getTime()) {
  839. effectDate = fplanformaldate;
  840. }
  841. // 离职折算
  842. if (leaveDate != null && DateTimeUtils.getYear(currentDate) == DateTimeUtils.getYear(leaveDate)) {
  843. if (DateTimeUtils.getYear(leaveDate) == DateTimeUtils.getYear(cfEndTime) && cfEndTime.getTime() > leaveDate.getTime()) {
  844. cfEndTime = leaveDate;
  845. }
  846. }
  847. // 开始时间必须小于或等于结束日期
  848. if (cfStartTime.getTime() > cfEndTime.getTime()) {
  849. continue;
  850. }
  851. standardLimit = standardLimit.multiply(BigDecimal.valueOf(DateTimeUtils.getMonth(cfEndTime) - DateTimeUtils.getMonth(cfStartTime) + 1)).divide(BigDecimal.valueOf(MONTH_NUM_12), 10, BigDecimal.ROUND_HALF_UP);
  852. // 年假取整
  853. // 整数部分
  854. BigDecimal standardLimitInteger = standardLimit.setScale(0, RoundingMode.FLOOR);
  855. // 小数部分
  856. BigDecimal standardLimitDecimal = standardLimit.subtract(standardLimitInteger);
  857. if (Double.doubleToLongBits(INTEGERPERCISION_HALF) == Double.doubleToLongBits(nursingAndParentalLeaveIntegerPrecision)) {
  858. if (StringUtils.equals(INTEGERMETHOD_UP, nursingAndParentalLeaveIntegerMethod)) {
  859. if (standardLimitDecimal.compareTo(BigDecimal.valueOf(0.5)) > 0) {
  860. standardLimit = standardLimit.setScale(0, RoundingMode.CEILING);
  861. } else if (standardLimitDecimal.compareTo(BigDecimal.ZERO) > 0){
  862. standardLimit = standardLimitInteger.add(BigDecimal.valueOf(0.5));
  863. } else {
  864. standardLimit = standardLimitInteger;
  865. }
  866. } else {
  867. if (standardLimitDecimal.compareTo(BigDecimal.valueOf(0.5)) > 0) {
  868. standardLimit = standardLimitInteger.add(BigDecimal.valueOf(0.5));
  869. } else {
  870. standardLimit = standardLimit.setScale(0, RoundingMode.FLOOR);
  871. }
  872. }
  873. } else {
  874. if (StringUtils.equals(INTEGERMETHOD_UP, nursingAndParentalLeaveIntegerMethod)) {
  875. standardLimit = standardLimit.setScale(0, RoundingMode.CEILING);
  876. } else {
  877. standardLimit = standardLimit.setScale(0, RoundingMode.FLOOR);
  878. }
  879. }
  880. if (StringUtils.isNotEmpty(limitId)) {
  881. HolidayLimitInfo holidayLimitInfo = new HolidayLimitInfo();
  882. holidayLimitInfo.setId(BOSUuid.read(limitId));
  883. // 标准额度
  884. holidayLimitInfo.setStandardLimit(standardLimit);
  885. holidayLimitInfo.setRealLimit(standardLimit.add(iRowSet.getBigDecimal("FADDORSUBLIMIT")));
  886. holidayLimitInfo.setRemainLimit(standardLimit.add(iRowSet.getBigDecimal("FADDORSUBLIMIT")).subtract(iRowSet.getBigDecimal("FUSEDLIMIT")).subtract(iRowSet.getBigDecimal("FreezeLimit")));
  887. holidayLimitInfo.setCycleBeginDate(cfStartTime);
  888. holidayLimitInfo.setCycleEndDate(cfEndTime);
  889. holidayLimitInfo.setEffectDate(effectDate);
  890. holidayLimitInfo.setDelayDate(yearLastDay);
  891. if (leaveDate != null && leaveDate.getTime() == cfEndTime.getTime()) {
  892. holidayLimitInfo.setDelayDate(cfEndTime);
  893. }
  894. holidayLimitInfo.setLastUpdateUser(ContextUtil.getCurrentUserInfo(ctx));
  895. holidayLimitInfo.setLastUpdateTime(new Timestamp(nowDate.getTime()));
  896. updateList.add(holidayLimitInfo);
  897. } else {
  898. HolidayLimitInfo holidayLimitInfo = new HolidayLimitInfo();
  899. holidayLimitInfo.setStandardLimit(standardLimit);
  900. holidayLimitInfo.setRealLimit(standardLimit);
  901. holidayLimitInfo.setRemainLimit(standardLimit);
  902. holidayLimitInfo.setFreezeLimit(BigDecimal.ZERO);
  903. holidayLimitInfo.setUsedLimit(BigDecimal.ZERO);
  904. holidayLimitInfo.setAddOrSubLimit(BigDecimal.ZERO);
  905. holidayLimitInfo.setPreOverdraftLimit(BigDecimal.ZERO);
  906. holidayLimitInfo.setCycleBeginDate(cfStartTime);
  907. holidayLimitInfo.setCycleEndDate(cfEndTime);
  908. holidayLimitInfo.setEffectDate(effectDate);
  909. holidayLimitInfo.setDelayDate(yearLastDay);
  910. if (leaveDate != null && leaveDate.getTime() == cfEndTime.getTime()) {
  911. holidayLimitInfo.setDelayDate(cfEndTime);
  912. }
  913. holidayLimitInfo.setYear(DateTimeUtils.getYear(yearFirstDay));
  914. HolidayPolicyInfo holidayPolicyInfo = new HolidayPolicyInfo();
  915. holidayPolicyInfo.setId(BOSUuid.read(holidayPolicyId));
  916. holidayLimitInfo.setHolidayPolicy(holidayPolicyInfo);
  917. holidayLimitInfo.setHolidayUnit(HolidayTypeUnitEnum.day);
  918. holidayLimitInfo.setEnableCycle(true);
  919. PersonInfo personInfo = new PersonInfo();
  920. personInfo.setId(BOSUuid.read(iRowSet.getString("FPERSONID")));
  921. holidayLimitInfo.setProposer(personInfo);
  922. holidayLimitInfo.setStatus(HolidayLimitStatus.audited);
  923. if (StringUtils.isNotEmpty(iRowSet.getString("FADMINORGUNITID"))) {
  924. AdminOrgUnitInfo adminOrgUnitInfo = new AdminOrgUnitInfo();
  925. adminOrgUnitInfo.setId(BOSUuid.read(iRowSet.getString("FADMINORGUNITID")));
  926. holidayLimitInfo.setAdminOrgUnit(adminOrgUnitInfo);
  927. }
  928. if (StringUtils.isNotEmpty(iRowSet.getString("FHRORGUNITID"))) {
  929. HROrgUnitInfo hrOrgUnitInfo = new HROrgUnitInfo();
  930. hrOrgUnitInfo.setId(BOSUuid.read(iRowSet.getString("FHRORGUNITID")));
  931. holidayLimitInfo.setHrOrgUnit(hrOrgUnitInfo);
  932. }
  933. if (StringUtils.isNotEmpty(iRowSet.getString("FPOSITIONID"))) {
  934. PositionInfo positionInfo = new PositionInfo();
  935. positionInfo.setId(BOSUuid.read(iRowSet.getString("FPOSITIONID")));
  936. holidayLimitInfo.setPosition(positionInfo);
  937. }
  938. CtrlUnitInfo ctrlUnitInfo = new CtrlUnitInfo();
  939. ctrlUnitInfo.setId(BOSUuid.read("00000000-0000-0000-0000-000000000000CCE7AED4"));
  940. holidayLimitInfo.setCU(ctrlUnitInfo);
  941. holidayLimitInfo.setCycleDate(yearLastDay);
  942. holidayLimitInfo.setCreator(ContextUtil.getCurrentUserInfo(ctx));
  943. holidayLimitInfo.setCreateTime(new Timestamp(nowDate.getTime()));
  944. holidayLimitInfo.setLastUpdateUser(ContextUtil.getCurrentUserInfo(ctx));
  945. holidayLimitInfo.setLastUpdateTime(new Timestamp(nowDate.getTime()));
  946. addList.add(holidayLimitInfo);
  947. }
  948. }
  949. if (addList.size() > 0) {
  950. HolidayLimitFactory.getLocalInstance(ctx).addnewBatchData(addList);
  951. }
  952. if (updateList.size() > 0) {
  953. HolidayLimitFactory.getLocalInstance(ctx).updateBatchData(updateList);
  954. }
  955. } catch (ParseException | SQLException e) {
  956. throw new BOSException(e);
  957. } catch (EASBizException e) {
  958. throw new BOSException(e);
  959. }
  960. }
  961. /**
  962. * 创建社会关系临时表 处理日期区间合并数据
  963. * @param ctx
  964. * @param cnLeave
  965. * @return
  966. * @throws BOSException
  967. */
  968. private String createPersonFamilyTempTable(Context ctx, String cnLeave) throws BOSException {
  969. String dbType = ContextUtil.getDbType(ctx);
  970. String view_pf_PersonFamilyTempTable = "";
  971. // 育儿护理多段统计是否更新视图脚本
  972. if (StringUtils.equalsIgnoreCase(nursingAndParentalLeaveUpdateSql, "Y")) {
  973. // 删除视图
  974. if (StringUtils.equalsIgnoreCase("MS SQL Server", dbType)) {
  975. String dropView = " IF EXISTS (SELECT * FROM sys.views WHERE name = 'view_pf_DateRanges_"+cnLeave+"') " +
  976. " DROP VIEW view_pf_DateRanges_"+cnLeave;
  977. DbUtil.execute(ctx, dropView);
  978. dropView = " IF EXISTS (SELECT * FROM sys.views WHERE name = 'view_pf_CTE_"+cnLeave+"') " +
  979. " DROP VIEW view_pf_CTE_"+cnLeave;
  980. DbUtil.execute(ctx, dropView);
  981. dropView = " IF EXISTS (SELECT * FROM sys.views WHERE name = 'view_pf_MergedRanges_"+cnLeave+"') " +
  982. " DROP VIEW view_pf_MergedRanges_"+cnLeave;
  983. DbUtil.execute(ctx, dropView);
  984. dropView = " IF EXISTS (SELECT * FROM sys.views WHERE name = 'view_pf_GroupedRanges_"+cnLeave+"') " +
  985. " DROP VIEW view_pf_GroupedRanges_"+cnLeave;
  986. DbUtil.execute(ctx, dropView);
  987. }
  988. // 创建视图
  989. String createView = " /*dialect*/create or replace view view_pf_DateRanges_"+cnLeave+" as ( " +
  990. " select CFStartTime StartDate,CFEndTime EndDate,FPERSONID PersonID from t_hr_personfamily where CFCnleave = '"+cnLeave+"' " +
  991. " ) ";
  992. if (StringUtils.equalsIgnoreCase("MS SQL Server", dbType)) {
  993. createView = " /*dialect*/create view view_pf_DateRanges_"+cnLeave+" as ( " +
  994. " select CFStartTime StartDate,CFEndTime EndDate,FPERSONID PersonID from t_hr_personfamily where CFCnleave = '"+cnLeave+"' " +
  995. " ) ";
  996. }
  997. DbUtil.execute(ctx, createView);
  998. createView = " /*dialect*/create or replace view view_pf_CTE_"+cnLeave+" AS ( " +
  999. " SELECT PersonID,StartDate, EndDate,LAG(EndDate) OVER (PARTITION BY PersonID ORDER BY StartDate) AS prev_end_date FROM view_pf_DateRanges_"+ cnLeave +
  1000. ") ";
  1001. if (StringUtils.equalsIgnoreCase("MS SQL Server", dbType)) {
  1002. createView = " /*dialect*/create view view_pf_CTE_"+cnLeave+" AS ( " +
  1003. " SELECT PersonID,StartDate, EndDate,LAG(EndDate) OVER (PARTITION BY PersonID ORDER BY StartDate) AS prev_end_date FROM view_pf_DateRanges_" + cnLeave +
  1004. ") ";
  1005. }
  1006. DbUtil.execute(ctx, createView);
  1007. createView = " /*dialect*/create or replace view view_pf_MergedRanges_"+cnLeave+" AS ( " +
  1008. " SELECT PersonID,StartDate,EndDate,CASE WHEN StartDate <= prev_end_date + INTERVAL '1 day' THEN 0 ELSE 1 END AS is_overlap FROM view_pf_CTE_" + cnLeave +
  1009. ") ";
  1010. if (StringUtils.equalsIgnoreCase("MS SQL Server", dbType)) {
  1011. createView = " /*dialect*/create view view_pf_MergedRanges_"+cnLeave+" AS ( " +
  1012. " SELECT PersonID,StartDate,EndDate,CASE WHEN StartDate <= DATEADD(day, 1, prev_end_date) THEN 0 ELSE 1 END AS is_overlap FROM view_pf_CTE_" + cnLeave +
  1013. ") ";
  1014. }
  1015. DbUtil.execute(ctx, createView);
  1016. createView = " /*dialect*/create or replace view view_pf_GroupedRanges_"+cnLeave+" AS ( " +
  1017. " SELECT PersonID,StartDate,EndDate,SUM(is_overlap) OVER (PARTITION BY PersonID ORDER BY StartDate) AS grp FROM view_pf_MergedRanges_" + cnLeave +
  1018. ") ";
  1019. if (StringUtils.equalsIgnoreCase("MS SQL Server", dbType)) {
  1020. createView = " /*dialect*/create view view_pf_GroupedRanges_"+cnLeave+" AS ( " +
  1021. " SELECT PersonID,StartDate,EndDate,SUM(is_overlap) OVER (PARTITION BY PersonID ORDER BY StartDate) AS grp FROM view_pf_MergedRanges_" + cnLeave +
  1022. ") ";
  1023. }
  1024. DbUtil.execute(ctx, createView);
  1025. }
  1026. view_pf_PersonFamilyTempTable = " (SELECT PersonID fpersonid,MIN(StartDate) AS CFStartTime,MAX(EndDate) AS CFEndTime FROM view_pf_GroupedRanges_"+cnLeave+" GROUP BY PersonID, grp ORDER BY PersonID, CFStartTime) ";
  1027. if (StringUtils.equalsIgnoreCase("MS SQL Server", dbType)) {
  1028. view_pf_PersonFamilyTempTable = " (SELECT top 100 percent PersonID fpersonid,MIN(StartDate) AS CFStartTime,MAX(EndDate) AS CFEndTime FROM view_pf_GroupedRanges_"+cnLeave+" GROUP BY PersonID, grp ORDER BY PersonID, CFStartTime) ";
  1029. }
  1030. return view_pf_PersonFamilyTempTable;
  1031. }
  1032. /**
  1033. * 员工列表
  1034. * @param ctx
  1035. * @param
  1036. * @return
  1037. * @throws BOSException
  1038. * @throws SQLException
  1039. */
  1040. private List<String> getPersonData(Context ctx,String leaveNumber, int year) throws BOSException, SQLException{
  1041. String nursingSql = " SELECT a.FPROPOSERID FROM T_HR_ATS_HolidayLimit as a ,T_HR_ATS_HolidayPolicy as b , T_HR_ATS_HolidayType c " +
  1042. " where a.FHOLIDAYPOLICYID = b.FID and b.FHOLIDAYTYPEID = c.FID and c.FNUMBER = '" + leaveNumber + "' and FYear = "+year+" " ;
  1043. IRowSet rs = DbUtil.executeQuery(ctx, nursingSql);
  1044. List<String> personList = new ArrayList<String>();
  1045. while(rs.next()){
  1046. personList.add(rs.getString("FPROPOSERID"));
  1047. }
  1048. return personList;
  1049. }
  1050. /**
  1051. * 开始时间
  1052. * @param
  1053. * @return
  1054. */
  1055. private static Date getStartDate(Date startDate ){
  1056. Calendar calendar = Calendar.getInstance();
  1057. int year = calendar.get(Calendar.YEAR);
  1058. calendar.clear();
  1059. calendar.set(Calendar.YEAR, year);
  1060. calendar.add(Calendar.MONTH, 1);
  1061. calendar.set(Calendar.DAY_OF_MONTH, 0);
  1062. if(startDate.before(calendar.getTime())){
  1063. startDate = calendar.getTime();
  1064. }
  1065. return startDate;
  1066. }
  1067. /**
  1068. * 结束时间
  1069. * @param
  1070. * @return
  1071. */
  1072. private static Date getEndDate(Date endDate){
  1073. Calendar calendar = Calendar.getInstance();
  1074. int year = calendar.get(Calendar.YEAR);
  1075. calendar.set(Calendar.YEAR, year);
  1076. calendar.roll(Calendar.DAY_OF_YEAR, -1);
  1077. calendar.set(Calendar.MONTH, 11);
  1078. calendar.set(Calendar.DAY_OF_MONTH, 1);
  1079. if(endDate.after(calendar.getTime())){
  1080. endDate = calendar.getTime();
  1081. }
  1082. return endDate;
  1083. }
  1084. /**
  1085. * 返回休假天数
  1086. * @param day
  1087. * @param month
  1088. * @return
  1089. */
  1090. public double getLeaveDay(double day,int month) {
  1091. double leaveDay = day / 12.0 * month;
  1092. int floorInt = (int) leaveDay;
  1093. double decimals = leaveDay - floorInt;
  1094. if(decimals < 0.5) {
  1095. System.out.print("可休假额度:" + floorInt);
  1096. return floorInt ;
  1097. }else {
  1098. System.out.print("可休假额度:" + floorInt + 0.5);
  1099. return (floorInt + 0.5);
  1100. }
  1101. }
  1102. /**
  1103. * 获取假期类型为对应的假期制度id集合
  1104. * @param ctx
  1105. * @param holidayNumber
  1106. * @return
  1107. */
  1108. public String getHolidayPolicyIds(Context ctx, String holidayNumber) {
  1109. StringBuffer holidayPolicyIds = new StringBuffer();
  1110. try {
  1111. HolidayTypeCollection holidayTypeCollection = HolidayTypeFactory.getLocalInstance(ctx).getHolidayTypeCollection("where number = '"+holidayNumber+"'");
  1112. if(holidayTypeCollection!=null && holidayTypeCollection.size()>0) {
  1113. HolidayPolicyCollection holidayPolicyCollection = HolidayPolicyFactory.getLocalInstance(ctx).getHolidayPolicyCollection("where holidayType = '"+holidayTypeCollection.get(0).getId().toString()+"'");
  1114. for(int i=0;i<holidayPolicyCollection.size();i++) {
  1115. holidayPolicyIds.append("'"+holidayPolicyCollection.get(i).getId().toString()+"',");
  1116. }
  1117. if(holidayPolicyIds.length()>0) {
  1118. holidayPolicyIds = holidayPolicyIds.deleteCharAt(holidayPolicyIds.length()-1);
  1119. }
  1120. }
  1121. } catch (BOSException e) {
  1122. e.printStackTrace();
  1123. }
  1124. return holidayPolicyIds.toString();
  1125. }
  1126. /**
  1127. * 根据假期额度名称获取id
  1128. * @param ctx
  1129. * @param holidayName
  1130. * @return
  1131. */
  1132. // public String getHolidayPolicyID(Context ctx, String holidayNumber) {
  1133. // try {
  1134. // HolidayTypeCollection holidayTypeCollection = HolidayTypeFactory.getLocalInstance(ctx).getHolidayTypeCollection("where number = '"+holidayNumber+"'");
  1135. // if(holidayTypeCollection!=null && holidayTypeCollection.size()>0) {
  1136. // HolidayPolicyCollection holidayPolicyCollection = HolidayPolicyFactory.getLocalInstance(ctx).getHolidayPolicyCollection("where holidayType = '"+holidayTypeCollection.get(0).getId().toString()+"'");
  1137. // if(holidayPolicyCollection != null && holidayPolicyCollection.size()>0) {
  1138. // return holidayPolicyCollection.get(0).getId().toString();
  1139. // }
  1140. // }
  1141. // } catch (BOSException e) {
  1142. // e.printStackTrace();
  1143. // }
  1144. // return "";
  1145. // }
  1146. }