/**
 * Copyright (c) 2006-2006 System Integrator Corporation.
 *                 All Rights Reserved.
 */
package jp.co.sint.basic;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;

import javax.servlet.http.HttpServletRequest;

import jp.co.sint.config.SIConfig;
import jp.co.sint.config.SIDBMultiConf;
import jp.co.sint.database.SIDBAccessException;
import jp.co.sint.database.SIDBUtil;
import jp.co.sint.tools.SICheckDataConf;
import jp.co.sint.tools.SICheckValid;
import jp.co.sint.tools.SICustomError;
import jp.co.sint.tools.SICustomErrors;
import jp.co.sint.tools.SIURLParameter;
import jp.co.sint.tools.SIUtil;

import org.apache.log4j.Category;

/**
 * @version $Id: SIProcess.java,v 1.0 2006/04/03 Exp $
 * @author 入金関連を処理します。 <br>
 * Description:
 * <p>
 * History
 * </p>
 * <p>
 * Author&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reason
 * </p>
 * ============&nbsp;&nbsp;&nbsp;==========&nbsp;&nbsp;===========================<br>
 * Hong.M.J 2006/04/03 12:20:42 Original
 */
public class SIProcess extends SIBasic {
  
  // ログ用のインスタンスの生成
  private static Category log = Category.getInstance(SIConfig.SILOG4J_WEBSHOP_CATEGORY_NAME);
  
  private String cmdtyCode = "";// 親コード
  
  private String individualCode = "";// 在庫コード
  
  private String cmdtyNameTxt = "";// 商品名
  
  private String processNumber = "";// 加工番号
  
  private String storeNumber = "";// 入庫番号
  
  private String processPrice = "0";// 加工価格
  
  private String branchCode = "";// 加工支店
  
  private String chargeCode = "";// 加工担当者
  
  private String makerName = "";// 加工先メーカー名
  
  private String paymentMethod = "";// 決済方法
  
  private String remarks = "";// 摘要
  
  private String initDateTime = "";// 登録日時(加工日)
  
  private String usedNewFlg = "";// 中古・新品区分
  
  private String storeDateTime = "";// 入庫日
  
  private String backUrl = "";
  
  /**
   * @return branchCode を戻します。
   */
  public String getBranchCode() {
    return branchCode;
  }
  
  /**
   * @param branchCode branchCode を設定。
   */
  public void setBranchCode(String branchCode) {
    this.branchCode = branchCode;
  }
  
  /**
   * @return chargeCode を戻します。
   */
  public String getChargeCode() {
    return chargeCode;
  }
  
  /**
   * @param chargeCode chargeCode を設定。
   */
  public void setChargeCode(String chargeCode) {
    this.chargeCode = chargeCode;
  }
  
  /**
   * @return cmdtyCode を戻します。
   */
  public String getCmdtyCode() {
    return cmdtyCode;
  }
  
  /**
   * @param cmdtyCode cmdtyCode を設定。
   */
  public void setCmdtyCode(String cmdtyCode) {
    this.cmdtyCode = cmdtyCode;
  }
  
  /**
   * @return cmdtyNameTxt を戻します。
   */
  public String getCmdtyNameTxt() {
    return cmdtyNameTxt;
  }
  
  /**
   * @param cmdtyNameTxt cmdtyNameTxt を設定。
   */
  public void setCmdtyNameTxt(String cmdtyNameTxt) {
    this.cmdtyNameTxt = cmdtyNameTxt;
  }
  
  /**
   * @return individualCode を戻します。
   */
  public String getIndividualCode() {
    return individualCode;
  }
  
  /**
   * @param individualCode individualCode を設定。
   */
  public void setIndividualCode(String individualCode) {
    this.individualCode = individualCode;
  }
  
  /**
   * @return initDateTime を戻します。
   */
  public String getInitDateTime() {
    return initDateTime;
  }
  
  /**
   * @param initDateTime initDateTime を設定。
   */
  public void setInitDateTime(String initDateTime) {
    this.initDateTime = initDateTime;
  }
  
  /**
   * @return makerName を戻します。
   */
  public String getMakerName() {
    return makerName;
  }
  
  /**
   * @param makerName makerName を設定。
   */
  public void setMakerName(String makerName) {
    this.makerName = makerName;
  }
  
  /**
   * @return paymentMethod を戻します。
   */
  public String getPaymentMethod() {
    return paymentMethod;
  }
  
  /**
   * @param paymentMethod paymentMethod を設定。
   */
  public void setPaymentMethod(String paymentMethod) {
    this.paymentMethod = paymentMethod;
  }
  
  /**
   * @return processNumber を戻します。
   */
  public String getProcessNumber() {
    return processNumber;
  }
  
  /**
   * @param processNumber processNumber を設定。
   */
  public void setProcessNumber(String processNumber) {
    this.processNumber = processNumber;
  }
  
  /**
   * @return processPrice を戻します。
   */
  public String getProcessPrice() {
    return processPrice;
  }
  
  /**
   * @param processPrice processPrice を設定。
   */
  public void setProcessPrice(String processPrice) {
    if (SIUtil.isNull(processPrice)) this.processPrice = "0";
    this.processPrice = processPrice;
  }
  
  /**
   * @return remarks を戻します。
   */
  public String getRemarks() {
    return remarks;
  }
  
  /**
   * @param remarks remarks を設定。
   */
  public void setRemarks(String remarks) {
    this.remarks = remarks;
  }
  
  /**
   * @return storeDateTime を戻します。
   */
  public String getStoreDateTime() {
    return storeDateTime;
  }
  
  /**
   * @param storeDateTime storeDateTime を設定。
   */
  public void setStoreDateTime(String storeDateTime) {
    this.storeDateTime = storeDateTime;
  }
  
  /**
   * @return storeNumber を戻します。
   */
  public String getStoreNumber() {
    return storeNumber;
  }
  
  /**
   * @param storeNumber storeNumber を設定。
   */
  public void setStoreNumber(String storeNumber) {
    this.storeNumber = storeNumber;
  }
  
  /**
   * @return usedNewFlg を戻します。
   */
  public String getUsedNewFlg() {
    return usedNewFlg;
  }
  
  /**
   * @param usedNewFlg usedNewFlg を設定。
   */
  public void setUsedNewFlg(String usedNewFlg) {
    this.usedNewFlg = usedNewFlg;
  }
  
  /**
   * @return backUrl を戻します。
   */
  public String getBackUrl() {
    return backUrl;
  }
  
  /**
   * @param backUrl backUrl を設定。
   */
  public void setBackUrl(String backUrl) {
    this.backUrl = backUrl;
  }
  
  /**
   * <b>initDetail</b> 入力したデータを基づいて、このbeansを設定します。
   * 
   * @param request クライアントからリクエスト
   * @param lUrlParam
   * @return なし
   * @throws なし
   */
  public void init(HttpServletRequest lRequest, SIURLParameter lUrlParam) {
    this.setEncode(SIConfig.SIENCODE_SHIFT_JIS);
    super.init(lRequest, lUrlParam);
    this.setIndividualCode((String) lUrlParam.getParam("individualCode"));// 在庫コード
    this.setCmdtyCode((String) lUrlParam.getParam("cmdtyCode"));// 商品コード
    this.setCmdtyNameTxt((String) lUrlParam.getParam("cmdtyName"));// 商品名
    this.setProcessNumber((String) lUrlParam.getParam("processNumber"));// 加工番号
    this.setUsedNewFlg((String) lUrlParam.getParam("usedNewFlg"));
    this.setProcessPrice((String) lUrlParam.getParam("processPrice"));// 加工価格
    this.setBranchCode((String) lUrlParam.getParam("branchCode"));// 加工支店
    this.setChargeCode((String) lUrlParam.getParam("chargeCode"));// 加工担当者
    this.setMakerName((String) lUrlParam.getParam("makerName"));// 加工先メーカー名
    this.setPaymentMethod((String) lUrlParam.getParam("paymentMethod"));// 決済方法
    this.setRemarks((String) lUrlParam.getParam("remarks"));// 摘要
    this.setBackUrl((String) lUrlParam.getParam("backUrl"));
    this.setStoreDateTime((String) lUrlParam.getParam("storeDateTime"));
  }
  
  /**
   * <b>initDetail</b> 入力したデータを基づいて、このbeansを設定します。
   * 
   * @param request クライアントからリクエスト
   * @param lUrlParam
   * @return なし
   * @throws なし
   */
  public void initDetail(HttpServletRequest lRequest, SIURLParameter lUrlParam) {
    this.setEncode(SIConfig.SIENCODE_SHIFT_JIS);
    super.init(lRequest, lUrlParam);
    this.setCmdtyCode((String) lUrlParam.getParam("cmdtyCodeTxt"));// 商品コード
    this.setIndividualCode((String) lUrlParam.getParam("individualCodeTxt"));// 在庫コード
    this.setProcessNumber((String) lUrlParam.getParam("processNumber"));// 加工番号
    this.setBackUrl((String) lUrlParam.getParam("backUrl"));
    
  }
  
  /**
   * <b>validate</b> 入力したデータをチェックして、同時にSQLの条件文を作成します。
   * 
   * @param lRequest クライアントからのリクエスト
   * @return なし
   * @throws なし
   */
  public boolean validate(HttpServletRequest lRequest) {
    
    SICustomErrors errors = new SICustomErrors();
    
    // 加工支店
    SICheckValid.checkValid(errors, "加工支店", this.getBranchCode(), SICheckDataConf.SICHECK_DATA_EMPTY_TYPE);
    // 加工担当者
    SICheckValid.checkValid(errors, "加工担当者", this.getChargeCode(), SICheckDataConf.SICHECK_DATA_EMPTY_TYPE);
    // 加工先メーカー
    SICheckValid.checkValid(errors, "加工先メーカー", this.getMakerName(), SICheckDataConf.SICHECK_DATA_EMPTY_TYPE + SICheckDataConf.SICHECK_DATA_ZENKAKU_TYPE);
    // 決済方法
    SICheckValid.checkValid(errors, "決済方法", this.getPaymentMethod(), SICheckDataConf.SICHECK_DATA_EMPTY_TYPE + SICheckDataConf.SICHECK_DATA_DIGIT_TYPE);
    // 加工価格
    SICheckValid.checkValid(errors, "加工価格", this.getProcessPrice(), SICheckDataConf.SICHECK_DATA_EMPTY_TYPE + SICheckDataConf.SICHECK_DATA_DIGIT_TYPE);
    if (this.getProcessPrice().equals("0")) errors.addError(new SICustomError("input.data.instock.less", "加工価格", "1"));
    if (!errors.isEmpty()) {
      lRequest.setAttribute(SIConfig.SIERROR_ATTRIBUTE_MESSAGE_KEY, errors);
      return false;
    } else {
      lRequest.removeAttribute(SIConfig.SIERROR_ATTRIBUTE_MESSAGE_KEY);
      return true;
    }
  }
  
  public boolean validateNew(Connection lConnection) {
    String amount = "0";
    try {
      amount = SIDBUtil.getFirstData(lConnection, "SELECT total FROM realstocktotalvw WHERE cmdtyCode='" + this.cmdtyCode + "' AND individualCode='" + this.individualCode + "'");
    } catch (Exception e) {
      amount = "0";
    }
    return SIUtil.isNotNull(amount) && !amount.equals("0");
  }
  
  /**
   * <b>reset</b> 対象在庫コードの明細を取得する
   * 
   * @param lConnection
   * @return なし
   * @throws なし
   */
  public void reset(Connection lConnection) {
    Statement lStatement = null;
    ResultSet lResultSet = null;
    StringBuffer lSqlBuf = new StringBuffer();
    
    if (getEditModeTxt().equalsIgnoreCase(SIConfig.SIEDIT_MODE_INSERT)) {// 新規登録時
      lSqlBuf.append("SELECT bb.cmdtyCode, cc.individualCode, cc.usedNewFlg, bb.cmdtyname FROM individualtbl ").append(SIDBMultiConf.SIALIAS_CURR_NAME).append("cc, ");
      lSqlBuf.append(" cmdtymtbl ").append(SIDBMultiConf.SIALIAS_CURR_NAME).append(" bb ");
      lSqlBuf.append("WHERE 1=1");
      lSqlBuf.append(" AND bb.cmdtyCode = cc.cmdtyCode");
      lSqlBuf.append(" AND bb.cmdtyCode = ").append(SIDBUtil.SQL2Str(this.getCmdtyCode()));
      lSqlBuf.append(" AND cc.individualCode =").append(SIDBUtil.SQL2Str(this.getIndividualCode()));
    } else {// アップデート時
      lSqlBuf.append("SELECT aa.*,bb.usedNewFlg, cc.cmdtyname ,his.initdatetime AS storedate ");
      lSqlBuf.append("FROM ").append(SIConfig.SITABLE_CMDTY_PROCESS_NAME).append(" AS aa ");
      lSqlBuf.append("LEFT OUTER JOIN storehistorytbl AS his ");
      lSqlBuf.append("ON (his.cmdtycode = aa.cmdtycode AND his.individualcode = aa.individualcode AND his.storenumber = aa.storenumber) ");
      lSqlBuf.append(",individualtbl AS bb ");
      lSqlBuf.append(",cmdtymtbl AS cc ");
      lSqlBuf.append("WHERE aa.cmdtyCode = bb.cmdtyCode ");
      lSqlBuf.append("AND aa.cmdtyCode = cc.cmdtyCode ");
      lSqlBuf.append("AND aa.individualCode = bb.individualCode ");
      lSqlBuf.append("AND aa.cmdtyCode = ").append(SIDBUtil.SQL2Str(this.getCmdtyCode(), " "));
      lSqlBuf.append("AND aa.individualCode = ").append(SIDBUtil.SQL2Str(this.getIndividualCode(), " "));
      lSqlBuf.append("AND aa.processNumber = ").append(this.getProcessNumber());
    }
    
    log.debug("lSqlBuf=" + lSqlBuf.toString());
    // 実行
    try {
      lStatement = lConnection.createStatement();
      lResultSet = lStatement.executeQuery(lSqlBuf.toString());
      
      // 商品レコードのセットの作成
      while (lResultSet.next()) {
        this.setCmdtyCode(lResultSet.getString("cmdtyCode"));// //親コード
        this.setIndividualCode(lResultSet.getString("individualCode"));// 在庫コード
        this.setCmdtyNameTxt(lResultSet.getString("cmdtyname"));// 商品名
        this.setUsedNewFlg(lResultSet.getString("usedNewFlg"));// 中古・新品区分
        
        if (!getEditModeTxt().equalsIgnoreCase(SIConfig.SIEDIT_MODE_INSERT)) {// 編集時
          this.setProcessNumber(lResultSet.getString("processNumber"));// 加工番号
          this.setStoreNumber(lResultSet.getString("storeNumber"));// 入庫番号
          this.setProcessPrice(lResultSet.getString("processPrice"));// 加工価格
          this.setBranchCode(lResultSet.getString("branchCode"));// 加工支店
          this.setChargeCode(lResultSet.getString("chargeCode"));// 加工担当者
          this.setMakerName(lResultSet.getString("makerName"));// 加工先メーカー名
          this.setPaymentMethod(lResultSet.getString("paymentMethod"));// 決済方法
          this.setRemarks(lResultSet.getString("remarks"));// 摘要
          this.setInitDateTime(SIDBUtil.getDate(lResultSet.getTimestamp("initDateTime")));// 登録日時(加工日)
          this.setStoreDateTime(lResultSet.getString("storedate"));
        }
        
      }
    } catch (Exception ex) {
      ex.getStackTrace();
    } finally {
      SIDBUtil.close(lResultSet, lStatement);
    }
  }
  
  /**
   * <b>getCompanyCollection<b> 条件に合ったレコードを検索して、結果のコレクションを作成して戻します。
   * 
   * @param lConnection データベースへの接続コネクション
   * @return レコードのセット
   * @throws SIDBAccessException
   */
  public static Collection getCompanyCollection(Connection lConnection, SILogin lLogin) throws SIDBAccessException {
    StringBuffer lSqlBuf = new StringBuffer();
    
    lSqlBuf.append("SELECT BranchName,BranchCode ");
    lSqlBuf.append("FROM BranchTbl ");
    lSqlBuf.append("ORDER BY BranchCode ASC");
    
    log.debug("getCompanyCollection:lSqlBuf=" + lSqlBuf.toString());
    
    Collection lResultColl = new ArrayList();
    
    try {
      lResultColl = SIDBUtil.getCollection(lConnection, lSqlBuf.toString(), false, true);
    } catch (SIDBAccessException e) {
      e.printStackTrace();
    }
    return lResultColl;
  }
  
  /**
   * <b>getChargeCollection<b> 条件に合ったレコードを検索して、結果のコレクションを作成して戻します。
   * 
   * @param lConnection データベースへの接続コネクション
   * @return レコードのセット
   * @throws SIDBAccessException
   */
  public static Collection getChargeCollection(Connection lConnection, SILogin lLogin) throws SIDBAccessException {
    StringBuffer lSqlBuf = new StringBuffer();
    
    lSqlBuf.append("SELECT ChargeName,ChargeCode FROM ChargeTbl ");
    lSqlBuf.append("ORDER BY ChargeCode ASC");
    
    log.debug("getChargeCollection:lSqlBuf=" + lSqlBuf.toString());
    
    Collection lResultColl = new ArrayList();
    
    try {
      lResultColl = SIDBUtil.getCollection(lConnection, lSqlBuf.toString(), false, true);
    } catch (SIDBAccessException e) {
      e.printStackTrace();
    }
    return lResultColl;
  }
  
  /**
   * <b>getPaymentNumber</b> 加工番号を取得する
   * 
   * @param lConnection
   * @return なし
   * @throws SIDBAccessException
   */
  public String getProcessNumber(Connection lConnection) throws SIDBAccessException {
    
    String result = new String("0");
    StringBuffer lSqlBuf = new StringBuffer();
    lSqlBuf.append("SELECT COALESCE(MAX(ProcessNumber),0)+1 ");
    lSqlBuf.append(" FROM ").append(SIConfig.SITABLE_CMDTY_PROCESS_NAME);
    lSqlBuf.append(" WHERE CMDTYCODE = ").append(SIDBUtil.SQL2Str(this.getCmdtyCode()));
    lSqlBuf.append(" AND INDIVIDUALCODE = ").append(SIDBUtil.SQL2Str(this.getIndividualCode()));
    result = SIDBUtil.getFirstData(lConnection, lSqlBuf.toString());
    return result;
  }
}
