/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * Copyright (C) 2004-2011 Aimluck,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.schedule;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

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.util.RunData;
import org.apache.velocity.context.Context;

import com.aimluck.commons.field.ALCellNumberField;
import com.aimluck.commons.field.ALCellStringField;
import com.aimluck.commons.field.ALDateContainer;
import com.aimluck.commons.field.ALStringField;
import com.aimluck.eip.category.util.CommonCategoryUtils;
import com.aimluck.eip.cayenne.om.portlet.EipTCommonCategory;
import com.aimluck.eip.cayenne.om.portlet.EipTSchedule;
import com.aimluck.eip.cayenne.om.portlet.EipTScheduleMap;
import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALEipConstants;
import com.aimluck.eip.common.ALEipGroup;
import com.aimluck.eip.common.ALEipUser;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.mail.util.ALEipUserAddr;
import com.aimluck.eip.mail.util.ALMailUtils;
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.schedule.util.CellScheduleUtils;
import com.aimluck.eip.schedule.util.ScheduleUtils;
import com.aimluck.eip.services.eventlog.ALEventlogConstants;
import com.aimluck.eip.services.eventlog.ALEventlogFactoryService;
import com.aimluck.eip.util.ALEipUtils;

// change start
// /**
// * スケジュールのフォームデータを管理するクラスです。
// *
// */
/**
 * スケジュールのフォーム(共通編集フォーム)データを管理するクラスです。
 * 
 */
// change end
public class CellScheduleFormNoteData extends AbstractCellScheduleFormData {

  /** <code>logger</code> logger */
  private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(CellScheduleFormNoteData.class.getName());

  /** <code>name</code> 予定 */
  private ALStringField name;

  /** <code>place</code> 場所 */
  private ALStringField place;

  /** <code>note</code> 内容 */
  private ALStringField note;

  /** <code>public_flag</code> 公開/非公開フラグ */
  private ALStringField public_flag;

  /** <code>todo_id</code> ToDo ID */
  private ALCellNumberField common_category_id;

  /** <code>groups</code> グループ */
  private List<ALEipGroup> groups;

  /** <code>del_member_flag</code> [削除フラグ] 共有メンバーを削除するフラグ */
  private ALCellNumberField del_member_flag;

  /** <code>del_range_flag</code> [削除フラグ] 削除範囲のフラグ */
  private ALCellNumberField del_range_flag;

  private ALCellNumberField del_flag;

  /** ログインユーザー情報 */
  private ALEipUser loginUser;

  /**
   * フォームを表示します。
   * 
   * @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 enable_entityid = (ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID) != null);
      action.setMode(enable_entityid ? ALEipConstants.MODE_EDIT_FORM : ALEipConstants.MODE_NEW_FORM);
      setMode(action.getMode());
      List<String> msgList = new ArrayList<String>();

      EipTSchedule schedule;
      boolean res = true;

      if (enable_entityid) {
        schedule = ScheduleUtils.getEipTSchedule(rundata, context, false);
        res = loadFormData(rundata, context, msgList);
      } else {
        setFormData(rundata, context, msgList);
        schedule = Database.create(EipTSchedule.class);
      }

      String schedule_type = getScheduleType().getValue();
      if (CellScheduleUtils.SCHEDULE_TYPE_SPAN.equals(schedule_type)) {
        schedule.setStartDate(form_data.getStartDate().getValue());
        schedule.setEndDate(form_data.getEndDate().getValue());
        schedule.setRepeatPattern("S");
      } else if (CellScheduleUtils.SCHEDULE_TYPE_ONEDAY.equals(schedule_type)) {
        schedule.setStartDate(form_data.getStartDate().getValue());
        schedule.setEndDate(form_data.getEndDate().getValue());
        schedule.setRepeatPattern("N");
      } else {
        // 繰り返しスケジュール設定の場合
        char lim = 'N';
        Calendar cal = Calendar.getInstance();
        // 繰り返しの期間が設定されている場合
        // change start
        // if ("ON".equals(form_data.getLimitFlag().getValue())) {
        // lim = 'L';
        if (ScheduleConst.LIMIT_TYPE_DATE.equals(form_data.getLimitFlag().getValue())) {
          // 繰り返し期限在りの場合
          // change end
          int year = Integer.parseInt(form_data.getLimitEndDate().getYear());
          int month = Integer.parseInt(form_data.getLimitEndDate().getMonth()) - 1;
          int day = Integer.parseInt(form_data.getLimitEndDate().getDay());
          cal.set(year, month, day);

          Calendar limitStartCal = Calendar.getInstance();
          limitStartCal.setTime(form_data.getStartDate().getValue());
          limitStartCal.set(Calendar.YEAR, Integer.parseInt(form_data.getLimitStartDate().getYear()));
          limitStartCal.set(Calendar.MONTH, Integer.parseInt(form_data.getLimitStartDate().getMonth()) - 1);
          limitStartCal.set(Calendar.DATE, Integer.parseInt(form_data.getLimitStartDate().getDay()));
          schedule.setStartDate(limitStartCal.getTime());
          schedule.setEndDate(cal.getTime());
          // add start
        } else if (ScheduleConst.LIMIT_TYPE_NOFT.equals(form_data.getLimitFlag().getValue())) {
          // 繰り返し回数在りの場合
          schedule.setRepeatNum((int) form_data.getRepeatNum().getValue());
          // add end
        } else {
          // 繰り返し期限未設定の場合
          schedule.setStartDate(form_data.getStartDate().getValue());
          schedule.setEndDate(form_data.getEndDate().getValue());
        }
        // remove start
        // 繰り返しパターン判定は本プロジェクト向けに変更されているので
        // 既存部分は削除
        // if ("D".equals(form_data.getRepeatType().getValue())) {
        // schedule.setRepeatPattern(new StringBuffer()
        // .append('D')
        // .append(lim)
        // .toString());
        // } else if ("W".equals(form_data.getRepeatType().getValue())) {
        // schedule.setRepeatPattern(new StringBuffer()
        // .append('W')
        // .append(form_data.getWeek0().getValue() != null ? 1 : 0)
        // .append(form_data.getWeek1().getValue() != null ? 1 : 0)
        // .append(form_data.getWeek2().getValue() != null ? 1 : 0)
        // .append(form_data.getWeek3().getValue() != null ? 1 : 0)
        // .append(form_data.getWeek4().getValue() != null ? 1 : 0)
        // .append(form_data.getWeek5().getValue() != null ? 1 : 0)
        // .append(form_data.getWeek6().getValue() != null ? 1 : 0)
        // .append(lim)
        // .toString());
        // } else {
        // DecimalFormat format = new DecimalFormat("00");
        // schedule.setRepeatPattern(new StringBuffer()
        // .append('M')
        // .append(format.format(form_data.getMonthDay().getValue()))
        // .append(lim)
        // .toString());
        // }
        // remove end
      }
      // remove start
      // 共有施設設定は未使用のため削除
      // context.put("isDuplicateFacility", "false");
      // List<FacilityResultData> facilityList =
      // CellScheduleUtils.getShareFacilityMemberList(rundata);
      // if (facilityList.size() > 0) {
      // List<Integer> fids = new ArrayList<Integer>();
      // for (FacilityResultData facility : facilityList) {
      // fids.add(Integer.valueOf((int) facility.getFacilityId().getValue()));
      // }
      // if (ScheduleUtils.isDuplicateFacilitySchedule(
      // schedule,
      // fids,
      // null,
      // null)) {
      // context.put("isDuplicateFacility", "true");
      // }
      // }
      // // 施設のアクセスコントロールのチェック
      // int acltype =
      // (ALEipConstants.MODE_NEW_FORM.equals(getMode()))
      // ? ALAccessControlConstants.VALUE_ACL_INSERT
      // : ALAccessControlConstants.VALUE_ACL_UPDATE;
      // if (!facilityCheckAclPermission(rundata, acltype)) {
      // if (acltype == ALAccessControlConstants.VALUE_ACL_UPDATE) {
      // int[] old_ids = ScheduleUtils.getFacilityIds(schedule);
      // boolean check = false;
      // if (old_ids.length != facilityList.size()) {
      // msgList.add(" 施設を予約する権限がありません ");
      // res = false;
      // } else {
      // for (int old_id : old_ids) {
      // for (Object record : facilityList) {
      // FacilityResultData frd = (FacilityResultData) record;
      // int facilityid = (int) frd.getFacilityId().getValue();
      // if (old_id == facilityid) {
      // check = true;
      // break;
      // }
      // }
      // if (!check) {
      // msgList.add(" 施設を予約する権限がありません ");
      // res = false;
      // }
      // check = false;
      // }
      // }
      // } else {
      // if (facilityList.size() > 0) {
      // msgList.add(" 施設を予約する権限がありません ");
      // res = false;
      // }
      // }
      // }
      // remove end
      res = res && (form_data.validateDelegate(msgList, getLoginUser(), getEntityId(), getScheduleType().getValue()));
      action.setResultData(this);
      action.addErrorMessages(msgList);
      action.putData(rundata, context);
      return res;
    } catch (ALPageNotFoundException e) {
      ALEipUtils.redirectPageNotFound(rundata);
      return false;
    } catch (ALDBErrorException e) {
      ALEipUtils.redirectDBError(rundata);
      return false;
    }

  }

  /**
   * 
   * @param action
   * @param rundata
   * @param context
   * @throws ALPageNotFoundException
   * @throws ALDBErrorException
   */
  @Override
  public void init(ALAction action, RunData rundata, Context context) throws ALPageNotFoundException, ALDBErrorException {

    super.init(action, rundata, context);
  }

  /*
   * 
   */
  @Override
  public void initField() {
    // 予定
    name = new ALStringField();
    name.setFieldName("予定");
    name.setTrim(true);
    // 場所
    place = new ALStringField();
    place.setFieldName("場所");
    place.setTrim(true);
    // 内容
    note = new ALStringField();
    note.setFieldName("内容");
    note.setTrim(false);
    // 公開区分
    public_flag = new ALStringField();
    public_flag.setFieldName("公開区分");
    public_flag.setTrim(true);
    public_flag.setValue("O");

    // [削除フラグ] 共有メンバーを削除するフラグ
    del_member_flag = new ALCellNumberField();
    del_member_flag.setValue(CellScheduleUtils.FLAG_DEL_MEMBER_ALL);
    // [削除フラグ] 削除範囲のフラグ
    del_range_flag = new ALCellNumberField();
    del_range_flag.setValue(CellScheduleUtils.FLAG_DEL_RANGE_ALL);

    del_flag = new ALCellNumberField();
    del_flag.setValue(0);

    // 2007.3.28 ToDo連携
    common_category_id = new ALCellNumberField();
    common_category_id.setFieldName("カテゴリ");
    common_category_id.setValue(1);

    super.initField();
  }

  /*
   * 
   */
  @Override
  protected void setValidator() {

    // 予定
    getName().setNotNull(true);
    getName().limitMaxLength(50);

    // 場所
    getPlace().limitMaxLength(50);

    // 内容
    getNote().limitMaxLength(1000);

    super.setValidator();
  }

  /**
   * 
   * @param msgList
   * @return
   * @throws ALDBErrorException
   * @throws ALPageNotFoundException
   */
  @Override
  protected boolean validate(List<String> msgList) throws ALDBErrorException, ALPageNotFoundException {
    // 予定
    getName().validate(msgList);

    // 場所
    getPlace().validate(msgList);

    // 内容
    getNote().validate(msgList);

    return super.validate(msgList);
  }

  @Override
  protected void loadCustomFormData(EipTSchedule record) {
    // 予定
    name.setValue(record.getName());

    // 場所
    place.setValue(record.getPlace());

    // 内容
    note.setValue(record.getNote());

    // 公開フラグ
    public_flag.setValue(record.getPublicFlag());

    // 週をsetFormDataで再設定させる
    form_data.getWeek0().setValue("");
    form_data.getWeek1().setValue("");
    form_data.getWeek2().setValue("");
    form_data.getWeek3().setValue("");
    form_data.getWeek4().setValue("");
    form_data.getWeek5().setValue("");
    form_data.getWeek6().setValue("");
  }

  /**
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * @throws ALPageNotFoundException
   * @throws ALDBErrorException
   */
  @Override
  protected boolean setFormData(RunData rundata, Context context, List<String> msgList) throws ALPageNotFoundException, ALDBErrorException {
    Field[] fields = this.getClass().getDeclaredFields();
    boolean res = ScheduleUtils.setFormDataDelegate(rundata, context, this, fields, msgList);

    if (!res) {
      return res;
    }

    return super.setFormData(rundata, context, msgList);
  }

  /**
   * ** add start スケジュールの追加処理 ** add end
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * @throws ALDBErrorException
   */
  @Override
  protected boolean insertFormData(RunData rundata, Context context, List<String> msgList) throws ALDBErrorException {
    EipTSchedule schedule = null;
    List<ALEipUser> memberList = new ArrayList<ALEipUser>();
    try {

      // 期間は時刻を0:00に固定
      if (isSpan()) {
        Calendar startDate = Calendar.getInstance();
        startDate.setTime(form_data.getStartDate().getValue());
        startDate.set(Calendar.HOUR_OF_DAY, 0);
        startDate.set(Calendar.MINUTE, 0);

        Calendar endDate = Calendar.getInstance();
        endDate.setTime(form_data.getEndDate().getValue());
        endDate.set(Calendar.HOUR_OF_DAY, 0);
        endDate.set(Calendar.MINUTE, 0);

        form_data.getStartDate().setValue(startDate.getTime());
        form_data.getEndDate().setValue(endDate.getTime());
      }
      // remove start
      // 期間スケジュール以外は画面のパラメータをそのまま使用
      // else {
      // Calendar startcal = new GregorianCalendar();
      // startcal.setTime(form_data.getStartDate().getValue());
      // Calendar endcal = Calendar.getInstance();
      // endcal.setTime(form_data.getEndDate().getValue());
      // endcal.set(Calendar.YEAR, startcal.get(Calendar.YEAR));
      // endcal.set(Calendar.MONTH, startcal.get(Calendar.MONTH));
      // endcal.set(Calendar.DATE, startcal.get(Calendar.DATE));
      // form_data.getEndDate().setValue(endcal.getTime());
      // }
      // remove end
      // オーナーID
      int ownerid = ALEipUtils.getUserId(rundata);
      // 新規オブジェクトモデル
      schedule = Database.create(EipTSchedule.class);

      // add start
      // 入力値をDB項目へ変換
      convertInputParamToSchedule(schedule);
      // add end

      // 親スケジュール ID
      schedule.setParentId(Integer.valueOf(0));

      // remove start
      // DB項目へのセットはconvertInputParamToScheduleメソッドにてまとめたため削除
      // // 予定
      // schedule.setName(getName().getValue());
      // // 場所
      // schedule.setPlace(getPlace().getValue());
      // // 内容
      // schedule.setNote(getNote().getValue());
      // // 公開フラグ
      // schedule.setPublicFlag(getPublicFlag().getValue());
      // // 共有メンバーによる編集／削除フラグ
      // if (form_data.getMemberList().size() > 1) {
      // schedule.setEditFlag(form_data.getEditFlag().getValue());
      // } else {
      // schedule.setEditFlag("F");
      // }
      // remove end

      // オーナーID
      schedule.setOwnerId(Integer.valueOf(ownerid));
      // 作成日
      Date now = new Date();
      schedule.setCreateDate(now);
      schedule.setCreateUserId(Integer.valueOf(ownerid));
      // 更新日
      schedule.setUpdateDate(now);
      schedule.setUpdateUserId(Integer.valueOf(ownerid));

      // remove start
      // 設定処理を共通メソッドに移管
      // if (isSpan()) {
      // // 期間スケジュール設定の場合
      // schedule.setEndDate(form_data.getEndDate().getValue());
      // schedule.setRepeatPattern("S");
      //
      // schedule.setStartDate(form_data.getStartDate().getValue());
      // } else if (!isRepeat()) {
      // // 終了日時
      // schedule.setEndDate(form_data.getEndDate().getValue());
      // schedule.setRepeatPattern("N");
      //
      // schedule.setStartDate(form_data.getStartDate().getValue());
      // } else {
      // // 繰り返しスケジュール設定の場合
      // char lim = 'N';
      // Calendar cal = Calendar.getInstance();
      // cal.setTime(form_data.getEndDate().getValue());
      // if ("ON".equals(form_data.getLimitFlag().getValue())) {
      // lim = 'L';
      // cal.set(form_data.getLimitEndDate().getValue().getYear(), form_data
      // .getLimitEndDate()
      // .getValue()
      // .getMonth() - 1, form_data.getLimitEndDate().getValue().getDay());
      //
      // ALDateContainer container = form_data.getLimitStartDate().getValue();
      // Calendar limitStartCal = Calendar.getInstance();
      // limitStartCal.setTime(form_data.getStartDate().getValue());
      // limitStartCal.set(Calendar.YEAR, container.getYear());
      // limitStartCal.set(Calendar.MONTH, container.getMonth() - 1);
      // limitStartCal.set(Calendar.DATE, container.getDay());
      // schedule.setStartDate(limitStartCal.getTime());
      // } else {
      // schedule.setStartDate(form_data.getStartDate().getValue());
      // }
      //
      // schedule.setEndDate(cal.getTime());
      // if ("D".equals(form_data.getRepeatType().getValue())) {
      // schedule.setRepeatPattern(new StringBuffer()
      // .append('D')
      // .append(lim)
      // .toString());
      // } else if ("W".equals(form_data.getRepeatType().getValue())) {
      // schedule.setRepeatPattern(new StringBuffer()
      // .append('W')
      // .append(form_data.getWeek0().getValue() != null ? 1 : 0)
      // .append(form_data.getWeek1().getValue() != null ? 1 : 0)
      // .append(form_data.getWeek2().getValue() != null ? 1 : 0)
      // .append(form_data.getWeek3().getValue() != null ? 1 : 0)
      // .append(form_data.getWeek4().getValue() != null ? 1 : 0)
      // .append(form_data.getWeek5().getValue() != null ? 1 : 0)
      // .append(form_data.getWeek6().getValue() != null ? 1 : 0)
      // .append(lim)
      // .toString());
      // } else {
      // DecimalFormat format = new DecimalFormat("00");
      // schedule.setRepeatPattern(new StringBuffer()
      // .append('M')
      // .append(format.format(form_data.getMonthDay().getValue()))
      // .append(lim)
      // .toString());
      // }
      // }
      // remove end

      EipTCommonCategory category1 = CommonCategoryUtils.getEipTCommonCategory(Long.valueOf(1));

      // change start
      // ScheduleMapに参加メンバーを追加する
      // for (ALEipUser user : form_data.getMemberList()) {
      // int userid = (int) user.getUserId().getValue();
      //
      // EipTScheduleMap map = Database.create(EipTScheduleMap.class);
      // map.setEipTSchedule(schedule);
      // map.setUserId(Integer.valueOf(userid));
      // // O: 自スケジュール T: 仮スケジュール C: 確定スケジュール
      // if (userid == ALEipUtils.getUserId(rundata)) {
      // map.setStatus("O");
      // } else {
      // map.setStatus("T");
      // }
      //
      // EipTCommonCategory category =
      // CommonCategoryUtils.getEipTCommonCategory(common_category_id
      // .getValue());
      // if (category == null) {
      // map.setCommonCategoryId(Integer.valueOf(1));
      // map.setEipTSchedule(schedule);
      // map.setEipTCommonCategory(category1);
      // } else {
      // map.setCommonCategoryId(Integer.valueOf((int) (common_category_id
      // .getValue())));
      // map.setEipTSchedule(schedule);
      // map.setEipTCommonCategory(category);
      // }
      // map.setType(ScheduleUtils.SCHEDULEMAP_TYPE_USER);
      // }

      // remove start
      // 施設は未使用のため削除
      // 公開スケジュールの場合は、グループに施設を追加する
      // boolean isFacility = false;
      // if ("O".equals(public_flag.getValue())) {
      // for (FacilityResultData frd : form_data.getFacilityMemberList()) {
      // isFacility = true;
      // int facilityid = (int) frd.getFacilityId().getValue();
      //
      // EipTScheduleMap map = Database.create(EipTScheduleMap.class);
      // map.setEipTSchedule(schedule);
      // map.setUserId(Integer.valueOf(facilityid));
      // // O: 自スケジュール T: 仮スケジュール C: 確定スケジュール
      // map.setStatus("O");
      // map.setType(ScheduleUtils.SCHEDULEMAP_TYPE_FACILITY);
      // map.setEipTCommonCategory(category1);
      // map.setCommonCategoryId(Integer.valueOf(1));
      // }
      // }
      // // 施設のアクセスコントロールのチェック
      // if (isFacility
      // && !facilityCheckAclPermission(
      // rundata,
      // ALAccessControlConstants.VALUE_ACL_INSERT)) {
      // msgList.add(" 施設を予約する権限がありません ");
      // return false;
      // }
      // remove end

      // 必須メンバーを登録
      createScheduleMapForNewSchedule(form_data.getMemberList(), ScheduleConst.SCHEDULEMAP_REQUIRED_T, schedule, category1, ownerid);
      // 任意メンバーを登録
      createScheduleMapForNewSchedule(form_data.getSubMemberList(), ScheduleConst.SCHEDULEMAP_REQUIRED_F, schedule, category1, ownerid);
      // change end
      Database.commit();

      // イベントログに保存
      ALEipUtils.setTemp(rundata, context, ALEipConstants.MODE, ALEipConstants.MODE_INSERT);
      ALEventlogFactoryService.getInstance().getEventlogHandler().log(schedule.getScheduleId(), ALEventlogConstants.PORTLET_TYPE_SCHEDULE, schedule.getName());

      // アクティビティ
      ALEipUser loginUser = getLoginUser();
      // List<ALEipUser> memberList = form_data.getMemberList();
      // add start
      memberList.addAll(form_data.getMemberList());
      memberList.addAll(form_data.getSubMemberList());
      // add end
      if (loginUser != null) {
        String loginName = loginUser.getName().getValue();
        List<String> recipients = new ArrayList<String>();
        for (ALEipUser user : memberList) {
          if (loginUser.getUserId().getValue() != user.getUserId().getValue()) {
            recipients.add(user.getName().getValue());
          }
        }
        ScheduleUtils.createShareScheduleActivity(schedule, loginName, recipients, true);
      }

    } catch (Exception e) {
      Database.rollback();
      // change start
      // logger.error("[CellScheduleFormData]", e);
      // throw new ALDBErrorException();
      logger.error("スケジュール作成（編集）の画面入力値取得に失敗しました。ログインユーザー:" + loginUser.getName().getValue(), e);
      msgList.add("スケジュール作成（編集）の画面入力値取得に失敗しました。");
      return false;
      // change end
    }

    // change start
    // スケジュールメール送信処理共通化
    // try {
    // // メール送信
    // int msgType =
    // ALMailUtils.getSendDestType(ALMailUtils.KEY_MSGTYPE_SCHEDULE);
    // if (msgType > 0) {
    // // パソコンへメールを送信
    // List<ALEipUserAddr> destMemberList =
    // ALMailUtils.getALEipUserAddrs(form_data.getMemberList(), ALEipUtils
    // .getUserId(rundata), false);
    // String subject = "[" + ALOrgUtilsService.getAlias() + "]スケジュール";
    // String org_id = ALOrgUtilsService.getAlias();
    //
    // // メール送信
    // List<ALAdminMailMessage> messageList =
    // new ArrayList<ALAdminMailMessage>();
    // for (ALEipUserAddr destMember : destMemberList) {
    // ALAdminMailMessage message = new ALAdminMailMessage(destMember);
    // message.setPcSubject(subject);
    // message.setCellularSubject(subject);
    // // change start
    // // message.setPcBody(ScheduleUtils.createMsgForPc(
    // // rundata,
    // // schedule,
    // // form_data.getMemberList()));
    // message.setPcBody(ScheduleUtils.createMsgForPc(ALEipUtils
    // .getUserId(rundata), schedule, form_data.getMemberList(), form_data
    // .getMemberList(), "追加しました。", rundata, false));
    // // change end
    // message.setCellularBody(ScheduleUtils.createMsgForCellPhone(
    // rundata,
    // schedule,
    // form_data.getMemberList(),
    // destMember.getUserId()));
    // messageList.add(message);
    // }
    //
    // ALMailService.sendAdminMail(new ALAdminMailContext(org_id, ALEipUtils
    // .getUserId(rundata), messageList, ALMailUtils
    // .getSendDestType(ALMailUtils.KEY_MSGTYPE_SCHEDULE)));
    // // msgList.addAll(errors);
    //
    // }
    // } catch (Exception ex) {
    // msgList.add("メールを送信できませんでした。");
    // logger.error("Exception", ex);
    // return false;
    // }
    // メール送信先
    // 参加メンバー（ログインユーザーを除く）を送信先にする

    List<ALEipUserAddr> sendToUserList = ALMailUtils.getALEipUserAddrs(memberList, ALEipUtils.getUserId(rundata), false);
    // メール送信実行
    if (!ScheduleUtils.sendScheduleMail(sendToUserList, schedule.getOwnerId(), schedule, form_data.getMemberList(), form_data.getSubMemberList(),
    // change start 要件No.1 スケジュール案内受信
      // "予定作成",
      ScheduleUtils.MEETING_CREATE,
      // change end
      "作成しました。",
      rundata,
      // add start 要件No.1 スケジュール案内受信
      "",
      ScheduleUtils.CREATE_MSG_MODE_REQ
    // add end
      )) {
      msgList.add("mailErrMsg=メールを送信できませんでした。entityId=" + schedule.getScheduleId());
      return false;
    }
    // change end
    return true;

  }

  /**
   * ** add start スケジュールの更新処理 ** add end
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * @throws ALPageNotFoundException
   * @throws ALDBErrorException
   */
  @SuppressWarnings("unchecked")
  @Override
  protected boolean updateFormData(RunData rundata, Context context, List<String> msgList) throws ALPageNotFoundException, ALDBErrorException {
    EipTSchedule schedule = null;
    // add start
    ArrayList<ALEipUser> newmemberList = new ArrayList<ALEipUser>();
    List<ALEipUser> memberList = new ArrayList<ALEipUser>();
    // add end

    // add start
    List<ALEipUser> removedMemberList = new ArrayList<ALEipUser>(0);
    boolean isSameSchedule = false;
    loginUser = getLoginUser();
    // add end
    try {

      // Validate のときに SELECT していることに注意する
      // 期間は時刻を0:00に固定
      if (isSpan()) {
        Calendar startDate = Calendar.getInstance();
        startDate.setTime(form_data.getStartDate().getValue());
        startDate.set(Calendar.HOUR_OF_DAY, 0);
        startDate.set(Calendar.MINUTE, 0);

        Calendar endDate = Calendar.getInstance();
        endDate.setTime(form_data.getEndDate().getValue());
        endDate.set(Calendar.HOUR_OF_DAY, 0);
        endDate.set(Calendar.MINUTE, 0);

        form_data.getStartDate().setValue(startDate.getTime());
        form_data.getEndDate().setValue(endDate.getTime());
      }
      // remove start
      // 期間スケジュール以外は画面のパラメータをそのまま使用
      // else {
      // Calendar startcal = new GregorianCalendar();
      // startcal.setTime(form_data.getStartDate().getValue());
      // Calendar endcal = Calendar.getInstance();
      // endcal.setTime(form_data.getEndDate().getValue());
      // endcal.set(Calendar.YEAR, startcal.get(Calendar.YEAR));
      // endcal.set(Calendar.MONTH, startcal.get(Calendar.MONTH));
      // endcal.set(Calendar.DATE, startcal.get(Calendar.DATE));
      // form_data.getEndDate().setValue(endcal.getTime());
      // }
      // remove end
      // オブジェクトモデルを取得
      schedule = ScheduleUtils.getEipTSchedule(rundata, context, false);
      if (schedule == null) {
        return false;
      }

      int ownerid = ALEipUtils.getUserId(rundata);

      // スケジュールのアップデート権限を検証する．
      if (ownerid != schedule.getOwnerId().intValue() && "F".equals(schedule.getEditFlag())) {
        // アップデート失敗時は、スケジュールの一覧を表示させる．
        return true;
      }
      // remove start
      // 施設は未使用のため削除
      // // 施設のアクセスコントロールのチェック
      // List<FacilityResultData> facilityList =
      // CellScheduleUtils.getShareFacilityMemberList(rundata);
      // if (!facilityCheckAclPermission(
      // rundata,
      // ALAccessControlConstants.VALUE_ACL_UPDATE)) {
      // int[] old_ids = ScheduleUtils.getFacilityIds(schedule);
      // if (old_ids.length != facilityList.size()) {
      // msgList.add(" 施設を予約する権限がありません ");
      // return false;
      // }
      // boolean check = false;
      // for (int old_id : old_ids) {
      // for (Object record : facilityList) {
      // FacilityResultData frd = (FacilityResultData) record;
      // int facilityid = (int) frd.getFacilityId().getValue();
      // if (old_id == facilityid) {
      // check = true;
      // break;
      // }
      // }
      // if (!check) {
      // msgList.add(" 施設を予約する権限がありません ");
      // return false;
      // }
      // check = false;
      // }
      // }

      // このスケジュールの共有カテゴリの取得
      // SelectQuery<EipTScheduleMap> mapquery =
      // Database.query(EipTScheduleMap.class);
      // Expression mapexp =
      // ExpressionFactory.matchExp(
      // EipTScheduleMap.SCHEDULE_ID_PROPERTY,
      // schedule.getScheduleId());
      // mapquery.setQualifier(mapexp);
      // List<EipTScheduleMap> list = mapquery.fetchList();
      // if (list != null && list.size() > 0) {
      // EipTScheduleMap map = list.get(0);
      // EipTCommonCategory category = map.getEipTCommonCategory();
      // if (category == null) {
      // common_category_id.setValue(1);
      // } else {
      // common_category_id.setValue(category
      // .getCommonCategoryId()
      // .longValue());
      // }
      // }

      // add start
      // 新たに追加されたメンバーのリストを取得
      // メンバーリスト
      memberList = new ArrayList<ALEipUser>();
      memberList.addAll(form_data.getMemberList());
      memberList.addAll(form_data.getSubMemberList());
      List<?> scheduleMapList = schedule.getEipTScheduleMaps();
      List<Integer> oldmemberIdList = new ArrayList<Integer>();
      for (Object record : scheduleMapList) {
        EipTScheduleMap map = (EipTScheduleMap) record;
        if (ScheduleUtils.SCHEDULEMAP_TYPE_USER.equals(map.getType())) {
          oldmemberIdList.add(map.getUserId());
        }
      }
      List<Integer> newmemberIdList = new ArrayList<Integer>();
      for (ALEipUser user : memberList) {
        int memberId = (int) user.getUserId().getValue();
        newmemberIdList.add(memberId);
        if (!isContains(oldmemberIdList, memberId)) {
          newmemberList.add(ALEipUtils.getALEipUser(memberId));
        }
      }
      // add end
      // add by motegi 2011.12.01
      // 今回メンバーから除外されたユーザーリスト取得
      for (Integer id : oldmemberIdList) {
        if (!isContains(newmemberIdList, id)) {
          removedMemberList.add(ALEipUtils.getALEipUser(id));
        }
      }
      // add end
      EipTCommonCategory category1 = CommonCategoryUtils.getEipTCommonCategory(Long.valueOf(1));

      // if (form_data.getEditRepeatFlag().getValue() ==
      // CellScheduleUtils.FLAG_EDIT_REPEAT_ONE) {
      // // 繰り返しスケジュールの個別日程を変更する．
      // // 新規オブジェクトモデル
      // EipTSchedule newSchedule = Database.create(EipTSchedule.class);
      // // 繰り返しの親スケジュール ID
      // newSchedule.setParentId(schedule.getScheduleId());
      // // 予定
      // newSchedule.setName(name.getValue());
      // // 場所
      // newSchedule.setPlace(place.getValue());
      // // 内容
      // newSchedule.setNote(note.getValue());
      // // 公開フラグ
      // newSchedule.setPublicFlag(public_flag.getValue());
      // // 共有メンバーによる編集／削除フラグ
      // newSchedule.setEditFlag("F");
      // // オーナーID
      // newSchedule.setOwnerId(Integer.valueOf(ownerid));
      // // 作成日
      // Date now = new Date();
      // newSchedule.setCreateDate(now);
      // newSchedule.setCreateUserId(Integer.valueOf(ownerid));
      // // 更新日
      // newSchedule.setUpdateDate(now);
      // newSchedule.setUpdateUserId(Integer.valueOf(ownerid));
      // // 終了日時
      // newSchedule.setEndDate(form_data.getEndDate().getValue());
      // newSchedule.setRepeatPattern("N");
      // newSchedule.setStartDate(form_data.getStartDate().getValue());
      //
      // int allsize =
      // form_data.getMemberList().size()
      // + form_data.getFacilityMemberList().size();
      // if (allsize > 0) {
      // List<EipTScheduleMap> scheduleMaps = schedule.getEipTScheduleMaps();
      // for (ALEipUser user : form_data.getMemberList()) {
      // int userid = (int) user.getUserId().getValue();
      //
      // EipTScheduleMap map = Database.create(EipTScheduleMap.class);
      // map.setEipTSchedule(newSchedule);
      // map.setUserId(Integer.valueOf(userid));
      //
      // // O: 自スケジュール T: 仮スケジュール C: 確定スケジュール
      // if (userid == ALEipUtils.getUserId(rundata)) {
      // map.setStatus("O");
      // } else {
      // if ("T".equals(form_data.getChangeTmpreserveFlag().getValue())) {
      // map.setStatus("T");
      // } else {
      // EipTScheduleMap tmpMap = getScheduleMap(scheduleMaps, userid);
      // if (tmpMap != null) {
      // map.setStatus(tmpMap.getStatus());
      // } else {
      // map.setStatus("T");
      // }
      // }
      // }
      // EipTCommonCategory category =
      // CommonCategoryUtils.getEipTCommonCategory(common_category_id
      // .getValue());
      // if (category == null) {
      // map.setCommonCategoryId(Integer.valueOf(1));
      // map.setEipTCommonCategory(category1);
      // } else {
      // map.setCommonCategoryId(Integer.valueOf((int) (common_category_id
      // .getValue())));
      // map.setEipTCommonCategory(category);
      // }
      // map.setType(ScheduleUtils.SCHEDULEMAP_TYPE_USER);
      // }
      //
      // // remove start
      // // // グループに施設を追加する．
      // // if ("O".equals(public_flag.getValue())) {
      // // for (FacilityResultData frd : form_data.getFacilityMemberList()) {
      // // int facilityid = (int) frd.getFacilityId().getValue();
      // //
      // // EipTScheduleMap map = Database.create(EipTScheduleMap.class);
      // // map.setEipTSchedule(newSchedule);
      // // map.setUserId(Integer.valueOf(facilityid));
      // // // O: 自スケジュール T: 仮スケジュール C: 確定スケジュール
      // // map.setStatus("O");
      // // map.setType(ScheduleUtils.SCHEDULEMAP_TYPE_FACILITY);
      // // map.setEipTCommonCategory(category1);
      // // map.setCommonCategoryId(Integer.valueOf(1));
      // // }
      // // }
      // // remove end
      // }
      //
      // // 登録されていたメンバーと今回追加されたメンバーのユーザー ID を取得する．
      // List<EipTScheduleMap> scheduleMaps = schedule.getEipTScheduleMaps();
      // List<Integer> memberIdList = new ArrayList<Integer>();
      // for (EipTScheduleMap map : scheduleMaps) {
      // memberIdList.add(map.getUserId());
      // }
      // int memberListSize = form_data.getMemberList().size();
      // for (int i = 0; i < memberListSize; i++) {
      // int memberId =
      // (int) form_data.getMemberList().get(i).getUserId().getValue();
      // if (!ScheduleUtils.isContains(memberIdList, memberId)) {
      // memberIdList.add(Integer.valueOf(memberId));
      // }
      // }
      // int memberIdListSize = memberIdList.size();
      // int[] memberIds = new int[memberIdListSize];
      // for (int i = 0; i < memberIdListSize; i++) {
      // memberIds[i] = memberIdList.get(i).intValue();
      // }
      // // ダミーのスケジュールを登録する．
      // ScheduleUtils.insertDummySchedule(schedule, ownerid, form_data
      // .getViewDate()
      // .getValue(), form_data.getViewDate().getValue(), memberIds);
      // } else {
      // // 予定
      // schedule.setName(name.getValue());
      // // 場所
      // schedule.setPlace(place.getValue());
      // // 内容
      // schedule.setNote(note.getValue());
      // // 公開フラグ
      // schedule.setPublicFlag(public_flag.getValue());
      // // 共有メンバーによる編集／削除フラグ
      // if (schedule.getOwnerId().intValue() == ALEipUtils.getUserId(rundata)
      // || schedule.getOwnerId().intValue() == 0) {
      // schedule.setEditFlag(form_data.getEditFlag().getValue());
      // }
      //
      // // スケジュールの所有ユーザがすでにメンバーから抜けているかを検証する．
      // int ownerUserId = schedule.getOwnerId().intValue();
      // boolean rejectOwnerUser = false;
      // List<EipTScheduleMap> tmpScheduleMaps = schedule.getEipTScheduleMaps();
      // for (EipTScheduleMap map : tmpScheduleMaps) {
      // if (ownerUserId == map.getUserId().intValue()
      // && "R".equals(map.getStatus())) {
      // rejectOwnerUser = true;
      // break;
      // }
      // }
      //
      // // 今回のアップデートでスケジュールの所有者がメンバーから抜けているかを検証する．
      // boolean includeOwnerUser = false;
      // for (ALEipUser eipUser : form_data.getMemberList()) {
      // if (ownerUserId == eipUser.getUserId().getValue()) {
      // includeOwnerUser = true;
      // break;
      // }
      // }
      // if (rejectOwnerUser || !includeOwnerUser) {
      // // スケジュールの登録ユーザがすでにメンバーから抜けている場合、
      // // 最後に更新した人のユーザ ID をオーナ ID に設定する．
      // schedule.setOwnerId(Integer.valueOf(ALEipUtils.getUserId(rundata)));
      // }
      //
      // // 更新日
      // schedule.setUpdateDate(new Date());
      // schedule
      // .setUpdateUserId(Integer.valueOf(ALEipUtils.getUserId(rundata)));
      //
      // String schedule_type = getScheduleType().getValue();
      // if (CellScheduleUtils.SCHEDULE_TYPE_SPAN.equals(schedule_type)) {
      // schedule.setStartDate(form_data.getStartDate().getValue());
      // schedule.setEndDate(form_data.getEndDate().getValue());
      // schedule.setRepeatPattern("S");
      // } else if
      // (CellScheduleUtils.SCHEDULE_TYPE_ONEDAY.equals(schedule_type)) {
      // schedule.setStartDate(form_data.getStartDate().getValue());
      // schedule.setEndDate(form_data.getEndDate().getValue());
      // schedule.setRepeatPattern("N");
      // } else {
      // char lim = 'N';
      // Calendar cal = Calendar.getInstance();
      // cal.setTime(form_data.getEndDate().getValue());
      // if ("ON".equals(form_data.getLimitFlag().getValue())) {
      // lim = 'L';
      // cal.set(form_data.getLimitEndDate().getValue().getYear(), form_data
      // .getLimitEndDate()
      // .getValue()
      // .getMonth() - 1, form_data.getLimitEndDate().getValue().getDay());
      //
      // ALDateContainer container =
      // form_data.getLimitStartDate().getValue();
      // Calendar limitStartCal = Calendar.getInstance();
      // limitStartCal.setTime(form_data.getStartDate().getValue());
      // limitStartCal.set(Calendar.YEAR, container.getYear());
      // limitStartCal.set(Calendar.MONTH, container.getMonth() - 1);
      // limitStartCal.set(Calendar.DATE, container.getDay());
      //
      // schedule.setStartDate(limitStartCal.getTime());
      // } else {
      // schedule.setStartDate(form_data.getStartDate().getValue());
      // }
      //
      // schedule.setEndDate(cal.getTime());
      // if ("D".equals(form_data.getRepeatType().getValue())) {
      // String tmpPattern =
      // new StringBuffer().append('D').append(lim).toString();
      // schedule.setRepeatPattern(tmpPattern);
      // } else if ("W".equals(form_data.getRepeatType().getValue())) {
      // String tmpPattern =
      // new StringBuffer()
      // .append('W')
      // .append(form_data.getWeek0().getValue() != null ? 1 : 0)
      // .append(form_data.getWeek1().getValue() != null ? 1 : 0)
      // .append(form_data.getWeek2().getValue() != null ? 1 : 0)
      // .append(form_data.getWeek3().getValue() != null ? 1 : 0)
      // .append(form_data.getWeek4().getValue() != null ? 1 : 0)
      // .append(form_data.getWeek5().getValue() != null ? 1 : 0)
      // .append(form_data.getWeek6().getValue() != null ? 1 : 0)
      // .append(lim)
      // .toString();
      // schedule.setRepeatPattern(tmpPattern);
      // } else {
      // DecimalFormat format = new DecimalFormat("00");
      // schedule.setRepeatPattern(new StringBuffer()
      // .append('M')
      // .append(format.format(form_data.getMonthDay().getValue()))
      // .append(lim)
      // .toString());
      // }
      // }
      //
      // SelectQuery<EipTScheduleMap> query =
      // Database.query(EipTScheduleMap.class);
      // Expression exp =
      // ExpressionFactory.matchExp(
      // EipTScheduleMap.SCHEDULE_ID_PROPERTY,
      // schedule.getScheduleId());
      // query.setQualifier(exp);
      // List<EipTScheduleMap> schedulemaps = query.fetchList();
      // Database.deleteAll(schedulemaps);
      //
      // for (ALEipUser user : form_data.getMemberList()) {
      // int userid = (int) user.getUserId().getValue();
      //
      // EipTScheduleMap map = Database.create(EipTScheduleMap.class);
      // map.setEipTSchedule(schedule);
      // map.setUserId(Integer.valueOf(userid));
      // // O: 自スケジュール T: 仮スケジュール C: 確定スケジュール
      // if (userid == schedule.getOwnerId().intValue()) {
      // map.setStatus("O");
      // } else {
      // if ("T".equals(form_data.getChangeTmpreserveFlag().getValue())) {
      // map.setStatus("T");
      // } else {
      // EipTScheduleMap tmpMap = getScheduleMap(schedulemaps, userid);
      // if (tmpMap != null) {
      // map.setStatus(tmpMap.getStatus());
      // } else {
      // map.setStatus("T");
      // }
      // }
      // }
      //
      // EipTCommonCategory category =
      // CommonCategoryUtils.getEipTCommonCategory(common_category_id
      // .getValue());
      // if (category == null) {
      // map.setCommonCategoryId(Integer.valueOf(1));
      // map.setEipTSchedule(schedule);
      // map.setEipTCommonCategory(category1);
      // } else {
      // map.setCommonCategoryId(Integer.valueOf((int) (common_category_id
      // .getValue())));
      // map.setEipTSchedule(schedule);
      // map.setEipTCommonCategory(category);
      // }
      // map.setType(ScheduleUtils.SCHEDULEMAP_TYPE_USER);
      // }
      //
      // if ("O".equals(public_flag.getValue())) {
      // for (FacilityResultData frd : form_data.getFacilityMemberList()) {
      // int facilityid = (int) frd.getFacilityId().getValue();
      //
      // EipTScheduleMap map = Database.create(EipTScheduleMap.class);
      // map.setEipTSchedule(schedule);
      // map.setUserId(Integer.valueOf(facilityid));
      // map.setStatus("O");
      // map.setType(ScheduleUtils.SCHEDULEMAP_TYPE_FACILITY);
      // map.setEipTCommonCategory(category1);
      // map.setCommonCategoryId(Integer.valueOf(1));
      // }
      // }
      // }
      //

      // add start
      // 回答状態引き継ぎ判定用
      // 修正前開始日時の取得
      Date oldStartDate = schedule.getStartDate();
      // 修正前終了日時の取得
      Date oldEndDate = schedule.getEndDate();
      // 修正前予定名の取得
      String oldName = schedule.getName();
      // 修正前場所の取得
      String oldPlace = schedule.getPlace();
      // 修正前内容の取得
      String oldNote = schedule.getNote();
      // 修正前内容の取得
      String oldRepeatPattern = schedule.getRepeatPattern();
      // 修正前公開フラグの取得
      String oldPublicFlag = schedule.getPublicFlag();
      // 修正前公開フラグの取得
      Integer oldRepeatNum = schedule.getRepeatNum();

      // 入力値をDB項目へ変換
      convertInputParamToSchedule(schedule);

      // add start 2011.12.10
      isSameSchedule =
        schedule.getStartDate().getTime() == oldStartDate.getTime()
          && schedule.getEndDate().getTime() == oldEndDate.getTime()
          && isSameValue(schedule.getName(), oldName)
          && isSameValue(schedule.getPlace(), oldPlace)
          && isSameValue(schedule.getNote(), oldNote)
          && isSameValue(schedule.getRepeatPattern(), oldRepeatPattern)
          && isSameValue(schedule.getPublicFlag(), oldPublicFlag)
          && isSameValue(oldRepeatNum, schedule.getRepeatNum());

      // add end

      // オーナーIDを取得
      int ownerUserId = schedule.getOwnerId().intValue();
      // 更新日
      schedule.setUpdateDate(new Date());
      schedule.setUpdateUserId(Integer.valueOf(ALEipUtils.getUserId(rundata)));
      List<?> scheduleMaps = schedule.getEipTScheduleMaps();

      Database.deleteAll(scheduleMaps);
      // 日付・時刻変更判定：変更がない場合、回答状態を引き継ぐ
      boolean isSuccession = schedule.getStartDate().getTime() == oldStartDate.getTime() && schedule.getEndDate().getTime() == oldEndDate.getTime();

      // 必須メンバー登録
      createScheduleMapForUpdateSchedule(
        form_data.getMemberList(),
        ScheduleConst.SCHEDULEMAP_REQUIRED_T,
        schedule,
        category1,
        ownerUserId,
        scheduleMaps,
        isSuccession);

      // 任意メンバー登録
      createScheduleMapForUpdateSchedule(
        form_data.getSubMemberList(),
        ScheduleConst.SCHEDULEMAP_REQUIRED_F,
        schedule,
        category1,
        ownerUserId,
        scheduleMaps,
        isSuccession);
      // add end
      Database.commit();

      // イベントログに保存
      ALEipUtils.setTemp(rundata, context, ALEipConstants.MODE, ALEipConstants.MODE_UPDATE);
      ALEventlogFactoryService.getInstance().getEventlogHandler().log(schedule.getScheduleId(), ALEventlogConstants.PORTLET_TYPE_SCHEDULE, schedule.getName());

      // アクティビティ
      ALEipUser loginUser = getLoginUser();
      // remove start
      // List<ALEipUser> memberList = form_data.getMemberList();
      // remove start
      if (loginUser != null) {
        String loginName = loginUser.getName().getValue();
        List<String> recipients = new ArrayList<String>();
        for (ALEipUser user : memberList) {
          if (loginUser.getUserId().getValue() != user.getUserId().getValue()) {
            recipients.add(user.getName().getValue());
          }
        }
        ScheduleUtils.createShareScheduleActivity(schedule, loginName, recipients, false);
      }

    } catch (Exception e) {
      Database.rollback();
      // change start
      // logger.error("[ScheduleFormData]", e);
      // throw new ALDBErrorException();
      logger.error("スケジュールの更新に失敗しました。ログインユーザー:" + loginUser.getName().getValue(), e);
      msgList.add("スケジュールの更新に失敗しました。");
      return false;
      // change end
    }

    // change start
    // try {
    // // メール送信
    // int msgType =
    // ALMailUtils.getSendDestType(ALMailUtils.KEY_MSGTYPE_SCHEDULE);
    // if (msgType > 0) {
    // // パソコンへメールを送信
    // List<ALEipUserAddr> destMemberList =
    // ALMailUtils.getALEipUserAddrs(form_data.getMemberList(), ALEipUtils
    // .getUserId(rundata), false);
    // String subject = "[" + ALOrgUtilsService.getAlias() + "]スケジュール";
    // String org_id = ALOrgUtilsService.getAlias();
    //
    // List<ALAdminMailMessage> messageList =
    // new ArrayList<ALAdminMailMessage>();
    // for (ALEipUserAddr destMember : destMemberList) {
    // ALAdminMailMessage message = new ALAdminMailMessage(destMember);
    // message.setPcSubject(subject);
    // message.setCellularSubject(subject);
    // // change start
    // // message.setPcBody(ScheduleUtils.createMsgForPc(rundata, schedule,
    // // form_data.getMemberList()));
    // message.setPcBody(ScheduleUtils.createMsgForPc(ALEipUtils
    // .getUserId(rundata), schedule, form_data.getMemberList(), form_data
    // .getMemberList(), "変更しました。", rundata, false));
    // // change end
    // message.setCellularBody(ScheduleUtils.createMsgForCellPhone(
    // rundata,
    // schedule,
    // form_data.getMemberList(),
    // destMember.getUserId()));
    // messageList.add(message);
    // }
    //
    // ALMailService.sendAdminMail(new ALAdminMailContext(org_id, ALEipUtils
    // .getUserId(rundata), messageList, ALMailUtils
    // .getSendDestType(ALMailUtils.KEY_MSGTYPE_SCHEDULE)));
    // // msgList.addAll(errors);
    //
    // }
    // } catch (Exception ex) {
    // msgList.add("メールを送信できませんでした。");
    // logger.error("Exception", ex);
    // return false;
    // }
    if (!isSameSchedule) {
      // スケジュール内容に変更があった場合は、メンバー全員にメールを送信
      List<ALEipUserAddr> sendToUserList = ALMailUtils.getALEipUserAddrs(memberList, ALEipUtils.getUserId(rundata), false);
      // メール送信実行
      if (!ScheduleUtils.sendScheduleMail(sendToUserList, schedule.getOwnerId(), schedule, form_data.getMemberList(), form_data.getSubMemberList(),
      // change start 要件No.1 スケジュール案内受信
        // "予定変更",
        ScheduleUtils.MEETING_UPDATE,
        // change end
        "変更しました。",
        rundata,
        // add start 要件No.1 スケジュール案内受信
        "",
        ScheduleUtils.CREATE_MSG_MODE_REQ
      // add end
        )) {
        msgList.add("mailErrMsg=メールを送信できませんでした。entityId=" + schedule.getScheduleId());
        return false;
      }
    } else {
      // スケジュール内容に変更がない場合は、新規追加メンバーにメール送信
      // 後の処理で、削除されたメンバーへメールを送信する。

      // メール送信先
      // 参加メンバー（ログインユーザーを除く）を送信先にする
      List<ALEipUserAddr> sendToUserList = ALMailUtils.getALEipUserAddrs(newmemberList, ALEipUtils.getUserId(rundata), false);

      if (!ScheduleUtils.sendScheduleMail(sendToUserList, schedule.getOwnerId(), schedule, form_data.getMemberList(), form_data.getSubMemberList(),
      // change start 要件No.1 スケジュール案内受信
        // "予定作成",
        ScheduleUtils.MEETING_CREATE,
        // change end
        "作成しました。",
        rundata,
        // add start 要件No.1 スケジュール案内受信
        "",
        ScheduleUtils.CREATE_MSG_MODE_REQ
      // add end
        )) {
        msgList.add("mailErrMsg=メールを送信できませんでした。entityId=" + schedule.getScheduleId());
        return false;
      }
    }

    if (removedMemberList.size() > 0) {

      // 今回更新でメンバーから除外されたユーザーに通知
      // スケジュール内容の変更有無に関わらず送信

      List<ALEipUserAddr> sendToRemovedUserAddrList = ALMailUtils.getALEipUserAddrs(removedMemberList, (int) loginUser.getUserId().getValue(), false);

      if (!ScheduleUtils.sendScheduleMail(sendToRemovedUserAddrList, (int) loginUser.getUserId().getValue(), schedule.getOwnerId(), schedule, form_data
        .getMemberList(), form_data.getSubMemberList(),
      // change start 要件No.1 スケジュール案内受信
        // "予定削除",
        ScheduleUtils.MEETING_DELETE,
        // change end
        "削除しました。",
        rundata,
        true,
        // add start 要件No.1 スケジュール案内受信
        "",
        ScheduleUtils.CREATE_MSG_MODE_REQ
      // add end
        )) {
        msgList.add("mailErrMsg=メールを送信できませんでした。entityId=" + schedule.getScheduleId());
        return false;
      }
    }

    // change end
    return true;

  }

  // change start
  // private EipTScheduleMap getScheduleMap(List<EipTScheduleMap> scheduleMaps,
  // int userid) {
  // for (EipTScheduleMap map : scheduleMaps) {
  // if (map.getUserId().intValue() == userid) {
  // return map;
  // }
  // }
  // return null;
  // }
  /**
   * 引き継ぎスケジュールマップ取得
   * 
   * @param scheduleMaps
   *          抽出対象のスケジュールマップ一覧
   * @param userid
   *          抽出条件のユーザーID
   * @param type
   *          抽出条件のユーザー/施設
   * @return ユーザーID、必須フラグ、ユーザー/施設が一致するスケジュールマップ。一致するものがない場合null。
   */
  private EipTScheduleMap getScheduleMap(List<?> scheduleMaps, int userid, String type) {
    for (Object record : scheduleMaps) {
      EipTScheduleMap map = (EipTScheduleMap) record;
      if (map.getUserId().intValue() == userid && type.equals(map.getType())) {
        return map;
      }
    }
    return null;
  }

  // change end
  /**
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * @throws ALPageNotFoundException
   * @throws ALDBErrorException
   */
  @Override
  protected boolean deleteFormData(RunData rundata, Context context, List<String> msgList) throws ALPageNotFoundException, ALDBErrorException {
    try {
      // パラメータを取得する．
      if (rundata.getParameters().containsKey("del_flag")) {
        del_flag.setValue(rundata.getParameters().getString("del_flag"));
      }
      // パラメータの設定
      if (del_flag.getValue() == 1) {
        del_member_flag.setValue(0);
        del_range_flag.setValue(1);
      } else if (del_flag.getValue() == 2) {
        del_member_flag.setValue(1);
        del_range_flag.setValue(0);
      } else if (del_flag.getValue() == 3) {
        del_member_flag.setValue(1);
        del_range_flag.setValue(1);
      } else {
        // del_flag.getValue() == 0 の場合
        del_member_flag.setValue(0);
        del_range_flag.setValue(0);
      }

      // オブジェクトモデルを取得
      EipTSchedule schedule = ScheduleUtils.getEipTSchedule(rundata, context, false);
      if (schedule == null) {
        return false;
      }

      // 共有メンバーを取得する．
      List<ALEipUser> members = ScheduleUtils.getUsers(rundata, context, true);
      if (members != null && members.size() > 0) {
        form_data.getMemberList().addAll(members);
      }
      // 削除権限を検証する．
      boolean isMember = false;
      int loginuserId = (int) getLoginUser().getUserId().getValue();
      int membersSize = form_data.getMemberList().size();
      ALEipUser eipUser = null;
      for (int i = 0; i < membersSize; i++) {
        eipUser = form_data.getMemberList().get(i);
        if (loginuserId == eipUser.getUserId().getValue()) {
          isMember = true;
          break;
        }
      }
      if (!isMember) {
        logger.error("[ScheduleFormData] ALPageNotFoundException: The user does not have the auth to delete the schedule.");
        throw new ALPageNotFoundException();
      }

      if (loginuserId != schedule.getOwnerId().intValue()
        && "F".equals(schedule.getEditFlag())
        && CellScheduleUtils.FLAG_DEL_MEMBER_ONE != del_member_flag.getValue()) {
        // del_member_flag.setValue(FLAG_DEL_MEMBER_ONE);
        return true;
      }

      int delFlag = -1;
      if (del_member_flag.getValue() == CellScheduleUtils.FLAG_DEL_MEMBER_ALL) {
        if (del_range_flag.getValue() == CellScheduleUtils.FLAG_DEL_RANGE_ALL) {
          delFlag = 0;
        } else {
          // del_range_flag.getValue() == FLAG_DEL_RANGE_ONE
          delFlag = 1;
        }
      } else {
        // del_member_flag.getValue() == FLAG_DEL_MEMBER_ONE
        // EIP_M_SCHEDULE_MAP の STATUS のみ変更する．
        if (del_range_flag.getValue() == CellScheduleUtils.FLAG_DEL_RANGE_ALL) {
          delFlag = 2;
        } else {
          // del_range_flag.getValue() == FLAG_DEL_RANGE_ONE
          delFlag = 3;
        }
      }

      if (delFlag == 0) {
        deleteSchedule(schedule);
      } else if (delFlag == 1) {
        if (!"N".equals(schedule.getRepeatPattern())) {
          int ownerid = ALEipUtils.getUserId(rundata);
          // ダミーのスケジュールを登録する．
          int memberIdListSize = form_data.getMemberList().size();
          int[] memberIdList = new int[memberIdListSize];
          for (int i = 0; i < memberIdListSize; i++) {
            memberIdList[i] = (int) form_data.getMemberList().get(i).getUserId().getValue();
          }
          ScheduleUtils.insertDummySchedule(schedule, ownerid, form_data.getViewDate().getValue(), form_data.getViewDate().getValue(), memberIdList);
        }
      } else if (delFlag == 2) {
        List<EipTScheduleMap> scheduleMaps = ScheduleUtils.getEipTScheduleMaps(schedule);
        if (scheduleMaps != null && scheduleMaps.size() > 0) {
          int rejectedScheduleCount = 0;
          List<EipTScheduleMap> userScheduleMap = new ArrayList<EipTScheduleMap>();
          for (EipTScheduleMap scheduleMap : scheduleMaps) {
            if (ScheduleUtils.SCHEDULEMAP_TYPE_USER.equals(scheduleMap.getType())) {
              userScheduleMap.add(scheduleMap);
              if ("R".equals(scheduleMap.getStatus())) {
                rejectedScheduleCount++;
              }
            }
          }
          int scheduleUserCount = userScheduleMap.size();

          if (rejectedScheduleCount >= scheduleUserCount - 1) {
            // この schedule ID のスケジュールを, ユーザが全員予定を削除したため，
            // 親スケジュールごと削除する．
            deleteSchedule(schedule);
          } else {
            for (EipTScheduleMap scheduleMap : userScheduleMap) {
              if (scheduleMap.getUserId().intValue() == getLoginUser().getUserId().getValue()) {
                if ((scheduleMap.getUserId().intValue() == getLoginUser().getUserId().getValue())
                  || (schedule.getCreateUserId().intValue() == getLoginUser().getUserId().getValue())) {
                  if ("O".equals(scheduleMap.getStatus())) {
                    schedule.setOwnerId(Integer.valueOf(0));
                    if ("F".equals(schedule.getEditFlag())) {
                      // 削除するユーザーが，スケジュールの登録者であり，
                      // かつ，そのスケジュールの編集権限が他の共有メンバーに与えられていないときには，
                      // そのスケジュールの編集権限を 'T' に設定する．
                      schedule.setEditFlag("T");
                    }
                  }
                  scheduleMap.setStatus("R");
                }
              }
            }
          }
        }

      } else if (delFlag == 3) {
        if (!"N".equals(schedule.getRepeatPattern())) {
          int ownerid = ALEipUtils.getUserId(rundata);
          // 共有メンバーとしてログインユーザのみ設定する．
          form_data.getMemberList().clear();
          form_data.getMemberList().add(getLoginUser());
          // ダミーのスケジュールを登録する．
          int memberIdListSize = form_data.getMemberList().size();
          int[] memberIdList = new int[memberIdListSize];
          for (int i = 0; i < memberIdListSize; i++) {
            memberIdList[i] = (int) form_data.getMemberList().get(i).getUserId().getValue();
          }
          ScheduleUtils.insertDummySchedule(schedule, ownerid, form_data.getViewDate().getValue(), form_data.getViewDate().getValue(), memberIdList);
        }
      } else {
        Database.delete(schedule);
      }

      Database.commit();

      // イベントログに保存
      ALEipUtils.setTemp(rundata, context, ALEipConstants.MODE, ALEipConstants.MODE_DELETE);
      ALEventlogFactoryService.getInstance().getEventlogHandler().log(schedule.getScheduleId(), ALEventlogConstants.PORTLET_TYPE_SCHEDULE, schedule.getName());

    } catch (Exception e) {
      Database.rollback();
      logger.error("[ScheduleFormData]", e);
      throw new ALDBErrorException();

    }
    return true;
  }

  /**
   * 指定したスケジュールを削除する．
   * 
   * @param schedule
   */
  private void deleteSchedule(EipTSchedule schedule) {
    int scheduleId = schedule.getScheduleId().intValue();
    // orm_schedule.doDelete(schedule);
    Database.delete(schedule);

    // ダミースケジュールの取得
    SelectQuery<EipTSchedule> query = Database.query(EipTSchedule.class);
    Expression exp1 = ExpressionFactory.matchExp(EipTSchedule.PARENT_ID_PROPERTY, Integer.valueOf(scheduleId));
    query.setQualifier(exp1);
    Expression exp2 = ExpressionFactory.matchExp(EipTSchedule.EIP_TSCHEDULE_MAPS_PROPERTY + "." + EipTScheduleMap.STATUS_PROPERTY, "D");
    query.andQualifier(exp2);
    List<EipTSchedule> dellist = query.fetchList();
    // ダミースケジュールの削除
    if (dellist != null && dellist.size() > 0) {
      Database.deleteAll(dellist);
    }
  }

  // remove start
  // /**
  // * Facilityのアクセス権限をチェック
  // *
  // * @param rundata
  // * @param aclType
  // * @return
  // */
  // private boolean facilityCheckAclPermission(RunData rundata, int aclType) {
  // ALAccessControlFactoryService aclservice =
  // (ALAccessControlFactoryService) ((TurbineServices) TurbineServices
  // .getInstance()).getService(ALAccessControlFactoryService.SERVICE_NAME);
  // ALAccessControlHandler aclhandler = aclservice.getAccessControlHandler();
  //
  // hasAuthority =
  // aclhandler.hasAuthority(
  // ALEipUtils.getUserId(rundata),
  // ALAccessControlConstants.POERTLET_FEATURE_SCHEDULE_FACILITY,
  // aclType);
  // return hasAuthority;
  // }

  // remove end
  /**
   * 予定を取得します。
   * 
   * @return
   */
  public ALStringField getName() {
    return name;
  }

  /**
   * 内容を取得します。
   * 
   * @return
   */
  public ALStringField getNote() {
    return note;
  }

  /**
   * 場所を取得します。
   * 
   * @return
   */
  public ALStringField getPlace() {
    return place;
  }

  /**
   * 公開/非公開フラグを取得します。
   * 
   * @return
   */
  public ALStringField getPublicFlag() {
    return public_flag;
  }

  /**
   * グループリストを取得します。
   * 
   * @return
   */
  @Override
  public List<ALEipGroup> getGroupList() {
    return groups;
  }

  // add start
  /**
   * 入力値DB項目変換処理[AIPO_COM_PC_001_53]
   * 
   * @param schedule
   *          変換先スケジュールエンティティ
   * @throws ALPageNotFoundException
   *           有効期限の日付変換に失敗した場合
   */
  private void convertInputParamToSchedule(EipTSchedule schedule) throws ALPageNotFoundException {

    // 予定
    schedule.setName(name.getValue());
    // 場所
    schedule.setPlace(place.getValue());
    // 内容
    schedule.setNote(note.getValue());
    // 公開フラグ
    schedule.setPublicFlag(public_flag.getValue());
    // 共有メンバーによる編集／削除フラグ
    // 不可固定
    schedule.setEditFlag("F");

    // 日時パターン別項目
    if (isSpan()) {
      // 期間予定
      schedule.setStartDate(form_data.getStartDate().getValue());
      schedule.setEndDate(form_data.getEndDate().getValue());
      schedule.setRepeatPattern(ScheduleConst.SCHEDULE_PATTERN_SPAN);
    } else if (isCrossOver()) {
      // 日またぎ予定
      schedule.setStartDate(form_data.getStartDate().getValue());
      schedule.setEndDate(form_data.getEndDate().getValue());
      schedule.setRepeatPattern(ScheduleConst.SCHEDULE_PATTERN_DAYS);
    } else if (isOneday()) {
      // 単発予定
      schedule.setStartDate(form_data.getStartDate().getValue());
      schedule.setEndDate(form_data.getEndDate().getValue());
      schedule.setRepeatPattern(ScheduleConst.SCHEDULE_PATTERN_ONEDAY);
    } else {
      // 繰り返し予定

      try {

        // 終了日未定値
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
        Date lastDate = df.parse(ScheduleConst.SCHEDULE_LIMIT_ENDDATE_NONEND);

        // 有効期限開始日時
        ALDateContainer container = form_data.getLimitStartDate().getValue();
        Calendar limitStartCal = Calendar.getInstance();
        // 開始時刻を設定
        limitStartCal.setTime(form_data.getStartDate().getValue());
        // 開始年月日を設定
        limitStartCal.set(Calendar.YEAR, container.getYear());
        limitStartCal.set(Calendar.MONTH, container.getMonth() - 1);
        limitStartCal.set(Calendar.DATE, container.getDay());
        schedule.setStartDate(limitStartCal.getTime());

        // 反復回数終了日
        Calendar nOfTEndCal = Calendar.getInstance();
        // 初期値に有効期限開始日を設定する
        nOfTEndCal.set(Calendar.YEAR, container.getYear());
        nOfTEndCal.set(Calendar.MONTH, container.getMonth() - 1);
        nOfTEndCal.set(Calendar.DATE, container.getDay());
        nOfTEndCal.set(Calendar.HOUR_OF_DAY, 0);
        nOfTEndCal.set(Calendar.MINUTE, 0);
        nOfTEndCal.set(Calendar.SECOND, 0);
        nOfTEndCal.set(Calendar.MILLISECOND, 0);

        // 繰り返しパターン設定
        ALCellStringField repeat_type = CellScheduleUtils.getRepeatTypeForValidate(form_data.getRepeatType().getValue());
        if (ScheduleConst.REPEAT_TYPE_DAY.equals(repeat_type.getValue())) {

          // 日パターン
          String pattern = "000" + form_data.getDayInterval().getValueAsString();
          schedule.setRepeatPattern(ScheduleConst.SCHEDULE_PATTERN_DAILY
            + pattern.substring(pattern.length() - 3, pattern.length())
            + ScheduleConst.SCHEDULE_PATTERN_TERMINATION);

          // 有効期限終了パターンが反復回数の場合、日ベースで終了日を算出する
          if (ScheduleConst.LIMIT_TYPE_NOFT.equals(form_data.getLimitFlag().getValue())) {
            // 反復回数 - 1回分、日間隔を加算する
            for (long i = 1L; i < form_data.getRepeatNum().getValue(); i++) {
              nOfTEndCal.add(Calendar.DAY_OF_MONTH, (int) form_data.getDayInterval().getValue());
            }
          }

        } else if (ScheduleConst.REPEAT_TYPE_WEEK.equals(repeat_type.getValue())) {

          // 週パターン
          String pattern = "00" + form_data.getWeekInterval().getValueAsString();
          String dowFlag = "";
          for (String status : getCheckedWeekDoW()) {
            dowFlag += ScheduleConst.DOW_CHECKED.equals(status) ? "1" : "0";
          }
          schedule.setRepeatPattern(ScheduleConst.SCHEDULE_PATTERN_WEEKLY
            + pattern.substring(pattern.length() - 2, pattern.length())
            + dowFlag
            + ScheduleConst.SCHEDULE_PATTERN_TERMINATION);

          // 有効期限終了パターンが反復回数の場合、週ベースで終了日を算出する
          if (ScheduleConst.LIMIT_TYPE_NOFT.equals(form_data.getLimitFlag().getValue())) {
            // 週初日を仮指定
            nOfTEndCal.set(Calendar.DAY_OF_WEEK, 1);
            // 反復回数 - 1回分、週間隔を加算する
            for (long i = 1L; i < form_data.getRepeatNum().getValue(); i++) {
              nOfTEndCal.add(Calendar.WEEK_OF_MONTH, (int) form_data.getWeekInterval().getValue());
            }
            // 週末日を指定する
            nOfTEndCal.set(Calendar.DAY_OF_WEEK, nOfTEndCal.getActualMaximum(Calendar.DAY_OF_WEEK));
          }

        } else if (ScheduleConst.REPEAT_TYPE_MONTH.equals(repeat_type.getValue())) {

          int monthInterval = 0;

          ALCellStringField month_type = CellScheduleUtils.getMonthTypeForValidate(form_data.getRepeatType().getValue());
          // 月パターン
          if (ScheduleConst.MONTH_TYPE_MD.equals(month_type.getValue())) {

            // xヶ月ごとの dd日に設定 CxxddL
            String pattern1 = "00" + form_data.getMdMonthInterval().getValueAsString();
            String pattern2 = "00" + form_data.getMdDay().getValueAsString();
            schedule.setRepeatPattern(ScheduleConst.SCHEDULE_PATTERN_MONTHLY_DAY
              + pattern1.substring(pattern1.length() - 2, pattern1.length())
              + pattern2.substring(pattern2.length() - 2, pattern2.length())
              + ScheduleConst.SCHEDULE_PATTERN_TERMINATION);

            monthInterval = (int) form_data.getMdMonthInterval().getValue();

          } else if (ScheduleConst.MONTH_TYPE_MW.equals(month_type.getValue())) {

            // Xヶ月ごとの 第Y Z曜日に設定 ExxWyzN
            String pattern = "00" + form_data.getMwMonthInterval().getValueAsString();
            schedule.setRepeatPattern(ScheduleConst.SCHEDULE_PATTERN_MONTHLY_WEEK
              + pattern.substring(pattern.length() - 2, pattern.length())
              + "W"
              + form_data.getMwCount().getValueAsString()
              + form_data.getMwDoW().getValue()
              + ScheduleConst.SCHEDULE_PATTERN_TERMINATION);

            monthInterval = (int) form_data.getMwMonthInterval().getValue();

          }

          // 有効期限終了パターンが反復回数の場合、月ベースで終了日を算出する
          if (ScheduleConst.LIMIT_TYPE_NOFT.equals(form_data.getLimitFlag().getValue())) {
            // 月初日を仮指定
            nOfTEndCal.set(Calendar.DAY_OF_MONTH, 1);
            // 反復回数 - 1回分、月間隔を加算する
            for (long i = 1L; i < form_data.getRepeatNum().getValue(); i++) {
              nOfTEndCal.add(Calendar.MONTH, monthInterval);
            }
            // 月末日を指定する
            nOfTEndCal.set(Calendar.DAY_OF_MONTH, nOfTEndCal.getActualMaximum(Calendar.DAY_OF_MONTH));
          }

        } else if (ScheduleConst.REPEAT_TYPE_YEAR.equals(repeat_type.getValue())) {

          ALCellStringField year_type = CellScheduleUtils.getYearTypeForValidate(form_data.getRepeatType().getValue());
          if (ScheduleConst.YEAR_TYPE_MD.equals(year_type.getValue())) {

            // X月Y日に設定 FmmddL
            String pattern1 = "00" + form_data.getYmdMonth().getValueAsString();
            String pattern2 = "00" + form_data.getYmdDay().getValueAsString();
            schedule.setRepeatPattern(ScheduleConst.SCHEDULE_PATTERN_YEARLY_DAY
              + pattern1.substring(pattern1.length() - 2, pattern1.length())
              + pattern2.substring(pattern2.length() - 2, pattern2.length())
              + ScheduleConst.SCHEDULE_PATTERN_TERMINATION);

          } else if (ScheduleConst.YEAR_TYPE_MW.equals(year_type.getValue())) {

            // X月第Y Z曜日に設定 GmmWyzL
            String pattern = "00" + form_data.getYmwMonth().getValueAsString();
            schedule.setRepeatPattern(ScheduleConst.SCHEDULE_PATTERN_YEARLY_WEEK
              + pattern.substring(pattern.length() - 2, pattern.length())
              + "W"
              + form_data.getYmwCount().getValueAsString()
              + form_data.getYmwDoW().getValue()
              + ScheduleConst.SCHEDULE_PATTERN_TERMINATION);

          }

          // 有効期限終了パターンが反復回数の場合、年ベースで終了日を算出する
          if (ScheduleConst.LIMIT_TYPE_NOFT.equals(form_data.getLimitFlag().getValue())) {
            // 反復回数 - 1回の年数を加算
            nOfTEndCal.add(Calendar.YEAR, (int) (form_data.getRepeatNum().getValue() - 1L));
            // 年末日を設定
            nOfTEndCal.set(Calendar.DAY_OF_YEAR, nOfTEndCal.getActualMaximum(Calendar.DAY_OF_YEAR));
          }

        }

        // 有効期限終了日時
        Calendar limitEndCal = Calendar.getInstance();

        // 終了時刻を設定
        limitEndCal.setTime(form_data.getEndDate().getValue());
        Calendar limitEndYmdCal = Calendar.getInstance();
        if (ScheduleConst.LIMIT_TYPE_NONEND.equals(form_data.getLimitFlag().getValue())) {

          // 終了日なし
          limitEndYmdCal.setTime(lastDate);
          schedule.setRepeatNum(null);

        } else if (ScheduleConst.LIMIT_TYPE_NOFT.equals(form_data.getLimitFlag().getValue())) {

          // 反復回数
          if (lastDate.before(nOfTEndCal.getTime())) {
            // 反復回数の計算結果が終了日未定日付を超えた場合は、終了日未定日付を設定する
            limitEndYmdCal.setTime(lastDate);
          } else {
            limitEndYmdCal.setTime(nOfTEndCal.getTime());
          }
          schedule.setRepeatNum((int) form_data.getRepeatNum().getValue());

        } else if (ScheduleConst.LIMIT_TYPE_DATE.equals(form_data.getLimitFlag().getValue())) {

          // 終了日
          ALDateContainer endYmdContainer = form_data.getLimitEndDate().getValue();
          limitEndYmdCal.setTime(endYmdContainer.getDate());
          schedule.setRepeatNum(null);

        }
        limitEndCal.set(Calendar.YEAR, limitEndYmdCal.get(Calendar.YEAR));
        limitEndCal.set(Calendar.MONTH, limitEndYmdCal.get(Calendar.MONTH));
        limitEndCal.set(Calendar.DATE, limitEndYmdCal.get(Calendar.DATE));
        schedule.setEndDate(limitEndCal.getTime());

      } catch (Exception e) {
        // カレンダーウィジットで登録するため、不正日付は想定外
        String limitStartDateStr = "";
        String limitEndDateStr = "";
        if (null != form_data.getLimitStartDate()) {
          limitStartDateStr = form_data.getLimitStartDate().toString();
        }
        if (null != form_data.getLimitEndDate()) {
          limitEndDateStr = form_data.getLimitEndDate().toString();
        }
        logger.error(
          "繰り返し期間の日付変換でエラーが発生しました。ログインユーザー:" + loginUser.getName().toString() + "/繰り返し期間開始日:" + limitStartDateStr + "/繰り返し期間終了日:" + limitEndDateStr,
          e);
        throw new ALPageNotFoundException();
      }
    }
  }

  /**
   * 参加メンバーのスケジュールマップ作成（スケジュール新規登録）
   * 
   * @param list
   *          参加メンバー一覧
   * @param required
   *          登録したい必須フラグの値
   * @param schedule
   *          新規登録対象スケジュール
   * @param category
   *          カテゴリー
   * @param ownerUserId
   *          主催者ユーザーID
   */
  private void createScheduleMapForNewSchedule(List<ALEipUser> list, String required, EipTSchedule schedule, EipTCommonCategory category, int ownerUserId) {
    for (ALEipUser user : list) {
      EipTScheduleMap map = Database.create(EipTScheduleMap.class);
      int userid = (int) user.getUserId().getValue();

      // スケジュール
      map.setEipTSchedule(schedule);

      // ユーザーID
      map.setUserId(Integer.valueOf(userid));

      if (userid == ownerUserId) {
        // 主催者ユーザーと参加メンバーが同一の場合、所有者
        map.setStatus(ScheduleConst.SCHEDULEMAP_STATUS_OWNER);
      } else {
        // 未回答
        map.setStatus(ScheduleConst.SCHEDULEMAP_STATUS_NON_RES);
      }

      // 種別：ユーザー固定
      map.setType(ScheduleUtils.SCHEDULEMAP_TYPE_USER);

      // 共有カテゴリー
      map.setCommonCategoryId(Integer.valueOf(1));
      map.setEipTCommonCategory(category);

      // 必須フラグ
      map.setRequired(required);

      // 重要フラグ：通常
      map.setPriority(ScheduleConst.SCHEDULEMAP_PRIORITY_F);

      // ダミー未回答フラグ：通常
      map.setDummyNonResponse(ScheduleConst.SCHEDULEMAP_DUMMY_NON_RES_F);

    }
  }

  /**
   * 参加メンバーのスケジュールマップ作成（スケジュール更新）
   * 
   * @param list
   *          参加メンバー一覧
   * @param required
   *          登録したい必須フラグの値
   * @param schedule
   *          更新対象スケジュール
   * @param category
   *          カテゴリー
   * @param ownerUserId
   *          主催者ユーザーID
   * @param oldScheduleMaps
   *          洗い替え前のスケジュールマップ
   * @param isSuccession
   *          旧データより回答状態を引き継ぐ場合true
   */
  private void createScheduleMapForUpdateSchedule(List<ALEipUser> list, String required, EipTSchedule schedule, EipTCommonCategory category, int ownerUserId,
      List<?> oldScheduleMaps, boolean isSuccession) {

    for (ALEipUser user : list) {
      EipTScheduleMap map = Database.create(EipTScheduleMap.class);
      int userid = (int) user.getUserId().getValue();

      // スケジュール
      map.setEipTSchedule(schedule);
      // ユーザーID
      map.setUserId(Integer.valueOf(userid));
      // 状態：未回答
      map.setStatus(ScheduleConst.SCHEDULEMAP_STATUS_NON_RES);
      // 種別：ユーザー固定
      map.setType(ScheduleUtils.SCHEDULEMAP_TYPE_USER);
      // 共有カテゴリー
      map.setCommonCategoryId(Integer.valueOf(1));
      map.setEipTCommonCategory(category);
      // 必須フラグ
      map.setRequired(required);
      // 重要フラグ：通常
      map.setPriority(ScheduleConst.SCHEDULEMAP_PRIORITY_F);
      // ダミー未回答フラグ：通常
      map.setDummyNonResponse(ScheduleConst.SCHEDULEMAP_DUMMY_NON_RES_F);

      // 旧スケジュールマップを取得
      EipTScheduleMap oldMap = getScheduleMap(oldScheduleMaps, userid, ScheduleUtils.SCHEDULEMAP_TYPE_USER);

      // 状態・ダミー未回答の引き継ぎ
      if (userid == schedule.getOwnerId().intValue()) {
        // 主催者ユーザーと参加メンバーが同一の場合
        // 状態：所有者
        map.setStatus(ScheduleConst.SCHEDULEMAP_STATUS_OWNER);
      } else if (oldMap != null && required.equals(oldMap.getRequired()) && isSuccession) {
        // 旧スケジュールマップと必須/任意が一致 かつ 引き継ぎ可の場合
        // 状態：引き継ぎ
        map.setStatus(oldMap.getStatus());
        // ダミー未回答フラグ：引き継ぎ
        map.setDummyNonResponse(oldMap.getDummyNonResponse());
      }

      // 重要フラグの引き継ぎ
      if (oldMap != null) {
        // 旧スケジュールマップが有る場合
        // 重要フラグ：引き継ぎ
        map.setPriority(oldMap.getPriority());
        // add start 要件No.26 スケジュール個別色換え
        // 個別色：引き継ぎ
        map.setIndividualColor(oldMap.getIndividualColor());
        // add end
      }

      // スケジュール配下に追加
      schedule.addToEipTScheduleMaps(map);
    }
  }

  /**
   * 週パターンチェック済み曜日一覧取得
   * 
   * @return チェック済み曜日一覧（0番=日曜日、1番=月曜日...）
   */
  public List<String> getCheckedWeekDoW() {
    List<String> result = new ArrayList<String>(0);
    if (ScheduleConst.DOW_CHECKED.equals(form_data.getWeek0().toString())) {
      result.add(ScheduleConst.DOW_CHECKED);
    } else {
      result.add(ScheduleConst.DOW_UNCHECKED);
    }
    if (ScheduleConst.DOW_CHECKED.equals(form_data.getWeek1().toString())) {
      result.add(ScheduleConst.DOW_CHECKED);
    } else {
      result.add(ScheduleConst.DOW_UNCHECKED);
    }
    if (ScheduleConst.DOW_CHECKED.equals(form_data.getWeek2().toString())) {
      result.add(ScheduleConst.DOW_CHECKED);
    } else {
      result.add(ScheduleConst.DOW_UNCHECKED);
    }
    if (ScheduleConst.DOW_CHECKED.equals(form_data.getWeek3().toString())) {
      result.add(ScheduleConst.DOW_CHECKED);
    } else {
      result.add(ScheduleConst.DOW_UNCHECKED);
    }
    if (ScheduleConst.DOW_CHECKED.equals(form_data.getWeek4().toString())) {
      result.add(ScheduleConst.DOW_CHECKED);
    } else {
      result.add(ScheduleConst.DOW_UNCHECKED);
    }
    if (ScheduleConst.DOW_CHECKED.equals(form_data.getWeek5().toString())) {
      result.add(ScheduleConst.DOW_CHECKED);
    } else {
      result.add(ScheduleConst.DOW_UNCHECKED);
    }
    if (ScheduleConst.DOW_CHECKED.equals(form_data.getWeek6().toString())) {
      result.add(ScheduleConst.DOW_CHECKED);
    } else {
      result.add(ScheduleConst.DOW_UNCHECKED);
    }
    return result;
  }

  /**
   * 第一引数のリストに，第二引数で指定したユーザ ID が含まれているかを検証する．
   * 
   * @param memberIdList
   * @param memberId
   * @return
   */
  private boolean isContains(List<Integer> memberIdList, int userId) {
    int size = memberIdList.size();
    Integer tmpInt = null;
    for (int i = 0; i < size; i++) {
      tmpInt = memberIdList.get(i);
      if (userId == tmpInt.intValue()) {
        return true;
      }
    }
    return false;
  }

  /**
   * オブジェクト（String、Integerに対応）が等しいかチェック
   * 
   * @param a
   *          比較オブジェクト
   * @param b
   *          比較オブジェクト
   * 
   * @return true:aとbは等しい
   * 
   */
  private boolean isSameValue(Object a, Object b) {
    if (a == null && b == null) {
      return true;
    }
    if (a != null && a.equals(b)) {
      return true;
    }
    if (b != null && b.equals(a)) {
      return true;
    }
    return false;
  }

  // add end
}
