package com.aimluck.eip.cashflow;

import java.util.ArrayList;
import java.util.List;
import java.util.jar.Attributes;

import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.query.SQLTemplate;
import org.apache.cayenne.query.SelectQuery;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.jetspeed.services.rundata.JetspeedRunData;
import org.apache.turbine.util.RunData;
import org.apache.velocity.context.Context;

import com.aimluck.commons.field.ALDateField;
import com.aimluck.commons.field.ALNumberField;
import com.aimluck.commons.field.ALStringField;
import com.aimluck.commons.utils.ALDateUtil;
import com.aimluck.eip.cayenne.om.portlet.ImwMHanyo;
import com.aimluck.eip.cayenne.om.portlet.ImwMClient;
import com.aimluck.eip.cayenne.om.portlet.ImwMItem;
import com.aimluck.eip.cayenne.om.portlet.ImwMItemCategory;
import com.aimluck.eip.cayenne.om.portlet.ImwMItemSubcategory;
import com.aimluck.eip.cayenne.om.portlet.ImwTAccount;
import com.aimluck.eip.cayenne.om.portlet.ImwTAccountPlan;
import com.aimluck.eip.cayenne.om.portlet.ImwTOfficeCalendarMap;
import com.aimluck.eip.cayenne.om.security.TurbineUser;
import com.aimluck.eip.common.ALAbstractSelectData;
import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALData;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.modules.actions.common.ALAction;
import com.aimluck.eip.orm.DatabaseOrmService;
import com.aimluck.eip.services.accessctl.ALAccessControlConstants;
import com.aimluck.eip.cashflow.util.AccountPlanUtils;
import com.aimluck.eip.util.ALEipUtils;

/**
 * 入出金予定検索データを管理するクラスです。 <BR>
 *
 */
public class AccountPlanSelectData extends ALAbstractSelectData implements ALData {

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

  /** 現在選択されているタブ */
  private String currentTab;
  
  /** カテゴリリスト */
  private ArrayList categoryList;
  
  /** 科目リスト */
  private ArrayList itemList = null;
  
  /** 取引先リスト */
  private ArrayList clientList;
  
  /** 入出金予定リスト */
  private ArrayList accountPlanList;
  
  /** 一覧表示区分リスト*/
  private ArrayList accountClassList;
  
  /** カテゴリの総数 */
  private int categorySum;

  /**
   * 
   * @param action
   * @param rundata
   * @param context
   * @see com.aimluck.eip.common.ALAbstractSelectData#init(com.aimluck.eip.modules.actions.common.ALAction,
   *      org.apache.turbine.util.RunData, org.apache.velocity.context.Context)
   */
  public void init(ALAction action, RunData rundata, Context context)
      throws ALPageNotFoundException, ALDBErrorException {
    String sort = ALEipUtils.getTemp(rundata, context, LIST_SORT_STR);
    if (sort == null || sort.equals("")) {
      ALEipUtils.setTemp(rundata, context, LIST_SORT_STR, "category_name");
      logger.debug("[AccountPlanSelectData] Init Parameter. : "
          + "category_name");
    }

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

  /**
   * 一覧データを取得します。 <BR>
   * 
   * @param rundata
   * @param context
   * @return
   * @see com.aimluck.eip.common.ALAbstractSelectData#selectList(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context)
   */
  protected List selectList(RunData rundata, Context context) 
    throws ALPageNotFoundException, ALDBErrorException {
      String tabParam = rundata.getParameters().getString("publictab");
      currentTab = ALEipUtils.getTemp(rundata, context, "publictab");
      if (tabParam == null && currentTab == null) {
        ALEipUtils.setTemp(rundata, context, "publictab", "list");
        currentTab = "list";
      } else if (tabParam != null) {
        ALEipUtils.setTemp(rundata, context, "publictab", tabParam);
        currentTab = tabParam;
      }
      
    try {
      DataContext dataContext = DatabaseOrmService.getInstance()
      .getDataContext();

      SelectQuery query = getSelectQuery(rundata, context);
      buildSelectQueryForListView(query);
      buildSelectQueryForListViewSort(query, rundata, context);

      List list = dataContext.performQuery(query);
      categorySum = list.size();
      
      return buildPaginatedList(list);
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return null;
    }
  }
  /**
   * 
   * @param rundata
   * @param context
   */
  public void loadDataList(RunData rundata, Context context) {
    // カテゴリリスト
    categoryList = new ArrayList();
    try {
      DataContext dataContext = DatabaseOrmService.getInstance()
          .getDataContext();
      SelectQuery query = new SelectQuery(ImwMItemCategory.class);

      List aList = dataContext.performQuery(query);
     
      int size = aList.size();
      for (int i = 0; i < size; i++) {
        ImwMItemCategory record = (ImwMItemCategory) aList.get(i);
        AccountPlanResultData rd = new AccountPlanResultData();
        rd.initField();
        rd.setCategoryId(record.getItemCategoryId().longValue());
        rd.setCategoryName(record.getItemCategoryName());
        categoryList.add(rd);
      }
    } catch (Exception ex) {
      logger.error("Exception", ex);
    }
    
    // 取引先リスト
    clientList = new ArrayList();
    try {
      DataContext dataContext = DatabaseOrmService.getInstance()
          .getDataContext();
      SelectQuery query = new SelectQuery(ImwMClient.class);

      Expression exp1 = ExpressionFactory.matchExp(
          ImwMClient.DISABLED_PROPERTY, 'F');
      query.setQualifier(exp1);
      List aList = dataContext.performQuery(query);

      int size = aList.size();
      for (int i = 0; i < size; i++) {
        ImwMClient record = (ImwMClient) aList.get(i);
        AccountPlanResultData rd = new AccountPlanResultData();
        rd.initField();
        rd.setClientId(record.getClientId().longValue());
        rd.setClientName(record.getClientName());
        clientList.add(rd);
      }
    } catch (Exception ex) {
      logger.error("Exception", ex);
    }
    
    // 一覧表示区分リスト
    accountClassList = new ArrayList();
    try {
      DataContext dataContext = DatabaseOrmService.getInstance()
          .getDataContext();
      SelectQuery query = new SelectQuery(ImwMHanyo.class);

      Expression exp1 = ExpressionFactory.matchExp(
          ImwMHanyo.DISABLED_PROPERTY, 'F');
      query.setQualifier(exp1);
      Expression exp2 = ExpressionFactory.matchExp(
          ImwMHanyo.PARENT_HANYO_ID_PROPERTY, 17);
      query.andQualifier(exp2);
      List aList = dataContext.performQuery(query);

      int size = aList.size();
      for (int i = 0; i < size; i++) {
        ImwMHanyo record = (ImwMHanyo) aList.get(i);
        AccountPlanResultData rd = new AccountPlanResultData();
        rd.initField();
        rd.setAccountClass(record.getValue());
        accountClassList.add(rd);
      }
    } catch (Exception ex) {
      logger.error("Exception", ex);
    }
  }

  /**
   * 検索条件を設定した SelectQuery を返します。 <BR>
   * 
   * @param rundata
   * @param context
   * @return
   */
  private SelectQuery getSelectQuery(RunData rundata, Context context) {
    SelectQuery query = new SelectQuery(ImwTAccountPlan.class);

//    Expression exp = ExpressionFactory.matchExp(
//        ImwTAccountPlan.DECIDE_FLAG_PROPERTY, Integer.valueOf(0));
//    query.setQualifier(exp);

//    SelectQuery query = new SelectQuery(ImwTAccount.class);
//
//    Expression exp = ExpressionFactory.matchExp(
//        ImwTAccount.DECIDE_FLAG_PROPERTY, Integer.valueOf(1));
//    query.setQualifier(exp);
    
    // タブ別表示データ
    if ("list".equals(currentTab)) {
      Expression exp = ExpressionFactory.matchExp(
          ImwTAccountPlan.DECIDE_FLAG_PROPERTY, Integer.valueOf(0));
      query.setQualifier(exp);
    } else if ("complete".equals(currentTab)) {
      Expression exp = ExpressionFactory.matchExp(
          ImwTAccountPlan.DECIDE_FLAG_PROPERTY, Integer.valueOf(1));
      query.setQualifier(exp);
    }
     
    return buildSelectQueryForFilter(query, rundata, context);
  }

  /**
   * フィルタ用の <code>SelectQuery</code> を構築します。
   * 
   * @param crt
   * @param rundata
   * @param context
   * @return
   */
  protected SelectQuery buildSelectQueryForFilter(SelectQuery query,
      RunData rundata, Context context) {
    String filter = ALEipUtils.getTemp(rundata, context, LIST_FILTER_STR);
    String filter_type = ALEipUtils.getTemp(rundata, context,
        LIST_FILTER_TYPE_STR);
    String crt_key = null;
    Attributes map = getColumnMap();
    if (filter == null || filter_type == null || filter.equals(""))
      return query;
    crt_key = map.getValue(filter_type);
    if (crt_key == null)
      return query;

    Expression exp = ExpressionFactory.matchExp(crt_key, Integer.valueOf(filter));
    query.andQualifier(exp);
    current_filter = filter;
    current_filter_type = filter_type;
    return query;
  }
  
  /**
   * 詳細データを取得します。 <BR>
   * 
   * @param rundata
   * @param context
   * @return
   * @see com.aimluck.eip.common.ALAbstractSelectData#selectDetail(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context)
   */
  protected Object selectDetail(RunData rundata, Context context)
      throws ALPageNotFoundException, ALDBErrorException {
    // オブジェクトモデルを取得
    return AccountPlanUtils.getImwTAccountPlan(rundata, context,false);
//    return AccountPlanUtils.getImwTAccount(rundata, context,false);
  }

  /**
   * ResultDataを取得します。（一覧データ） <BR>
   * 
   * @param obj
   * @return
   * @see com.aimluck.eip.common.ALAbstractSelectData#getListData(java.lang.Object)
   */
  protected Object getResultData(Object obj) {
    ImwTAccountPlan record = (ImwTAccountPlan) obj;
    AccountPlanResultData rd = new AccountPlanResultData();
    
    rd.initField();
    rd.setAccountPlanId(record.getAccountPlanId().longValue());
    
//    ImwTAccount record = (ImwTAccount) obj;
//    AccountPlanResultData rd = new AccountPlanResultData();
//    
//    rd.initField();
//    rd.setAccountPlanId(record.getAccountId().longValue());
    
    rd.setClientId(record.getImwMClient().getClientId().longValue());
    rd.setClientName(record.getImwMClient().getClientName());
    rd.setItemId(record.getImwMItem().getItemId().longValue());
    rd.setItemName(record.getImwMItem().getItemName());
    rd.setAccountDate(ALDateUtil.format(record.getAccountDate(), "yyyy年M月d日"));
    rd.setPrice(record.getPrice().toString());
    rd.setNote(record.getNote());
    rd.setCreateDate(record.getCreateData().toString());
    
    DataContext dataContext = DatabaseOrmService.getInstance()
      .getDataContext();
    SelectQuery query = new SelectQuery(ImwMItemCategory.class);

    Expression exp = ExpressionFactory.matchDbExp(
        ImwMItemCategory.ITEM_CATEGORY_ID_PK_COLUMN, record.getImwMItem().getItemCategoryId());
    query.setQualifier(exp);
    List list = dataContext.performQuery(query);
    if (list == null || list.size() == 0) {
      return null;
    }
    ImwMItemCategory imwmitemcategory = (ImwMItemCategory)list.get(0);
    rd.setAccountClass(imwmitemcategory.getAccountClass().toString());
    return rd;
  }

  /**
   * ResultDataを取得します。（詳細データ） <BR>
   * 
   * @param obj
   * @return
   * @see com.aimluck.eip.common.ALAbstractSelectData#getResultDataDetail(java.lang.Object)
   */
  protected Object getResultDataDetail(Object obj) {
    ImwTAccountPlan record = (ImwTAccountPlan) obj;
    AccountPlanResultData rd = new AccountPlanResultData();
//    ImwTAccount record = (ImwTAccount) obj;
//    AccountPlanResultData rd = new AccountPlanResultData();
    
    DataContext dataContext = DatabaseOrmService.getInstance()
    .getDataContext();
    
    // 入出金区分を取得する
    SelectQuery query = new SelectQuery(ImwMItemCategory.class);
    Expression exp = ExpressionFactory.matchDbExp(
        ImwMItemCategory.ITEM_CATEGORY_ID_PK_COLUMN, record.getImwMItem().getItemCategoryId());
    query.setQualifier(exp);
    List list = dataContext.performQuery(query);
    if (list == null || list.size() == 0) {
      return null;
    }
    ImwMItemCategory imwmitemcategory = (ImwMItemCategory)list.get(0);
    Integer accountclass = imwmitemcategory.getAccountClass();   
     
    // 顧客マスタ（取引先情報）を取得する
    Integer clientid = record.getImwMClient().getClientId();
    SelectQuery clientquery = new SelectQuery(ImwMClient.class);
    
    Expression exp1 = ExpressionFactory.matchDbExp(
        ImwMClient.CLIENT_ID_PK_COLUMN, Integer.valueOf(clientid));
    clientquery.setQualifier(exp1);
    List listclient = dataContext.performQuery(clientquery);
    if (listclient == null || listclient.size() == 0) {
      return null;
    }
    ImwMClient imwmclient = (ImwMClient)listclient.get(0);
    Integer moneyclass = null;
    
    if (accountclass == 1) {
      accountclass = 1;
      moneyclass = Integer.valueOf(imwmclient.getReceiptClass());
    }else if (accountclass == 2 || accountclass == 3) {
      accountclass = 2;
      moneyclass = Integer.valueOf(imwmclient.getPayClass());
    }

    // 汎用データを取得する
    ImwMHanyo imwmhanyo = AccountPlanUtils.getHanyoByKey(16, moneyclass.toString());
       
    rd.initField();
//    rd.setCategoryName(record.getImwMItem().getImwMItemCategory().getItemCategoryName());
//    rd.setSubCategoryName(record.getImwMItem().getImwMItemSubcategory().getItemSubcategoryName());
    rd.setItemName(record.getImwMItem().getItemName());
    rd.setClientName(record.getImwMClient().getClientName());
    rd.setMoneyClassName(imwmhanyo.getHanyokubunnm());
    if (accountclass == 2) {
      rd.setReceiptDate(ALDateUtil.format(record.getReceiptDate(),"yyyy年M月d日"));
    }else{
      rd.setBillingDate(ALDateUtil.format(record.getBillingDate(),"yyyy年M月d日"));  
    }
    
    if (moneyclass == 3) {
      // 区分：手形
      rd.setDraftNumber(record.getDraftNumber().toString());
      rd.setRemitter(imwmclient.getClientName().toString());
      rd.setRemittanceDate(ALDateUtil.format(record.getRemittanceDate(),"yyyy年M月d日"));
      rd.setPayBankName(record.getPayBankName());
      rd.setPayBankBranchName(record.getPayBankBranchName());
      rd.setChargeBankName(record.getChargeBankName());
      rd.setChargeBankBranchName(record.getChargeBankBranchName());
      if (record.getChargeMoney() != null) {
        rd.setChargeMoney(record.getChargeMoney().toString());
      }
      rd.setChargeDate(ALDateUtil.format(record.getChargeDate(), "yyyy年M月d日"));
      if (record.getChargeHandling() != null) {
        rd.setChargeHandling(record.getChargeHandling().toString());  
      }
    }

    rd.setAccountDate(ALDateUtil.format(record.getAccountDate(), "yyyy年M月d日"));
    rd.setPrice(record.getPrice().toString());
    rd.setNote(record.getNote());

    rd.setMoneyClass(moneyclass.toString());
    rd.setAccountClass(accountclass.toString());
    
    return rd;
  }

  /**
   * @return
   * @see com.aimluck.eip.common.ALAbstractSelectData#getColumnMap()
   */
  protected Attributes getColumnMap() {
    Attributes map = new Attributes();

    map.putValue("accountclass", ImwTAccountPlan.IMW_MITEM_PROPERTY + "."
        + ImwMItem.IMW_MITEM_CATEGORY_PROPERTY + "."
        + ImwMItemCategory.ACCOUNT_CLASS_PROPERTY);
//    map.putValue("accountclass", ImwTAccount.IMW_MITEM_PROPERTY + "."
//        + ImwMItem.IMW_MITEM_CATEGORY_PROPERTY + "."
//        + ImwMItemCategory.ACCOUNT_CLASS_PROPERTY);
    return map;
  }

  public int getCategorySum() {
    return categorySum;
  }
  
  /**
  *
  * @return
  */
 public ArrayList getCategoryList() {
   return categoryList;
 }

 /**
 *
 * @return
 */
public ArrayList getAccountClassList() {
  return accountClassList;
}


  /**
   * アクセス権限チェック用メソッド。<br />
   * アクセス権限の機能名を返します。
   * 
   * @return
   */
  public String getAclPortletFeature() {
    return ALAccessControlConstants.POERTLET_CASHFLOW;
  }
}
