/* * Aipo is a groupware program developed by TOWN, Inc. * Copyright (C) 2004-2015 TOWN, Inc. * http://www.aipo.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.aimluck.eip.exttimecard; import java.lang.reflect.Field; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.cayenne.exp.Expression; import org.apache.cayenne.exp.ExpressionFactory; import org.apache.jetspeed.services.logging.JetspeedLogFactoryService; import org.apache.jetspeed.services.logging.JetspeedLogger; import org.apache.turbine.services.TurbineServices; import org.apache.turbine.util.RunData; import org.apache.velocity.context.Context; import com.aimluck.commons.field.ALDateField; import com.aimluck.commons.field.ALDateTimeField; import com.aimluck.commons.field.ALNumberField; import com.aimluck.commons.field.ALStringField; import com.aimluck.eip.cayenne.om.portlet.EipTExtTimecard; import com.aimluck.eip.cayenne.om.portlet.EipTExtTimecardSystem; import com.aimluck.eip.common.ALAbstractFormData; import com.aimluck.eip.common.ALDBErrorException; import com.aimluck.eip.common.ALEipConstants; import com.aimluck.eip.common.ALPageNotFoundException; import com.aimluck.eip.common.ALPermissionException; import com.aimluck.eip.exttimecard.util.ExtTimecardUtils; import com.aimluck.eip.modules.actions.common.ALAction; import com.aimluck.eip.orm.Database; import com.aimluck.eip.orm.query.SelectQuery; import com.aimluck.eip.services.accessctl.ALAccessControlConstants; import com.aimluck.eip.services.accessctl.ALAccessControlFactoryService; import com.aimluck.eip.services.accessctl.ALAccessControlHandler; import com.aimluck.eip.services.eventlog.ALEventlogConstants; import com.aimluck.eip.services.eventlog.ALEventlogFactoryService; import com.aimluck.eip.util.ALEipUtils; import com.aimluck.eip.util.ALLocalizationUtils; /** * タイムカードのフォームデータを管理するクラスです。 <BR> * */ public class ExtTimecardFormData extends ALAbstractFormData { /** logger */ private static final JetspeedLogger logger = JetspeedLogFactoryService .getLogger(ExtTimecardFormData.class.getName()); private ALNumberField timecard_id; private ALNumberField user_id; private ALDateTimeField punch_date; private ALStringField type; private ALDateTimeField clock_in_time; private ALDateTimeField clock_out_time; private ALStringField reason; private ALDateTimeField outgoing_time1; private ALDateTimeField outgoing_time2; private ALDateTimeField outgoing_time3; private ALDateTimeField outgoing_time4; private ALDateTimeField outgoing_time5; private ALDateTimeField comeback_time1; private ALDateTimeField comeback_time2; private ALDateTimeField comeback_time3; private ALDateTimeField comeback_time4; private ALDateTimeField comeback_time5; private ALDateTimeField outgoing_comeback; private ALStringField remarks; private ALDateField create_date; private ALDateField update_date; private int entity_id; private int login_uid; private String selectedUserId; private String edit_mode; private String alt_mode; private String old_clock_in_time_hour; private String old_clock_in_time_minute; private String old_clock_out_time_hour; private String old_clock_out_time_minute; private ALStringField rest_num; /** タイムカードの設定 */ private EipTExtTimecardSystem timecard_system; private int current_clock_out_time_hour; private int current_clock_out_time_minute; /** 他人アクセス権限の機能名 */ private final String aclPortletFeatureOther = ALAccessControlConstants.POERTLET_FEATURE_TIMECARD_TIMECARD_OTHER; private ALAccessControlHandler aclHandler; /** アクセス権限の機能名 */ private String aclPortletFeature = null; /** * * @param action * @param rundata * @param context * * */ @Override public void init(ALAction action, RunData rundata, Context context) throws ALPageNotFoundException, ALDBErrorException { super.init(action, rundata, context); login_uid = ALEipUtils.getUserId(rundata); selectedUserId = rundata.getParameters().getString("userid", ""); // 出勤・退勤時間 old_clock_in_time_hour = rundata.getParameters().get("old_clock_in_time_hour"); old_clock_in_time_minute = rundata.getParameters().get("old_clock_in_time_minute"); old_clock_out_time_hour = rundata.getParameters().get("old_clock_out_time_hour"); old_clock_out_time_minute = rundata.getParameters().get("old_clock_out_time_minute"); timecard_system = ExtTimecardUtils.getEipTExtTimecardSystemCurrentUserId(rundata, context); ALAccessControlFactoryService aclservice = (ALAccessControlFactoryService) ((TurbineServices) TurbineServices .getInstance()).getService(ALAccessControlFactoryService.SERVICE_NAME); aclHandler = aclservice.getAccessControlHandler(); } /** * 各フィールドを初期化します。 <BR> * * */ @Override public void initField() { timecard_id = new ALNumberField(); user_id = new ALNumberField(); type = new ALStringField(); type.setFieldName(ALLocalizationUtils .getl10n("EXTTIMECARD_SETFIELDNAME_KINDS")); type.setValue(""); punch_date = new ALDateTimeField(); punch_date.setFieldName(ALLocalizationUtils .getl10n("EXTTIMECARD_SETFIELDNAME_DATE")); clock_in_time = new ALDateTimeField(); clock_in_time.setFieldName(ALLocalizationUtils .getl10n("EXTTIMECARD_SETFIELDNAME_WORKTIME")); clock_out_time = new ALDateTimeField(); outgoing_comeback = new ALDateTimeField(); outgoing_comeback.setFieldName(ALLocalizationUtils .getl10n("EXTTIMECARD_SETFIELDNAME_OUTGOINGTIME")); reason = new ALStringField(); reason.setFieldName(ALLocalizationUtils .getl10n("EXTTIMECARD_SETFIELDNAME_REASON")); reason.setValue(""); remarks = new ALStringField(); remarks.setFieldName(ALLocalizationUtils .getl10n("EXTTIMECARD_SETFIELDNAME_REMARKS")); remarks.setValue(""); create_date = new ALDateField(); create_date.setValue(new Date()); update_date = new ALDateField(); update_date.setValue(new Date()); edit_mode = ""; alt_mode = ""; rest_num = new ALStringField(); rest_num.setValue("0"); try { Field field; for (int i = 1; i <= EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY; i++) { field = this.getClass().getDeclaredField("outgoing_time" + i); field.set(this, new ALDateTimeField()); field = this.getClass().getDeclaredField("comeback_time" + i); field.set(this, new ALDateTimeField()); } } catch (RuntimeException e) { // RuntimeException logger.error("[ExtTimecardFormData]", e); return; } catch (Exception e) { logger.error("[ExtTimecardFormData]", e); return; } } /** * フォームを表示します。 * * @param action * @param rundata * @param context * @return TRUE 成功 FALSE 失敗 */ @Override public boolean doViewForm(ALAction action, RunData rundata, Context context) { try { init(action, rundata, context); boolean isedit = (ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID) != null); action.setMode(isedit ? ALEipConstants.MODE_EDIT_FORM : ALEipConstants.MODE_NEW_FORM); setMode(action.getMode()); List<String> msgList = new ArrayList<String>(); boolean res = (isedit) ? loadFormData(rundata, context, msgList) : setFormData( rundata, context, msgList); int aclType = ALAccessControlConstants.VALUE_ACL_INSERT; if (isedit) { aclType = ALAccessControlConstants.VALUE_ACL_UPDATE; } String userId = selectedUserId; EipTExtTimecard timecard = ExtTimecardUtils.getEipTExtTimecard(rundata, context); if (!(timecard == null)) { userId = String.valueOf(timecard.getUserId()); } if (String.valueOf(login_uid).equals(userId) || "".equals(userId)) { aclPortletFeature = ALAccessControlConstants.POERTLET_FEATURE_TIMECARD_TIMECARD_SELF; } else { aclPortletFeature = ALAccessControlConstants.POERTLET_FEATURE_TIMECARD_TIMECARD_OTHER; } doCheckAclPermission(rundata, context, aclType); action.setResultData(this); if (!msgList.isEmpty()) { action.addErrorMessages(msgList); } action.putData(rundata, context); return res; } catch (ALPermissionException e) { ALEipUtils.redirectPermissionError(rundata); return false; } catch (ALPageNotFoundException e) { ALEipUtils.redirectPageNotFound(rundata); return false; } catch (ALDBErrorException e) { ALEipUtils.redirectDBError(rundata); return false; } } /** * タイムカードの各フィールドに対する制約条件を設定します。 <BR> * * */ @Override protected void setValidator() { // reason.setNotNull(true); // reason.limitMaxLength(1000); // work_date.setNotNull(true); } /** * タイムカードのフォームに入力されたデータの妥当性検証を行います。 <BR> * * @param msgList * @return TRUE 成功 FALSE 失敗 * */ @Override protected boolean validate(List<String> msgList) { try { if (type.getValue().equals("")) { msgList.add(ALLocalizationUtils .getl10n("EXTTIMECARD_ALERT_SELECT_KIND")); } if (!"punchin".equals(edit_mode) && !"punchout".equals(edit_mode) && !"outgoing".equals(edit_mode) && !"comeback".equals(edit_mode)) { // time has changed or not at work if (isModify() || isNotAtWork()) { // Plans for the future is not checked if (isNotFuture()) { reason.setNotNull(true); reason.validate(msgList); } } } if (getMode().equals(ALEipConstants.MODE_INSERT)) { SelectQuery<EipTExtTimecard> workflg_query = Database.query(EipTExtTimecard.class); Expression workflg_exp = ExpressionFactory.matchExp(EipTExtTimecard.USER_ID_PROPERTY, Integer .valueOf(login_uid)); workflg_query.setQualifier(workflg_exp); workflg_query.orderDesending(EipTExtTimecard.PUNCH_DATE_PROPERTY); List<EipTExtTimecard> workflg_list = workflg_query.fetchList(); if (workflg_list != null && workflg_list.size() > 0) { } else { } } /** 更新・挿入時 */ if (edit_mode.equals("") && "P".equals(type.getValue())) { /** 日付を punch_date に合わせる */ if (ajustDate(clock_in_time, punch_date) && ajustDate(clock_out_time, punch_date)) { if (clock_in_time.getValue().getTime() > clock_out_time .getValue() .getTime()) { msgList.add(ALLocalizationUtils .getl10n("EXTTIMECARD_ALERT_SELECT_PUNCH_OUT_TIME")); } } /** 勤怠時間は必須項目 */ boolean out_flag = false; if (!(old_clock_out_time_hour.isEmpty()) || !(old_clock_out_time_minute.isEmpty())) { out_flag = true; } else { out_flag = false; } if (getIsPast() && "P".equals(type.getValue())) { if (!clock_in_time.isNotNullValue() || (!clock_out_time.isNotNullValue() && out_flag) || current_clock_out_time_hour == -1 && current_clock_out_time_minute != -1 || current_clock_out_time_hour != -1 && current_clock_out_time_minute == -1) { msgList.add(ALLocalizationUtils.getl10nFormat( "EXTTIMECARD_ALERT_TYPE_CLOCKINTIME", clock_in_time.getFieldName())); } /** 外出復帰時間が適切に入力されているかチェック */ Field field_out, field_come; for (int i = 1; i <= Integer.parseInt(rest_num.getValue()); i++) { field_out = this.getClass().getDeclaredField("outgoing_time" + i); field_come = this.getClass().getDeclaredField("comeback_time" + i); ALDateTimeField outgoing = (ALDateTimeField) field_out.get(this); ALDateTimeField comeback = (ALDateTimeField) field_come.get(this); if (!outgoing.isNotNullValue() || !comeback.isNotNullValue()) { msgList.add(ALLocalizationUtils.getl10nFormat( "EXTTIMECARD_ALERT_TYPE_OUTGOING_COMEBACK", outgoing_comeback.getFieldName(), i)); } } /** 外出/復帰時間をリストに代入 */ List<Map<String, Long>> list_from_to = new ArrayList<Map<String, Long>>(); for (int i = 1; i <= EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY; i++) { field_out = this.getClass().getDeclaredField("outgoing_time" + i); field_come = this.getClass().getDeclaredField("comeback_time" + i); ALDateTimeField outgoing = (ALDateTimeField) field_out.get(this); ALDateTimeField comeback = (ALDateTimeField) field_come.get(this); if (ajustDate(outgoing, punch_date) && ajustDate(comeback, punch_date)) { long from = outgoing.getValue().getTime(); long to = comeback.getValue().getTime(); if (from <= to) { if (clock_in_time.isNotNullValue() && from < clock_in_time.getValue().getTime()) { msgList.add(ALLocalizationUtils.getl10nFormat( "EXTTIMECARD_ALERT_SELECT_OUTGOING_AFTER_PUNCH_IN", i)); } if (clock_out_time.isNotNullValue() && to > clock_out_time.getValue().getTime()) { msgList.add(ALLocalizationUtils.getl10nFormat( "EXTTIMECARD_ALERT_SELECT_COMEBACK_AFTER_PUNCH_OUT", i)); } HashMap<String, Long> from_to = new HashMap<String, Long>(); from_to.put("from", outgoing.getValue().getTime()); from_to.put("to", comeback.getValue().getTime()); list_from_to.add(from_to); } else { msgList.add(ALLocalizationUtils.getl10nFormat( "EXTTIMECARD_ALERT_SELECT_COMEBACK_AFTER_OUTGOING", i)); } } else if (ajustDate(outgoing, punch_date) && !ajustDate(comeback, punch_date) && i == 1) { HashMap<String, Long> from_to = new HashMap<String, Long>(); from_to.put("from", outgoing.getValue().getTime()); // from_to.put("to", comeback.getValue().getTime()); list_from_to.add(from_to); return (msgList.size() == 0); } } /** 外出時間の重複をチェックする */ int i = 1; if (list_from_to.size() > 0) { List<Map<String, Long>> empty_from_to = new ArrayList<Map<String, Long>>(); long min_from = list_from_to.get(0).get("from"); long max_to = list_from_to.get(0).get("to"); list_from_to.remove(0); for (Map<String, Long> map : list_from_to) { long new_from = map.get("from"); long new_to = map.get("to"); if (new_to <= min_from) { Map<String, Long> empty = new HashMap<String, Long>(); empty.put("from", new_to); empty.put("to", min_from); empty_from_to.add(empty); min_from = new_from; } else if (new_from >= max_to) { Map<String, Long> empty = new HashMap<String, Long>(); empty.put("from", max_to); empty.put("to", new_from); empty_from_to.add(empty); max_to = new_to; } else { /** empty_from_toのリストから入れる場所を探す */ boolean duplicate_flag = true; for (Map<String, Long> empty_map : empty_from_to) { if (empty_map.get("from") <= new_from && empty_map.get("to") >= new_to) { /** 区間を分割し、もとあった空白を削除 */ HashMap<String, Long> empty_left = new HashMap<String, Long>(); empty_left.put("from", empty_map.get("from")); empty_left.put("to", new_from); empty_from_to.add(empty_left); HashMap<String, Long> empty_right = new HashMap<String, Long>(); empty_right.put("from", new_to); empty_right.put("to", empty_map.get("to")); empty_from_to.add(empty_right); empty_from_to.remove(empty_map); duplicate_flag = false; break; } } if (duplicate_flag) { msgList.add(ALLocalizationUtils .getl10n("EXTTIMECARD_ALERT_OUTGOINGTIME")); return false; } } } /** 並べ替える */ Collections.sort( empty_from_to, new Comparator<Map<String, Long>>() { @Override public int compare(Map<String, Long> o1, Map<String, Long> o2) { Map<String, Long> hash1 = o1; Map<String, Long> hash2 = o2; long from1 = hash1.get("from"); long from2 = hash2.get("from"); if (from1 == from2) { long to1 = hash1.get("to"); long to2 = hash2.get("to"); return (int) (to1 - to2); } else { return (int) (from1 - from2); } } @Override public int hashCode() { return super.hashCode(); } @Override public boolean equals(Object obj) { return super.equals(obj); } }); long from = min_from; long to; for (Map<String, Long> empty : empty_from_to) { to = empty.get("from"); field_out = this.getClass().getDeclaredField("outgoing_time" + i); field_come = this.getClass().getDeclaredField("comeback_time" + i); ALDateTimeField outgoing = (ALDateTimeField) field_out.get(this); ALDateTimeField comeback = (ALDateTimeField) field_come.get(this); outgoing.setValue(new Date(from)); comeback.setValue(new Date(to)); i++; from = empty.get("to"); } to = max_to; field_out = this.getClass().getDeclaredField("outgoing_time" + i); field_come = this.getClass().getDeclaredField("comeback_time" + i); ALDateTimeField outgoing = (ALDateTimeField) field_out.get(this); ALDateTimeField comeback = (ALDateTimeField) field_come.get(this); outgoing.setValue(new Date(from)); comeback.setValue(new Date(to)); i++; } /** 余った場所には空のALDateTimeFieldを追加する */ for (; i <= EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY; i++) { field_out = this.getClass().getDeclaredField("outgoing_time" + i); field_come = this.getClass().getDeclaredField("comeback_time" + i); field_out.set(this, new ALDateTimeField()); field_come.set(this, new ALDateTimeField()); } } } remarks.validate(msgList); } catch (RuntimeException ex) { // RuntimeException logger.error("exttimecard", ex); return false; } catch (Exception ex) { logger.error("exttimecard", ex); return false; } return (msgList.size() == 0); } @SuppressWarnings("unused") private EipTExtTimecard getNearlyAboveRecord(List<EipTExtTimecard> list, int timecard_id) { EipTExtTimecard result = null; EipTExtTimecard record = null; int size = list.size(); for (int i = 0; i < size; i++) { record = list.get(i); if (record.getExtTimecardId().intValue() >= timecard_id) { return result; } else { result = record; } } return null; } @SuppressWarnings("unused") private EipTExtTimecard getNearlyBelowRecord(List<EipTExtTimecard> list, int timecard_id) { EipTExtTimecard record = null; int size = list.size(); for (int i = 0; i < size; i++) { record = list.get(i); if (record.getExtTimecardId().intValue() > timecard_id) { return record; } } return null; } @Override protected boolean setFormData(RunData rundata, Context context, List<String> msgList) throws ALPageNotFoundException, ALDBErrorException { setClockOutTime(rundata); boolean res = super.setFormData(rundata, context, msgList); if (res) { if (ALEipConstants.MODE_UPDATE.equals(this.getMode())) { try { if (!(this.entity_id > 0)) { String entity_idstr = ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID); if (entity_idstr == null || entity_idstr.equals("") || Integer.valueOf(entity_idstr) == null) { // アカウントIDが空の場合 logger.debug("[ExtTimecard] Empty entityID..."); return false; } entity_id = Integer.parseInt(entity_idstr); } if ("".equals(this.type.getValue())) { String type = rundata.getParameters().get("type"); this.type.setValue(type); } String punch_date_year = rundata.getParameters().get("punch_date_year"); String punch_date_month = rundata.getParameters().get("punch_date_month"); String punch_date_day = rundata.getParameters().get("punch_date_day"); StringBuffer buffer = new StringBuffer(8); buffer .append(punch_date_year) .append('/') .append(punch_date_month) .append('/') .append(punch_date_day); this.punch_date.setValue(buffer.toString()); } catch (Exception e) { logger.error("exttimecard", e); return false; } } else if (ALEipConstants.MODE_NEW_FORM.equals(this.getMode())) { String session_date = rundata.getParameters().get("date"); if (session_date != null && !"".equals(session_date)) { this.punch_date.setValue(session_date); this.type.setValue("P"); } } else if ("alt_insert".equals(this.alt_mode)) { StringBuffer buffer = new StringBuffer(8); String type = rundata.getParameters().get("type"); String punch_date_year = rundata.getParameters().get("punch_date_year"); String punch_date_month = rundata.getParameters().get("punch_date_month"); String punch_date_day = rundata.getParameters().get("punch_date_day"); buffer .append(punch_date_year) .append('/') .append(punch_date_month) .append('/') .append(punch_date_day); String reason = rundata.getParameters().get("reason"); String remarks = rundata.getParameters().get("remarks"); this.type.setValue(type); this.punch_date.setValue(buffer.toString()); this.reason.setValue(reason); this.remarks.setValue(remarks); } else { ALDateTimeField current_date = new ALDateTimeField(); current_date.setValue(new Date()); // 種類=出勤を入れる this.type.setValue(EipTExtTimecard.TYPE_WORK); this.punch_date.setValue(current_date.toString()); } // 日時をセッションに保存 ALEipUtils.setTemp(rundata, context, "punch_date", punch_date.toString()); } return res; } /** * タイムカードをデータベースから読み出します。 <BR> * * @param rundata * @param context * @param msgList * @return TRUE 成功 FALSE 失敗 */ @Override protected boolean loadFormData(RunData rundata, Context context, List<String> msgList) { try { // オブジェクトモデルを取得 EipTExtTimecard timecard = ExtTimecardUtils.getEipTExtTimecard(rundata, context); if (timecard == null) { return false; } // timecard_id.setValue(timecard.getExtTimecardId().longValue()); user_id.setValue(timecard.getUserId().intValue()); punch_date.setValue(timecard.getPunchDate()); type.setValue(timecard.getType()); clock_in_time.setValue(timecard.getClockInTime()); clock_out_time.setValue(timecard.getClockOutTime()); // 外出・復帰時間 outgoing_time1.setValue(timecard.getOutgoingTime1()); outgoing_time2.setValue(timecard.getOutgoingTime2()); outgoing_time3.setValue(timecard.getOutgoingTime3()); outgoing_time4.setValue(timecard.getOutgoingTime4()); outgoing_time5.setValue(timecard.getOutgoingTime5()); comeback_time1.setValue(timecard.getComebackTime1()); comeback_time2.setValue(timecard.getComebackTime2()); comeback_time3.setValue(timecard.getComebackTime3()); comeback_time4.setValue(timecard.getComebackTime4()); comeback_time5.setValue(timecard.getComebackTime5()); reason.setValue(timecard.getReason()); remarks.setValue(timecard.getRemarks()); create_date.setValue(timecard.getCreateDate()); update_date.setValue(timecard.getUpdateDate()); int rest_num_tmp = 0; for (int i = 1; i <= 5; i++) { if (this.getOutgoingTime(i).isNotNullValue()) { rest_num_tmp++; } else if (this.getComebackTime(i).isNotNullValue()) { rest_num_tmp++; } } rest_num.setValue(Integer.toString(rest_num_tmp)); // 日時をセッションに保存 ALEipUtils.setTemp(rundata, context, "punch_date", punch_date .getValue() .toString()); } catch (Exception ex) { logger.error("exttimecard", ex); return false; } return true; } /** * タイムカードをデータベースから削除します。 <BR> * * @param rundata * @param context * @param msgList * @return TRUE 成功 FALSE 失敗 */ @Override protected boolean deleteFormData(RunData rundata, Context context, List<String> msgList) { try { } catch (Exception ex) { logger.error("exttimecard", ex); return false; } return true; } /** * タイムカードをデータベースに格納します。 <BR> * * @param rundata * @param context * @param msgList * @return TRUE 成功 FALSE 失敗 */ @Override protected boolean insertFormData(RunData rundata, Context context, List<String> msgList) { boolean hasOthersInsertAcl = aclHandler.hasAuthority( ALEipUtils.getUserId(rundata), aclPortletFeatureOther, ALAccessControlConstants.VALUE_ACL_INSERT); try { // 新規オブジェクトモデル EipTExtTimecard timecard = Database.create(EipTExtTimecard.class); if (!"".equals(selectedUserId)) { // others data if (hasOthersInsertAcl) { timecard.setUserId(Integer.parseInt(selectedUserId)); } else { msgList.add(ALLocalizationUtils.getl10n("COMMON_PERMISSION_DENIED")); return false; } } else { // self data timecard.setUserId(Integer.valueOf(ALEipUtils.getUserId(rundata))); } Calendar cal = Calendar.getInstance(); if (timecard_system.getChangeHour() > cal.get(Calendar.HOUR_OF_DAY)) { cal.add(Calendar.DATE, -1); } // 日付 timecard.setPunchDate(cal.getTime()); // タイプ timecard.setType(type.getValue()); if (EipTExtTimecard.TYPE_NO_SELECT.equals(type.getValue())) { timecard.setType(EipTExtTimecard.TYPE_NO_SELECT); } if (edit_mode.equals("punchin")) { // 出勤 timecard.setClockInTime(cal.getTime()); timecard.setType(EipTExtTimecard.TYPE_WORK); } else if (edit_mode.equals("punchout")) { // 退勤 timecard.setClockOutTime(cal.getTime()); } else if (edit_mode.equals("outgoing")) { // 外出 timecard.setOutgoingTime1(cal.getTime()); } else if (edit_mode.equals("comeback")) { // 復帰 timecard.setComebackTime1(cal.getTime()); } else { // 修正時 timecard.setPunchDate(punch_date.getValue()); /** 未来時刻への打刻は不可 */ if (cal.getTime().after(punch_date.getValue())) { if (!"P".equals(type.getValue())) { // 出退勤時間 timecard.setClockInTime(null); timecard.setClockOutTime(null); // 外出・復帰時間 for (int i = 1; i <= EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY; i++) { timecard.setOutgoingTime(null, i); timecard.setComebackTime(null, i); } } else { // 出退勤時間 timecard.setClockInTime(clock_in_time.getValue()); if (!clock_out_time.getDay().isEmpty()) { // 退勤時間が入っていた時 timecard.setClockOutTime(clock_out_time.getValue()); } // 外出・復帰時間 Field field_out, field_come; for (int i = 1; i <= EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY; i++) { field_out = this.getClass().getDeclaredField("outgoing_time" + i); field_come = this.getClass().getDeclaredField("comeback_time" + i); ALDateTimeField outgoing = (ALDateTimeField) field_out.get(this); ALDateTimeField comeback = (ALDateTimeField) field_come.get(this); if (!outgoing.isNullHour() && !outgoing.isNullMinute()) { timecard.setOutgoingTime(outgoing.getValue(), i); } if (!comeback.isNullHour() && !comeback.isNullMinute()) { timecard.setComebackTime(comeback.getValue(), i); } } } // 修正理由 timecard.setReason(reason.getValue()); } // 備考 timecard.setRemarks(remarks.getValue()); } // 作成日 timecard.setCreateDate(Calendar.getInstance().getTime()); // 更新日 timecard.setUpdateDate(Calendar.getInstance().getTime()); // タイムカードを登録 Database.commit(); // イベントログに保存 ALEventlogFactoryService.getInstance().getEventlogHandler().log( timecard.getExtTimecardId(), ALEventlogConstants.PORTLET_TYPE_EXTTIMECARD, null); } catch (RuntimeException ex) { // RuntimeException Database.rollback(); logger.error("exttimecard", ex); return false; } catch (Exception ex) { Database.rollback(); logger.error("exttimecard", ex); return false; } return true; } /** * データベースに格納されているタイムカードを更新します。 <BR> * * @param rundata * @param context * @param msgList * @return TRUE 成功 FALSE 失敗 */ @Override protected boolean updateFormData(RunData rundata, Context context, List<String> msgList) { boolean hasOthersUpdateAcl = aclHandler.hasAuthority( ALEipUtils.getUserId(rundata), aclPortletFeatureOther, ALAccessControlConstants.VALUE_ACL_UPDATE); try { if (!edit_mode.equals("")) { ALEipUtils.setTemp(rundata, context, ALEipConstants.ENTITY_ID, String .valueOf(entity_id)); } EipTExtTimecard timecard = ExtTimecardUtils.getEipTExtTimecard(rundata, context); if (timecard == null) { return false; } Integer userId = timecard.getUserId(); if (login_uid != userId.intValue() && !hasOthersUpdateAcl) { msgList.add(ALLocalizationUtils.getl10n("COMMON_PERMISSION_DENIED")); return false; } Calendar cal = Calendar.getInstance(); if (edit_mode.equals("punchin")) { // 出勤 timecard.setClockInTime(cal.getTime()); timecard.setType(EipTExtTimecard.TYPE_WORK); } else if (edit_mode.equals("punchout")) { // 退勤 timecard.setClockOutTime(cal.getTime()); } else if (edit_mode.equals("outgoing")) { // 外出 timecard.setNewOutgoingTime(cal.getTime()); } else if (edit_mode.equals("comeback")) { // 復帰 timecard.setNewComebackTime(cal.getTime()); } else { // 修正時 // タイプ timecard.setType(type.getValue()); if (EipTExtTimecard.TYPE_NO_SELECT.equals(type.getValue())) { timecard.setType(EipTExtTimecard.TYPE_NO_SELECT); } // 修正理由 timecard.setReason(reason.getValue()); // 備考 timecard.setRemarks(remarks.getValue()); /** 未来時刻への打刻は不可 */ // Calendar cal = Calendar.getInstance(); if (cal.getTime().after(punch_date.getValue())) { // 削除する if (!"P".equals(type.getValue())) { // 出退勤時間 timecard.setClockInTime(null); timecard.setClockOutTime(null); // 外出・復帰時間 for (int i = 1; i <= EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY; i++) { timecard.setOutgoingTime(null, i); timecard.setComebackTime(null, i); } } else { // 出退勤時間 timecard.setClockInTime(clock_in_time.getValue()); if (!clock_out_time.getHour().equals("") && !clock_out_time.getMinute().equals("")) { timecard.setClockOutTime(clock_out_time.getValue()); } else { // 初期化 timecard.setClockOutTime(null); } // 外出・復帰時間 Field field_out, field_come; for (int i = 1; i <= EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY; i++) { field_out = this.getClass().getDeclaredField("outgoing_time" + i); field_come = this.getClass().getDeclaredField("comeback_time" + i); timecard.setOutgoingTime(null, i); timecard.setComebackTime(null, i); ALDateTimeField outgoing = (ALDateTimeField) field_out.get(this); ALDateTimeField comeback = (ALDateTimeField) field_come.get(this); if (!outgoing.isNullHour() && !outgoing.isNullMinute()) { timecard.setOutgoingTime(outgoing.getValue(), i); } if (!comeback.isNullHour() && !comeback.isNullMinute()) { timecard.setComebackTime(comeback.getValue(), i); } } } } } // 更新日 timecard.setUpdateDate(Calendar.getInstance().getTime()); Database.commit(); // イベントログに保存 ALEventlogFactoryService.getInstance().getEventlogHandler().log( timecard.getExtTimecardId(), ALEventlogConstants.PORTLET_TYPE_EXTTIMECARD, null); } catch (RuntimeException ex) { // RuntimeException Database.rollback(); logger.error("exttimecard", ex); return false; } catch (Exception ex) { Database.rollback(); logger.error("exttimecard", ex); return false; } return true; } /** * 各ボタンを押したときの動作 <BR> * * @param action * @param rundata * @param context * @return TRUE 成功 FALSE 失敗 */ public boolean doPunch(ALAction action, RunData rundata, Context context, String mode) { try { edit_mode = mode; EipTExtTimecard timecard = ExtTimecardUtils.getUpdateEipTExtTimecard(rundata, context); this.type.setValue("P"); if (timecard != null) { // 更新すべきidを記憶 entity_id = timecard.getExtTimecardId(); // 当日内の更新なのでupdate文を発行 super.doUpdate(action, rundata, context); } else { // 日をまたいでの更新なのでinsert文を発行 super.doInsert(action, rundata, context); } } catch (Exception ex) { Database.rollback(); logger.error("exttimecard", ex); return false; } return true; } /** * アクセス権限をチェックします。 * * @return */ @Override protected boolean doCheckAclPermission(RunData rundata, Context context, int defineAclType) throws ALPermissionException { // 当日中のタイムカード打刻は、更新ではなく追加扱いにする if (defineAclType == ALAccessControlConstants.VALUE_ACL_UPDATE) { if ("punchin".equals(edit_mode) || "punchout".equals(edit_mode) || "outgoing".equals(edit_mode) || "comeback".equals(edit_mode)) { defineAclType = ALAccessControlConstants.VALUE_ACL_INSERT; } } return super.doCheckAclPermission(rundata, context, defineAclType); } /** * 日付 * * @return */ public ALDateTimeField getPunchDate() { return punch_date; } /** * 日付を取得します。 * * @return */ public String getDateStr() { try { SimpleDateFormat sdf = new SimpleDateFormat(ALLocalizationUtils.getl10n("EXTTIMECARD_FORMAT")); return sdf.format(punch_date.getValue()); } catch (Exception e) { return ""; } } /** * 日付が過去かどうか * * @return */ public boolean getIsPast() { Date now = Calendar.getInstance().getTime(); Date date = punch_date.getValue(); return date.before(now); } /** * 日付が現在かどうか * * @return */ public boolean getIsToday() { int change_hour = ExtTimecardUtils .getEipTExtTimecardSystemByUserId(login_uid) .getChangeHour(); Calendar cal = Calendar.getInstance(); Date date = punch_date.getValue(); boolean is_today = false; if ((Calendar.getInstance().get(Calendar.HOUR_OF_DAY)) < change_hour) { Calendar tmp_cal = Calendar.getInstance(); tmp_cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal .get(Calendar.DATE)); is_today = ExtTimecardUtils.sameDay(date, tmp_cal.getTime()); } else { is_today = ExtTimecardUtils.sameDay(date, cal.getTime()); } return is_today; } /** * 種類 * * @return */ public ALStringField getType() { return type; } /** * 出勤時間 * * @return */ public ALDateTimeField getClockInTime() { return clock_in_time; } public String getClockInTimeHourMinuteText() { return ALLocalizationUtils.getl10nFormat( "EXTTIMECARD_HOUR_MINUTE_FORMAT", clock_in_time.getHour().toString(), clock_in_time.getMinute().toString()); } /** * 退勤時間 * * @return */ public ALDateTimeField getClockOutTime() { return clock_out_time; } public String getClockOutTimeHourMinuteText() { return ALLocalizationUtils.getl10nFormat( "EXTTIMECARD_HOUR_MINUTE_FORMAT", clock_out_time.getHour().toString(), clock_out_time.getMinute().toString()); } /** * 外出時間 * * @return */ public ALDateTimeField getOutgoingTime(int n) { if (n > EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY) { return null; } switch (n) { case 1: return outgoing_time1; case 2: return outgoing_time2; case 3: return outgoing_time3; case 4: return outgoing_time4; case 5: return outgoing_time5; } return null; } /** * 復帰時間 * * @return */ public ALDateTimeField getComebackTime(int n) { if (n > EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY) { return null; } switch (n) { case 1: return comeback_time1; case 2: return comeback_time2; case 3: return comeback_time3; case 4: return comeback_time4; case 5: return comeback_time5; } return null; } public ALDateTimeField getOutgoingTime2() { return outgoing_time2; } /** * 修正理由 * * @return */ public ALStringField getReason() { return reason; } /** * 備考 * * @return */ public ALStringField getRemarks() { return remarks; } /** * タイムカード設定 * * @return */ public EipTExtTimecardSystem getTimecardSystem() { return timecard_system; } /** * 指定した2つの日付を比較する. * * @param date1 * @param date2 * @param checkTime * 時間まで比較する場合,true. * @return 等しい場合,0. date1>date2の場合, 1. date1 <date2の場合, 2. */ @SuppressWarnings("unused") private int compareToDate(Date date1, Date date2) { Calendar cal1 = Calendar.getInstance(); Calendar cal2 = Calendar.getInstance(); cal1.setTime(date1); cal2.setTime(date2); int date1Year = cal1.get(Calendar.YEAR); int date1Month = cal1.get(Calendar.MONTH) + 1; int date1Day = cal1.get(Calendar.DATE); int date1Hour = cal1.get(Calendar.HOUR); int date1Minute = cal1.get(Calendar.MINUTE); int date1Second = cal1.get(Calendar.SECOND); int date2Year = cal2.get(Calendar.YEAR); int date2Month = cal2.get(Calendar.MONTH) + 1; int date2Day = cal2.get(Calendar.DATE); int date2Hour = cal2.get(Calendar.HOUR); int date2Minute = cal2.get(Calendar.MINUTE); int date2Second = cal2.get(Calendar.SECOND); if (date1Year == date2Year && date1Month == date2Month && date1Day == date2Day && date1Hour == date2Hour && date1Minute == date2Minute && date1Second == date2Second) { return 0; } if (cal1.after(cal2)) { return 2; } else { return 1; } } /** * 日付がずれていたら、強制的に直します。 * * @param datetime * @param ajustto * @return */ private boolean ajustDate(ALDateTimeField datetime, ALDateTimeField ajustto) { if (datetime != null && !datetime.isNullHour() && !datetime.isNullMinute()) { Date punch = ajustto.getValue(); Calendar cal = Calendar.getInstance(); cal.setTime(punch); cal.set(Calendar.HOUR, Integer.parseInt(datetime.getHour())); cal.set(Calendar.MINUTE, Integer.parseInt(datetime.getMinute())); cal.set(Calendar.SECOND, 0); /** CHANGE_HOUR以下だったら、次の日とみなす */ if (Integer.parseInt(datetime.getHour()) < timecard_system .getChangeHour()) { cal.add(Calendar.DAY_OF_MONTH, 1); } datetime.setValue(cal.getTime()); return true; } return false; } /** * アクセス権限チェック用メソッド。<br /> * アクセス権限の機能名を返します。 * * @return */ @Override public String getAclPortletFeature() { return aclPortletFeature; } /** * alt_modeをセットする */ public void setAltMode(String alt_mode) { this.alt_mode = alt_mode; } /** * alt_modeをゲットする */ public String getAltMode() { return this.alt_mode; } /** * 外出数をゲットする */ public int getRestNum() { return Integer.parseInt(rest_num.getValue()); } /** * 編集のとき、フォームに入力されている退勤時間を取得します。 * */ public void setClockOutTime(RunData rundata) { try { Field[] fields = this.getClass().getDeclaredFields(); int length = fields.length; for (int i = 0; i < length; i++) { fields[i].setAccessible(true); String name = fields[i].getName(); Object obj = fields[i].get(this); if (name.equals("clock_out_time")) { // フィールドが ALDateTimeField の場合 if (obj instanceof ALDateTimeField) { String hourString = new StringBuffer().append(name).append( ALEipConstants.POST_DATE_HOUR).toString(); String minitusString = new StringBuffer().append(name).append( ALEipConstants.POST_DATE_MINUTE).toString(); current_clock_out_time_hour = rundata.getParameters().getInt(hourString); current_clock_out_time_minute = rundata.getParameters().getInt(minitusString); } } } } catch (Exception ex) { logger.error("exttimecard", ex); } } public String getSelectedUserId() { return selectedUserId; } private boolean isModify() { return !old_clock_in_time_hour.equals(clock_in_time.getHour()) || !old_clock_in_time_minute.equals(clock_in_time.getMinute()) || !old_clock_out_time_hour.equals(clock_out_time.getHour()) || !old_clock_out_time_minute.equals(clock_out_time.getMinute()); } private boolean isNotFuture() { return Calendar.getInstance().getTime().after(punch_date.getValue()); } private boolean isNotAtWork() { return !"P".equals(type.getValue()); } public boolean isNewRule() { return ExtTimecardUtils.isNewRule(); } }