MyShrMobileNewService.java 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  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 MyShrMobileNewService 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. String password = ctx.getAIS();
  52. UserInfo currentUserInfo = ContextUtil.getCurrentUserInfo(ctx);
  53. HashMap map = new HashMap();
  54. String data = currentUserInfo.getPerson().getId().toString()+","+System.currentTimeMillis();
  55. String encryptedData = null;
  56. //加密
  57. try {
  58. encryptedData = encrypt(data, password);
  59. } catch (Exception e) {
  60. e.printStackTrace();
  61. }
  62. System.out.println("encryptedData:"+encryptedData);
  63. map.put("encryptedData", encryptedData);
  64. ErrorCodeUtil.setSuccess(map, ctx);
  65. return map;
  66. }
  67. private String encrypt(String data, String password) throws Exception {
  68. SecretKey key = generateKey(password);
  69. Cipher cipher = Cipher.getInstance(ALGORITHM);
  70. cipher.init(Cipher.ENCRYPT_MODE, key);
  71. byte[] encryptedData = cipher.doFinal(data.getBytes());
  72. return Base64.getEncoder().encodeToString(encryptedData);
  73. }
  74. private String decrypt(String encryptedData, String password) throws Exception {
  75. SecretKey key = generateKey(password);
  76. Cipher cipher = Cipher.getInstance(ALGORITHM);
  77. cipher.init(Cipher.DECRYPT_MODE, key);
  78. byte[] decryptedData = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
  79. return new String(decryptedData);
  80. }
  81. private SecretKey generateKey(String password) throws Exception {
  82. KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
  83. keyGenerator.init(KEY_SIZE, new SecureRandom(password.getBytes()));
  84. return new SecretKeySpec(keyGenerator.generateKey().getEncoded(), ALGORITHM);
  85. }
  86. /**
  87. * 生成打卡确认单
  88. */
  89. private void _initWorkHoursConfirm(Context ctx, String number, String star, String end, int day)
  90. throws BOSException, EASBizException {
  91. IRowSet rs = null;
  92. List<String> keyList = new ArrayList<String>();
  93. IWorkHoursConfirm biz = WorkHoursConfirmFactory.getLocalInstance(ctx);
  94. WorkHoursConfirmInfo wInfo = null;
  95. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  96. List<WorkHoursConfirmInfo> listInfo = null;
  97. List<String> listproid = new ArrayList<String>();
  98. Map<String,String> mapdate = new HashMap<String,String>();
  99. Map<String,String> mapproid = new HashMap<String,String>();
  100. //存放打卡数据 map
  101. Map<String,List<WorkHoursConfirmInfo>> mapInfo = new HashMap<String,List<WorkHoursConfirmInfo>>();
  102. StringBuffer sb = new StringBuffer("/*dialect*/");
  103. if(day <= 0) {
  104. //默认3天
  105. day = 3;
  106. }
  107. sb = new StringBuffer("/*dialect*/");
  108. sb.append(" select t3.fid pid,t3en.FNAME_L2 CFCLOCKLOCATION from T_HR_ATS_PunchCardRecord t ").append(" \n");
  109. sb.append(" inner join T_BD_Person t1 on t1.fid = t.FPROPOSERID ").append(" \n");
  110. sb.append(" inner join CT_PRO_MemberManagement t2 on t2.CFEmployeeID = t1.fid ").append(" \n");
  111. sb.append(" inner join CT_PRO_ProjectManagement t3 on t3.fid = t2.CFProjectManagemenID ").append(" \n");
  112. sb.append(" left join CT_PRO_ProjectClock t3en on t3en.CFPROJECTID = t3.fid and t3en.CFSTATE = '1' ").append(" \n");
  113. sb.append(" where t3.CFExpectedStartTime <FPUNCHCARDTIME and t3.CFExpectedEndTime >= FPUNCHCARDTIME ").append(" \n");
  114. //按照时间过滤
  115. if(star != null && star.length() > 0) {
  116. sb.append(" and t.FPUNCHCARDTIME >= TO_DATE('"+star+"', 'YYYY-MM-DD HH24:MI:SS')").append(" \n");
  117. }else if(end != null && end.length() > 0) {
  118. sb.append(" and t.FPUNCHCARDTIME <= TO_DATE('"+end+"', 'YYYY-MM-DD HH24:MI:SS')").append(" \n");
  119. }else {
  120. sb.append(" and t.FPUNCHCARDTIME >= sysdate -"+day).append(" \n");
  121. }
  122. if(number !=null && number.length() > 0) {
  123. sb.append(" and t1.fnumber in (").append(number).append(") \n");
  124. }
  125. //获取打卡数据
  126. rs = DbUtil.executeQuery(ctx, sb.toString());
  127. try {
  128. Map<String,List<String>> proCFCLOCKLOCATION = new HashMap<String,List<String>>();
  129. List<String> CFCLOCKLOCATIONList = new ArrayList<String>();
  130. if(rs != null && rs.size() > 0) {
  131. while (rs.next()) {
  132. String proid = rs.getString("pid");
  133. String CFCLOCKLOCATION = rs.getString("CFCLOCKLOCATION");
  134. if(CFCLOCKLOCATION != null && CFCLOCKLOCATION.length() > 0) {
  135. if(proCFCLOCKLOCATION.containsKey(proid)) {
  136. CFCLOCKLOCATIONList = proCFCLOCKLOCATION.get(proid);
  137. }else {
  138. CFCLOCKLOCATIONList = new ArrayList<String>();
  139. }
  140. if(!CFCLOCKLOCATIONList.contains(CFCLOCKLOCATION)) {
  141. CFCLOCKLOCATIONList.add(CFCLOCKLOCATION);
  142. }
  143. proCFCLOCKLOCATION.put(proid, CFCLOCKLOCATIONList);
  144. }
  145. }
  146. }
  147. System.out.println("proCFCLOCKLOCATION"+proCFCLOCKLOCATION.toString());
  148. sb = new StringBuffer("/*dialect*/");
  149. 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 "
  150. + ",TO_CHAR(t.FPUNCHCARDTIME, 'YYYY-MM-DD HH24:MI:SS') CFCLOCKTIME,t.FPUNCHCARDPLACE FPUNCHCARDPLACE from T_HR_ATS_PunchCardRecord t ").append(" \n");
  151. sb.append(" inner join T_BD_Person t1 on t1.fid = t.FPROPOSERID ").append(" \n");
  152. sb.append(" inner join CT_PRO_MemberManagement t2 on t2.CFEmployeeID = t1.fid ").append(" \n");
  153. sb.append(" inner join CT_PRO_ProjectManagement t3 on t3.fid = t2.CFProjectManagemenID ").append(" \n");
  154. sb.append(" where t3.CFExpectedStartTime <FPUNCHCARDTIME and t3.CFExpectedEndTime >= FPUNCHCARDTIME ").append(" \n");
  155. sb.append(" and t.fid not in (select FSOURCEBILLID from CT_PRO_WorkHoursConfirm where FSOURCEBILLID is not null ) ").append(" \n");
  156. //按照时间过滤
  157. if(star != null && star.length() > 0) {
  158. sb.append(" and t.FPUNCHCARDTIME >= TO_DATE('"+star+"', 'YYYY-MM-DD HH24:MI:SS')").append(" \n");
  159. }else if(end != null && end.length() > 0) {
  160. sb.append(" and t.FPUNCHCARDTIME <= TO_DATE('"+end+"', 'YYYY-MM-DD HH24:MI:SS')").append(" \n");
  161. }else {
  162. sb.append(" and t.FPUNCHCARDTIME >= sysdate -"+day).append(" \n");
  163. }
  164. if(number !=null && number.length() > 0) {
  165. sb.append(" and t1.fnumber in (").append(number).append(") \n");
  166. }
  167. sb.append(" order by t1.fid, t.FPUNCHCARDTIME desc ").append(" \n");//排序
  168. rs = DbUtil.executeQuery(ctx, sb.toString());
  169. while (rs.next()) {
  170. String pid = rs.getString("pid");
  171. String tfid = rs.getString("tfid");
  172. String proid = rs.getString("proid");
  173. String FPUNCHCARDPLACE = rs.getString("FPUNCHCARDPLACE"); //考勤位置打卡
  174. String CFCLOCKTIME = rs.getString("CFCLOCKTIME"); //年月日时分秒 打卡时间
  175. String CFCLOCKTIME1 = rs.getString("CFCLOCKTIME1"); //年月日--------当前
  176. String key = pid+CFCLOCKTIME1;//员工id+年月日为 一个 唯一组合
  177. //同一天不在多个项目情况下进行标记
  178. if(!listproid.contains(key) && mapproid.containsKey(key) && mapproid.get(key).equals(proid)) {
  179. listproid.add(key);
  180. }
  181. //去重-年月日时分秒匹配-跳过
  182. if(mapdate.containsKey(key) && mapproid.get(key).equals(CFCLOCKTIME)) {
  183. continue;
  184. }
  185. if(mapInfo.containsKey(key)) {
  186. listInfo = mapInfo.get(key);
  187. }else {
  188. listInfo = new ArrayList<WorkHoursConfirmInfo>();
  189. keyList.add(key);
  190. mapproid.put(key, proid);
  191. mapdate.put(key, CFCLOCKTIME);
  192. }
  193. wInfo = getWConfirmInfo(ctx,pid, proid,proCFCLOCKLOCATION,FPUNCHCARDPLACE,simpleDateFormat.parse(CFCLOCKTIME),tfid);
  194. listInfo.add(wInfo);
  195. mapInfo.put(key, listInfo);
  196. }
  197. } catch (SQLException | ParseException e) {
  198. e.printStackTrace();
  199. }
  200. //写入打卡数据
  201. WorkHoursConfirmCollection addSubColl = new WorkHoursConfirmCollection();
  202. WorkHoursConfirmCollection addAudColl = new WorkHoursConfirmCollection();
  203. //多个项目且不在同一个项目情况下
  204. List<String> notList = new ArrayList<String>();
  205. System.out.println("notList: "+notList.size());
  206. if(listproid.size() > 0) {
  207. for (int i = 0; i < listproid.size(); i++) {
  208. String key = listproid.get(i);
  209. listInfo = mapInfo.get(key);
  210. String oldprojid = null;
  211. boolean isoneprojid = true;
  212. for (int j = 0; j < listInfo.size(); j++) {
  213. wInfo = listInfo.get(j);
  214. if(j == 0) {
  215. if(wInfo.getProject() != null && wInfo.getProject().getId() != null) {
  216. oldprojid = wInfo.getProject().getId().toString();
  217. }else {
  218. oldprojid = "0";
  219. }
  220. }else {
  221. //不在同一个项目
  222. if((wInfo.getProject() != null && !oldprojid.equals(wInfo.getProject().getId().toString()))
  223. || wInfo.getProject() == null ||wInfo.getProject().getId() == null) {
  224. isoneprojid = false;
  225. break;
  226. }
  227. }
  228. }
  229. //不在同一个项目
  230. if(!isoneprojid) {
  231. for (int j = 0; j < listInfo.size(); j++) {
  232. wInfo = listInfo.get(j);
  233. wInfo.setProject(null); //所属项目
  234. wInfo.setBillState(HRBillStateEnum.SAVED);//暂存
  235. addSubColl.add(wInfo);
  236. }
  237. notList.add(key);
  238. }
  239. }
  240. }
  241. //剩余数据处理
  242. if (keyList.size() > 0){
  243. for (int i = 0; i < keyList.size(); i++) {
  244. String key = keyList.get(i);
  245. if(notList.contains(key)) {
  246. continue;
  247. }
  248. listInfo = mapInfo.get(key);
  249. for (int j = 0; j < listInfo.size(); j++) {
  250. wInfo = listInfo.get(j);
  251. //直接生效
  252. if(wInfo.getBillState().compareTo(HRBillStateEnum.AUDITED) == 0) {
  253. addAudColl.add(wInfo);
  254. }else {
  255. //匹配不上的
  256. addSubColl.add(wInfo);
  257. }
  258. }
  259. }
  260. }
  261. //提交工作流
  262. if(addSubColl.size() > 0) {
  263. CoreBaseCollection addSubCollnew = new CoreBaseCollection();
  264. List<String> addList = new ArrayList<String>();
  265. for (int i = 0; i < addSubColl.size(); i++) {
  266. WorkHoursConfirmInfo getinfo = addSubColl.get(i);
  267. if(!addList.contains(getinfo.getSourceBillId())) {
  268. addList.add(getinfo.getSourceBillId());
  269. addSubCollnew.add(getinfo);
  270. }
  271. }
  272. System.out.println("addSubCollnew: "+addSubCollnew.size());
  273. biz.submit(addSubCollnew);
  274. }
  275. if(addAudColl.size() > 0) {
  276. CoreBaseCollection addAudCollNew = new CoreBaseCollection();
  277. List<String> addList = new ArrayList<String>();
  278. for (int i = 0; i < addAudColl.size(); i++) {
  279. WorkHoursConfirmInfo getinfo = addAudColl.get(i);
  280. if(!addList.contains(getinfo.getSourceBillId())) {
  281. addList.add(getinfo.getSourceBillId());
  282. addAudCollNew.add(getinfo);
  283. }
  284. }
  285. System.out.println("addAudCollNew: "+addAudCollNew.size());
  286. //保存处理-审核通过
  287. Result re = biz.addnew(addAudCollNew);
  288. LineResult lr = null;
  289. if(re != null && re.size() > 0){
  290. for (int i = 0; i < re.size(); i++) {
  291. lr = re.getLineResult(i);
  292. biz.setAudited(BOSUuid.read(lr.getPk().toString())); //-审核通过
  293. }
  294. }
  295. }
  296. }
  297. /**
  298. * 解析为工时确认单
  299. * @param pid
  300. * @param proid
  301. * @param p1
  302. * @param p2
  303. * @param clockTime
  304. * @return
  305. */
  306. private WorkHoursConfirmInfo getWConfirmInfo(Context ctx,String pid,String proid,Map<String,List<String>> map,String p2,Date clockTime,String FSOURCEBILLID) {
  307. WorkHoursConfirmInfo wInfo = new WorkHoursConfirmInfo();
  308. PersonInfo pinfo = new PersonInfo();pinfo.setId(BOSUuid.read(pid)); //人员
  309. PersonCollection personCollection = null;
  310. try {
  311. personCollection = PersonFactory.getLocalInstance(ctx).getPersonCollection(" select * where id = '"+pid+"'");
  312. } catch (BOSException e) {
  313. e.printStackTrace();
  314. }
  315. if(personCollection != null && personCollection.size()>0){
  316. pinfo = personCollection.get(0);
  317. }
  318. ProjectManagementInfo proinfo = new ProjectManagementInfo();proinfo.setId(BOSUuid.read(proid)); //所属项目
  319. wInfo.setEmployee(pinfo);
  320. wInfo.setProject(proinfo); //所属项目
  321. wInfo.setClockDate(clockTime); //打卡日期
  322. wInfo.setSourceBillId(FSOURCEBILLID);//来源id
  323. wInfo.setHrOrgUnit(pinfo.getHrOrgUnit());
  324. wInfo.setCU(pinfo.getCU());
  325. Timestamp t = new Timestamp(clockTime.getTime());
  326. wInfo.setClockTime(t); //打卡--------------------------------------------------------------------------------------------------------------
  327. //打卡位置 clockLocation
  328. if(map != null) {
  329. List<String> plist = map.get(proid);
  330. System.out.println("p2:"+p2);
  331. if(plist != null && plist.contains(p2)) {
  332. wInfo.setClockLocation(p2);
  333. wInfo.setBillState(HRBillStateEnum.AUDITED);//审核通过
  334. }else {
  335. wInfo.setProject(null); //所属项目
  336. wInfo.setBillState(HRBillStateEnum.SAVED);//暂存
  337. }
  338. }else {
  339. wInfo.setProject(null); //所属项目
  340. wInfo.setBillState(HRBillStateEnum.SAVED);//暂存
  341. }
  342. return wInfo;
  343. }
  344. /**
  345. * 工时计算
  346. */
  347. private void _updateWorkHoursReport(Context ctx, String number, String star, String end, int day,String type)
  348. throws BOSException, EASBizException {
  349. List<String> proidList = new ArrayList<String>();
  350. //获取工时确认单生成工时单
  351. String CFCLOCKTIME = null; //年月日-时分秒
  352. String CFCLOCKDATE = null; //年月日
  353. String CFPROJECTID = null; //项目id
  354. String CFEMPLOYEEID = null; //人员id
  355. String CFCLOCKLOCATION = null; //位置
  356. String fid = null; //fid
  357. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  358. SimpleDateFormat sdfs = new SimpleDateFormat("HH:mm:ss");
  359. IWorkHoursReport biz = WorkHoursReportFactory.getLocalInstance(ctx);
  360. CoreBaseCollection coll = new CoreBaseCollection();
  361. WorkHoursReportInfo info = null;
  362. List<String> listDate = new ArrayList<String>(); //一天天的判断
  363. Map<String,List<Map<String,String>>> dateMap = null;
  364. List<Map<String,String>> listMap = null;
  365. Map<String,List<String>> mapListPersonid = new HashMap<String,List<String>>(); //每天有多少人
  366. List<String> personidList = null;
  367. Map<String,String> map = null;
  368. Map<String,Map<String,List<Map<String,String>>>> mapRs = new HashMap<String,Map<String,List<Map<String,String>>>>();
  369. if(day <= 0) {
  370. //默认3天
  371. day = 3;
  372. }
  373. StringBuffer sb = new StringBuffer("/*dialect*/");
  374. sb.append(" select fid fid,CFPROJECTID CFPROJECTID,CFEMPLOYEEID CFEMPLOYEEID"
  375. + " ,TO_CHAR(CFCLOCKDATE, 'YYYY-MM-DD') CFCLOCKDATE"
  376. + " ,TO_CHAR(CFCLOCKTIME, 'YYYY-MM-DD HH24:MI:SS') CFCLOCKTIME "
  377. + " FROM CT_PRO_WorkHoursConfirm where FBILLSTATE ='3' "
  378. + " and CFPROJECTID is not null ").append(" \n");
  379. //按照时间过滤
  380. if(star != null && star.length() > 0) {
  381. sb.append(" and CFCLOCKDATE >= TO_DATE('"+star+"', 'YYYY-MM-DD HH24:MI:SS')").append(" \n");
  382. }else if(end != null && end.length() > 0) {
  383. sb.append(" and CFCLOCKDATE <= TO_DATE('"+end+"', 'YYYY-MM-DD HH24:MI:SS')").append(" \n");
  384. }else {
  385. sb.append(" and CFCLOCKDATE >= sysdate -"+day).append(" \n");
  386. }
  387. if(number !=null && number.length() > 0) {
  388. sb.append(" and CFEMPLOYEEID in (select fid from (").append(number).append(")) \n");
  389. }
  390. sb.append(" order by CFEMPLOYEEID,CFCLOCKTIME asc").append(" \n");//排序
  391. //获取打卡数据-审核通过的数据
  392. IRowSet rs = DbUtil.executeQuery(ctx, sb.toString());
  393. System.out.println("sb:"+sb);
  394. try {
  395. while (rs.next()) {
  396. CFCLOCKTIME = rs.getString("CFCLOCKTIME"); //年月日-时分秒
  397. CFCLOCKDATE = rs.getString("CFCLOCKDATE"); //年月日
  398. CFPROJECTID = rs.getString("CFPROJECTID"); //项目id
  399. CFEMPLOYEEID = rs.getString("CFEMPLOYEEID"); //人员id
  400. CFCLOCKLOCATION = "";//rs.getString("CFCLOCKLOCATION"); //位置
  401. fid = rs.getString("fid"); //fid
  402. map = new HashMap<String,String>();
  403. map.put("CFCLOCKTIME", CFCLOCKTIME);
  404. map.put("CFCLOCKDATE", CFCLOCKDATE);
  405. map.put("CFPROJECTID", CFPROJECTID);
  406. map.put("CFEMPLOYEEID", CFEMPLOYEEID);
  407. map.put("fid", fid);
  408. if(!listDate.contains(CFCLOCKDATE)){
  409. listDate.add(CFCLOCKDATE);
  410. dateMap = new HashMap<String,List<Map<String,String>>>();
  411. personidList = new ArrayList<String>();
  412. }else {
  413. dateMap = mapRs.get(CFCLOCKDATE);
  414. personidList = mapListPersonid.get(CFCLOCKDATE);
  415. }
  416. //重复人员
  417. if(!personidList.contains(CFEMPLOYEEID)) {
  418. personidList.add(CFEMPLOYEEID);
  419. listMap = new ArrayList<Map<String,String>>();
  420. }else {
  421. listMap = dateMap.get(CFEMPLOYEEID);
  422. }
  423. listMap.add(map);
  424. dateMap.put(CFEMPLOYEEID,listMap);
  425. mapListPersonid.put(CFCLOCKDATE, personidList);
  426. mapRs.put(CFCLOCKDATE, dateMap);
  427. }
  428. } catch (SQLException e) {
  429. e.printStackTrace();
  430. }
  431. List<String> delist = new ArrayList<String>();
  432. //一天一天的处理
  433. for (int i = 0; i < listDate.size(); i++) {
  434. CFCLOCKDATE = listDate.get(i);
  435. dateMap = mapRs.get(CFCLOCKDATE);
  436. personidList = mapListPersonid.get(CFCLOCKDATE);
  437. for (int j = 0; j < personidList.size(); j++) {
  438. CFEMPLOYEEID = personidList.get(j);//人员id
  439. listMap = dateMap.get(CFEMPLOYEEID); //这个人有多少打卡数据
  440. String oldCFPROJECTID = null; //旧的项目
  441. String oldCFCLOCKTIME = null; //旧的打卡时间
  442. String oldfid = null; //旧的fid
  443. String deleteWhere = " CFEMPLOYEEID='"+CFEMPLOYEEID+"' and to_char(CFDATA,'YYYY-MM-DD') = '"+CFCLOCKDATE+"'";
  444. for (int j2 = 0; j2 < listMap.size(); j2++) {
  445. map = listMap.get(j2);
  446. CFCLOCKTIME = map.get("CFCLOCKTIME"); //年月日-时分秒
  447. CFPROJECTID = map.get("CFPROJECTID"); //项目id
  448. CFEMPLOYEEID = map.get("CFEMPLOYEEID"); //人员id
  449. CFCLOCKLOCATION = map.get("CFEMPLOYEEID"); //位置
  450. fid = map.get("fid"); //fid
  451. //第一次记录最早的
  452. if(j2 == 0){
  453. oldCFPROJECTID = CFPROJECTID;
  454. oldCFCLOCKTIME = CFCLOCKTIME;
  455. oldfid = fid;
  456. }
  457. //跟上一次的不一致情况下
  458. if(!oldCFPROJECTID.equals(CFPROJECTID)) {
  459. map = listMap.get(j2-1);
  460. CFCLOCKTIME = map.get("CFCLOCKTIME"); //年月日-时分秒
  461. CFPROJECTID = map.get("CFPROJECTID"); //项目id
  462. CFEMPLOYEEID = map.get("CFEMPLOYEEID"); //人员id
  463. CFCLOCKLOCATION = map.get("CFEMPLOYEEID"); //位置
  464. fid = map.get("fid"); //fid
  465. //取上一次的数据与第一次数据进行比较计算
  466. //计算两者时间差几个小时
  467. try {
  468. Date oldDate = sdf.parse(oldCFCLOCKTIME);
  469. Date date = sdf.parse(CFCLOCKTIME);
  470. long diffInMillies = date.getTime() - oldDate.getTime();
  471. // 将毫秒数转换为小时
  472. long diffInHours = diffInMillies / (60 * 60 * 1000);
  473. BigDecimal hours = new BigDecimal(diffInHours);
  474. //组装数据
  475. info = initInfo(ctx,CFEMPLOYEEID, oldCFPROJECTID, date, sdf.format(sdf.parse(CFCLOCKTIME)), null, hours,oldfid+","+fid);
  476. if(!delist.contains(deleteWhere)) {
  477. delist.add(deleteWhere);
  478. }
  479. coll.add(info);
  480. } catch (ParseException ee) {
  481. ee.printStackTrace();
  482. }
  483. //当前重新开始
  484. map = listMap.get(j2);
  485. CFCLOCKTIME = map.get("CFCLOCKTIME"); //年月日-时分秒
  486. CFPROJECTID = map.get("CFPROJECTID"); //项目id
  487. CFEMPLOYEEID = map.get("CFEMPLOYEEID"); //人员id
  488. CFCLOCKLOCATION = map.get("CFEMPLOYEEID"); //位置
  489. fid = map.get("fid"); //fid
  490. oldCFPROJECTID = CFPROJECTID;
  491. oldCFCLOCKTIME = CFCLOCKTIME;
  492. oldfid = fid;
  493. }
  494. //最后一次记录
  495. if(j2 == listMap.size()-1){
  496. if(oldCFPROJECTID.equals(CFPROJECTID) && !oldCFCLOCKTIME.equals(CFCLOCKTIME)) { //项目相同时间相同情况下
  497. try {
  498. Date oldDate = sdf.parse(oldCFCLOCKTIME);
  499. Date date = sdf.parse(CFCLOCKTIME);
  500. long diffInMillies = date.getTime() - oldDate.getTime();
  501. // 将毫秒数转换为小时
  502. long diffInHours = diffInMillies / (60 * 60 * 1000);
  503. BigDecimal hours = new BigDecimal(diffInHours);
  504. //组装数据
  505. info = initInfo(ctx,CFEMPLOYEEID, oldCFPROJECTID, date, sdf.format(sdf.parse(CFCLOCKTIME)), null, hours,oldfid+","+fid);
  506. if(!delist.contains(deleteWhere)) {
  507. delist.add(deleteWhere);
  508. }
  509. coll.add(info);
  510. } catch (ParseException ee) {
  511. ee.printStackTrace();
  512. }
  513. }
  514. }
  515. }
  516. }
  517. }
  518. //删除情况下
  519. if(type.equals("update") && delist.size() > 0) {
  520. //删除当天
  521. for (int i = 0; i < delist.size(); i++) {
  522. DbUtil.execute(ctx, " delete from CT_PRO_WorkHoursReport where CFDATASOURCE = 'workHoursCal' and FBILLSTATE = '3' "
  523. + "and CFFILLINGSTARTDATE = CFFILLINGENDDATE and fid in(select FParentID from CT_PRO_WorkHoursReportentry where "+delist.get(i)+") ");
  524. DbUtil.execute(ctx, " delete from CT_PRO_WorkHoursReportentry where "+delist.get(i)+" ");
  525. }
  526. }
  527. //保存处理-审核通过
  528. System.out.println("coll:"+coll.toString());
  529. if(coll.size() > 0) {
  530. for (int i = 0; i < coll.size(); i++) {
  531. info = (WorkHoursReportInfo) coll.get(i);
  532. proidList.add(info.getAffiliatedProject().getId().toString());//项目id
  533. IObjectPK pk = biz.addnew(info);
  534. biz.setAudited(BOSUuid.read(pk.toString())); //-审核通过
  535. }
  536. }
  537. //计算比例
  538. if(proidList.size() > 0) {
  539. for (int i = 0; i < proidList.size(); i++) {
  540. String proid = proidList.get(i);
  541. String sql = " SELECT tt.CFPLANNEDMANDAYS CFPLANNEDMANDAYS,sum(CASE when tt.CFWORKINGHOURS >= 8 THEN 8 ELSE tt.CFWORKINGHOURS END) CFWORKINGHOURS"
  542. + " FROM (" +
  543. " SELECT t2.CFPLANNEDMANDAYS CFPLANNEDMANDAYS ,to_char(t1.CFDATA,'YYYY-MM-DD') CFDATA,sum(t1.CFWORKINGHOURS) CFWORKINGHOURS FROM CT_PRO_WorkHoursReport t" +
  544. " inner join CT_PRO_WorkHoursReportentry t1 on t1.FPARENTID = t.fid" +
  545. " inner join CT_PRO_ProjectManagement t2 on t2.fid = t.CFAFFILIATEDPROJEC" +
  546. " where t.FBILLSTATE = '3' and t2.fid = '"+proid+"'" +
  547. " group by t2.CFPLANNEDMANDAYS,to_char(t1.CFDATA,'YYYY-MM-DD')" +
  548. " )tt group by tt.CFPLANNEDMANDAYS " +
  549. "";
  550. rs = DbUtil.executeQuery(ctx,sql );
  551. try {
  552. System.out.println("sql:"+sql);
  553. if (rs.next()) {
  554. BigDecimal FPRODAYCONSUMPTION = BigDecimal.ZERO;
  555. BigDecimal CFPLANNEDMANDAYS = rs.getBigDecimal("CFPLANNEDMANDAYS"); //项目总人天
  556. BigDecimal CFWORKINGHOURS = rs.getBigDecimal("CFWORKINGHOURS"); //申报人天 已审核通过
  557. if(CFPLANNEDMANDAYS.compareTo(FPRODAYCONSUMPTION) == 1
  558. && CFWORKINGHOURS.compareTo(FPRODAYCONSUMPTION) == 1) {
  559. //项目总人天除以 申报人天
  560. //申报人天= 总数/8
  561. CFWORKINGHOURS = CFWORKINGHOURS.divide(new BigDecimal(8),2,BigDecimal.ROUND_HALF_UP); //8小时 四舍五入 保留2位小数
  562. FPRODAYCONSUMPTION = CFWORKINGHOURS.divide(CFPLANNEDMANDAYS,4,BigDecimal.ROUND_HALF_UP);
  563. FPRODAYCONSUMPTION = FPRODAYCONSUMPTION.multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP);
  564. }
  565. DbUtil.execute(ctx, "update CT_PRO_ProjectManagement set FPRODAYCONSUMPTION ="+FPRODAYCONSUMPTION+" where fid = '"+proid+"'");
  566. }
  567. } catch (SQLException e) {
  568. e.printStackTrace();
  569. }
  570. }
  571. }
  572. }
  573. /**
  574. * 组装工时单据
  575. * @param pid
  576. * @param proid
  577. * @param data
  578. * @param ClockTime
  579. * @param ClockLocation
  580. * @param hours
  581. * @return
  582. */
  583. private WorkHoursReportInfo initInfo(Context ctx,String pid,String proid,Date data,String ClockTime
  584. ,String ClockLocation,BigDecimal hours,String ids) {
  585. WorkHoursReportInfo info = new WorkHoursReportInfo();
  586. WorkHoursReportEntryInfo einfo = new WorkHoursReportEntryInfo();
  587. PersonInfo pinfo = new PersonInfo();pinfo.setId(BOSUuid.read(pid)); //人员
  588. PersonCollection personCollection = null;
  589. try {
  590. personCollection = PersonFactory.getLocalInstance(ctx).getPersonCollection(" select * where id = '"+pid+"'");
  591. } catch (BOSException e) {
  592. e.printStackTrace();
  593. }
  594. if(personCollection != null && personCollection.size()>0){
  595. pinfo = personCollection.get(0);
  596. }
  597. ProjectManagementInfo proinfo = new ProjectManagementInfo();
  598. proinfo.setId(BOSUuid.read(proid)); //所属项目
  599. info.setHrOrgUnit(pinfo.getHrOrgUnit());
  600. info.setCU(pinfo.getCU());
  601. info.setDataSource(dataSource.workHoursCal);
  602. info.setAffiliatedProject(proinfo);
  603. info.setBillState(HRBillStateEnum.AUDITED); //审核通过
  604. info.setFillingStartDate(data); //默认当天
  605. info.setFillingEndDate(data); //默认当天
  606. info.setSourceBillId(ids);
  607. einfo.setEmployee(pinfo);
  608. // einfo.setClockLocation("工时计算");
  609. einfo.setClockTime(ClockTime); //打卡时间
  610. einfo.setData(data); //日期
  611. einfo.setWorkingHours(hours); //工时
  612. info.getEntrys().add(einfo);
  613. return info;
  614. }
  615. }