/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
package lu.tudor.santec.gecamed.billing.ejb.entity.beans;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Transient;

import lu.tudor.santec.gecamed.core.ejb.entity.beans.GECAMedEntityBean;
import lu.tudor.santec.gecamed.usermanagement.ejb.entity.beans.GecamedUser;

//***************************************************************************
//* Class Definition and Members                                            *
//***************************************************************************

/**
 * The Ledger keeps track of financial transactions on invoices. Besides the
 * amounts being credited and debited, the ledger also keeps track of payment
 * method, payment date as well as transaction date and user executing it.
 * @author nico.mack@tudor.lu
 * @since 06/07/03
 */

@Entity
@Table(name = "ledger", schema = "billing")

@NamedQueries 
	({
	@NamedQuery(name = Ledger.c_LedgersByInvoice,     	 query = "SELECT OBJECT(o) FROM Ledger o WHERE o.invoice = :invoice ORDER BY o.transactionDate"),
	@NamedQuery(name = Ledger.c_LedgersByInvoiceID,    	 query = "SELECT OBJECT(o) FROM Ledger o WHERE o.invoiceId=:invoiceID ORDER BY o.transactionDate"),
	@NamedQuery(name = Ledger.c_LedgersByCashier,     	 query = "SELECT OBJECT(o) FROM Ledger o WHERE o.cashier = :cashier ORDER BY o.transactionDate"),
	@NamedQuery(name = Ledger.c_DailyLedgersByCashier,   query = "SELECT OBJECT(o) FROM Ledger o WHERE o.cashier = :cashier AND o.transactionDate = :date ORDER BY o.transactionDate"),
	@NamedQuery(name = Ledger.c_LedgerCountBySettlement, query = "SELECT COUNT(o)  FROM Ledger o WHERE o.settlement = :settlement")
	})

public class Ledger extends GECAMedEntityBean implements Serializable 
	{
	private static final long serialVersionUID = 1L;

	private Invoice		m_Invoice;
	private GecamedUser	m_Cashier;
	private Settlement	m_Settlement;
	private Date		m_SettlementDate;
	private Date		m_TransactionDate;
	private Double		m_Credit;
	private Double		m_Debit;
	private Integer 	m_InvoiceId;
	
//***************************************************************************
//* Class Constants                                                         *
//***************************************************************************

	public static final transient String c_LedgersByInvoice     	= "getLedgersByInvoice";
	public static final transient String c_LedgersByInvoiceID     	= "getLedgersByInvoiceID";
	public static final transient String c_LedgersByCashier     	= "getAllLedgersByCashier";
	public static final transient String c_DailyLedgersByCashier   	= "getDailyLedgersByCashier";
	public static final transient String c_LedgerCountBySettlement 	= "getLedgerCountBySettlement";
	
//***************************************************************************
//* Constructor(s)                                                          *
//***************************************************************************	

public Ledger ()
	{
	m_TransactionDate = new Date ();
	}	

//---------------------------------------------------------------------------
//***************************************************************************
//* Primitives                                       						*
//***************************************************************************
//---------------------------------------------------------------------------

@Transient
public static double round (double p_Value)
	{
	long		l_Rounder;
		
	l_Rounder = (long) ((p_Value * 100) + 0.5);
	p_Value = ((double) l_Rounder / 100);
	
	return p_Value;
	}

//---------------------------------------------------------------------------
//***************************************************************************
//* Getter and Setter Methods	                                            *
//***************************************************************************	
//---------------------------------------------------------------------------
/**
 * Returns the invoice this transaction relates to
 * @return the related invoice
 */
//---------------------------------------------------------------------------

@ManyToOne (fetch = javax.persistence.FetchType.LAZY)
@JoinColumn (name ="invoice_id")

public Invoice getInvoice() 
	{
	return m_Invoice;
	}

//---------------------------------------------------------------------------
/**
 * Sets the invoice this transaction relates to
 * @param p_Invoice specifies the related invoice
 */
//---------------------------------------------------------------------------

public void setInvoice (Invoice p_Invoice) 
	{
	m_Invoice = p_Invoice;
	}


@Column(name = "invoice_id", insertable =false, updatable = false)
public Integer getInvoiceId() 
	{
	return m_InvoiceId;
	}

//---------------------------------------------------------------------------
/**
 * Sets the Id of the statement this invoice stub is part of
 * @param p_StatementId specifies the new Id of the statement this stub is
 * to be part of, <code>null</code> if none.
 */
//---------------------------------------------------------------------------

public void setInvoiceId (Integer p_InvoiceId) 
	{
	m_InvoiceId = p_InvoiceId;
	}

//---------------------------------------------------------------------------
/**
 * Returns the user who generated this transcation by settling an invoice.
 * @return The user at the origin of this transaction 
 */
//---------------------------------------------------------------------------

@ManyToOne (fetch = javax.persistence.FetchType.EAGER)
@JoinColumn (name ="cashier_id")

public GecamedUser getCashier() 
	{
	return m_Cashier;
	}

//---------------------------------------------------------------------------
/**
 * Sets the user who generated this transcation
 * @param p_Cashier specifies the GECAMed user to be at the origin of this
 * transcation
 */
//---------------------------------------------------------------------------

public void setCashier (GecamedUser p_Cashier) 
	{
	m_Cashier = p_Cashier;
	}

//---------------------------------------------------------------------------
/**
 * Returns the settlement method of this transcation
 * @return The settlement method of this transcation
 */
//---------------------------------------------------------------------------

@ManyToOne (fetch = javax.persistence.FetchType.EAGER)
@JoinColumn (name ="settlement_id")

public Settlement getSettlement() 
	{
	return m_Settlement;
	}

//---------------------------------------------------------------------------
/**
 * Sets the settlement method of this transcation
 * @param p_Settlement specifies the new settlement method for this transcation
 */
//---------------------------------------------------------------------------

public void setSettlement (Settlement p_Settlement) 
	{
	m_Settlement = p_Settlement;
	}

//---------------------------------------------------------------------------
/**
 * Returns the original settlement date of the invoice this transaction
 * refers to
 * @return invoice settlement date
 */
//---------------------------------------------------------------------------

@Column (name ="settlement_date")

public Date getSettlementDate() 
	{
	return m_SettlementDate;
	}

//---------------------------------------------------------------------------
/**
 * Sets the original invoice settlement date for this transaction
 * @param p_SettlementDate specifies the new settlement date
 */
//---------------------------------------------------------------------------

public void setSettlementDate (Date p_SettlementDate) 
	{
	m_SettlementDate = (p_SettlementDate != null) ? new Date (p_SettlementDate.getTime()) : null;
	}

//---------------------------------------------------------------------------
/**
 * Returns the date of this transaction, i.e. when the transaction was recorded
 * in the ledger
 * @return transaction date
 */
//---------------------------------------------------------------------------

@Column (name ="transaction_date")

public Date getTransactionDate() 
	{
	return m_TransactionDate;
	}

//---------------------------------------------------------------------------
/**
 * Sets the transaction date for this ledger entry
 * @param p_TransactionDate specifies the transaction date
 */
//---------------------------------------------------------------------------

public void setTransactionDate (Date p_TransactionDate) 
	{
	m_TransactionDate = (p_TransactionDate != null) ? new Date (p_TransactionDate.getTime()) : null;
	}

//---------------------------------------------------------------------------
/**
 * Returns the amount debited by this transaction
 * @return debited amount
 */
//---------------------------------------------------------------------------

@Column (name ="debit")
public Double getDebit() 
	{
	return m_Debit;
	}

//---------------------------------------------------------------------------
/**
 * Sets the debit for this transaction.
 * @param p_Debit specifies the amount to be debited
 */
//---------------------------------------------------------------------------

public void setDebit (Double p_Debit) 
	{
	m_Debit = p_Debit;
	}

//---------------------------------------------------------------------------
/**
 * Returns the amount credited by this transaction
 * @return credited amount
 */
//---------------------------------------------------------------------------

@Column (name ="credit")
public Double getCredit() 
	{
	return m_Credit;
	}

//---------------------------------------------------------------------------
/**
 * Sets the credit for this transaction.
 * @param p_Credit specifies the amount to be credited
 */
//---------------------------------------------------------------------------

public void setCredit (Double p_Credit) 
	{
	m_Credit = p_Credit;
	}
//***************************************************************************
//* End of Class															*
//***************************************************************************
}
