/*
 * @DbProcess.java	version 1.0	27/02/2010
 *
 * Copyright 2010 Viettel Telecom. All rights reserved.
 * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.vas.sicbosubnc.wsfw.database;

import com.vas.sicbosubncom.wsfw.obj.Configuration;
import com.vas.sicbosubncom.wsfw.obj.Game;
import com.vas.sicbosubncom.wsfw.obj.ChargeLog;
import com.vas.sicbosubncom.wsfw.obj.RankingObj;
import com.vas.sicbosubncom.wsfw.obj.ProductInfo;
import com.vas.sicbosubncom.wsfw.obj.TopPlayer;
import com.vas.sicbosubncom.wsfw.obj.PlayingTimeRewrad;
import com.vas.sicbosubncom.wsfw.obj.MpsConfigObj;
import com.vas.sicbosubncom.wsfw.obj.ListPrize;
import com.vas.sicbosubncom.wsfw.obj.SmsMtObj;
import com.vas.sicbosubncom.wsfw.obj.HistoryPrize;
import com.vas.sicbosubncom.wsfw.obj.WebServiceLog;
import com.vas.sicbosubncom.wsfw.obj.SpinRecharge;
import com.vas.sicbosubncom.wsfw.obj.FqInviting;
import com.vas.sicbosubncom.wsfw.obj.PointTotalObj;
import com.vas.sicbosubncom.wsfw.obj.UserInfo;
import com.vas.sicbosubncom.wsfw.obj.TransactionLog;
import com.vas.sicbosubncom.wsfw.obj.MinigameReward;
import com.vas.sicbosubncom.wsfw.obj.AccountInfo;
import com.vas.sicbosubncom.wsfw.obj.HistoryPlay;
import com.vas.sicbosubncom.wsfw.obj.PlayingTimeHistory;
import com.vas.sicbosubncom.wsfw.obj.SpinGift;
import com.vas.sicbosubncom.wsfw.obj.RegisterInfo;
import com.vas.sicbosubnc.wsfw.common.Common;
import com.vas.sicbosubnc.wsfw.common.WebserviceManager;

import static com.vas.sicbosubnc.wsfw.database.DbProcessorAbstract.TIME_BREAK;
import com.vas.sicbosubnc.wsfw.obj.draw.LuckySprin;
import com.vas.sicbosubnc.wsfw.obj.draw.PrizeObj;
import com.vas.sicbosubnc.wsfw.obj.draw.PrizeWinner;
import com.vas.sicbosubnc.wsfw.obj.draw.SpinResultObj;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;


import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import oracle.jdbc.OracleTypes;

import org.apache.log4j.Logger;

/**
 * Cac truy van de CSDL he thong
 *
 * @author NhungTTT3
 * @since 27-02-2010
 */
public class WsProcessUtils extends DbProcessorAbstract {

    //    private long TIME_LAST_QUERY;
    private Logger logger;
    private String loggerLabel = "WsProcessUtils: ";
    private int ERRORTIME = 3;
//    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//    private String schema;
    private SimpleDateFormat fullDf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

    // user profile
    private final String SQL_GET_USER_PROFILE_BY_MSISDN
            = "select * from fq_user_info WHERE msisdn = ?";

    // Them phan check user
    private final String SQL_GET_USER_BY_MSISDN
            = "select * from account_user WHERE msisdn = ? and status <> 0 and service_id = ?";
    private final String SQL_GET_USER
            = "select * from account_user WHERE msisdn = ? and status <> 0 ";
    
    private final String SQL_GET_LISTPRIZE_BY_ACTIONTYPE
            = "select * from list_prize WHERE action_type = ? and status <> 0 ";
    private final String SQL_GET_USER_BY_MSISDN_AND_PASSWORD
            = "select * from account_user WHERE msisdn = ? and pass = ? and service_id = ? and status <> 0";
    private final String SQL_CHECK_USED_MSISDN = "select * from REG_INFO WHERE msisdn = ? and product_name = ?";
    private final String sqlGetUser = "select * from ws_user where username = ?";
    private final String sqlCheckUser = "select * from ws_user where username = ? and password=?";
    private final String sqlCheckCheckPass = "SELECT * FROM blacklist_Password WHERE password = ?";
    
    private final String SQL_GET_MSISDN_TOOL = "SELECT * from tool_sim where msisdn = ? ";
    private final String sqlLuckySprin = "select * from lucky_spin where msisdn = ? ";
    

    
    //    private final String SQL_GET_REGISTER_INFO
//            = "SELECT * FROM REG_INFO WHERE MSISDN = ? and product_name = ? and status = 1";
//    private final String SQL_GET_REGISTER_INFO_ALL
//            = "SELECT * FROM REG_INFO WHERE MSISDN = ? and status = 1";
//    private final String SQL_GET_REGISTER_IN_DAY
//            = "SELECT * FROM REG_INFO WHERE MSISDN = ? and product_name = ? and expire_time > sysdate order by register_time desc";
    private final String SQL_GET_TOTAL_MONEY_PAID
            = "select nvl(sum(money),0) money from history_play where money is not null and play_day > trunc(sysdate)";
    private final String SQL_LOAD_PRIZE
            = "SELECT * FROM LIST_PRIZE WHERE status = 1 ";
    private final String SQL_SELECT_PRIZE
            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE ORDER BY DBMS_RANDOM.RANDOM) WHERE status = 1 and rownum <= 1";
    private final String SQL_SELECT_PRIZE_NOTX2
            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE where type <> 2 or type_add <> 2 ORDER BY DBMS_RANDOM.RANDOM) WHERE status = 1 and rownum <= 1";
    private final String SQL_SELECT_WINNER_NO_REGISTER
            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE where type <> 4 or number_add = 0 ORDER BY DBMS_RANDOM.RANDOM) WHERE status = 1 and rownum <= 1";
    private final String SQL_SELECT_WINNER_NO_REGISTER_NOTX2
            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE where (type <> 4 or number_add = 0) and (type <> 2 or type_add <> 2) ORDER BY DBMS_RANDOM.RANDOM) WHERE status = 1 and rownum <= 1";
    private final String SQL_SELECT_WINNER_NO_MONEY
            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE where type <> 2 or (type = 2 and type_add = 1 and number_add < 2) ORDER BY DBMS_RANDOM.RANDOM) "
            + "WHERE status = 1 and rownum <= 1";
    private final String SQL_SELECT_WINNER_NO_MONEY_NOTX2
            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE where (type <> 2 or (type = 2 and type_add = 1 and number_add < 2)) and (type <> 2 or type_add <> 2) ORDER BY DBMS_RANDOM.RANDOM) "
            + "WHERE status = 1 and rownum <= 1";
    private final String SQL_SELECT_WINNER_NO_REGISTER_NO_MONEY
            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE where (number_add <= 0) or (type = 1) or (type = 2 and type_add = 1 and number_add < 2) ORDER BY DBMS_RANDOM.RANDOM) WHERE status = 1 and rownum <= 1";
    private final String SQL_SELECT_WINNER_NO_REGISTER_NO_MONEY_NOTX2
            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE where (number_add <= 0 or (type = 1) or (type = 2 and type_add = 1 and number_add < 2)) and (type <> 2 or type_add <> 2) ORDER BY DBMS_RANDOM.RANDOM) WHERE status = 1 and rownum <= 1";
    private final String SQL_GET_CURRENT_RANK
            = "select no, spin_count from (select msisdn, spin_count, rownum no from "
            + "(select * from ranking where sub_type = ? and rank_type = ? and period = ? and end_time > sysdate order by spin_count desc, last_update)) "
            + "where msisdn = ?";
    //    private final String SQL_GET_CURRENT_RANK_UNSUB
//            = "select no, spin_count from (select msisdn, spin_count, rownum no from "
//            + "(select * from ranking where sub_type = 0 and end_time > sysdate order by spin_count desc)) "
//            + "where msisdn = ?";
    private static final String SQL_CHECK_TIMES_PLAY
            = "SELECT * FROM REG_INFO WHERE MSISDN = ? and status = 1";
    private static final String SQL_INSERT_HISTORY_PLAY_WINNER
            = "insert into history_play(id,list_id, register_id,MSISDN,product_name, play_day,spin_times,played_times,type,type_add,number_add, money, balance_id,note) "
            + "values(history_play_seq.NEXTVAL, ?,?,?,?, sysdate, ?, ?, ?,?,?,?,?,?)";
    private static final String SQL_TRANS_LOG
            = "INSERT INTO TRANSACTION_LOG(TRANSACTION_ID, TYPE, MSISDN, REQUEST, RESPONSE,"
            + "ERROR_CODE, COMMAND, REQUEST_TIME, RESPONSE_TIME, CHANNEL) "
            + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

    public WsProcessUtils(String dbName, Logger logger) {
        this.logger = logger;
        this.dbName = dbName;
        init(dbName, logger);
    }

    public WsProcessUtils() {
        super();
    }

    /**
     * Close Statement
     *
     * @param stmt
     * @param smName
     */
    private void closeStatement(PreparedStatement stmt, String smName) {
        if (stmt != null) {
            try {
                br.setLength(0);
                br.append(loggerLabel).
                        append("Close Statement: ").
                        append(smName);
                logger.debug(br);
                stmt.close();
                stmt = null;
            } catch (SQLException ex) {
                br.setLength(0);
                br.append(loggerLabel).
                        append("ERROR close Statement ").
                        append(smName).
                        append(": ").
                        append(ex.getMessage());
                logger.warn(br);
                stmt = null;
            }
        }
    }

    public void setDbName(String dbName) {
        this.dbName = dbName;
//        schema = ConnectionPoolManager.getConnectionMap().get(dbName).getUser() + ".";
    }

    public String getDbName() {
        return this.dbName;
    }

    public HashMap getConfig(String module) throws Exception {
        long timeStart = System.currentTimeMillis();
        ResultSet rs = null;
        HashMap listMessage = new HashMap();
        PreparedStatement getConfigSt = null;
        String sql = "select PARAM_NAME, PARAM_VALUE, PARAM_VALUE_FR from CONFIG where upper(module)=?";

        br.setLength(0);
        br.append(loggerLabel).
                append(" GET CONFIG: ").
                append(sql);
        logger.info(br);
        Connection connection = null;
        try {
            connection = getConnection(dbName);
            getConfigSt = connection.prepareStatement(sql);
            getConfigSt.setString(1, module.toUpperCase());
            rs = getConfigSt.executeQuery();
            while (rs.next()) {
                listMessage.put(rs.getString("PARAM_NAME"), rs.getString("PARAM_VALUE"));
                listMessage.put(rs.getString("PARAM_NAME") + "_FR", rs.getString("PARAM_VALUE_FR"));
            }
        } catch (Exception ex) {
            logger.error(loggerLabel + "ERROR getListMessage", ex);

            throw ex;
        } finally {
            closeResultSet(rs);
            closeStatement(getConfigSt, sql);
            closeConnection(connection);
            logTime("Time to getConfig", timeStart);
        }
        return listMessage;
    }

    protected void closeResource(ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
                rs = null;
            }
        } catch (SQLException e) {
            this.logger.warn(e);
            rs = null;
        }
    }

    protected void closeResource(Statement stmt) {
        try {
            if (stmt != null) {
                stmt.close();
                stmt = null;
            }
        } catch (SQLException e) {
            this.logger.warn(e);
            stmt = null;
        }
    }

    protected void closeResource(Connection conn) {
        try {
            if (conn != null) {
                conn.close();
                conn = null;
            }
        } catch (SQLException e) {
            this.logger.warn(e);
            conn = null;
        }
    }

    /**
     * Kiem tra thue bao dang su dung dich vu hay khong
     *
     * @param msisdn
     * @param productName
     * @return
     */
    /**
     * Ghi log webservice
     *
     * @param ws
     * @return
     */
    public boolean iInsertWsLog(WebServiceLog ws) {
        long timeSt = System.currentTimeMillis();
        boolean result = false;

        while (true) {
            result = insertWsLog(ws);
            if (result != true) {
                break;
            } else {
                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
                    br.setLength(0);
                    br.append(loggerLabel).
                            append("BREAK iInsertWsLog ==> ERROR DATABASE\n").
                            append(ws.toString());
                    logger.error(br);
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    private boolean insertWsLog(WebServiceLog ws) {

        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        String sqlInsertWSLog = "insert into ws_log (ID,REQUEST,RESPONSE,REQUESTTIME,RESPONSETIME,RESPONSECODE,USERID,CHANNEL,IPCLIENT,MSISDN,FEE,WS_NAME)"
                + "values ( WS_LOG_SEQ.NEXTVAL,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )";

        br.setLength(0);
        br.append(loggerLabel).
                append("Insert WEBSERVICE_LOG:\n").
                append(ws.toString());
        logger.debug(br);

        Connection connection = null;
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sqlInsertWSLog);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            ps.setString(1, ws.getRequest().toString());
            ps.setString(2, ws.getResponse().toString());
            ps.setTimestamp(3, ws.getRequestTime());
            ps.setTimestamp(4, ws.getResponseTime());
            ps.setString(5, ws.getResponseCode());
            ps.setLong(6, ws.getUserId());
            ps.setString(7, ws.getChannel());
            ps.setString(8, ws.getIpClient());
            ps.setString(9, ws.getMsisdn());
            ps.setDouble(10, ws.getFee());
            ps.setString(11, ws.getWsName());
            return ps.execute();

        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR Insert to WEBSERVICE_LOG: ").
                    append(ex.toString()).
                    append("\n").
                    append(ws.toString());
            logger.error(br, ex);
        } finally {
            closeStatement(ps, sqlInsertWSLog);
            closeConnection(connection);
            logTime("Time to iInsertWsLog", timeStart);
        }
        return false;
    }

    public Boolean updateAddMoreTimes(long registerId, int times) {

        try {
            return iUpdateAddMoreTimes(registerId, times);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updateAddMoreTimes");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean iUpdateAddMoreTimes(long registerId, int times) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "UPDATE reg_info SET number_spin = number_spin + ? WHERE register_id = ? AND status = 1";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            ps.setInt(1, times);
            ps.setLong(2, registerId);
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iUpdateAddMoreTimes");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iUpdateAddMoreTimes", timeStart);
        }
    }

    public Boolean updateRenewReg(RegisterInfo regInfo) {

        try {
            return iUpdateRenewReg(regInfo);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updateRegisterInfo");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean iUpdateRenewReg(RegisterInfo regInfo) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "update reg_info set expire_time=?, number_spin=? , extend_status=?, status = ?, played_times = ?, last_extend = sysdate "
                + "  where register_id=?";
        ;
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            ps.setTimestamp(1, regInfo.getExpireTime());
            ps.setInt(2, regInfo.getNumberSpin());
            ps.setInt(3, regInfo.getExtendStatus());
            ps.setInt(4, regInfo.getStatus());
            ps.setInt(5, regInfo.getPlayedTimes());
            ps.setLong(6, regInfo.getRegisterId());

            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iUpdateRenewReg");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iUpdateRenewReg", timeStart);
        }
    }

    public boolean iInsertChargeLog(ChargeLog ws) {
        long timeSt = System.currentTimeMillis();
        boolean result = false;

        while (true) {
            result = insertChargeLog(ws);
            if (result != true) {
                break;
            } else {
                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
                    br.setLength(0);
                    br.append(loggerLabel).
                            append("BREAK iInsertChargeLog ==> ERROR DATABASE\n").
                            append(ws.toString());
                    logger.error(br);
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    private boolean insertChargeLog(ChargeLog ws) {

        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        String sql = "INSERT INTO charge_log (ID,MSISDN,FEE,CHARGE_TIME,INSERT_TIME,DESCRIPTION,ACCOUNT_ID, STATUS) \n"
                + "VALUES(charge_log_seq.nextval, ?, ?, ?, sysdate, ?, ?, ?)";

        br.setLength(0);
        br.append(loggerLabel).
                append("Insert WEBSERVICE_LOG:\n").
                append(ws.toString());
        logger.debug(br);

        Connection connection = null;
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            ps.setString(1, ws.getMsisdn());
            ps.setDouble(2, ws.getFee());
            ps.setTimestamp(3, ws.getChargeTime());
            ps.setString(4, ws.getDescription());
            ps.setString(5, ws.getAccountId());
            ps.setInt(6, ws.getStatus());
            return ps.execute();

        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR insertChargeLog: ").
                    append(ex.toString()).
                    append("\n").
                    append(ws.toString());
            logger.error(br, ex);
        } finally {
            closeStatement(ps, sql);
            closeConnection(connection);
            logTime("Time to insertChargeLog", timeStart);
        }
        return false;
    }

    public UserInfo iGetUser(String userName) {
        UserInfo user = null;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (user == null) {
            try {
                user = getUserInfo(userName);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
                logger.error(br, ex);
                count++;
            }
            if (user == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).append("==>BREAK query select VTFREE_USER\n");
                logger.error(br);
                break;
            }
        }
        return user;
    }

    /**
     * Lay thong tin nguoi dung
     *
     * @param userName
     * @return
     * @throws SQLException
     */
    private UserInfo getUserInfo(String userName) throws SQLException {
        ResultSet rs = null;
        PreparedStatement ps = null;
        UserInfo user = null;
        long timeStart = System.currentTimeMillis();
        Connection connection = null;
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sqlGetUser);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, userName);
            rs = ps.executeQuery();
            user = new UserInfo();

            if (rs.next()) {
                logger.info("result: " + rs);
                user.setWsUserId(rs.getLong(UserInfo.WS_USER_ID));
                user.setUser(userName);
                user.setPass(rs.getString(UserInfo.PASS));
                user.setIp(rs.getString(UserInfo.IP));
            }
            logger.info("user: " + user);
            return user;
        } catch (SQLException ex) {
            throw ex;
        } finally {
            closeResultSet(rs);
            closeStatement(ps, sqlGetUser);
            closeConnection(connection);
            logTime("Time to getUserInfo", timeStart);
        }
    }

    /**
     * Lay mo_seq de insert db
     *
     * @return
     */
    public Long iGetMoSequence() {
        long timeSt = System.currentTimeMillis();
        Long result = null;

        while (true) {
            result = getMoSequence();
            if (result != null) {
                break;
            } else {
                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
                    br.setLength(0);
                    br.append(loggerLabel).
                            append("BREAK getMoSequence ==> ERROR DATABASE\n");
                    logger.error(br);
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    private Long getMoSequence() {
        long timeStart = System.currentTimeMillis();
        String sqlGetMoSeq = "select mo_seq.nextval SEQ from dual";

        PreparedStatement ps = null;
        ResultSet rs = null;

        Connection connection = null;
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sqlGetMoSeq);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            rs = ps.executeQuery();
            //check MSISDN
            while (rs.next()) {
                return rs.getLong("SEQ");
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR getMoSequence").
                    append(ex.toString());

            logger.error(br, ex);
        } finally {
            closeStatement(ps, sqlGetMoSeq);
            closeResultSet(rs);
            closeConnection(connection);
            logTime("Time to getMoSequence", timeStart);
        }
        return null;
    }

    public int[] insertMt(SmsMtObj mt) {
        long timeBegin = System.currentTimeMillis();
        int count = 0;
        int[] result = null;
        while (result == null) {
            try {
                count++;
                result = iInsertMt(mt);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).
                        append(new Date()).
                        append("\nERROR insert insertMt");
                logger.error(br, ex);
            }
            if (result == null && ((System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) || (count > 3))) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK query insertMt\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private int[] iInsertMt(SmsMtObj mt) throws Exception {
        PreparedStatement ps = null;
        Connection connection = null;
        String sqlInsertMt = "insert into MT(MT_ID, MO_HIS_ID,MSISDN,MESSAGE,RECEIVE_TIME,RETRY_NUM,CHANNEL) "
                + "values(MT_SEQ.NEXTVAL, 0, ?, ?, sysdate, 0, ?)";
        long startTime = System.currentTimeMillis();
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sqlInsertMt);
            ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            ps.clearParameters();
            ps.setString(1, mt.getMsisdn());
            ps.setString(2, mt.getMessage());
            ps.setString(3, mt.getChannel());
            ps.addBatch();
            return ps.executeBatch();

        } catch (Exception ex) {
            logger.error("Exception : ", ex);
        } finally {
            closeStatement(ps);
            closeConnection(connection);
            logTime("Time to insertMt", startTime);
        }
        return null;
    }

    public int[] insertMt(String msisdn, String message, String channel) {
        long timeBegin = System.currentTimeMillis();
        int count = 0;
        int[] result = null;
        while (result == null) {
            try {
                count++;
                result = iInsertMt(msisdn, message, channel);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).
                        append(new Date()).
                        append("\nERROR insert insertMt");
                logger.error(br, ex);
            }
            if (result == null && ((System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) || (count > 3))) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK query insertMt\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private int[] iInsertMt(String msisdn, String message, String channel) {
        PreparedStatement ps = null;
        Connection connection = null;
        String sqlInsertMt = "insert into MT(MT_ID,MO_HIS_ID,MSISDN,MESSAGE,RECEIVE_TIME,RETRY_NUM,CHANNEL) "
                + "values(MT_SEQ.NEXTVAL, 0, ?, ?, sysdate, 0, ?)";
        long startTime = System.currentTimeMillis();
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sqlInsertMt);
            ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            ps.clearParameters();
            ps.setString(1, msisdn);
            ps.setString(2, message);
            ps.setString(3, channel);
            ps.addBatch();
            return ps.executeBatch();

        } catch (Exception ex) {
            logger.error("Exception : ", ex);
        } finally {
            closeStatement(ps);
            closeConnection(connection);
            logTime("Time to insertMt", startTime);
        }
        return null;
    }

    public Boolean getMsisdnTool(String msisdn ) {
        long timeBegin = System.currentTimeMillis();
        Boolean result = null;
        int count = 0;
        while (result == null) {
            try {
                result = iGetMsisdnTool(msisdn);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).
                        append(new Date()).
                        append("\nERROR getMsisdnTool");
                logger.error(br, ex);
                count++;
            }
            if ((result == false && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery)
                    || count >= 3) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK getMsisdnTool\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }
    
    private Boolean iGetMsisdnTool(String msisdn) throws SQLException {
        PreparedStatement ps = null;
        Connection connection = null;
        ResultSet rs = null;            
        long startTime = System.currentTimeMillis();

        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(SQL_GET_MSISDN_TOOL);
           if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            ps.setString(1, msisdn);
            rs = ps.executeQuery();

            // Kiểm tra có dữ liệu hay không
            return rs.next();
        } catch (SQLException ex) {
            throw ex;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetMsisdnTool",startTime);
        }
    }
    
    public boolean iInsertRegisterInfo(RegisterInfo regInfo) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = insertRegisterInfo(regInfo);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR iInsertRegisterInfo ");
                logger.error(br, ex);
                count++;
            }
            if ((result == false && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery)
                    || count >= 3) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK iInsertRegisterInfo\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }
    
    private boolean insertRegisterInfo(RegisterInfo regInfo) throws Exception {
        boolean rs = false;
        PreparedStatement ps = null;
        Connection connection = null;
        long startTime = System.currentTimeMillis();
        String sql = "insert into reg_info (register_id, msisdn, product_name, register_time, number_spin, played_times, extend_status, status, expire_time, renew, service_id, channel) "
                + "values (register_seq.nextval, ?, ?, sysdate, ?, ?, 0, 1, ?, ?, ?, ?)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            ps.setString(1, regInfo.getMsisdn());
            ps.setString(2, regInfo.getProductName());
            ps.setInt(3, regInfo.getNumberSpin());
            ps.setInt(4, regInfo.getPlayedTimes());
            ps.setTimestamp(5, regInfo.getExpireTime());
            ps.setInt(6, regInfo.getRenew());
            ps.setInt(7, regInfo.getServiceId());
            ps.setString(8, regInfo.getChannel());

            ps.executeUpdate();
            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to insertRegisterInfo", startTime);
        }
        return rs;
    }

    public Boolean checkRegistered(String msisdn, String packName) {
        Boolean registered = null;
        try {
            registered = iCheckRegistered(msisdn, packName);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR checkRegistered");
            logger.error(br, ex);
        }

        return registered;
    }

    private Boolean iCheckRegistered(String msisdn, String packName) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        long startTime = System.currentTimeMillis();
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(SQL_CHECK_USED_MSISDN);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setString(2, packName);
            rs = ps.executeQuery();
            if (rs.next()) {
                return true;
            }
            return false;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iCheckRegistered");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to check registered", startTime);
        }
    }

    public Boolean checkRegisteredForTheFirstTime(String msisdn, String serviceId) {
        Boolean registered = null;
        try {
            registered = iCheckRegisteredForTheFirstTime(msisdn, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR checkRegistered");
            logger.error(br, ex);
        }

        return registered;
    }

    private Boolean iCheckRegisteredForTheFirstTime(String msisdn, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        long startTime = System.currentTimeMillis();
        String sql = "select * from REG_INFO WHERE msisdn = ? and renew = 1 and service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setInt(2, Integer.parseInt(serviceId));
            rs = ps.executeQuery();
            if (rs.next()) {
                return true;
            }
            return false;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iCheckRegistered");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to check registered", startTime);
        }
    }

    public int getTotalMoneyPaid() {
        try {
            return iGetTotalMoneyPaid();
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getTotalMoneyPaid");
            logger.error(br, ex);
        }
        return 3000;
    }

    private int iGetTotalMoneyPaid() {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        long startTime = System.currentTimeMillis();
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(SQL_GET_TOTAL_MONEY_PAID);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            //ps.setInt(1, questionLevel);
            rs = ps.executeQuery();
            while (rs.next()) {
                return rs.getInt("money");
            }
            return 0;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetTotalMoneyPaid");
            logger.error(br, ex);
            return 3000;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetTotalMoneyPaid", startTime);
        }
    }

    public HashMap<String, ListPrize> loadPrize() {
        HashMap<String, ListPrize> mapQuestion = new HashMap();
        try {
            mapQuestion = iLoadPrize();
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR loadPrize");
            logger.error(br, ex);
        }
        return mapQuestion;
    }

    private HashMap iLoadPrize() {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        HashMap result = new HashMap();
        long startTime = System.currentTimeMillis();

        try {
            connection = getConnection(dbName);

            ps = connection.prepareStatement(SQL_LOAD_PRIZE);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            //ps.setInt(1, questionLevel);
            rs = ps.executeQuery();
            while (rs.next()) {
                ListPrize prize = new ListPrize();
                prize.setPrizeId(rs.getInt("PRIZE_ID"));
                prize.setType(rs.getInt("type"));
                prize.setTypeAdd(rs.getInt("TYPE_ADD"));
                prize.setNumberAdd(rs.getInt("NUMBER_ADD"));
                prize.setMoney(rs.getDouble("MONEY"));
                prize.setBalanceId(rs.getString("BALANCE_ID"));
                prize.setExpireDays(rs.getInt("EXPIRE_DAY"));
                prize.setResetBalance(rs.getInt("RESET_BALANCE"));
                prize.setDescription(rs.getString("DESCRIPTION"));
                prize.setRatioMoney(rs.getInt("RATIO_MONEY"));
                prize.setUnit(rs.getString("UNIT"));
                result.put(prize.getPrizeId() + "", prize);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetRandomPrize");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iLoadPrize", startTime);
        }
        return result;

    }

    public List<ListPrize> getRandomPrize(int type, boolean notX2) {
        List<ListPrize> questionList = new ArrayList<ListPrize>();
        try {
            questionList = iGetRandomPrize(type, notX2);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getRandomPrize");
            logger.error(br, ex);
        }
        return questionList;
    }

    private List<ListPrize> iGetRandomPrize(int type, boolean notX2) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<ListPrize> prizeList = new ArrayList<ListPrize>();
        long startTime = System.currentTimeMillis();
        if (type == 1) {
            try {
                connection = getConnection(dbName);

                ps = connection.prepareStatement(notX2 ? SQL_SELECT_PRIZE_NOTX2 : SQL_SELECT_PRIZE);
                if (WebserviceManager.queryDbTimeout > 0) {
                    ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
                }
                //ps.setInt(1, questionLevel);
                rs = ps.executeQuery();
                while (rs.next()) {
                    ListPrize prize = new ListPrize();
                    prize.setPrizeId(rs.getInt("PRIZE_ID"));
                    prize.setType(rs.getInt("type"));
                    prize.setTypeAdd(rs.getInt("TYPE_ADD"));
                    prize.setNumberAdd(rs.getInt("NUMBER_ADD"));
                    prize.setMoney(rs.getDouble("MONEY"));
                    prize.setBalanceId(rs.getString("BALANCE_ID"));
                    prize.setExpireDays(rs.getInt("EXPIRE_DAY"));
                    prize.setResetBalance(rs.getInt("RESET_BALANCE"));
                    prize.setDescription(rs.getString("DESCRIPTION"));
                    prize.setRatioMoney(rs.getInt("RATIO_MONEY"));
                    prize.setUnit(rs.getString("UNIT"));
                    prizeList.add(prize);
                }
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).
                        append(new Date()).
                        append("\nERROR iGetRandomPrize");
                logger.error(br, ex);
                return null;
            } finally {
                closeResource(rs);
                closeResource(ps);
                closeResource(connection);
                logTime("Time to iGetRandomPrize (" + type + "," + notX2 + ")", startTime);
            }
            return prizeList;
        } else if (type == 2) {
            // get all, except add money
            try {
                connection = getConnection(dbName);

                ps = connection.prepareStatement(notX2 ? SQL_SELECT_WINNER_NO_REGISTER_NO_MONEY_NOTX2 : SQL_SELECT_WINNER_NO_REGISTER_NO_MONEY);
                if (WebserviceManager.queryDbTimeout > 0) {
                    ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
                }
                //ps.setInt(1, questionLevel);
                rs = ps.executeQuery();
                while (rs.next()) {
                    ListPrize prize = new ListPrize();
                    prize.setPrizeId(rs.getInt("PRIZE_ID"));
                    prize.setType(rs.getInt("type"));
                    prize.setTypeAdd(rs.getInt("TYPE_ADD"));
                    prize.setNumberAdd(rs.getInt("NUMBER_ADD"));
                    prize.setMoney(rs.getDouble("MONEY"));
                    prize.setBalanceId(rs.getString("BALANCE_ID"));
                    prize.setExpireDays(rs.getInt("EXPIRE_DAY"));
                    prize.setResetBalance(rs.getInt("RESET_BALANCE"));
                    prize.setDescription(rs.getString("DESCRIPTION"));
                    prize.setRatioMoney(rs.getInt("RATIO_MONEY"));
                    prize.setUnit(rs.getString("UNIT"));
                    prizeList.add(prize);
                }
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).
                        append(new Date()).
                        append("\nERROR iGetRandomPrize");
                logger.error(br, ex);
                return null;
            } finally {
                closeResource(rs);
                closeResource(ps);
                closeResource(connection);
                logTime("Time to iGetRandomPrize (" + type + "," + notX2 + ")", startTime);
            }
            return prizeList;
        } else if (type == 3) {
            // get all, except add money
            try {
                connection = getConnection(dbName);
                ps = connection.prepareStatement(notX2 ? SQL_SELECT_WINNER_NO_MONEY_NOTX2 : SQL_SELECT_WINNER_NO_MONEY);
                if (WebserviceManager.queryDbTimeout > 0) {
                    ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
                }
                //ps.setInt(1, questionLevel);
                rs = ps.executeQuery();
                while (rs.next()) {
                    ListPrize prize = new ListPrize();
                    prize.setPrizeId(rs.getInt("PRIZE_ID"));
                    prize.setType(rs.getInt("type"));
                    prize.setTypeAdd(rs.getInt("TYPE_ADD"));
                    prize.setNumberAdd(rs.getInt("NUMBER_ADD"));
                    prize.setMoney(rs.getDouble("MONEY"));
                    prize.setBalanceId(rs.getString("BALANCE_ID"));
                    prize.setExpireDays(rs.getInt("EXPIRE_DAY"));
                    prize.setResetBalance(rs.getInt("RESET_BALANCE"));
                    prize.setDescription(rs.getString("DESCRIPTION"));
                    prize.setRatioMoney(rs.getInt("RATIO_MONEY"));
                    prize.setUnit(rs.getString("UNIT"));
                    prizeList.add(prize);
                }
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).
                        append(new Date()).
                        append("\nERROR iGetRandomPrize");
                logger.error(br, ex);
                return null;
            } finally {
                closeResource(rs);
                closeResource(ps);
                closeResource(connection);
                logTime("Time to iGetRandomPrize (" + type + "," + notX2 + ")", startTime);
            }
            return prizeList;
        } else {
            // not register --> only lose turn + add money
            try {
                connection = getConnection(dbName);
                ps = connection.prepareStatement(notX2 ? SQL_SELECT_WINNER_NO_REGISTER_NOTX2 : SQL_SELECT_WINNER_NO_REGISTER);
                if (WebserviceManager.queryDbTimeout > 0) {
                    ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
                }
                //ps.setInt(1, questionLevel);
                rs = ps.executeQuery();
                while (rs.next()) {
                    ListPrize prize = new ListPrize();
                    prize.setPrizeId(rs.getInt("PRIZE_ID"));
                    prize.setType(rs.getInt("type"));
                    prize.setTypeAdd(rs.getInt("TYPE_ADD"));
                    prize.setNumberAdd(rs.getInt("NUMBER_ADD"));
                    prize.setMoney(rs.getDouble("MONEY"));
                    prize.setBalanceId(rs.getString("BALANCE_ID"));
                    prize.setExpireDays(rs.getInt("EXPIRE_DAY"));
                    prize.setResetBalance(rs.getInt("RESET_BALANCE"));
                    prize.setDescription(rs.getString("DESCRIPTION"));
                    prize.setRatioMoney(rs.getInt("RATIO_MONEY"));
                    prize.setUnit(rs.getString("UNIT"));
                    prizeList.add(prize);
                }
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).
                        append(new Date()).
                        append("\nERROR iGetRandomPrize");
                logger.error(br, ex);
                return null;
            } finally {
                closeResource(rs);
                closeResource(ps);
                closeResource(connection);
                logTime("Time to iGetRandomPrize (" + type + "," + notX2 + ")", startTime);
            }
            return prizeList;
        }

    }

    public List<HistoryPrize> getMyPrizes(String msisdn) {
        try {
            return iGetMyPrizes(msisdn);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getMyPrizes");
            logger.error(br, ex);
        }

        return null;
    }

    private List<HistoryPrize> iGetMyPrizes(String msisdn) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        long startTime = System.currentTimeMillis();
        List<HistoryPrize> result = null;
        String sql = "select * from (Select msisdn, to_char(play_day,'dd/MM/yyyy HH24:mi:ss') play_day, play_day play_time, note from history_play "
                + "where msisdn = ? order by play_time desc) where rownum <= 10";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            rs = ps.executeQuery();
            result = new ArrayList();
            while (rs.next()) {
                HistoryPrize obj = new HistoryPrize();
                obj.setMsisdn(rs.getString("MSISDN"));
                obj.setPlayDay(rs.getString("play_day"));
                obj.setNote(rs.getString("note"));
                result.add(obj);
            }
            return result;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetMyPrizes");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetMyPrizes", startTime);
        }
    }

    public List<TopPlayer> getCurrentTopPlayer(int subType, int rankType, int period) {
        try {
            return iGetCurrentTopPLayer(subType, rankType, period);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getCurrentTopPlayer");
            logger.error(br, ex);
        }

        return null;
    }

    private List<TopPlayer> iGetCurrentTopPLayer(int subType, int rankType, int period) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        long startTime = System.currentTimeMillis();
        List<TopPlayer> result = null;
        String sql = "Select a.* , rownum from (select * from ranking where sub_type = ? and rank_type = ? and period = ? "
                + "and end_time > sysdate order by spin_count desc,last_update) a "
                + "where end_time > sysdate and rownum <= 10";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, subType);
            ps.setInt(2, rankType);
            ps.setInt(3, period);
            rs = ps.executeQuery();
            result = new ArrayList();
            while (rs.next()) {
                TopPlayer obj = new TopPlayer();
                obj.setMsisdn(rs.getString("MSISDN"));
                obj.setSpinCount(rs.getInt("SPIN_COUNT"));
                obj.setRank(rs.getInt("ROWNUM"));
                result.add(obj);
            }
            return result;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetCurrentTopPLayer");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetCurrentTopPLayer", startTime);
        }
    }

    /**
     * @param msisdn
     * @return Integer[order, spin_count]
     */
    public Integer[] iGetCurrentRank(String msisdn, int subType, int rankType, int period) {
        try {
            return getCurrentRank(msisdn, subType, rankType, period);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR iGetCurrentRank");
            logger.error(br, ex);
        }

        return null;
    }

    private Integer[] getCurrentRank(String msisdn, int subType, int rankType, int period) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        long startTime = System.currentTimeMillis();

        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(SQL_GET_CURRENT_RANK);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, subType);
            ps.setInt(2, rankType);
            ps.setInt(3, period);
            ps.setString(4, msisdn);
            rs = ps.executeQuery();
            while (rs.next()) {
                int no = rs.getInt("NO");
                int spin = rs.getInt("spin_count");
                return new Integer[]{no, spin};
            }
            return new Integer[]{0, 0};
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR getCurrentRank");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to get current rank", startTime);
        }
    }

    //    public Integer[] iGetCurrentRankUnsub(String msisdn) {
//        try {
//            return getCurrentRankUnsub(msisdn);
//        } catch (Exception ex) {
//            br.append(loggerLabel).append(new Date()).append("\nERROR iGetCurrentRankUnsub");
//            logger.error(br, ex);
//        }
//
//        return null;
//    }
//
//    private Integer[] getCurrentRankUnsub(String msisdn) {
//        PreparedStatement ps = null;
//        ResultSet rs = null;
//        Connection connection = null;
//        long startTime = System.currentTimeMillis();
//
//        try {
//            connection = getConnection(dbName);
//            ps = connection.prepareStatement(SQL_GET_CURRENT_RANK_UNSUB);
//            if (WebserviceManager.queryDbTimeout > 0) {
//                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
//            }
//            ps.setString(1, msisdn);
//            rs = ps.executeQuery();
//            while (rs.next()) {
//                int no = rs.getInt("NO");
//                int spin = rs.getInt("spin_count");
//                return new Integer[]{no, spin};
//            }
//            return new Integer[]{0, 0};
//        } catch (Exception ex) {
//            br.setLength(0);
//            br.append(loggerLabel).
//                    append(new Date()).
//                    append("\nERROR getCurrentRankUnsub");
//            logger.error(br, ex);
//            return null;
//        } finally {
//            closeResource(rs);
//            closeResource(ps);
//            closeResource(connection);
//            logTime("Time to get current rank unsub", startTime);
//        }
//    }
//    public List<RegisterInfo> getTimesPlay(String msisdn) {
//        List<RegisterInfo> questionNumberTimesPlay = new ArrayList<RegisterInfo>();
//        try {
//            questionNumberTimesPlay = iGetTimesPlay(msisdn);
//        } catch (Exception ex) {
//            br.append(loggerLabel).append(new Date()).append("\nERROR getTimesPlay");
//            logger.error(br, ex);
//        }
//
//        return questionNumberTimesPlay;
//    }
//
//    private List<RegisterInfo> iGetTimesPlay(String msisdn) {
//        PreparedStatement ps = null;
//        ResultSet rs = null;
//        Connection connection = null;
//        List<RegisterInfo> questionNumberTimesPlayList = new ArrayList<RegisterInfo>();
//
//        long startTime = System.currentTimeMillis();
//        try {
//            connection = getConnection(dbName);
//            ps = connection.prepareStatement(SQL_CHECK_TIMES_PLAY);
//            if (WebserviceManager.queryDbTimeout > 0) {
//                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
//            }
//            ps.setString(1, msisdn);
//            rs = ps.executeQuery();
//            while (rs.next()) {
//                RegisterInfo regInfo = new RegisterInfo();
//                regInfo.setRegisterId(rs.getLong("REGISTER_ID"));
//                regInfo.setMsisdn(rs.getString("MSISDN"));
//                regInfo.setProductName(rs.getString("PRODUCT_NAME"));
//                regInfo.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
//                regInfo.setNumberSpin(rs.getInt("NUMBER_SPIN"));
////                regInfo.setPlayedTimes(rs.getInt("PLAYED_TIMES"));
//                regInfo.setExtendStatus(rs.getInt("EXTEND_STATUS"));
//                regInfo.setStatus(rs.getInt("STATUS"));
//                questionNumberTimesPlayList.add(regInfo);
//            }
//        } catch (Exception ex) {
//            br.setLength(0);
//            br.append(loggerLabel).
//                    append(new Date()).
//                    append("\nERROR iGetTimesPlay");
//            logger.error(br, ex);
//            return null;
//        } finally {
//            closeResource(rs);
//            closeResource(ps);
//            closeResource(connection);
//            logTime("Time to iGetTimesPlay", startTime);
//        }
//        return questionNumberTimesPlayList;
//    }
    public Boolean updatePlayedTimes(int newSpinTimes, long registerId) {

        try {
            return iUpdatePlayedTimes(newSpinTimes, registerId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updatePlayedTimes");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean iUpdatePlayedTimes(int newSpinTimes, long registerId) {
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "UPDATE reg_info SET played_times = played_times + 1, number_spin = ? WHERE register_id = ? AND status = 1";

        long startTime = System.currentTimeMillis();
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, newSpinTimes);
            ps.setLong(2, registerId);
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iUpdatePlayedTimes");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iUpdatePlayedTimes " + registerId, startTime);
        }
    }

    public boolean iInsertHistoryPlayWinner(HistoryPlay historyWinner) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = insertHistoryPlayWinner(historyWinner);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR - ").append(count).
                        append("\n").append(SQL_INSERT_HISTORY_PLAY_WINNER);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK iInsertHistoryPlayWinner\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean insertHistoryPlayWinner(HistoryPlay historyWinner) throws Exception {
        boolean rs = false;
        PreparedStatement ps = null;
        Connection connection = null;
        long startTime = System.currentTimeMillis();
        try {

            connection = getConnection(dbName);

            ps = connection.prepareStatement(SQL_INSERT_HISTORY_PLAY_WINNER);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setLong(1, historyWinner.getListId());
            ps.setLong(2, historyWinner.getRegisterId());
            ps.setString(3, historyWinner.getMsisdn());
            ps.setString(4, historyWinner.getProductName());
            ps.setInt(5, historyWinner.getSpinedTime());
            ps.setInt(6, historyWinner.getPlayedTimes());
            ps.setInt(7, historyWinner.getType());
            ps.setInt(8, historyWinner.getTypeAdd());
            ps.setInt(9, historyWinner.getNumberAdd());
            ps.setDouble(10, historyWinner.getMoney());
            ps.setString(11, historyWinner.getBalanceId());
            ps.setString(12, historyWinner.getNote());
            ps.executeUpdate();
            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to insertHistoryPlayWinner", startTime);
        }
        return rs;
    }
    public AccountInfo iGetAccount(String msisdn) {
            AccountInfo user = null;
            long timeBegin = System.currentTimeMillis();
            int count = 1;
            while (user == null) {
                try {
                    user = getAccount(msisdn);
                } catch (Exception ex) {
                    br.setLength(0);
                    br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
                    logger.error(br, ex);
                    count++;
                }
                if (user == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
                    br.setLength(0);
                    br.append(loggerLabel).append(new Date()).append("==>BREAK query iGetAccountByMsisdn\n");
                    logger.error(br);
                    break;
                }
            }
            return user;
        }
    public AccountInfo iGetAccountByMsisdn(String msisdn, String productName) {
        AccountInfo user = null;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (user == null) {
            try {
                user = getAccountByMsisdn(msisdn, productName);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
                logger.error(br, ex);
                count++;
            }
            if (user == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).append("==>BREAK query iGetAccountByMsisdn\n");
                logger.error(br);
                break;
            }
        }
        return user;
    }
    
    private AccountInfo getAccount(String msisdn) throws SQLException {
        ResultSet rs = null;
        PreparedStatement ps = null;
        AccountInfo user = null;
        long timeStart = System.currentTimeMillis();
        Connection connection = null;
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(SQL_GET_USER);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            rs = ps.executeQuery();
            user = new AccountInfo();
            logTime("getAccountByMsisdn", timeStart);
            if (rs.next()) {
                logTime("next", timeStart);
                user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
                user.setUsers(rs.getString(AccountInfo.USERS));
                user.setPassword(rs.getString(AccountInfo.PASSWORD));
                user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
                user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
                user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
                user.setIsActive(rs.getString(AccountInfo.IS_ACTIVE));
                user.setChannel(rs.getString(AccountInfo.CHANNEL));
                user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
                user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
                user.setRole(rs.getString(AccountInfo.ROLE));
                user.setLanguage(rs.getString(AccountInfo.LANGUAGE));
                user.setIsLock(rs.getString(AccountInfo.IS_LOCK));
                user.setTotalFalse(rs.getString(AccountInfo.TOTAL_FALSE));
                user.setTimeLock(rs.getString(AccountInfo.TIME_LOCK));
                user.setStatus(rs.getString(AccountInfo.STATUS));
                user.setPoint(rs.getString(AccountInfo.POINT));
                user.setLastUpdate(rs.getString(AccountInfo.LAST_UPDATE));
                user.setLastLogin(rs.getString(AccountInfo.LAST_LOGIN));
                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
                user.setEmail(rs.getString(AccountInfo.EMAIL));
                user.setPicture(rs.getString(AccountInfo.PICTURE));
                user.setFullName(rs.getString(AccountInfo.FULLNAME));
            }
            return user;
        } catch (SQLException ex) {
            throw ex;
        } finally {
            closeResultSet(rs);
            closeStatement(ps, SQL_GET_USER_BY_MSISDN);
            closeConnection(connection);
            logTime("Time to getAccountByMsisdn", timeStart);
        }
    }
    

    private AccountInfo getAccountByMsisdn(String msisdn, String productName) throws SQLException {
        ResultSet rs = null;
        PreparedStatement ps = null;
        AccountInfo user = null;
        long timeStart = System.currentTimeMillis();
        Connection connection = null;
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(SQL_GET_USER_BY_MSISDN);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setString(2, productName);
            rs = ps.executeQuery();
            user = new AccountInfo();
            logTime("getAccountByMsisdn", timeStart);
            if (rs.next()) {
                logTime("next", timeStart);
                user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
                user.setUsers(rs.getString(AccountInfo.USERS));
                user.setPassword(rs.getString(AccountInfo.PASSWORD));
                user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
                user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
                user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
                user.setIsActive(rs.getString(AccountInfo.IS_ACTIVE));
                user.setChannel(rs.getString(AccountInfo.CHANNEL));
                user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
                user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
                user.setRole(rs.getString(AccountInfo.ROLE));
                user.setLanguage(rs.getString(AccountInfo.LANGUAGE));
                user.setIsLock(rs.getString(AccountInfo.IS_LOCK));
                user.setTotalFalse(rs.getString(AccountInfo.TOTAL_FALSE));
                user.setTimeLock(rs.getString(AccountInfo.TIME_LOCK));
                user.setStatus(rs.getString(AccountInfo.STATUS));
                user.setPoint(rs.getString(AccountInfo.POINT));
                user.setLastUpdate(rs.getString(AccountInfo.LAST_UPDATE));
                user.setLastLogin(rs.getString(AccountInfo.LAST_LOGIN));
                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
                user.setEmail(rs.getString(AccountInfo.EMAIL));
                user.setPicture(rs.getString(AccountInfo.PICTURE));
                user.setFullName(rs.getString(AccountInfo.FULLNAME));
            }
            return user;
        } catch (SQLException ex) {
            throw ex;
        } finally {
            closeResultSet(rs);
            closeStatement(ps, SQL_GET_USER_BY_MSISDN);
            closeConnection(connection);
            logTime("Time to getAccountByMsisdn", timeStart);
        }
    }

     public PrizeObj igetListPrizeByActionType(String ActionType) {
        PrizeObj mPrizeObj = null;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (mPrizeObj == null) {
            try {
                mPrizeObj = getListPrizeByActionType(ActionType);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
                logger.error(br, ex);
                count++;
            }
            if (mPrizeObj == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).append("==>BREAK query iGetAccountByMsisdn\n");
                logger.error(br);
                break;
            }
        }
        return mPrizeObj;
    }
    
    private PrizeObj getListPrizeByActionType(String ActionType) throws SQLException {
        ResultSet rs = null;
        PreparedStatement ps = null;
        PrizeObj mPrizeObj = null;
        long timeStart = System.currentTimeMillis();
        Connection connection = null;
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(SQL_GET_LISTPRIZE_BY_ACTIONTYPE);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, ActionType);
            rs = ps.executeQuery();
            mPrizeObj = new PrizeObj();
            logTime("getListPrizeByActionType", timeStart);
            if (rs.next()) {
                logTime("next", timeStart);
                mPrizeObj.setId(rs.getLong(PrizeObj.ID));
                mPrizeObj.setActionType(rs.getString(PrizeObj.ACTION_TYPE));
                mPrizeObj.setActionCode(rs.getString(PrizeObj.ACTION_CODE));
                mPrizeObj.setStatus(rs.getInt(PrizeObj.STATUS));
                mPrizeObj.setDescription(rs.getString(PrizeObj.DESCRIPTION));
                mPrizeObj.setPeriod(rs.getInt(PrizeObj.PERIOD));
                mPrizeObj.setMoneyConverted(rs.getInt(PrizeObj.MONEY_CONVERTED));
                mPrizeObj.setValuePrize(rs.getInt(PrizeObj.VALUE_PRIZE));
            }
            return mPrizeObj;
        } catch (SQLException ex) {
            throw ex;
        } finally {
            closeResultSet(rs);
            closeStatement(ps, SQL_GET_LISTPRIZE_BY_ACTIONTYPE);
            closeConnection(connection);
            logTime("Time to getListPrizeByActionType", timeStart);
        }
    }
    
    public Boolean updatePointAccountUser(String msisdn, String point, String serviceId) {
        long timeSt = System.currentTimeMillis();
        Boolean result = false;

        while (true) {
            result = iUpdatePointAccountUser(msisdn, point, serviceId);
            if (result != null) {
                break;
            } else {
                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
                    br.setLength(0);
                    br.append(loggerLabel).
                            append("BREAK updatePointAccountUser ==> ERROR DATABASE\n").
                            append(msisdn);
                    logger.error(br);
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    private Boolean iUpdatePointAccountUser(String msisdn, String point, String serviceId) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql1 = "update account_user set point_ = point_ - ? where msisdn = ? and service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql1);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, point);
            ps.setString(2, msisdn);
            ps.setString(3, serviceId);
            ps.execute();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).append(new Date()).
                    append("\nERROR iUpdatePointAccountUser: ").
                    append(sql1).append("\n").
                    append(msisdn);
            logger.error(br, ex);
            return null;
        } finally {
            closeStatement(ps, sql1);
            closeConnection(connection);
            logTime("Time to iUpdatePointAccountUser", timeStart);
        }
    }

    public Boolean returnPointAccountUser(String msisdn, String point, String serviceId) {
        long timeSt = System.currentTimeMillis();
        Boolean result = false;

        while (true) {
            result = iReturnPointAccountUser(msisdn, point, serviceId);
            if (result != null) {
                break;
            } else {
                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
                    br.setLength(0);
                    br.append(loggerLabel).
                            append("BREAK returnPointAccountUser ==> ERROR DATABASE\n").
                            append(msisdn);
                    logger.error(br);
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    private Boolean iReturnPointAccountUser(String msisdn, String point, String serviceId) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql1 = "update account_user set point_ = point_ + ? where msisdn = ? and service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql1);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, point);
            ps.setString(2, msisdn);
            ps.setString(3, serviceId);
            ps.execute();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).append(new Date()).
                    append("\nERROR iReturnPointAccountUser: ").
                    append(sql1).append("\n").
                    append(msisdn);
            logger.error(br, ex);
            return null;
        } finally {
            closeStatement(ps, sql1);
            closeConnection(connection);
            logTime("Time to iReturnPointAccountUser", timeStart);
        }
    }

    public AccountInfo getUserProfile(String msisdn, String serviceId) {
        AccountInfo user = null;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (user == null) {
            try {
                user = iGetUserProfile(msisdn, serviceId);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
                logger.error(br, ex);
                count++;
            }
            if (user == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).append("==>BREAK query getUserProfile\n");
                logger.error(br);
                break;
            }
        }
        return user;
    }

    private AccountInfo iGetUserProfile(String msisdn, String serviceId) throws SQLException {
        ResultSet rs = null;
        PreparedStatement ps = null;
        AccountInfo user = null;
        long timeStart = System.currentTimeMillis();
        Connection connection = null;
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement("select MSISDN, PICTURE, BIRTHDAY, FULLNAME, EMAIL, POINT_ from account_user WHERE msisdn = ? and status <> 0 and service_id = ?");
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setString(2, serviceId);
            rs = ps.executeQuery();
            user = new AccountInfo();
            logTime("iGetUserProfile", timeStart);
            if (rs.next()) {
                logTime("next", timeStart);
                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
                user.setEmail(rs.getString(AccountInfo.EMAIL));
                user.setPicture(rs.getString(AccountInfo.PICTURE));
                user.setFullName(rs.getString(AccountInfo.FULLNAME));
                user.setPoint(rs.getString(AccountInfo.POINT));

            }
            return user;
        } catch (SQLException ex) {
            throw ex;
        } finally {
            closeResultSet(rs);
            closeStatement(ps, SQL_GET_USER_BY_MSISDN);
            closeConnection(connection);
            logTime("Time to iGetUserProfile", timeStart);
        }
    }

    public AccountInfo iGetAccountByMsisdnAndPassword(String msisdn, String password, String serviceId) {
        AccountInfo user = null;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (user == null) {
            try {
                user = getAccountByMsisdnAndPassword(msisdn, password, serviceId);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
                logger.error(br, ex);
                count++;
            }
            if (user == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).append("==>BREAK query iGetAccountByMsisdn\n");
                logger.error(br);
                break;
            }
        }
        return user;
    }

    private AccountInfo getAccountByMsisdnAndPassword(String msisdn, String password, String serviceId) throws SQLException {
        ResultSet rs = null;
        PreparedStatement ps = null;
        AccountInfo user = null;
        long timeStart = System.currentTimeMillis();
        Connection connection = null;
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(SQL_GET_USER_BY_MSISDN_AND_PASSWORD);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setString(2, password);
            ps.setString(3, serviceId);
            rs = ps.executeQuery();
            user = new AccountInfo();
            logTime("getAccountByMsisdnAndPassword", timeStart);
            if (rs.next()) {
                logTime("next", timeStart);
                user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
                user.setUsers(rs.getString(AccountInfo.USERS));
                user.setPassword(rs.getString(AccountInfo.PASSWORD));
                user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
                user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
                user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
                user.setIsActive(rs.getString(AccountInfo.IS_ACTIVE));
                user.setChannel(rs.getString(AccountInfo.CHANNEL));
                user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
                user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
                user.setRole(rs.getString(AccountInfo.ROLE));
                user.setLanguage(rs.getString(AccountInfo.LANGUAGE));
                user.setIsLock(rs.getString(AccountInfo.IS_LOCK));
                user.setTotalFalse(rs.getString(AccountInfo.TOTAL_FALSE));
                user.setTimeLock(rs.getString(AccountInfo.TIME_LOCK));
                user.setStatus(rs.getString(AccountInfo.STATUS));
                user.setPoint(rs.getString(AccountInfo.POINT));
                user.setLastUpdate(rs.getString(AccountInfo.LAST_UPDATE));
                user.setLastLogin(rs.getString(AccountInfo.LAST_LOGIN));
                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
                user.setEmail(rs.getString(AccountInfo.EMAIL));
                user.setPicture(rs.getString(AccountInfo.PICTURE));
                user.setFullName(rs.getString(AccountInfo.FULLNAME));
            }
            return user;
        } catch (SQLException ex) {
            throw ex;
        } finally {
            closeResultSet(rs);
            closeStatement(ps, SQL_GET_USER_BY_MSISDN_AND_PASSWORD);
            closeConnection(connection);
            logTime("Time to getAccountByMsisdnAndPassword", timeStart);
        }
    }

    public Boolean resetSpins(String serviceId, Timestamp lastUpdate) {
        long timeSt = System.currentTimeMillis();
        Boolean result = false;

        while (true) {
            result = iResetSpins(serviceId, lastUpdate);
            if (result != null) {
                break;
            } else {
                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
                    br.setLength(0);
                    br.append(loggerLabel).
                            append("BREAK updateAccountAndSpin ==> ERROR DATABASE\n").
                            append(lastUpdate);
                    logger.error(br);
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    private Boolean iResetSpins(String serviceId, Timestamp lastUpdate) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "update account_user set last_update = ?, total_spin = 0, free_spin = 0 where service_id = ? and last_update <= sysdate";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setTimestamp(1, lastUpdate);
            ps.setInt(2, Integer.parseInt(serviceId));
            ps.execute();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).append(new Date()).
                    append("\nERROR iResetSpins: ").
                    append(sql).append("\n").
                    append(lastUpdate);
            logger.error(br, ex);
            return null;
        } finally {
            closeStatement(ps, sql);
            closeConnection(connection);
            logTime("Time to iResetSpins", timeStart);
        }
    }

//    public AccountInfo getAccountAndSpin(String id, String serviceId) {
//        AccountInfo user = null;
//        long timeBegin = System.currentTimeMillis();
//        int count = 1;
//        while (user == null) {
//            try {
//                user = iGetAccountAndSpin(id);
//            } catch (Exception ex) {
//                br.setLength(0);
//                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
//                logger.error(br, ex);
//                count++;
//            }
//            if (user == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
//                br.setLength(0);
//                br.append(loggerLabel).append(new Date()).append("==>BREAK query iGetAccountByMsisdn\n");
//                logger.error(br);
//                break;
//            }
//        }
//        return user;
//    }
//
//    private AccountInfo iGetAccountAndSpin(String id) throws SQLException {
//        ResultSet rs = null;
//        PreparedStatement ps = null;
//        AccountInfo user = null;
//        long timeStart = System.currentTimeMillis();
//        Connection connection = null;
//        String sql = "select * from account_user WHERE ID = ? and last_update > sysdate";
//        try {
//            connection = getConnection(dbName);
//            ps = connection.prepareStatement(sql);
//            if (WebserviceManager.enableQueryDbTimeout) {
//                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
//            }
//            ps.setInt(1, Integer.parseInt(id));
//            rs = ps.executeQuery();
//            user = new AccountInfo();
//            logTime("iUpdateAccountAndSpin", timeStart);
//            if (rs.next()) {
//                user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
//                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
//                user.setUsers(rs.getString(AccountInfo.USERS));
//                user.setPassword(rs.getString(AccountInfo.PASSWORD));
//                user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
//                user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
//                user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
//                user.setIsActive(rs.getString(AccountInfo.IS_ACTIVE));
//                user.setChannel(rs.getString(AccountInfo.CHANNEL));
//                user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
//                user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
//                user.setRole(rs.getString(AccountInfo.ROLE));
//                user.setLanguage(rs.getString(AccountInfo.LANGUAGE));
//                user.setIsLock(rs.getString(AccountInfo.IS_LOCK));
//                user.setTotalFalse(rs.getString(AccountInfo.TOTAL_FALSE));
//                user.setTimeLock(rs.getString(AccountInfo.TIME_LOCK));
//                user.setStatus(rs.getString(AccountInfo.STATUS));
//                user.setPoint(rs.getString(AccountInfo.POINT));
//                user.setLastUpdate(rs.getString(AccountInfo.LAST_UPDATE));
//                user.setLastLogin(rs.getString(AccountInfo.LAST_LOGIN));
//                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
//                user.setEmail(rs.getString(AccountInfo.EMAIL));
//                user.setPicture(rs.getString(AccountInfo.PICTURE));
//                user.setFullName(rs.getString(AccountInfo.FULLNAME));
//                logger.info("last update: " + user.getLastUpdate());
//
//            }
//            return user;
//        } catch (SQLException ex) {
//            throw ex;
//        } finally {
//            closeResultSet(rs);
//            closeStatement(ps);
//            closeConnection(connection);
//            logTime("Time to iUpdateAccountAndSpin", timeStart);
//        }
//    }

    public List<AccountInfo> getAccountByUserWonMiniGame(String fromDate, String toDate, String serviceId) {
        List<AccountInfo> user = null;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (user == null) {
            try {
                user = iGetAccountByUserWonMiniGame(fromDate, toDate, serviceId);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
                logger.error(br, ex);
                count++;
            }
            if (user == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).append("==>BREAK query getAccountByUserWonMiniGame\n");
                logger.error(br);
                break;
            }
        }
        return user;
    }

    private List<AccountInfo> iGetAccountByUserWonMiniGame(String fromDate, String toDate, String serviceId) throws SQLException {
        ResultSet rs = null;
        PreparedStatement ps = null;
        List<MinigameReward> rewards = new ArrayList<>();
        long timeStart = System.currentTimeMillis();
        Connection connection = null;
        String sql = "select * from minigame_reward WHERE created_date >= to_date(? || ' 00:00:00', 'MM/DD/YYYY HH24:MI:SS') AND created_date <= to_date(? || ' 23:59:59', 'MM/DD/YYYY HH24:MI:SS') AND service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, fromDate);
            ps.setString(2, toDate);
            ps.setInt(3, Integer.parseInt(serviceId));
            rs = ps.executeQuery();
            logTime("iGetAccountByUserWonMiniGame", timeStart);
            while (rs.next()) {
                MinigameReward reward = new MinigameReward();
                reward.setServiceId(rs.getInt(MinigameReward.SERVICE_ID));
                reward.setStatus(rs.getInt(MinigameReward.STATUS));
                reward.setChannel(rs.getString(MinigameReward.CHANNEL));
                reward.setUpdateDate(rs.getTimestamp(MinigameReward.UPDATE_DATE));
                reward.setCreatedDate(rs.getTimestamp(MinigameReward.CREATED_DATE));
                reward.setMsisdn(rs.getString(MinigameReward.MSISDN));
                reward.setMinigameId(rs.getInt(MinigameReward.MINIGAME_ID));
                reward.setId(rs.getInt(MinigameReward.ID));
                rewards.add(reward);
            }

            // get account
            List<AccountInfo> listAccountWon = new ArrayList<>();
            String sql2 = "select * from account_user WHERE msisdn = ? AND service_id = ?";
            for (int i = 0; i < rewards.size(); i++) {
                ps = connection.prepareStatement(sql2);
                ps.setString(1, rewards.get(i).getMsisdn());
                ps.setInt(2, Integer.parseInt(serviceId));
                rs = ps.executeQuery();
                AccountInfo user = new AccountInfo();
                if (rs.next()) {
                    user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
                    user.setMsisdn(rs.getString(AccountInfo.MSISDN));
                    user.setUsers(rs.getString(AccountInfo.USERS));
                    user.setPassword(rs.getString(AccountInfo.PASSWORD));
                    user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
                    user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
                    user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
                    user.setIsActive(rs.getString(AccountInfo.IS_ACTIVE));
                    user.setChannel(rs.getString(AccountInfo.CHANNEL));
                    user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
                    user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
                    user.setRole(rs.getString(AccountInfo.ROLE));
                    user.setLanguage(rs.getString(AccountInfo.LANGUAGE));
                    user.setIsLock(rs.getString(AccountInfo.IS_LOCK));
                    user.setTotalFalse(rs.getString(AccountInfo.TOTAL_FALSE));
                    user.setTimeLock(rs.getString(AccountInfo.TIME_LOCK));
                    user.setStatus(rs.getString(AccountInfo.STATUS));
                    user.setPoint(rs.getString(AccountInfo.POINT));
                    user.setLastUpdate(rs.getString(AccountInfo.LAST_UPDATE));
                    user.setLastLogin(rs.getString(AccountInfo.LAST_LOGIN));
                    user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
                    user.setEmail(rs.getString(AccountInfo.EMAIL));
                    user.setPicture(rs.getString(AccountInfo.PICTURE));
                    user.setFullName(rs.getString(AccountInfo.FULLNAME));
                    listAccountWon.add(user);
                }
            }
            return listAccountWon;
        } catch (SQLException ex) {
            throw ex;
        } finally {
            closeResultSet(rs);
            closeStatement(ps);
            closeConnection(connection);
            logTime("Time to iGetAccountByUserWonMiniGame", timeStart);
        }
    }

    public Boolean updateAccountAndSpin(String id, Timestamp lastUpdate) {
        long timeSt = System.currentTimeMillis();
        Boolean result = false;

        while (true) {
            result = iUpdateAccountAndSpin(id, lastUpdate);
            if (result != null) {
                break;
            } else {
                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
                    br.setLength(0);
                    br.append(loggerLabel).
                            append("BREAK updateAccountAndSpin ==> ERROR DATABASE\n").
                            append(id);
                    logger.error(br);
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    private Boolean iUpdateAccountAndSpin(String id, Timestamp lastUpdate) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql1 = "update account_user set last_update = ?, total_spin = 0, free_spin = 0 where ID = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql1);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setTimestamp(1, lastUpdate);
            ps.setInt(2, Integer.parseInt(id));
            ps.execute();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).append(new Date()).
                    append("\nERROR iUpdateAccountAndSpin: ").
                    append(sql1).append("\n").
                    append(id);
            logger.error(br, ex);
            return null;
        } finally {
            closeStatement(ps, sql1);
            closeConnection(connection);
            logTime("Time to iUpdateAccountAndSpin", timeStart);
        }
    }

    public Boolean iAddPointToAccountByMsisdn(String msisdn, String serviceId) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql1 = "update account_user set POINT_ = POINT_ + 3 where msisdn = ? and service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql1);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setInt(2, Integer.parseInt(serviceId));
            ps.execute();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).append(new Date()).
                    append("\nERROR addPointToAccountByMsisdn: ").
                    append(sql1).append("\n").
                    append(msisdn);
            logger.error(br, ex);
            return null;
        } finally {
            closeStatement(ps, sql1);
            closeConnection(connection);
            logTime("Time to addPointToAccountByMsisdn", timeStart);
        }
    }

    public Boolean insertAccountUser(String msisdn, String password, String channel, String productName) {
        long timeSt = System.currentTimeMillis();
        Boolean result = false;

        while (true) {
            result = iInsertAccountUser(msisdn, createMD5(password), channel, productName);
            if (result != null) {
                break;
            } else {
                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
                    br.setLength(0);
                    br.append(loggerLabel).
                            append("BREAK insertAccountUser ==> ERROR DATABASE\n").
                            append(msisdn);
                    logger.error(br);
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    public static String createMD5(String inforRequest) {
        // Trong Java Core thường dùng logger (log4j, slf4j), ở đây tôi mô phỏng flow của bạn
        // System.out.println("inforRequest: " + inforRequest); 

        try {
            // 1. Khởi tạo instance MD5
            MessageDigest md = MessageDigest.getInstance("MD5");

            // 2. ComputeHash tương đương: dùng getBytes(UTF_8) để đồng nhất với .NET
            byte[] hashBytes = md.digest(inforRequest.getBytes(StandardCharsets.UTF_8));

            // 3. Convert byte array sang Hex string (Lowercase, không dấu gạch ngang)
            StringBuilder sb = new StringBuilder();
            for (byte b : hashBytes) {
                // & 0xff để xử lý byte signed trong Java về unsigned như .NET
                sb.append(String.format("%02x", b));
            }

            String text = sb.toString();
            // System.out.println("myHash: " + text);
            return text;

        } catch (Exception e) {
            throw new RuntimeException("MD5 algorithm not found", e);
        }
    }
    private Boolean iInsertAccountUser(String msisdn, String password, String channel, String productName) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql1 = "insert into account_user (id, msisdn, USERNAME, PASSWORD, channel, free_spin, service_id,BET_COIN) \n"
                + "values(account_seq.nextval, ?, ?, ?, ?, ?, ?,?)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql1);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setString(2, msisdn);
            ps.setString(3, password);
            ps.setString(4, channel);
            ps.setInt(5, Common.Constant.SPIN_FREE);
            ps.setString(6, productName);
            ps.setInt(7, Common.Constant.SPIN_FREE);
            ps.execute();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).append(new Date()).
                    append("\nERROR iInsertAccountUser: ").
                    append(sql1).append("\n").
                    append(msisdn);
            logger.error(br, ex);
            return null;
        } finally {
            closeStatement(ps, sql1);
            closeConnection(connection);
            logTime("Time to iInsertAccountUser", timeStart);
        }
    }

    public Boolean insertUserProfile(String msisdn) {
        long timeSt = System.currentTimeMillis();
        Boolean result = false;

        while (true) {
            result = iInsertUserProfile(msisdn);
            if (result != null) {
                break;
            } else {
                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
                    br.setLength(0);
                    br.append(loggerLabel).
                            append("BREAK insertAccountUser ==> ERROR DATABASE\n").
                            append(msisdn);
                    logger.error(br);
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    private Boolean iInsertUserProfile(String msisdn) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql1 = "insert into fq_user_info (id, msisdn) \n"
                + "values(users_seq.nextval, ?)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql1);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.execute();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).append(new Date()).
                    append("\nERROR iInsertUserProfile: ").
                    append(sql1).append("\n").
                    append(msisdn);
            logger.error(br, ex);
            return null;
        } finally {
            closeStatement(ps, sql1);
            closeConnection(connection);
            logTime("Time to iInsertUserProfile", timeStart);
        }
    }

    public Boolean createAccountUser(String msisdn, String password, String channel, String serviceId) {
        long timeSt = System.currentTimeMillis();
        Boolean result = false;

        while (true) {
            result = iCreateAccountUser(msisdn, password, channel, serviceId);
            if (result != null) {
                break;
            } else {
                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
                    br.setLength(0);
                    br.append(loggerLabel).
                            append("BREAK insertAccountUser ==> ERROR DATABASE\n").
                            append(msisdn);
                    logger.error(br);
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    private Boolean iCreateAccountUser(String msisdn, String password, String channel, String serviceId) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql1 = "insert into account_user (id, msisdn, users, pass, channel, service_Id) \n"
                + "values(account_seq.nextval, ?, ?, ?, ?, ?)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql1);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setString(2, msisdn);
            ps.setString(3, password);
            ps.setString(4, channel);
            ps.setString(5, serviceId);
            ps.execute();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).append(new Date()).
                    append("\nERROR iCreateAccountUser: ").
                    append(sql1).append("\n").
                    append(msisdn);
            logger.error(br, ex);
            return null;
        } finally {
            closeStatement(ps, sql1);
            closeConnection(connection);
            logTime("Time to iCreateAccountUser", timeStart);
        }
    }

    public Boolean createInviting(String msisdn, String friendMsisdn, String channel, String serviceId) {
        long timeSt = System.currentTimeMillis();
        Boolean result = false;

        while (true) {
            result = iCreateInviting(msisdn, friendMsisdn, channel, serviceId);
            if (result != null) {
                break;
            } else {
                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
                    br.setLength(0);
                    br.append(loggerLabel).
                            append("BREAK createInviting ==> ERROR DATABASE\n").
                            append(msisdn);
                    logger.error(br);
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    private Boolean iCreateInviting(String msisdn, String friendMsisdn, String channel, String serviceId) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql1 = "insert into fq_inviting (id, owner_msisdn, friend_msisdn, channel, service_Id, status) \n"
                + "values(inviting_seq.nextval, ?, ?, ?, ?, 1)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql1);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setString(2, friendMsisdn);
            ps.setString(3, channel);
            ps.setString(4, serviceId);
            ps.execute();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).append(new Date()).
                    append("\nERROR iCreateInviting: ").
                    append(sql1).append("\n").
                    append(msisdn);
            logger.error(br, ex);
            return null;
        } finally {
            closeStatement(ps, sql1);
            closeConnection(connection);
            logTime("Time to iCreateInviting", timeStart);
        }
    }

    public Boolean updateAccountUser(String msisdn, String password) {
        long timeSt = System.currentTimeMillis();
        Boolean result = false;

        while (true) {
            result = iUpdateAccountUser(msisdn, password);
            if (result != null) {
                break;
            } else {
                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
                    br.setLength(0);
                    br.append(loggerLabel).
                            append("BREAK updateAccountUser ==> ERROR DATABASE\n").
                            append(msisdn);
                    logger.error(br);
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    private Boolean iUpdateAccountUser(String msisdn, String password) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql1 = "update account_user set pass = ? where msisdn = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql1);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, password);
            ps.setString(2, msisdn);
            ps.execute();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).append(new Date()).
                    append("\nERROR iUpdateAccountUser: ").
                    append(sql1).append("\n").
                    append(msisdn);
            logger.error(br, ex);
            return null;
        } finally {
            closeStatement(ps, sql1);
            closeConnection(connection);
            logTime("Time to iUpdateAccountUser", timeStart);
        }
    }

    public Boolean createUserInfo(String msisdn) {
        long timeSt = System.currentTimeMillis();
        Boolean result = false;

        while (true) {
            result = iCreateUserInfo(msisdn);
            if (result != null) {
                break;
            } else {
                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
                    br.setLength(0);
                    br.append(loggerLabel).
                            append("BREAK createUserInfo ==> ERROR DATABASE\n").
                            append(msisdn);
                    logger.error(br);
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    private Boolean iCreateUserInfo(String msisdn) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql1 = "insert into fq_user_info (id, msisdn) \n"
                + "values(users_seq.nexval, ?)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql1);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.execute();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).append(new Date()).
                    append("\nERROR iCreateUserInfo: ").
                    append(sql1).append("\n").
                    append(msisdn);
            logger.error(br, ex);
            return null;
        } finally {
            closeStatement(ps, sql1);
            closeConnection(connection);
            logTime("Time to iCreateUserInfo", timeStart);
        }
    }

    public List<SpinRecharge> checkValidSpinRecharge(String msisdn) {
        List<SpinRecharge> result = new ArrayList<SpinRecharge>();
        try {
            result = iCheckValidSpinRecharge(msisdn);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR checkValidSpinRecharge");
            logger.error(br, ex);
        }

        return result;
    }

    private List<SpinRecharge> iCheckValidSpinRecharge(String msisdn) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<SpinRecharge> listReg = new ArrayList<SpinRecharge>();
        String sql = "select * from spin_recharge where msisdn = ? and charge_time >= trunc(sysdate) and status = 0";
        long timeStart = System.currentTimeMillis();
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            rs = ps.executeQuery();
            while (rs.next()) {
                SpinRecharge spinRecharge = new SpinRecharge();
                spinRecharge.setId(rs.getLong("ID"));
                spinRecharge.setMsisdn(rs.getString("MSISDN"));
                spinRecharge.setChargeTime(rs.getTimestamp("CHARGE_TIME"));
                spinRecharge.setMoney(rs.getDouble("MONEY"));
                spinRecharge.setSpinAdded(rs.getInt("SPIN_ADDED"));
                spinRecharge.setStatus(rs.getInt("STATUS"));
                spinRecharge.setLastUpdate(rs.getTimestamp("LAST_UPDATE"));
                listReg.add(spinRecharge);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR checkValidSpinRecharge");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to check valid spin recharge " + msisdn, timeStart);
        }
        return listReg;
    }

    public Boolean iUpdateClaimSpinRecharge(long id) {

        try {
            return updateClaimSpinRecharge(id);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updateClaimSpinRecharge");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean updateClaimSpinRecharge(long id) {
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "UPDATE spin_recharge SET status = 1, last_update = sysdate WHERE id = ?";
        long timeStart = System.currentTimeMillis();
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setLong(1, id);
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR updateClaimSpinRecharge");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to updateClaimSpinRecharge", timeStart);
        }
    }

    public List<SpinGift> getSpinGift(String msisdn) {
        List<SpinGift> questionNumberTimesPlay = new ArrayList<SpinGift>();
        try {
            questionNumberTimesPlay = iGetSpinGift(msisdn);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getSpinGift");
            logger.error(br, ex);
        }

        return questionNumberTimesPlay;
    }

    private List<SpinGift> iGetSpinGift(String msisdn) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        long timeStart = System.currentTimeMillis();
        List<SpinGift> listReg = new ArrayList<SpinGift>();
        String sql = "select * from spin_gift where msisdn = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            rs = ps.executeQuery();
            while (rs.next()) {
                SpinGift spinGift = new SpinGift();
                spinGift.setId(rs.getLong("ID"));
                spinGift.setMsisdn(rs.getString("MSISDN"));
                spinGift.setGiftMsisdn(rs.getString("GIFT_MSISDN"));
                spinGift.setGiftTime(rs.getTimestamp("GIFT_TIME"));
                spinGift.setNumberSpin(rs.getInt("NUMBER_SPIN"));
                spinGift.setLastUpdate(rs.getTimestamp("LAST_UPDATE"));
                listReg.add(spinGift);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetSpinGift");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetSpinGift", timeStart);
        }
        return listReg;
    }

    public Boolean iUpdateSpinGift(SpinGift sg) {

        try {
            return updateSpinGift(sg);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updateSpinGift");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean updateSpinGift(SpinGift sg) {
        PreparedStatement ps = null;
        Connection connection = null;
        long timeStart = System.currentTimeMillis();
        String sql = "UPDATE spin_gift SET gift_msisdn=?, number_spin = ?, last_update = sysdate WHERE msisdn = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, sg.getGiftMsisdn());
            ps.setInt(2, sg.getNumberSpin());
            ps.setString(3, sg.getMsisdn());
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR updateSpinGift");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to updateSpinGift", timeStart);
        }
    }

    public Boolean iUpdatePassword(String msisdn, String newPassword) {
        try {
            return updatePassword(msisdn, newPassword);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR iUpdatePassword");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean updatePassword(String msisdn, String newPassword) {
        PreparedStatement ps = null;
        Connection connection = null;
        long timeStart = System.currentTimeMillis();
        String sql = "UPDATE account_user SET password=?,  last_update = sysdate WHERE msisdn = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, newPassword);
            ps.setString(2, msisdn);
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR updatePassword");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to updatePassword", timeStart);
        }
    }

    public Boolean iUpdateLastLogin(String msisdn) {
        try {
            return updateLastLogin(msisdn);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updateLastLogin");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean updateLastLogin(String msisdn) {
        PreparedStatement ps = null;
        Connection connection = null;
        long timeStart = System.currentTimeMillis();
        String sql = "UPDATE account_user SET  last_update = sysdate, last_login = sysdate WHERE msisdn = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR updateLastLogin");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to updateLastLogin", timeStart);
        }
    }

    public boolean iInsertSpinGift(SpinGift sg) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = insertSpinGift(sg);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR insertSpinGift - ").append(count);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK insertSpinGift\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean insertSpinGift(SpinGift sg) throws Exception {
        boolean rs = false;
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "INSERT INTO spin_gift (ID,MSISDN,GIFT_MSISDN,GIFT_TIME,NUMBER_SPIN,LAST_UPDATE) \n"
                + "VALUES(spin_gift_seq.nextval, ?, ?, sysdate, ?, sysdate)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            ps.setString(1, sg.getMsisdn());
            ps.setString(2, sg.getGiftMsisdn());
            ps.setInt(3, sg.getNumberSpin());

            ps.executeUpdate();
            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to insertSpinGift", timeStart);
        }
        return rs;
    }

    public Boolean disableAutoExtend(long registerId) {
        long timeSt = System.currentTimeMillis();
        Boolean result = false;

        while (true) {
            result = iDisableAutoExtend(registerId);
            if (result != null) {
                break;
            } else {
                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
                    br.setLength(0);
                    br.append(loggerLabel).
                            append("BREAK disableAutoExtend ==> ERROR DATABASE\n").
                            append(registerId);
                    logger.error(br);
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
            }
        }
        return result;
    }

    private Boolean iDisableAutoExtend(long registerId) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql1 = "update reg_info set status = 0, end_time = sysdate where register_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql1);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setLong(1, registerId);
            ps.execute();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).append(new Date()).
                    append("\nERROR iDisableAutoExtend: ").
                    append(sql1).append("\n").
                    append(registerId);
            logger.error(br, ex);
            return null;
        } finally {
            closeStatement(ps, sql1);
            closeConnection(connection);
            logTime("Time to iDisableAutoExtend", timeStart);
        }
    }

    public List<RankingObj> getRankObj(String msisdn, int rankType, int period) {
        List<RankingObj> rankList = new ArrayList<RankingObj>();
        try {
            rankList = iGetRankObj(msisdn, rankType, period);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getRankObj");
            logger.error(br, ex);
        }

        return rankList;
    }

    private List<RankingObj> iGetRankObj(String msisdn, int rankType, int period) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<RankingObj> listRanking = new ArrayList<RankingObj>();
        String sql = "select * from ranking where msisdn = ? and rank_type = ? and period = ? and end_time > sysdate";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setInt(2, rankType);
            ps.setInt(3, period);
            rs = ps.executeQuery();
            while (rs.next()) {
                RankingObj rankObj = new RankingObj();
                rankObj.setId(rs.getLong("ID"));
                rankObj.setMsisdn(rs.getString("MSISDN"));
                rankObj.setStartTime(rs.getTimestamp("START_TIME"));
                rankObj.setEndTime(rs.getTimestamp("END_TIME"));
                rankObj.setSpintCount(rs.getInt("SPIN_COUNT"));
                rankObj.setRankType(rs.getInt("RANK_TYPE"));
                listRanking.add(rankObj);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetRankObj");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetRankObj", timeStart);
        }
        return listRanking;
    }

    public Boolean iUpdateRanking(long id, int subType, int count) {

        try {
            return updateRanking(id, subType, count);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updateRanking");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean updateRanking(long id, int subType, int count) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "UPDATE ranking  SET spin_count=spin_count+ ? ,last_update = sysdate, sub_type = ? WHERE id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, count);
            ps.setInt(2, subType);
            ps.setLong(3, id);
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR updateRanking");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to updateRanking", timeStart);
        }
    }

    public boolean iInsertRanking(RankingObj ranking) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = insertRanking(ranking);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR InsertRanking - ").append(count);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK InsertRanking\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean insertRanking(RankingObj ranking) throws Exception {
        long timeStart = System.currentTimeMillis();
        boolean rs = false;
        PreparedStatement ps = null;
//        PreparedStatement ps2 = null;
        Connection connection = null;
        String sql = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
                + "VALUES(ranking_seq.nextval, ?, ?, ?, ?, sysdate, sysdate,?, ?, 0)";
//        String sqlWeek = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
//                + "VALUES(ranking_seq.nextval, ?, ?, trunc(sysdate,'iw') + 7 - 1/86400, ?, sysdate, sysdate,?, ?, 1)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, ranking.getMsisdn());
            ps.setTimestamp(2, ranking.getStartTime());
            ps.setTimestamp(3, ranking.getEndTime());
            ps.setInt(4, ranking.getSpintCount());
            ps.setInt(5, ranking.getSubType());
            ps.setInt(6, ranking.getRankType());
            ps.executeUpdate();

//            ps2 = connection.prepareStatement(sqlWeek);
//            if (WebserviceManager.enableQueryDbTimeout) {
//                ps2.setQueryTimeout(WebserviceManager.queryDbTimeout);
//            }
//            ps2.setString(1, ranking.getMsisdn());
//            ps2.setTimestamp(2, ranking.getStartTime());
//            ps2.setInt(3, ranking.getSpintCount());
//            ps2.setInt(4, ranking.getSubType());
//            ps2.setInt(5, ranking.getRankType());
//            ps2.executeUpdate();
            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps);
//            closeResource(ps2);
            closeResource(connection);
            logTime("Time to insertRanking", timeStart);
        }
        return rs;
    }

    public boolean iInsertRankingWeekly(RankingObj ranking) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = insertRankingWeekly(ranking);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR insertRankingWeekly - ").append(count);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK insertRankingWeekly\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean insertRankingWeekly(RankingObj ranking) throws Exception {
        long timeStart = System.currentTimeMillis();
        boolean rs = false;
        PreparedStatement ps2 = null;
        Connection connection = null;
        String sqlWeek = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
                + "VALUES(ranking_seq.nextval, ?, ?, trunc(sysdate,'iw') + 7 - 1/86400, ?, sysdate, sysdate,?, ?, 1)";
        try {
            connection = getConnection(dbName);

            ps2 = connection.prepareStatement(sqlWeek);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps2.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps2.setString(1, ranking.getMsisdn());
            ps2.setTimestamp(2, ranking.getStartTime());
            ps2.setInt(3, ranking.getSpintCount());
            ps2.setInt(4, ranking.getSubType());
            ps2.setInt(5, ranking.getRankType());
            ps2.executeUpdate();

            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps2);
            closeResource(connection);
            logTime("Time to insertRankingWeekly", timeStart);
        }
        return rs;
    }

    public boolean iInsertRankingMonth(RankingObj ranking) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = insertRankingMonth(ranking);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR iInsertRankingMonth - ").append(count);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK iInsertRankingMonth\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean insertRankingMonth(RankingObj ranking) throws Exception {
        long timeStart = System.currentTimeMillis();
        boolean rs = false;
        PreparedStatement ps2 = null;
        Connection connection = null;
        String sqlMonth = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
                + "VALUES(ranking_seq.nextval, ?, ?, add_months(trunc(sysdate,'MM'),1) - 1/86400, ?, sysdate, sysdate,?, ?, 2)";
        try {
            connection = getConnection(dbName);
            ps2 = connection.prepareStatement(sqlMonth);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps2.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps2.setString(1, ranking.getMsisdn());
            ps2.setTimestamp(2, ranking.getStartTime());
//            ps2.setTimestamp(3, ranking.getEndTime());
            ps2.setInt(3, ranking.getSpintCount());
            ps2.setInt(4, ranking.getSubType());
            ps2.setInt(5, ranking.getRankType());
            ps2.executeUpdate();

            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps2);
            closeResource(connection);
            logTime("Time to insertRankingMonth", timeStart);
        }
        return rs;
    }

    public boolean iInsertInviteTemp(String msisdn) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = insertInviteTemp(msisdn);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR insertInviteTemp - ").append(count);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK insertInviteTemp\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean insertInviteTemp(String msisdn) throws Exception {
        long timeStart = System.currentTimeMillis();
        boolean rs = false;
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "INSERT INTO invite_temp (MSISDN) \n"
                + "VALUES(?)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);

            ps.executeUpdate();
            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to insertInviteTemp", timeStart);
        }
        return rs;
    }

    public boolean iInsertInviteHistory(String msisdn, String friend) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = insertInviteHistory(msisdn, friend);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR insertInviteHistory - ").append(count);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK insertInviteHistory\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean insertInviteHistory(String msisdn, String friend) throws Exception {
        long timeStart = System.currentTimeMillis();
        boolean rs = false;
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "INSERT INTO invite_history (ID,MSISDN,INVITED_MSISDN,INVITE_DATE) \n"
                + "VALUES(invite_history_seq.nextval, ?, ?, sysdate)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setString(2, friend);

            ps.executeUpdate();
            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to insertInviteHistory", timeStart);
        }
        return rs;
    }

    public Boolean checkInviteHistory(String msisdn, String friendMsisdn) {
        Boolean registered = null;
        try {
            registered = iCheckInviteHistory(msisdn, friendMsisdn);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR checkInviteHistory");
            logger.error(br, ex);
        }

        return registered;
    }

    private Boolean iCheckInviteHistory(String msisdn, String friendMsisdn) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        long startTime = System.currentTimeMillis();
        String sql = "Select * from invite_history where msisdn = ? and invited_msisdn = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setString(2, friendMsisdn);
            rs = ps.executeQuery();
            if (rs.next()) {
                return true;
            }
            return false;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR checkInviteHistory");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to check checkInviteHistory", startTime);
        }
    }

    public String checkPresentInvite(String friendMsisdn) {
        String registered = null;
        try {
            registered = iCheckPresentInvite(friendMsisdn);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR checkPresentInvite");
            logger.error(br, ex);
        }

        return registered;
    }

    private String iCheckPresentInvite(String friendMsisdn) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        long startTime = System.currentTimeMillis();
        String sql = "Select * from invite_history where invited_msisdn = ? and get_present = 0";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, friendMsisdn);
            rs = ps.executeQuery();
            if (rs.next()) {
                return rs.getString("msisdn");
            }
            return "";
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iCheckPresentInvite");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to check iCheckPresentInvite", startTime);
        }
    }

    public Boolean updatePresentInvite(String friendMsisdn) {
        Boolean registered = null;
        try {
            registered = iUpdatePresentInvite(friendMsisdn);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updatePresentInvite");
            logger.error(br, ex);
        }

        return registered;
    }

    private Boolean iUpdatePresentInvite(String friendMsisdn) {
        PreparedStatement ps = null;
        Connection connection = null;
        long startTime = System.currentTimeMillis();
        String sql = "update invite_history set get_present = 1 where invited_msisdn = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, friendMsisdn);
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR updatePresentInvite");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to check updatePresentInvite", startTime);
        }
    }

    public Boolean deleteInviteTemp(String msisdn) {

        try {
            return iDeleteInviteTemp(msisdn);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR deleteInviteTemp");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean iDeleteInviteTemp(String msisdn) {
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "DELETE from invite_temp where msisdn = ?";

        long startTime = System.currentTimeMillis();
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR deleteInviteTemp");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to deleteInviteTemp", startTime);
        }
    }

    public Boolean checkInvited(String msisdn) {
        Boolean registered = null;
        try {
            registered = iCheckInvited(msisdn);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR checkInvited");
            logger.error(br, ex);
        }

        return registered;
    }

    private Boolean iCheckInvited(String msisdn) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        long startTime = System.currentTimeMillis();
        String sql = "Select * from invite_temp where msisdn = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            rs = ps.executeQuery();
            if (rs.next()) {
                return true;
            }
            return false;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iCheckInvited");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to check iCheckInvited", startTime);
        }
    }

    public List<PointTotalObj> getPointTotal(String msisdn) {
        List<PointTotalObj> rankList = new ArrayList<PointTotalObj>();
        try {
            rankList = iGetPointTotal(msisdn);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getPointTotal");
            logger.error(br, ex);
        }

        return rankList;
    }

    private List<PointTotalObj> iGetPointTotal(String msisdn) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<PointTotalObj> listPoint = new ArrayList<PointTotalObj>();
        String sql = "select * from point_total where msisdn = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            rs = ps.executeQuery();
            while (rs.next()) {
                PointTotalObj pointTotalObj = new PointTotalObj();
                pointTotalObj.setId(rs.getLong("ID"));
                pointTotalObj.setMsisdn(rs.getString("MSISDN"));
                pointTotalObj.setLastUpdate(rs.getTimestamp("LAST_UPDATE"));
                pointTotalObj.setPoint(rs.getInt("POINT"));
                listPoint.add(pointTotalObj);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetRankObj");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetPointTotal", timeStart);
        }
        return listPoint;
    }

    public Integer getChangedPoint(String msisdn) {
        Integer result = null;
        try {
            result = iGetChangedPoint(msisdn);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getChangedPoint");
            logger.error(br, ex);
        }

        return result;
    }

    private Integer iGetChangedPoint(String msisdn) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        Integer result = null;
        String sql = "select nvl(-sum(fee),0) * 10 point from charge_log where msisdn = ? and charge_time > trunc(sysdate) and description = 'Change point'";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            rs = ps.executeQuery();
            if (rs.next()) {
                result = rs.getInt("point");
            }
            return result;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR getChangedPoint");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to getChangedPoint", timeStart);
        }
    }

    public Boolean iUpdatePointTotal(long id, int pointAdded) {

        try {
            return updatePointTotal(id, pointAdded);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updatePointTotal");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean updatePointTotal(long id, int pointAdded) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "UPDATE point_total SET point=point+? ,last_update = sysdate WHERE id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, pointAdded);
            ps.setLong(2, id);
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR updatePointTotal");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to updatePointTotal", timeStart);
        }
    }

    public boolean iInsertPointTotal(PointTotalObj pointTotal) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = insertPointTotal(pointTotal);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR iInsertPointTotal - ").append(count);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK iInsertPointTotal\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean insertPointTotal(PointTotalObj pointObj) throws Exception {
        long timeStart = System.currentTimeMillis();
        boolean rs = false;
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "INSERT INTO point_total (ID,MSISDN,POINT,LAST_UPDATE,SUB_TYPE) \n"
                + "VALUES(point_total_seq.nextval,?,?,sysdate,?)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, pointObj.getMsisdn());
            ps.setInt(2, pointObj.getPoint());
            ps.setInt(3, pointObj.getSubType());

            ps.executeUpdate();
            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to insertPointTotal", timeStart);
        }
        return rs;
    }

    public List iLoadPackage() {
        List mConfig = null;
        long timeBegin = System.currentTimeMillis();
        while (mConfig == null) {
            try {
                mConfig = loadPackage();
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR - iLoadPackage");
                logger.error(br, ex);
            }
            if (mConfig == null && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK iLoadPackage");
                logger.error(br);
                break;
            }
        }
        return mConfig;
    }

    private List loadPackage() throws SQLException {
        long timeStart = System.currentTimeMillis();
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;
        List listConfig = null;
        String sql = "SELECT * FROM PACKG";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            rs = ps.executeQuery();
            listConfig = new ArrayList();
            while (rs.next()) {
                ProductInfo prize = new ProductInfo();
                prize.setProductId(rs.getInt("PRODUCT_ID"));
                prize.setFee(rs.getDouble("FEE"));
                prize.setNumberSpin(rs.getInt("NUMBER_SPIN"));
                prize.setProductName(rs.getString("PRODUCT_NAME"));
                prize.setSmsSyntax(rs.getString("SMS_SYNTAX"));
                prize.setBizId(rs.getInt("BIZ_ID"));
                prize.setExpireDays(rs.getInt("EXPIRE_DAYS"));
                prize.setRenew(rs.getInt("RENEW"));
                listConfig.add(prize);
            }
            logger.error("result: " + listConfig);

        } catch (SQLException ex) {
            throw ex;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to loadPackage", timeStart);
        }
        return listConfig;
    }

    public FqInviting getInvitingActive(String msisdn) {
        FqInviting inviter = null;
        try {
            inviter = iGetInvitingActive(msisdn);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getInviting");
            logger.error(br, ex);
        }

        return inviter;
    }

    private FqInviting iGetInvitingActive(String msisdn) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        FqInviting inviting = new FqInviting();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM FQ_INVITING WHERE FRIEND_MSISDN = ? and status = 1";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            rs = ps.executeQuery();
            while (rs.next()) {
                inviting.setId(rs.getInt("ID"));
                inviting.setSvId(rs.getInt("SERVICE_ID"));
                inviting.setCreatedDate(rs.getTimestamp("CREATED_DATE"));
                inviting.setOwnerMsisdn(rs.getString("OWNER_MSISDN"));
                inviting.setFriendMsisdn(rs.getString("FRIEND_MSISDN"));
                inviting.setUpdateDate(rs.getTimestamp("UPDATE_DATE"));
                inviting.setStatus(rs.getInt("STATUS"));
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetInviting");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetInviting", startTime);
        }
        return inviting;
    }

    public FqInviting getInviting(String msisdn) {
        FqInviting inviter = null;
        try {
            inviter = iGetInviting(msisdn);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getInviting");
            logger.error(br, ex);
        }

        return inviter;
    }

    private FqInviting iGetInviting(String msisdn) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        FqInviting inviting = new FqInviting();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM FQ_INVITING WHERE FRIEND_MSISDN = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            rs = ps.executeQuery();
            while (rs.next()) {
                inviting.setId(rs.getInt("ID"));
                inviting.setSvId(rs.getInt("SERVICE_ID"));
                inviting.setCreatedDate(rs.getTimestamp("CREATED_DATE"));
                inviting.setOwnerMsisdn(rs.getString("OWNER_MSISDN"));
                inviting.setFriendMsisdn(rs.getString("FRIEND_MSISDN"));
                inviting.setUpdateDate(rs.getTimestamp("UPDATE_DATE"));
                inviting.setStatus(rs.getInt("STATUS"));
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetInviting");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetInviting", startTime);
        }
        return inviting;
    }

    public Boolean updateStatusInvitingFriend(String ownerMsisdn, String friendMsisdn, String serviceId) {

        try {
            Boolean update = iUpdateStatusInvitingFriend(ownerMsisdn, friendMsisdn, serviceId);
            return update;
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updateStatusInvitingFriend");
            logger.error(br, ex);
        }
        return null;
    }

    private Boolean iUpdateStatusInvitingFriend(String ownerMsisdn, String friendMsisdn, String serviceId) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "UPDATE fq_inviting SET status = 0 WHERE FRIEND_MSISDN = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, friendMsisdn);
            //ps.setInt(2, Integer.parseInt(serviceId));
            ps.executeUpdate();

            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iUpdateStatusInvitingFriend");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iUpdateStatusInvitingFriend", timeStart);
        }
    }

    public List<RegisterInfo> getRegisterInfo(String msisdn, String packName) {
        List<RegisterInfo> questionNumberTimesPlay = new ArrayList<RegisterInfo>();
        try {
            questionNumberTimesPlay = iGetRegisterInfo(msisdn, packName);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getRegisterInfo");
            logger.error(br, ex);
        }

        return questionNumberTimesPlay;
    }

    // case the user can play, don't care about the expire date, for renewMps
    private List<RegisterInfo> iGetRegisterInfo(String msisdn, String packName) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        long startTime = System.currentTimeMillis();
//        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and product_name = ? and status = 1";
        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and product_name = ? and status = 1 and renew = 1";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setString(2, packName);

//            ps.setString(2, packName);
            rs = ps.executeQuery();
            while (rs.next()) {
                RegisterInfo regInfo = new RegisterInfo();
                regInfo.setRegisterId(rs.getLong("REGISTER_ID"));
                regInfo.setMsisdn(rs.getString("MSISDN"));
                regInfo.setProductName(rs.getString("PRODUCT_NAME"));
                regInfo.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
                regInfo.setNumberSpin(rs.getInt("NUMBER_SPIN"));
                regInfo.setPlayedTimes(rs.getInt("PLAYED_TIMES"));
                regInfo.setExtendStatus(rs.getInt("EXTEND_STATUS"));
                regInfo.setStatus(rs.getInt("STATUS"));
                listReg.add(regInfo);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetRegisterInfo");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to get reg info", startTime);
        }
        return listReg;
    }

    public List<RegisterInfo> getRegisterNotCheckStatusInfo(String msisdn, String packName) {
        List<RegisterInfo> questionNumberTimesPlay = new ArrayList<RegisterInfo>();
        try {
            questionNumberTimesPlay = iGetRegisterNotCheckStatusInfo(msisdn, packName);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getRegisterInfo");
            logger.error(br, ex);
        }

        return questionNumberTimesPlay;
    }

    // case the user can play, don't care about the expire date, for renewMps
    private List<RegisterInfo> iGetRegisterNotCheckStatusInfo(String msisdn, String packName) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        long startTime = System.currentTimeMillis();
//        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and product_name = ? and status = 1";
        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and product_name = ? and renew = 1 and end_time is null ORDER BY expire_time DESC";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setString(2, packName);

//            ps.setString(2, packName);
            rs = ps.executeQuery();
            while (rs.next()) {
                RegisterInfo regInfo = new RegisterInfo();
                regInfo.setRegisterId(rs.getLong("REGISTER_ID"));
                regInfo.setMsisdn(rs.getString("MSISDN"));
                regInfo.setProductName(rs.getString("PRODUCT_NAME"));
                regInfo.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
                regInfo.setNumberSpin(rs.getInt("NUMBER_SPIN"));
                regInfo.setPlayedTimes(rs.getInt("PLAYED_TIMES"));
                regInfo.setExtendStatus(rs.getInt("EXTEND_STATUS"));
                regInfo.setStatus(rs.getInt("STATUS"));
                listReg.add(regInfo);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetRegisterInfo");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to get reg info", startTime);
        }
        return listReg;
    }

    public List<RegisterInfo> getRegisterInfoAll(String msisdn) {
        List<RegisterInfo> questionNumberTimesPlay = new ArrayList<RegisterInfo>();
        try {
            questionNumberTimesPlay = iGetRegisterInfoAll(msisdn);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getRegisterInfoAll");
            logger.error(br, ex);
        }

        return questionNumberTimesPlay;
    }

    private List<RegisterInfo> iGetRegisterInfoAll(String msisdn) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and status = 1";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            rs = ps.executeQuery();
            while (rs.next()) {
                RegisterInfo regInfo = new RegisterInfo();
                regInfo.setRegisterId(rs.getLong("REGISTER_ID"));
                regInfo.setMsisdn(rs.getString("MSISDN"));
                regInfo.setProductName(rs.getString("PRODUCT_NAME"));
                regInfo.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
                regInfo.setNumberSpin(rs.getInt("NUMBER_SPIN"));
                regInfo.setPlayedTimes(rs.getInt("PLAYED_TIMES"));
                regInfo.setExtendStatus(rs.getInt("EXTEND_STATUS"));
                regInfo.setStatus(rs.getInt("STATUS"));
                listReg.add(regInfo);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR getRegisterInfoAll");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to get reg info all", startTime);
        }
        return listReg;
    }

    public List<RegisterInfo> getRegisterInday(String msisdn, String productName) {
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        try {
            listReg = iGetRegisterInday(msisdn, productName);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getRegisterInDay");
            logger.error(br, ex);
        }

        return listReg;
    }

    // get all active package
    private List<RegisterInfo> iGetRegisterInday(String msisdn, String productName) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and product_name = ? and renew = 1 and status = 1 and expire_time > sysdate order by register_time desc";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setString(2, productName);
            rs = ps.executeQuery();
            while (rs.next()) {
                RegisterInfo regInfo = new RegisterInfo();
                regInfo.setRegisterId(rs.getLong("REGISTER_ID"));
                regInfo.setMsisdn(rs.getString("MSISDN"));
                regInfo.setProductName(rs.getString("PRODUCT_NAME"));
                regInfo.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
                regInfo.setNumberSpin(rs.getInt("NUMBER_SPIN"));
                regInfo.setPlayedTimes(rs.getInt("PLAYED_TIMES"));
                regInfo.setExtendStatus(rs.getInt("EXTEND_STATUS"));
                regInfo.setStatus(rs.getInt("STATUS"));
                regInfo.setRenew(rs.getInt("RENEW"));
                listReg.add(regInfo);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR getRegisterInDay");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to get reg info in day", startTime);
        }
        return listReg;
    }

    public List<RegisterInfo> getUserServices(String msisdn, String serviceId) {
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        try {
            listReg = iGetUserServices(msisdn, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getUserServices");
            logger.error(br, ex);
        }

        return listReg;
    }

    private List<RegisterInfo> iGetUserServices(String msisdn, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and status = 1 and service_id = ? and expire_time > sysdate order by register_time desc";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setString(2, serviceId);
            rs = ps.executeQuery();
            while (rs.next()) {
                RegisterInfo info = new RegisterInfo();
                info.setRegisterId(rs.getLong("REGISTER_ID"));
                info.setMsisdn(rs.getString("MSISDN"));
                info.setPlayedTimes(rs.getInt("PLAYED_TIMES"));
                info.setProductName(rs.getString("PRODUCT_NAME"));
                info.setNumberSpin(rs.getInt("NUMBER_SPIN"));
                info.setStatus(rs.getInt("STATUS"));
                listReg.add(info);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetUserServices");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetUserServices", startTime);
        }
        return listReg;
    }

    public List<RegisterInfo> getUserServicesRenew(String msisdn, String serviceId) {
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        try {
            listReg = iGetUserServicesRenew(msisdn, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getUserServices");
            logger.error(br, ex);
        }

        return listReg;
    }

    private List<RegisterInfo> iGetUserServicesRenew(String msisdn, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and status = 1 and renew = 1 and service_id = ? and expire_time > sysdate order by register_time desc";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setString(2, serviceId);
            rs = ps.executeQuery();
            while (rs.next()) {
                RegisterInfo info = new RegisterInfo();
                info.setRegisterId(rs.getLong("REGISTER_ID"));
                info.setMsisdn(rs.getString("MSISDN"));
                info.setPlayedTimes(rs.getInt("PLAYED_TIMES"));
                info.setProductName(rs.getString("PRODUCT_NAME"));
                info.setNumberSpin(rs.getInt("NUMBER_SPIN"));
                info.setStatus(rs.getInt("STATUS"));
                listReg.add(info);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetUserServices");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetUserServices", startTime);
        }
        return listReg;
    }

    public List<Game> getDataByParentId(String parentId, String seqPage, String rowOnPage, String serviceId) {
        List<Game> listGames = new ArrayList<Game>();
        try {
            listGames = iGetDataByParentId(parentId, seqPage, rowOnPage, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getRegisterInDay");
            logger.error(br, ex);
        }

        return listGames;
    }

    private List<Game> iGetDataByParentId(String parentId, String seqPage, String rowOnPage, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<Game> listGames = new ArrayList<Game>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM (SELECT ID, code, content_type, content_, created_date, description_global, " +
                "description_local, from_date, icon, introduction_global, introduction_local, is_played, level_, " +
                "logo, name_global, name_local, parent_id, service_id, status, to_date_, type_of, update_date," +
                "ROW_NUMBER() OVER (ORDER BY update_date) R FROM FQ_GAMES where PARENT_ID = ? AND service_id = ?) where R BETWEEN ? and ?";
//        SELECT last_name FROM
//                (SELECT last_name, ROW_NUMBER() OVER (ORDER BY last_name) R FROM employees)
//        WHERE R BETWEEN 51 and 100;
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            int seq = Integer.parseInt(seqPage);
            int row = Integer.parseInt(rowOnPage);
            int from = (seq - 1) * row + 1;
            int to = (seq) * row;


            ps.setString(1, parentId);
            ps.setInt(2, Integer.parseInt(serviceId));
            ps.setInt(3, from);
            ps.setInt(4, to);
//            ps.setInt(3, to);

            rs = ps.executeQuery();
            while (rs.next()) {
                Game game = new Game();
                game.setId(rs.getString(Game.ID));
                game.setCode(rs.getString(Game.CODE));
                game.setContent(rs.getString(Game.CONTENT));
                game.setContentType(rs.getString(Game.CONTENT_TYPE));
                game.setCreatedDate(rs.getString(Game.CREATED_DATE));
                game.setDescriptionGlobal(rs.getString(Game.DESCRIPTION_GLOBAL));
                game.setDescriptionLocal(rs.getString(Game.DESCRIPTION_LOCAL));
                game.setFromDate(rs.getString(Game.FROM_DATE));
                game.setIcon(rs.getString(Game.ICON));
                game.setIntroductionGlobal(rs.getString(Game.INTRODUCTION_GLOBAL));
                game.setIntroductionLocal(rs.getString(Game.INTRODUCTION_LOCAL));
                game.setIsPlayed(rs.getString(Game.IS_PLAYED));
                game.setLevel(rs.getString(Game.LEVEL));
                game.setLogo(rs.getString(Game.LOGO));
                game.setNameGlobal(rs.getString(Game.NAME_GLOBAL));
                game.setNameLocal(rs.getString(Game.NAME_LOCAL));
                game.setParentId(rs.getString(Game.PARENT_ID));
                game.setServiceId(rs.getString(Game.SERVICE_ID));
                game.setStatus(rs.getString(Game.STATUS));
                game.setToDate(rs.getString(Game.TO_DATE));
                game.setTypeOf(rs.getString(Game.TYPE_OF));
                game.setUpdateDate(rs.getString(Game.UPDATE_DATE));
                listGames.add(game);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetDataByParentId");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetDataByParentId", startTime);
        }
        return listGames;
    }

    public int getTotalPage(String parentId, String seqPage, String rowOnPage, String serviceId) {
        int totalpage = 0;
        try {
            totalpage = iGetTotalPage(parentId, seqPage, rowOnPage, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getRegisterInDay");
            logger.error(br, ex);
        }

        return totalpage;
    }

    private int iGetTotalPage(String parentId, String seqPage, String rowOnPage, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        int totalPage = 0;
        long startTime = System.currentTimeMillis();
        String sql = "SELECT COUNT(*) FROM fq_games where PARENT_ID = ? AND service_id = ?";
//        SELECT last_name FROM
//                (SELECT last_name, ROW_NUMBER() OVER (ORDER BY last_name) R FROM employees)
//        WHERE R BETWEEN 51 and 100;
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            ps.setString(1, parentId);
            ps.setInt(2, Integer.parseInt(serviceId));

            rs = ps.executeQuery();
            int total = 0;
            while (rs.next()) {
                total = rs.getInt("COUNT(*)");
            }

            totalPage = total / Integer.parseInt(rowOnPage);
            if (total % Integer.parseInt(rowOnPage) != 0) {
                totalPage += 1;
            }
            logger.error("total page: " + totalPage);
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetTotalPage");
            logger.error(br, ex);
            return 0;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetTotalPage", startTime);
        }
        return totalPage;
    }

    public List<Game> getDataById(String id, String seqPage, String rowOnPage, String serviceId) {
        List<Game> listGames = new ArrayList<Game>();
        try {
            listGames = iGetDataById(id, seqPage, rowOnPage, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getRegisterInDay");
            logger.error(br, ex);
        }

        return listGames;
    }

    private List<Game> iGetDataById(String id, String seqPage, String rowOnPage, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<Game> listGames = new ArrayList<Game>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM FQ_GAMES WHERE ID = ? AND service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            int seq = Integer.parseInt(seqPage);
            int row = Integer.parseInt(rowOnPage);
            int from = (seq - 1) * row;
            int to = (seq) * row;

            ps.setInt(1, Integer.parseInt(id));
            ps.setInt(2, Integer.parseInt(serviceId));
            rs = ps.executeQuery();
            while (rs.next()) {
                Game game = new Game();
                game.setId(rs.getString(Game.ID));
                game.setCode(rs.getString(Game.CODE));
                game.setContent(rs.getString(Game.CONTENT));
                game.setContentType(rs.getString(Game.CONTENT_TYPE));
                game.setCreatedDate(rs.getString(Game.CREATED_DATE));
                game.setDescriptionGlobal(rs.getString(Game.DESCRIPTION_GLOBAL));
                game.setDescriptionLocal(rs.getString(Game.DESCRIPTION_LOCAL));
                game.setFromDate(rs.getString(Game.FROM_DATE));
                game.setIcon(rs.getString(Game.ICON));
                game.setIntroductionGlobal(rs.getString(Game.INTRODUCTION_GLOBAL));
                game.setIntroductionLocal(rs.getString(Game.INTRODUCTION_LOCAL));
                game.setIsPlayed(rs.getString(Game.IS_PLAYED));
                game.setLevel(rs.getString(Game.LEVEL));
                game.setLogo(rs.getString(Game.LOGO));
                game.setNameGlobal(rs.getString(Game.NAME_GLOBAL));
                game.setNameLocal(rs.getString(Game.NAME_LOCAL));
                game.setParentId(rs.getString(Game.PARENT_ID));
                game.setServiceId(rs.getString(Game.SERVICE_ID));
                game.setStatus(rs.getString(Game.STATUS));
                game.setToDate(rs.getString(Game.TO_DATE));
                game.setTypeOf(rs.getString(Game.TYPE_OF));
                game.setUpdateDate(rs.getString(Game.UPDATE_DATE));
                listGames.add(game);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetDataByParentId");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetDataByParentId", startTime);
        }
        return listGames;
    }

    public Boolean updateUserPlaying(long registerId, String msisdn, String serviceId) {

        try {
            Boolean playing = iUpdateUserPlaying(registerId);
            Boolean spin = iUpdateTotalSpin(msisdn, serviceId);
            if (playing && spin)
                return true;
            else
                return false;
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updateUserPlaying");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean iUpdateUserPlaying(long registerId) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "UPDATE reg_info SET PLAYED_TIMES=PLAYED_TIMES+1 WHERE register_id = ?";

        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setLong(1, registerId);
            ps.executeUpdate();

            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR updateUserPlaying");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to updateUserPlaying", timeStart);
        }
    }

    private Boolean iUpdateTotalSpin(String msisdn, String serviceId) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "UPDATE account_user SET TOTAL_SPIN=TOTAL_SPIN+1 WHERE msisdn = ? and service_id = ?";

        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setInt(2, Integer.parseInt(serviceId));
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iUpdateTotalSpin");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iUpdateTotalSpin", timeStart);
        }
    }

    public Boolean reduceFreeSpin(String msisdn, String serviceId) {

        try {
            return iReduceFreeSpin(msisdn, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR reduceFreeSpin");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean iReduceFreeSpin(String msisdn, String serviceId) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "UPDATE account_user SET FREE_SPIN=FREE_SPIN-1, TOTAL_SPIN=TOTAL_SPIN+1 WHERE msisdn = ? and service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setInt(2, Integer.parseInt(serviceId));
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iReduceFreeSpin");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iReduceFreeSpin", timeStart);
        }
    }

    public Boolean updateUserPoint(String msisdn, String point, String serviceId) {

        try {
            return iUpdateUserPoint(msisdn, point, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updateUserPoint");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean iUpdateUserPoint(String msisdn, String point, String serviceId) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "UPDATE account_user SET point_=point_+? WHERE msisdn = ? and service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, Integer.parseInt(point));
            ps.setString(2, msisdn);
            ps.setInt(2, Integer.parseInt(serviceId));

            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iUpdateUserPoint");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iUpdateUserPoint", timeStart);
        }
    }

    public List<AccountInfo> getAccounts(String msisdn, String seqPage, String rowOnPage, String serviceId) {
        List<AccountInfo> listAccounts = new ArrayList<AccountInfo>();
        try {
            listAccounts = iGetAccounts(msisdn, seqPage, rowOnPage, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getRanking");
            logger.error(br, ex);
        }

        return listAccounts;
    }

    private List<AccountInfo> iGetAccounts(String msisdn, String seqPage, String rowOnPage, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<AccountInfo> listAccounts = new ArrayList<AccountInfo>();
        long startTime = System.currentTimeMillis();
//        String sql = "SELECT msisdn, created_date, update_date, point_, picture, fullname, email, birthday FROM ACCOUNT_USER  WHERE service_id = ?";
        String sql = "SELECT * FROM ACCOUNT_USER WHERE service_id = ? ORDER BY POINT_ DESC";

        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, Integer.parseInt(serviceId));

            rs = ps.executeQuery();
            while (rs.next()) {
                AccountInfo user = new AccountInfo();
                user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
//                user.setUsers(rs.getString(AccountInfo.USERS));
//                user.setPassword(rs.getString(AccountInfo.PASSWORD));
                user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
                user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
                user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
//                user.setIsActive(rs.getInt(AccountInfo.IS_ACTIVE));
//                user.setChannel(rs.getString(AccountInfo.CHANNEL));
                user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
                user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
//                user.setRole(rs.getString(AccountInfo.ROLE));
//                user.setLanguage(rs.getInt(AccountInfo.LANGUAGE));
//                user.setIsLock(rs.getInt(AccountInfo.IS_LOCK));
//                user.setTotalFalse(rs.getInt(AccountInfo.TOTAL_FALSE));
//                user.setTimeLock(rs.getTimestamp(AccountInfo.TIME_LOCK));
//                user.setStatus(rs.getInt(AccountInfo.STATUS));
                user.setPoint(rs.getString(AccountInfo.POINT));
//                user.setLastUpdate(rs.getTimestamp(AccountInfo.LAST_UPDATE));
//                user.setLastLogin(rs.getTimestamp(AccountInfo.LAST_LOGIN));
                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
                user.setEmail(rs.getString(AccountInfo.EMAIL));
                user.setPicture(rs.getString(AccountInfo.PICTURE));
                user.setFullName(rs.getString(AccountInfo.FULLNAME));
                listAccounts.add(user);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetAccounts");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetAccounts", startTime);
        }
        return listAccounts;
    }

    public List<AccountInfo> getAccountsByPlayedTime(String msisdn, String seqPage, String rowOnPage, String serviceId) {
        List<AccountInfo> listAccounts = new ArrayList<AccountInfo>();
        try {
            listAccounts = iGetAccountsByPlayedTime(msisdn, seqPage, rowOnPage, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getAccountsByPlayedTime");
            logger.error(br, ex);
        }

        return listAccounts;
    }

    private List<AccountInfo> iGetAccountsByPlayedTime(String msisdn, String seqPage, String rowOnPage, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<AccountInfo> listAccounts = new ArrayList<AccountInfo>();
        long startTime = System.currentTimeMillis();
//        String sql = "SELECT msisdn, created_date, update_date, point_, picture, fullname, email, birthday FROM ACCOUNT_USER  WHERE service_id = ?";
//        String sql = "SELECT * FROM ACCOUNT_USER WHERE service_id = ? ORDER BY total_spin DESC";

        String sql = "SELECT * FROM (SELECT ID, msisdn, service_id, created_date, update_date, free_spin," +
                "total_spin, point_, birthday, email, picture, fullname," +
                "ROW_NUMBER() OVER (ORDER BY total_spin) R FROM account_user where total_spin > ? and service_id = ?) where R BETWEEN ? and ?";

        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            int seq = Integer.parseInt(seqPage);
            int row = Integer.parseInt(rowOnPage);
            int from = (seq - 1) * row + 1;
            int to = (seq) * row;

            ps.setInt(1, Common.Constant.SPIN_FREE);
            ps.setInt(2, Integer.parseInt(serviceId));
            ps.setInt(3, from);
            ps.setInt(4, to);
            rs = ps.executeQuery();

            while (rs.next()) {
                AccountInfo user = new AccountInfo();
                user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
//                user.setUsers(rs.getString(AccountInfo.USERS));
//                user.setPassword(rs.getString(AccountInfo.PASSWORD));
                user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
                user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
                user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
//                user.setIsActive(rs.getInt(AccountInfo.IS_ACTIVE));
//                user.setChannel(rs.getString(AccountInfo.CHANNEL));
                user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
                user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
//                user.setRole(rs.getString(AccountInfo.ROLE));
//                user.setLanguage(rs.getInt(AccountInfo.LANGUAGE));
//                user.setIsLock(rs.getInt(AccountInfo.IS_LOCK));
//                user.setTotalFalse(rs.getInt(AccountInfo.TOTAL_FALSE));
//                user.setTimeLock(rs.getTimestamp(AccountInfo.TIME_LOCK));
//                user.setStatus(rs.getInt(AccountInfo.STATUS));
                user.setPoint(rs.getString(AccountInfo.POINT));
//                user.setLastUpdate(rs.getTimestamp(AccountInfo.LAST_UPDATE));
//                user.setLastLogin(rs.getTimestamp(AccountInfo.LAST_LOGIN));
                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
                user.setEmail(rs.getString(AccountInfo.EMAIL));
                user.setPicture(rs.getString(AccountInfo.PICTURE));
                user.setFullName(rs.getString(AccountInfo.FULLNAME));
                listAccounts.add(user);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetAccountsByPlayedTime");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetAccountsByPlayedTime", startTime);
        }
        return listAccounts;
    }

    public List<AccountInfo> getAccountsByHighestPlayedTime(int max, String serviceId) {
        List<AccountInfo> listAccounts = new ArrayList<AccountInfo>();
        try {
            listAccounts = iGetAccountsByHighestPlayedTime(max, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getAccountsByHighestPlayedTime");
            logger.error(br, ex);
        }

        return listAccounts;
    }

    private List<AccountInfo> iGetAccountsByHighestPlayedTime(int max, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<AccountInfo> listAccounts = new ArrayList<AccountInfo>();
        long startTime = System.currentTimeMillis();
//        String sql = "SELECT msisdn, created_date, update_date, point_, picture, fullname, email, birthday FROM ACCOUNT_USER  WHERE service_id = ?";
//        String sql = "SELECT * FROM ACCOUNT_USER WHERE service_id = ? ORDER BY total_spin DESC";

        String sql = "SELECT * FROM (SELECT ID, msisdn, service_id, created_date, update_date, free_spin," +
                "total_spin, point_, birthday, email, picture, fullname," +
                "ROW_NUMBER() OVER (ORDER BY total_spin) R FROM account_user where total_spin > ? and service_id = ?) where R BETWEEN 0 and ?";

        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            ps.setInt(1, Common.Constant.SPIN_FREE);
            ps.setInt(2, Integer.parseInt(serviceId));
            ps.setInt(3, max);
            rs = ps.executeQuery();

            while (rs.next()) {
                AccountInfo user = new AccountInfo();
                user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
//                user.setUsers(rs.getString(AccountInfo.USERS));
//                user.setPassword(rs.getString(AccountInfo.PASSWORD));
                user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
                user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
                user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
//                user.setIsActive(rs.getInt(AccountInfo.IS_ACTIVE));
//                user.setChannel(rs.getString(AccountInfo.CHANNEL));
                user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
                user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
//                user.setRole(rs.getString(AccountInfo.ROLE));
//                user.setLanguage(rs.getInt(AccountInfo.LANGUAGE));
//                user.setIsLock(rs.getInt(AccountInfo.IS_LOCK));
//                user.setTotalFalse(rs.getInt(AccountInfo.TOTAL_FALSE));
//                user.setTimeLock(rs.getTimestamp(AccountInfo.TIME_LOCK));
//                user.setStatus(rs.getInt(AccountInfo.STATUS));
                user.setPoint(rs.getString(AccountInfo.POINT));
//                user.setLastUpdate(rs.getTimestamp(AccountInfo.LAST_UPDATE));
//                user.setLastLogin(rs.getTimestamp(AccountInfo.LAST_LOGIN));
                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
                user.setEmail(rs.getString(AccountInfo.EMAIL));
                user.setPicture(rs.getString(AccountInfo.PICTURE));
                user.setFullName(rs.getString(AccountInfo.FULLNAME));
                listAccounts.add(user);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetAccountsByHighestPlayedTime");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetAccountsByHighestPlayedTime", startTime);
        }
        return listAccounts;
    }

    public boolean insertHighestPlayingTimes(String msisdn, String totalSpin, String serviceId) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = iInsertHighestPlayingTimes(msisdn, totalSpin, serviceId);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR insertHighestPlayingTimes - ").append(count);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK insertHighestPlayingTimes\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean iInsertHighestPlayingTimes(String msisdn, String totalSpin, String serviceId) throws Exception {
        long timeStart = System.currentTimeMillis();
        boolean rs = false;
        PreparedStatement ps = null;
//        PreparedStatement ps2 = null;
        Connection connection = null;
        String sql = "INSERT INTO playing_times_reward (ID,MSISDN,TOTAL_SPIN,CREATED_DATE,UPDATE_DATE,SERVICE_ID) \n"
                + "VALUES(playing_times_reward_seq.nextval, ?, ?, sysdate, sysdate, ?)";
//        String sqlWeek = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
//                + "VALUES(ranking_seq.nextval, ?, ?, trunc(sysdate,'iw') + 7 - 1/86400, ?, sysdate, sysdate,?, ?, 1)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setInt(2, Integer.parseInt(totalSpin));
            ps.setInt(3, Integer.parseInt(serviceId));
            ps.executeUpdate();

//            ps2 = connection.prepareStatement(sqlWeek);
//            if (WebserviceManager.enableQueryDbTimeout) {
//                ps2.setQueryTimeout(WebserviceManager.queryDbTimeout);
//            }
//            ps2.setString(1, ranking.getMsisdn());
//            ps2.setTimestamp(2, ranking.getStartTime());
//            ps2.setInt(3, ranking.getSpintCount());
//            ps2.setInt(4, ranking.getSubType());
//            ps2.setInt(5, ranking.getRankType());
//            ps2.executeUpdate();
            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps);
//            closeResource(ps2);
            closeResource(connection);
            logTime("Time to iInsertHighestPlayingTimes", timeStart);
        }
        return rs;
    }

    public List<PlayingTimeRewrad> getHighestPlayedTime(String serviceId) {
        List<PlayingTimeRewrad> playingTimeRewrads = new ArrayList<PlayingTimeRewrad>();
        try {
            playingTimeRewrads = iGetHighestPlayedTime(serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getHighestPlayedTime");
            logger.error(br, ex);
        }

        return playingTimeRewrads;
    }

    private List<PlayingTimeRewrad> iGetHighestPlayedTime(String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<PlayingTimeRewrad> playingTimeRewrads = new ArrayList<PlayingTimeRewrad>();
        long startTime = System.currentTimeMillis();
//        String sql = "SELECT msisdn, created_date, update_date, point_, picture, fullname, email, birthday FROM ACCOUNT_USER  WHERE service_id = ?";
//        String sql = "SELECT * FROM ACCOUNT_USER WHERE service_id = ? ORDER BY total_spin DESC";

        String sql = "SELECT * FROM playing_times_reward where service_id = ?";

        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            ps.setInt(1, Integer.parseInt(serviceId));
            rs = ps.executeQuery();

            while (rs.next()) {
                PlayingTimeRewrad playingTimeRewrad = new PlayingTimeRewrad();
                playingTimeRewrad.setId(rs.getInt(PlayingTimeRewrad.ID));
                playingTimeRewrad.setMsisdn(rs.getString(PlayingTimeRewrad.MSISDN));
                playingTimeRewrad.setServiceId(rs.getInt(PlayingTimeRewrad.SERVICE_ID));
                playingTimeRewrad.setCreatedDate(rs.getTimestamp(PlayingTimeRewrad.CREATED_DATE));
                playingTimeRewrad.setUpdateDate(rs.getTimestamp(PlayingTimeRewrad.UPDATE_DATE));
                playingTimeRewrad.setStatus(rs.getInt(PlayingTimeRewrad.STATUS));
                playingTimeRewrad.setTotalSpin(rs.getInt(PlayingTimeRewrad.TOTAL_SPIN));
                playingTimeRewrad.setChannel(rs.getString(PlayingTimeRewrad.CHANNEL));
                playingTimeRewrads.add(playingTimeRewrad);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetHighestPlayedTime");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetHighestPlayedTime", startTime);
        }
        return playingTimeRewrads;
    }

    public boolean deleteHighestPlayedTime(String serviceId) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = ideleteHighestPlayedTime(serviceId);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR deleteHighestPlayedTime - ").append(count);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK deleteHighestPlayedTime\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean ideleteHighestPlayedTime(String serviceId) throws Exception {
        long timeStart = System.currentTimeMillis();
        boolean rs = false;
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "DELETE from playing_times_reward WHERE service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, Integer.parseInt(serviceId));
            ps.executeUpdate();
            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps);
//            closeResource(ps2);
            closeResource(connection);
            logTime("Time to ideleteHighestPlayedTime", timeStart);
        }
        return rs;
    }

    public List<PlayingTimeHistory> getPlayedTimeHistory(String serviceId) {
        List<PlayingTimeHistory> playingTimeHistories = new ArrayList<PlayingTimeHistory>();
        try {
            playingTimeHistories = iGetPlayedTimeHistory(serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getPlayedTimeHistory");
            logger.error(br, ex);
        }
        return playingTimeHistories;
    }

    private List<PlayingTimeHistory> iGetPlayedTimeHistory(String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<PlayingTimeHistory> playingTimeHistories = new ArrayList<PlayingTimeHistory>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM playing_times_history where service_id = ?";

        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, Integer.parseInt(serviceId));
            rs = ps.executeQuery();

            while (rs.next()) {
                PlayingTimeHistory playingTimeHistory = new PlayingTimeHistory();
                playingTimeHistory.setId(rs.getInt(PlayingTimeHistory.ID));
                playingTimeHistory.setChannel(rs.getString(PlayingTimeHistory.CHANNEL));
                playingTimeHistory.setServiceId(rs.getInt(PlayingTimeHistory.SERVICE_ID));
                playingTimeHistory.setCreatedDate(rs.getTimestamp(PlayingTimeHistory.CREATED_DATE));
                playingTimeHistory.setUpdateDate(rs.getTimestamp(PlayingTimeHistory.UPDATE_DATE));
                playingTimeHistory.setStatus(rs.getInt(PlayingTimeHistory.STATUS));
                playingTimeHistories.add(playingTimeHistory);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetPlayedTimeHistory");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetPlayedTimeHistory", startTime);
        }
        return playingTimeHistories;
    }

    public boolean insertPlayingTimesHistory(String serviceId) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = iInsertPlayingTimesHistory(serviceId);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR insertPlayingTimesHistory - ").append(count);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK insertPlayingTimesHistory\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean iInsertPlayingTimesHistory(String serviceId) throws Exception {
        long timeStart = System.currentTimeMillis();
        boolean rs = false;
        PreparedStatement ps = null;
//        PreparedStatement ps2 = null;
        Connection connection = null;
        String sql = "INSERT INTO playing_times_history (ID,CREATED_DATE,UPDATE_DATE,SERVICE_ID) \n"
                + "VALUES(playing_times_history_seq.nextval, sysdate, sysdate, ?)";
//        String sqlWeek = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
//                + "VALUES(ranking_seq.nextval, ?, ?, trunc(sysdate,'iw') + 7 - 1/86400, ?, sysdate, sysdate,?, ?, 1)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, Integer.parseInt(serviceId));
            ps.executeUpdate();

//            ps2 = connection.prepareStatement(sqlWeek);
//            if (WebserviceManager.enableQueryDbTimeout) {
//                ps2.setQueryTimeout(WebserviceManager.queryDbTimeout);
//            }
//            ps2.setString(1, ranking.getMsisdn());
//            ps2.setTimestamp(2, ranking.getStartTime());
//            ps2.setInt(3, ranking.getSpintCount());
//            ps2.setInt(4, ranking.getSubType());
//            ps2.setInt(5, ranking.getRankType());
//            ps2.executeUpdate();
            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps);
//            closeResource(ps2);
            closeResource(connection);
            logTime("Time to iInsertPlayingTimesHistory", timeStart);
        }
        return rs;
    }

    public Boolean updatePlayingTimesHistory(int id) {

        try {
            return iUpdatePlayingTimesHistory(id);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updatePlayingTimesHistory");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean iUpdatePlayingTimesHistory(int id) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "UPDATE playing_times_history SET update_date = sysdate WHERE id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, id);
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iUpdatePlayingTimesHistory");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iUpdatePlayingTimesHistory", timeStart);
        }
    }

    public Boolean updateUserProfile(String msisdn, String fullName, String picture, String birthday, String serviceId) {

        try {
            return iUpdateUserProfile(msisdn, fullName, picture, birthday, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updateUserProfile");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean iUpdateUserProfile(String msisdn, String fullName, String picture, String birthday, String serviceId) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "UPDATE account_user SET fullname = ?, picture = ?, birthday = TO_DATE(?, 'MM/DD/YYYY') WHERE MSISDN = ? AND service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, fullName);
            ps.setString(2, picture);
            ps.setString(3, birthday);
            ps.setString(4, msisdn);
            ps.setString(5, serviceId);
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iUpdateUserProfile");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iUpdateUserProfile", timeStart);
        }
    }

    public List<Game> getMiniGames(String parentId, String isPlayed, String fromDate, String toDate, String serviceId) {
        List<Game> listGames = new ArrayList<Game>();
        try {
            listGames = iGetMiniGames(parentId, isPlayed, fromDate, toDate, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getMiniGames");
            logger.error(br, ex);
        }
        return listGames;
    }

    private List<Game> iGetMiniGames(String parentId, String isPlayed, String fromDate, String toDate, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<Game> listGames = new ArrayList<Game>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM FQ_GAMES WHERE parent_id = ? AND is_played = ? AND to_date_ >= to_date(? || ' 00:00:00', 'MM/DD/YYYY HH24:MI:SS')\n" +
                " AND to_date_ <= to_date(? || ' 23:59:59', 'MM/DD/YYYY HH24:MI:SS') AND service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, Integer.parseInt(parentId));
            ps.setInt(2, Integer.parseInt(isPlayed));
            ps.setString(3, fromDate);
            ps.setString(4, toDate);
            ps.setInt(5, Integer.parseInt(serviceId));
            rs = ps.executeQuery();
            while (rs.next()) {
                Game game = new Game();
                game.setId(rs.getString(Game.ID));
                game.setCode(rs.getString(Game.CODE));
                game.setContent(rs.getString(Game.CONTENT));
                game.setContentType(rs.getString(Game.CONTENT_TYPE));
                game.setCreatedDate(rs.getTimestamp(Game.CREATED_DATE).toString());
                game.setDescriptionGlobal(rs.getString(Game.DESCRIPTION_GLOBAL));
                game.setDescriptionLocal(rs.getString(Game.DESCRIPTION_LOCAL));
                game.setFromDate(rs.getTimestamp(Game.FROM_DATE).toString());
                game.setIcon(rs.getString(Game.ICON));
                game.setIntroductionGlobal(rs.getString(Game.INTRODUCTION_GLOBAL));
                game.setIntroductionLocal(rs.getString(Game.INTRODUCTION_LOCAL));
                game.setIsPlayed(rs.getString(Game.IS_PLAYED));
                game.setLevel(rs.getString(Game.LEVEL));
                game.setLogo(rs.getString(Game.LOGO));
                game.setNameGlobal(rs.getString(Game.NAME_GLOBAL));
                game.setNameLocal(rs.getString(Game.NAME_LOCAL));
                game.setParentId(rs.getString(Game.PARENT_ID));
                game.setServiceId(rs.getString(Game.SERVICE_ID));
                game.setStatus(rs.getString(Game.STATUS));
                game.setToDate(rs.getTimestamp(Game.TO_DATE).toString());
                game.setTypeOf(rs.getString(Game.TYPE_OF));
                game.setUpdateDate(rs.getTimestamp(Game.UPDATE_DATE).toString());
                listGames.add(game);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetMiniGames");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetMiniGames", startTime);
        }
        return listGames;
    }

    public List<MinigameReward> getMiniGameRewards(String minigameId, String serviceId) {
        List<MinigameReward> listRewards = new ArrayList<MinigameReward>();
        try {
            listRewards = iGetMiniGameRewards(minigameId, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getMiniGameRewards");
            logger.error(br, ex);
        }
        return listRewards;
    }

    private List<MinigameReward> iGetMiniGameRewards(String minigameId, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<MinigameReward> listRewards = new ArrayList<MinigameReward>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM minigame_reward WHERE minigame_id = ? AND service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, Integer.parseInt(minigameId));
            ps.setInt(2, Integer.parseInt(serviceId));
            rs = ps.executeQuery();
            while (rs.next()) {
                MinigameReward reward = new MinigameReward();
                reward.setId(rs.getInt(MinigameReward.ID));
                reward.setMinigameId(rs.getInt(MinigameReward.MINIGAME_ID));
                reward.setMsisdn(rs.getString(MinigameReward.MSISDN));
                reward.setCreatedDate(rs.getTimestamp(MinigameReward.CREATED_DATE));
                reward.setUpdateDate(rs.getTimestamp(MinigameReward.UPDATE_DATE));
                reward.setChannel(rs.getString(MinigameReward.CHANNEL));
                reward.setStatus(rs.getInt(MinigameReward.STATUS));
                reward.setServiceId(rs.getInt(MinigameReward.SERVICE_ID));
                listRewards.add(reward);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetMiniGameRewards");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetMiniGameRewards", startTime);
        }
        return listRewards;
    }

    public List<MinigameReward> getUserRewardByTime(String fromDate, String toDate, String serviceId) {
        List<MinigameReward> listRewards = new ArrayList<MinigameReward>();
        try {
            listRewards = iGetUserRewardByTime(fromDate, toDate, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getMiniGameRewards");
            logger.error(br, ex);
        }
        return listRewards;
    }

    private List<MinigameReward> iGetUserRewardByTime(String fromDate, String toDate, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<MinigameReward> listRewards = new ArrayList<MinigameReward>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM minigame_reward WHERE update_date >= to_date(? || ' 00:00:00', 'MM/DD/YYYY HH24:MI:SS')" +
                " AND update_date <= to_date(? || ' 23:59:59', 'MM/DD/YYYY HH24:MI:SS') AND service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, fromDate);
            ps.setString(2, toDate);
            ps.setInt(3, Integer.parseInt(serviceId));
            rs = ps.executeQuery();
            while (rs.next()) {
                MinigameReward reward = new MinigameReward();
                reward.setId(rs.getInt(MinigameReward.ID));
                reward.setMinigameId(rs.getInt(MinigameReward.MINIGAME_ID));
                reward.setMsisdn(rs.getString(MinigameReward.MSISDN));
                reward.setCreatedDate(rs.getTimestamp(MinigameReward.CREATED_DATE));
                reward.setUpdateDate(rs.getTimestamp(MinigameReward.UPDATE_DATE));
                reward.setChannel(rs.getString(MinigameReward.CHANNEL));
                reward.setStatus(rs.getInt(MinigameReward.STATUS));
                reward.setServiceId(rs.getInt(MinigameReward.SERVICE_ID));
                listRewards.add(reward);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetMiniGameRewards");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetMiniGameRewards", startTime);
        }
        return listRewards;
    }

    public MinigameReward getUserReward(String minigameId, String msisdn, String serviceId) {
        MinigameReward reward = null;
        try {
            reward = iGetUserReward(minigameId, msisdn, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getUserReward");
            logger.error(br, ex);
        }
        return reward;
    }

    private MinigameReward iGetUserReward(String minigameId, String msisdn, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        MinigameReward reward = null;
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM minigame_reward WHERE minigame_id = ? AND msisdn = ? AND service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, Integer.parseInt(minigameId));
            ps.setString(2, msisdn);
            ps.setInt(3, Integer.parseInt(serviceId));
            rs = ps.executeQuery();
            reward = new MinigameReward();
            while (rs.next()) {
                reward.setId(rs.getInt(MinigameReward.ID));
                reward.setMinigameId(rs.getInt(MinigameReward.MINIGAME_ID));
                reward.setMsisdn(rs.getString(MinigameReward.MSISDN));
                reward.setCreatedDate(rs.getTimestamp(MinigameReward.CREATED_DATE));
                reward.setUpdateDate(rs.getTimestamp(MinigameReward.UPDATE_DATE));
                reward.setChannel(rs.getString(MinigameReward.CHANNEL));
                reward.setStatus(rs.getInt(MinigameReward.STATUS));
                reward.setServiceId(rs.getInt(MinigameReward.SERVICE_ID));
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetUserReward");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetMiniGameRewards", startTime);
        }
        return reward;
    }

    public boolean insertMiniGameReward(String minigameId, String msisdn, String serviceId) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = iInsertMiniGameReward(minigameId, msisdn, serviceId);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR insertInviteHistory - ").append(count);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK insertMiniGameReward\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean iInsertMiniGameReward(String minigameId, String msisdn, String serviceId) throws Exception {
        long timeStart = System.currentTimeMillis();
        boolean rs = false;
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "INSERT INTO minigame_reward (id, msisdn, minigame_id, service_id) \n"
                + "VALUES(minigame_reward_seq.nextval, ?, ?, ?)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            ps.setInt(2, Integer.parseInt(minigameId));
            ps.setInt(3, Integer.parseInt(serviceId));
            ps.executeUpdate();
            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iInsertMiniGameReward", timeStart);
        }
        return rs;
    }

    public int insertTransLog1(TransactionLog log) throws SQLException {
        PreparedStatement ps = null;
        long startTime = System.currentTimeMillis();
        Connection connection = null;
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(SQL_TRANS_LOG);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            int i = 1;
            ps.setString(i++, log.getTransactionId());
            ps.setInt(i++, log.getType());
            ps.setString(i++, log.getMsisdn());
            ps.setString(i++, log.getRequest());
            ps.setString(i++, log.getResponse());
            ps.setString(i++, log.getErrorCode());
            ps.setString(i++, log.getCommand());
            ps.setTimestamp(i++, log.getRequestTime());
            ps.setTimestamp(i++, log.getResponseTime());
            ps.setString(i++, log.getChannel());

            return ps.executeUpdate();
        } catch (SQLException ex) {
            throw ex;
        } finally {
            closeStatement(ps);
            closeConnection(connection);
            logTime("Time to insert TRANSACTION_LOG", startTime);
        }
    }

    public String getConfiguration(String key, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        String value = null;
        long startTime = System.currentTimeMillis();

        String sql = "SELECT * FROM configuration where para_key = ? and service_id = ?";

        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            ps.setString(1, key);
            ps.setInt(2, Integer.parseInt(serviceId));
            rs = ps.executeQuery();

            while (rs.next()) {
                value = rs.getString("PARA_VALUE");
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR getConfiguration");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to getConfiguration", startTime);
        }
        return value;
    }

    public String getConfigurationByKey(String key) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        String value = null;
        long startTime = System.currentTimeMillis();

        String sql = "SELECT * FROM config where PARAM_NAME = ? and module = ?";

        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            ps.setString(1, key);
            ps.setString(2, "REPORT");
            rs = ps.executeQuery();

            while (rs.next()) {
                value = rs.getString("PARAM_VALUE");
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR getConfigurationByKey");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to getConfigurationByKey", startTime);
        }
        return value;
    }

    public ProductInfo iLoadPackageByName(String subServiceName) {
        ProductInfo product = null;
        long timeBegin = System.currentTimeMillis();
        while (product == null) {
            try {
                product = loadPackageByName(subServiceName);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR - iLoadPackage");
                logger.error(br, ex);
            }
        }
        return product;
    }

    private ProductInfo loadPackageByName(String subServiceName) throws SQLException {
        long timeStart = System.currentTimeMillis();
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;
        ProductInfo product = new ProductInfo();
        String sql = "SELECT * FROM PACKG where product_name = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, subServiceName);
            rs = ps.executeQuery();
            while (rs.next()) {
                product.setProductId(rs.getInt("PRODUCT_ID"));
                product.setFee(rs.getDouble("FEE"));
                product.setNumberSpin(rs.getInt("NUMBER_SPIN"));
                product.setProductName(rs.getString("PRODUCT_NAME"));
                product.setSmsSyntax(rs.getString("SMS_SYNTAX"));
                product.setBizId(rs.getInt("BIZ_ID"));
                product.setExpireDays(rs.getInt("EXPIRE_DAYS"));
                product.setRenew(rs.getInt("RENEW"));
            }
            logger.error("result: " + product);
        } catch (SQLException ex) {
            throw ex;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to loadPackageByName", timeStart);
        }
        return product;
    }

    public HashMap loadMpsConfig() {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        HashMap<String, MpsConfigObj> mMps = new HashMap();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM MPS_CONFIG";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            rs = ps.executeQuery();
            while (rs.next()) {
                MpsConfigObj mpsConfig = new MpsConfigObj();
                mpsConfig.setActionCode(rs.getString(MpsConfigObj.ACTION_CODE));
                mpsConfig.setCategory(rs.getString(MpsConfigObj.CATEGORY));
                mpsConfig.setCommand(rs.getString(MpsConfigObj.COMMAND));
                mpsConfig.setCpName(rs.getString(MpsConfigObj.CP_NAME));
                mpsConfig.setPrice(rs.getString(MpsConfigObj.PRICE));
                mpsConfig.setService(rs.getString(MpsConfigObj.SERVICE));
                mpsConfig.setSubService(rs.getString(MpsConfigObj.SUB_SERVICE));
                mpsConfig.setKeyPath(rs.getString(MpsConfigObj.KEY_PATH));
                mMps.put(mpsConfig.getActionCode(), mpsConfig);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR loadMpsConfig");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to load mps config", startTime);
        }
        return mMps;
    }


    // FOR ADMIN
    public Boolean checkAdminLogin(String user_admin, String pass_admin, String serviceId) {
        Boolean registered = null;
        try {
            registered = icheckAdminLogin(user_admin, pass_admin, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR checkAdminLogin");
            logger.error(br, ex);
        }

        return registered;
    }

    private Boolean icheckAdminLogin(String user_admin, String pass_admin, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM ACCOUNT_ADMIN WHERE user_admin = ? AND pass_admin = ? AND service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, user_admin);
            ps.setString(2, pass_admin);
            ps.setInt(3, Integer.parseInt(serviceId));
            rs = ps.executeQuery();
            if (rs.next()) {
                return true;
            }
            return false;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR icheckAdminLogin");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to icheckAdminLogin", startTime);
        }
    }

    public boolean insertNewGame(Game game) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = iInsertNewGame(game);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR insertNewGame - ").append(count);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK insertNewGame\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean iInsertNewGame(Game game) throws Exception {
        long timeStart = System.currentTimeMillis();
        boolean rs = false;
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "INSERT INTO fq_games (ID,PARENT_ID,SERVICE_ID,CODE,NAME_GLOBAL,NAME_LOCAL,DESCRIPTION_GLOBAL,DESCRIPTION_LOCAL,\n"
                + "INTRODUCTION_GLOBAL,INTRODUCTION_LOCAL,ICON,LOGO,CONTENT_,CONTENT_TYPE,UPDATE_DATE,LEVEL_,FROM_DATE,TO_DATE_,STATUS,IS_PLAYED,TYPE_OF,NOTE)\n"
                + " VALUES(games_seq.nextval, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, sysdate, ?, to_date(?, 'YYYY-MM-DD HH24:MI:SS'), to_date(?, 'YYYY-MM-DD HH24:MI:SS'), ?, ?, ?, ?)";
//        String sqlWeek = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
//                + "VALUES(ranking_seq.nextval, ?, ?, trunc(sysdate,'iw') + 7 - 1/86400, ?, sysdate, sysdate,?, ?, 1)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setLong(1, Long.parseLong(game.getParentId()));
            ps.setInt(2, Integer.parseInt(game.getServiceId()));
            ps.setString(3, game.getCode());
            ps.setString(4, game.getNameGlobal());
            ps.setString(5, game.getNameLocal());
            ps.setString(6, game.getDescriptionGlobal());
            ps.setString(7, game.getDescriptionLocal());
            ps.setString(8, game.getIntroductionGlobal());
            ps.setString(9, game.getIntroductionLocal());
            ps.setString(10, game.getIcon());
            ps.setString(11, game.getLogo());
            ps.setString(12, game.getContent());
            ps.setString(13, game.getContentType());
            ps.setInt(14, game.getLevel() != null ? Integer.parseInt(game.getLevel()) : 5);
            ps.setString(15, game.getFromDate());
            ps.setString(16, game.getToDate());
            ps.setInt(17, Integer.parseInt(game.getStatus()));
            ps.setInt(18, Integer.parseInt(game.getIsPlayed()));
            ps.setInt(19, Integer.parseInt(game.getTypeOf()));
            ps.setString(20, game.getNote());
            ps.executeUpdate();
            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps);
//            closeResource(ps2);
            closeResource(connection);
            logTime("Time to iInsertNewGame", timeStart);
        }
        return rs;
    }

    public boolean updateGame(Game game) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = iUpdateGame(game);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR insertNewGame - ").append(count);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK insertNewGame\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean iUpdateGame(Game game) throws Exception {
        long timeStart = System.currentTimeMillis();
        boolean rs = false;
        PreparedStatement ps = null;
        Connection connection = null;
//        2020-10-13 19:05:00
        String sql = "UPDATE fq_games SET CODE=?,NAME_GLOBAL=?,NAME_LOCAL=?,DESCRIPTION_GLOBAL=?,DESCRIPTION_LOCAL=?,INTRODUCTION_GLOBAL=?,INTRODUCTION_LOCAL=?,\n"
                + "ICON=?,LOGO=?,CONTENT_=?,CONTENT_TYPE=?,UPDATE_DATE=sysdate,FROM_DATE=to_date(?, 'YYYY-MM-DD HH24:MI:SS'),TO_DATE_=to_date(?, 'YYYY-MM-DD HH24:MI:SS'),STATUS=?,IS_PLAYED=?,TYPE_OF=?,NOTE=?\n"
                + " WHERE ID = ?";
//        String sqlWeek = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
//                + "VALUES(ranking_seq.nextval, ?, ?, trunc(sysdate,'iw') + 7 - 1/86400, ?, sysdate, sysdate,?, ?, 1)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, game.getCode());
            ps.setString(2, game.getNameGlobal());
            ps.setString(3, game.getNameLocal());
            ps.setString(4, game.getDescriptionGlobal());
            ps.setString(5, game.getDescriptionLocal());
            ps.setString(6, game.getIntroductionGlobal());
            ps.setString(7, game.getIntroductionLocal());
            ps.setString(8, game.getIcon());
            ps.setString(9, game.getLogo());
            ps.setString(10, game.getContent());
            ps.setString(11, game.getContentType());
            ps.setString(12, game.getFromDate());
            ps.setString(13, game.getToDate());
            ps.setInt(14, game.getStatus() != null ? Integer.parseInt(game.getStatus()) : 0);
            ps.setInt(15, game.getIsPlayed() != null ? Integer.parseInt(game.getIsPlayed()) : 0);
            ps.setInt(16, game.getIsPlayed() != null ? Integer.parseInt(game.getTypeOf()) : 0);
            ps.setString(17, game.getNote());
            ps.setInt(18, Integer.parseInt(game.getId()));
            ps.executeUpdate();
            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps);
//            closeResource(ps2);
            closeResource(connection);
            logTime("Time to iUpdateGame", timeStart);
        }
        return rs;
    }

    public boolean deleteGame(String id, String serviceId) {
        boolean result = false;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (result == false) {
            try {
                result = ideleteGame(id, serviceId);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR deleteGame - ").append(count);
                logger.error(br, ex);
                count++;
            }
            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).
                        append("==> BREAK deleteGame\n");
                logger.error(br);
                break;
            }
        }
        return result;
    }

    private boolean ideleteGame(String id, String serviceId) throws Exception {
        long timeStart = System.currentTimeMillis();
        boolean rs = false;
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "DELETE from fq_games WHERE ID = ? and service_id = ?";
//        String sqlWeek = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
//                + "VALUES(ranking_seq.nextval, ?, ?, trunc(sysdate,'iw') + 7 - 1/86400, ?, sysdate, sysdate,?, ?, 1)";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, Integer.parseInt(id));
            ps.setInt(2, Integer.parseInt(serviceId));
            ps.executeUpdate();
            rs = true;
        } catch (Exception ex) {
            throw ex;
        } finally {
            closeResource(ps);
//            closeResource(ps2);
            closeResource(connection);
            logTime("Time to deleteGame", timeStart);
        }
        return rs;
    }

    public Boolean updateConfiguration(String key, String value, String serviceId) {

        try {
            return iUpdateConfiguration(key, value, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR updateStatusReward");
            logger.error(br, ex);
        }

        return null;
    }

    private Boolean iUpdateConfiguration(String key, String value, String serviceId) {
        long timeStart = System.currentTimeMillis();
        PreparedStatement ps = null;
        Connection connection = null;
        String sql = "UPDATE configuration SET para_value = ? WHERE para_key = ? and service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, Integer.parseInt(value));
            ps.setString(2, key);
            ps.setInt(3, Integer.parseInt(serviceId));
            ps.executeUpdate();
            return true;
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iUpdateStatusReward");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iUpdateStatusReward", timeStart);
        }
    }

    public List<Configuration> getConfiguration(String serviceId) {
        List<Configuration> configurations = new ArrayList<Configuration>();
        try {
            configurations = iGetConfiguration(serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getConfiguration");
            logger.error(br, ex);
        }
        return configurations;
    }

    private List<Configuration> iGetConfiguration(String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<Configuration> configurations = new ArrayList<Configuration>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM configuration where service_id = ?";

        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, Integer.parseInt(serviceId));
            rs = ps.executeQuery();

            while (rs.next()) {
                Configuration configuration = new Configuration();
                configuration.setId(rs.getString("ID"));
                configuration.setPara_key(rs.getString("PARA_KEY"));
                configuration.setPara_value(rs.getString("PARA_VALUE"));
                configuration.setService_id(rs.getString("SERVICE_ID"));
                configurations.add(configuration);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetConfiguration");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetConfiguration", startTime);
        }
        return configurations;
    }

    public List<ChargeLog> getChargeLogAddMoneyHistory(Timestamp fromDate, Timestamp toDate) {
        List<ChargeLog> chargeLogs = new ArrayList<ChargeLog>();
        try {
            chargeLogs = iGetChargeLogAddMoneyHistory(fromDate, toDate);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getChargeLogAddMoneyHistory");
            logger.error(br, ex);
        }
        return chargeLogs;
    }

    private List<ChargeLog> iGetChargeLogAddMoneyHistory(Timestamp fromDate, Timestamp toDate) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<ChargeLog> chargeLogs = new ArrayList<ChargeLog>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM charge_log where charge_time >= ? and charge_time <= ? and fee < 0 and fee > -50";

        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setTimestamp(1, fromDate);
            ps.setTimestamp(2, toDate);
            rs = ps.executeQuery();

            while (rs.next()) {
                ChargeLog chargeLog = new ChargeLog();
                chargeLog.setFee(rs.getDouble("FEE"));
                chargeLogs.add(chargeLog);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetPlayedTimeHistory");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetChargeLogAddMoneyHistory", startTime);
        }
        return chargeLogs;
    }

    // FOR REPORTING
    public List<RegisterInfo> getNewRegisterByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        try {
            listReg = iGtNewRegisterByDay(fromDate, toDate, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getNewRegisterByDay");
            logger.error(br, ex);
        }

        return listReg;
    }

    private List<RegisterInfo> iGtNewRegisterByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM REG_INFO WHERE status = 1 AND renew = 1 and REGISTER_TIME >= ? " +
                "and REGISTER_TIME < ? and service_id = ? ";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setTimestamp(1, fromDate);
            ps.setTimestamp(2, toDate);
            ps.setInt(3, Integer.parseInt(serviceId));

            rs = ps.executeQuery();
            while (rs.next()) {
                RegisterInfo info = new RegisterInfo();
                info.setProductName(rs.getString("PRODUCT_NAME"));
                info.setStatus(rs.getInt("STATUS"));
                info.setLastExtend(rs.getTimestamp("LAST_EXTEND"));
                info.setEndTime(rs.getTimestamp("END_TIME"));
                info.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
                listReg.add(info);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGtNewRegisterByDay");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGtNewRegisterByDay", startTime);
        }
        return listReg;
    }

    public List<RegisterInfo> getReNewRegisterByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        try {
            listReg = iGetReNewRegisterByDay(fromDate, toDate, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getReNewRegisterByDay");
            logger.error(br, ex);
        }

        return listReg;
    }

    private List<RegisterInfo> iGetReNewRegisterByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM REG_INFO WHERE status = 1 and LAST_EXTEND >= ? " +
                "and LAST_EXTEND < ? and service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setTimestamp(1, fromDate);
            ps.setTimestamp(2, toDate);
            ps.setInt(3, Integer.parseInt(serviceId));

            rs = ps.executeQuery();
            while (rs.next()) {
                RegisterInfo info = new RegisterInfo();
                info.setProductName(rs.getString("PRODUCT_NAME"));
                info.setStatus(rs.getInt("STATUS"));
                info.setLastExtend(rs.getTimestamp("LAST_EXTEND"));
                info.setEndTime(rs.getTimestamp("END_TIME"));
                info.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
                listReg.add(info);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetReNewRegisterByDay");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetReNewRegisterByDay", startTime);
        }
        return listReg;
    }

    public List<RegisterInfo> getBuyMoreByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        try {
            listReg = iGetBuyMoreByDay(fromDate, toDate, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getBuyMoreByDay");
            logger.error(br, ex);
        }

        return listReg;
    }

    private List<RegisterInfo> iGetBuyMoreByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM REG_INFO WHERE renew = 0 AND status = 1 and REGISTER_TIME >= ? " +
                "and REGISTER_TIME < ?  and service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setTimestamp(1, fromDate);
            ps.setTimestamp(2, toDate);
            ps.setInt(3, Integer.parseInt(serviceId));

            rs = ps.executeQuery();
            while (rs.next()) {
                RegisterInfo info = new RegisterInfo();
                info.setProductName(rs.getString("PRODUCT_NAME"));
                info.setStatus(rs.getInt("STATUS"));
                info.setLastExtend(rs.getTimestamp("LAST_EXTEND"));
                info.setEndTime(rs.getTimestamp("END_TIME"));
                info.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
                listReg.add(info);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetBuyMoreByDay");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetBuyMoreByDay", startTime);
        }
        return listReg;
    }

    public List<RegisterInfo> getCancelRegisterByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        try {
            listReg = iGetCancelRegisterByDay(fromDate, toDate, serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getCancelRegisterByDay");
            logger.error(br, ex);
        }

        return listReg;
    }

    private List<RegisterInfo> iGetCancelRegisterByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM REG_INFO WHERE status = 0 and END_TIME >= ? " +
                "and END_TIME < ? and service_id = ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setTimestamp(1, fromDate);
            ps.setTimestamp(2, toDate);
            ps.setInt(3, Integer.parseInt(serviceId));

            rs = ps.executeQuery();
            while (rs.next()) {
                RegisterInfo info = new RegisterInfo();
                info.setProductName(rs.getString("PRODUCT_NAME"));
                info.setStatus(rs.getInt("STATUS"));
                info.setLastExtend(rs.getTimestamp("LAST_EXTEND"));
                info.setEndTime(rs.getTimestamp("END_TIME"));
                info.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
                listReg.add(info);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetCancelRegisterByDay");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetCancelRegisterByDay", startTime);
        }
        return listReg;
    }

    public List<ChargeLog> getChargeLogByDay(Timestamp fromDate, Timestamp toDate) {
        List<ChargeLog> listReg = new ArrayList<ChargeLog>();
        try {
            listReg = iGetChargeLogByDay(fromDate, toDate);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getDailyRewardByDay");
            logger.error(br, ex);
        }

        return listReg;
    }

    private List<ChargeLog> iGetChargeLogByDay(Timestamp fromDate, Timestamp toDate) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        List<ChargeLog> listReg = new ArrayList<ChargeLog>();
        long startTime = System.currentTimeMillis();
        String sql = "SELECT * FROM CHARGE_LOG WHERE CHARGE_TIME >= ? " +
                "and CHARGE_TIME < ?";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setTimestamp(1, fromDate);
            ps.setTimestamp(2, toDate);

            rs = ps.executeQuery();
            while (rs.next()) {
                ChargeLog info = new ChargeLog();
                info.setFee(rs.getDouble("FEE"));
                info.setChargeTime(rs.getTimestamp("CHARGE_TIME"));
                listReg.add(info);
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetDailyRewardByDay");
            logger.error(br, ex);
            return null;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetDailyRewardByDay", startTime);
        }
        return listReg;
    }
    public int getTotalSub(String serviceId) {
        int listReg = 0;
        try {
            listReg = iGetTotalSub(serviceId);
        } catch (Exception ex) {
            br.append(loggerLabel).append(new Date()).append("\nERROR getTotalSub");
            logger.error(br, ex);
        }
        return listReg;
    }

    private int iGetTotalSub(String serviceId) {
        int total = 0;

        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;
        long startTime = System.currentTimeMillis();
        String sql = "SELECT COUNT(*) FROM REG_INFO WHERE service_id = ? AND status = 1 AND renew = 1 and EXPIRE_TIME > sysdate";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setInt(1, Integer.parseInt(serviceId));

            rs = ps.executeQuery();
            if (rs.next()) {
                total = rs.getInt("COUNT(*)");
            }
        } catch (Exception ex) {
            br.setLength(0);
            br.append(loggerLabel).
                    append(new Date()).
                    append("\nERROR iGetTotalSub");
            logger.error(br, ex);
            return total;
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to iGetTotalSub", startTime);
        }
        return total;
    }
    
    public SpinResultObj countLuckySpin(String msisdn) {
        PreparedStatement ps = null;
        long timeStart = System.currentTimeMillis();
        ResultSet rs = null;
        Connection connection = null;
        String sql = "select nvl(sum(added - used),0) remain_spin, nvl(sum(added),0) total_spin,  nvl(sum(used),0) used_spin  from lucky_spin \n"
                + "where msisdn = ? and expire_time > sysdate";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            rs = ps.executeQuery();
            SpinResultObj result = new SpinResultObj();
            while (rs.next()) {
                result.setRemainSpin(rs.getInt("remain_spin"));
                result.setTotalSpin(rs.getInt("total_spin"));
                result.setUsedSpin(rs.getInt("used_spin"));
                return result;
            }
        } catch (Exception ex) {
            logger.error("Error countLuckySpin", ex);
        } finally {
            closeResultSet(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to countLuckySpin", timeStart);
        }
        return null;
    }
    public SpinResultObj doSpin(String msisdn) {
        long timeStart = System.currentTimeMillis();
        CallableStatement cs = null;
        ResultSet rs = null;
        Connection connection = null;
        String sql = "{call update_lucky_spin ( ?, ? )}";
        try {
            connection = getConnection(dbName);
            cs = connection.prepareCall(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                cs.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            cs.setString(1, msisdn);
            cs.registerOutParameter(2, OracleTypes.CURSOR);
            cs.executeUpdate();
            rs = (ResultSet) cs.getObject(2);
            SpinResultObj result = new SpinResultObj();
            while (rs.next()) {
                result.setLuckySpinId(rs.getLong("id"));
                result.setPrizeId(rs.getInt("prize_id"));
                result.setRemainSpin(rs.getInt("remain_spin"));
                result.setTotalSpin(rs.getInt("total_spin"));
                result.setUsedSpin(rs.getInt("used_spin"));
                result.setTotalCoin(rs.getInt("total_coin"));
                return result;
            }
        } catch (Exception ex) {
            logger.error("Error call update_lucky_spin", ex);
        } finally {
            closeResource(rs);
            closeResource(cs);
            closeResource(connection);
            logTime("Time to call update_lucky_spin", timeStart);
        }
        return null;
    }
    public SpinResultObj doSpinT(String msisdn,int prizeId, String partner_tran_id) {
        long timeStart = System.currentTimeMillis();
        CallableStatement cs = null;
        ResultSet rs = null;
        Connection connection = null;
        String sql = "{call update_lucky_spin_tool ( ?, ?,?,? )}";
        try {
            connection = getConnection(dbName);
            cs = connection.prepareCall(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                cs.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            cs.setString(1, msisdn);
            cs.setInt(2, prizeId);
            cs.setString(3, partner_tran_id);
            cs.registerOutParameter(4, OracleTypes.CURSOR);
            cs.executeUpdate();
            rs = (ResultSet) cs.getObject(4);
            SpinResultObj result = new SpinResultObj();
            while (rs.next()) {
                result.setLuckySpinId(rs.getLong("id"));
                result.setPrizeId(rs.getInt("prize_id"));
                result.setRemainSpin(rs.getInt("remain_spin"));
                result.setTotalSpin(rs.getInt("total_spin"));
                result.setUsedSpin(rs.getInt("used_spin"));
                result.setTotalCoin(rs.getInt("total_coin"));
                result.setPrizeWinnerId(rs.getInt("prize_winner_id"));
                return result;
            }
        } catch (Exception ex) {
            logger.error("Error call update_lucky_spin", ex);
        } finally {
            closeResource(rs);
            closeResource(cs);
            closeResource(connection);
            logTime("Time to call update_lucky_spin", timeStart);
        }
        return null;
    }
    
    public SpinResultObj doSpinSubmitPrize(String msisdn,int prizeId, int PrizeWinnerID, String transId) {
        long timeStart = System.currentTimeMillis();
        CallableStatement cs = null;
        ResultSet rs = null;
        Connection connection = null;
        String sql = "{call add_prize_submit ( ?, ?,?,?,? )}";
        try {
            connection = getConnection(dbName);
            cs = connection.prepareCall(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                cs.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            cs.setString(1, msisdn);
            cs.setInt(2, prizeId);
            cs.setInt(3, PrizeWinnerID);
            cs.setString(4, transId);
            cs.registerOutParameter(5, OracleTypes.CURSOR);
            cs.executeUpdate();
            rs = (ResultSet) cs.getObject(5);
            SpinResultObj result = new SpinResultObj();
            while (rs.next()) {
                result.setLuckySpinId(rs.getLong("id"));
                result.setPrizeId(rs.getInt("prize_id"));
                result.setRemainSpin(rs.getInt("remain_spin"));
                result.setTotalSpin(rs.getInt("total_spin"));
                result.setUsedSpin(rs.getInt("used_spin"));
                result.setTotalCoin(rs.getInt("total_coin"));
                result.setPrizeWinnerId(rs.getInt("prize_winner_id"));
                return result;
            }
        } catch (Exception ex) {
            logger.error("Error call update_lucky_spin", ex);
        } finally {
            closeResource(rs);
            closeResource(cs);
            closeResource(connection);
            logTime("Time to call update_lucky_spin", timeStart);
        }
        return null;
    }
    public List<PrizeWinner> getListWinner(String msisdn, int period, int page, int pageSize, int isTop, int codeType, String startDate, String endDate) throws SQLException {
    ResultSet rs = null;
    PreparedStatement ps = null;
    List<PrizeWinner> result = new ArrayList<>();
    long startTime = System.currentTimeMillis();
    Connection connection = null;

    StringBuilder sql = new StringBuilder();
    sql.append("SELECT * FROM (SELECT ROWNUM rn, a.* FROM (")
       .append("SELECT pw.*, lp.description, lp.prize_name,lp.IS_TOP ")
       .append("FROM prize_winner pw ")
       .append("LEFT JOIN list_prize lp ON pw.prize_id = lp.id ")
       .append("WHERE 1=1 ");

    List<Object> params = new ArrayList<>();

    if (period > 0) {
        sql.append("AND pw.period = ? ");
        params.add(period);
    }
    if (msisdn != null && !msisdn.trim().isEmpty()) {
        sql.append("AND pw.msisdn = ? ");
        params.add(msisdn);
    }
    if (isTop > 0) {
        sql.append("AND lp.is_top = ? ");
        params.add(isTop);
    }
    if (startDate != null && endDate != null) {
        sql.append("AND CODE_TIME >= to_date(?,'yyyy-MM-dd HH24:mi:ss') AND CODE_TIME <= to_date(?,'yyyy-MM-dd HH24:mi:ss') ");
        params.add(startDate);
        params.add(endDate);
    }

    sql.append("ORDER BY pw.code_time DESC) a) ")
       .append("WHERE rn > ").append((page - 1) * pageSize)
       .append(" AND rn <= ").append(page * pageSize);

    try {
        connection = getConnection(dbName);
        ps = connection.prepareStatement(sql.toString());
        if (WebserviceManager.queryDbTimeout > 0) {
            ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
        }

        // Set parameters
        for (int i = 0; i < params.size(); i++) {
            ps.setObject(i + 1, params.get(i));
        }

        // Logging SQL with params
        String loggedSql = sql.toString();
        for (Object param : params) {
            String value = (param instanceof String || param instanceof Timestamp)
                ? "'" + param.toString() + "'" : String.valueOf(param);
            loggedSql = loggedSql.replaceFirst("\\?", value);
        }
        logger.info("Executing SQL: " + loggedSql);

        rs = ps.executeQuery();

        while (rs.next()) {
            PrizeWinner pw = new PrizeWinner();
            pw.setId(rs.getInt("ID"));
            pw.setMsisdn(rs.getString("MSISDN"));
            pw.setCode(rs.getString("CODE"));
            pw.setCodeTime(fullDf.format(rs.getTimestamp("CODE_TIME")));
            Timestamp processTime = rs.getTimestamp("PROCESS_TIME");
            pw.setProcessTime(processTime == null ? "" : fullDf.format(processTime));
            pw.setPrizeDescription(rs.getString("DESCRIPTION"));
            pw.setPrizeName(rs.getString("PRIZE_NAME"));
            pw.setPeriod(rs.getInt("PERIOD"));
            pw.setTop(rs.getInt("IS_TOP"));
            pw.setPage(page);
            result.add(pw);
        }

        return result;
    } catch (SQLException ex) {
        logger.error("Error while fetching prize winners", ex);
        throw ex; // rethrow để cho phép controller hoặc caller xử lý tiếp
    } finally {
        closeResource(rs);
        closeResource(ps);
        closeResource(connection);
        logTime("Time to execute getListWinner", startTime);
    }
}

    
//    public List<PrizeWinner> getListWinner(String msisdn, int period, int page, int pageSize, int isTop, int codeType,Timestamp startDate,Timestamp endDate) throws SQLException {
//        ResultSet rs = null;
//        PreparedStatement ps = null;
//        List<PrizeWinner> result = null;
//        long startTime = System.currentTimeMillis();
//        Connection connection = null;
//        String sql = "select * from (select rownum rn,  a.* from \n"
//                + "(select  pw.*,  lp.description, lp.prize_name "
//                + "from prize_winner pw \n"
//                + "left join list_prize lp on pw.prize_id = lp.id "
//                + "where 1=1  ";
//        if (period == 1) {
//            sql += " and CODE_TIME >= trunc(sysdate)-15 ";
//        } else if (period == 2) {
//            sql += " and CODE_TIME >= trunc(sysdate)-30 ";
//        }
//        if (period > 0) {
//            sql += " and pw.period = ? \n";
//        }
//        if (msisdn != null && !msisdn.isEmpty()) {
//            sql += " and pw.msisdn = ? ";
//        }
//        if (isTop >= 0) {
//            sql += " and lp.is_top = ? ";
//        }
//        if (startDate != null && endDate != null) {
//                sql += " and CODE_TIME >= ? and CODE_TIME <= ? ";
//        }
////        sql += " and pw.code_type = ? ";
//        sql += "order by code_time desc) a )\n"
//                + "where rn > " + (page - 1) + " * " + pageSize + " and rn <= " + page + " * " + pageSize;
//        try {
//            connection = getConnection(dbName);
//            ps = connection.prepareStatement(sql);
//            if (WebserviceManager.queryDbTimeout > 0) {
//                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
//            }
//            int i = 0;
//            if (period > 0) {
//                ps.setInt(++i, period);
//            }
//            if (msisdn != null && !msisdn.isEmpty()) {
//                ps.setString(++i, msisdn);
//            }
//            if (isTop >= 0) {
//                ps.setInt(++i, isTop);
//            }
//            if (startDate != null && endDate != null) {
//                ps.setTimestamp(++i, startDate);
//                ps.setTimestamp(++i, endDate);
//            }
////            ps.setInt(++i, codeType);
//            rs = ps.executeQuery();
//            result = new ArrayList();
//            while (rs.next()) {
//                PrizeWinner lc = new PrizeWinner();
//                lc.setId(rs.getInt("ID"));
//                lc.setMsisdn(rs.getString("MSISDN"));
//                lc.setCode(rs.getString("CODE"));
//                lc.setCodeTime(fullDf.format(rs.getTimestamp("CODE_TIME")));
//                lc.setProcessTime(rs.getTimestamp("PROCESS_TIME") == null ? "" : fullDf.format(rs.getTimestamp("PROCESS_TIME")));
//                lc.setPrizeDescription(rs.getString("DESCRIPTION"));
//                lc.setPrizeName(rs.getString("PRIZE_NAME"));
////                lc.setChannel(rs.getString("CHANNEL"));
//                lc.setPeriod(rs.getInt("PERIOD"));
////                lc.setCodeType(rs.getInt("CODE_TYPE"));
//                lc.setPage(page);
//                result.add(lc);
//            }
//            return result;
//        } catch (SQLException ex) {
//            logger.error("Error get list winner", ex);
//        } finally {
//            closeResource(rs);
//            closeResource(ps);
//            closeResource(connection);
//            logTime("Time to getListWinner", startTime);
//        }
//        return null;
//    }

    public int getCountWinner(String msisdn, int period, int isTop, int codeType,String startDate,String endDate) throws SQLException {
        ResultSet rs = null;
        PreparedStatement ps = null;
//        List<PrizeWinner> result = null;
        long startTime = System.currentTimeMillis();
        Connection connection = null;
        String sql = "select count(*) counter from \n"
                + "(select rownum, pw.*,   lp.description from prize_winner pw \n"
                + "left join list_prize lp on pw.prize_id = lp.id "
                //                + "left join group_prize g on lp.sub_group_prize = g.sub_group_id "
                + "where 1=1 ";
        if (period > 0) {
            sql += " and pw.period = ? \n";
        }
        if (msisdn != null && !msisdn.isEmpty()) {
            sql += " and pw.msisdn = ? ";
        }
        if (isTop >= 0) {
            sql += " and lp.is_top = ? ";
        }
        sql += "order by code_time desc) \n";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.queryDbTimeout > 0) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            int i = 0;
            if (period > 0) {
                ps.setInt(++i, period);
            }
            if (msisdn != null && !msisdn.isEmpty()) {
                ps.setString(++i, msisdn);
            }
            if (isTop >= 0) {
                ps.setInt(++i, isTop);
            }
            rs = ps.executeQuery();
            while (rs.next()) {
                return rs.getInt("COUNTER");
            }
        } catch (SQLException ex) {
            logger.error("Error count winner", ex);
        } finally {
            closeResource(rs);
            closeResource(ps);
            closeResource(connection);
            logTime("Time to getCountWinner", startTime);
        }
        return 0;
    }
    
    
    public String addTurnSpin(String msisdn, int turn) {
        long timeStart = System.currentTimeMillis();
        CallableStatement cs = null;
        ResultSet rs = null;
        Connection connection = null;
        String sql = "{call ADD_COIN ( ?, ? )}";
        try {
            connection = getConnection(dbName);
            cs = connection.prepareCall(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                cs.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }

            cs.setString(1, msisdn);
            cs.setInt(2, turn);
            cs.executeUpdate();
        } catch (Exception ex) {
            logger.error("Error call ADD_COIN", ex);
        } finally {
            closeResource(rs);
            closeResource(cs);
            closeResource(connection);
            logTime("Time to call ADD_COIN", timeStart);
        }
        return null;
    }
    
    
    public LuckySprin igetLuckySprin(String msisdn) {
        LuckySprin mSprin = null;
        long timeBegin = System.currentTimeMillis();
        int count = 1;
        while (mSprin == null) {
            try {
                mSprin = getLuckySprin(msisdn);
            } catch (Exception ex) {
                br.setLength(0);
                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
                logger.error(br, ex);
                count++;
            }
            if (mSprin == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
                br.setLength(0);
                br.append(loggerLabel).append(new Date()).append("==>BREAK query select VTFREE_USER\n");
                logger.error(br);
                break;
            }
        }
        return mSprin;
    }

    /**
     * Lay thong tin luot choi
     *
     * @param userName
     * @return
     * @throws SQLException
     */
    private LuckySprin getLuckySprin(String msisdn) throws SQLException {
        ResultSet rs = null;
        PreparedStatement ps = null;
        LuckySprin mSprin = null;
        long timeStart = System.currentTimeMillis();
        Connection connection = null;
        String sql = "SELECT ID,MSISDN,ADDED,USED FROM lucky_spin where MSISDN = ? ";
        try {
            connection = getConnection(dbName);
            ps = connection.prepareStatement(sql);
            if (WebserviceManager.enableQueryDbTimeout) {
                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
            }
            ps.setString(1, msisdn);
            rs = ps.executeQuery();
            mSprin = new LuckySprin();

            if (rs.next()) {
                logger.info("result: " + rs);
                mSprin.setUsed(rs.getInt("USED"));
                mSprin.setAdded(rs.getInt("ADDED"));
                mSprin.setMsisdn(rs.getString("MSISDN"));
                mSprin.setId(rs.getInt("ID"));
            }
            logger.info("mSprin: " + mSprin);
            return mSprin;
        } catch (SQLException ex) {
            throw ex;
        } finally {
            closeResultSet(rs);
            closeStatement(ps, sqlGetUser);
            closeConnection(connection);
            logTime("Time to getUserInfo", timeStart);
        }
    }

    
}
