/*Note that this method is applicable to employees with hourly rate*/
        public void GenerateEmployeeDailySalaryByDateRange(DateTime dateFrom, DateTime dateTo)
        {
            //Delete existing by date range
            DeleteByDateRange(dateFrom, dateTo);

            IList <TotalEmployeeHours> totalEmployeeHours =
                _totalEmployeeHoursService.GetByDateRange(dateFrom, dateTo);

            Double restDayRate               = Double.Parse(_settingService.GetByKey(SettingValue.RATE_REST_DAY));
            Double OTRate                    = Double.Parse(_settingService.GetByKey(SettingValue.RATE_OT));
            Double nightDiffRate             = Double.Parse(_settingService.GetByKey(SettingValue.RATE_NIGHTDIF));
            Double holidayRegularRate        = Double.Parse(_settingService.GetByKey(SettingValue.RATE_HOLIDAY_REGULAR));
            Double holidaySpecialRate        = Double.Parse(_settingService.GetByKey(SettingValue.RATE_HOLIDAY_SPECIAL));
            Double OTRateHoliday             = Double.Parse(_settingService.GetByKey(SettingValue.RATE_OT_HOLIDAY));
            Double holidaySpecialRestDayRate = Double.Parse(_settingService.GetByKey(SettingValue.RATE_HOLIDAY_SPECIAL_REST_DAY));

            foreach (TotalEmployeeHours totalHours in totalEmployeeHours)
            {
                EmployeeInfo employeeInfo = _employeeInfoService.GetByEmployeeId(totalHours.EmployeeId);

                var hourlyRate = _employeeSalaryService.GetEmployeeHourlyRate(employeeInfo);

                var employeeWorkSchedule =
                    _employeeWorkScheduleService.GetByEmployeeId(totalHours.EmployeeId);

                //No work schedule, no computation
                if (employeeWorkSchedule != null)
                {
                    DateTime date           = totalHours.Date;
                    Double   rateMultiplier = 0;

                    var     workSchedule = employeeWorkSchedule.WorkSchedule;
                    var     isRestDay    = date.IsRestDay(workSchedule.WeekStart, workSchedule.WeekEnd);
                    Holiday holiday      = _holidayService.GetHoliday(date);

                    //Check if rest day and not special holiday
                    if (isRestDay &&
                        !(holiday != null && !holiday.IsRegularHoliday))
                    {
                        rateMultiplier *= restDayRate;
                    }

                    //Check if holiday
                    if (holiday != null)
                    {
                        if (holiday.IsRegularHoliday)
                        {
                            rateMultiplier *= holidayRegularRate;
                        }
                        else
                        {
                            if (isRestDay)
                            {
                                rateMultiplier *= holidaySpecialRestDayRate;
                            }
                            else
                            {
                                rateMultiplier *= holidaySpecialRate;
                            }
                        }
                    }
                    //if OT
                    if (totalHours.Type == RateType.OverTime)
                    {
                        //If holiday use holiday ot rate
                        if (holiday != null)
                        {
                            rateMultiplier *= OTRateHoliday;
                        }
                        else
                        {
                            rateMultiplier *= OTRate;
                        }
                    }

                    decimal totalPayment = 0;

                    //if NightDif
                    if (totalHours.Type == RateType.NightDifferential)
                    {
                        //rateMultiplier *= nightDiffRate;

                        /*if (rateMultiplier > 1)
                         * {
                         *  totalPayment = ((decimal)(totalHours.Hours * (rateMultiplier - 1)) * hourlyRate);
                         * }*/
                        totalPayment += (decimal)(nightDiffRate * totalHours.Hours * rateMultiplier);
                    }
                    else
                    {
                        totalPayment = ((decimal)(totalHours.Hours * rateMultiplier)) * hourlyRate;
                    }

                    var employeeDailySalary = new EmployeeDailyPayroll
                    {
                        EmployeeId           = totalHours.EmployeeId,
                        Date                 = totalHours.Date,
                        TotalPay             = totalPayment,
                        TotalEmployeeHoursId = totalHours.TotalEmployeeHoursId,
                        RateType             = totalHours.Type
                    };

                    //Save
                    _employeeDailyPayrollRepository.Add(employeeDailySalary);
                }
            }
            _unitOfWork.Commit();

            //Generate holiday pays
            GenerateEmployeeHolidayPay(dateFrom, dateTo);
            _unitOfWork.Commit();
        }
        public void GenerateEmployeeHolidayPay(DateTime payrollStartDate, DateTime payrollEndDate)
        {
            //Get all active employees
            IList <EmployeeInfo> employees = _employeeInfoService.GetAllActive();

            foreach (DateTime day in DatetimeExtension.EachDay(payrollStartDate, payrollEndDate))
            {
                //Check if holiday
                var  holiday = _holidayService.GetHoliday(day);
                bool isSpecialHolidayPaid = Convert.ToInt32(_settingService.GetByKey(SettingValue.PAYROLL_IS_SPHOLIDAY_WITH_PAY)) > 0;

                if (holiday != null && (holiday.IsRegularHoliday || isSpecialHolidayPaid))
                {
                    foreach (EmployeeInfo employee in employees)
                    {
                        WorkSchedule workSchedule = _employeeWorkScheduleService.GetByEmployeeId(employee.EmployeeId).WorkSchedule;

                        if (workSchedule != null)
                        {
                            //Check if within schedule
                            if (day.IsRestDay(workSchedule.WeekStart, workSchedule.WeekEnd))
                            {
                                //Don't proceed
                                continue;
                            }
                        }
                        else
                        {
                            //No work schedule, no holiday pay
                            continue;
                        }

                        //If with schedule on this date, generate holiday pay

                        //Check if already have daily entry
                        EmployeeDailyPayroll dailyPayroll = _employeeDailyPayrollRepository.GetByDate(employee.EmployeeId, day);

                        int workHours  = Convert.ToInt32(_settingService.GetByKey(SettingValue.PAYROLL_REGULAR_HOURS));
                        var hourlyRate = _employeeSalaryService.GetEmployeeHourlyRate(employee);

                        //If null create a holiday pay
                        if (dailyPayroll == null)
                        {
                            EmployeeDailyPayroll newDailyPayroll = new EmployeeDailyPayroll
                            {
                                EmployeeId = employee.EmployeeId,
                                Date       = day,
                                TotalPay   = hourlyRate * workHours,
                                //RateType = RateType.
                            };

                            _employeeDailyPayrollRepository.Add(newDailyPayroll);
                        }
                        else
                        {
                            //If existing create new for remaining unpaid hours
                            //if total hours worked is less than regular working hours
                            //Get total hours worked
                            IList <TotalEmployeeHours> employeeHours =
                                _totalEmployeeHoursService.GetByTypeAndDateRange(employee.EmployeeId, null, payrollStartDate, payrollEndDate);
                            var totalEmployeeHours = employeeHours.Sum(h => h.Hours);
                            if (totalEmployeeHours < workHours)
                            {
                                var remainingUnpaidHours =
                                    Convert.ToDecimal(workHours - totalEmployeeHours);

                                EmployeeDailyPayroll newDailyPayroll = new EmployeeDailyPayroll
                                {
                                    EmployeeId = employee.EmployeeId,
                                    Date       = day,
                                    TotalPay   = hourlyRate * remainingUnpaidHours,
                                    //RateType = RateType.Holiday
                                };
                                _employeeDailyPayrollRepository.Add(newDailyPayroll);
                            }
                        }
                    }
                }
            }
        }