public List<PayrollExport> GetPayrollExportList(int companyID, int departmentID, DateTime beginDate, DateTime endDate, int workingCalendarID, ref string errorNumber)
        {
            List<int> employeeNumberList = GetEmployeeNumberList_1(companyID, departmentID);

            if (employeeNumberList == null || employeeNumberList.Count == 0)
                return null;

            List<PayrollExport> payrollExportList = new List<PayrollExport>();
            PayrollExport payrollExport = null;

            foreach (int emplNumber in employeeNumberList)
            {
                WorkingCalendar workingCalendar = GetWorkingCalendarByEmployee(emplNumber);

                PayPeriod payPeriod = GetPayPeriod(workingCalendar.PayPeriodID);
                DateTime dtPayStart = payPeriod.StartFrom.Date;
                int customPeriod = payPeriod.CustomPeriod;
                PayPeriodType payPeriodType = GetPayPeriodType(payPeriod.PayPeriodTypeID);
                string periodTypeName = payPeriodType.Name;

                //DateTime dtPayEnd = dtPayStart;
                //SetBeginEndPeriodTime(beginDate, endDate, ref dtPayStart, ref dtPayEnd, periodTypeName, customPeriod, false);

                //if (dtPayEnd.CompareTo(endDate) > 0 || dtPayEnd.CompareTo(DateTime.Now) > 0)
                //{
                //    continue;
                //}

                //List<AttendanceLogReport> attendanceLogReportListByEmpl = GetAttendanceLogReportList(emplNumber, dtPayStart, dtPayEnd);

                //if (attendanceLogReportListByEmpl.Count == 0)
                //{
                //    while (dtPayEnd.CompareTo(endDate) < 0 || attendanceLogReportListByEmpl.Count == 0)
                //    {
                //        dtPayStart = dtPayEnd;
                //        SetBeginEndPeriodTime(beginDate, endDate, ref dtPayStart, ref dtPayEnd, periodTypeName, customPeriod, false);

                //        if (dtPayEnd.CompareTo(endDate) > 0 || dtPayEnd.CompareTo(DateTime.Now) > 0)
                //        {
                //            continue;
                //        }
                //        attendanceLogReportListByEmpl = GetAttendanceLogReportList(emplNumber, dtPayStart, dtPayEnd);
                //    }
                //    if (attendanceLogReportListByEmpl.Count == 0)
                //        continue;
                //}

                //beginDate = dStartFrom;
                //endDate = dEndTo;
                List<AttendanceLogReport> attendanceLogReportListByEmpl = GetAttendanceLogReportList(emplNumber, beginDate, endDate);
                if (attendanceLogReportListByEmpl.Count == 0)
                    continue;

                attendanceLogReportListByEmpl.Sort(delegate(AttendanceLogReport e1, AttendanceLogReport e2) { return e1.WorkFrom.CompareTo(e2.WorkFrom); });

                Hashtable hOvertimeHour1 = new Hashtable();
                Hashtable hOvertimeHour2 = new Hashtable();
                Hashtable hOvertimeHour3 = new Hashtable();
                Hashtable hOvertimeHour4 = new Hashtable();

                double regularHours = 0, totalHours = 0, totalHoursWithRate = 0, totalOvertimeHours = 0;
                string overtimeHourAndRate = "";

                foreach (AttendanceLogReport attRp in attendanceLogReportListByEmpl)
                {
                    regularHours += attRp.WorkingHour;

                    totalHours += attRp.TotalHour;

                    totalHoursWithRate += attRp.WorkingHour * attRp.RegularRate / 100
                        + attRp.OvertimeHour1 * attRp.OvertimeRate1 / 100
                        + attRp.OvertimeHour2 * attRp.OvertimeRate2 / 100
                        + attRp.OvertimeHour3 * attRp.OvertimeRate3 / 100
                        + attRp.OvertimeHour4 * attRp.OvertimeRate4 / 100;

                    totalOvertimeHours += attRp.OvertimeHour1
                    + attRp.OvertimeHour2
                    + attRp.OvertimeHour3
                    + attRp.OvertimeHour4;

                    if (attRp.OvertimeHour1 > 0)
                    {
                        if (hOvertimeHour1.ContainsKey(attRp.OvertimeRate1))
                        {
                            double overtimeHour = (double)hOvertimeHour1[attRp.OvertimeRate1];
                            hOvertimeHour1[attRp.OvertimeRate1] = overtimeHour + attRp.OvertimeHour1;
                        }
                        else
                            hOvertimeHour1.Add(attRp.OvertimeRate1, attRp.OvertimeHour1);
                    }

                    if (attRp.OvertimeHour2 > 0)
                    {
                        if (hOvertimeHour2.ContainsKey(attRp.OvertimeRate2))
                        {
                            double overtimeHour = (double)hOvertimeHour2[attRp.OvertimeRate2];
                            hOvertimeHour2[attRp.OvertimeRate2] = overtimeHour + attRp.OvertimeHour2;
                        }
                        else
                            hOvertimeHour2.Add(attRp.OvertimeRate2, attRp.OvertimeHour2);
                    }

                    if (attRp.OvertimeHour3 > 0)
                    {
                        if (hOvertimeHour3.ContainsKey(attRp.OvertimeRate3))
                        {
                            double overtimeHour = (double)hOvertimeHour3[attRp.OvertimeRate3];
                            hOvertimeHour3[attRp.OvertimeRate3] = overtimeHour + attRp.OvertimeHour3;
                        }
                        else
                            hOvertimeHour3.Add(attRp.OvertimeRate3, attRp.OvertimeHour3);
                    }

                    if (attRp.OvertimeHour4 > 0)
                    {
                        if (hOvertimeHour4.ContainsKey(attRp.OvertimeRate4))
                        {
                            double overtimeHour = (double)hOvertimeHour4[attRp.OvertimeRate4];
                            hOvertimeHour4[attRp.OvertimeRate4] = overtimeHour + attRp.OvertimeHour4;
                        }
                        else
                            hOvertimeHour4.Add(attRp.OvertimeRate4, attRp.OvertimeHour4);
                    }
                }

                StringBuilder strOvertime = new StringBuilder();

                foreach (DictionaryEntry item in hOvertimeHour1)
                    strOvertime.AppendFormat("{0} x {1}%\n", item.Value, item.Key);

                foreach (DictionaryEntry item in hOvertimeHour2)
                    strOvertime.AppendFormat("{0} x {1}%\n", item.Value, item.Key);

                foreach (DictionaryEntry item in hOvertimeHour3)
                    strOvertime.AppendFormat("{0} x {1}%\n", item.Value, item.Key);

                foreach (DictionaryEntry item in hOvertimeHour4)
                    strOvertime.AppendFormat("{0} x {1}%\n", item.Value, item.Key);

                overtimeHourAndRate = strOvertime.ToString();

                AttendanceLogReport attendanceLogReport = attendanceLogReportListByEmpl[0];

                payrollExport = new PayrollExport();

                payrollExport.DateFrom = attendanceLogReportListByEmpl[0].WorkFrom;
                payrollExport.DateTo = attendanceLogReportListByEmpl[attendanceLogReportListByEmpl.Count - 1].WorkFrom;

                payrollExport.EmployeeNumber = emplNumber;
                payrollExport.FullName = attendanceLogReport.FullName;
                payrollExport.JobDescription = attendanceLogReport.JobDescription;
                payrollExport.Department = attendanceLogReport.Department;
                payrollExport.PayrollNumber = attendanceLogReport.PayrollNumber;
                payrollExport.RegularHour = Math.Round(regularHours, 2);
                payrollExport.OvertimeHour = overtimeHourAndRate;
                payrollExport.TotalHours = Math.Round(totalHours, 2);
                payrollExport.TotalHoursWithRate = Math.Round(totalHoursWithRate, 2);
                payrollExport.TotalOvertimeHours = Math.Round(totalOvertimeHours, 2);
                payrollExportList.Add(payrollExport);

                hOvertimeHour1.Clear();
                hOvertimeHour2.Clear();
                hOvertimeHour3.Clear();
                hOvertimeHour4.Clear();
            }

            return payrollExportList;
        }
        public List<PayrollExport> GetPayrollExportList(int companyID, int departmentID, DateTime beginDate, DateTime endDate, int workingCalendarID, ref string errorNumber)
        {
            List<int> employeeNumberList = GetEmployeeNumberList_1(companyID, departmentID);

            if (employeeNumberList == null || employeeNumberList.Count == 0)
                return null;

            List<PayrollExport> payrollExportList = new List<PayrollExport>();
            PayrollExport payrollExport = null;

            foreach (int emplNumber in employeeNumberList)
            {
                WorkingCalendar workingCalendar = GetWorkingCalendarByEmployee(emplNumber);

                PayPeriod payPeriod = GetPayPeriod(workingCalendar.PayPeriodID);
                DateTime dtPayStart = payPeriod.StartFrom.Date;
                int customPeriod = payPeriod.CustomPeriod;
                PayPeriodType payPeriodType = GetPayPeriodType(payPeriod.PayPeriodTypeID);
                string periodTypeName = payPeriodType.Name;
                bool applyFlexiHours = workingCalendar.ApplyFlexiHours;
                double flexiHours = Convert.ToDouble(workingCalendar.FlexiHours);
                DayOfWeek weekStartsOn = GetDayOfWeek(workingCalendar.WeekStartsOn);

                List<Shift> shiftList = GetShiftListByWorkingCalendar(workingCalendar.ID);

                #region temp
                ////DateTime dtPayEnd = dtPayStart;
                //SetBeginEndPeriodTime(beginDate, endDate, ref dtPayStart, ref dtPayEnd, periodTypeName, customPeriod, false);

                //if (dtPayEnd.CompareTo(endDate) > 0 || dtPayEnd.CompareTo(DateTime.Now) > 0)
                //{
                //    continue;
                //}

                //List<AttendanceLogReport> attendanceLogReportListByEmpl = GetAttendanceLogReportList(emplNumber, dtPayStart, dtPayEnd);

                //if (attendanceLogReportListByEmpl.Count == 0)
                //{
                //    while (dtPayEnd.CompareTo(endDate) < 0 || attendanceLogReportListByEmpl.Count == 0)
                //    {
                //        dtPayStart = dtPayEnd;
                //        SetBeginEndPeriodTime(beginDate, endDate, ref dtPayStart, ref dtPayEnd, periodTypeName, customPeriod, false);

                //        if (dtPayEnd.CompareTo(endDate) > 0 || dtPayEnd.CompareTo(DateTime.Now) > 0)
                //        {
                //            continue;
                //        }
                //        attendanceLogReportListByEmpl = GetAttendanceLogReportList(emplNumber, dtPayStart, dtPayEnd);
                //    }
                //    if (attendanceLogReportListByEmpl.Count == 0)
                //        continue;
                //}

                //beginDate = dStartFrom;
                //endDate = dEndTo;

                #endregion temp

                List<AttendanceLogReport> attendanceLogReportListByEmpl = GetAttendanceLogReportList(emplNumber, beginDate, endDate);
                if (attendanceLogReportListByEmpl.Count == 0)
                    continue;

                attendanceLogReportListByEmpl.Sort(delegate(AttendanceLogReport e1, AttendanceLogReport e2) { return e1.WorkFrom.CompareTo(e2.WorkFrom); });

                if (applyFlexiHours)
                {
                    AttendanceLogReport attendanceLogReport = attendanceLogReportListByEmpl[0];
                    while (true)
                    {
                        if (weekStartsOn.Equals(attendanceLogReport.WorkFrom.DayOfWeek))
                            break;

                        attendanceLogReportListByEmpl.RemoveAt(0);

                        if (attendanceLogReportListByEmpl.Count == 0)
                            break;

                        attendanceLogReport = attendanceLogReportListByEmpl[0];
                    }

                    double regularHours = 0, totalHours = 0, totalHoursWithRate = 0, totalOvertimeHours = 0;
                    string overtimeHourAndRate = "";

                    DateTime beginFlexiDate = attendanceLogReport.WorkFrom;
                    DateTime endFlexiDate = beginFlexiDate.AddDays(6);

                    double regularHoursTmp = 0;
                    int count = attendanceLogReportListByEmpl.Count;
                    foreach (AttendanceLogReport attRp in attendanceLogReportListByEmpl)
                    {
                        count--;
                        totalHours += attRp.TotalHour;

                        if (endFlexiDate.CompareTo(attRp.WorkFrom) != -1)
                        {
                            regularHoursTmp += attRp.TotalHour;
                        }
                        else
                        {
                            if (regularHoursTmp > flexiHours)
                            {
                                regularHours += flexiHours;
                                totalOvertimeHours += regularHoursTmp - flexiHours;
                            }
                            else
                            {
                                regularHours += regularHoursTmp;
                            }
                            beginFlexiDate = attRp.WorkFrom;
                            endFlexiDate = beginFlexiDate.AddDays(6);
                            regularHoursTmp = attRp.TotalHour;
                        }

                        if (count == 0)
                        {
                            if (regularHoursTmp > flexiHours)
                            {
                                regularHours += flexiHours;
                                totalOvertimeHours += regularHoursTmp - flexiHours;
                            }
                            else
                            {
                                regularHours += regularHoursTmp;
                            }
                        }
                    }
                    double overtimeHour1 = 0, overtimeHour2 = 0, overtimeHour3 = 0, overtimeHour4 = 0;

                    if (attendanceLogReport.OvertimeHour1 > 0)
                    {
                        if (totalOvertimeHours > attendanceLogReport.OvertimeHour1)
                        {
                            overtimeHour1 = attendanceLogReport.OvertimeHour1;
                            totalOvertimeHours -= attendanceLogReport.OvertimeHour1;

                            if (attendanceLogReport.OvertimeHour2 > 0)
                            {
                                if (totalOvertimeHours > attendanceLogReport.OvertimeHour2)
                                {
                                    overtimeHour2 = attendanceLogReport.OvertimeHour2;
                                    totalOvertimeHours -= attendanceLogReport.OvertimeHour2;

                                    if (attendanceLogReport.OvertimeHour3 > 0)
                                    {
                                        if (totalOvertimeHours > attendanceLogReport.OvertimeHour3)
                                        {
                                            overtimeHour3 = attendanceLogReport.OvertimeHour3;
                                            totalOvertimeHours -= attendanceLogReport.OvertimeHour3;

                                            if (attendanceLogReport.OvertimeHour4 > 0)
                                            {
                                                overtimeHour4 = totalOvertimeHours;
                                            }
                                        }
                                        else
                                            overtimeHour3 = totalOvertimeHours;
                                    }
                                }
                                else
                                    overtimeHour2 = totalOvertimeHours;
                            }
                        }
                        else
                            overtimeHour1 = totalOvertimeHours;
                    }

                    totalHoursWithRate = regularHours * attendanceLogReport.RegularRate / 100
                            + overtimeHour1 * attendanceLogReport.OvertimeRate1 / 100
                            + overtimeHour2 * attendanceLogReport.OvertimeRate2 / 100
                            + overtimeHour3 * attendanceLogReport.OvertimeRate3 / 100
                            + overtimeHour4 * attendanceLogReport.OvertimeRate4 / 100;

                    StringBuilder strOvertime = new StringBuilder();

                    if (overtimeHour1 > 0)
                        strOvertime.AppendFormat("{0} x {1}%\n", overtimeHour1, attendanceLogReport.OvertimeRate1);

                    if (overtimeHour2 > 0)
                        strOvertime.AppendFormat("{0} x {1}%\n", overtimeHour2, attendanceLogReport.OvertimeRate2);

                    if (overtimeHour3 > 0)
                        strOvertime.AppendFormat("{0} x {1}%\n", overtimeHour3, attendanceLogReport.OvertimeRate3);

                    if (overtimeHour4 > 0)
                        strOvertime.AppendFormat("{0} x {1}%\n", overtimeHour4, attendanceLogReport.OvertimeRate4);

                    overtimeHourAndRate = strOvertime.ToString();

                    payrollExport = new PayrollExport();

                    payrollExport.DateFrom = attendanceLogReportListByEmpl[0].WorkFrom;
                    payrollExport.DateTo = attendanceLogReportListByEmpl[attendanceLogReportListByEmpl.Count - 1].WorkFrom;

                    payrollExport.EmployeeNumber = emplNumber;
                    payrollExport.FullName = attendanceLogReport.FullName;
                    payrollExport.JobDescription = attendanceLogReport.JobDescription;
                    payrollExport.Department = attendanceLogReport.Department;
                    payrollExport.PayrollNumber = attendanceLogReport.PayrollNumber;
                    payrollExport.RegularHour = Math.Round(regularHours, 2);
                    payrollExport.OvertimeHour = overtimeHourAndRate;
                    payrollExport.TotalHours = Math.Round(totalHours, 2);
                    payrollExport.TotalHoursWithRate = Math.Round(totalHoursWithRate, 2);
                    payrollExport.TotalOvertimeHours = Math.Round(totalOvertimeHours, 2);
                    payrollExportList.Add(payrollExport);
                }
                else
                {
                    Hashtable hOvertimeHour1 = new Hashtable();
                    Hashtable hOvertimeHour2 = new Hashtable();
                    Hashtable hOvertimeHour3 = new Hashtable();
                    Hashtable hOvertimeHour4 = new Hashtable();

                    double regularHours = 0, totalHours = 0, totalHoursWithRate = 0, totalOvertimeHours = 0;
                    string overtimeHourAndRate = "";

                    foreach (AttendanceLogReport attRp in attendanceLogReportListByEmpl)
                    {
                        regularHours += attRp.WorkingHour;

                        totalHours += attRp.TotalHour;

                        totalHoursWithRate += attRp.WorkingHour * attRp.RegularRate / 100
                            + attRp.OvertimeHour1 * attRp.OvertimeRate1 / 100
                            + attRp.OvertimeHour2 * attRp.OvertimeRate2 / 100
                            + attRp.OvertimeHour3 * attRp.OvertimeRate3 / 100
                            + attRp.OvertimeHour4 * attRp.OvertimeRate4 / 100;

                        totalOvertimeHours += attRp.OvertimeHour1
                        + attRp.OvertimeHour2
                        + attRp.OvertimeHour3
                        + attRp.OvertimeHour4;

                        if (attRp.OvertimeHour1 > 0)
                        {
                            if (hOvertimeHour1.ContainsKey(attRp.OvertimeRate1))
                            {
                                double overtimeHour = (double)hOvertimeHour1[attRp.OvertimeRate1];
                                hOvertimeHour1[attRp.OvertimeRate1] = overtimeHour + attRp.OvertimeHour1;
                            }
                            else
                                hOvertimeHour1.Add(attRp.OvertimeRate1, attRp.OvertimeHour1);
                        }

                        if (attRp.OvertimeHour2 > 0)
                        {
                            if (hOvertimeHour2.ContainsKey(attRp.OvertimeRate2))
                            {
                                double overtimeHour = (double)hOvertimeHour2[attRp.OvertimeRate2];
                                hOvertimeHour2[attRp.OvertimeRate2] = overtimeHour + attRp.OvertimeHour2;
                            }
                            else
                                hOvertimeHour2.Add(attRp.OvertimeRate2, attRp.OvertimeHour2);
                        }

                        if (attRp.OvertimeHour3 > 0)
                        {
                            if (hOvertimeHour3.ContainsKey(attRp.OvertimeRate3))
                            {
                                double overtimeHour = (double)hOvertimeHour3[attRp.OvertimeRate3];
                                hOvertimeHour3[attRp.OvertimeRate3] = overtimeHour + attRp.OvertimeHour3;
                            }
                            else
                                hOvertimeHour3.Add(attRp.OvertimeRate3, attRp.OvertimeHour3);
                        }

                        if (attRp.OvertimeHour4 > 0)
                        {
                            if (hOvertimeHour4.ContainsKey(attRp.OvertimeRate4))
                            {
                                double overtimeHour = (double)hOvertimeHour4[attRp.OvertimeRate4];
                                hOvertimeHour4[attRp.OvertimeRate4] = overtimeHour + attRp.OvertimeHour4;
                            }
                            else
                                hOvertimeHour4.Add(attRp.OvertimeRate4, attRp.OvertimeHour4);
                        }
                    }

                    StringBuilder strOvertime = new StringBuilder();

                    foreach (DictionaryEntry item in hOvertimeHour1)
                        strOvertime.AppendFormat("{0} x {1}%\n", item.Value, item.Key);

                    foreach (DictionaryEntry item in hOvertimeHour2)
                        strOvertime.AppendFormat("{0} x {1}%\n", item.Value, item.Key);

                    foreach (DictionaryEntry item in hOvertimeHour3)
                        strOvertime.AppendFormat("{0} x {1}%\n", item.Value, item.Key);

                    foreach (DictionaryEntry item in hOvertimeHour4)
                        strOvertime.AppendFormat("{0} x {1}%\n", item.Value, item.Key);

                    overtimeHourAndRate = strOvertime.ToString();

                    AttendanceLogReport attendanceLogReport = attendanceLogReportListByEmpl[0];

                    payrollExport = new PayrollExport();

                    payrollExport.DateFrom = attendanceLogReportListByEmpl[0].WorkFrom;
                    payrollExport.DateTo = attendanceLogReportListByEmpl[attendanceLogReportListByEmpl.Count - 1].WorkFrom;

                    payrollExport.EmployeeNumber = emplNumber;
                    payrollExport.FullName = attendanceLogReport.FullName;
                    payrollExport.JobDescription = attendanceLogReport.JobDescription;
                    payrollExport.Department = attendanceLogReport.Department;
                    payrollExport.PayrollNumber = attendanceLogReport.PayrollNumber;
                    payrollExport.RegularHour = Math.Round(regularHours, 2);
                    payrollExport.OvertimeHour = overtimeHourAndRate;
                    payrollExport.TotalHours = Math.Round(totalHours, 2);
                    payrollExport.TotalHoursWithRate = Math.Round(totalHoursWithRate, 2);
                    payrollExport.TotalOvertimeHours = Math.Round(totalOvertimeHours, 2);
                    payrollExportList.Add(payrollExport);

                    hOvertimeHour1.Clear();
                    hOvertimeHour2.Clear();
                    hOvertimeHour3.Clear();
                    hOvertimeHour4.Clear();
                }
            }

            return payrollExportList;
        }