public List<AttendanceLogRecord> GetAttendanceLogRecordList(int iCompany, int iDepartment, DateTime beginDate, DateTime endDate, int columnIndex, bool isOrderByAcs)
        {
            List<AttendanceReport> attendanceReports = GetAttendanceReport(iCompany, iDepartment, beginDate, endDate, columnIndex, isOrderByAcs);
            if (attendanceReports.Count == 0)
                return null;

            List<string> lEmplNumbers = GetEmployeeNumberList(iCompany, iDepartment);
            if (lEmplNumbers == null || lEmplNumbers.Count == 0)
                return null;
            string sEmplNumbers = string.Join(",", lEmplNumbers.ToArray());

            OleDbCommand odCom = BuildSelectCmd("Employee", "EmployeeNumber, FirstName, LastName, PayrollNumber, JobDescription", "EmployeeNumber IN(" + sEmplNumbers + ") AND Active=TRUE");

            OleDbDataAdapter odApt = new OleDbDataAdapter(odCom);

            //TODO why don't use a List<Employee> here?
            DataTable dtEmpl = new DataTable();
            odApt.Fill(dtEmpl);

            List<AttendanceLogRecord> attLogList = new List<AttendanceLogRecord>();
            AttendanceLogRecord attLog = null;

            List<AttendanceRecord> attRecordList = new List<AttendanceRecord>();
            AttendanceRecord attRecord = null;

            foreach (AttendanceReport attReport in attendanceReports)
            {
                string sAttendanceRecordIDs = attReport.AttendanceRecordIDList;
                sAttendanceRecordIDs = sAttendanceRecordIDs.Replace("{", "").Replace("}", ",").Trim(',');

                //TODO List<AttendanceRecord> GetAttendanceRecordByAttendanceReport(int attendanceReportID, bool orderByTime)
                odCom = BuildSelectCmd("AttendanceRecord", "*", "ID IN(" + sAttendanceRecordIDs + ")");
                OleDbDataReader odRdr = odCom.ExecuteReader();

                attRecordList.Clear();
                while (odRdr.Read())
                {
                    attRecord = new AttendanceRecord();
                    attRecord.ID = (int)odRdr["ID"];
                    attRecord.EmployeeNumber = (int)odRdr["EmployeeNumber"];
                    attRecord.Note = odRdr["Note"].ToString();
                    //attRecord.PhotoData = odRdr["PhotoData"].ToString();
                    attRecord.Time = (DateTime)odRdr["Time"];
                    attRecordList.Add(attRecord);
                }
                odRdr.Close();

                attRecordList.Sort(delegate(AttendanceRecord e1, AttendanceRecord e2) { return e1.Time.CompareTo(e2.Time); });
                int roundValue = GetConfig().RecordRoundingValue;
                foreach (AttendanceRecord att in attRecordList)
                {
                    att.Time = Util.RoundDateTime(att.Time, roundValue);
                }

                bool isCheckIn = true;
                bool isFirst = true;

                DateTime dDateLog = attRecordList[0].Time.Date;
                foreach (AttendanceRecord att in attRecordList)
                {
                    attLog = new AttendanceLogRecord();
                    if (isFirst)
                    {
                        attLog.EmployeeNumber = attReport.EmployeeNumber;
                        attLog.DateLog = attReport.WorkFrom.Date;

                        //TODO wrong number, total hours here is based on the in/out, not report
                        //attLog.TotalHours = attReport.RegularHour + attReport.OvertimeHour1 + attReport.OvertimeHour2 + attReport.OvertimeHour3 + attReport.OvertimeHour4;
                        attLog.TotalHours = Math.Round(CalculateTotalHours(attRecordList), 2);

                        DataRow[] rdEmpl = dtEmpl.Select("EmployeeNumber=" + attReport.EmployeeNumber);
                        if (rdEmpl.Length > 0)
                            attLog.EmployeeName = rdEmpl[0]["LastName"] + ", " + rdEmpl[0]["FirstName"];
                        isFirst = false;
                    }

                    attLog.ID = att.ID;
                    attLog.TimeLog = (isCheckIn ? "In " : "Out ") + att.Time.ToString("HH:mm");
                    if (att.Time.Date.CompareTo(attReport.WorkFrom.Date) > 0)
                        attLog.TimeLog += " [" + att.Time.Date.ToShortDateString() + "]";
                    attLog.Note = att.Note;

                    attLogList.Add(attLog);

                    isCheckIn = !isCheckIn;
                }
                if (isCheckIn == false && dDateLog.Equals(DateTime.Now.Date) == false)
                {
                    attLog = new AttendanceLogRecord();
                    attLog.TimeLog = "OutMistakes";
                    attLogList.Add(attLog);
                }
            }
            return attLogList;
        }
        public List<AttendanceLogRecord> GetAttendanceLogRecordList(int iCompany, int iDepartment, DateTime beginDate, DateTime endDate, int columnIndex, bool isOrderByAcs)
        {
            List<AttendanceReport> attendanceReports = GetAttendanceReport(iCompany, iDepartment, beginDate, endDate, columnIndex, isOrderByAcs);
            if (attendanceReports.Count == 0)
                return null;

            List<string> lEmplNumbers = GetEmployeeNumberList(iCompany, iDepartment);
            if (lEmplNumbers == null || lEmplNumbers.Count == 0)
                return null;
            string sEmplNumbers = string.Join(",", lEmplNumbers.ToArray());

            OleDbCommand odCom = BuildSelectCmd("Employee", "EmployeeNumber, FirstName, LastName", "EmployeeNumber IN(" + sEmplNumbers + ") AND Active=TRUE");

            OleDbDataReader odRdr = odCom.ExecuteReader();

            List<Employee> employeeList = new List<Employee>();
            Employee empl;
            while (odRdr.Read())
            {
                empl = new Employee();
                empl.EmployeeNumber = (int)odRdr["EmployeeNumber"];
                empl.LastName = odRdr["LastName"].ToString();
                empl.FirstName = odRdr["FirstName"].ToString();
                employeeList.Add(empl);
            }
            odRdr.Close();

            List<AttendanceLogRecord> attLogList = new List<AttendanceLogRecord>();
            AttendanceLogRecord attLog = null;

            List<AttendanceRecord> attRecordList = new List<AttendanceRecord>();
            AttendanceRecord attRecord = null;

            foreach (AttendanceReport attReport in attendanceReports)
            {
                string sAttendanceRecordIDs = attReport.AttendanceRecordIDList;
                sAttendanceRecordIDs = sAttendanceRecordIDs.Replace("{", "").Replace("}", ",").Trim(',');

                odCom = BuildSelectCmd("AttendanceRecord", "*", "ID IN(" + sAttendanceRecordIDs + ")");
                odRdr = odCom.ExecuteReader();

                attRecordList.Clear();
                while (odRdr.Read())
                {
                    attRecord = new AttendanceRecord();
                    attRecord.ID = (int)odRdr["ID"];
                    attRecord.EmployeeNumber = (int)odRdr["EmployeeNumber"];
                    attRecord.Note = odRdr["Note"].ToString();
                    attRecord.Time = (DateTime)odRdr["Time"];
                    attRecordList.Add(attRecord);
                }
                odRdr.Close();

                attRecordList.Sort(delegate(AttendanceRecord e1, AttendanceRecord e2) { return e1.Time.CompareTo(e2.Time); });
                int roundValue = GetConfig().RecordRoundingValue;
                foreach (AttendanceRecord att in attRecordList)
                {
                    att.Time = Util.RoundDateTime(att.Time, roundValue);
                }

                bool isCheckIn = true;
                bool isFirst = true;

                DateTime dDateLog = attRecordList[0].Time.Date;
                foreach (AttendanceRecord att in attRecordList)
                {
                    attLog = new AttendanceLogRecord();
                    if (isFirst)
                    {
                        attLog.EmployeeNumber = attReport.EmployeeNumber;
                        attLog.DateLog = attReport.WorkFrom.Date;

                        //TODO wrong number, total hours here is based on the in/out, not report
                        attLog.TotalHours = Math.Round(CalculateTotalHours(attRecordList), 2);

                        Employee employee = employeeList.Find(delegate(Employee e) { return e.EmployeeNumber == attReport.EmployeeNumber; });

                        attLog.EmployeeName = employee.LastName + ", " + employee.FirstName;
                        isFirst = false;
                    }

                    attLog.ID = att.ID;
                    attLog.TimeLog = (isCheckIn ? "In " : "Out ") + att.Time.ToString("HH:mm");
                    if (att.Time.Date.CompareTo(attReport.WorkFrom.Date) > 0)
                        attLog.TimeLog += " [" + att.Time.Date.ToShortDateString() + "]";
                    attLog.Note = att.Note;

                    attLogList.Add(attLog);

                    isCheckIn = !isCheckIn;
                }

                if (isCheckIn == false && dDateLog.Equals(DateTime.Now.Date) == false)
                {
                    attLog = new AttendanceLogRecord();
                    //attLog.DateLog = attReport.WorkFrom.Date;
                    //attLog.EmployeeNumber = attReport.EmployeeNumber;
                    attLog.TimeLog = "OutMistakes";
                    attLogList.Add(attLog);
                }
            }

            List<RoostedDayOff> roostedDayOffList = GetRoostedDayOffList();
            Hashtable hasEmplName = new Hashtable();
            if (roostedDayOffList.Count > 0)
            {
                AttendanceLogRecord attRc = null;
                foreach (RoostedDayOff roostedDayOff in roostedDayOffList)
                {
                    string employeeName = null;
                    if (hasEmplName.ContainsKey(roostedDayOff.EmployeeNumber))
                    {
                        employeeName = (string)hasEmplName[roostedDayOff.EmployeeNumber];
                    }
                    else
                    {
                        Employee employee = GetEmployeeByEmployeeNumber(roostedDayOff.EmployeeNumber);
                        if (employee == null)
                            continue;

                        employeeName = employee.LastName + ", " + employee.FirstName;

                        hasEmplName.Add(roostedDayOff.EmployeeNumber, employeeName );
                    }

                    attRc = new AttendanceLogRecord();
                    attRc.EmployeeNumber = roostedDayOff.EmployeeNumber;
                    attRc.EmployeeName = employeeName;
                    attRc.DateLog = roostedDayOff.Date;
                    attRc.TotalHours= roostedDayOff.TotalHours;
                    attRc.TimeLog = "Roosted day off";
                    attRc.Note = roostedDayOff.Note;

                    int indexRp = attLogList.FindIndex(0, delegate(AttendanceLogRecord e) { return e.EmployeeNumber == attRc.EmployeeNumber && e.DateLog.Date.CompareTo(attRc.DateLog.Date) == 1; });
                    if (indexRp < 0)
                    {
                        indexRp = attLogList.FindLastIndex(delegate(AttendanceLogRecord e) { return e.EmployeeNumber == attRc.EmployeeNumber; });

                        if (indexRp < 0)
                        {
                            indexRp = attLogList.FindIndex(delegate(AttendanceLogRecord e) { return e.EmployeeNumber > attRc.EmployeeNumber; });

                            if (indexRp < 0)
                            {
                                indexRp = attLogList.Count;
                            }
                        }
                        else
                            indexRp++;
                    }

                    int indexRp_1 = 0;
                    while (true)
                    {
                        if (indexRp > attLogList.Count - 1)
                            break;
                        indexRp_1 = attLogList.FindIndex(indexRp, 1, delegate(AttendanceLogRecord e) { return e.DateLog.Equals(DateTime.MinValue); });
                        if (indexRp_1 < 1)
                            break;
                        indexRp++;
                    }

                    attLogList.Insert(indexRp, attRc);
                }
                hasEmplName.Clear();
                roostedDayOffList.Clear();
            }
            return attLogList;
        }