package com.fp.general.security.rules;

import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fp.base.persistence.util.helper.GeneralDescriptions;
import com.fp.bpm.query.Query;
import com.fp.common.helper.CalculationBase;
import com.fp.dto.data.SaveData;
import com.fp.dto.query.QueryRequest;
import com.fp.dto.rules.QueryRule;
import com.fp.general.db.DataHelper;
import com.fp.general.exception.GeneralException;
import com.fp.persistence.commondb.NestedSave;
import com.fp.persistence.commondb.PersistenceHelper;
import com.fp.persistence.commondb.helper.APPDates;
import com.fp.persistence.commondb.helper.FormatDates;
import com.fp.persistence.pcustomer.gene.TcustPersonDetail;
import com.fp.persistence.pgeneral.date.TgeneAccountingDateBranch;
import com.fp.persistence.pgeneral.gene.TgeneArea;
import com.fp.persistence.pgeneral.gene.TgeneAreaKey;
import com.fp.persistence.pgeneral.gene.TgeneBranch;
import com.fp.persistence.pgeneral.gene.TgeneCatalogDetail;
import com.fp.persistence.pgeneral.gene.TgeneCatalogDetailKey;
import com.fp.persistence.pgeneral.gene.TgeneChannels;
import com.fp.persistence.pgeneral.gene.TgeneCity;
import com.fp.persistence.pgeneral.gene.TgeneCityKey;
import com.fp.persistence.pgeneral.gene.TgeneCompany;
import com.fp.persistence.pgeneral.gene.TgeneCountry;
import com.fp.persistence.pgeneral.gene.TgeneLabel;
import com.fp.persistence.pgeneral.gene.TgeneOffice;
import com.fp.persistence.pgeneral.gene.TgeneOfficeKey;
import com.fp.persistence.pgeneral.gene.TgeneProvince;
import com.fp.persistence.pgeneral.gene.TgeneProvinceKey;
import com.fp.persistence.pgeneral.safe.TsafeJavaScript;
import com.fp.persistence.pgeneral.safe.TsafePassword;
import com.fp.persistence.pgeneral.safe.TsafePasswordKey;
import com.fp.persistence.pgeneral.safe.TsafeProfile;
import com.fp.persistence.pgeneral.safe.TsafeTerminal;
import com.fp.persistence.pgeneral.safe.TsafeTerminalKey;
import com.fp.persistence.pgeneral.safe.TsafeUserDetail;
import com.fp.persistence.pgeneral.safe.TsafeUserProfile;
import com.fp.persistence.pgeneral.safe.TsafeUserSession;
import com.fp.persistence.pgeneral.safe.TsafeUserSessionKey;
import com.fp.persistence.pgeneral.safe.TsafeUserSessionLog;
import com.fp.persistence.pgeneral.safe.TsafeUserSessionLogKey;
import com.fp.sessionbeans.helper.Sequence;

/**
 * Clase que se encargara del ingreso a la aplicacion
 * 
 * @author scastillo
 * @version 2.1
 */
public class UserLogonCas extends QueryRule {

    private static final long serialVersionUID = 1L;

    private static SimpleDateFormat simpleDateFormatCreateTime = new SimpleDateFormat("HH:mm:ss");

    private TsafePassword tsafePassword;

    private boolean isjsf;

    /**
     * Metodo que ejecuta el proceso
     * 
     * @param pQueryRequest
     * @throws Exception
     */
    @Override
    public QueryRequest process(QueryRequest pQueryRequest) throws Exception {
        this.isjsf = pQueryRequest.isJsf();
        TsafeUserDetail userdetail = this.getTsafeUserDetail(pQueryRequest);

        String terminal = (String) pQueryRequest.get("ip");
        String host = (String) pQueryRequest.get("host");
        String jsessionid = (String) pQueryRequest.get("jsessionid");
        String usercode = (String) pQueryRequest.get("login");
        if (userdetail == null) {
            this.writeLog(pQueryRequest, usercode, terminal, jsessionid, host, "GENE-0011", "USUARIO NO EXISTE");
            throw new GeneralException("GENE-0011", "USUARIO NO EXISTE");
        }
        if (userdetail.getUserstatuscatalog().compareTo("ACT") != 0) {
            TgeneCatalogDetailKey tgeneCatalogDetailKey = new TgeneCatalogDetailKey(userdetail.getUserstatuscatalog(),
                    userdetail.getUserstatuscatalogcode());
            TgeneCatalogDetail tgeneCatalogDetail = TgeneCatalogDetail.find(PersistenceHelper.getEntityManager(), tgeneCatalogDetailKey);
            this.writeLog(pQueryRequest, userdetail, "GENE-0010", "EL USUARIO " + userdetail.getPk().getUsercode() + " SE ENCUENTRA "
                    + tgeneCatalogDetail.getDescription());
            throw new GeneralException("GENE-0010", "EL USUARIO {0} SE ENCUENTRA {1}", userdetail.getPk().getUsercode(),
                    tgeneCatalogDetail.getDescription());
        }
        TsafeTerminal tsafeTerminal = null;
        // userdetail.getTerminalcode()
        if ((userdetail.getBranchfromterminal() != null) && (userdetail.getBranchfromterminal().compareTo("Y") == 0)
                && (userdetail.getTerminalcode() != null)) {
            TsafeTerminalKey tsafeTerminalKey = new TsafeTerminalKey(userdetail.getTerminalcode(), userdetail.getCompanycode());
            TsafeTerminal tsafeTerminalAux = TsafeTerminal.find(PersistenceHelper.getEntityManager(), tsafeTerminalKey);
            if (tsafeTerminalAux == null) {
                this.writeLog(pQueryRequest, userdetail, "CORE-0002", "TERMINAL " + terminal + " NO DEFINIDO EN TSAFETERMINAL");
                throw new GeneralException("CORE-0002", "TERMINAL {0} NO DEFINIDO EN TSAFETERMINAL", terminal);
            } else {
                tsafeTerminal = tsafeTerminalAux;
                terminal = tsafeTerminalAux.getIpaddress();
            }
        }
        if (tsafeTerminal == null) {
            tsafeTerminal = TsafeTerminal.find(PersistenceHelper.getEntityManager(), userdetail.getCompanycode(), terminal);
        }
        if ((userdetail.getBranchfromterminal() != null) && (userdetail.getBranchfromterminal().compareTo("Y") == 0)) {
            if (tsafeTerminal == null) {
                this.writeLog(pQueryRequest, userdetail, "CORE-0002", "TERMINAL " + terminal + " NO DEFINIDO EN TSAFETERMINAL");
                throw new GeneralException("CORE-0002", "TERMINAL {0} NO DEFINIDO EN TSAFETERMINAL", terminal);
            } else if ((tsafeTerminal != null) && (userdetail.getTerminalcode() != null)) {
                TsafeTerminalKey tsafeTerminalKey = new TsafeTerminalKey(userdetail.getTerminalcode(), userdetail.getCompanycode());
                TsafeTerminal tsafeTerminalaux = TsafeTerminal.find(PersistenceHelper.getEntityManager(), tsafeTerminalKey);
                if ((tsafeTerminalaux != null) && (tsafeTerminalaux.getIpaddress() != null)
                        && (tsafeTerminalaux.getIpaddress().compareTo(terminal) != 0)) {
                    this.writeLog(pQueryRequest, userdetail, "CORE-0056", "LA IP " + terminal + " NO SE ENCUENTRA AUTORIZADA PARA EL USUARIO "
                            + userdetail.getPk().getUsercode());
                    throw new GeneralException("CORE-0056", "LA IP {0} NO SE ENCUENTRA AUTORIZADA PARA EL USUARIO {1}", terminal, userdetail.getPk()
                            .getUsercode());
                }
            }
            if (userdetail.getBranchcode().compareTo(tsafeTerminal.getBranchcode()) != 0) {
                throw new GeneralException("CORE-0064", "EL TERMINAL {0} ASOCIADO AL USUARIO SE ENCUENTRA EN OTRA SUCURSAL {1}");
            }
            if (userdetail.getOfficecode().compareTo(tsafeTerminal.getOfficecode()) != 0) {
                throw new GeneralException("CORE-0065", "EL TERMINAL {0} ASOCIADO AL USUARIO SE ENCUENTRA EN OTRA OFICINA {1}");
            }
            if (userdetail.getAreacode().compareTo(tsafeTerminal.getAreacode()) != 0) {
                throw new GeneralException("CORE-0066", "EL TERMINAL {0} ASOCIADO AL USUARIO SE ENCUENTRA EN OTRA ÁREA {1}");
            }
        }
        if ((tsafeTerminal != null) && (tsafeTerminal.getSliptprinter() != null)) {
            userdetail.addAddtionalInfo("spn", tsafeTerminal.getSliptprinter());
        } else {
            userdetail.addAddtionalInfo("spn", null);
        }
        TsafePasswordKey key = new TsafePasswordKey(pQueryRequest.getCompany(), userdetail.getChannelcode());
        this.tsafePassword = TsafePassword.find(PersistenceHelper.getEntityManager(), key);

        this.completeLocation(userdetail);
        this.completeAreaName(userdetail);
        this.completeCompanyName(userdetail);
        this.completeChannelName(userdetail);
        this.completeBranchName(userdetail, pQueryRequest, terminal);
        this.completeOfficeName(userdetail);
        this.completeProfile(userdetail);
        this.completeDates(userdetail);
        if (!pQueryRequest.isJsf()) {
            this.completeJavaScript(userdetail);
            this.completeInternazionalization(userdetail);
        }
        //datos de usuario de la sbs
        TcustPersonDetail tcp = TcustPersonDetail.find(PersistenceHelper.getEntityManager(), userdetail.getPk().getPersoncode());
        userdetail.addAddtionalInfo("sbsemployee", tcp.getSbsemployee());
        userdetail.addAddtionalInfo("sbsusercode", tcp.getSbsusercode());
        // this.createSession(userdetail, pQueryRequest, terminal, jsessionid, host);
        return pQueryRequest;
    }

    private TsafeUserDetail getTsafeUserDetail(QueryRequest pQueryRequest) throws Exception {
        TsafeUserDetail userdetail = null;
        if (!pQueryRequest.isJsf()) {
            Query qry = new Query();
            PersistenceHelper.getEntityManager().clear();
            qry.process(pQueryRequest);
            userdetail = (TsafeUserDetail) pQueryRequest.getResponse().get("TSAFEUSERDETAIL");
        } else {
            userdetail = TsafeUserDetail.find(PersistenceHelper.getEntityManager(), pQueryRequest.get("login").toString());
            pQueryRequest.getResponse().put("TSAFEUSERDETAIL", userdetail);
        }
        return userdetail;
    }

    /**
     * Metodo que agrega el nombre de la sucursal y la ip del cleinte en el detail
     * 
     * @param pUserdetail
     * @param pQueryRequest
     * @param terminal
     * @throws Exception
     */
    private void completeBranchName(TsafeUserDetail pUserdetail, QueryRequest pQueryRequest, String terminal) throws Exception {
        TgeneBranch branch = DataHelper.getInstance().getTgeneBranch(pUserdetail.getBranchcode(), pUserdetail.getCompanycode());
        pUserdetail.addAddtionalInfo("bn", branch.getDescription());
        pUserdetail.addAddtionalInfo("ip", terminal);
    }

    /**
     * Metodo que agrega la descripción del area del usuario
     * 
     * @param pUserdetail
     * @throws Exception
     */
    private void completeAreaName(TsafeUserDetail pUserdetail) throws Exception {
        TgeneAreaKey tgeneAreaKey = new TgeneAreaKey(pUserdetail.getCompanycode(), pUserdetail.getAreacode());
        TgeneArea tgeneArea = (TgeneArea) PersistenceHelper.getSession().get(TgeneArea.class, tgeneAreaKey);
        pUserdetail.addAddtionalInfo("an", tgeneArea.getDescripction());
    }

    /**
     * Metodo que agrega el nombre de la compania
     * 
     * @param pUserdetail
     * @throws Exception
     */
    private void completeCompanyName(TsafeUserDetail pUserdetail) throws Exception {
        TgeneCompany tgeneCompany = (TgeneCompany) PersistenceHelper.getSession().get(TgeneCompany.class, pUserdetail.getCompanycode());
        pUserdetail.addAddtionalInfo("cn", GeneralDescriptions.getPersonname(tgeneCompany.getPersoncode()));
    }

    /**
     * Metodo que agrega la descripcion del canal del usuario
     * 
     * @param pUserdetail
     * @throws Exception
     */
    private void completeChannelName(TsafeUserDetail pUserdetail) throws Exception {
        TgeneChannels tgeneChannels = (TgeneChannels) PersistenceHelper.getSession().get(TgeneChannels.class, pUserdetail.getChannelcode());
        pUserdetail.addAddtionalInfo("chn", tgeneChannels.getDescription());
    }

    /**
     * Metodo que agrega la oficina en el detail
     * 
     * @param pUserdetail
     * @throws Exception
     */
    private void completeOfficeName(TsafeUserDetail pUserdetail) throws Exception {
        TgeneOfficeKey tgeneOfficeKey = new TgeneOfficeKey(pUserdetail.getOfficecode(), pUserdetail.getBranchcode(), pUserdetail.getCompanycode());
        TgeneOffice office = TgeneOffice.find(PersistenceHelper.getEntityManager(), tgeneOfficeKey);
        pUserdetail.addAddtionalInfo("on", office.getDescription());
    }

    /**
     * Metodo que completa la fecha contable y de trabajao
     * 
     * @param pUserdetail
     * @throws Exception
     */
    private void completeDates(TsafeUserDetail pUserdetail) throws Exception {
        TgeneAccountingDateBranch tgeneAccountingDateBranch = com.fp.persistence.commondb.db.DataHelper.getInstance().getTgeneAccountingDateBranch(
                pUserdetail.getCompanycode(), 0);
        String hour = UserLogonCas.simpleDateFormatCreateTime.format(FormatDates.getInstance().getDataBaseTimestamp());
        pUserdetail.addAddtionalInfo("wt", hour);
        if (tgeneAccountingDateBranch == null) {
            pUserdetail.addAddtionalInfo("ad", null);
            pUserdetail.addAddtionalInfo("wd", null);
        } else {
            pUserdetail.addAddtionalInfo("ad", tgeneAccountingDateBranch.getAccountingdate());
            pUserdetail.addAddtionalInfo("wd", tgeneAccountingDateBranch.getWorkingdate());
        }
    }

    /**
     * Metodo para completar datos de ubicacion del usuario
     * 
     * @param pUserdetail
     * @throws Exception
     */
    private void completeLocation(TsafeUserDetail pUserdetail) throws Exception {
        if ((pUserdetail.getBranchcode() != null) && (pUserdetail.getCompanycode() != null) && (pUserdetail.getOfficecode() != null)) {
            TgeneOfficeKey tgeneOfficeKey = new TgeneOfficeKey(pUserdetail.getOfficecode(), pUserdetail.getBranchcode(), pUserdetail.getCompanycode());
            TgeneOffice tgeneOffice = TgeneOffice.find(PersistenceHelper.getEntityManager(), tgeneOfficeKey);
            pUserdetail.addAddtionalInfo("address", tgeneOffice.getAddress());
            pUserdetail.addAddtionalInfo("citycode", tgeneOffice.getCitycode());
            if (tgeneOffice.getCountrycode() != null) {

                TgeneCountry tgeneCountry = TgeneCountry.find(PersistenceHelper.getEntityManager(), tgeneOffice.getCountrycode());
                pUserdetail.addAddtionalInfo("countrycode", tgeneCountry.getPk());
                pUserdetail.addAddtionalInfo("countryname", tgeneCountry.getDescription());
            } else {
                pUserdetail.addAddtionalInfo("countrycode", null);
                pUserdetail.addAddtionalInfo("countryname", null);
            }
            if ((tgeneOffice.getCountrycode() != null) && (tgeneOffice.getProvincecode() != null)) {
                TgeneProvinceKey tgeneProvinceKey = new TgeneProvinceKey(tgeneOffice.getCountrycode(), tgeneOffice.getProvincecode());
                TgeneProvince tgeneProvince = TgeneProvince.find(PersistenceHelper.getEntityManager(), tgeneProvinceKey);
                pUserdetail.addAddtionalInfo("provincecode", tgeneProvince.getPk().getProvincecode());
                pUserdetail.addAddtionalInfo("provincename", tgeneProvince.getDescription());
            } else {
                pUserdetail.addAddtionalInfo("provincecode", null);
                pUserdetail.addAddtionalInfo("provincename", null);
            }
            if ((tgeneOffice.getCountrycode() != null) && (tgeneOffice.getProvincecode() != null) && (tgeneOffice.getCantoncode() != null)
                    && (tgeneOffice.getCitycode() != null)) {
                TgeneCityKey tgeneCityKey = new TgeneCityKey(tgeneOffice.getCountrycode(), tgeneOffice.getProvincecode(),
                        tgeneOffice.getCantoncode(), tgeneOffice.getCitycode());
                TgeneCity tgeneCity = TgeneCity.find(PersistenceHelper.getEntityManager(), tgeneCityKey);
                pUserdetail.addAddtionalInfo("cityname", tgeneCity.getDescription());
            } else {
                pUserdetail.addAddtionalInfo("cityname", null);
            }
            pUserdetail.addAddtionalInfo("username", GeneralDescriptions.getUsername(pUserdetail.getPk().getUsercode()));
        } else {
            pUserdetail.addAddtionalInfo("address", null);
            pUserdetail.addAddtionalInfo("citycode", null);
            pUserdetail.addAddtionalInfo("cityname", null);
            pUserdetail.addAddtionalInfo("countrycode", null);
            pUserdetail.addAddtionalInfo("countryname", null);
            pUserdetail.addAddtionalInfo("provincecode", null);
            pUserdetail.addAddtionalInfo("provincename", null);
            pUserdetail.addAddtionalInfo("username", null);
        }
    }

    /**
     * Metodo que completa el perfile del usuario
     * 
     * @param pUserdetail
     * @throws Exception
     */
    private void completeProfile(TsafeUserDetail pUserdetail) throws Exception {
        List<TsafeUserProfile> profile = DataHelper.getInstance().getTsafeUserProfile(pUserdetail.getPk().getUsercode());
        if (this.isjsf) {
            pUserdetail.addAddtionalInfo("lprofile", profile);
            for (TsafeUserProfile tsafeUserProfile : profile) {
                TsafeProfile tsafeProfile = TsafeProfile.find(PersistenceHelper.getEntityManager(), tsafeUserProfile.getPk().getProfilecode());
                tsafeUserProfile.addAddtionalInfo("nprofile", tsafeProfile.getDescription());
            }
            return;
        }
        String profileData = "";
        String profileDataDesc = "";

        for (int i = 0; i < profile.size(); i++) {
            if (i > 0) {
                profileData += ".";
                profileDataDesc += ".";
            }
            profileData += profile.get(i).getPk().getProfilecode();
            TsafeProfile tsafeProfile = TsafeProfile.find(PersistenceHelper.getEntityManager(), profile.get(i).getPk().getProfilecode());
            profileDataDesc += tsafeProfile.getDescription();
        }
        pUserdetail.addAddtionalInfo("profile", profileData);
        pUserdetail.addAddtionalInfo("profiledesc", profileDataDesc);
    }

    /**
     * Metodo que verifica si el password ingresado es correcto
     * 
     * @param pUserdetail
     * @param pQueryRequest
     * @throws Exception
     */
    private boolean validatePassword(TsafeUserDetail pUserdetail, QueryRequest pQueryRequest, String terminal, String jsessionid, String host)
            throws Exception {
        String passwd = (String) pQueryRequest.get("itemValue");
        // Valida que el password no este expirado
        this.validateExpiration(pUserdetail, pQueryRequest);
        if (passwd.compareTo(pUserdetail.getPassword()) != 0) {
            boolean maxintentos = this.increaseTryNumber(pUserdetail, pQueryRequest, terminal, jsessionid, host);
            if (maxintentos) {
                return false;
            }
            this.writeLog(pQueryRequest, pUserdetail, "GENE-0003", "USUARIO O PASSWORD INCORRECTO");
            pQueryRequest.getResponse().setResponseCode("GENE-0003");
            pQueryRequest.getResponse().setResponseUserMessage("USUARIO O PASSWORD INCORRECTO");
            return false;
        }
        return true;
    }

    /**
     * Metodo que verifica si el password ingresado es correcto
     * 
     * @param pUserdetail
     * @param pQueryRequest
     * @throws Exception
     */
    private void validateExpiration(TsafeUserDetail pUserdetail, QueryRequest pQueryRequest) throws Exception {
        // Valida que el password no este expirado
        if ((this.tsafePassword.getValiditydays() != null) && (this.tsafePassword.getValiditydays() > 0)) {
            APPDates appd = new APPDates(pUserdetail.getDatefrom().toString().substring(0, 10), CalculationBase.B365365);
            TgeneAccountingDateBranch db = com.fp.persistence.commondb.db.DataHelper.getInstance().getTgeneAccountingDateBranch(
                    pQueryRequest.getCompany(), 0);
            APPDates appd1 = new APPDates(db.getWorkingdate(), CalculationBase.B365365);
            if (appd1.compareTo(appd) >= 0) {
                Integer days = appd1.substract(appd);
                if (days.compareTo(this.tsafePassword.getValiditydays()) > 0) {
                    throw new GeneralException("GENE-0023", "CONTRASEÑA EXPIRADA");
                }
                days = days + this.tsafePassword.getMessagedays();
                if (days.compareTo(this.tsafePassword.getValiditydays()) >= 0) {
                    days = days - this.tsafePassword.getMessagedays();
                    days = this.tsafePassword.getValiditydays() - days;
                    pUserdetail.addAddtionalInfo("dpwd", days);
                }
            }
        }
    }

    /**
     * Metodo que completa la internacionalizacion dentro de la aplicacion
     * 
     * @param pUserdetail
     * @throws Exception
     */
    private void completeInternazionalization(TsafeUserDetail pUserdetail) throws Exception {
        List<TgeneLabel> lTgeneLabel = TgeneLabel.getTgeneLabel(PersistenceHelper.getEntityManager(), pUserdetail.getLanguagecode(),
                pUserdetail.getChannelcode());
        Map<String, String> map = new HashMap<String, String>();
        for (int i = 0; i < lTgeneLabel.size(); i++) {
            TgeneLabel tgeneLabel = lTgeneLabel.get(i);
            map.put(tgeneLabel.getPk().getLabel(), tgeneLabel.getDescription());
        }
        pUserdetail.put("i18n", map);
    }

    /**
     * Metodo que completa los javascript
     * 
     * @param pUserdetail
     * @throws Exception
     */
    private void completeJavaScript(TsafeUserDetail pUserdetail) throws Exception {
        List<String> tsafeJavaScript = TsafeJavaScript.find(PersistenceHelper.getEntityManager(), pUserdetail.getCompanycode(),
                pUserdetail.getChannelcode());
        pUserdetail.put("js", tsafeJavaScript);
    }

    /**
     * Metodo que crea la sesion cuando no existe una
     * 
     * @param pUserdetail
     * @param pQueryRequest
     * @param terminal
     * @param jsessionid
     * @param host
     * @throws Exception
     */
    private void createSession(TsafeUserDetail pUserdetail, QueryRequest pQueryRequest, String terminal, String jsessionid, String host)
            throws Exception {
        TsafeUserSessionKey tsafeUserSessionKey = new TsafeUserSessionKey(pUserdetail.getPk().getUsercode(), FormatDates.getDefaultExpiryTimestamp());
        TsafeUserSession tsafeUserSession = TsafeUserSession.find(PersistenceHelper.getEntityManager(), tsafeUserSessionKey);
        PersistenceHelper.detatch(tsafeUserSession);
        if (tsafeUserSession == null) {
            tsafeUserSession = new TsafeUserSession();
            tsafeUserSession.setDatefrom(FormatDates.getInstance().getDataBaseTimestamp());
            tsafeUserSession.setPk(tsafeUserSessionKey);
            tsafeUserSession.setTrynumber(1);
            tsafeUserSession.setSessionid(jsessionid);
            tsafeUserSession.setTerminalcode(terminal);
            tsafeUserSession.setWebserverip(host);
            this.saveObject(tsafeUserSession);
        } else {
            if (tsafeUserSession.getTerminalcode().compareTo(terminal) == 0) {
                tsafeUserSession.setDatefrom(FormatDates.getInstance().getDataBaseTimestamp());
                this.saveObject(tsafeUserSession);
            } else {
                this.writeLog(pQueryRequest, pUserdetail, "GENE-0009", "EL USUARIO " + pUserdetail.getPk().getUsercode()
                        + " SE ENCUENTRA TRABAJANDO EN EL TERMINAL " + tsafeUserSession.getTerminalcode());
                throw new GeneralException("GENE-0009", "EL USUARIO {0} SE ENCUENTRA TRABAJANDO EN EL TERMINAL {1}", pUserdetail.getPk()
                        .getUsercode(), tsafeUserSession.getTerminalcode());
            }
        }
    }

    /**
     * Metodo que incrementa el numero de intentos
     * 
     * @param pUserdetail
     * @param pQueryRequest
     * @param terminal
     * @param jsessionid
     * @param host
     * @return
     * @throws Exception
     */
    private boolean increaseTryNumber(TsafeUserDetail pUserdetail, QueryRequest pQueryRequest, String terminal, String jsessionid, String host)
            throws Exception {
        TsafeUserSessionKey tsafeUserSessionKey = new TsafeUserSessionKey(pUserdetail.getPk().getUsercode(), FormatDates.getDefaultExpiryTimestamp());
        TsafeUserSession tsafeUserSession = TsafeUserSession.find(PersistenceHelper.getEntityManager(), tsafeUserSessionKey);
        if (tsafeUserSession != null) {
            TsafeUserSession tsafeUserSessionAux = (TsafeUserSession) tsafeUserSession.cloneMe();
            tsafeUserSessionAux.getPk().setDateto(FormatDates.getInstance().getDataBaseTimestamp());
            this.saveObject(tsafeUserSessionAux);
            tsafeUserSession.setTrynumber(tsafeUserSession.getTrynumber() + 1);
            this.saveObject(tsafeUserSession);

            if ((this.tsafePassword.getIntentnumber() != null) && (tsafeUserSession.getTrynumber() >= this.tsafePassword.getIntentnumber())) {
                pUserdetail.setUserstatuscatalog("BLQ");
                this.saveObject(pUserdetail);
                pQueryRequest.getResponse().setResponseCode("GENE-0007");
                pQueryRequest.getResponse().setResponseUserMessage(
                        MessageFormat.format("EL USUARIO {0} HA SIDO BLOQUEADO POR INGRESO DE CLAVE ERRONEA", pUserdetail.getPk().getUsercode()));
                return true;
            }
        } else {
            this.createSession(pUserdetail, pQueryRequest, terminal, jsessionid, host);
        }
        return false;
    }

    /**
     * Método que guarda los datos en la tabla
     * 
     * @param object
     * @throws Exception
     */
    private void saveObject(Object object) throws Exception {
        PersistenceHelper.getEntityManager().merge(object);
    }

    /**
     * 
     * @param pQueryRequest
     * @param usercode
     * @param terminal
     * @param jsessionid
     * @param host
     * @param errorCode
     * @param messageError
     * @throws Exception
     */
    private void writeLog(QueryRequest pQueryRequest, String usercode, String terminal, String jsessionid, String host, String errorCode,
            String messageError) throws Exception {
        TgeneAccountingDateBranch tgeneAccountingDateBranch = com.fp.persistence.commondb.db.DataHelper.getInstance().getTgeneAccountingDateBranch(
                pQueryRequest.getCompany(), 0);
        TsafeUserSessionLogKey tsafeUserSessionLogKey = new TsafeUserSessionLogKey(tgeneAccountingDateBranch.getAccountingdate(),
                this.getSequenceLoginLog(), pQueryRequest.getCompany());
        TsafeUserSessionLog tsafeUserSessionLog = new TsafeUserSessionLog(tsafeUserSessionLogKey, usercode, terminal, jsessionid, host, FormatDates
                .getInstance().getDataBaseTimestamp(PersistenceHelper.getEntityManager()), errorCode, messageError);
        NestedSave nestedSave = new NestedSave(pQueryRequest.getCompany(), tsafeUserSessionLog);
        nestedSave.start();
    }

    /**
     * 
     * @param pQueryRequest
     * @param tsafeUserDetail
     * @param errorCode
     * @param messageError
     * @throws Exception
     */
    private void writeLog(QueryRequest pQueryRequest, TsafeUserDetail tsafeUserDetail, String errorCode, String messageError) throws Exception {
        TgeneAccountingDateBranch tgeneAccountingDateBranch = com.fp.persistence.commondb.db.DataHelper.getInstance().getTgeneAccountingDateBranch(
                pQueryRequest.getCompany(), 0);
        String terminal = (String) pQueryRequest.get("ip");
        String host = (String) pQueryRequest.get("host");
        String jsessionid = (String) pQueryRequest.get("jsessionid");
        TsafeUserSessionLogKey tsafeUserSessionLogKey = new TsafeUserSessionLogKey(tgeneAccountingDateBranch.getAccountingdate(),
                this.getSequenceLoginLog(), pQueryRequest.getCompany());
        TsafeUserSessionLog tsafeUserSessionLog = new TsafeUserSessionLog(tsafeUserSessionLogKey, tsafeUserDetail.getPk().getUsercode(), terminal,
                jsessionid, host, FormatDates.getInstance().getDataBaseTimestamp(PersistenceHelper.getEntityManager()), errorCode, messageError);
        tsafeUserSessionLog.setBranchcode(tsafeUserDetail.getBranchcode());
        tsafeUserSessionLog.setOfficecode(tsafeUserDetail.getOfficecode());
        NestedSave nestedSave = new NestedSave(pQueryRequest.getCompany(), tsafeUserSessionLog);
        nestedSave.start();
    }

    /**
     * Metodo que entrega la secuencia para gurdar los logs
     * 
     * @return
     * @throws Exception
     */
    private Integer getSequenceLoginLog() throws Exception {
        Sequence sequence = new Sequence();
        Integer loginsequnce = Integer.valueOf(sequence.getNextValue("LOGINLOG").toString());
        SaveData.getMap().put("LOGINLOG", loginsequnce.toString());
        return loginsequnce;
    }
}
