package com.fp.persistence.pgeneral.receive.acco;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.fp.common.helper.Constant;
import com.fp.dto.hb.HibernateBean;

/** Clase que implementa la entidad de Hibernate que hace referencia a la tabla TRECEIVABLEACCOUNTDEMANDEPO */
@Entity(name = "TreceivableAccountDemanDepo")
@Table(name = "TRECEIVABLEACCOUNTDEMANDEPO")
public class TreceivableAccountDemanDepo extends com.fp.dto.AbstractDataBalanceTransport implements Serializable, HibernateBean, Cloneable {
    /**
     * HashCode asociado con la Instancia
     */
    @Transient
    private int hashValue = 0;

    /**
     * Version de la Clase
     */
    private static final long serialVersionUID = 1L;

    /**
     * Clave primaria de la Entidad TreceivableAccountDemanDepo
     */
    @EmbeddedId
    private TreceivableAccountDemanDepoKey pk;

    @Column(name = "DATEFROM", nullable = false)
    /**
     * Fecha desde la cual esta vigente el registro de la cuenta por cobrar
     */
    private Timestamp datefrom;

    @Column(name = "ACCOUNTINGDATE", nullable = true)
    /**
     * Fecha contable con la que se crea la cuenta por cobrar
     */
    private Date accountingdate;

    @Column(name = "CURRENCYCODE", nullable = true)
    /**
     * Codigo de moneda
     */
    private String currencycode;

    @Column(name = "BALANCETYPE", nullable = true)
    /**
     * Código de tipo de saldo de registro de la CXC. Efectivo, Bloqueado , Pignorado, Retenciones Locales, remesas ..Etc
     */
    private String balancetype;

    @Column(name = "BALANCEGROUP", nullable = true)
    /**
     * Codigo del grupo de balance 1 Activo, 2 Pasivo, 3 Patrimonio .. 62 contingente deudor 61 por contra deudor 
     */
    private String balancegroup;

    @Column(name = "RECOVERBALANCETYPE", nullable = true)
    /**
     * Código de tipo de saldo de cobro de la CXC. Efectivo, Bloqueado , Pignorado, Retenciones Locales, remesas ..Etc
     */
    private String recoverbalancetype;

    @Column(name = "RECOVERBALANCEGROUP", nullable = true)
    /**
     * Codigo del grupo de balance 1 Activo, 2 Pasivo, 3 Patrimonio .. 62 contingente deudor 61 por contra deudor 
     */
    private String recoverbalancegroup;

    @Column(name = "PRIORITY", nullable = true)
    /**
     * Prioridad de cobro de la cuenta por cobrar dentro en el dia
     */
    private Integer priority;

    @Column(name = "ISPARTIAL", nullable = true)
    /**
     * Indica si la cuenta por cobrar permite cobros parciales
     */
    private String ispartial;

    @Column(name = "MINIMUMPAYMENT", nullable = true)
    /**
     * Si permite cobros parciales, Valor minimo de cobro
     */
    private BigDecimal minimumpayment;

    @Column(name = "EXPIREDATE", nullable = true)
    /**
     * Fecha de vencimiento de la cuenta por cobrar.
     */
    private Date expiredate;

    @Column(name = "MESSAGE", nullable = true)
    /**
     * Numero de mensaje con el cual se realizo la ultima transacción en la cuenta.
     */
    private String message;

    @Column(name = "ORIGINALMESSAGE", nullable = true)
    /**
     * Numero de mensaje con el cual se creo la cuenta por cobrar.
     */
    private String originalmessage;

    @Column(name = "REVERSEMESSAGE", nullable = true)
    /**
     * Numero de mensaje de reverso de la cuenta por cobrar.
     */
    private String reversemessage;

    @Column(name = "REVERSE", nullable = true)
    /**
     * Indica si la cuenta por cobrar esta reversada.
     */
    private String reverse;

    @Column(name = "ORIGINALAMOUNT", nullable = true)
    /**
     * Monto original
     */
    private BigDecimal originalamount;

    @Column(name = "PENDINGAMOUNT", nullable = true)
    /**
     * Monto pendiente de pago
     */
    private BigDecimal pendingamount;

    @Column(name = "LASTPAYAMOUNT", nullable = true)
    /**
     * Ultimo monto pagado
     */
    private BigDecimal lastpayamount;

    @Column(name = "LASTPAY", nullable = true)
    /**
     * Fecha de ultimo pago
     */
    private Date lastpay;

    @Column(name = "DESCRIPTION", nullable = true)
    /**
     * Glosa de la cuenta por cobrar.
     */
    private String description;

    /** Contructor por defecto */
    public TreceivableAccountDemanDepo() {
    }

    /**
     * Contructor de TreceivableAccountDemanDepo
     * 
     * @param pPk Clave Primaria del entity
     * @param pDatefrom Fecha desde la cual esta vigente el registro de la cuenta por cobrar
     */
    public TreceivableAccountDemanDepo(TreceivableAccountDemanDepoKey pPk, Timestamp pDatefrom) {
        this();
        pk = pPk;
        datefrom = pDatefrom;
    }

    /**
     * Metodo que entrega datos de la tabla dada la clave primaria.
     * 
     * @param pEntityManager referencia de la session a obtener datos del bean.
     * @param pKey Caleve primaria del bean.
     * @return TreceivableAccountDemanDepo
     */
    public static TreceivableAccountDemanDepo find(EntityManager pEntityManager, TreceivableAccountDemanDepoKey pKey) throws Exception {
        TreceivableAccountDemanDepo obj = pEntityManager.find(TreceivableAccountDemanDepo.class, pKey);
        return obj;
    }

    /**
     * Entrega la Clave primaria de TreceivableAccountDemanDepo
     * 
     * @return El objeto que referencia a la Clave primaria de TreceivableAccountDemanDepo
     */
    public TreceivableAccountDemanDepoKey getPk() {
        return pk;
    }

    /**
     * Fija un nuevo valor a la Clave primaria de TreceivableAccountDemanDepo
     * 
     * @param pPk El objeto que referencia a la nueva Clave primaria de TreceivableAccountDemanDepo
     */
    public void setPk(TreceivableAccountDemanDepoKey pPk) {
        pk = pPk;
    }

    /**
     * Obtiene el valor de datefrom
     * 
     * @return valor de datefrom
     */
    public Timestamp getDatefrom() {
        return datefrom;
    }

    /**
     * Fija el valor de datefrom
     * 
     * @param pDatefrom nuevo Valor de datefrom
     */
    public void setDatefrom(Timestamp pDatefrom) {
        datefrom = pDatefrom;
    }

    /**
     * Obtiene el valor de accountingdate
     * 
     * @return valor de accountingdate
     */
    public Date getAccountingdate() {
        return accountingdate;
    }

    /**
     * Fija el valor de accountingdate
     * 
     * @param pAccountingdate nuevo Valor de accountingdate
     */
    public void setAccountingdate(Date pAccountingdate) {
        accountingdate = pAccountingdate;
    }

    /**
     * Obtiene el valor de currencycode
     * 
     * @return valor de currencycode
     */
    public String getCurrencycode() {
        return currencycode;
    }

    /**
     * Fija el valor de currencycode
     * 
     * @param pCurrencycode nuevo Valor de currencycode
     */
    public void setCurrencycode(String pCurrencycode) {
        currencycode = pCurrencycode;
    }

    /**
     * Obtiene el valor de balancetype
     * 
     * @return valor de balancetype
     */
    public String getBalancetype() {
        return balancetype;
    }

    /**
     * Fija el valor de balancetype
     * 
     * @param pBalancetype nuevo Valor de balancetype
     */
    public void setBalancetype(String pBalancetype) {
        balancetype = pBalancetype;
    }

    /**
     * Obtiene el valor de balancegroup
     * 
     * @return valor de balancegroup
     */
    public String getBalancegroup() {
        return balancegroup;
    }

    /**
     * Fija el valor de balancegroup
     * 
     * @param pBalancegroup nuevo Valor de balancegroup
     */
    public void setBalancegroup(String pBalancegroup) {
        balancegroup = pBalancegroup;
    }

    /**
     * Obtiene el valor de recoverbalancetype
     * 
     * @return valor de recoverbalancetype
     */
    public String getRecoverbalancetype() {
        return recoverbalancetype;
    }

    /**
     * Fija el valor de recoverbalancetype
     * 
     * @param pRecoverbalancetype nuevo Valor de recoverbalancetype
     */
    public void setRecoverbalancetype(String pRecoverbalancetype) {
        recoverbalancetype = pRecoverbalancetype;
    }

    /**
     * Obtiene el valor de recoverbalancegroup
     * 
     * @return valor de recoverbalancegroup
     */
    public String getRecoverbalancegroup() {
        return recoverbalancegroup;
    }

    /**
     * Fija el valor de recoverbalancegroup
     * 
     * @param pRecoverbalancegroup nuevo Valor de recoverbalancegroup
     */
    public void setRecoverbalancegroup(String pRecoverbalancegroup) {
        recoverbalancegroup = pRecoverbalancegroup;
    }

    /**
     * Obtiene el valor de priority
     * 
     * @return valor de priority
     */
    public Integer getPriority() {
        return priority;
    }

    /**
     * Fija el valor de priority
     * 
     * @param pPriority nuevo Valor de priority
     */
    public void setPriority(Integer pPriority) {
        priority = pPriority;
    }

    /**
     * Obtiene el valor de ispartial
     * 
     * @return valor de ispartial
     */
    public String getIspartial() {
        return ispartial;
    }

    /**
     * Fija el valor de ispartial
     * 
     * @param pIspartial nuevo Valor de ispartial
     */
    public void setIspartial(String pIspartial) {
        ispartial = pIspartial;
    }

    /**
     * Obtiene el valor de minimumpayment
     * 
     * @return valor de minimumpayment
     */
    public BigDecimal getMinimumpayment() {
        return minimumpayment;
    }

    /**
     * Fija el valor de minimumpayment
     * 
     * @param pMinimumpayment nuevo Valor de minimumpayment
     */
    public void setMinimumpayment(BigDecimal pMinimumpayment) {
        minimumpayment = pMinimumpayment;
    }

    /**
     * Obtiene el valor de expiredate
     * 
     * @return valor de expiredate
     */
    public Date getExpiredate() {
        return expiredate;
    }

    /**
     * Fija el valor de expiredate
     * 
     * @param pExpiredate nuevo Valor de expiredate
     */
    public void setExpiredate(Date pExpiredate) {
        expiredate = pExpiredate;
    }

    /**
     * Obtiene el valor de message
     * 
     * @return valor de message
     */
    public String getMessage() {
        return message;
    }

    /**
     * Fija el valor de message
     * 
     * @param pMessage nuevo Valor de message
     */
    public void setMessage(String pMessage) {
        message = pMessage;
    }

    /**
     * Obtiene el valor de originalmessage
     * 
     * @return valor de originalmessage
     */
    public String getOriginalmessage() {
        return originalmessage;
    }

    /**
     * Fija el valor de originalmessage
     * 
     * @param pOriginalmessage nuevo Valor de originalmessage
     */
    public void setOriginalmessage(String pOriginalmessage) {
        originalmessage = pOriginalmessage;
    }

    /**
     * Obtiene el valor de reversemessage
     * 
     * @return valor de reversemessage
     */
    public String getReversemessage() {
        return reversemessage;
    }

    /**
     * Fija el valor de reversemessage
     * 
     * @param pReversemessage nuevo Valor de reversemessage
     */
    public void setReversemessage(String pReversemessage) {
        reversemessage = pReversemessage;
    }

    /**
     * Obtiene el valor de reverse
     * 
     * @return valor de reverse
     */
    public String getReverse() {
        return reverse;
    }

    /**
     * Fija el valor de reverse
     * 
     * @param pReverse nuevo Valor de reverse
     */
    public void setReverse(String pReverse) {
        reverse = pReverse;
    }

    /**
     * Obtiene el valor de originalamount
     * 
     * @return valor de originalamount
     */
    public BigDecimal getOriginalamount() {
        return originalamount;
    }

    /**
     * Fija el valor de originalamount
     * 
     * @param pOriginalamount nuevo Valor de originalamount
     */
    public void setOriginalamount(BigDecimal pOriginalamount) {
        originalamount = pOriginalamount;
    }

    /**
     * Obtiene el valor de pendingamount
     * 
     * @return valor de pendingamount
     */
    public BigDecimal getPendingamount() {
        return pendingamount;
    }

    /**
     * Fija el valor de pendingamount
     * 
     * @param pPendingamount nuevo Valor de pendingamount
     */
    public void setPendingamount(BigDecimal pPendingamount) {
        pendingamount = pPendingamount;
    }

    /**
     * Obtiene el valor de lastpayamount
     * 
     * @return valor de lastpayamount
     */
    public BigDecimal getLastpayamount() {
        return lastpayamount;
    }

    /**
     * Fija el valor de lastpayamount
     * 
     * @param pLastpayamount nuevo Valor de lastpayamount
     */
    public void setLastpayamount(BigDecimal pLastpayamount) {
        lastpayamount = pLastpayamount;
    }

    /**
     * Obtiene el valor de lastpay
     * 
     * @return valor de lastpay
     */
    public Date getLastpay() {
        return lastpay;
    }

    /**
     * Fija el valor de lastpay
     * 
     * @param pLastpay nuevo Valor de lastpay
     */
    public void setLastpay(Date pLastpay) {
        lastpay = pLastpay;
    }

    /**
     * Obtiene el valor de description
     * 
     * @return valor de description
     */
    public String getDescription() {
        return description;
    }

    /**
     * Fija el valor de description
     * 
     * @param pDescription nuevo Valor de description
     */
    public void setDescription(String pDescription) {
        description = pDescription;
    }

    public boolean equals(Object rhs) {
        if (rhs == null)
            return false;
        if (!(rhs instanceof TreceivableAccountDemanDepo))
            return false;
        TreceivableAccountDemanDepo that = (TreceivableAccountDemanDepo) rhs;
        if (this.getPk() == null || that.getPk() == null)
            return false;
        return (this.getPk().equals(that.getPk()));
    }

    /**
     * Implementación del metodo hashCode de la la entidad TreceivableAccountDemanDepo
     * 
     * @return el hashCode la instancia
     */
    public int hashCode() {
        if (this.hashValue == 0) {
            int result = 17;
            if (this.getPk() == null) {
                result = super.hashCode();
            } else {
                result = this.getPk().hashCode();
            }
            this.hashValue = result;
        }
        return this.hashValue;
    }

    /** Implementación toString */
    public String toString() {
        Field[] fs = this.getClass().getDeclaredFields();
        String data = "";
        for (Field f : fs) {
            try {
                String name = f.getName();
                if (f.getType().getName().compareTo("java.util.Set") == 0)
                    continue;
                if (name.compareTo("hashValue") == 0 || name.compareTo("serialVersionUID") == 0)
                    continue;
                data += name + "=" + f.get(this) + ";";
            } catch (Exception e) {
                continue;
            }
        }
        if (data.compareTo("") == 0) {
            data = super.toString();
        }
        return data;
    }

    /** Implementación de la creación de un bean en blanco TreceivableAccountDemanDepo */
    public Object createInstance() {
        TreceivableAccountDemanDepo instance = new TreceivableAccountDemanDepo();
        instance.setPk(new TreceivableAccountDemanDepoKey());
        return instance;
    }

    /**
     * Clona la entidad TreceivableAccountDemanDepo
     * 
     * @see com.fp.dto.hb.HibernateBean#cloneMe()
     */
    public Object cloneMe() throws CloneNotSupportedException {
        TreceivableAccountDemanDepo p = (TreceivableAccountDemanDepo) this.clone();
        p.setPk((TreceivableAccountDemanDepoKey) this.pk.cloneMe());
        return p;
    }

    public Object getId() {
        return this.pk;
    }
    
    //Metodos manuales.
    
    /**Sentencia que obtiene una lista de TreceivableAccount dado un numero de mensaje. */
    private static final String HQL_MSG = "from TreceivableAccountDemanDepo t " +
            " where t.message = :message" ;
   
    /**
     * Entrega una lista de TreceivableAccount dado un numeor de mensaje.
     * @param pEntityManager  Referencia a la session de base de datos.
     * @param pMessage  Numero de mensaje a buscar registros de TreceivableAccount
     * @return  List<TreceivableAccount>
     */
    @SuppressWarnings("unchecked")
    public static List<TreceivableAccountDemanDepo> findByMessage(EntityManager pEntityManager,String pMessage) {
        List<TreceivableAccountDemanDepo> ldata = null;
        Query qry = pEntityManager.createQuery(HQL_MSG);
        qry.setParameter("message", pMessage);
        ldata = qry.getResultList();
        return ldata;
    }
   
   
    /**Sentencia que obtiene una lista de TreceivableAccount dado un numero de mensaje orgiginal. */
    private static final String HQL_ORIMSG = "from TreceivableAccountDemanDepo t " +
            " where t.originalmessage = :originalmessage "+
            " and t.message != t.originalmessage ";
   
    /**
     * Entrega una lista de TreceivableAccount dado un numeor de mensaje original.
     * @param pEntityManager  Referencia a la session de base de datos.
     * @param pMessage  Numero de mensaje a buscar registros de TreceivableAccount
     * @return  List<TreceivableAccount>
     */
    @SuppressWarnings("unchecked")
    public static List<TreceivableAccountDemanDepo> findByOriginalMessage(EntityManager pEntityManager,String pMessage) {
        List<TreceivableAccountDemanDepo> ldata = null;
        Query qry = pEntityManager.createQuery(HQL_ORIMSG);
        qry.setParameter("originalmessage", pMessage);
        ldata = qry.getResultList();
        return ldata;
    }   
   
   
    /** Sentencia que devuelve una lista de cuentas por cobrar, pendientes de pago.*/
    private static String HQL_RECOVERY = " from TreceivableAccountDemanDepo ra "+
      " where ra.pk.account = :account "+
      " and ra.pk.dateto = :dateto "+
      " and ra.pk.company = :company "+
      " and ra.pk.partitiondb = :partition "+
      " and ra.expiredate >= :accountingdate"+
      " and ra.pendingamount > 0 "+
      " order by ra.priority,ra.pk.creationdate ";
   
    /**
     * Metodo que entrega una lista de cuenta por pagar pendientes de pago.
     * @param pEntityManager  Referencia a una session de base de datos.
     * @param pAccount  Numero de cuenta por cobrar.
     * @param pCompany  Codido de compania asociada a la cuenta por cobrar.
     * @param pAccountingDate  Fecha contable.
     * @return  List<TreceivableAccount>
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public static List<TreceivableAccountDemanDepo> find(EntityManager pEntityManager,String pAccount,Integer pCompany,
            Date pAccountingDate) throws Exception {
        List<TreceivableAccountDemanDepo> ldata = null;
        Query qry = pEntityManager.createQuery(HQL_RECOVERY);
        qry.setParameter("account", pAccount);
        qry.setParameter("dateto", Constant.getDefaultExpiryDate());
        qry.setParameter("company", pCompany);
        qry.setParameter("partition", Constant.getPartition(Constant.getDefaultExpiryDate()));
        qry.setParameter("accountingdate", pAccountingDate);
        ldata = qry.getResultList();
        return ldata;
    }   
   
    /** Sentencia que devuelve un registro de la cuenta por pagar vigente, para la cuenta tipo de saldo grupo balance.*/
    private static String HQL_VIGENT = " from TreceivableAccountDemanDepo ra "+
      " where ra.pk.account = :account "+
      " and ra.pk.dateto = :dateto "+
      " and ra.pk.company = :company "+
      " and ra.pk.partitiondb = :partition "+
      " and ra.balancetype >= :balancetype "+
      " and ra.balancegroup >= :balancegroup ";
   
    /**
     * Metodo que entrega una datos de cuenta por pagar dada la cuenta, tipo de saldo grupo de balance.
     * @param pEntityManager  Referencia a una session de base de datos.
     * @param pAccount  Numero de cuenta por cobrar.
     * @param pCompany  Codido de compania asociada a la cuenta por cobrar.
     * @param pBalanceType  Tipo de saldo.
     * @param pBalanceGroup  Grupo de balance.
     * @return  TreceivableAccount
     * @throws Exception
     */
    public static TreceivableAccountDemanDepo findVigent(EntityManager pEntityManager,String pAccount,Integer pCompany,
            String pBalanceType,String pBalanceGroup) throws Exception {
        TreceivableAccountDemanDepo obj = null;
        Query qry = pEntityManager.createQuery(HQL_VIGENT);
        qry.setParameter("account", pAccount);
        qry.setParameter("dateto", Constant.getDefaultExpiryDate());
        qry.setParameter("company", pCompany);
        qry.setParameter("partition", Constant.getPartition(Constant.getDefaultExpiryDate()));
        qry.setParameter("balancetype", pBalanceType);
        qry.setParameter("balancegroup", pBalanceGroup);       
        try {
            obj = (TreceivableAccountDemanDepo)qry.getSingleResult();   
        } catch (NoResultException e) {
            return obj;
        }
        return obj;
    }   



}
