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

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;

import jp.co.sint.config.SIConfig;
import jp.co.sint.database.SIDBUtil;
import jp.co.sint.tools.SICheckUtil;
import jp.co.sint.tools.SIDateTime;
import jp.co.sint.tools.SIException;
import jp.co.sint.tools.SIUtil;

import org.apache.log4j.Category;

/**
 * @version $Id: SIPointRule.java,v 1.0 2003/09/16 Exp $
 * @author Arai Makoto <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>
 * Arai Makoto 2003/09/16 10:56:43 Original
 */
public class SIPointRule extends SIBasic {
  // ログ用のインスタンスの生成
  private static Category log = Category.getInstance(SIConfig.SILOG4J_WEBSHOP_CATEGORY_NAME);
  
  private String mallShopCode = "";
  private String minCost = "0";
  private String pointRate = "0";
  private String initPoint = "0";
  private String setDateOfBonus = "";
  private String bonusFromDate = "";
  private String bonusToDate = "";
  private String bonusPointRate = "0";
  private String specialRate = "1.0";
  private String stndrdOfIssue = "";
  private String period = "";
  private String delFlg = "";
  
  private String vipRate1 = "1.2";//ゴールド会員用最終倍率
  private String vipRate2 = "1.5";//プラチナ会員用最終倍率
  private String vipRate3 = "2.0";//ダイヤモンド会員用最終倍率
  
  public SIPointRule() {}
  
  public SIPointRule(String lMallShopCode) {
    setMallShopCode(lMallShopCode);
  }
  
  /**
   * @return
   */
  public String getBonusFromDate() {
    return bonusFromDate;
  }
  
  /**
   * @return
   */
  public String getBonusPointRate() {
    return bonusPointRate;
  }
  
  /**
   * @return
   */
  public String getBonusToDate() {
    return bonusToDate;
  }
  
  /**
   * @return
   */
  public String getInitPoint() {
    return initPoint;
  }
  
  /**
   * @return
   */
  public String getMallShopCode() {
    return mallShopCode;
  }
  
  /**
   * @return
   */
  public String getMinCost() {
    return minCost;
  }
  
  /**
   * @return
   */
  public String getPeriod() {
    return period;
  }
  
  /**
   * @return
   */
  public String getPointRate() {
    return pointRate;
  }
  
  /**
   * @return
   */
  public String getSetDateOfBonus() {
    return setDateOfBonus;
  }
  
  /**
   * @return
   */
  public String getStndrdOfIssue() {
    return stndrdOfIssue;
  }
  
  /**
   * @param string
   */
  public void setBonusFromDate(String string) {
    if (SIUtil.isNull(string)) string = "";
    this.bonusFromDate = SIUtil.changeTo(string.trim(), this.encode);
  }
  
  /**
   * @param string
   */
  public void setBonusPointRate(String string) {
    if (SIUtil.isNull(string)) string = "";
    this.bonusPointRate = SIUtil.changeTo(string.trim(), this.encode);
  }
  
  /**
   * @param string
   */
  public void setBonusToDate(String string) {
    if (SIUtil.isNull(string)) string = "";
    this.bonusToDate = SIUtil.changeTo(string.trim(), this.encode);
  }
  
  /**
   * @param string
   */
  public void setInitPoint(String string) {
    if (SIUtil.isNull(string)) string = "";
    this.initPoint = SIUtil.changeTo(string.trim(), this.encode);
  }
  
  /**
   * @param string
   */
  public void setMallShopCode(String string) {
    if (SIUtil.isNull(string)) string = "";
    this.mallShopCode = SIUtil.changeTo(string.trim(), this.encode);
  }
  
  /**
   * @param string
   */
  public void setMinCost(String string) {
    if (SIUtil.isNull(string)) string = "";
    this.minCost = SIUtil.changeTo(string.trim(), this.encode);
  }
  
  /**
   * @param string
   */
  public void setPeriod(String string) {
    if (SIUtil.isNull(string)) string = "";
    this.period = SIUtil.changeTo(string.trim(), this.encode);
  }
  
  /**
   * @param string
   */
  public void setPointRate(String string) {
    if (SIUtil.isNull(string)) string = "";
    this.pointRate = SIUtil.changeTo(string.trim(), this.encode);
  }
  
  /**
   * @param string
   */
  public void setSetDateOfBonus(String string) {
    if (SIUtil.isNull(string)) string = "";
    this.setDateOfBonus = SIUtil.changeTo(string.trim(), this.encode);
  }
  
  /**
   * @param string
   */
  public void setStndrdOfIssue(String string) {
    if (SIUtil.isNull(string)) string = "";
    this.stndrdOfIssue = SIUtil.changeTo(string.trim(), this.encode);
  }
  
  //getter of delFlg
  public String getDelFlg() {
    return this.delFlg;
  }
  
  //setter of delFlg
  public void setDelFlg(String delFlg) {
    if (SIUtil.isNull(delFlg)) delFlg = "";
    this.delFlg = SIUtil.changeTo(delFlg.trim(), this.encode);
  }
  
  public String getSpecialRate() {
    return specialRate;
  }
  
  public void setSpecialRate(String specialRate) {
    if (SIUtil.isNull(specialRate)) specialRate = "1.0";
    this.specialRate = specialRate;
  }
  
  /**
   * <b>reset</b> SQLからポイントルールの情報を取得しセッターに格納
   * 
   * @param Connection
   * @return boolean 結果が存在するかどうか
   * @throws なし
   */
  public boolean reset(Connection lConnection) {
    boolean lResult = false;
    
    Statement lStatement = null;
    ResultSet lResultSet = null;
    StringBuffer lSqlBuf = new StringBuffer();
    lSqlBuf.append("SELECT * FROM PointShopMTbl ");
    lSqlBuf.append("WHERE MallShopCode=").append(SIDBUtil.SQL2Str(this.getMallShopCode(), " "));
    
    log.debug("reset:lSqlBuf=" + lSqlBuf.toString());
    try {
      lStatement = lConnection.createStatement();
      lResultSet = lStatement.executeQuery(lSqlBuf.toString());
      
      if (lResultSet.next()) {
        this.setEncode(SIConfig.SIENCODE_NONE);
        lResult = true;
        this.setEncode(SIConfig.SIENCODE_NONE);
        this.setMallShopCode(lResultSet.getString("MallShopCode"));
        this.setMinCost(lResultSet.getString("MinCost"));
        this.setPointRate(lResultSet.getString("PointRate"));
        this.setInitPoint(lResultSet.getString("InitPoint"));
        this.setSetDateOfBonus(lResultSet.getString("SetDateOfBonus"));
        this.setBonusFromDate(SIDBUtil.getDate(lResultSet.getTimestamp("BonusFromDate")));
        this.setBonusToDate(SIDBUtil.getDate(lResultSet.getTimestamp("BonusToDate")));
        this.setBonusPointRate(lResultSet.getString("BonusPointRate"));
        this.setStndrdOfIssue(lResultSet.getString("StndrdOfIssue"));
        this.setPeriod(lResultSet.getString("Period"));
        this.setSpecialRate(lResultSet.getString("specialRate"));
        lResult = true;
      } else {
        log.error("not find record for mallshopcode=" + getMallShopCode());
      }
    } catch (SQLException sqle) {
      sqle.printStackTrace();
    } finally {
      SIDBUtil.close(lStatement, lResultSet);
    }
    return lResult;
  }
  
  /**
   * <b>calcPoint</b>
   * 
   * @param Connection
   * @param lPrice
   * @param boolean
   * @return boolean 結果が存在するかどうか
   * @throws なし
   */
  /*
  public String calcPoint(Connection lConnection, String lPrice, String custCode, boolean lInitFlg) {
    log.debug("calcPoint:lPrice=" + lPrice + ",lInitFlg=" + lInitFlg);
    String lResPoint = "0";
    SIDateTime lDateTime = new SIDateTime();
    
    // 初回購入時
    if (lInitFlg) {
      lResPoint = getInitPoint();
      log.debug("calcPoint:init setup,lResPoint,getInitPoint()=" + getInitPoint());
    }
    
    // 最低購入金額
    if (SIUtil.isNull(lPrice)) lPrice = "0";
    if (Long.parseLong(lPrice) < Long.parseLong(getMinCost())) return lResPoint;
    
    try {
      // From To
      if (SIUtil.isNotNull(getBonusFromDate()) && SIUtil.isNotNull(getBonusToDate())) {
        if (!SICheckUtil.dateGreater(getBonusFromDate(), lDateTime.getFullDate()) && !SICheckUtil.dateLess(getBonusToDate(), lDateTime.getFullDate())
            || lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getBonusPointRate(), "100")));
        } else {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getPointRate(), "100")));
        }
        // From
      } else if (SIUtil.isNotNull(getBonusFromDate()) && SIUtil.isNull(getBonusToDate())) {
        if (!SICheckUtil.dateGreater(getBonusFromDate(), lDateTime.getFullDate()) || lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getBonusPointRate(), "100")));
        } else {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getPointRate(), "100")));
        }
        // To
      } else if (SIUtil.isNull(getBonusFromDate()) && SIUtil.isNotNull(getBonusToDate())) {
        if (!SICheckUtil.dateLess(getBonusToDate(), lDateTime.getFullDate()) || lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getBonusPointRate(), "100")));
        } else {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getPointRate(), "100")));
        }
      } else {
        if (lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getBonusPointRate(), "100")));
        } else {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getPointRate(), "100")));
        }
      }
      
      //会員種別による最終倍率設定
      StringBuffer lSql = new StringBuffer();
      lSql.append("SELECT CASE WHEN nopointflg=1 THEN 0 WHEN memberlevelcode=1 THEN 1 ");
      lSql.append("WHEN memberlevelcode=2 THEN 2 ELSE null END AS rate ");
      lSql.append("FROM custtbl WHERE custcode=").append(SIDBUtil.SQL2Str(custCode));
      
      String pointFlg = SIDBUtil.getFirstData(lConnection, lSql.toString());
      if (SIUtil.isNotNull(pointFlg)&&"0".equals(pointFlg)) {//ポイント無効
        lResPoint = "0";
      } else if (SIUtil.isNotNull(pointFlg)&&"1".equals(pointFlg)) {//ゴールド会員（メンバーレベルコード１）
        lResPoint = SIUtil.multi_LD(lResPoint, vipRate1);
      } else if (SIUtil.isNotNull(pointFlg)&&"2".equals(pointFlg)) {//プラチナ会員（メンバーレベルコード２）
        lResPoint = SIUtil.multi_LD(lResPoint, vipRate2);
      }
    } catch (ParseException e) {
      e.printStackTrace();
    } catch (SIException e) {
      e.printStackTrace();
    }
    log.debug("getBonusFromDate()=" + getBonusFromDate() + ",getBonusToDate()=" + getBonusFromDate());
    log.debug("lDateTime.getFullDate()=" + lDateTime.getFullDate() + ",lResPoint=" + lResPoint);
    log.debug("getBonusPointRate()=" + getBonusPointRate() + ",getPointRate()=" + getPointRate());
    
    log.debug("calcPoint:lResPoint=" + lResPoint);
    return lResPoint;
  }
  */
  
  /**
   * <b>calcPoint</b>
   * 
   * @param Connection
   * @param lPrice
   * @param boolean
   * @return boolean 結果が存在するかどうか
   * @throws なし
   */
  /*
  public String calcPointInUpdateOrder(Connection lConnection, String lPrice, String custCode, boolean lInitFlg, String lOrderDate) {
    log.debug("calcPoint:lPrice=" + lPrice + ",lInitFlg=" + lInitFlg);
    String lResPoint = "0";
    SIDateTime lDateTime = new SIDateTime();
    try {
      lDateTime = new SIDateTime(lOrderDate);
    } catch (Exception e) {}
    
    // 初回購入時
    if (lInitFlg) {
      lResPoint = getInitPoint();
      log.debug("calcPoint:init setup,lResPoint,getInitPoint()=" + getInitPoint());
    }
    
    // 最低購入金額
    if (SIUtil.isNull(lPrice)) lPrice = "0";
    if (Long.parseLong(lPrice) < Long.parseLong(getMinCost())) return lResPoint;
    
    try {
      // From To
      if (SIUtil.isNotNull(getBonusFromDate()) && SIUtil.isNotNull(getBonusToDate())) {
        if (!SICheckUtil.dateGreater(getBonusFromDate(), lDateTime.getFullDate()) && !SICheckUtil.dateLess(getBonusToDate(), lDateTime.getFullDate())
            || lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getBonusPointRate(), "100")));
        } else {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getPointRate(), "100")));
        }
        // From
      } else if (SIUtil.isNotNull(getBonusFromDate()) && SIUtil.isNull(getBonusToDate())) {
        if (!SICheckUtil.dateGreater(getBonusFromDate(), lDateTime.getFullDate()) || lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getBonusPointRate(), "100")));
        } else {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getPointRate(), "100")));
        }
        // To
      } else if (SIUtil.isNull(getBonusFromDate()) && SIUtil.isNotNull(getBonusToDate())) {
        if (!SICheckUtil.dateLess(getBonusToDate(), lDateTime.getFullDate()) || lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getBonusPointRate(), "100")));
        } else {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getPointRate(), "100")));
        }
      } else {
        if (lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getBonusPointRate(), "100")));
        } else {
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lPrice, SIUtil.div_DL(getPointRate(), "100")));
        }
      }
      
      //会員種別による最終倍率設定
      StringBuffer lSql = new StringBuffer();
      lSql.append("SELECT CASE WHEN nopointflg=1 THEN 0 WHEN memberlevelcode=1 THEN 1 ");
      lSql.append("WHEN memberlevelcode=2 THEN 2 ELSE null END AS rate ");
      lSql.append("FROM custtbl WHERE custcode=").append(SIDBUtil.SQL2Str(custCode));
      
      String pointFlg = SIDBUtil.getFirstData(lConnection, lSql.toString());
      if (SIUtil.isNotNull(pointFlg)&&"0".equals(pointFlg)) {//ポイント無効
        lResPoint = "0";
      } else if (SIUtil.isNotNull(pointFlg)&&"1".equals(pointFlg)) {//ゴールド会員（メンバーレベルコード１）
        lResPoint = SIUtil.multi_LD(lResPoint, vipRate1);
      } else if (SIUtil.isNotNull(pointFlg)&&"2".equals(pointFlg)) {//プラチナ会員（メンバーレベルコード２）
        lResPoint = SIUtil.multi_LD(lResPoint, vipRate2);
      }
    } catch (ParseException e) {
      e.printStackTrace();
    } catch (SIException e) {
      e.printStackTrace();
    }
    log.debug("getBonusFromDate()=" + getBonusFromDate() + ",getBonusToDate()=" + getBonusFromDate());
    log.debug("lDateTime.getFullDate()=" + lDateTime.getFullDate() + ",lResPoint=" + lResPoint);
    log.debug("getBonusPointRate()=" + getBonusPointRate() + ",getPointRate()=" + getPointRate());
    
    log.debug("calcPoint:lResPoint=" + lResPoint);
    return lResPoint;
  }
  */
  
  /**
   * <b>calcPoint</b>
   * 
   * @param Connection
   * @param lCmdtyPrice (individualCode,totalPrice)
   * @param discountPrice
   * @param boolean
   * @return String 獲得ポイント
   * @throws なし
   */
  public String calcPoint(Connection lConnection, String[][] lCmdtyPrice, String discountPrice, String custCode, boolean lInitFlg) {
    String lResPoint = "0";
    String totalPrice = "0";
    String ctgryBonusRate = "";
    String individualBonusRate = "";
    String[] temp = {"",""};
    SIDateTime lDateTime = new SIDateTime();
    StringBuffer str = new StringBuffer();
    boolean isBonus=false;
    
    // 初回購入時
    if (lInitFlg) {
      lResPoint = getInitPoint();
      log.debug("calcPoint:init setup,lResPoint,getInitPoint()=" + getInitPoint());
    }
    
    for (int i=0;i<lCmdtyPrice.length;i++){
      totalPrice = SIUtil.add(totalPrice, lCmdtyPrice[i][1]);
    }
    
    // 最低購入金額
    if (SIUtil.isNull(totalPrice)) totalPrice = "0";
    if (Long.parseLong(totalPrice) < Long.parseLong(getMinCost())) return lResPoint;
    
    try {
      for (int j=0;j<lCmdtyPrice.length;j++){
        str = new StringBuffer();
        str.append("SELECT bonuspointrate FROM bonuspointtbl WHERE ctgrycode = ").append(SIDBUtil.SQL2Str(lCmdtyPrice[j][0].substring(0, 2)," "));
        str.append("AND bonusfromdate <= current_date AND bonustodate >= current_date");
        
        ctgryBonusRate = SIDBUtil.getFirstData(lConnection, str.toString());//カテゴリボーナス
        
        str = new StringBuffer();
        str.append("SELECT bonuspointrate FROM bonuspointindividualtbl WHERE individualcode = ").append(SIDBUtil.SQL2Str(lCmdtyPrice[j][0]," "));
        str.append("AND bonusfromdate <= current_date AND bonustodate >= current_date");
        
        individualBonusRate = SIDBUtil.getFirstData(lConnection, str.toString());//カテゴリボーナス
        
        // From To
        if (SIUtil.isNotNull(getBonusFromDate()) && SIUtil.isNotNull(getBonusToDate())) {
          if (!SICheckUtil.dateGreater(getBonusFromDate(), lDateTime.getFullDate()) && !SICheckUtil.dateLess(getBonusToDate(), lDateTime.getFullDate())
              || lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
            lCmdtyPrice[j][0] = getBonusPointRate();
            isBonus = true;
          } else {
            lCmdtyPrice[j][0] = getPointRate();
          }
        // From
        } else if (SIUtil.isNotNull(getBonusFromDate()) && SIUtil.isNull(getBonusToDate())) {
          if (!SICheckUtil.dateGreater(getBonusFromDate(), lDateTime.getFullDate()) || lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
            lCmdtyPrice[j][0] = getBonusPointRate();
            isBonus = true;
          } else {
            lCmdtyPrice[j][0] = getPointRate();
          }
        // To
        } else if (SIUtil.isNull(getBonusFromDate()) && SIUtil.isNotNull(getBonusToDate())) {
          if (!SICheckUtil.dateLess(getBonusToDate(), lDateTime.getFullDate()) || lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
            lCmdtyPrice[j][0] = getBonusPointRate();
            isBonus = true;
          } else {
            lCmdtyPrice[j][0] = getPointRate();
          }
        } else {
          if (lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
            lCmdtyPrice[j][0] = getBonusPointRate();
            isBonus = true;
          } else {
            lCmdtyPrice[j][0] = getPointRate();
          }
        }
        //個別設定orカテゴリ別設定があればレート上書き
        if(SIUtil.isNotNull(individualBonusRate)){
          log.debug("individualCode=" + lCmdtyPrice[j][0] + ",IndividualBonusPointRate()=" + individualBonusRate);
          lCmdtyPrice[j][0] = individualBonusRate;
        }else if(SIUtil.isNotNull(ctgryBonusRate)){
          log.debug("individualHeader=" + lCmdtyPrice[j][0].substring(0, 2) + ",CtgryBonusPointRate()=" + ctgryBonusRate);
          lCmdtyPrice[j][0] = ctgryBonusRate;
        }
      }
      for (int k1=0;k1<lCmdtyPrice.length;k1++){
        //各商品購入額をポイントレート（降順）、金額（昇順）にソート
        for (int k2=k1;k2<lCmdtyPrice.length;k2++){
          if((Double.parseDouble(lCmdtyPrice[k1][0]) < Double.parseDouble(lCmdtyPrice[k2][0]))
           || (lCmdtyPrice[k1][0].equals(lCmdtyPrice[k2][0]) && (Integer.parseInt(lCmdtyPrice[k1][1]) > Integer.parseInt(lCmdtyPrice[k2][1])))){
            temp[0] = lCmdtyPrice[k2][0];
            temp[1] = lCmdtyPrice[k2][1];
            lCmdtyPrice[k2][0] = lCmdtyPrice[k1][0];
            lCmdtyPrice[k2][1] = lCmdtyPrice[k1][1];
            lCmdtyPrice[k1][0] = temp[0];
            lCmdtyPrice[k1][1] = temp[1];
          }
        }
        //割引額がなくなるまでマイナス
        if(!discountPrice.equals("0")){
          if(SICheckUtil.isGreater(lCmdtyPrice[k1][1],discountPrice)){
            lCmdtyPrice[k1][1] = SIUtil.sub(lCmdtyPrice[k1][1], discountPrice);
            discountPrice = "0";
          }else{
            discountPrice = SIUtil.sub(discountPrice, lCmdtyPrice[k1][1]);
            lCmdtyPrice[k1][1] = "0";
          }
        }
        //ポイント加算
        if(!lCmdtyPrice[k1][1].equals("0")){
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lCmdtyPrice[k1][1], SIUtil.div_DL(lCmdtyPrice[k1][0], "100")));
        }
      }
      
      //会員種別による最終倍率設定
      StringBuffer lSql = new StringBuffer();
      lSql.append("SELECT CASE WHEN nopointflg=1 THEN 0 WHEN memberlevelcode=1 THEN 1 ");
      lSql.append("WHEN memberlevelcode=2 THEN 2 ELSE null END AS rate ");
      lSql.append("FROM custtbl WHERE custcode=").append(SIDBUtil.SQL2Str(custCode));
      
      String pointFlg = SIDBUtil.getFirstData(lConnection, lSql.toString());
      String specialBonus = SIUtil.sub(SIUtil.multi_LD(lResPoint, getSpecialRate()), lResPoint);
      
      if (SIUtil.isNotNull(pointFlg)&&"0".equals(pointFlg)) {//ポイント無効
        lResPoint = "0";
      } else if (SIUtil.isNotNull(pointFlg)&&"1".equals(pointFlg)) {//ゴールド会員（メンバーレベルコード１）
        lResPoint = SIUtil.multi_LD(lResPoint, vipRate1);
      } else if (SIUtil.isNotNull(pointFlg)&&"2".equals(pointFlg)) {//プラチナ会員（メンバーレベルコード２）
        lResPoint = SIUtil.multi_LD(lResPoint, vipRate2);
      } else if (SIUtil.isNotNull(pointFlg)&&"3".equals(pointFlg)) {//ダイヤモンド会員（メンバーレベルコード３）
        lResPoint = SIUtil.multi_LD(lResPoint, vipRate3);
      }
      if (isBonus) lResPoint = SIUtil.add(lResPoint, specialBonus);
    } catch (ParseException e) {
      e.printStackTrace();
    } catch (SIException e) {
      e.printStackTrace();
    }
    log.debug("getBonusFromDate()=" + getBonusFromDate() + ",getBonusToDate()=" + getBonusFromDate());
    log.debug("lDateTime.getFullDate()=" + lDateTime.getFullDate() + ",lResPoint=" + lResPoint);
    log.debug("getBonusPointRate()=" + getBonusPointRate() + ",getPointRate()=" + getPointRate());
    log.debug("specialRate=" + getSpecialRate());
    log.debug("calcPoint:lResPoint=" + lResPoint);
    return lResPoint;
  }
  
  /**
   * <b>calcPoint</b>
   * 
   * @param Connection
   * @param lCmdtyPrice (individualCode,totalPrice)
   * @param discountPrice
   * @param boolean
   * @return String 獲得ポイント
   * @throws なし
   */
  public String calcPointInUpdateOrder(Connection lConnection, String[][] lCmdtyPrice, String discountPrice, String custCode, boolean lInitFlg, String lOrderDate) {
    String lResPoint = "0";
    String totalPrice = "0";
    String ctgryBonusRate = "";
    String individualBonusRate = "";
    String[] temp = {"",""};
    SIDateTime lDateTime = new SIDateTime();
    StringBuffer str = new StringBuffer();
    boolean isBonus = false;
    
    try {
      lDateTime = new SIDateTime(lOrderDate);
    } catch (Exception e) {}
    
    // 初回購入時
    if (lInitFlg) {
      lResPoint = getInitPoint();
      log.debug("calcPoint:init setup,lResPoint,getInitPoint()=" + getInitPoint());
    }
    
    for (int i=0;i<lCmdtyPrice.length;i++){
      totalPrice = SIUtil.add(totalPrice, lCmdtyPrice[i][1]);
    }
    
    // 最低購入金額
    if (SIUtil.isNull(totalPrice)) totalPrice = "0";
    if (Long.parseLong(totalPrice) < Long.parseLong(getMinCost())) return lResPoint;
    
    try {
      for (int j=0;j<lCmdtyPrice.length;j++){
        str = new StringBuffer();
        str.append("SELECT bonuspointrate FROM bonuspointtbl WHERE ctgrycode = ").append(SIDBUtil.SQL2Str(lCmdtyPrice[j][0].substring(0, 2)," "));
        str.append("AND bonusfromdate <= ").append(SIDBUtil.SQL2Str(lDateTime.getFullDate()," "));
        str.append("AND bonustodate >= ").append(SIDBUtil.SQL2Str(lDateTime.getFullDate()));
        
        ctgryBonusRate = SIDBUtil.getFirstData(lConnection, str.toString());//カテゴリボーナス
        
        str = new StringBuffer();
        str.append("SELECT bonuspointrate FROM bonuspointindividualtbl WHERE individualcode = ").append(SIDBUtil.SQL2Str(lCmdtyPrice[j][0]," "));
        str.append("AND bonusfromdate <= ").append(SIDBUtil.SQL2Str(lDateTime.getFullDate()," "));
        str.append("AND bonustodate >= ").append(SIDBUtil.SQL2Str(lDateTime.getFullDate()));
        
        individualBonusRate = SIDBUtil.getFirstData(lConnection, str.toString());//商品個別ボーナス
        
        // From To
        if (SIUtil.isNotNull(getBonusFromDate()) && SIUtil.isNotNull(getBonusToDate())) {
          if (!SICheckUtil.dateGreater(getBonusFromDate(), lDateTime.getFullDate()) && !SICheckUtil.dateLess(getBonusToDate(), lDateTime.getFullDate())
              || lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
            lCmdtyPrice[j][0] = getBonusPointRate();
            isBonus = true;
          } else {
            lCmdtyPrice[j][0] = getPointRate();
          }
        // From
        } else if (SIUtil.isNotNull(getBonusFromDate()) && SIUtil.isNull(getBonusToDate())) {
          if (!SICheckUtil.dateGreater(getBonusFromDate(), lDateTime.getFullDate()) || lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
            lCmdtyPrice[j][0] = getBonusPointRate();
            isBonus = true;
          } else {
            lCmdtyPrice[j][0] = getPointRate();
          }
        // To
        } else if (SIUtil.isNull(getBonusFromDate()) && SIUtil.isNotNull(getBonusToDate())) {
          if (!SICheckUtil.dateLess(getBonusToDate(), lDateTime.getFullDate()) || lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
            lCmdtyPrice[j][0] = getBonusPointRate();
            isBonus = true;
          } else {
            lCmdtyPrice[j][0] = getPointRate();
          }
        } else {
          if (lDateTime.getDayStr().equals(this.getSetDateOfBonus())) {
            lCmdtyPrice[j][0] = getBonusPointRate();
            isBonus = true;
          } else {
            lCmdtyPrice[j][0] = getPointRate();
          }
        }
        //個別設定orカテゴリ別設定があればレート上書き
        if(SIUtil.isNotNull(individualBonusRate)){
          lCmdtyPrice[j][0] = individualBonusRate;
        }else if(SIUtil.isNotNull(ctgryBonusRate)){
          lCmdtyPrice[j][0] = ctgryBonusRate;
        }
      }
      for (int k1=0;k1<lCmdtyPrice.length;k1++){
        //各商品購入額をポイントレート（降順）、金額（昇順）にソート
        for (int k2=k1;k2<lCmdtyPrice.length;k2++){
          if((Double.parseDouble(lCmdtyPrice[k1][0]) < Double.parseDouble(lCmdtyPrice[k2][0]))
           || (lCmdtyPrice[k1][0].equals(lCmdtyPrice[k2][0]) && (Integer.parseInt(lCmdtyPrice[k1][1]) > Integer.parseInt(lCmdtyPrice[k2][1])))){
            temp[0] = lCmdtyPrice[k2][0];
            temp[1] = lCmdtyPrice[k2][1];
            lCmdtyPrice[k2][0] = lCmdtyPrice[k1][0];
            lCmdtyPrice[k2][1] = lCmdtyPrice[k1][1];
            lCmdtyPrice[k1][0] = temp[0];
            lCmdtyPrice[k1][1] = temp[1];
          }
        }
        //割引額がなくなるまでマイナス
        if(!discountPrice.equals("0")){
          if(SICheckUtil.isGreater(lCmdtyPrice[k1][1],discountPrice)){
            lCmdtyPrice[k1][1] = SIUtil.sub(lCmdtyPrice[k1][1], discountPrice);
            discountPrice = "0";
          }else{
            discountPrice = SIUtil.sub(discountPrice, lCmdtyPrice[k1][1]);
            lCmdtyPrice[k1][1] = "0";
          }
        }
        //ポイント加算
        if(!lCmdtyPrice[k1][1].equals("0")){
          lResPoint = SIUtil.add_LL(lResPoint, SIUtil.multi_LD(lCmdtyPrice[k1][1], SIUtil.div_DL(lCmdtyPrice[k1][0], "100")));
        }
      }
      
      //会員種別による最終倍率設定
      StringBuffer lSql = new StringBuffer();
      lSql.append("SELECT CASE WHEN nopointflg=1 THEN 0 WHEN memberlevelcode=1 THEN 1 ");
      lSql.append("WHEN memberlevelcode=2 THEN 2 WHEN memberlevelcode=3 THEN 3 ELSE null END AS rate ");
      lSql.append("FROM custtbl WHERE custcode=").append(SIDBUtil.SQL2Str(custCode));
      
      String pointFlg = SIDBUtil.getFirstData(lConnection, lSql.toString());
      String specialBonus = SIUtil.sub(SIUtil.multi_LD(lResPoint, getSpecialRate()), lResPoint);
      
      if (SIUtil.isNotNull(pointFlg)&&"0".equals(pointFlg)) {//ポイント無効
        lResPoint = "0";
      } else if (SIUtil.isNotNull(pointFlg)&&"1".equals(pointFlg)) {//ゴールド会員（メンバーレベルコード１）
        lResPoint = SIUtil.multi_LD(lResPoint, vipRate1);
      } else if (SIUtil.isNotNull(pointFlg)&&"2".equals(pointFlg)) {//プラチナ会員（メンバーレベルコード２）
        lResPoint = SIUtil.multi_LD(lResPoint, vipRate2);
      } else if (SIUtil.isNotNull(pointFlg)&&"3".equals(pointFlg)) {//ダイヤモンド会員（メンバーレベルコード３）
        lResPoint = SIUtil.multi_LD(lResPoint, vipRate3);
      }
      if (isBonus) lResPoint = SIUtil.add(lResPoint, specialBonus);
    } catch (ParseException e) {
      e.printStackTrace();
    } catch (SIException e) {
      e.printStackTrace();
    }
    log.debug("getBonusFromDate()=" + getBonusFromDate() + ",getBonusToDate()=" + getBonusFromDate());
    log.debug("lDateTime.getFullDate()=" + lDateTime.getFullDate() + ",lResPoint=" + lResPoint);
    log.debug("getBonusPointRate()=" + getBonusPointRate() + ",getPointRate()=" + getPointRate());
    log.debug("specialRate=" + getSpecialRate());
    log.debug("calcPoint:lResPoint=" + lResPoint);
    return lResPoint;
  }
}
