/*
 * Copyright(C) 2010 avanza Co.,Ltd. All rights reserved.
 * http://www.avnz.co.jp/
 * 
 * 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.lunchorder;

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.ALNumberField;
import com.aimluck.commons.field.ALStringField;
import com.aimluck.eip.cayenne.om.portlet.AvzTLunchOrder;
import com.aimluck.eip.cayenne.om.portlet.AvzTLunchOrderItem;
import com.aimluck.eip.common.ALAbstractFormData;
import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALEipConstants;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.lunchorder.util.LunchOrderUtils;
import com.aimluck.eip.modules.actions.common.ALAction;
import com.aimluck.eip.orm.Database;
import com.aimluck.eip.orm.query.ResultList;
import com.aimluck.eip.orm.query.SelectQuery;
import com.aimluck.eip.services.eventlog.ALEventlogConstants;
import com.aimluck.eip.services.eventlog.ALEventlogFactoryService;
import com.aimluck.eip.util.ALEipUtils;

/**
 * 注文表のフォームデータを管理するクラスです。 <BR>
 * 
 */
public class LunchOrderMapInputFormData extends ALAbstractFormData {

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

  /** 子テーブル（商品入力フォーム）一覧 */
  private List<LunchOrderMapInputFormResultData> itemFieldList;

  /** 弁当屋ID */
  private String entityId;

  /** 弁当屋名 */
  private ALStringField storeName;

  /** コメント */
  private ALStringField comment;

  /** 締め切り時刻（時） */
  private ALNumberField deadLineTime_hour;

  /** 締め切り時刻（分） */
  private ALNumberField deadLineTime_minute;

  /** 最低条件有無フラグ */
  private ALStringField minStatus;

  /** 最低条件（金額） */
  private ALNumberField minPrice;

  /** 最低条件（数） */
  private ALNumberField minNum;

  /** 入力された最低条件値 */
  private ALNumberField minProperty;

  /** 商品入力フィールドの数 */
  private int itemFieldlength;

  /** 登録弁当（商品）価格 */
  private ALNumberField[] item_id = new ALNumberField[itemFieldlength];

  /** 登録弁当（商品）名 */
  private ALStringField[] item_name = new ALStringField[itemFieldlength];

  /** 登録弁当（商品）価格 */
  private ALNumberField[] item_price = new ALNumberField[itemFieldlength];

  /** 登録弁当（商品）コメント */
  private ALStringField[] item_comment = new ALStringField[itemFieldlength];

  /** 登録商品最低注文数に含めるか含めないか判断用フラグ */
  private ALNumberField[] item_min_order_flag =
    new ALNumberField[itemFieldlength];

  /** セッション用変数 */
  private String sessionItemId;

  /** セッション用変数 */
  private String sessionItemName;

  /** セッション用変数 */
  private String sessionItemComment;

  /** セッション用変数 */
  private String sessionItemPrice;

  /** セッション用変数 */
  private String sessionItemMinOrderFlag;

  /** プレビュー画面からの遷移を判断するフラグ */
  private String returnFlag = "F";

  /** <code>MIN_NUM</code> 最低注文条件変数の識別子 */
  public static final String MIN_NUM = "N";

  /** <code>MIN_PRICE</code> 最低注文条件変数の識別子 */
  public static final String MIN_PRICE = "P";

  /** <code>NONE_CONDITION</code> 最低注文条件変数の識別子 */
  public static final String NONE_CONDITION = "F";

  /** <code>ORDER_FLAGS_TRUE</code> 商品条件変数の識別子 */
  public static final String ORDER_FLAGS_TRUE = "T";

  /** <code>ORDER_FLAGS_SET_TRUE</code> 商品条件変数の識別子 */
  public static final int ORDER_FLAGS_SET_TRUE = 1;

  /** <code>ORDER_FLAGS_SET_FALSE</code> 商品条件変数の識別子 */
  public static final int ORDER_FLAGS_SET_FALSE = 0;

  /** <code>DEAD_LINE_TIME_TRUE</code>締め切り時刻変数の識別子 */
  public static final String DEAD_LINE_TIME_TRUE = "T";

  /**
   * 
   * @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)
   */
  @Override
  public void init(ALAction action, RunData rundata, Context context)
      throws ALPageNotFoundException, ALDBErrorException {
    super.init(action, rundata, context);

  }

  /**
   * 親テーブル用フィールドを初期化します。 <BR>
   * 
   * @see com.aimluck.eip.common.ALData#initField()
   */
  public void initField() {
    // 弁当屋名
    storeName = new ALStringField();
    storeName.setFieldName("お弁当屋名");
    storeName.setTrim(true);
    // コメント
    comment = new ALStringField();
    comment.setFieldName("コメント");
    comment.setTrim(true);
    // 締め切り時刻(時)
    deadLineTime_hour = new ALNumberField();
    deadLineTime_hour.setFieldName("注文締め切り時刻");
    // 締め切り時刻（分）
    deadLineTime_minute = new ALNumberField();

    // 最低条件有無フラグ
    minStatus = new ALStringField();
    // 最低注文金額
    minPrice = new ALNumberField();
    // 最低注文数
    minNum = new ALNumberField();

    // 最低条件値
    minProperty = new ALNumberField();
  }

  /**
   * 子テーブル用フィールドを初期化します。 <BR>
   * 
   * @see com.aimluck.eip.common.ALData#initField()
   */
  public void initItemField(RunData rundata) {
    itemFieldlength = getItemFieldSize(rundata);// フィールドの数を取得
    item_id = new ALNumberField[itemFieldlength];
    item_name = new ALStringField[itemFieldlength];
    item_price = new ALNumberField[itemFieldlength];
    item_comment = new ALStringField[itemFieldlength];
    item_min_order_flag = new ALNumberField[itemFieldlength];
    for (int i = 1; i < itemFieldlength; i++) {// フィールドの数分初期化

      item_id[i] = new ALNumberField();// hiddenで送るフィールド初期化

      item_name[i] = new ALStringField();// 登録商品を入力するフィールド初期化
      item_name[i].setFieldName("商品名:" + (i) + "行目");// フィールド名（エラーメッセージ表示時）

      item_price[i] = new ALNumberField();// 価格を入力するフィールド初期化
      item_price[i].setFieldName("価格:" + (i) + "行目");// フィールド名（エラーメッセージ表示時）

      item_comment[i] = new ALStringField();// コメントを入力するフィールド初期化
      item_comment[i].setFieldName("商品コメント:" + (i) + "行目");// フィールド名（エラーメッセージ表示時）

      item_min_order_flag[i] = new ALNumberField();// 最低注文数に含めるか含めないかをチェックボックスで指定するフィールド
      item_min_order_flag[i].setValue(0);// デフォルトはチェックされていない状態＝最低注文数に含めない（フラグ”０”）

    }
    // 子テーブル入力フォームチェック用に入力値をセット
    setItemField(rundata);
  }

  public void setItemField(RunData rundata) {// 子テーブル入力フォームチェック用に入力値をセット

    for (int i = 1; i < itemFieldlength; i++) {

      String itemNames = rundata.getParameters().getString("item_name_" + i);// 商品名を取得
      String itemPrices = rundata.getParameters().getString("item_price_" + i);// 価格を取得
      String itemComments =
        rundata.getParameters().getString("item_comment_" + i);// 商品コメントを取得

      item_name[i].setValue(itemNames);
      item_price[i].setValue(itemPrices);
      item_comment[i].setValue(itemComments);

    }
  }

  /**
   * 注文表の各フィールドに対する制約条件を設定します。 <BR>
   * 
   * @see com.aimluck.eip.common.ALAbstractFormData#setValidator()
   */
  @Override
  protected void setValidator() {
    // 弁当屋名必須項目
    storeName.setNotNull(true);
    // 弁当屋名の文字数制限値
    storeName.limitMaxLength(50);
    // 弁当屋コメントの文字数制限値
    comment.limitMaxLength(100);
    // 弁当屋の最低条件値の最大値
    minProperty.limitMaxValue(100000);
    // 弁当屋の最低条件値の最小値
    minProperty.limitMinValue(0);
    minProperty.setNotNull(true);
    int validateItemFieldlength = getItemFieldlength();// 子のフィールド数取得

    for (int i = 1; i < validateItemFieldlength; i++) {
      item_name[i].limitMaxLength(50);// 登録商品名最大入力文字数設定
      item_name[i].setNotNull(true);// NotNull制約を付け加える
      item_price[i].limitMaxValue(10000);// 価格のMAX値設定
      item_price[i].limitMinValue(0);// 価格のMIN値設定
      item_price[i].setNotNull(true);// NotNull制約を付け加える
      item_comment[i].limitMaxLength(100);// 登録商品 コメント最大入力文字数設定

    }
  }

  /**
   * 注文表のフォームに入力されたデータの妥当性検証を行います。 <BR>
   * 
   * @param msgList
   * @return TRUE 成功 FALSE 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#validate(java.util.ArrayList)
   */
  @Override
  protected boolean validate(List<String> msgList) {
    // 弁当屋名必須項目名
    storeName.validate(msgList);
    // 弁当屋コメント項目名
    comment.validate(msgList);
    // 最低条件
    String status = minStatus.getValue();
    if (!(status.equals(NONE_CONDITION))) {// 条件なし以外は最低条件必須
      if (status.equals(MIN_PRICE)) {
        minProperty.setFieldName("最低注文金額");
      } else {
        minProperty.setFieldName("最低注文数");
      }
      minProperty.validate(msgList);
    }

    // 子テーブル（商品入力フォーム）の妥当性検証
    int length = getItemFieldlength();
    for (int i = 1; i < length; i++) {
      item_name[i].validate(msgList);// 商品名
      item_price[i].validate(msgList);// 価格
      item_comment[i].validate(msgList);// 商品コメント

    }

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

  /**
   * 注文表をデータベースから読み出します。 <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)
   */
  @Override
  protected boolean loadFormData(RunData rundata, Context context,
      List<String> msgList) {
    try {

      // オブジェクトモデルを取得
      AvzTLunchOrder avzTLunchOrder =
        LunchOrderUtils.getAvzTLunchOrder(rundata, context);
      if (avzTLunchOrder == null) {
        return false;
      }

      // 弁当屋名
      storeName.setValue(avzTLunchOrder.getStoreName());
      // コメント
      comment.setValue(avzTLunchOrder.getComment());
      // 締め切り時刻
      String deadlineDate = String.valueOf(avzTLunchOrder.getDeadlineDate());// 一旦String型にして、（hourとminuteに分ける）

      // velocity表示用に時刻をhourとminuteに分ける処理
      int hour = 0;
      int minute = 0;

      if (deadlineDate.length() == 3) {// hourが1桁だったら
        hour = Integer.valueOf(deadlineDate.substring(0, 1));// 文字列１文字目を時としてセット
        minute = Integer.valueOf(deadlineDate.substring(1));// 文字列２文字目以降を分としてセット
      } else if (deadlineDate.length() == 4) {// hourが2桁だったら
        hour = Integer.valueOf(deadlineDate.substring(0, 2));// 文字列１文字目と２文字めを時としてセット
        minute = Integer.valueOf(deadlineDate.substring(2));// 文字列３文字目以降を分としてセット
      } else {// ０時０分だったら

      }

      deadLineTime_hour.setValue(hour);// 時刻（時）セット
      deadLineTime_minute.setValue(minute);// 時刻（分）セット
      minStatus.setValue(avzTLunchOrder.getMinStatus());// 最低条件セット
      String status = avzTLunchOrder.getMinStatus();

      if (status.equals(MIN_NUM)) {// 最低条件に数が設定されていた場合
        minNum.setValue(avzTLunchOrder.getMinNum());// 最低注文数セット
        minProperty.setValue(avzTLunchOrder.getMinNum());
      } else if (status.equals(MIN_PRICE)) {// 最低条件に価格が設定されていた場合
        minPrice.setValue(avzTLunchOrder.getMinPlice());// 最低注文価格セット
        minProperty.setValue(avzTLunchOrder.getMinPlice());
      } else {

      }
      // 商品入力フィールド一覧
      itemFieldList = new ArrayList<LunchOrderMapInputFormResultData>();

      int parentId = avzTLunchOrder.getOrderMapId();// 親Ｉｄ取得

      SelectQuery<AvzTLunchOrderItem> query =
        Database.query(AvzTLunchOrderItem.class);

      Expression exp =
        ExpressionFactory.matchDbExp(
          AvzTLunchOrderItem.TO_AVZ_TLUNCH_ORDER_PROPERTY
            + "."
            + AvzTLunchOrder.ORDER_MAP_ID_PK_COLUMN,
          parentId);

      query.setQualifier(exp);
      query.orderAscending("itemTitle");
      ResultList<AvzTLunchOrderItem> avzTLunchOrderItem = query.getResultList();

      int itemLength = avzTLunchOrderItem.size();// //子のフィールド数取得

      for (int i = 0; i < itemLength; i++) {
        AvzTLunchOrderItem itemRecord = avzTLunchOrderItem.get(i);

        LunchOrderMapInputFormResultData rd =
          new LunchOrderMapInputFormResultData();// インスタンス生成

        rd.initField(); // オブジェクトのフィールドを初期化
        rd.setItemId(itemRecord.getItemId());// 弁当ＩＤセット
        rd.setItemName(itemRecord.getItemTitle());// 弁当名セット
        rd.setItemPrice(itemRecord.getPrice());// 価格セット
        rd.setItemComment(itemRecord.getComment());// コメントセット
        rd.setItemMinOrderFlag(itemRecord.getMinOrderFlag());
        itemFieldList.add(rd);
      }

    } 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)
   */
  @Override
  protected boolean deleteFormData(RunData rundata, Context context,
      List<String> msgList) {
    try {
      // 削除オブジェクトモデルを取得
      AvzTLunchOrder avzTLunchOrder =
        LunchOrderUtils.getAvzTLunchOrder(rundata, context);
      if (avzTLunchOrder == null) {
        return false;
      }
      int entity_id = avzTLunchOrder.getOrderMapId();
      String name = avzTLunchOrder.getStoreName();

      // 削除
      Database.delete(avzTLunchOrder);
      Database.commit();

      // イベントログに保存
      ALEventlogFactoryService.getInstance().getEventlogHandler().log(
        entity_id,
        ALEventlogConstants.PORTLET_TYPE_NONE,
        name);
    } catch (Exception ex) {
      Database.rollback();
      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)
   */
  @Override
  protected boolean insertFormData(RunData rundata, Context context,
      List<String> msgList) {
    try {

      // 新規オブジェクトモデル（親テーブルAvzTLunchOrder）
      AvzTLunchOrder avzTLunchOrder = Database.create(AvzTLunchOrder.class);

      Date now = Calendar.getInstance().getTime();// 現在時刻取得
      // 作成者ID
      avzTLunchOrder.setUserId(ALEipUtils.getUserId(rundata));

      // 弁当屋名
      avzTLunchOrder.setStoreName(storeName.getValue());
      // コメント
      avzTLunchOrder.setComment(comment.getValue());
      // 最低条件有無フラグ
      avzTLunchOrder.setMinStatus(minStatus.getValue());

      if (minStatus.getValue().equals(MIN_PRICE)) {
        // 最低条件（金額）
        avzTLunchOrder.setMinPlice(Integer.valueOf(String.valueOf(minProperty
          .getValue())));
        avzTLunchOrder.setMinNum(0);// 最低条件に"金額"を設定する場合最低数は０に設定
      } else if (minStatus.getValue().equals(MIN_NUM)) {
        // 最低条件（数）
        avzTLunchOrder.setMinNum(Integer.valueOf(String.valueOf(minProperty
          .getValue())));
        avzTLunchOrder.setMinPlice(0);// 最低条件に"数"を設定する場合最低金額は０に設定
      } else {// 条件が無い場合は両方に０を設定
        avzTLunchOrder.setMinNum(0);
        avzTLunchOrder.setMinPlice(0);
      }
      // 作成日
      avzTLunchOrder.setCreateDate(now);
      // 更新日
      avzTLunchOrder.setUpdateDate(now);

      if ((DEAD_LINE_TIME_TRUE).equals(rundata.getParameters().getString(
        "deadLineTime"))) {// 締め切り時刻を設定する場合
        // 締め切り時刻
        String stringDeadLineTime_hour = deadLineTime_hour.getValueAsString();

        String stringDeadLineTime_minute =
          deadLineTime_minute.getValueAsString();

        int deadLineTime =
          Integer.parseInt(stringDeadLineTime_hour + stringDeadLineTime_minute);

        avzTLunchOrder.setDeadlineDate(deadLineTime);

      } else {// 締め切り時刻を設定しない場合（時刻を数値で判断するので2400だと締め切りにならない）
        avzTLunchOrder.setDeadlineDate(2400);
      }

      int length = getItemFieldSize(rundata);// //子のフィールド数取得

      if (length > 0) {// （子テーブルAvzTLunchOrderItem）に登録するオブジェクトがある場合
        for (int i = 1; i < length; i++) {

          // 新規オブジェクトモデル（子テーブルAvzTLunchOrderItem）
          AvzTLunchOrderItem avzTLunchOrderItem =
            Database.create(AvzTLunchOrderItem.class);

          String itemNames =
            rundata.getParameters().getString("item_name_" + i);// 商品名を取得
          String itemPrices =
            rundata.getParameters().getString("item_price_" + i);// 価格を取得
          String itemComments =
            rundata.getParameters().getString("item_comment_" + i);// コメントを取得
          String itemMinOrderFlags =
            rundata.getParameters().getString("item_min_order_flag_" + i);// 最低注文数に含めるか含めないか*/

          avzTLunchOrderItem.setToAvzTLunchOrder(avzTLunchOrder);// 親クラスのOrderMapIdを登録
          avzTLunchOrderItem.setItemTitle(itemNames);// 商品名登録
          avzTLunchOrderItem.setPrice(Integer.valueOf(itemPrices));// 価格登録
          avzTLunchOrderItem.setComment(itemComments);// 商品コメント登録
          if ((ORDER_FLAGS_TRUE).equals(itemMinOrderFlags)) {// trueだったらDBにフラグ"1"を入れる。それ以外は"0"を入れる。
            avzTLunchOrderItem.setMinOrderFlag(ORDER_FLAGS_SET_TRUE);
          } else {
            avzTLunchOrderItem.setMinOrderFlag(ORDER_FLAGS_SET_FALSE);
          }

        }

        Database.commit();
      }

    } catch (Exception ex) {
      Database.rollback();
      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)
   */
  @Override
  protected boolean updateFormData(RunData rundata, Context context,
      List<String> msgList) {
    try {

      // 編集オブジェクトモデルを取得
      AvzTLunchOrder avzTLunchOrder =
        LunchOrderUtils.getAvzTLunchOrder(rundata, context);
      if (avzTLunchOrder == null) {
        return false;
      }

      Date now = Calendar.getInstance().getTime();

      // 弁当屋名
      avzTLunchOrder.setStoreName(storeName.getValue());
      avzTLunchOrder.setUserId(Integer.valueOf(ALEipUtils.getUserId(rundata)));
      // コメント
      avzTLunchOrder.setComment(comment.getValue());
      // 更新日
      avzTLunchOrder.setUpdateDate(now);

      if ((DEAD_LINE_TIME_TRUE).equals(rundata.getParameters().getString(
        "deadLineTime"))) {// 締め切り時刻を設定する場合
        // 締め切り時刻
        String stringDeadLineTime_hour = deadLineTime_hour.getValueAsString();

        String stringDeadLineTime_minute =
          deadLineTime_minute.getValueAsString();

        int deadLineTime =
          Integer.parseInt(stringDeadLineTime_hour + stringDeadLineTime_minute);

        avzTLunchOrder.setDeadlineDate(deadLineTime);

      } else {// 締め切り時刻を設定しない場合（時刻を数値で判断するので2400だと締め切りにならない）
        avzTLunchOrder.setDeadlineDate(2400);
      }

      // 最低条件有無フラグ
      avzTLunchOrder.setMinStatus(minStatus.getValue());
      if (minStatus.getValue().equals(MIN_PRICE)) {
        // 最低条件（金額）
        avzTLunchOrder.setMinPlice(Integer.valueOf(String.valueOf(minProperty
          .getValue())));
        avzTLunchOrder.setMinNum(0);
      } else if (minStatus.getValue().equals(MIN_NUM)) {
        // 最低条件（数）
        avzTLunchOrder.setMinNum(Integer.valueOf(String.valueOf(minProperty
          .getValue())));
        avzTLunchOrder.setMinPlice(0);

      } else {
        avzTLunchOrder.setMinNum(0);
        avzTLunchOrder.setMinPlice(0);
      }

      int itemFieldSize = getItemFieldSize(rundata);// //子のフィールド数取得
      int itemUpdataFieldSize = getUpdataItemFieldSize(rundata);// 更新フィールドの数を取得(edit_length(itemIdがあるもの)の長さ)

      if (itemFieldSize == 0 || itemUpdataFieldSize == 0) {// 商品入力フィールドの数もしくは更新フィールドの数が0の場合
        // 登録済み商品を全削除する処理

        String LunchOrderMapId =
          ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);

        SelectQuery<AvzTLunchOrderItem> query =
          Database.query(AvzTLunchOrderItem.class);

        Expression exp =
          ExpressionFactory.matchExp(
            AvzTLunchOrderItem.ORDER_MAP_ID_PROPERTY,
            LunchOrderMapId);

        query.setQualifier(exp);
        ResultList<AvzTLunchOrderItem> avzTLunchOrderItems =
          query.getResultList();

        // AvzTLunchOrderItemを削除
        int size = avzTLunchOrderItems.size();

        for (int h = 0; h < size; h++) {
          AvzTLunchOrderItem avzTLunchOrderItem = avzTLunchOrderItems.get(h);
          if (avzTLunchOrderItem == null) {
            return false;
          }
          Database.delete(avzTLunchOrderItem);
        }

      } else {// 商品入力フィールドの数もしくは更新フィールドの数が0以外の場合
        // 編集フォームにおいて削除ボタンで削除した商品をを削除

        String LunchOrderMapId =
          ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);

        SelectQuery<AvzTLunchOrderItem> query =
          Database.query(AvzTLunchOrderItem.class);

        Expression exp1 =
          ExpressionFactory.matchExp(
            AvzTLunchOrderItem.ORDER_MAP_ID_PROPERTY,
            LunchOrderMapId);

        query.setQualifier(exp1);
        // 選択された注文表テーブル（ＡｖｚＴＬｕｎｃｈＯｒｄｅｒ）の子のアイテムテーブル（AvzTLunchOrderItem）オブジェクトを取得
        ResultList<AvzTLunchOrderItem> avzTLunchOrderItems =
          query.getResultList();
        int lunchOrderItemDbSize = avzTLunchOrderItems.size();
        // hiddenで送ったitemIdと合致しないものは全て削除（更新する商品はhiddenでitemIdを送る）
        for (int k = 0; k < lunchOrderItemDbSize; k++) {
          AvzTLunchOrderItem avzTLunchOrderDbItem = avzTLunchOrderItems.get(k);
          String dbId = avzTLunchOrderDbItem.getItemId().toString();// AvzTLunchOrderItemテーブルにあるitemId取得

          outer: for (int m = 1; m < itemUpdataFieldSize + 1; m++) {
            String itemId = rundata.getParameters().getString("item_id_" + m);// 弁当ＩＤ（商品ＩＤ）を取得
            String item_Id = itemId;// hiddenで送ったiｔｅｍＩｄを取得

            if (item_Id.equals(dbId)) {// 合致するものは更新するので削除しない
              break outer;
            }

            if (m == itemUpdataFieldSize) {// 合致するものが無い場合は削除
              Database.delete(avzTLunchOrderDbItem);

            }
          }
        }

      }
      if (itemFieldSize > 0) {// 更新処理

        for (int i = 1; i < itemFieldSize; i++) {

          if (!(i < itemUpdataFieldSize + 1)) {// 更新分ではなく新規追加分の場合

            AvzTLunchOrderItem avzTLunchOrderUpdateItem =
              Database.create(AvzTLunchOrderItem.class);

            String counts[] = rundata.getParameters().getStrings("add_value[]");

            String count = counts[i - itemUpdataFieldSize];// input
            // name属性に使用する変数

            String itemNames =
              rundata.getParameters().getString("item_name_" + count);// 弁当（商品）名を取得
            String itemPrices =
              rundata.getParameters().getString("item_price_" + count);// 価格を取得
            String itemComments =
              rundata.getParameters().getString("item_comment_" + count);// コメントを取得
            String minOrderFlags =
              rundata.getParameters().getString("item_min_order_flag_" + count);// 最低注文数に含めるか含めないか

            avzTLunchOrderUpdateItem.setToAvzTLunchOrder(avzTLunchOrder);// 親クラスのOrderMapIdを登録
            avzTLunchOrderUpdateItem.setItemTitle(itemNames);// 商品名登録
            avzTLunchOrderUpdateItem.setPrice(Integer.valueOf(itemPrices));// 価格登録
            avzTLunchOrderUpdateItem.setComment(itemComments);// 商品コメント登録

            if ((ORDER_FLAGS_TRUE).equals(minOrderFlags)) {// 注文数に含めるか含めないかのフラグtrueだったら
              avzTLunchOrderUpdateItem.setMinOrderFlag(ORDER_FLAGS_SET_TRUE);
            } else {
              avzTLunchOrderUpdateItem.setMinOrderFlag(ORDER_FLAGS_SET_FALSE);
            }

          } else {// 更新するフィールドがある場合の処理

            String itemId = rundata.getParameters().getString("item_id_" + i);// 弁当ＩＤ（商品ＩＤ）を取得
            String itemNames =
              rundata.getParameters().getString("item_name_" + i);// 弁当（商品）名を取得
            String itemPrices =
              rundata.getParameters().getString("item_price_" + i);// 価格を取得
            String itemComments =
              rundata.getParameters().getString("item_comment_" + i);// コメントを取得
            String minOrderFlags =
              rundata.getParameters().getString("item_min_order_flag_" + i);// 最低注文数に含めるか含めないか

            Expression exp =
              ExpressionFactory.matchDbExp(
                AvzTLunchOrderItem.ITEM_ID_PK_COLUMN,
                itemId);

            SelectQuery<AvzTLunchOrderItem> query =
              Database.query(AvzTLunchOrderItem.class, exp);

            ResultList<AvzTLunchOrderItem> items = query.getResultList();

            AvzTLunchOrderItem avzTLunchOrderItem = items.get(0);

            avzTLunchOrderItem.setItemTitle(itemNames);
            avzTLunchOrderItem.setPrice(Integer.valueOf((itemPrices)));
            avzTLunchOrderItem.setComment(itemComments);

            if ((ORDER_FLAGS_TRUE).equals(minOrderFlags)) {// 注文数に含めるか含めないかのフラグtrueだったら
              avzTLunchOrderItem.setMinOrderFlag(ORDER_FLAGS_SET_TRUE);
            } else {
              avzTLunchOrderItem.setMinOrderFlag(ORDER_FLAGS_SET_FALSE);
            }
          }
        }
      }
      // 注文表更新
      Database.commit();
      ALEventlogFactoryService.getInstance().getEventlogHandler().log(
        avzTLunchOrder.getOrderMapId(),
        ALEventlogConstants.PORTLET_TYPE_NONE,
        avzTLunchOrder.getStoreName());
    } catch (Exception ex) {
      Database.rollback();
      logger.error("Exception", ex);
      return false;
    }
    return true;
  }

  // boolean res の setSessionFormData ,preViewValidateを呼び出す
  public boolean setData(ALAction action, RunData rundata, Context context) {
    try {
      init(action, rundata, context);
      List<String> msgList = new ArrayList<String>();
      setValidator();
      boolean res =
        (setSessionFormData(rundata, context, msgList) && preViewValidate(
          msgList,
          rundata));
      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;
    }
  }

  /**
   * プレビュー時弁当注文のフォームに入力されたデータの妥当性検証を行います。 <BR>
   * 
   * @param msgList
   * @return TRUE 成功 FALSE 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#validate(java.util.ArrayList)
   */
  protected boolean preViewValidate(List<String> msgList, RunData runData) {
    // 弁当屋名必須項目名
    storeName.validate(msgList);
    // 最低条件
    String status = minStatus.getValue();
    if (!(status.equals(NONE_CONDITION))) {// 条件なし以外は最低条件必須
      if (status.equals(MIN_PRICE)) {
        minProperty.setFieldName("最低注文金額");
      } else {
        minProperty.setFieldName("最低注文数");
      }
      minProperty.validate(msgList);
    }

    // 子テーブル（商品入力フォーム）の妥当性検証
    int length = getItemFieldlength();
    for (int i = 1; i < length; i++) {
      item_name[i].validate(msgList);// 商品名
      item_price[i].validate(msgList);// 価格
      item_comment[i].validate(msgList);// 商品コメント
    }

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

  /**
   * セッションにデータを設定します。
   * 
   * @param rundata
   * @param context
   * @param msgList
   *            エラーメッセージのリスト
   * @return TRUE 成功 FALSE 失敗
   */
  public boolean setSessionFormData(RunData rundata, Context context,
      List<String> msgList) throws ALPageNotFoundException, ALDBErrorException {
    boolean res = super.setFormData(rundata, context, msgList);
    if (res) {
      try {
        if ((ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID)) != null) {
          entityId =
            ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);
        } else {
          entityId = "";
        }
        String storeId = entityId;// 注文表ID。新規の場合は空文字
        String storeName = rundata.getParameters().getString("storeName");// 弁当屋名
        String storeComment = rundata.getParameters().getString("comment");// 弁当屋コメント
        String deadLineHour;// 締め切り時刻（時）
        String deadLineMinute;// 締め切り時刻（分）
        if ((DEAD_LINE_TIME_TRUE).equals(rundata.getParameters().getString(
          "deadLineTime"))) {// 締め切り時刻が設定されている場合
          deadLineHour = rundata.getParameters().getString(// 締め切り時刻（時）
            "deadLineTime_hour");
          deadLineMinute = rundata.getParameters().getString(// 締め切り時刻（分）
            "deadLineTime_minute");
        } else {// 締め切り時刻が設定されていない場合
          deadLineHour = "24";
          deadLineMinute = "00";
        }
        String minStatus = rundata.getParameters().getString("minStatus");// 最低条件
        String minProperty = rundata.getParameters().getString("minProperty");// 最低条件値

        int sessionItemTotalLength = getItemFieldSize(rundata);

        for (int i = 1; i < sessionItemTotalLength; i++) {

          String itemId = rundata.getParameters().getString("item_id_" + i);// 弁当ＩＤ（商品ＩＤ）を取得

          String itemNames =
            rundata.getParameters().getString("item_name_" + i);// 弁当（商品）名を取得
          String replaceItemNames = itemNames.replaceAll(",", "､");
          String itemPrices =
            rundata.getParameters().getString("item_price_" + i);// 価格を取得

          String itemComments =
            rundata.getParameters().getString("item_comment_" + i);// コメントを取得
          String replaceItemComments = itemComments.replaceAll(",", "､");
          String minOrderFlags =
            rundata.getParameters().getString("item_min_order_flag_" + i);// 最低注文数に含めるか含めないか

          if (minOrderFlags != null && minOrderFlags.equals(ORDER_FLAGS_TRUE)) {
            minOrderFlags = String.valueOf(ORDER_FLAGS_SET_TRUE);
          } else {
            minOrderFlags = String.valueOf(ORDER_FLAGS_SET_FALSE);
          }
          if (i == 1) {
            sessionItemId = itemId;
            sessionItemName = replaceItemNames;
            sessionItemPrice = itemPrices;
            sessionItemComment = replaceItemComments;
            sessionItemMinOrderFlag = minOrderFlags;
          } else {
            sessionItemId = sessionItemId + "," + itemId;
            sessionItemName = sessionItemName + "," + replaceItemNames;
            sessionItemPrice = sessionItemPrice + "," + itemPrices;
            sessionItemComment = sessionItemComment + "," + replaceItemComments;
            sessionItemMinOrderFlag =
              sessionItemMinOrderFlag + "," + minOrderFlags;
          }
        }
        /** セッション保存時に使用するKey名 */
        String storeIdListKey = "com.aimluck.eip.lunchorder.storeIdListKey";// 弁当屋ID
        String storeNameListKey = "com.aimluck.eip.lunchorder.storeNameListKey";// 弁当屋名
        String storeCommentListKey =
          "com.aimluck.eip.lunchorder.storeCommentListKey";// 弁当屋コメント
        String deadLineHourListKey =
          "com.aimluck.eip.lunchorder.deadLineHourListKey";// 締め切り時刻（時）
        String deadLineMinuteListKey =
          "com.aimluck.eip.lunchorder.deadLineMinuteListKey";// 締め切り時刻（分）
        String minStatusListKey = "com.aimluck.eip.lunchorder.minStatusListKey";// 最低条件
        String minPropertyListKey =
          "com.aimluck.eip.lunchorder.minPropertyListKey";// 最低条件値
        String itemIdListKey = "com.aimluck.eip.lunchorder.itemIdListKey";// 弁当ID（商品ID）
        String itemNameListKey = "com.aimluck.eip.lunchorder.itemNameListKey";// 弁当名（商品名）
        String itemCommentListKey =
          "com.aimluck.eip.lunchorder.itemCommentListKey";// 弁当コメント（商品コメント）
        String itemPriceListKey = "com.aimluck.eip.lunchorder.itemPriceListKey";// 価格
        String itemMinOrderFlagListKey =
          "com.aimluck.eip.lunchorder.itemMinOrderFlagListKey";// 最低注文数に含めるか含めないか
        // セッションに入力された情報を格納。引数は(rundata,context,セッションKey名,セッションに格納するオブジェクト)
        ALEipUtils.setTemp(rundata, context, storeIdListKey, storeId);
        ALEipUtils.setTemp(rundata, context, storeNameListKey, storeName);
        ALEipUtils.setTemp(rundata, context, storeCommentListKey, storeComment);
        ALEipUtils.setTemp(rundata, context, deadLineHourListKey, deadLineHour);
        ALEipUtils.setTemp(
          rundata,
          context,
          deadLineMinuteListKey,
          deadLineMinute);
        ALEipUtils.setTemp(rundata, context, minStatusListKey, minStatus);
        ALEipUtils.setTemp(rundata, context, minPropertyListKey, minProperty);
        ALEipUtils.setTemp(rundata, context, itemIdListKey, sessionItemId);
        ALEipUtils.setTemp(rundata, context, itemNameListKey, sessionItemName);
        ALEipUtils.setTemp(
          rundata,
          context,
          itemCommentListKey,
          sessionItemComment);
        ALEipUtils
          .setTemp(rundata, context, itemPriceListKey, sessionItemPrice);
        ALEipUtils.setTemp(
          rundata,
          context,
          itemMinOrderFlagListKey,
          sessionItemMinOrderFlag);

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

    }
    return res;
  }

  // セッション開放
  public void clearLunchOrderMapPreViewSession(RunData rundata, Context context) {
    List<String> list = new ArrayList<String>();
    // 削除したいセッションのKeyを親クラスのメソッドに渡して処理
    list.add("com.aimluck.eip.lunchorder.storeNameListKey");
    list.add("com.aimluck.eip.lunchorder.storeCommentListKey");
    list.add("com.aimluck.eip.lunchorder.itemIdListKey");
    list.add("com.aimluck.eip.lunchorder.itemNameListKey");
    list.add("com.aimluck.eip.lunchorder.itemCommentListKey");
    list.add("com.aimluck.eip.lunchorder.itemPriceListKey");
    list.add("com.aimluck.eip.lunchorder.deadLineHourListKey");
    list.add("com.aimluck.eip.lunchorder.deadLineMinuteListKey");
    list.add("com.aimluck.eip.lunchorder.minStatusListKey");
    list.add("com.aimluck.eip.lunchorder.minPropertyListKey");
    list.add("com.aimluck.eip.lunchorder.itemMinOrderFlagListKey");

    ALEipUtils.removeTemp(rundata, context, list);
  }

  /**
   * 注文表にある追加商品入力フィールドの数を取得するメソッド
   * 
   * @param rundata
   * @return
   */
  public int getAddItemFieldSize(RunData rundata) {
    String addItemFieldSizes[] =
      (rundata.getParameters().getStrings("add_value[]"));
    int addItemFieldSize = addItemFieldSizes.length;
    return addItemFieldSize;
  }

  /**
   * 注文表にある商品入力フィールドの数を取得するメソッド
   * 
   * @param rundata
   * @return
   */
  public int getItemFieldSize(RunData rundata) {
    try {
      String addFieldSizes[] =
        (rundata.getParameters().getStrings("add_value[]"));
      int itemFieldSize = addFieldSizes.length;
      if ((rundata.getParameters().getStrings("edit_length[]")) != null) {
        String editFieldSizes[] =
          (rundata.getParameters().getStrings("edit_length[]"));
        itemFieldSize = addFieldSizes.length + editFieldSizes.length;
      }
      return itemFieldSize;
    } catch (Exception ex) {
      // itemFieldSizes[]がＮＵＬＬだったら０を返す
      logger.error("Exception", ex);
      return 0;
    }
  }

  /**
   * 注文表にある更新商品入力フィールドの数を取得するメソッド（hiddenパラメータがある商品）
   * 
   * @param rundata
   * @return
   */
  public int getUpdataItemFieldSize(RunData rundata) {
    try {
      String itemUpdataFieldSizes[] =
        (rundata.getParameters().getStrings("edit_length[]"));
      int length = itemUpdataFieldSizes.length;

      return length;
    } catch (Exception ex) {
      // itemUpdataFieldSizes[]がＮＵＬＬだったら０を返す
      logger.error("Exception", ex);
      return 0;
    }

  }

  /**
   * 弁当屋名を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getStoreName() {
    return storeName;
  }

  /**
   * コメントを取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getComment() {
    return comment;
  }

  /**
   * 締め切り時刻（hour）を取得します。 <BR>
   * 
   * @return
   */
  public ALNumberField getDeadLineTimeHour() {
    return deadLineTime_hour;
  }

  /**
   * 締め切り時刻（minute）を取得します。 <BR>
   * 
   * @return
   */
  public ALNumberField getDeadLineTimeMinute() {
    return deadLineTime_minute;
  }

  /**
   * 最低条件を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getMinStatus() {
    return minStatus;
  }

  /**
   * 最低金額を取得します。 <BR>
   * 
   * @return
   */
  public ALNumberField getMinPrice() {
    return minPrice;
  }

  /**
   * 最低注文数を取得します。 <BR>
   * 
   * @return
   */
  public ALNumberField getMinNum() {
    return minNum;
  }

  /**
   * 最低条件値を取得します。 <BR>
   * 
   * @return
   */
  public ALNumberField getMinProperty() {
    return minProperty;
  }

  /**
   * 子テーブル（商品入力フィールド）の数を取得します。引数にrundataを使わないﾊﾟﾀｰﾝ <BR>
   * 
   * @return
   */
  public int getItemFieldlength() {
    return itemFieldlength;
  }

  /**
   * 子テーブル（商品入力フィールド）一覧を取得します。 <BR>
   * 
   * @return
   */
  public List<LunchOrderMapInputFormResultData> getItemFieldList() {
    return itemFieldList;
  }

  /**
   * プレビュー画面からの遷移かどうかを判断するフラグをsetします。 <BR>
   * 
   * @return
   */
  public String setReturnFlag(String string) {
    returnFlag = string;
    return returnFlag;
  }

  /**
   * プレビュー画面からの遷移かどうかを判断するフラグを取得します。 <BR>
   * 
   * @return
   */
  public String getReturnFlag() {

    return returnFlag;
  }

}
