WorhHoursService.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. package com.kingdee.eas.custom.server;
  2. import java.math.BigDecimal;
  3. import java.math.RoundingMode;
  4. import java.security.SecureRandom;
  5. import java.sql.SQLException;
  6. import java.sql.Timestamp;
  7. import java.text.ParseException;
  8. import java.text.SimpleDateFormat;
  9. import java.util.ArrayList;
  10. import java.util.Base64;
  11. import java.util.Date;
  12. import java.util.HashMap;
  13. import java.util.List;
  14. import java.util.Map;
  15. import javax.crypto.Cipher;
  16. import javax.crypto.KeyGenerator;
  17. import javax.crypto.SecretKey;
  18. import javax.crypto.spec.SecretKeySpec;
  19. import com.kingdee.bos.BOSException;
  20. import com.kingdee.bos.Context;
  21. import com.kingdee.bos.bsf.service.app.IHRMsfService;
  22. import com.kingdee.bos.dao.IObjectPK;
  23. import com.kingdee.bos.util.BOSUuid;
  24. import com.kingdee.eas.base.permission.UserInfo;
  25. import com.kingdee.eas.basedata.person.PersonCollection;
  26. import com.kingdee.eas.basedata.person.PersonFactory;
  27. import com.kingdee.eas.basedata.person.PersonInfo;
  28. import com.kingdee.eas.common.EASBizException;
  29. import com.kingdee.eas.framework.CoreBaseCollection;
  30. import com.kingdee.eas.framework.LineResult;
  31. import com.kingdee.eas.framework.Result;
  32. import com.kingdee.eas.hr.base.HRBillStateEnum;
  33. import com.kingdee.eas.hr.project.IWorkHoursConfirm;
  34. import com.kingdee.eas.hr.project.IWorkHoursReport;
  35. import com.kingdee.eas.hr.project.ProjectManagementInfo;
  36. import com.kingdee.eas.hr.project.WorkHoursConfirmCollection;
  37. import com.kingdee.eas.hr.project.WorkHoursConfirmFactory;
  38. import com.kingdee.eas.hr.project.WorkHoursConfirmInfo;
  39. import com.kingdee.eas.hr.project.WorkHoursReportEntryInfo;
  40. import com.kingdee.eas.hr.project.WorkHoursReportFactory;
  41. import com.kingdee.eas.hr.project.WorkHoursReportInfo;
  42. import com.kingdee.eas.hr.project.dataSource;
  43. import com.kingdee.eas.util.app.ContextUtil;
  44. import com.kingdee.eas.util.app.DbUtil;
  45. import com.kingdee.jdbc.rowset.IRowSet;
  46. import com.kingdee.shr.empresume.util.ErrorCodeUtil;
  47. public class WorhHoursService implements IHRMsfService{
  48. private static final String ALGORITHM = "AES";
  49. private static final int KEY_SIZE = 128;
  50. public Object process(Context ctx, Map param) throws EASBizException, BOSException {
  51. _initWorkHoursConfirm(ctx, null, null, null, 100);
  52. return null;
  53. }
  54. /**
  55. * 生成打卡确认单
  56. */
  57. private void _initWorkHoursConfirm(Context ctx, String number, String star, String end, int day)
  58. throws BOSException, EASBizException {
  59. IRowSet rs = null;
  60. List<String> keyList = new ArrayList<String>();
  61. IWorkHoursConfirm biz = WorkHoursConfirmFactory.getLocalInstance(ctx);
  62. WorkHoursConfirmInfo wInfo = null;
  63. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  64. List<WorkHoursConfirmInfo> listInfo = null;
  65. List<String> listproid = new ArrayList<String>();
  66. Map<String,String> mapdate = new HashMap<String,String>();
  67. Map<String,String> mapproid = new HashMap<String,String>();
  68. //存放打卡数据 map
  69. Map<String,List<WorkHoursConfirmInfo>> mapInfo = new HashMap<String,List<WorkHoursConfirmInfo>>();
  70. StringBuffer sb = new StringBuffer("/*dialect*/");
  71. if(day <= 0) {
  72. //默认3天
  73. day = 3;
  74. }
  75. sb = new StringBuffer("/*dialect*/");
  76. sb.append(" select distinct t1.fid pfid,t3.fid pid,TO_CHAR(t.FPUNCHCARDTIME, 'YYYY-MM-DD') CFCLOCKTIME1,t3en.fname_l2 CFCLOCKLOCATION from T_HR_ATS_PunchCardRecord t ").append(" \n");
  77. sb.append(" inner join T_BD_Person t1 on t1.fid = t.FPROPOSERID ").append(" \n");
  78. sb.append(" inner join CT_PRO_MemberManagement t2 on t2.CFEmployeeID = t1.fid ").append(" \n");
  79. sb.append(" inner join CT_PRO_ProjectManagement t3 on t3.fid = t2.CFProjectManagemenID ").append(" \n");
  80. sb.append(" inner join CT_PRO_ProjectClock t3en on t3en.CFPROJECTID = t3.fid and t3en.CFSTATE = '1' ").append(" \n");
  81. sb.append(" where t.FPUNCHCARDPLACE is not null ").append(" \n");
  82. // sb.append(" where t3.CFExpectedStartTime <FPUNCHCARDTIME and t3.CFExpectedEndTime >= FPUNCHCARDTIME ").append(" \n");
  83. //按照时间过滤
  84. if(star != null && star.length() > 0) {
  85. sb.append(" and t.FPUNCHCARDTIME >= TO_DATE('"+star+"', 'YYYY-MM-DD HH24:MI:SS')").append(" \n");
  86. }else if(end != null && end.length() > 0) {
  87. sb.append(" and t.FPUNCHCARDTIME <= TO_DATE('"+end+"', 'YYYY-MM-DD HH24:MI:SS')").append(" \n");
  88. }else {
  89. sb.append(" and t.FPUNCHCARDTIME >= sysdate -"+day).append(" \n");
  90. }
  91. if(number !=null && number.length() > 0) {
  92. sb.append(" and t1.fnumber in (").append(number).append(") \n");
  93. }
  94. //获取打卡数据
  95. rs = DbUtil.executeQuery(ctx, sb.toString());
  96. //项目对应的所有位置
  97. Map<String,List<String>> proCFCLOCKLOCATION = new HashMap<String,List<String>>();
  98. //人员+年月日 有几个项目
  99. Map<String,List<String>> keypro = new HashMap<String,List<String>>();
  100. List<String> CFCLOCKLOCATIONList = new ArrayList<String>();
  101. List<String> proList = new ArrayList<String>();
  102. try {
  103. if(rs != null && rs.size() > 0) {
  104. while (rs.next()) {
  105. String pfid = rs.getString("pfid");
  106. String CFCLOCKTIME1 = rs.getString("CFCLOCKTIME1");
  107. String proid = rs.getString("pid");
  108. String CFCLOCKLOCATION = rs.getString("CFCLOCKLOCATION");
  109. String key = pfid+CFCLOCKTIME1; //人员+年月日
  110. if(keypro.containsKey(key)) {
  111. proList = keypro.get(key);
  112. }else {
  113. proList = new ArrayList<String>();
  114. }
  115. if(!proList.contains(proid)) {
  116. proList.add(proid);
  117. }
  118. keypro.put(key, proList);
  119. if(CFCLOCKLOCATION != null && CFCLOCKLOCATION.length() > 0) {
  120. if(proCFCLOCKLOCATION.containsKey(proid)) {
  121. CFCLOCKLOCATIONList = proCFCLOCKLOCATION.get(proid);
  122. }else {
  123. CFCLOCKLOCATIONList = new ArrayList<String>();
  124. }
  125. if(!CFCLOCKLOCATIONList.contains(CFCLOCKLOCATION)) {
  126. CFCLOCKLOCATIONList.add(CFCLOCKLOCATION);
  127. }
  128. proCFCLOCKLOCATION.put(proid, CFCLOCKLOCATIONList);
  129. }
  130. }
  131. }
  132. System.out.println("keypro"+keypro.toString());
  133. System.out.println("proCFCLOCKLOCATION"+proCFCLOCKLOCATION.toString());
  134. sb = new StringBuffer("/*dialect*/");
  135. sb.append(" select t.fid tfid,t1.fid pid,t1.fnumber,t1.fname_l2,t3.fid proid,t3.fnumber,t3.CFProjectName ,TO_CHAR(t.FPUNCHCARDTIME, 'YYYY-MM-DD') CFCLOCKTIME1 "
  136. + ",TO_CHAR(t.FPUNCHCARDTIME, 'YYYY-MM-DD HH24:MI:SS') CFCLOCKTIME,t.FPUNCHCARDPLACE FPUNCHCARDPLACE from T_HR_ATS_PunchCardRecord t ").append(" \n");
  137. sb.append(" inner join T_BD_Person t1 on t1.fid = t.FPROPOSERID ").append(" \n");
  138. sb.append(" inner join CT_PRO_MemberManagement t2 on t2.CFEmployeeID = t1.fid ").append(" \n");
  139. sb.append(" inner join CT_PRO_ProjectManagement t3 on t3.fid = t2.CFProjectManagemenID ").append(" \n");
  140. // sb.append(" where t3.CFExpectedStartTime <FPUNCHCARDTIME and t3.CFExpectedEndTime >= FPUNCHCARDTIME ").append(" \n");
  141. sb.append(" where t.FPUNCHCARDPLACE is not null and t.fid not in (select FSOURCEBILLID from CT_PRO_WorkHoursConfirm where FSOURCEBILLID is not null ) ").append(" \n");
  142. //按照时间过滤
  143. if(star != null && star.length() > 0) {
  144. sb.append(" and t.FPUNCHCARDTIME >= TO_DATE('"+star+"', 'YYYY-MM-DD HH24:MI:SS')").append(" \n");
  145. }else if(end != null && end.length() > 0) {
  146. sb.append(" and t.FPUNCHCARDTIME <= TO_DATE('"+end+"', 'YYYY-MM-DD HH24:MI:SS')").append(" \n");
  147. }else {
  148. sb.append(" and t.FPUNCHCARDTIME >= sysdate -"+day).append(" \n");
  149. }
  150. if(number !=null && number.length() > 0) {
  151. sb.append(" and t1.fnumber in (").append(number).append(") \n");
  152. }
  153. sb.append(" order by t1.fid, t.FPUNCHCARDTIME desc ").append(" \n");//排序
  154. rs = DbUtil.executeQuery(ctx, sb.toString());
  155. while (rs.next()) {
  156. String pid = rs.getString("pid");
  157. String tfid = rs.getString("tfid");
  158. String proid = rs.getString("proid");
  159. String FPUNCHCARDPLACE = rs.getString("FPUNCHCARDPLACE"); //考勤位置打卡
  160. String CFCLOCKTIME = rs.getString("CFCLOCKTIME"); //年月日时分秒 打卡时间
  161. String CFCLOCKTIME1 = rs.getString("CFCLOCKTIME1"); //年月日--------当前
  162. String key = pid+CFCLOCKTIME1;//员工id+年月日为 一个 唯一组合
  163. //同一天不在多个项目情况下进行标记
  164. if(!listproid.contains(key)) {
  165. listproid.add(key);
  166. }
  167. //去重-年月日时分秒匹配-跳过
  168. if(mapdate.containsKey(key) && mapproid.get(key).equals(CFCLOCKTIME)) {
  169. continue;
  170. }
  171. if(mapInfo.containsKey(key)) {
  172. listInfo = mapInfo.get(key);
  173. }else {
  174. listInfo = new ArrayList<WorkHoursConfirmInfo>();
  175. keyList.add(key);
  176. mapproid.put(key, proid);
  177. mapdate.put(key, CFCLOCKTIME);
  178. }
  179. wInfo = getWConfirmInfo(ctx,pid, proid,proCFCLOCKLOCATION,FPUNCHCARDPLACE,simpleDateFormat.parse(CFCLOCKTIME),tfid);
  180. listInfo.add(wInfo);
  181. mapInfo.put(key, listInfo);
  182. }
  183. } catch (SQLException | ParseException e) {
  184. e.printStackTrace();
  185. }
  186. //写入打卡数据
  187. WorkHoursConfirmCollection addSubColl = new WorkHoursConfirmCollection();
  188. WorkHoursConfirmCollection addAudColl = new WorkHoursConfirmCollection();
  189. //多个项目且不在同一个项目情况下
  190. List<String> notList = new ArrayList<String>();
  191. if(listproid.size() > 0) {
  192. for (int i = 0; i < listproid.size(); i++) {
  193. String key = listproid.get(i);
  194. if(keypro.containsKey(key)) {
  195. proList = keypro.get(key);
  196. //当天有多个项目
  197. if(proList.size() > 1) {
  198. listInfo = mapInfo.get(key);
  199. List<String> addList = new ArrayList<String>();
  200. List<String> locaProList = new ArrayList<String>();
  201. List<String> idProList = new ArrayList<String>();
  202. boolean boolismu = false;
  203. //同一个打卡位置关联了多个项目
  204. for (int j = 0; j < listInfo.size(); j++) {
  205. wInfo = listInfo.get(j);
  206. if(wInfo.getProject() != null && wInfo.getClockLocation() != null) {
  207. String proid = wInfo.getProject().getId().toString();
  208. List<String> getclock = proCFCLOCKLOCATION.get(proid);
  209. if(getclock != null) {
  210. for (int k = 0; k < getclock.size(); k++) {
  211. if(getclock.get(k).contains(wInfo.getClockLocation())){
  212. if(locaProList.contains(wInfo.getClockLocation())) {
  213. if(!idProList.contains(proid)) {
  214. boolismu = true;
  215. }
  216. }else {
  217. if(!idProList.contains(proid)){
  218. idProList.add(proid);
  219. }
  220. locaProList.add(wInfo.getClockLocation());
  221. }
  222. }
  223. }
  224. }
  225. }
  226. }
  227. if(boolismu) {
  228. for (int j = 0; j < listInfo.size(); j++) {
  229. wInfo = listInfo.get(j);
  230. if(locaProList.contains(wInfo.getClockLocation())) {
  231. wInfo.setProject(null); //所属项目
  232. wInfo.setBillState(HRBillStateEnum.SAVED);//暂存
  233. addSubColl.add(wInfo);
  234. }
  235. }
  236. }
  237. for (int j = 0; j < listInfo.size(); j++) {
  238. wInfo = listInfo.get(j);
  239. if(wInfo.getClockLocation() != null && wInfo.getProject() != null && !addList.contains(wInfo.getSourceBillId())) {
  240. addList.add(wInfo.getSourceBillId());
  241. if(wInfo.getBillState().compareTo(HRBillStateEnum.AUDITED) == 0) {
  242. addAudColl.add(wInfo);
  243. }else {
  244. //匹配不上的
  245. addSubColl.add(wInfo);
  246. }
  247. }
  248. }
  249. for (int j = 0; j < listInfo.size(); j++) {
  250. wInfo = listInfo.get(j);
  251. if(wInfo.getClockLocation() != null && !addList.contains(wInfo.getSourceBillId())) {
  252. addList.add(wInfo.getSourceBillId());
  253. if(wInfo.getBillState().compareTo(HRBillStateEnum.AUDITED) == 0) {
  254. addAudColl.add(wInfo);
  255. }else {
  256. //匹配不上的
  257. addSubColl.add(wInfo);
  258. }
  259. }
  260. }
  261. notList.add(key);
  262. }
  263. }
  264. }
  265. }
  266. //剩余数据处理
  267. if (keyList.size() > 0){
  268. for (int i = 0; i < keyList.size(); i++) {
  269. String key = keyList.get(i);
  270. if(notList.contains(key)) {
  271. continue;
  272. }
  273. listInfo = mapInfo.get(key);
  274. for (int j = 0; j < listInfo.size(); j++) {
  275. wInfo = listInfo.get(j);
  276. //直接生效
  277. if(wInfo.getBillState().compareTo(HRBillStateEnum.AUDITED) == 0) {
  278. addAudColl.add(wInfo);
  279. }else {
  280. //匹配不上的
  281. addSubColl.add(wInfo);
  282. }
  283. }
  284. }
  285. }
  286. //提交工作流
  287. if(addSubColl.size() > 0) {
  288. CoreBaseCollection addSubCollnew = new CoreBaseCollection();
  289. List<String> addList = new ArrayList<String>();
  290. for (int i = 0; i < addSubColl.size(); i++) {
  291. WorkHoursConfirmInfo getinfo = addSubColl.get(i);
  292. if(getinfo.getClockLocation() != null && !addList.contains(getinfo.getSourceBillId())) {
  293. addList.add(getinfo.getSourceBillId());
  294. addSubCollnew.add(getinfo);
  295. }
  296. }
  297. if(addSubCollnew.size() > 0) {
  298. biz.submit(addSubCollnew);
  299. }
  300. }
  301. if(addAudColl.size() > 0) {
  302. CoreBaseCollection addAudCollNew = new CoreBaseCollection();
  303. List<String> addList = new ArrayList<String>();
  304. for (int i = 0; i < addAudColl.size(); i++) {
  305. WorkHoursConfirmInfo getinfo = addAudColl.get(i);
  306. if(getinfo.getClockLocation() != null && !addList.contains(getinfo.getSourceBillId())) {
  307. addList.add(getinfo.getSourceBillId());
  308. addAudCollNew.add(getinfo);
  309. }
  310. }
  311. if(addAudCollNew.size() > 0) {
  312. //保存处理-审核通过
  313. Result re = biz.addnew(addAudCollNew);
  314. LineResult lr = null;
  315. if(re != null && re.size() > 0){
  316. for (int i = 0; i < re.size(); i++) {
  317. lr = re.getLineResult(i);
  318. biz.setAudited(BOSUuid.read(lr.getPk().toString())); //-审核通过
  319. }
  320. }
  321. }
  322. }
  323. }
  324. /**
  325. * 解析为工时确认单
  326. * @param pid
  327. * @param proid
  328. * @param p1
  329. * @param p2
  330. * @param clockTime
  331. * @return
  332. */
  333. private WorkHoursConfirmInfo getWConfirmInfo(Context ctx,String pid,String proid,Map<String,List<String>> map,String p2,Date clockTime,String FSOURCEBILLID) {
  334. WorkHoursConfirmInfo wInfo = new WorkHoursConfirmInfo();
  335. PersonInfo pinfo = new PersonInfo();pinfo.setId(BOSUuid.read(pid)); //人员
  336. PersonCollection personCollection = null;
  337. try {
  338. personCollection = PersonFactory.getLocalInstance(ctx).getPersonCollection(" select * where id = '"+pid+"'");
  339. } catch (BOSException e) {
  340. e.printStackTrace();
  341. }
  342. if(personCollection != null && personCollection.size()>0){
  343. pinfo = personCollection.get(0);
  344. }
  345. ProjectManagementInfo proinfo = new ProjectManagementInfo();proinfo.setId(BOSUuid.read(proid)); //所属项目
  346. wInfo.setEmployee(pinfo);
  347. wInfo.setProject(proinfo); //所属项目
  348. wInfo.setClockDate(clockTime); //打卡日期
  349. wInfo.setSourceBillId(FSOURCEBILLID);//来源id
  350. wInfo.setHrOrgUnit(pinfo.getHrOrgUnit());
  351. wInfo.setCU(pinfo.getCU());
  352. Timestamp t = new Timestamp(clockTime.getTime());
  353. wInfo.setClockTime(t); //打卡--------------------------------------------------------------------------------------------------------------
  354. //打卡位置 clockLocation
  355. if(map != null) {
  356. List<String> plist = map.get(proid);
  357. if(plist != null && plist.contains(p2)) {
  358. wInfo.setClockLocation(p2);
  359. wInfo.setBillState(HRBillStateEnum.AUDITED);//审核通过
  360. }else {
  361. if(p2 != null && p2.length() > 0){
  362. wInfo.setClockLocation(p2);
  363. }
  364. wInfo.setProject(null); //所属项目
  365. wInfo.setBillState(HRBillStateEnum.SAVED);//暂存
  366. }
  367. }else {
  368. wInfo.setProject(null); //所属项目
  369. wInfo.setBillState(HRBillStateEnum.SAVED);//暂存
  370. }
  371. return wInfo;
  372. }
  373. }