/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * Copyright (C) 2004-2008 Aimluck,Inc.
 * http://aipostyle.com/
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU 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 General Public License for more details.
 *
 * You should have received a copy of the GNU 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.LinkedHashMap;
import java.util.List;

import jp.co.imtt.businesssystem.util.BusinessSystemUtils;

import org.apache.cayenne.DataRow;
import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.query.SQLTemplate;
import org.apache.cayenne.query.SelectQuery;
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.cayenne.om.portlet.EipTExtTimecardSystemMap;
import com.aimluck.eip.cayenne.om.portlet.ImwTOfficeCalendarMap;
import com.aimluck.eip.cayenne.om.portlet.ImwTPaidHoliday;
import com.aimluck.eip.cayenne.om.security.TurbineUser;
import com.aimluck.eip.common.ALAbstractFormData;
import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALEipConstants;
import com.aimluck.eip.common.ALEipUser;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.exttimecard.util.ExtTimecardUtils;
import com.aimluck.eip.modules.actions.common.ALAction;
import com.aimluck.eip.orm.DatabaseOrmService;
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.workflow.util.WorkflowUtils;

/**
 * タイムカードのフォームデータを管理するクラスです。 <BR>
 *
 */
public class ExtTimecardFormData extends ALAbstractFormData {

  /** logger */
  private static final JetspeedLogger logger = JetspeedLogFactoryService
      .getLogger(ExtTimecardFormData.class.getName());

  /** ToDo名 */

  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;
  
  /* Add　2010/8/19 金廣 Start--- */
  private ALStringField car_commuting_class;
  /* Add　2010/8/19 金廣 End--- */
  
  /* Add　2010/8/20 小濵 Start--- */
  private ALStringField holiday_flag;
  /* Add　2010/8/20 小濵 End--- */

  /* Add　2010/8/23 小濵 Start--- */
  private ALStringField system_id;
  /* Add　2010/8/23 小濵 End--- */

  /* Add　2010/8/24 小濵 Start--- */
  private ALStringField office_id;
  /* Add　2010/8/24 小濵 End--- */

  private int entity_id;

  private int login_uid;
  
  private String target_user_id;

  private DataContext dataContext;

  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 int rest_num;

  /** アクセス権限の機能名 */
  private String aclPortletFeature = null;

  /** 閲覧権限の有無 */
  private boolean hasAclOther; 
  
  
  /** タイムカードの設定 */
  private EipTExtTimecardSystem timecard_system;

  /**
   *
   * @param action
   * @param rundata
   * @param context
   * @see com.aimluck.eip.common.ALAbstractFormData#init(com.aimluck.eip.modules.actions.common.ALAction,
   *      org.apache.turbine.util.RunData, org.apache.velocity.context.Context)
   */
  public void init(ALAction action, RunData rundata, Context context)
      throws ALPageNotFoundException, ALDBErrorException {
    super.init(action, rundata, context);

    login_uid = ALEipUtils.getUserId(rundata);

    
    // 出勤・退勤時間
    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");

    dataContext = DatabaseOrmService.getInstance().getDataContext();



    
    // アクセス権
    ALAccessControlFactoryService aclservice = (ALAccessControlFactoryService) ((TurbineServices) TurbineServices
        .getInstance()).getService(ALAccessControlFactoryService.SERVICE_NAME);
    ALAccessControlHandler aclhandler = aclservice.getAccessControlHandler();
    hasAclOther = aclhandler.hasAuthority(ALEipUtils.getUserId(rundata),
        ALAccessControlConstants.POERTLET_FEATURE_TIMECARD_TIMECARD_OTHER,
        ALAccessControlConstants.VALUE_ACL_LIST);
    
    if (hasAclOther) {
      //他人のタイムカードの閲覧権限がある場合
      target_user_id = getTargetUserId(rundata, context);
    }
    if (target_user_id == null)
      target_user_id = String.valueOf(login_uid);
    
    timecard_system = ExtTimecardUtils
          .getEipTExtTimecardSystemByUserId(Integer.valueOf(target_user_id));
   
  }

  /**
   * 各フィールドを初期化します。 <BR>
   *
   * @see com.aimluck.eip.common.ALData#initField()
   */
  public void initField() {
    timecard_id = new ALNumberField();
    user_id = new ALNumberField();

    type = new ALStringField();
    type.setFieldName("種類");
    type.setValue("");

    punch_date = new ALDateTimeField();
    punch_date.setFieldName("日付");

    clock_in_time = new ALDateTimeField();
    clock_in_time.setFieldName("勤怠時間");
    clock_out_time = new ALDateTimeField();

    outgoing_comeback = new ALDateTimeField();
    outgoing_comeback.setFieldName("外出時間");

    reason = new ALStringField();
    reason.setFieldName("修正理由");
    reason.setValue("");

    remarks = new ALStringField();
    remarks.setFieldName("備考");
    remarks.setValue("");

    create_date = new ALDateField();
    create_date.setValue(new Date());

    update_date = new ALDateField();
    update_date.setValue(new Date());
    
    /* Add　2010/8/19 金廣 Start--- */
    car_commuting_class = new ALStringField();
    car_commuting_class.setFieldName("自家用車通勤区分");
    car_commuting_class.setValue("");    
    /* Add　2010/8/19 金廣 End--- */
    
    /* Add　2010/8/20 小濵 Start--- */
    holiday_flag = new ALStringField();
    /* Add　2010/8/20 小濵 End--- */    

    /* Add　2010/8/23 小濵 Start--- */
    system_id = new ALStringField();
    system_id.setFieldName("勤務形態");
    system_id.setValue("");
    /* Add　2010/8/23 小濵 End--- */

    /* Add　2010/8/24 小濵 Start--- */
    office_id = new ALStringField();
    office_id.setFieldName("勤務先");
    office_id.setValue("");
    /* Add　2010/8/24 小濵 End--- */

    edit_mode = "";

    alt_mode = "";

    rest_num = 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 (Exception e) {
      return;
    }
  }
  
  /**
   * 表示切り替えで指定したユーザ ID を取得する．
   *
   * @param rundata
   * @param context
   * @return
   */
  private String getTargetUserId(RunData rundata, Context context) {
    String target_user_id = rundata.getParameters().getString(
          ExtTimecardUtils.TARGET_USER_ID);
    
    return target_user_id;
  }
  
  /**
   * タイムカードの各フィールドに対する制約条件を設定します。 <BR>
   *
   * @see com.aimluck.eip.common.ALAbstractFormData#setValidator()
   */
  protected void setValidator() {
    // reason.setNotNull(true);
    // reason.limitMaxLength(1000);

    // work_date.setNotNull(true);
  }

  /**
   * タイムカードのフォームに入力されたデータの妥当性検証を行います。 <BR>
   *
   * @param msgList
   * @return TRUE 成功 FALSE 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#validate(java.util.ArrayList)
   */
  protected boolean validate(ArrayList msgList) {
    try {

      if (!"punchin".equals(edit_mode) && !"punchout".equals(edit_mode)
          && !"outgoing".equals(edit_mode) && !"comeback".equals(edit_mode)) {
        /*
         * 以下は多分Aipo5のバグです。文字比較がうまくいっていません。ポインタ比較になっています。
         * if ((old_clock_in_time_hour != clock_in_time.getHour().toString())
            || (old_clock_in_time_minute != clock_in_time.getMinute().toString())
            || (old_clock_out_time_hour != clock_out_time.getHour().toString())
            || (old_clock_out_time_minute != clock_out_time.getMinute().toString())) {
          reason.setNotNull(true);
          reason.validate(msgList);
          remarks.validate(msgList);
        }*/
        
        String od =(old_clock_in_time_hour+":"+
            old_clock_in_time_minute+"-"+
            old_clock_out_time_hour+":"+
            old_clock_out_time_minute);
        String nd =(clock_in_time.getHour()+":"+
            clock_in_time.getMinute()+"-"+
            clock_out_time.getHour()+":"+
            clock_out_time.getMinute());
        if(!od.equals(nd)){
         reason.setNotNull(true);
         reason.validate(msgList);
         remarks.validate(msgList);
         }
      }

      if (getMode() == ALEipConstants.MODE_INSERT) {
        SelectQuery workflg_query = new SelectQuery(EipTExtTimecard.class);
        Expression workflg_exp = ExpressionFactory.matchExp(
            EipTExtTimecard.USER_ID_PROPERTY, Integer.valueOf(login_uid));
        workflg_query.setQualifier(workflg_exp);
        workflg_query.addOrdering(EipTExtTimecard.PUNCH_DATE_PROPERTY, false);
        workflg_query.setFetchingDataRows(true);
        List workflg_list = dataContext.performQuery(workflg_query);
        if (workflg_list != null && workflg_list.size() > 0) {
          DataRow dataRow = (DataRow) workflg_list.get(0);

          // if (((String) ALEipUtils.getObjFromDataRow(dataRow,
          // EipTExtTimecard.WORK_FLAG_COLUMN)).equals(work_flag.getValue())) {
          // return false;
          // } else {
          // return true;
          // }
        } else {
          // return true;
        }
      }

      /** Delete 2010/08/26 金廣 Start--- */
      // 出勤時間・退勤時間が未入力で、外出時間が入力されている場合に
      // Exceptionになる（Aipo既存バグ）
      // 回避するため、validate処理を除去する。
//      /** 更新・挿入時 */
//      if (edit_mode.equals("")) {
//        /** 日付を 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("『 <span class='em'>退勤時刻</span> 』は『 <span class='em'>出勤時刻</span> 』以降の時刻を指定してください。");
//          }
//        }
//
//        /** 外出／復帰時間をリストに代入 */
//        ArrayList<HashMap> list_from_to = new ArrayList<HashMap>();
//        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 (ajustDate(outgoing, punch_date)
//              && ajustDate(comeback, punch_date)) {
//            long from = outgoing.getValue().getTime();
//            long to = comeback.getValue().getTime();
//            if (from <= to) {
//              if (from < clock_in_time.getValue().getTime()) {
//                msgList
//                    .add("『 <span class='em'>外出時刻</span> 』は『 <span class='em'>出勤時刻</span> 』以降の時刻を指定してください。（"
//                        + i + "行目）");
//              }
//              if (to > clock_out_time.getValue().getTime()) {
//                msgList
//                    .add("『 <span class='em'>復帰時刻</span> 』は『 <span class='em'>退勤時刻</span> 』以前の時刻を指定してください。（"
//                        + i + "行目）");
//              }
//              HashMap from_to = new HashMap();
//              from_to.put("from", outgoing.getValue().getTime());
//              from_to.put("to", comeback.getValue().getTime());
//              list_from_to.add(from_to);
//            } else {
//              msgList
//                  .add("『 <span class='em'>復帰時刻</span> 』は『 <span class='em'>外出時刻</span> 』以降の時刻を指定してください。（"
//                      + i + "行目）");
//            }
//          } else if (ajustDate(outgoing, punch_date) && !ajustDate(comeback, punch_date) && i == 1) {
//            HashMap from_to = new HashMap();
//            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) {
//          ArrayList<HashMap> empty_from_to = new ArrayList<HashMap>();
//          long min_from = (Long) list_from_to.get(0).get("from");
//          long max_to = (Long) list_from_to.get(0).get("to");
//          list_from_to.remove(0);
//          for (HashMap map : list_from_to) {
//            long new_from = (Long) map.get("from");
//            long new_to = (Long) map.get("to");
//            if (new_to <= min_from) {
//              HashMap empty = new HashMap();
//              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) {
//              HashMap empty = new HashMap();
//              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 (HashMap empty_map : empty_from_to) {
//                if ((Long) empty_map.get("from") <= new_from
//                    && (Long) empty_map.get("to") >= new_to) {
//                  /** 区間を分割し、もとあった空白を削除 */
//                  HashMap empty_left = new HashMap();
//                  empty_left.put("from", empty_map.get("from"));
//                  empty_left.put("to", new_from);
//                  empty_from_to.add(empty_left);
//
//                  HashMap empty_right = new HashMap();
//                  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("外出時間が重複しています。");
//                return false;
//              }
//            }
//          }
//
//          /** 並べ替える */
//          Collections.sort(empty_from_to, new Comparator() {
//            public int compare(Object o1, Object o2) {
//              HashMap hash1 = (HashMap) o1;
//              HashMap hash2 = (HashMap) o2;
//              long from1 = (Long) hash1.get("from");
//              long from2 = (Long) hash2.get("from");
//              if (from1 == from2) {
//                long to1 = (Long) hash1.get("to");
//                long to2 = (Long) hash2.get("to");
//                return (int) (to1 - to2);
//              } else
//                return (int) (from1 - from2);
//            }
//
//            public boolean equals(Object obj) {
//              return super.equals(obj);
//            }
//          });
//
//          long from = min_from;
//          long to;
//          for (HashMap empty : empty_from_to) {
//            to = (Long) 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 = (Long) 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());
//        }
//      }
      /** Delete 2010/08/26 金廣 End----- */
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return false;
    }

    return (msgList.size() == 0);
  }

  private EipTExtTimecard getNearlyAboveRecord(List list, int timecard_id) {
    EipTExtTimecard result = null;
    EipTExtTimecard record = null;
    int size = list.size();
    for (int i = 0; i < size; i++) {
      record = (EipTExtTimecard) list.get(i);
      if (record.getExtTimecardId().intValue() >= timecard_id) {
        return result;
      } else {
        result = record;
      }
    }

    return null;
  }

  private EipTExtTimecard getNearlyBelowRecord(List list, int timecard_id) {
    EipTExtTimecard record = null;
    int size = list.size();
    for (int i = 0; i < size; i++) {
      record = (EipTExtTimecard) list.get(i);
      if (record.getExtTimecardId().intValue() > timecard_id) {
        return record;
      }
    }

    return null;
  }

  protected boolean setFormData(RunData rundata, Context context,
      ArrayList msgList) throws ALPageNotFoundException, ALDBErrorException {
    boolean res = super.setFormData(rundata, context, msgList);

    if (res) {
      if (ALEipConstants.MODE_UPDATE.equals(this.getMode())) {
        try {
          if (!(this.entity_id > 0)) {
            entity_id = Integer.parseInt(ALEipUtils.getTemp(rundata, context,
                ALEipConstants.ENTITY_ID));
          }
          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("Exception", e);
        }
      } 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("P");
        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 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#loadFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context)
   */
  protected boolean loadFormData(RunData rundata, Context context,
      ArrayList 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());
      
      /* Add　2010/8/19 金廣 Start--- */
      car_commuting_class.setValue(timecard.getCarCommutingClass());
      /* Add　2010/8/19 金廣 End--- */
      
      /* Add　2010/8/24 小濵 Start--- */      
      system_id.setValue(timecard.getSystemId().toString());
      /* Add　2010/8/24 小濵 End--- */      

      /* Add　2010/8/24 小濵 Start--- */      
      office_id.setValue(timecard.getOfficeId().toString());
      /* Add　2010/8/24 小濵 End--- */      

      for (int i = 1; i <= 5; i++) {
        if (this.getOutgoingTime(i).isNotNullValue()) {
          this.rest_num++;
        } else if (this.getComebackTime(i).isNotNullValue()) {
          this.rest_num++;
        }
      }

      // 日時をセッションに保存
      ALEipUtils.setTemp(rundata, context, "punch_date", punch_date.getValue()
          .toString());

    } catch (Exception ex) {
      logger.error("Exception", ex);
      return false;
    }
    return true;
  }

  /**
   * タイムカードをデータベースから削除します。 <BR>
   *
   * @param rundata
   * @param context
   * @param msgList
   * @return TRUE 成功 FALSE 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#deleteFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context)
   */
  protected boolean deleteFormData(RunData rundata, Context context,
      ArrayList msgList) {
    try {
      // // オブジェクトモデルを取得
      // EipTExtTimecard timecard = ExtTimecardUtils.getEipTExtTimecard(rundata,
      // context);
      // if (timecard == null)
      // return false;
      // // 打刻情報を削除
      // dataContext.deleteObject(timecard);
      // // イベントログに保存
      // ALEventlogFactoryService.getInstance().getEventlogHandler().log(
      // timecard.getExtTimecardId(), ALEventlogConstants.PORTLET_TYPE_TIMECARD,
      // reason.getValue());

    } catch (Exception ex) {
      logger.error("Exception", ex);
      return false;
    }
    return true;
  }

  /**
   * タイムカードをデータベースに格納します。 <BR>
   *
   * @param rundata
   * @param context
   * @param msgList
   * @return TRUE 成功 FALSE 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#insertFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  protected boolean insertFormData(RunData rundata, Context context,
      ArrayList msgList) {
    try {
      // 新規オブジェクトモデル
      EipTExtTimecard timecard = (EipTExtTimecard) dataContext
          .createAndRegisterNewObject(EipTExtTimecard.class);

      // ユーザーID
      // Change 2010/8/23 デフォルトでログインユーザーを取得していたので選択ユーザーへ変更 (青柳)
      timecard.setUserId(Integer.valueOf(target_user_id));

      Calendar cal = Calendar.getInstance();
      if (timecard_system.getChangeHour() > cal.get(Calendar.HOUR_OF_DAY)) {
        cal.add(Calendar.DATE, -1);
      }

      // 日付
      timecard.setPunchDate(cal.getTime());

      // タイプ
      /** Update 2010/08/26 金廣 Start--- */
//      timecard.setType(type.getValue());
      timecard.setType("P");
      /** Update 2010/08/26 金廣 End--- */
      
      if (edit_mode.equals("punchin")) {
        // 出勤
        timecard.setClockInTime(cal.getTime());
      } 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 (!clock_in_time.isNullHour() && !clock_in_time.isNullMinute()) {
            timecard.setClockInTime(clock_in_time.getValue());
          }
          if (!clock_out_time.isNullHour() && !clock_out_time.isNullMinute()) {
            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());
        }

        /* Add　2010/8/19 金廣 Start--- */
        if(!"".equals(car_commuting_class.getValue())){
          timecard.setCarCommutingClass(car_commuting_class.getValue());
        }
        /* Add　2010/8/19 金廣 End--- */

        
        /* Add　2010/8/20 小濵 Start--- */
        if("checked".equals(holiday_flag.getValue())){
          timecard.setPaidHolidayId1(null);
          timecard.setPaidHolidayId2(null);
          timecard.setOffTime(null);
          timecard.setPaidHolidayType(null);
        }
        /* Add　2010/8/20 小濵 End--- */

        /* Add　2010/8/23 小濵 Start--- */
        if(!"".equals(system_id.getValue())){
          timecard.setSystemId(Integer.parseInt(system_id.getValue()));
        }
        /* Add　2010/8/23 小濵 End--- */

        /* Add　2010/8/24 小濵 Start--- */
        if(!"".equals(office_id.getValue())){
          timecard.setOfficeId(Integer.parseInt(office_id.getValue()));
        }
        /* Add　2010/8/24 小濵 End--- */
        
        // 備考
        timecard.setRemarks(remarks.getValue());
      }

      // 作成日
      timecard.setCreateDate(Calendar.getInstance().getTime());

      // 更新日
      timecard.setUpdateDate(Calendar.getInstance().getTime());   
      
      // タイムカードを登録
      dataContext.commitChanges();

      // イベントログに保存
      ALEventlogFactoryService.getInstance().getEventlogHandler().log(
          timecard.getExtTimecardId(),
          ALEventlogConstants.PORTLET_TYPE_TIMECARD, null);

    } catch (Exception ex) {

      logger.error("Exception", ex);
      return false;
    }
    return true;
  }

  /**
   * データベースに格納されているタイムカードを更新します。 <BR>
   *
   * @param rundata
   * @param context
   * @param msgList
   * @return TRUE 成功 FALSE 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#updateFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  protected boolean updateFormData(RunData rundata, Context context,
      ArrayList msgList) {
    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;
      }

      Calendar cal = Calendar.getInstance();
      if (edit_mode.equals("punchin")) {
        // 出勤
        timecard.setClockInTime(cal.getTime());
      } 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 {
        // 修正時

        /** 未来時刻への打刻は不可 */
        // Calendar cal = Calendar.getInstance();
        if (cal.getTime().after(punch_date.getValue())) {
          // 出退勤時間
          if (!clock_in_time.isNullHour() && !clock_in_time.isNullMinute()) {
            timecard.setClockInTime(clock_in_time.getValue());
          }
          /** Add 2010/08/26 金廣 Start--- */
          else if(clock_in_time.isNullHour() && clock_in_time.isNullMinute()) {
            timecard.setClockInTime(null);
          }
          /** Add 2010/08/26 金廣 End----- */
          if (!clock_out_time.isNullHour() && !clock_out_time.isNullMinute()) {
            timecard.setClockOutTime(clock_out_time.getValue());
          }
          /** Add 2010/08/26 金廣 Start--- */
          else if (clock_out_time.isNullHour() && clock_out_time.isNullMinute()) {
            timecard.setClockOutTime(null);
          }
          /** Add 2010/08/26 金廣 End----- */

          // 外出・復帰時間
          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.setType(type.getValue());

        // 修正理由
        timecard.setReason(reason.getValue());
        
        /* Update　2010/8/26 金廣 Start--- */
//        if(!"".equals(car_commuting_class.getValue())){
//          timecard.setCarCommutingClass(car_commuting_class.getValue());
//        }
        if("".equals(car_commuting_class.getValue())){
          timecard.setCarCommutingClass(null);
        } else {
          timecard.setCarCommutingClass(car_commuting_class.getValue());
        }
        /* Update　2010/8/26 金廣 End--- */
        
        /* Add　2010/8/20 小濵 Start--- */
        int paidHolidayId1 = 0;
        int paidHolidayId2 = 0;
        if("checked".equals(holiday_flag.getValue())){
          //update 2011/2/8 muramoto start
          if (timecard.getPaidHolidayId1() != null){
            paidHolidayId1 = timecard.getPaidHolidayId1();
          }
          if (timecard.getPaidHolidayId2() != null){
            paidHolidayId2 = timecard.getPaidHolidayId2();
          }
          //有給ＩＤ振替処理実行
          checkpaidHolidayId(paidHolidayId1, paidHolidayId2, punch_date.getValue());
          //update 2011/2/8 muramoto end
          timecard.setPaidHolidayId1(null);
          timecard.setPaidHolidayId2(null);
          timecard.setOffTime(null);
          timecard.setPaidHolidayType(null);
        }
        /* Add　2010/8/20 小濵 End--- */

        /* Add　2010/8/23 小濵 Start--- */
        if(!"".equals(system_id.getValue())){
          timecard.setSystemId(Integer.parseInt(system_id.getValue()));
        }
        /* Add　2010/8/23 小濵 End--- */

        /* Add　2010/8/24 小濵 Start--- */
        if(!"".equals(office_id.getValue())){
          timecard.setOfficeId(Integer.parseInt(office_id.getValue()));
        }
        /* Add　2010/8/24 小濵 End--- */

        // 備考
        timecard.setRemarks(remarks.getValue());
      }

      // 更新日
      timecard.setUpdateDate(Calendar.getInstance().getTime());

      dataContext.commitChanges();

      /** Update 2010/10/01 金廣 Start--- */
      // 課題50 他人のタイムカードを編集した際、算出退勤時間が再計算されない問題の対応
//      BusinessSystemUtils.setCalClockOutTime(
//          timecard.getPunchDate(),
//          Integer.valueOf(ALEipUtils.getUserId(rundata)),
//          timecard.getSystemId());
      // ログインユーザでなく編集対象のユーザの算出退勤時間を更新させる。
      BusinessSystemUtils.setCalClockOutTime(
          timecard.getPunchDate(),
          Integer.valueOf(getTargetUserId(rundata, context)),
          timecard.getSystemId());
      /** Update 2010/10/01 金廣 Start--- */
      
      // イベントログに保存
      ALEventlogFactoryService.getInstance().getEventlogHandler().log(
          timecard.getExtTimecardId(),
          ALEventlogConstants.PORTLET_TYPE_TIMECARD, null);

    } catch (Exception ex) {
      logger.error("Exception", ex);
      return false;
    }

    return true;
  }

  /**
   * 各ボタンを押したときの動作 <BR>
   *
   * @param action
   * @param rundata
   * @param context
   * @return TRUE 成功 FALSE 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#updateFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  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) {
      logger.error("Exception", ex);
      return false;
    }
    return true;
  }

  /**
   * 他人分の閲覧権限
   */
  public boolean getHasAclOther(){
    return hasAclOther;
  }
  
  /**
   * 保存先ユーザーID
   * 
   * @author 青柳
   */
  public String getTargetUserId(){
    return target_user_id;
  }
  
  /**
   * 日付
   *
   * @return
   */
  public ALDateTimeField getPunchDate() {
    return punch_date;
  }

  /**
   * 日付を取得します。
   *
   * @return
   */
  public String getDateStr() {
    try {
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日（EE）");
      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 ALStringField getType() {
    return type;
  }

  /**
   * 出勤時間
   *
   * @return
   */
  public ALDateTimeField getClockInTime() {
    return clock_in_time;
  }

  /**
   * 退勤時間
   *
   * @return
   */
  public ALDateTimeField getClockOutTime() {
    return clock_out_time;
  }

  /**
   * 外出時間
   *
   * @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;
  }
  
  /* Add　2010/8/19 金廣 Start--- */
  /**
   * 自家用車通勤区分
   * 
   * @ return
   */
  public ALStringField getCarCommutingClass(){
    return car_commuting_class;
  }
  /* Add　2010/8/19 金廣 End--- */
  
  /**
   * タイムカード設定
   *
   * @return
   */
  public EipTExtTimecardSystem getTimecardSystem() {
    return timecard_system;
  }

  /**
   * 指定した2つの日付を比較する．
   *
   * @param date1
   * @param date2
   * @param checkTime
   *          時間まで比較する場合，true．
   * @return 等しい場合，0. date1>date2の場合, 1. date1 <date2の場合, 2.
   */
  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
   */
  public String getAclPortletFeature() {
    return ALAccessControlConstants.POERTLET_FEATURE_TIMECARD_TIMECARD_SELF;
  }

  /**
   * 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() {

    if (this.rest_num == 0) {
      return 1;
    } else {
      return this.rest_num;
    }

  }
  
  public List getSystemList() {
    return ExtTimecardUtils.getAllEipTExtTimecardSystem();
  }

  /* Add　2010/8/24 小濵 Start--- */
  public boolean getCarCommutingFlag() {

    DataContext dataContext = DatabaseOrmService.getInstance().getDataContext();
    SelectQuery query = new SelectQuery(TurbineUser.class);
    Expression exp = ExpressionFactory.matchDbExp(
        TurbineUser.USER_ID_PK_COLUMN, target_user_id);
    query.setQualifier(exp);
    List slist = dataContext.performQuery(query);
    if(String.valueOf(((TurbineUser) slist.get(0)).getCarCommutingFlag()).equals("1"))
      return true;
    else
      return false;
  }
  /* Add　2010/8/24 小濵 End--- */

  /* Add　2010/8/24 小濵 Start--- */
  /**
   * 勤務形態ID
   *
   * @return
   */
  public ALStringField getSystemId() {
    if(system_id != null && !(system_id.getValue().equals("")))
        return system_id;
    else{
      DataContext dataContext = DatabaseOrmService.getInstance().getDataContext();
      SelectQuery query = new SelectQuery(EipTExtTimecardSystemMap.class);
      Expression exp = ExpressionFactory.matchExp(
          EipTExtTimecardSystemMap.USER_ID_PROPERTY, target_user_id);
      query.setQualifier(exp);
      List slist = dataContext.performQuery(query);
      EipTExtTimecardSystemMap eipTExtTimecardSystemMap = (EipTExtTimecardSystemMap) slist.get(0);
      system_id.setValue(eipTExtTimecardSystemMap.getEipTExtTimecardSystem().getSystemId().toString());
      return system_id;
    }
  }
  /* Add　2010/8/24 小濵 End--- */

  /* Add　2010/8/24 小濵 Start--- */
  /**
   * 勤務先ID
   *
   * @return
   */
  public ALStringField getOfficeId() {
    if(office_id != null && !(office_id.getValue().equals("")))
        return office_id;
    else{
      DataContext dataContext = DatabaseOrmService.getInstance().getDataContext();
      SelectQuery query = new SelectQuery(ImwTOfficeCalendarMap.class);
      Expression exp = ExpressionFactory.matchExp(
          ImwTOfficeCalendarMap.USER_ID_PROPERTY, target_user_id);
      query.setQualifier(exp);
      List slist = dataContext.performQuery(query);
      ImwTOfficeCalendarMap imwTOfficeCalendarMap = (ImwTOfficeCalendarMap) slist.get(0);
      office_id.setValue(imwTOfficeCalendarMap.getImwTOffice().getOfficeId().toString());
      return office_id;
    }
  }
  
  public List getOfficeList() {
    return ExtTimecardUtils.getAllImwTOffice();
  }
  /* Add　2010/8/24 小濵 End--- */
  
  /** Add 2010/08/20 muramoto Start */
  /**
   * リクエストのフォームに入力されたデータの妥当性検証を行います。 <BR>
   * 
   * @param msgList
   * @return TRUE 成功 FALSE 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#validate(java.util.ArrayList)
   */
  public void checkpaidHolidayId(int paidHolidayId1, int paidHolidayId2, Date punchdate) {
      // 有給残日数
      double lastPaidHolidayDays;
      // 休暇日数
      int offDay1 = 0;
      int offDay2 = 0;
      String date = null;
      int paidHolidayId;
      int uppaidHolidayId;
      int timecardpaidHolidayId1;
      int timecardpaidHolidayId2;
      Date timecardpunchdate = null;
      int userid = Integer.valueOf(target_user_id);
      SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
      date = format.format(punchdate);
      //有給リストより有効な有給データを適用開始日の昇順で取得
      List holidaylist = getPaidHoliday(userid, date);
      if (holidaylist.size() != 0 && holidaylist != null && holidaylist.size() > 1) {
        //削除したい有給が今年付与されたもの以外の場合、削除フラグを立てる
        for (int j = 0; j < holidaylist.size(); j++) {
          ImwTPaidHoliday imwTPaidHoliday = (ImwTPaidHoliday) holidaylist.get(j);
          paidHolidayId = imwTPaidHoliday.getPaidHolidayId();
          if (paidHolidayId == paidHolidayId1 && j < holidaylist.size()){
          //有給を取り消した日数計算
              offDay1 = 1;
          }
          if (paidHolidayId == paidHolidayId2 && j < holidaylist.size()){
            //有給を取り消した日数計算
                offDay2 = 1;
          }
        }
        if (offDay1 == 1){
          try{
          //削除したい有給が今年付与されたもの以外の場合、有給ＩＤを振り変える。
            for (int j = 0; j < holidaylist.size(); j++) {
              ImwTPaidHoliday imwTPaidHoliday = (ImwTPaidHoliday) holidaylist.get(j);
              paidHolidayId = imwTPaidHoliday.getPaidHolidayId();
              //削除したいＩＤと一致した場合、次の年の有給を使用している有給データを取得
              if (paidHolidayId == paidHolidayId1){
                ImwTPaidHoliday imwTupPaidHoliday = (ImwTPaidHoliday) holidaylist.get(j+1);
                uppaidHolidayId=imwTupPaidHoliday.getPaidHolidayId();
                //振り返るタイムカードのリストを取得
                String query = "select t.punch_date, t.paid_holiday_id1, t.paid_holiday_id2" 
                  + " from eip_t_ext_timecard t"
                  + " where t.user_id = " + userid + " and (t.paid_holiday_id1 = "
                  + uppaidHolidayId + " or t.paid_holiday_id2 = " + uppaidHolidayId + ")"
                  + " and not t.punch_date = '" + date + "' order by t.punch_date";

                DataContext dataContext = DatabaseOrmService.getInstance()
                  .getDataContext();
                SQLTemplate rawSelect = new SQLTemplate(EipTExtTimecard.class, query,true);
                rawSelect.setFetchingDataRows(true);
                List list = dataContext.performQuery(rawSelect);
                DataRow dataRow;
                for (int i = 0; i < list.size(); i++){
                  dataRow = (DataRow) list.get(i);
                  timecardpaidHolidayId1=(Integer) ALEipUtils.getObjFromDataRow(dataRow,
                      EipTExtTimecard.PAID_HOLIDAY_ID1_COLUMN);
                  timecardpaidHolidayId2=(Integer) ALEipUtils.getObjFromDataRow(dataRow,
                      EipTExtTimecard.PAID_HOLIDAY_ID2_COLUMN);
                  timecardpunchdate = (Date)ALEipUtils.getObjFromDataRow(dataRow,
                      EipTExtTimecard.PUNCH_DATE_COLUMN);
                  //去年分と今年分の有給を使用しているデータを検索し、アップデートする
                  if (timecardpaidHolidayId1 == paidHolidayId1 && timecardpaidHolidayId2 == uppaidHolidayId){
                    //if (!(format.format(timecardpunchdate).equals(date))){  
                      //アップデート
                      String upquery = "update eip_t_ext_timecard"
                        + " set paid_holiday_id2 =" + paidHolidayId1
                        + " where user_id = " + userid + " and punch_date = '"
                        + format.format(timecardpunchdate) + "'";
                    
                      SQLTemplate Uptimecard = new SQLTemplate(EipTExtTimecard.class, upquery,true);
                      Uptimecard.setFetchingDataRows(true);
                      dataContext.performQuery(Uptimecard);
                      dataContext.commitChanges();
                      offDay1 = 0;
                      break;
                    //}
                  }
                }
                if(offDay1 == 1){
                  
                  //リストの一番目をアップデートする。
                  dataRow = (DataRow) list.get(0);
                  timecardpaidHolidayId1=(Integer) ALEipUtils.getObjFromDataRow(dataRow,
                      EipTExtTimecard.PAID_HOLIDAY_ID1_COLUMN);
                  timecardpaidHolidayId2=(Integer) ALEipUtils.getObjFromDataRow(dataRow,
                      EipTExtTimecard.PAID_HOLIDAY_ID2_COLUMN);
                  timecardpunchdate = (Date)ALEipUtils.getObjFromDataRow(dataRow,
                      EipTExtTimecard.PUNCH_DATE_COLUMN);
                  //アップデート
                  String upquery = "update eip_t_ext_timecard"
                    + " set paid_holiday_id1 =" + paidHolidayId1
                    + " where user_id = " + userid + " and punch_date = '"
                      + format.format(timecardpunchdate) + "'";
                  
                  SQLTemplate Uptimecard = new SQLTemplate(EipTExtTimecard.class, upquery,true);
                  Uptimecard.setFetchingDataRows(true);
                  dataContext.performQuery(Uptimecard);
                  dataContext.commitChanges();
                  offDay1 = 0; 
                }
              }
            }
          } catch (Exception ex) {
            logger.error("Exception", ex);
          }
        }
        //全休の場合
        if (offDay2 == 1){
          try{
          //削除したい有給が今年付与されたもの以外の場合、有給ＩＤを振り変える。
            for (int j = 0; j < holidaylist.size(); j++) {
              ImwTPaidHoliday imwTPaidHoliday = (ImwTPaidHoliday) holidaylist.get(j);
              paidHolidayId = imwTPaidHoliday.getPaidHolidayId();
              //削除したいＩＤと一致した場合、次の年の有給を使用している有給データを取得
              if (paidHolidayId == paidHolidayId2){
                ImwTPaidHoliday imwTupPaidHoliday = (ImwTPaidHoliday) holidaylist.get(j+1);
                uppaidHolidayId=imwTupPaidHoliday.getPaidHolidayId();
                //振り返るタイムカードのリストを取得
                String query = "select t.punch_date, t.paid_holiday_id1, t.paid_holiday_id2" 
                  + " from eip_t_ext_timecard t"
                  + " where t.user_id = " + userid + " and (t.paid_holiday_id1 = "
                  + uppaidHolidayId + " or t.paid_holiday_id2 = " + uppaidHolidayId + ")"
                  + " and not t.punch_date = '" + date + "' order by t.punch_date";

                DataContext dataContext = DatabaseOrmService.getInstance()
                  .getDataContext();
                SQLTemplate rawSelect = new SQLTemplate(ImwTPaidHoliday.class, query,true);
                rawSelect.setFetchingDataRows(true);
                List list = dataContext.performQuery(rawSelect);
                DataRow dataRow;
                for (int i = 0; i < list.size(); i++){
                  dataRow = (DataRow) list.get(i);
                  timecardpaidHolidayId1=(Integer) ALEipUtils.getObjFromDataRow(dataRow,
                      EipTExtTimecard.PAID_HOLIDAY_ID1_COLUMN);
                  timecardpaidHolidayId2=(Integer) ALEipUtils.getObjFromDataRow(dataRow,
                      EipTExtTimecard.PAID_HOLIDAY_ID2_COLUMN);
                  timecardpunchdate = (Date)ALEipUtils.getObjFromDataRow(dataRow,
                      EipTExtTimecard.PUNCH_DATE_COLUMN);
                  //去年分と今年分の有給を使用しているデータを検索し、アップデートする
                  if (timecardpaidHolidayId1 == paidHolidayId2 && timecardpaidHolidayId2 == uppaidHolidayId){
                    //アップデート
                    String upquery = "update eip_t_ext_timecard"
                      + " set paid_holiday_id2 =" + paidHolidayId2
                      + " where user_id = " + userid + " and punch_date = '"
                      + format.format(timecardpunchdate) + "'";
                    
                    SQLTemplate Uptimecard = new SQLTemplate(EipTExtTimecard.class, upquery,true);
                    Uptimecard.setFetchingDataRows(true);
                    dataContext.performQuery(Uptimecard);
                    dataContext.commitChanges();
                    offDay2 = 0;
                    break;
                  }
                }
                if(offDay2 == 1){
                  //リストの一番目をアップデートする。
                  dataRow = (DataRow) list.get(0);
                  timecardpaidHolidayId1=(Integer) ALEipUtils.getObjFromDataRow(dataRow,
                      EipTExtTimecard.PAID_HOLIDAY_ID1_COLUMN);
                  timecardpaidHolidayId2=(Integer) ALEipUtils.getObjFromDataRow(dataRow,
                      EipTExtTimecard.PAID_HOLIDAY_ID2_COLUMN);
                  timecardpunchdate = (Date)ALEipUtils.getObjFromDataRow(dataRow,
                      EipTExtTimecard.PUNCH_DATE_COLUMN);
                  //アップデート
                  String upquery = "update eip_t_ext_timecard"
                    + " set paid_holiday_id1 =" + paidHolidayId1
                    + " where user_id = " + userid + " and punch_date = '"
                    + format.format(timecardpunchdate) + "'";
                  
                  SQLTemplate Uptimecard = new SQLTemplate(EipTExtTimecard.class, upquery,true);
                  Uptimecard.setFetchingDataRows(true);
                  dataContext.performQuery(Uptimecard);
                  dataContext.commitChanges();
                  offDay2 = 0; 
                }
              }
            }
          } catch (Exception ex) {
            logger.error("Exception", ex);
          }
        }
      }
  }

  @SuppressWarnings("deprecation")
  public static List getPaidHoliday(int userId, String offDate) {
    
    String query = "select p.paid_holiday_id , p.paid_holiday_days"
      + " from imw_t_paid_holiday p" + " where p.user_id = " + userId
      + " and p.valid_start_date <= '" + offDate + "' and p.valid_end_date >= '" + offDate
      + "' order by p.valid_start_date";

    try {
      DataContext dataContext = DatabaseOrmService.getInstance()
          .getDataContext();
      SQLTemplate rawSelect = new SQLTemplate(ImwTPaidHoliday.class, query,
          true);
      rawSelect.setFetchingDataRows(true);
      List list = dataContext.performQuery(rawSelect);
      DataRow dataRow;
      int recordNum = list.size();
      List uList = new ArrayList();
      for (int i = 0; i < recordNum; i++) {
        dataRow = (DataRow) list.get(i);
        ImwTPaidHoliday rd = new ImwTPaidHoliday();
        rd.setPaidHolidayDays((Integer) ALEipUtils.getObjFromDataRow(dataRow,
            ImwTPaidHoliday.PAID_HOLIDAY_DAYS_COLUMN));
        rd.setPaidHolidayId(String.valueOf((Integer) ALEipUtils
            .getObjFromDataRow(dataRow,
                ImwTPaidHoliday.PAID_HOLIDAY_ID_PK_COLUMN)));
        uList.add(rd);
      }
      return uList;
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return null;
    }
  }
  //update 2011/2/4 muramoto end
}