using HRM.BO;
using Ease.Core.DataAccess;
using System;
using System.Data;


namespace HRM.DA
{
    #region LoanScheduleDA

    internal class LoanScheduleDA
    {
        #region Constructor

        private LoanScheduleDA()
        {
        }

        #endregion

        #region Insert function

        internal static void Insert(TransactionContext tc, LoanSchedule item)
        {
            tc.ExecuteNonQuery("INSERT INTO LoanSchedule(LoanScheduleID, LoanIssueID, ScheduleNo, OpeningBalance," +
                               " INSTALLMENTPRINCIPAL, INSTALLMENTINTEREST, DUEINSTALLMENTDATE, PAYMENTDATE, DAYS, " +
                               " CALCULATEDDATE, ACTUALINTEREST, ClosingBalance, PaymentMode, EmployeeID,InterestRate)" +
                               " VALUES(%n, %n, %n, %n, %n, %n, %d, %d, %n, %d, %n, %n,%n,%n,%n)", item.ID,
                item.LoanIssueID, item.ScheduleNo, item.OpeningBalance,
                item.InstallmentPrincipal, item.InstallmentInterest,
                item.DueInstallmentDate, DataReader.GetNullValue(item.PaymentDate),
                item.Days, item.CalculatedDate, item.ActualInterest,
                item.ClosingBalance, item.PaymentMode, item.EmployeeID, item.InterestRate);
        }

        #endregion

        #region Update function

        internal static void Update(TransactionContext tc, LoanSchedule item)
        {
            tc.ExecuteNonQuery("UPDATE LoanSchedule SET LoanIssueID=%n, ScheduleNo=%n, OpeningBalance=%n, " +
                               " InstallmentPrincipal=%n, InstallmentInterest=%n, DueInstallmentDate=%d, PaymentDate=%d, Days=%n," +
                               " CalculatedDate=%d, ActualInterest=%n, ClosingBalance=%n, paymentMode=%n,InterestRate=%n , ModifiedBy=%n, ModifiedDate =%D " +
                               " WHERE LoanScheduleID=%n", item.LoanIssueID, item.ScheduleNo,
                item.OpeningBalance, item.InstallmentPrincipal, item.InstallmentInterest,
                item.DueInstallmentDate, DataReader.GetNullValue(item.PaymentDate),
                item.Days, item.CalculatedDate, item.ActualInterest,
                item.ClosingBalance, item.PaymentMode, item.InterestRate, item.ModifiedBy, item.ModifiedDate, item.ID);
        }
        internal static void UpdateAmount(TransactionContext tc, LoanSchedule item)
        {
            tc.ExecuteNonQuery("UPDATE LoanSchedule SET  OpeningBalance=%n, " +
                               " InstallmentPrincipal=%n, InstallmentInterest=%n, " +
                               "  ActualInterest=%n, ClosingBalance=%n, ModifiedBy=%n, ModifiedDate =%D " +
                               " WHERE LoanScheduleID=%n", 
                item.OpeningBalance, item.InstallmentPrincipal, item.InstallmentInterest,
                item.ActualInterest, item.ClosingBalance, item.ModifiedBy, item.ModifiedDate, item.ID);
        }
        #endregion

        #region Get Function

        internal static IDataReader Get(TransactionContext tc)
        {
            return tc.ExecuteReader("SELECT * FROM LoanSchedule");
        }

        internal static IDataReader GetUnpaidSechedule(TransactionContext tc, DateTime dateTime)
        {
            return tc.ExecuteReader(" " +
                                    "SELECT * FROM LoanSchedule WHERE PaymentDate IS NULL AND DUEINSTALLMENTDATE BETWEEN %d AND %d order by EmployeeID, ScheduleNo ",
                PayrollGlobalFunctions.PayrollFirstDateOfMonth(dateTime),
                PayrollGlobalFunctions.PayrollLastDateOfMonth(dateTime));
        }


        internal static IDataReader Get(TransactionContext tc, int nID)
        {
            return tc.ExecuteReader("SELECT * FROM LoanSchedule WHERE LoanScheduleID=%n Order By DUEINSTALLMENTDATE",
                nID);
        }
        //internal static IDataReader Get(TransactionContext tc, int EmpID, int LoanID)
        //{
        //    return tc.ExecuteReader("SELECT LoanIssueID,sum(InstallmentPrincipal) as total FROM LoanSchedule WHERE LoanIssueID in(select LOANISSUEID from LOANISSUE where EMPLOYEEID=%n and LoanID=%n) AND PaymentDate is null group by LoanIssueID", EmpID,LoanID);
        //}

        internal static DataSet GetByEmpIDANDLoanID(TransactionContext tc, int EmpID, int LoanID)
        {
            DataSet oLoanAmounts = new DataSet();
            try
            {
                oLoanAmounts = tc.ExecuteDataSet(
                    "SELECT LoanIssueID,sum(InstallmentPrincipal) as total FROM LoanSchedule WHERE LoanIssueID in(select LOANISSUEID from LOANISSUE where EMPLOYEEID=%n and LoanID=%n) AND PaymentDate is null group by LoanIssueID",
                    EmpID, LoanID);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return oLoanAmounts;
        }

        internal static IDataReader GetByIssueID(TransactionContext tc, int nIssueID)
        {
            return tc.ExecuteReader("SELECT * FROM LoanSchedule WHERE LOANISSUEID=%n Order By DUEINSTALLMENTDATE",
                nIssueID);
        }

        internal static IDataReader GetByIssueIDAndMonth(TransactionContext tc, int nIssueID, DateTime dateTime)
        {
            return tc.ExecuteReader(
                "SELECT * FROM LoanSchedule WHERE LOANISSUEID=%n  AND DUEINSTALLMENTDATE = %d Order By DUEINSTALLMENTDATE",
                nIssueID, dateTime);
        }

        internal static DataSet GetLoanPaymentDue(TransactionContext tc, DateTime dFromDate, DateTime dToDate,
            int payrollTypeID)
        {
            DataSet oLoanPayments = new DataSet();
            try
            {
                string sql = SQLParser.MakeSQL(@"
                            SELECT e.EmployeeNo, e.Name, li.LoanAmount, li.LoanNo, li.LOANISSUEID, li.EMPLOYEEID, l.loanid, l.DESCRIPTION, ls.*  FROM LoanSchedule ls,LoanIssue li, LOANBASIC l,Employee e WHERE PaymentDate IS NULL 
                            AND  ls.LOANISSUEID =li.LOANISSUEID AND l.LOANID = li.LOANID  AND DUEINSTALLMENTDATE BETWEEN %d AND %d and e.EmployeeID =li.EmployeeID and e.status =1
                            and e.PayrollTypeId=%n order by li.EmployeeID, ScheduleNo
                            ", PayrollGlobalFunctions.PayrollFirstDateOfMonth(dFromDate),
                    PayrollGlobalFunctions.PayrollLastDateOfMonth(dToDate), payrollTypeID);
                oLoanPayments = tc.ExecuteDataSet(@"
                            SELECT e.EmployeeNo, e.Name, li.LoanAmount, li.LoanNo, li.LOANISSUEID, li.EMPLOYEEID, l.loanid, l.DESCRIPTION, ls.*  FROM LoanSchedule ls,LoanIssue li, LOANBASIC l,Employee e WHERE PaymentDate IS NULL 
                            AND  ls.LOANISSUEID =li.LOANISSUEID AND l.LOANID = li.LOANID  AND DUEINSTALLMENTDATE BETWEEN %d AND %d and e.EmployeeID =li.EmployeeID and e.status =1
                            and e.PayrollTypeId=%n order by li.EmployeeID, ScheduleNo
                            ", PayrollGlobalFunctions.PayrollFirstDateOfMonth(dFromDate),
                    PayrollGlobalFunctions.PayrollLastDateOfMonth(dToDate), payrollTypeID);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return oLoanPayments;
        }

        internal static DataSet GetAllActiveLoan(TransactionContext tc, string sEmps, int payrollTypeID)
        {
            DataSet oLoanPayments = new DataSet();
            try
            {
                string sql = SQLParser.MakeSQL(
                    @" SELECT li.LOANISSUEID,e.EmployeeNo, e.Name,g.DESCRIPTION Grade,d.NAME Designation, li.LoanAmount, li.LoanNo,  li.INTERESTRATE,  
                             li.EMPLOYEEID,li.ISSUEDATE, li.STARTPAYBACKMONTHDATE, l.loanid, l.DESCRIPTION ,li.NOOFINSTALLMENTS , (SUM(ls.INSTALLMENTPRINCIPAL)+SUM(ls.INSTALLMENTINTEREST)) OutStanding,
                             (li.NOOFINSTALLMENTS-COUNT(ls.LOANSCHEDULEID)) NoofPaid
                             FROM LoanSchedule ls,LoanIssue li, LOANBASIC l,Employee e,Grades g, Designation d WHERE PaymentDate IS NULL 
                            AND  ls.LOANISSUEID =li.LOANISSUEID AND l.LOANID = li.LOANID  and e.EmployeeID =li.EmployeeID and e.status =1
                            and e.PayrollTypeId=%n AND g.GRADEID=e.GRADEID AND e.DESIGNATIONID=d.DESIGNATIONID AND e.EmployeeID in (%q)
                            GROUP BY li.LOANISSUEID,e.EmployeeNo, e.Name,g.DESCRIPTION,d.NAME, li.LoanAmount, li.LoanNo,  li.INTERESTRATE,li.EMPLOYEEID, 
                            li.ISSUEDATE, li.STARTPAYBACKMONTHDATE,l.loanid, l.DESCRIPTION ,li.NOOFINSTALLMENTS
                            order by e.EmployeeNo", payrollTypeID, sEmps);
                oLoanPayments = tc.ExecuteDataSet(sql);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return oLoanPayments;
        }

        internal static DataSet GetCurrentMonthDueLoan(TransactionContext tc, string sEmps, int payrollTypeID,
            int loanID)
        {
            DataSet oLoanPayments = new DataSet();
            string sql;
            try
            {
                //if (loanID != null && !loanID.IsUnassigned)
                if (loanID != 0)
                {
                    sql = SQLParser.MakeSQL(
                        @" SELECT li.LOANISSUEID, e.EmployeeNo, e.Name, li.LoanAmount, li.LoanNo, li.INTERESTRATE,  
                                                 li.EMPLOYEEID, li.ISSUEDATE, li.STARTPAYBACKMONTHDATE, ls.INSTALLMENTPRINCIPAL, li.NOOFINSTALLMENTS, l.loanid, l.DESCRIPTION ,li.NOOFINSTALLMENTS , (SUM(ls.INSTALLMENTPRINCIPAL)+SUM(ls.INSTALLMENTINTEREST)) OutStanding,
                                                 (li.NOOFINSTALLMENTS-COUNT(ls.LOANSCHEDULEID)) NoofPaid
                                                 FROM LoanSchedule ls,LoanIssue li, LOANBASIC l,Employee e WHERE PaymentDate IS NULL 
                                                 AND  ls.LOANISSUEID =li.LOANISSUEID AND l.LOANID = li.LOANID  and e.EmployeeID =li.EmployeeID and e.status =1
                                                 AND l.loanid =%n and e.PayrollTypeId=%n AND e.EmployeeID in (%q)
                                                 GROUP BY li.LOANISSUEID,e.EmployeeNo, e.Name, li.LoanAmount, li.LoanNo,  li.INTERESTRATE, li.EMPLOYEEID, 
                                                 li.ISSUEDATE, li.STARTPAYBACKMONTHDATE, ls.INSTALLMENTPRINCIPAL, li.NOOFINSTALLMENTS, l.loanid, l.DESCRIPTION , li.NOOFINSTALLMENTS
                                                 order by e.EmployeeNo", loanID, payrollTypeID, sEmps);
                }
                else
                {
                    sql = SQLParser.MakeSQL(
                        @" SELECT li.LOANISSUEID, e.EmployeeNo, e.Name, li.LoanAmount, li.LoanNo, li.INTERESTRATE,  
                                                 li.EMPLOYEEID, li.ISSUEDATE, li.STARTPAYBACKMONTHDATE, ls.INSTALLMENTPRINCIPAL, li.NOOFINSTALLMENTS, l.loanid, l.DESCRIPTION ,li.NOOFINSTALLMENTS , (SUM(ls.INSTALLMENTPRINCIPAL)+SUM(ls.INSTALLMENTINTEREST)) OutStanding,
                                                 (li.NOOFINSTALLMENTS-COUNT(ls.LOANSCHEDULEID)) NoofPaid
                                                 FROM LoanSchedule ls,LoanIssue li, LOANBASIC l,Employee e WHERE PaymentDate IS NULL 
                                                 AND ls.LOANISSUEID =li.LOANISSUEID AND l.LOANID = li.LOANID  and e.EmployeeID =li.EmployeeID and e.status =1
                                                 and e.PayrollTypeId=%n AND e.EmployeeID in (%q)
                                                 GROUP BY li.LOANISSUEID,e.EmployeeNo, e.Name, li.LoanAmount, li.LoanNo,  li.INTERESTRATE, li.EMPLOYEEID, 
                                                 li.ISSUEDATE, li.STARTPAYBACKMONTHDATE, ls.INSTALLMENTPRINCIPAL, li.NOOFINSTALLMENTS, l.loanid, l.DESCRIPTION , li.NOOFINSTALLMENTS
                                                 order by e.EmployeeNo", payrollTypeID, sEmps);
                }

                oLoanPayments = tc.ExecuteDataSet(sql);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return oLoanPayments;
        }

        internal static DataSet GetScheduleForSalary(TransactionContext tc, DateTime monthDate, int payrollTypeID)
        {
            DataSet oLoanPayments = new DataSet();
            try
            {
                oLoanPayments = tc.ExecuteDataSet(@"
                            SELECT   li.LOANISSUEID, li.EMPLOYEEID, l.loanid, l.DESCRIPTION, ls.*, 
(SELECT sum(lss.INSTALLMENTPRINCIPAL) FROM LOANSCHEDULE lss WHERE lss.LOANISSUEID = li.LOANISSUEID AND lss.SCHEDULENO > ls.SCHEDULENO) AS RemainingAmount,
(SELECT sum(lss.INSTALLMENTINTEREST) FROM LOANSCHEDULE lss WHERE lss.LOANISSUEID = li.LOANISSUEID AND lss.SCHEDULENO > ls.SCHEDULENO) AS RemainingInterest 
                            FROM LoanSchedule ls,LoanIssue li, LOANBASIC l,Employee e WHERE PaymentDate IS NULL 
                            AND  ls.LOANISSUEID =li.LOANISSUEID AND l.LOANID = li.LOANID  AND DUEINSTALLMENTDATE BETWEEN %d AND %d and e.EmployeeID =li.EmployeeID and e.status =1 
                            and e.PayrollTypeId=%n order by li.EmployeeID, ScheduleNo
                            ", PayrollGlobalFunctions.PayrollFirstDateOfMonth(monthDate),
                    PayrollGlobalFunctions.PayrollLastDateOfMonth(monthDate), payrollTypeID);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return oLoanPayments;
        }

        #endregion

        #region Delete function

        internal static void Delete(TransactionContext tc, int nIssueID)
        {
            tc.ExecuteNonQuery("DELETE FROM LoanSchedule WHERE LOANISSUEID=%n", nIssueID);
        }

        internal static void Delete2(TransactionContext tc, int nIssueID)
        {
            tc.ExecuteNonQuery("DELETE FROM LoanSchedule WHERE LOANISSUEID=%n AND paymentdate is null", nIssueID);
        }

        internal static void UpdatePaymentDate(TransactionContext tc,
            int loanSheduleId, DateTime paymentDate, EnumLoanPaymentMode mode)
        {
            tc.ExecuteNonQuery("Update LoanSchedule SET paymentDate=%d, PaymentMode=%n"
                               + " WHERE LoanScheduleID=%n", paymentDate, mode, loanSheduleId);
        }

        public static int GetNewID(TransactionContext tc, string tableName, string columnName)
        {
            return tc.GenerateID(tableName, columnName);
        }

        #endregion
    }

    #endregion
}