3259 lines
170 KiB
C#
3259 lines
170 KiB
C#
using Ease.Core.DataAccess;
|
|
using Ease.Core.Model;
|
|
using HRM.BO;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Data;
|
|
using System.Threading;
|
|
using NPOI.SS.Formula.Functions;
|
|
|
|
namespace HRM.DA
|
|
{
|
|
public class AttendanceProcess
|
|
{
|
|
#region Declaration
|
|
|
|
//public event System.EventHandler RefreshStatus;
|
|
//List<Employee> _employees = null;
|
|
//List<MonthlyWorkPlan> _monthlyWorkPlans = null;
|
|
List<AttnNationalHoliday> _AttNHolidays = null;
|
|
EnumWorkPlanGroup _empWPtype = EnumWorkPlanGroup.Fixed;
|
|
List<AttnMonthlyBenefit> _atnMonthlyBenifits = null;
|
|
DateTime Attdate = DateTime.MinValue;
|
|
AttnProcessRunSummary _attnRunSummary;
|
|
List<Shift> shifts = null;
|
|
List<Shift> _shifts = null;
|
|
|
|
List<Employee> employees = null;
|
|
double _lateHour, _earlyHour, _oTHour;
|
|
Employee employee = null;
|
|
AttnParametarization _AttnParam = null;
|
|
DailyAttnProcess _DailyAttnProcess = null;
|
|
#endregion
|
|
|
|
#region Private functions
|
|
|
|
private EnumAttendanceType GetAttnType(DateTime empInTime, DateTime empOutTime, Shift shift, DateTime attnDate,
|
|
MonthlyWorkPlan empMonthlyWorkPlan)
|
|
{
|
|
EnumAttendanceType attntype = EnumAttendanceType.Present;
|
|
DateTime shiftInTime = attnDate.Subtract(attnDate.TimeOfDay).Add(shift.InTime.TimeOfDay);
|
|
|
|
DateTime shiftOutTime = DateTime.MinValue;
|
|
DateTime shiftOutTimeWithMinimumOT = DateTime.MinValue;
|
|
double _oTHour = 0;
|
|
|
|
if (shift.InTime <= shift.OutTime)
|
|
{
|
|
shiftOutTime = attnDate.Subtract(attnDate.TimeOfDay).Add(shift.OutTime.TimeOfDay);
|
|
shiftOutTimeWithMinimumOT = attnDate.Subtract(attnDate.TimeOfDay).Add(shift.OutTime.TimeOfDay)
|
|
.AddMinutes(shift.MinimumOutOTHour);
|
|
}
|
|
else
|
|
{
|
|
shiftOutTime = attnDate.AddDays(1).Subtract(attnDate.TimeOfDay).Add(shift.OutTime.TimeOfDay);
|
|
shiftOutTimeWithMinimumOT = attnDate.AddDays(1).Subtract(attnDate.TimeOfDay)
|
|
.Add(shift.OutTime.TimeOfDay).AddMinutes(shift.MinimumOutOTHour);
|
|
}
|
|
|
|
// DateTime shiftInTimeWithLatehour = attnDate.Subtract(attnDate.TimeOfDay).Add(shift.InTime.TimeOfDay).AddMinutes(shift.LateCalcualtion);
|
|
|
|
|
|
if (empMonthlyWorkPlan.Type != EnumWorkPlanDayType.WorkingDay)
|
|
{
|
|
TimeSpan OTHour = empOutTime.Subtract(empInTime);
|
|
_oTHour = Convert.ToDouble(OTHour.Hours) +
|
|
(Convert.ToDouble(OTHour.Minutes) >= Convert.ToDouble(shift.MinimumOutOTHour) ? 1 : 0);
|
|
//For Launch break
|
|
if (_oTHour > 6)
|
|
{
|
|
_oTHour = _oTHour - 1;
|
|
}
|
|
|
|
OTHour = empOutTime.Subtract(empOutTime);
|
|
// for fixed group employee, night 1 am to 2 pm is rest time, so this one hour will be not included in overtime.
|
|
if (_empWPtype == EnumWorkPlanGroup.Fixed && empInTime.Date > empOutTime.Date && empOutTime.Hour >= 1 &&
|
|
empOutTime.Minute >= shift.MinimumOutOTHour)
|
|
{
|
|
_oTHour = _oTHour - 1;
|
|
}
|
|
|
|
if (empMonthlyWorkPlan.Type == EnumWorkPlanDayType.NationalHoliday)
|
|
{
|
|
attntype = EnumAttendanceType.Holiday;
|
|
}
|
|
else if (empMonthlyWorkPlan.Type == EnumWorkPlanDayType.WeeklyHoliday)
|
|
{
|
|
attntype = EnumAttendanceType.WeeklyHoliday;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (empOutTime > shiftOutTimeWithMinimumOT)
|
|
{
|
|
TimeSpan OTHour = empOutTime.Subtract(shiftOutTime);
|
|
_oTHour = Convert.ToDouble(OTHour.Hours) +
|
|
(Convert.ToDouble(OTHour.Minutes) >= Convert.ToDouble(shift.MinimumOutOTHour) ? 1 : 0);
|
|
}
|
|
}
|
|
|
|
if (_oTHour < 0) _oTHour = 0;
|
|
|
|
|
|
return attntype;
|
|
}
|
|
|
|
private void CalcullateWorkdayType(DailyAttnProcess attnProcess, EmployeeWorkPlanSetup oEmpWorkplan,
|
|
WorkPlanGroup oEmpWPlanGroup, int payrollTypeID)
|
|
{
|
|
//List<ShiftRotation> oShiftRotations = null;
|
|
//oShiftRotations = ShiftRotation.Get(oEmpWPlanGroup.Type);
|
|
attnProcess.WorkDayType = EnumWorkPlanDayType.WorkingDay;
|
|
|
|
if (_AttNHolidays == null)
|
|
{
|
|
DateTime oLastDate = attnProcess.AttnDate.LastDateOfMonth();
|
|
DateTime oFirstDate = attnProcess.AttnDate.FirstDateOfMonth();
|
|
_AttNHolidays =
|
|
new AttnNationalHolidayService().GetByMonthAndPayrollType(oFirstDate, oLastDate, payrollTypeID);
|
|
}
|
|
|
|
AttnNationalHoliday oAttNHoliday = _AttNHolidays.Where(o =>
|
|
attnProcess.AttnDate.Date >= o.FromDate.Date && attnProcess.AttnDate.Date <= o.ToDate.Date)
|
|
.FirstOrDefault();
|
|
if (oAttNHoliday != null)
|
|
{
|
|
attnProcess.WorkDayType = EnumWorkPlanDayType.NationalHoliday;
|
|
attnProcess.ReferenceID = oAttNHoliday.ID;
|
|
return;
|
|
}
|
|
|
|
if (oEmpWPlanGroup.Type == EnumWorkPlanGroup.Fixed)
|
|
{
|
|
if ((oEmpWorkplan.WeekEndOn != null && attnProcess.AttnDate.DayOfWeek == (DayOfWeek)oEmpWorkplan.WeekEndOn)
|
|
|| (oEmpWorkplan.WeekEndOn2 != null && attnProcess.AttnDate.DayOfWeek == (DayOfWeek)oEmpWorkplan.WeekEndOn2))
|
|
{
|
|
attnProcess.WorkDayType = EnumWorkPlanDayType.WeeklyHoliday;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (oEmpWorkplan.WeekEndOn != null)
|
|
{
|
|
if (attnProcess.AttnDate.DayOfWeek == (DayOfWeek)oEmpWorkplan.WeekEndOn)
|
|
//if (attnProcess.AttnDate.DayOfWeek == (DayOfWeek)(((int)oEmpWorkplan.WeekEndOn + 1) % 7))
|
|
{
|
|
DayOfWeek DayOfWeekValue = (DayOfWeek)(((int)oEmpWorkplan.WeekEndOn + 1) % 7);
|
|
attnProcess.WorkDayType = EnumWorkPlanDayType.WeeklyHoliday;
|
|
}
|
|
}
|
|
//if ((oEmpWorkplan.HolidayOne != null &&
|
|
// attnProcess.AttnDate.DayOfWeek == (DayOfWeek)oEmpWorkplan.HolidayOne)
|
|
// || (oEmpWorkplan.HolidayTwo != null &&
|
|
// attnProcess.AttnDate.DayOfWeek == (DayOfWeek)oEmpWorkplan.HolidayTwo))
|
|
//{
|
|
// if (attnProcess.AttnDate.DayOfWeek == (DayOfWeek)oEmpWorkplan.HolidayOne)
|
|
// {
|
|
// attnProcess.WorkDayType = EnumWorkPlanDayType.WeeklyHoliday;
|
|
// }
|
|
//}
|
|
else
|
|
{
|
|
attnProcess.WorkDayType = AutoRotationHolidayCalc(oEmpWorkplan, attnProcess.AttnDate);
|
|
//if (attnProcess.AttnDate >= oEmpWorkplan.CreatedDate)
|
|
//{
|
|
// int nShiftInterval = 7;
|
|
// TimeSpan st = attnProcess.AttnDate - oEmpWorkplan.CreatedDate;
|
|
// int dayCount = st.Days;
|
|
// int nCircleDay = (dayCount % nShiftInterval);
|
|
|
|
// if ((nShiftInterval - nCircleDay - 1) == 0)
|
|
// {
|
|
// attnProcess.WorkDayType = EnumWorkPlanDayType.WeeklyHoliday;
|
|
// }
|
|
//}
|
|
}
|
|
}
|
|
}
|
|
public static EnumWorkPlanDayType AutoRotationHolidayCalc(EmployeeWorkPlanSetup oEmpWorkplan, DateTime targetDate)
|
|
{
|
|
EnumWorkPlanDayType oEnumWPDayType = EnumWorkPlanDayType.WorkingDay;
|
|
if (targetDate >= oEmpWorkplan.StartDate)
|
|
{
|
|
int nShiftInterval = 7;
|
|
TimeSpan st = targetDate - oEmpWorkplan.StartDate;
|
|
int dayCount = st.Days;
|
|
int nCircleDay = (dayCount % nShiftInterval);
|
|
|
|
if ((nShiftInterval - nCircleDay - 1) == 0)
|
|
{
|
|
oEnumWPDayType = EnumWorkPlanDayType.WeeklyHoliday;
|
|
}
|
|
|
|
}
|
|
|
|
return oEnumWPDayType;
|
|
}
|
|
//private void CalcullateOT(DailyAttnProcess attnProcess, Shift oshift, DateTime Attdate)
|
|
//{
|
|
// attnProcess.OTHour = 0;
|
|
|
|
// DateTime actualInTime = (DateTime)attnProcess.InTime;
|
|
// DateTime actualOutTime = (DateTime)attnProcess.OutTime;
|
|
// DateTime shiftInTime = ((DateTime)attnProcess.InTime).Date.Add(oshift.InTime.TimeOfDay);
|
|
// DateTime shiftOutTime = ((DateTime)attnProcess.InTime).Date.Add(oshift.OutTime.TimeOfDay);
|
|
// if (shiftOutTime < shiftInTime)
|
|
// {
|
|
// shiftOutTime = shiftOutTime.AddDays(1);
|
|
// }
|
|
|
|
// double standardHourWorked = shiftOutTime.Subtract(shiftInTime).TotalHours;
|
|
// double actualHourWorked = actualOutTime.Subtract(actualInTime).TotalHours;
|
|
|
|
// if (attnProcess.WorkDayType == EnumWorkPlanDayType.WorkingDay)
|
|
// {
|
|
// if (actualHourWorked > standardHourWorked)
|
|
// {
|
|
// double minutesBeforeShiftTime = 0;
|
|
// double minutesAfterShiftTime = 0;
|
|
// double inOTMinutes, outOTMinutes;
|
|
// inOTMinutes = outOTMinutes = 0;
|
|
|
|
// if (actualInTime < shiftInTime)
|
|
// {
|
|
// minutesBeforeShiftTime = shiftInTime.Subtract(actualInTime).TotalMinutes;
|
|
// var minimumOtInMinutes = oshift.MinimumInOTHour;
|
|
|
|
// if (minutesBeforeShiftTime > minimumOtInMinutes)
|
|
// {
|
|
// inOTMinutes = minutesBeforeShiftTime;
|
|
// }
|
|
// }
|
|
|
|
// if ((actualHourWorked * 60.0) - (standardHourWorked * 60.0) > minutesBeforeShiftTime)
|
|
// {
|
|
// minutesAfterShiftTime = (actualHourWorked * 60.0) - (standardHourWorked * 60.0) -
|
|
// minutesBeforeShiftTime;
|
|
// var minimumOtOutMinutes = oshift.MinimumOutOTHour;
|
|
|
|
// if (minutesAfterShiftTime > minimumOtOutMinutes)
|
|
// {
|
|
// outOTMinutes = minutesAfterShiftTime;
|
|
// }
|
|
// }
|
|
|
|
// if (inOTMinutes + outOTMinutes > 0)
|
|
// {
|
|
// attnProcess.OTHour = (inOTMinutes + outOTMinutes) / 60.0;
|
|
// }
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// //For Launch break
|
|
// if (actualHourWorked > 6 && oshift.LunchHour > 0)
|
|
// {
|
|
// actualHourWorked -= (oshift.LunchHour / 60.0);
|
|
// }
|
|
|
|
// attnProcess.OTHour = actualHourWorked;
|
|
// }
|
|
|
|
// if (attnProcess.OTHour < 0)
|
|
// {
|
|
// attnProcess.OTHour = 0;
|
|
// }
|
|
//}
|
|
private void CalcullateOT(bool isOtEligible, DailyAttnProcess attnProcess, Shift oshift, DateTime Attdate)
|
|
{
|
|
// all in one
|
|
attnProcess.OTHour = 0;
|
|
// it will calculate total working hour
|
|
if (attnProcess.InTime != null && attnProcess.OutTime != null)
|
|
{
|
|
attnProcess.OTHour = 0;
|
|
|
|
DateTime actualInTime = (DateTime)attnProcess.InTime;
|
|
DateTime actualOutTime = (DateTime)attnProcess.OutTime;
|
|
|
|
DateTime shiftInTime = ((DateTime)attnProcess.InTime).Date.Add(oshift.InTime.TimeOfDay);
|
|
DateTime shiftOutTime = ((DateTime)attnProcess.InTime).Date.Add(oshift.OutTime.TimeOfDay);
|
|
|
|
|
|
if (shiftOutTime < shiftInTime)
|
|
{
|
|
shiftOutTime = shiftOutTime.AddDays(1);
|
|
}
|
|
|
|
double standardHourWorked = shiftOutTime.Subtract(shiftInTime).TotalHours;
|
|
double actualHourWorked = actualOutTime.Subtract(actualInTime).TotalHours;
|
|
if (isOtEligible)
|
|
{
|
|
if (attnProcess.WorkDayType == EnumWorkPlanDayType.WorkingDay)
|
|
{
|
|
#region working day
|
|
|
|
double minutesBeforeShiftTime = 0;
|
|
double minutesAfterShiftTime = 0;
|
|
double inOTMinutes, outOTMinutes;
|
|
inOTMinutes = outOTMinutes = 0;
|
|
|
|
if (actualInTime < shiftInTime)
|
|
{
|
|
minutesBeforeShiftTime = shiftInTime.Subtract(actualInTime).TotalMinutes;
|
|
var minimumOtInMinutes = oshift.MinimumInOTHour;
|
|
|
|
if (minutesBeforeShiftTime > minimumOtInMinutes)
|
|
{
|
|
inOTMinutes = minutesBeforeShiftTime;
|
|
}
|
|
}
|
|
|
|
if (shiftOutTime < actualOutTime)
|
|
{
|
|
minutesAfterShiftTime = actualOutTime.Subtract(shiftOutTime).TotalMinutes;
|
|
var minimumOtOutMinutes = oshift.MinimumOutOTHour;
|
|
|
|
if (minutesAfterShiftTime > minimumOtOutMinutes)
|
|
{
|
|
outOTMinutes = minutesAfterShiftTime;
|
|
}
|
|
}
|
|
|
|
if (inOTMinutes + outOTMinutes > 0)
|
|
{
|
|
attnProcess.OTHour = (inOTMinutes + outOTMinutes);
|
|
attnProcess.OTHour = Math.Round(Math.Floor(attnProcess.OTHour / 60) +
|
|
((attnProcess.OTHour % 60) / 100),2);
|
|
}
|
|
#endregion working day
|
|
}
|
|
else
|
|
{
|
|
double tempactualHourWorked = actualOutTime.Subtract(actualInTime).TotalHours;
|
|
actualHourWorked -= oshift.LunchHour ;
|
|
attnProcess.OTHour = Math.Round(Math.Floor(actualHourWorked / 60) +
|
|
((actualHourWorked % 60) / 100), 2);
|
|
}
|
|
if (attnProcess.OTHour < 0)
|
|
attnProcess.OTHour = 0;
|
|
}
|
|
}
|
|
//only for lifung
|
|
attnProcess.OTHour = 0;
|
|
if (attnProcess.WorkHour > 8) attnProcess.OTHour = Math.Round( attnProcess.WorkHour - 8,2);
|
|
}
|
|
private void CalcullateOTEchoTex(bool isOtEligible, DailyAttnProcess attnProcess, Shift oshift, DateTime Attdate, bool _IsOTFractionate)
|
|
{
|
|
double _oTHour = 0;
|
|
attnProcess.OTHour = 0;
|
|
if (isOtEligible == false || (attnProcess.InTime == DateTime.MinValue || attnProcess.InTime == null) || (attnProcess.OutTime == DateTime.MinValue || attnProcess.OutTime == null))
|
|
{
|
|
return;
|
|
}
|
|
|
|
DateTime shiftInTime = (DateTime)attnProcess.InTime;
|
|
DateTime originalShiftInTime = Attdate.Subtract(Attdate.TimeOfDay).Add(oshift.InTime.TimeOfDay);
|
|
|
|
// if anyone comes early than shift time
|
|
// then that will not be considderred in OT
|
|
if (originalShiftInTime > shiftInTime)
|
|
{
|
|
shiftInTime = originalShiftInTime;
|
|
}
|
|
|
|
DateTime shiftOutTime = (DateTime)attnProcess.OutTime;
|
|
DateTime originalShiftOutTime = DateTime.MinValue;
|
|
TimeSpan shiftTimeDifference = new TimeSpan(0);
|
|
TimeSpan shiftTotalTimeWithMinimumOT = new TimeSpan(0);
|
|
|
|
if (oshift.InTime.TimeOfDay > oshift.OutTime.TimeOfDay)
|
|
{
|
|
originalShiftOutTime = originalShiftInTime.Date.AddDays(1).Add(oshift.OutTime.TimeOfDay);
|
|
}
|
|
else
|
|
{
|
|
originalShiftOutTime = originalShiftInTime.Date.Add(oshift.OutTime.TimeOfDay);
|
|
}
|
|
|
|
shiftTimeDifference = originalShiftOutTime - originalShiftInTime;
|
|
|
|
shiftTotalTimeWithMinimumOT = shiftTimeDifference.Add(TimeSpan.FromMinutes(oshift.MinimumOTHour));
|
|
|
|
TimeSpan OTHour = TimeSpan.FromHours(0);
|
|
|
|
if (attnProcess.WorkDayType != EnumWorkPlanDayType.WorkingDay)
|
|
{
|
|
OTHour = attnProcess.OutTime.Value.Subtract((DateTime)attnProcess.InTime);
|
|
}
|
|
else
|
|
{
|
|
if (shiftOutTime.Subtract(shiftInTime).TotalHours > shiftTotalTimeWithMinimumOT.TotalHours)
|
|
{
|
|
OTHour = shiftOutTime.Subtract(shiftInTime) - shiftTimeDifference;
|
|
}
|
|
}
|
|
|
|
// Normal OT Calcullation
|
|
//_oTHour = Convert.ToDouble(OTHour.Hours) + (Convert.ToDouble(OTHour.Minutes) >= Convert.ToDouble(oshift.MinimumOTHour) ?
|
|
// (_IsOTFractionate? (Convert.ToDouble(OTHour.Minutes)/60) : 1)
|
|
// : 0);
|
|
|
|
// Echo OT Calcullation
|
|
_oTHour = OTHour.Hours;
|
|
|
|
if (Convert.ToDouble(OTHour.Minutes) >= Convert.ToDouble(oshift.MinimumOTHour))
|
|
{
|
|
if (_IsOTFractionate)
|
|
{
|
|
_oTHour += (60 - Convert.ToDouble(oshift.MinimumOTHour)) > Convert.ToDouble(OTHour.Minutes) ? (Convert.ToDouble(OTHour.Minutes) / 60) : 1;
|
|
}
|
|
else
|
|
{
|
|
_oTHour += 1;
|
|
}
|
|
}
|
|
// Echo OT Calcullation End
|
|
|
|
if (_oTHour < 0) _oTHour = 0;
|
|
|
|
attnProcess.OTHour = _oTHour;
|
|
}
|
|
#endregion
|
|
|
|
public void MobileDataThreadProcess(List<AttnMobileRawData> offlineData)
|
|
{
|
|
if (offlineData == null || offlineData.Count == 0)
|
|
return;
|
|
|
|
var Groupdate =
|
|
from dateGroup in offlineData
|
|
group dateGroup by dateGroup.AttnDate;
|
|
|
|
Employee oemp = new EmployeeService().Get(offlineData[0].EmpID);
|
|
List<Employee> emps = new List<Employee>();
|
|
emps.Add(oemp);
|
|
User ouser = new UserService().Get(oemp.EmployeeNo);
|
|
foreach(var item in Groupdate)
|
|
{
|
|
Thread myNewThread = new Thread(() => Process(item.Key,
|
|
EnumProcessMode.Auto, oemp.PayrollTypeID, ouser.ID, emps));
|
|
myNewThread.Start();
|
|
|
|
}
|
|
|
|
//Thread myNewThread = new Thread(() => SendMail(oTran));
|
|
//myNewThread.Start();
|
|
|
|
}
|
|
|
|
|
|
#region Public Functions
|
|
public void Process(DateTime ProcessDate, EnumProcessMode prMode, int payrollTypeID, int processUserID)
|
|
{
|
|
DateTime endDate = DateTime.Today.Date;
|
|
List<Employee> emp = new EmployeeService().Get(EnumEmployeeStatus.Regardless, payrollTypeID);
|
|
_shifts = new ShiftService().GetAllShift();
|
|
for (DateTime currentDate = ProcessDate; currentDate <= endDate; currentDate = currentDate.AddDays(1))
|
|
{
|
|
Process(currentDate, EnumProcessMode.Auto, payrollTypeID, processUserID, emp);
|
|
}
|
|
}
|
|
|
|
public void Process(DateTime fromDate, EnumProcessMode prMode, int payrollTypeID, int processUserID, List<Employee> emps)
|
|
{
|
|
bool isEchoTex = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "attendence", "echotexprocess");
|
|
if (isEchoTex == true)
|
|
{
|
|
echoTexProcess(fromDate, prMode, payrollTypeID, processUserID, emps);
|
|
return;
|
|
}
|
|
_attnRunSummary = new AttnProcessRunSummary();
|
|
_attnRunSummary.ProcessMode = prMode;
|
|
// bool isInOutApplicable = false;
|
|
|
|
_shifts = _shifts ?? new ShiftService().GetAllShift();
|
|
|
|
string msg = "";
|
|
try
|
|
{
|
|
#region Initialization for Attendence Process
|
|
|
|
Attdate = fromDate;
|
|
// isInOutApplicable = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "attendence", "inoutapplicable");
|
|
|
|
List<DailyAttnProcess> dailyattProcesses = new List<DailyAttnProcess>();
|
|
List<DailyAttendanceAllowance> dailyAttendanceAllowances = new List<DailyAttendanceAllowance>();
|
|
|
|
List<EmpFieldTrack> oEmpFieldTracks = new List<EmpFieldTrack>();
|
|
|
|
DateTime startTime = new DateTime(Attdate.Year, Attdate.Month, Attdate.Day, 5, 20, 0);
|
|
DateTime ToTime = Attdate.AddDays(1);
|
|
ToTime = new DateTime(ToTime.Year, ToTime.Month, ToTime.Day, 10, 0, 0);
|
|
LeaveEntry empLeaveEntry = null;
|
|
List<ActingResponsibilitySetup> _tempraryShifts = new ActingResponsibilitySetupService().GetTemporaryShiftEmployee(Attdate);
|
|
List<EmployeeWorkPlanSetup> empWPGroups = new EmployeeWorkPlanSetupService().Get();
|
|
|
|
List<DailyAttnProcess> manualAttnProcesses = null;
|
|
List<SearchEmployee> _employees = emps !=null? Employee.getSearchEmp(emps): null;
|
|
if (emps == null || emps.Count == 0)
|
|
{
|
|
SearchManager omg = new SearchManager();
|
|
omg.SearchFrom = EnumSearchFrom.Employee;
|
|
omg.Parameter.AddDefaultParameter(payrollTypeID, EnumEmployeeStatus.Live);
|
|
omg.Parameter.Add(EnumSearchParameter.JoiningDate, EnumSQLOperator.SmallerThan,
|
|
EnumSearchObjDataType.Date, Attdate.AddDays(1));
|
|
_employees = new SearchEmployeeService().Find(omg);
|
|
}
|
|
List<Employee> discontinueEmps = new EmployeeService().GetDiscontinueEmp(Attdate, DateTime.Now, payrollTypeID);
|
|
DateTime oLastDate = fromDate;
|
|
DateTime oFirstDate = fromDate;
|
|
_AttNHolidays = new AttnNationalHolidayService().GetByMonthAndPayrollType(oFirstDate, oLastDate, payrollTypeID);
|
|
List<AttnRawData> attRawdata = new AttnRawDataService().Get(startTime, ToTime, payrollTypeID);// get raw data by a date and order by date, employee, punchTime
|
|
List<EmployeeOutsideDuty> outSideDuties = new EmployeeOutsideDutyService().Get(Attdate); // get transaction by the a rate
|
|
List<LeaveEntry> leaves = new LeaveEntryService().Get(Attdate); // workplans by the date
|
|
List<LeaveParameter> lvParameters = new LeaveParameterService().Get(EnumStatus.Regardless, payrollTypeID, null, false);
|
|
|
|
if (discontinueEmps != null && discontinueEmps.Count > 0)
|
|
{
|
|
foreach (Employee emp in discontinueEmps)
|
|
{
|
|
if (_employees.Any(x => x.ID == emp.ID) == false)
|
|
_employees.Add(emp.getSearchEmployee());
|
|
}
|
|
}
|
|
|
|
manualAttnProcesses = new DailyAttnProcessService().GetManualProcess(payrollTypeID, Attdate);
|
|
if (_employees.Count == 1)
|
|
{
|
|
manualAttnProcesses.RemoveAll(o => o.EmployeeID != _employees[0].ID);
|
|
}
|
|
|
|
foreach (DailyAttnProcess item in manualAttnProcesses)
|
|
{
|
|
//if (leaves != null && leaves.Count > 0)
|
|
//{
|
|
// if (item.AttenType == EnumAttendanceType.Leave)
|
|
// {
|
|
// empLeaveEntry = leaves.Where(lv => lv.EmpID == item.EmployeeID).FirstOrDefault();
|
|
// item.leaveEntry = empLeaveEntry;
|
|
// }
|
|
//}
|
|
dailyattProcesses.Add(item);
|
|
}
|
|
List<MonthlyWorkPlan> monthlyWorkPlans = new MonthlyWorkPlanService().GetByDate(Attdate, payrollTypeID);
|
|
#endregion
|
|
if (monthlyWorkPlans == null || monthlyWorkPlans.Count == 0)
|
|
{
|
|
throw new Exception("Monthly work plan is not yet set for the selected date of month.");
|
|
}
|
|
|
|
foreach (SearchEmployee emp in _employees)
|
|
{
|
|
Shift oshift = null;
|
|
|
|
msg = emp.EmployeeNo + " " + emp.Name + " Date:" + Attdate.ToString(" dd MMM yy");
|
|
#region EmployeeWise Setup
|
|
// 1. If Joining date is after Attendendence date then no attendence
|
|
|
|
// if (emp.JoiningDate > Attdate) continue;
|
|
|
|
var manualEntry = manualAttnProcesses.Where(obj => obj.EmployeeID == emp.ID).ToList();
|
|
if (manualEntry.Count > 0) continue; //####
|
|
|
|
DailyAttnProcess attnProcess = new DailyAttnProcess();
|
|
attnProcess.SearchEmployee = emp;
|
|
attnProcess.CreatedBy = processUserID;
|
|
attnProcess.CreatedDate = DateTime.Today;
|
|
attnProcess.AttnDate = Attdate;
|
|
attnProcess.EmployeeID = emp.EmployeeID;
|
|
attnProcess.IsManualEntry = false;
|
|
_lateHour = 0; _earlyHour = 0; _oTHour = 0;
|
|
|
|
List<AttnRawData> empAttnData = null;
|
|
EmployeeOutsideDuty empOutsideDuty = null;
|
|
|
|
if (attRawdata != null && attRawdata.Count > 0)
|
|
empAttnData = attRawdata.Where(erd => erd.EmployeeID == emp.ID).OrderBy(erd => erd.PunchTime).ToList();
|
|
if (outSideDuties != null && outSideDuties.Count > 0)
|
|
empOutsideDuty = outSideDuties.Where(od => od.EmployeeID == emp.ID).FirstOrDefault();
|
|
if (leaves != null && leaves.Count > 0)
|
|
empLeaveEntry = leaves.Where(lv => lv.EmpID == emp.ID).FirstOrDefault();
|
|
|
|
|
|
EmployeeWorkPlanSetup oEmpWorkplan = empWPGroups.Where(oGr => oGr.EmployeeID == emp.ID).FirstOrDefault();
|
|
|
|
// 3. If There is no EmployeeWorkPlanSetup then no attendence
|
|
//if (oEmpWorkplan == null)
|
|
//{
|
|
// continue;
|
|
// //throw new Exception("Employee Work-Group is not Defined for " + emp.Name + " (" + emp.EmployeeNo + ")");
|
|
//}
|
|
|
|
// WorkPlanGroup oEmpWPlanGroup = workPlanGroups.Where(o => o.ID.Integer == oEmpWorkplan.WorkPlanGroupID.Integer).Single();
|
|
|
|
#endregion
|
|
|
|
#region Calcullate ShiftID and WorkPlan Day Type
|
|
|
|
MonthlyWorkPlan mplan = null;
|
|
ActingResponsibilitySetup tempShiftEmployee = _tempraryShifts.Where(o => o.EmployeeID == attnProcess.EmployeeID).FirstOrDefault();
|
|
mplan = GetPlanwithEmployee(Attdate, emp.EmployeeID, empWPGroups, monthlyWorkPlans, null);
|
|
if(emp.EmployeeNo=="BP0010")
|
|
{
|
|
}
|
|
attnProcess.MonthlyWorkPlan = mplan;
|
|
if (attnProcess.MonthlyWorkPlan != null)
|
|
{
|
|
attnProcess.ShiftID = mplan.ShiftID;
|
|
attnProcess.Shift = _shifts.FirstOrDefault(x => x.ID == mplan.ShiftID);
|
|
attnProcess.WorkDayType = mplan.Type;
|
|
attnProcess.ActualShiftID = null;
|
|
if (tempShiftEmployee != null)
|
|
{
|
|
// set original shift into the temporary shiftt
|
|
if (tempShiftEmployee.ShiftID == null)
|
|
{
|
|
attnProcess.ActualShiftID = attnProcess.ShiftID;
|
|
mplan = GetPlanwithEmployee(Attdate, emp.ID, empWPGroups, monthlyWorkPlans, tempShiftEmployee);
|
|
attnProcess.ShiftID = mplan.ShiftID;
|
|
}
|
|
else
|
|
{
|
|
attnProcess.ActualShiftID = attnProcess.ShiftID;
|
|
attnProcess.ShiftID = tempShiftEmployee.ShiftID;
|
|
}
|
|
|
|
if (tempShiftEmployee.IsHoliday)
|
|
{
|
|
_earlyHour = 0;
|
|
_lateHour = 0;
|
|
attnProcess.InTime = null;
|
|
attnProcess.OutTime = null;
|
|
attnProcess.IsLate = false;
|
|
attnProcess.EarlyHour = 0;
|
|
attnProcess.LateHour = 0;
|
|
attnProcess.WorkDayType = EnumWorkPlanDayType.WeeklyHoliday;
|
|
}
|
|
else
|
|
{
|
|
attnProcess.WorkDayType = EnumWorkPlanDayType.WorkingDay;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Absent;
|
|
attnProcess.Comments = "Roster is not yet assigned.";
|
|
dailyattProcesses.Add(attnProcess);
|
|
continue;
|
|
//throw new Exception("Monthly Roster not found for the employee(" + attnProcess.Employee.EmployeeNo + ")" + attnProcess.Employee.Name);
|
|
}
|
|
//attnProcess.WorkDayType = 0;// attnProcess.MonthlyWorkPlan.Type;
|
|
//attnProcess.ReferenceID = 0;// attnProcess.MonthlyWorkPlan.HolidayID;
|
|
#endregion
|
|
|
|
#region calculate In/Out time & work day type
|
|
|
|
/*
|
|
* if ShiftID found and attendence data exists
|
|
* Calcullate InTime and OutTime
|
|
* If elligable for OT calcullate OT according to DayType(Holiday or Workday)
|
|
*/
|
|
|
|
if (empAttnData != null && empAttnData.Count > 0 && attnProcess.ShiftID != null)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Present;
|
|
attnProcess.InTime = null;
|
|
attnProcess.OutTime = null;
|
|
|
|
oshift = _shifts.FirstOrDefault(x => x.ID == attnProcess.ShiftID);
|
|
|
|
if (oshift == null) continue;
|
|
|
|
attnProcess.InTime = GetShiftInOutTime(empAttnData, attnProcess, oshift.ID, true);
|
|
attnProcess.OutTime = GetShiftInOutTime(empAttnData, attnProcess, oshift.ID, false);
|
|
|
|
if (attnProcess.InTime != null) attnProcess.InTime = ((DateTime)attnProcess.InTime).RemoveSecondsAndMiliseconds();
|
|
if (attnProcess.OutTime != null) attnProcess.OutTime = ((DateTime)attnProcess.OutTime).RemoveSecondsAndMiliseconds();
|
|
|
|
#region Calcullate Late & Delay & Early
|
|
|
|
#region previous Early and Late calculation
|
|
//if (attnProcess.InTime != null && totalLateMinute > oshift.LateCalcualtion)
|
|
//{
|
|
// // attnProcess.AttenType = EnumAttendanceType.Late;
|
|
// attnProcess.IsLate = true;
|
|
// _lateHour = (totalLateMinute) / 60;
|
|
//}
|
|
|
|
//if (attnProcess.OutTime != null && attnProcess.OutTime != null && ((DateTime)attnProcess.OutTime).Day == attnProcess.AttnDate.Day)
|
|
//{
|
|
// if (oshift.OutTime.TimeOfDay.Subtract(((DateTime)attnProcess.OutTime).TimeOfDay).TotalMinutes > 0)
|
|
// {
|
|
// _earlyHour = oshift.OutTime.TimeOfDay.Subtract(((DateTime)attnProcess.OutTime).TimeOfDay).TotalMinutes / 60;
|
|
// }
|
|
//}
|
|
#endregion
|
|
|
|
this.CalculateLateAndDelay(attnProcess, _shifts);
|
|
#endregion
|
|
}
|
|
|
|
#endregion
|
|
|
|
if (empOutsideDuty != null)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.OutSideDuty;
|
|
attnProcess.ReferenceID = empOutsideDuty.ID;
|
|
}
|
|
if (empLeaveEntry != null && (empLeaveEntry.LeaveStatus == EnumLeaveStatus.Approved))
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Leave;
|
|
attnProcess.ReferenceID = empLeaveEntry.LeaveID;
|
|
}
|
|
|
|
#region Calcullate not present status
|
|
if (attnProcess.WorkDayType == EnumWorkPlanDayType.WeeklyHoliday
|
|
|| attnProcess.WorkDayType == EnumWorkPlanDayType.NationalHoliday)
|
|
{
|
|
if (empOutsideDuty != null)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.OutSideDuty;
|
|
attnProcess.ReferenceID = empOutsideDuty.ID;
|
|
attnProcess.Comments = empOutsideDuty.Comments;
|
|
}
|
|
if (empLeaveEntry != null && (empLeaveEntry.LeaveStatus == EnumLeaveStatus.Approved)
|
|
&& lvParameters.Where(x => x.LeaveId == empLeaveEntry.LeaveID).Any(x => x.IgnoreHoliday == false))
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Leave;
|
|
attnProcess.ReferenceID = empLeaveEntry.LeaveID;
|
|
attnProcess.Comments = empLeaveEntry.Remarks;
|
|
}
|
|
}
|
|
if (attnProcess.InTime == null || attnProcess.OutTime == null)
|
|
{
|
|
if (empLeaveEntry != null && (empLeaveEntry.LeaveStatus == EnumLeaveStatus.Approved))
|
|
{
|
|
#region Check Leave Entry
|
|
// Check wether Ignore Holidays
|
|
if (lvParameters.Where(x => x.LeaveId == empLeaveEntry.LeaveID).Any(x => x.IgnoreHoliday))
|
|
{
|
|
if (attnProcess.WorkDayType == EnumWorkPlanDayType.WeeklyHoliday)
|
|
attnProcess.AttenType = EnumAttendanceType.WeeklyHoliday;
|
|
else if (attnProcess.WorkDayType == EnumWorkPlanDayType.NationalHoliday)
|
|
attnProcess.AttenType = EnumAttendanceType.Holiday;
|
|
else
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Leave;
|
|
attnProcess.ReferenceID = empLeaveEntry.LeaveID;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (attnProcess.AttenType != EnumAttendanceType.Present)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Leave;
|
|
attnProcess.ReferenceID = empLeaveEntry.LeaveID;
|
|
}
|
|
else
|
|
{
|
|
_earlyHour = 0;
|
|
_lateHour = 0;
|
|
attnProcess.IsLate = false;
|
|
attnProcess.EarlyHour = 0;
|
|
attnProcess.LateHour = 0;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
else if (empOutsideDuty != null)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.OutSideDuty;
|
|
attnProcess.ReferenceID = empOutsideDuty.ID;
|
|
}
|
|
else if (attnProcess.WorkDayType == EnumWorkPlanDayType.WeeklyHoliday)
|
|
attnProcess.AttenType = EnumAttendanceType.WeeklyHoliday;
|
|
else if (attnProcess.WorkDayType == EnumWorkPlanDayType.NationalHoliday)
|
|
attnProcess.AttenType = EnumAttendanceType.Holiday;
|
|
else if ((attnProcess.InTime != null && attnProcess.InTime != DateTime.MinValue) ||
|
|
(attnProcess.OutTime != null && attnProcess.OutTime != DateTime.MinValue))
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Present;
|
|
}
|
|
else
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Absent;
|
|
}
|
|
}
|
|
|
|
if (attnProcess.InTime != null && attnProcess.Shift.hasAbsentTime == true
|
|
&& attnProcess.WorkDayType == EnumWorkPlanDayType.WorkingDay)
|
|
{
|
|
if (attnProcess.Shift.InTime.TimeOfDay <= attnProcess.Shift.OutTime.TimeOfDay)
|
|
{
|
|
if (((DateTime)attnProcess.InTime).TimeOfDay > attnProcess.Shift.AbsentTime.TimeOfDay)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Absent;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (attnProcess.Shift.AbsentTime.TimeOfDay <= attnProcess.Shift.OutTime.TimeOfDay)
|
|
{
|
|
if (((DateTime)attnProcess.InTime).TimeOfDay > attnProcess.Shift.AbsentTime.TimeOfDay &&
|
|
((DateTime)attnProcess.InTime).TimeOfDay <= attnProcess.Shift.OutTime.TimeOfDay)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Absent;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!(((DateTime)attnProcess.InTime).TimeOfDay < attnProcess.Shift.AbsentTime.TimeOfDay
|
|
&& ((DateTime)attnProcess.InTime).TimeOfDay > attnProcess.Shift.OutTime.TimeOfDay))
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Absent;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
CalcullateOT(true, attnProcess, attnProcess.Shift, Attdate);
|
|
|
|
#region New Attendance Benefit Process
|
|
if(attnProcess.AttenType != EnumAttendanceType.Absent && attnProcess.InTime != null && attnProcess.OutTime != null)
|
|
attnProcess.Benifits = CalculateDailyAttendanceAllowance(attnProcess, payrollTypeID, processUserID);
|
|
#endregion
|
|
|
|
dailyattProcesses.Add(attnProcess); // Add the process to collection
|
|
}
|
|
|
|
msg = "Saving Data: ";
|
|
new DailyAttnProcessService().Save(dailyattProcesses, _atnMonthlyBenifits);
|
|
|
|
// msg = "Saving Allowance Data: ";
|
|
// new DailyAttendanceAllowanceService().Save(dailyAttendanceAllowances);
|
|
}
|
|
catch (ServiceException ex)
|
|
{
|
|
throw new ServiceException(msg + ex.Message, ex);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new ServiceException(msg + e.Message, e);
|
|
}
|
|
|
|
}
|
|
|
|
public void CalculateLateAndDelay(DailyAttnProcess attnProcess, List<Shift> shifts)
|
|
{
|
|
double totalLateMinute = 0;
|
|
DateTime temptime;
|
|
if (attnProcess.ShiftID == null) return;
|
|
Shift oshift = shifts.FirstOrDefault(x => x.ID == (int)attnProcess.ShiftID);
|
|
if (oshift == null) return;
|
|
CalculateLateAndDelay(attnProcess, oshift);
|
|
}
|
|
|
|
public void CalculateOverTime(DailyAttnProcess attnProcess, Shift shift)
|
|
{
|
|
if (attnProcess.ShiftID == null) return;
|
|
CalcullateOT(true, attnProcess, shift, attnProcess.AttnDate);
|
|
}
|
|
|
|
public void CalculateLateAndDelay(DailyAttnProcess attnProcess, Shift oshift)
|
|
{
|
|
double totalLateMinute = 0;
|
|
DateTime temptime;
|
|
attnProcess.IsLate = false;
|
|
attnProcess.LateHour = 0;
|
|
attnProcess.EarlyHour = 0;
|
|
_lateHour =0;
|
|
_earlyHour = 0;
|
|
if (oshift != null && attnProcess.InTime != null)
|
|
{
|
|
temptime = oshift.InTime.AddMinutes(oshift.FlexibleHour);
|
|
|
|
if (((DateTime)attnProcess.InTime).TimeOfDay > temptime.TimeOfDay)
|
|
{
|
|
totalLateMinute = ((DateTime)attnProcess.InTime).TimeOfDay.Subtract(temptime.TimeOfDay).TotalMinutes;
|
|
totalLateMinute = Math.Floor(totalLateMinute);// removing second
|
|
if (totalLateMinute > oshift.LateCalcualtion)
|
|
{
|
|
attnProcess.IsLate = true;
|
|
_lateHour = Math.Round( Math.Floor(totalLateMinute/60) + (totalLateMinute % 60)/100,2);
|
|
|
|
}
|
|
}
|
|
}
|
|
double earlyhour = 0;
|
|
if (oshift != null && attnProcess.InTime !=null && attnProcess.OutTime != null)
|
|
{
|
|
DateTime tempshiftTime = oshift.OutTime;
|
|
if (oshift.FlexibleHour == 0)
|
|
{
|
|
DateTime workInTime = (DateTime) attnProcess.InTime;
|
|
DateTime shiftInTime = new DateTime(workInTime.Year, workInTime.Month, workInTime.Day, oshift.InTime.Hour, oshift.InTime.Minute, 0);
|
|
if(workInTime < shiftInTime) workInTime = shiftInTime;
|
|
|
|
DateTime workoutTime = (DateTime)attnProcess.OutTime;
|
|
DateTime shiftoutTime = new DateTime(workoutTime.Year, workoutTime.Month, workoutTime.Day, oshift.OutTime.Hour, oshift.OutTime.Minute, 0);
|
|
if (workoutTime > shiftoutTime) workoutTime = shiftoutTime;
|
|
|
|
// double workHour = (workoutTime).Subtract((DateTime)workInTime).TotalMinutes;
|
|
double workHour = ((DateTime)attnProcess.OutTime).Subtract((DateTime)attnProcess.InTime).TotalMinutes;
|
|
workHour = Math.Floor(workHour); //removing second
|
|
|
|
|
|
|
|
attnProcess.OTHour = workHour - 480;// Math.Round(Math.Floor(workHour / 60) + (workHour % 60) / 100, 2);
|
|
if (attnProcess.OTHour < 0) attnProcess.OTHour = 0;
|
|
else attnProcess.OTHour = Math.Round(Math.Floor(attnProcess.OTHour / 60) + (attnProcess.OTHour % 60) / 100, 2);
|
|
|
|
workHour = workHour - oshift.LunchHour;
|
|
if (workHour < 0) workHour = 0;
|
|
// if (workHour> oshift.WorkHour*60) workHour = oshift.WorkHour * 60;
|
|
attnProcess.WorkHour = Math.Round(Math.Floor(workHour / 60) + (workHour % 60) / 100, 2);
|
|
|
|
|
|
if (((DateTime)attnProcess.OutTime).TimeOfDay < shiftoutTime.TimeOfDay)
|
|
{
|
|
_earlyHour = (shiftoutTime).Subtract((DateTime)attnProcess.OutTime).TotalMinutes;
|
|
_earlyHour = Math.Floor(_earlyHour);// removing second
|
|
earlyhour = _earlyHour;
|
|
_earlyHour = Math.Round(Math.Floor(_earlyHour / 60) + (_earlyHour % 60) / 100, 2);
|
|
}
|
|
|
|
|
|
}
|
|
// let calcualte workhour with flexible time later
|
|
}
|
|
|
|
attnProcess.LateHour = _lateHour;
|
|
attnProcess.EarlyHour = _earlyHour;
|
|
_DailyAttnProcess= attnProcess;
|
|
|
|
|
|
}
|
|
|
|
public DailyAttnProcess CalulateLateAndDelayForMobileAttendance(DailyAttnProcess oAttnProcess, Shift oShift)
|
|
{
|
|
CalculateLateAndDelay(oAttnProcess, oShift);
|
|
return _DailyAttnProcess;
|
|
}
|
|
public DailyAttnProcess CalulateOverTimeForMobileAttendance(DailyAttnProcess oAttnProcess, Shift oShift)
|
|
{
|
|
CalcullateOT(true,oAttnProcess, oShift, oAttnProcess.AttnDate);
|
|
return _DailyAttnProcess;
|
|
}
|
|
public List<DailyAttendanceAllowance> CalculateDailyAttendanceAllowance(DailyAttnProcess pDailyattProcesses, int payrolltypeid, int userid)
|
|
{
|
|
List<DailyAttendanceAllowance> items = new List<DailyAttendanceAllowance>();
|
|
|
|
//DailyAttendanceAllowance tempDailyAttendanceAllowance = new DailyAttendanceAllowance();
|
|
//tempDailyAttendanceAllowance.AttnDate = pDailyattProcesses.AttnDate;
|
|
//tempDailyAttendanceAllowance.EmployeeID = pDailyattProcesses.EmployeeID;
|
|
//tempDailyAttendanceAllowance.ShiftID = (int)pDailyattProcesses.ShiftID;
|
|
//tempDailyAttendanceAllowance.PayrollTypeID = pEmployee.PayrollTypeID;
|
|
|
|
|
|
if (pDailyattProcesses.ShiftID == null) return items;
|
|
|
|
if (pDailyattProcesses.Shift.HasBenefits)
|
|
{
|
|
if (pDailyattProcesses.Shift.HasExtraHourAllowance && pDailyattProcesses.OutTime != null && pDailyattProcesses.OutTime != DateTime.MinValue &&
|
|
((DateTime)pDailyattProcesses.OutTime).TimeOfDay > pDailyattProcesses.Shift.ExtraHourAllowanceFromTime.TimeOfDay)
|
|
{
|
|
|
|
DailyAttendanceAllowance ExtraHour = new DailyAttendanceAllowance();
|
|
ExtraHour.BenifitsType = EnumattnBeniftsType.Allowance;
|
|
ExtraHour.OtherBenifitItemID = pDailyattProcesses.Shift.ExtraHourAllowanceID;
|
|
ExtraHour.OtherBenifitValue = Convert.ToInt32(Math.Round(((DateTime)pDailyattProcesses.OutTime).TimeOfDay.Subtract(pDailyattProcesses.Shift.ExtraHourAllowanceFromTime.TimeOfDay).TotalHours));
|
|
items.Add(ExtraHour);
|
|
}
|
|
|
|
if ((pDailyattProcesses.Shift.HasHolidayAllowance && pDailyattProcesses.AttenType == EnumAttendanceType.WeeklyHoliday || pDailyattProcesses.AttenType == EnumAttendanceType.Holiday) &&
|
|
((pDailyattProcesses.InTime != null && pDailyattProcesses.InTime != DateTime.MinValue) &&
|
|
(pDailyattProcesses.OutTime != null && pDailyattProcesses.OutTime != DateTime.MinValue)))
|
|
{
|
|
//tempDailyAttendanceAllowance.HolidayAllowance = Convert.ToInt32(Math.Round(((DateTime)pDailyattProcesses.OutTime).Subtract(((DateTime)pDailyattProcesses.InTime)).TotalHours));
|
|
// tempDailyAttendanceAllowance.HolidayAllowance = 1;
|
|
DailyAttendanceAllowance hilidayAlloance = new DailyAttendanceAllowance();
|
|
hilidayAlloance.BenifitsType = EnumattnBeniftsType.Allowance;
|
|
hilidayAlloance.OtherBenifitItemID = pDailyattProcesses.Shift.HolidayAllowanceID;
|
|
hilidayAlloance.OtherBenifitValue = 1;
|
|
items.Add(hilidayAlloance);
|
|
}
|
|
|
|
if (pDailyattProcesses.Shift.HasNightAllowance && pDailyattProcesses.Shift.IsOverlapingDay)
|
|
{
|
|
DailyAttendanceAllowance NightAllowance = new DailyAttendanceAllowance();
|
|
NightAllowance.BenifitsType = EnumattnBeniftsType.Allowance;
|
|
NightAllowance.OtherBenifitItemID = pDailyattProcesses.Shift.NightAllowanceID;
|
|
NightAllowance.OtherBenifitValue = 1;
|
|
items.Add(NightAllowance);
|
|
}
|
|
|
|
|
|
if(pDailyattProcesses.Shift.HasOtherAllowance)
|
|
{
|
|
DailyAttendanceAllowance OtherAllowance = new DailyAttendanceAllowance();
|
|
OtherAllowance.BenifitsType = EnumattnBeniftsType.Allowance;
|
|
OtherAllowance.OtherBenifitItemID = pDailyattProcesses.Shift.OtherAllowanceID;
|
|
OtherAllowance.OtherBenifitValue = 1;
|
|
items.Add(OtherAllowance);
|
|
}
|
|
|
|
if (pDailyattProcesses.Shift.HasTiffinAllowance)
|
|
{
|
|
DailyAttendanceAllowance OtherAllowance = new DailyAttendanceAllowance();
|
|
OtherAllowance.BenifitsType = EnumattnBeniftsType.Allowance;
|
|
OtherAllowance.OtherBenifitItemID = pDailyattProcesses.Shift.TiffinAllowanceID;
|
|
OtherAllowance.OtherBenifitValue = 1;
|
|
items.Add(OtherAllowance);
|
|
}
|
|
|
|
if (pDailyattProcesses.Shift.HasSpecialAllowance)
|
|
{
|
|
DailyAttendanceAllowance OtherAllowance = new DailyAttendanceAllowance();
|
|
OtherAllowance.BenifitsType = EnumattnBeniftsType.Allowance;
|
|
OtherAllowance.OtherBenifitItemID = pDailyattProcesses.Shift.SpecialAllowanceID;
|
|
OtherAllowance.OtherBenifitValue = 1;
|
|
items.Add(OtherAllowance);
|
|
}
|
|
|
|
if (pDailyattProcesses.Shift.HasRegularOverTime == true
|
|
&& pDailyattProcesses.OTHour > 0)
|
|
{
|
|
if ( pDailyattProcesses.Shift.HasHolidayOverTime == true &&
|
|
(pDailyattProcesses.WorkDayType == EnumWorkPlanDayType.NationalHoliday ||
|
|
pDailyattProcesses.WorkDayType == EnumWorkPlanDayType.WeeklyAndNational ))
|
|
{
|
|
// do nothing
|
|
}
|
|
else
|
|
{
|
|
DailyAttendanceAllowance RegularOverTime = new DailyAttendanceAllowance();
|
|
RegularOverTime.BenifitsType = EnumattnBeniftsType.OT;
|
|
RegularOverTime.OtherBenifitItemID = pDailyattProcesses.Shift.RegularOverTimeAllowanceID;
|
|
RegularOverTime.OtherBenifitValue = pDailyattProcesses.OTHour;
|
|
items.Add(RegularOverTime);
|
|
|
|
}
|
|
}
|
|
|
|
if(pDailyattProcesses.Shift.HasRegularOverTime == true &&
|
|
pDailyattProcesses.Shift.HasHolidayOverTime == true && pDailyattProcesses.OTHour > 0 &&
|
|
(pDailyattProcesses.WorkDayType == EnumWorkPlanDayType.NationalHoliday ||
|
|
pDailyattProcesses.WorkDayType == EnumWorkPlanDayType.WeeklyAndNational
|
|
))
|
|
{
|
|
|
|
DailyAttendanceAllowance HolidayOverTime = new DailyAttendanceAllowance();
|
|
HolidayOverTime.BenifitsType = EnumattnBeniftsType.OT;
|
|
HolidayOverTime.OtherBenifitItemID = pDailyattProcesses.Shift.HolidayOverTimeAllowanceID;
|
|
HolidayOverTime.OtherBenifitValue = Convert.ToInt32(Math.Round(pDailyattProcesses.OTHour));
|
|
items.Add(HolidayOverTime);
|
|
}
|
|
|
|
if (this._AttnParam == null) this._AttnParam = new AttnParametarizationService().Get(payrolltypeid);
|
|
if (this._AttnParam == null) throw new Exception("Failed to get Attendance parameters");
|
|
items.ForEach(x =>
|
|
{
|
|
x.AttnDate = pDailyattProcesses.AttnDate;
|
|
x.EmployeeID = pDailyattProcesses.EmployeeID;
|
|
x.ShiftID = (int)pDailyattProcesses.ShiftID;
|
|
x.PayrollTypeID = payrolltypeid;
|
|
x.CreatedBy = userid;
|
|
x.CreatedDate = DateTime.Now;
|
|
x.SalaryMonth = GlobalFunctions.GetAttandaceSalaryMonth(x.AttnDate, this._AttnParam.MonthStartDay);
|
|
});
|
|
}
|
|
|
|
|
|
//DailyAttendanceAllowance tempDailyAttendanceAllowance = new DailyAttendanceAllowance();
|
|
//tempDailyAttendanceAllowance.AttnDate = pDailyattProcesses.AttnDate;
|
|
//tempDailyAttendanceAllowance.EmployeeID = pDailyattProcesses.EmployeeID;
|
|
//tempDailyAttendanceAllowance.ShiftID = (int)pDailyattProcesses.ShiftID;
|
|
//tempDailyAttendanceAllowance.PayrollTypeID = pEmployee.PayrollTypeID;
|
|
|
|
return items;
|
|
}
|
|
public List<AttnMonthlyBenefit> AttnMonthlyBenefitProcess_prev(List<DailyAttnProcess> dailyattProcesses, bool IsManualEntry, int payrollTypeId)
|
|
{
|
|
// this function is per previous system
|
|
List<AttnWiseAllowance> oAttnWiseAllowances = new AttnWiseAllowanceService().Get(payrollTypeId);
|
|
if (oAttnWiseAllowances == null || oAttnWiseAllowances.Count == 0) return null;
|
|
|
|
AttnParametarization oAttnParam = new AttnParametarizationService().Get(payrollTypeId);
|
|
#region AttnMonthlyBenefit Process
|
|
string empids = string.Empty;
|
|
DateTime tempIntime = DateTime.MinValue;
|
|
DateTime tempOuttime = DateTime.MinValue;
|
|
DateTime outTime = DateTime.MinValue;
|
|
try
|
|
{
|
|
#region Distinct Employee
|
|
List<DailyAttnProcess> distinctEmployee = dailyattProcesses
|
|
.GroupBy(p => p.EmployeeID)
|
|
.Select(g => g.First())
|
|
.ToList();
|
|
|
|
if (distinctEmployee.Count == 1)
|
|
{
|
|
empids = distinctEmployee[0].EmployeeID.ToString();
|
|
}
|
|
else
|
|
{
|
|
foreach (DailyAttnProcess dap in distinctEmployee)
|
|
{
|
|
empids += dap.EmployeeID.ToString() + ",";
|
|
}
|
|
empids = empids.Trim(',');
|
|
}
|
|
#endregion
|
|
|
|
List<DailyAttnProcess> distinctAttnDate = dailyattProcesses
|
|
.GroupBy(p => p.AttnDate)
|
|
.Select(g => g.First())
|
|
.ToList();
|
|
|
|
DateTime fromdate = GlobalFunctions.FirstDateOfMonth(distinctAttnDate[0].AttnDate.Date);
|
|
DateTime todate = GlobalFunctions.LastDateOfMonth(distinctAttnDate[0].AttnDate.Date);
|
|
|
|
List<Shift> shifts = new ShiftService().GetAllShift();
|
|
string propertyName = string.Empty;
|
|
bool isCalculatedValue = false;
|
|
DateTime applicableMonth = DateTime.MinValue;
|
|
double calculatedfValue = 0;
|
|
_atnMonthlyBenifits = new List<AttnMonthlyBenefit>();
|
|
// omonthlyWorkPlan = new List<MonthlyWorkPlan>();
|
|
|
|
if (distinctAttnDate.Count == 1)
|
|
{
|
|
// omonthlyWorkPlan = MonthlyWorkPlan.GetByDate(distinctAttnDate[0].AttnDate.Date);
|
|
AttnMnthBenefitValueMapper obj_Mapper = new AttnMnthBenefitValueMapper(distinctAttnDate[0].AttnDate.Date, oAttnParam.MonthStartDay, out applicableMonth);
|
|
_atnMonthlyBenifits = new AttnMonthlyBenefitService().Get(empids, applicableMonth);
|
|
}
|
|
else
|
|
{
|
|
foreach (DailyAttnProcess daProcess in distinctAttnDate)
|
|
{
|
|
DateTime tempTime = DateTime.MinValue;
|
|
AttnMnthBenefitValueMapper obj_Mapper = new AttnMnthBenefitValueMapper(daProcess.AttnDate.Date, oAttnParam.MonthStartDay, out applicableMonth);
|
|
List<AttnMonthlyBenefit> _atnMonthlyBenifitTemp = new AttnMonthlyBenefitService().Get(empids, applicableMonth);
|
|
// omonthlyWorkPlan.AddRange(MonthlyWorkPlan.GetByDate(daProcess.AttnDate.Date));
|
|
foreach (AttnMonthlyBenefit itemAMB in _atnMonthlyBenifitTemp)
|
|
{
|
|
if (!_atnMonthlyBenifits.Exists(o => o.EmployeeID == itemAMB.EmployeeID && o.SalaryMonth == itemAMB.SalaryMonth && o.ItemType == itemAMB.ItemType && o.ItemID == itemAMB.ItemID))
|
|
{
|
|
_atnMonthlyBenifits.Add(itemAMB);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Employee employee = null;
|
|
foreach (DailyAttnProcess item in dailyattProcesses)
|
|
{
|
|
employee = item.Employee;
|
|
PropertyInfo propertyInfo, propertyInfoIs;
|
|
AttnMnthBenefitValueMapper objMapper = new AttnMnthBenefitValueMapper(item.AttnDate.Date, oAttnParam.MonthStartDay, out applicableMonth);
|
|
propertyName = objMapper[item.AttnDate];
|
|
List<AttnWiseAllowance> itemAttnWiseAllowwances = new AttnWiseAllowanceService().GetAllApplicableItem(oAttnWiseAllowances, item);
|
|
|
|
if (itemAttnWiseAllowwances == null) continue;
|
|
|
|
itemAttnWiseAllowwances = itemAttnWiseAllowwances.GroupBy(p => p.ID).Select(g => g.First()).ToList();
|
|
propertyInfo = typeof(AttnMonthlyBenefit).GetProperties().FirstOrDefault(p => p.Name == propertyName);
|
|
propertyInfoIs = typeof(AttnMonthlyBenefit).GetProperties().FirstOrDefault(p => p.Name == "Is" + propertyName);
|
|
|
|
List<AttnMonthlyBenefit> _aMBenifits = _atnMonthlyBenifits.Where(o => o.EmployeeID == item.EmployeeID).ToList();
|
|
if (IsManualEntry == true)
|
|
{
|
|
for (int i = 0; i < _aMBenifits.Count(); i++)
|
|
{
|
|
calculatedfValue = 0;
|
|
propertyInfo.SetValue(_aMBenifits[i], 0, null);
|
|
propertyInfoIs.SetValue(_aMBenifits[i], false, null);
|
|
_aMBenifits[i] = new AttnMonthlyBenefitService().CalculateTotal(_aMBenifits[i]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < _aMBenifits.Count(); i++)
|
|
{
|
|
calculatedfValue = 0;
|
|
isCalculatedValue = (bool)propertyInfoIs.GetValue(_aMBenifits[i], null);
|
|
if (isCalculatedValue) continue;
|
|
propertyInfo.SetValue(_aMBenifits[i], 0, null);
|
|
_aMBenifits[i] = new AttnMonthlyBenefitService().CalculateTotal(_aMBenifits[i]);
|
|
}
|
|
}
|
|
|
|
foreach (AttnWiseAllowance attSetup in itemAttnWiseAllowwances)
|
|
{
|
|
|
|
employee = item.Employee;
|
|
AttnMonthlyBenefit oAttnWiseBenefit = _atnMonthlyBenifits
|
|
.FirstOrDefault(x => x.EmployeeID == item.EmployeeID
|
|
&& attSetup.ProvisionID == x.ItemID
|
|
&& attSetup.ProvisionType == x.ItemType
|
|
&& x.SalaryMonth == GlobalFunctions.GetAttandaceSalaryMonth(item.AttnDate.Date, oAttnParam.MonthStartDay));
|
|
if (oAttnWiseBenefit == null)
|
|
{
|
|
oAttnWiseBenefit = new AttnMonthlyBenefit();
|
|
oAttnWiseBenefit.EmployeeID = item.EmployeeID;
|
|
oAttnWiseBenefit.ItemType = attSetup.ProvisionType;
|
|
oAttnWiseBenefit.ItemID = attSetup.ProvisionID;
|
|
oAttnWiseBenefit.SalaryMonth = GlobalFunctions.GetAttandaceSalaryMonth(item.AttnDate.Date, oAttnParam.MonthStartDay);
|
|
_atnMonthlyBenifits.Add(oAttnWiseBenefit);
|
|
}
|
|
|
|
propertyInfo = typeof(AttnMonthlyBenefit).GetProperties().FirstOrDefault(p => p.Name == propertyName);
|
|
calculatedfValue = (double)propertyInfo.GetValue(oAttnWiseBenefit, null);
|
|
propertyInfoIs = typeof(AttnMonthlyBenefit).GetProperties().FirstOrDefault(p => p.Name == "Is" + propertyName);
|
|
isCalculatedValue = (bool)propertyInfoIs.GetValue(oAttnWiseBenefit, null);
|
|
if (IsManualEntry == false)
|
|
{
|
|
if (isCalculatedValue)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
if (oAttnWiseBenefit.ItemType == enumPayrollComponentType.Over_Time)
|
|
{
|
|
calculatedfValue = new AttnMonthlyBenefitService().CalculateOvertimeValue(attSetup, item, payrollTypeId);
|
|
propertyInfo.SetValue(oAttnWiseBenefit, calculatedfValue, null);
|
|
}
|
|
|
|
if (oAttnWiseBenefit.ItemType == enumPayrollComponentType.Allowance)
|
|
{
|
|
calculatedfValue = new AttnMonthlyBenefitService().CalculateAllowanceValue(attSetup, item);
|
|
propertyInfo.SetValue(oAttnWiseBenefit, calculatedfValue, null);
|
|
}
|
|
oAttnWiseBenefit = new AttnMonthlyBenefitService().CalculateTotal(oAttnWiseBenefit);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception(ex.Message);
|
|
}
|
|
|
|
return _atnMonthlyBenifits;
|
|
#endregion
|
|
}
|
|
|
|
#endregion
|
|
public static MonthlyWorkPlan GetPlanwithEmployee(DateTime EffectDate, int employeeid,
|
|
List<EmployeeWorkPlanSetup> plans, List<MonthlyWorkPlan> MworkPlans,
|
|
ActingResponsibilitySetup temporaryShiftEmp)
|
|
{
|
|
|
|
MonthlyWorkPlan dPlan = null;
|
|
if (temporaryShiftEmp == null)
|
|
{
|
|
EmployeeWorkPlanSetup workGroup = plans.FirstOrDefault(x => x.EmployeeID == employeeid);
|
|
if (workGroup != null)
|
|
{
|
|
dPlan = MworkPlans.FirstOrDefault(x => x.WorkPlanGroupID == workGroup.WorkPlanGroupID && x.WorkDate == EffectDate);
|
|
if (dPlan != null)
|
|
dPlan.EmployeeID = employeeid;
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dPlan = MworkPlans.FirstOrDefault(x => x.WorkPlanGroupID == temporaryShiftEmp.WorkPlanGroupID && x.WorkDate == EffectDate);
|
|
dPlan.EmployeeID = employeeid;
|
|
}
|
|
return dPlan;
|
|
}
|
|
|
|
private DateTime? GetShiftInOutTime(List<AttnRawData> RawData, DailyAttnProcess attnProcess, int shiftID, bool InCheck)
|
|
{
|
|
DateTime? Returntime = null;
|
|
Shift oShift = _shifts.FirstOrDefault(x => x.ID == shiftID);
|
|
if (InCheck == true)
|
|
{
|
|
|
|
DateTime MinInTime = new DateTime(attnProcess.AttnDate.Year,
|
|
attnProcess.AttnDate.Month,
|
|
attnProcess.AttnDate.Day,
|
|
oShift.InTime.Hour - 3,
|
|
0,
|
|
0);
|
|
DateTime inDate = attnProcess.AttnDate;
|
|
int hour = oShift.InTime.Hour + 4;
|
|
if (hour > 23)
|
|
{
|
|
inDate = inDate.AddDays(1);
|
|
hour = hour - 23;
|
|
}
|
|
DateTime MaxInTime = new DateTime(inDate.Year,
|
|
inDate.Month,
|
|
inDate.Day,
|
|
hour,
|
|
0,
|
|
0);
|
|
|
|
List<AttnRawData> rsts = RawData.Where(x => x.PunchTime > MinInTime && x.PunchTime < MaxInTime).ToList();
|
|
if (rsts != null && rsts.Count > 0) Returntime = rsts.Min(x => x.PunchTime);
|
|
}
|
|
else
|
|
{
|
|
DateTime fromtime = attnProcess.AttnDate;
|
|
int hour = oShift.InTime.Hour + 2;
|
|
if (oShift.InTime.Hour + 2 > 23)
|
|
{
|
|
fromtime = fromtime.AddDays(1);
|
|
hour = oShift.InTime.Hour + 2 - 23;
|
|
}
|
|
|
|
DateTime MinOutTime = new DateTime(attnProcess.AttnDate.Year,
|
|
fromtime.Month,
|
|
fromtime.Day,
|
|
hour, 0, 0);
|
|
|
|
DateTime oDate = attnProcess.AttnDate;
|
|
hour = 23;
|
|
if (oShift.IsOverlapingDay)
|
|
{
|
|
hour = 11;
|
|
oDate = attnProcess.AttnDate.AddDays(1);
|
|
}
|
|
else
|
|
{
|
|
hour = 5;
|
|
oDate = attnProcess.AttnDate.AddDays(1);
|
|
}
|
|
DateTime MaxOutTime = new DateTime(oDate.Year,
|
|
oDate.Month,
|
|
oDate.Day,
|
|
hour,
|
|
0,
|
|
0);
|
|
|
|
List<AttnRawData> rsts = RawData.Where(x => x.PunchTime > MinOutTime && x.PunchTime < MaxOutTime).ToList();
|
|
if (rsts != null && rsts.Count > 0) Returntime = rsts.Max(x => x.PunchTime);
|
|
}
|
|
return Returntime;
|
|
|
|
|
|
}
|
|
|
|
private void AddError(AttnProcessRunSummary oAttnRunSummary, EnumErrorType enumErrorType,
|
|
string errorDescription, Employee emp)
|
|
{
|
|
if (oAttnRunSummary.AttnProcessRunDetails == null)
|
|
oAttnRunSummary.AttnProcessRunDetails = new List<AttnProcessRunDetail>();
|
|
|
|
oAttnRunSummary.AttnProcessRunDetails.Add(new AttnProcessRunDetail()
|
|
{
|
|
EnumErrorType = enumErrorType,
|
|
Description = errorDescription,
|
|
EmployeeNo = emp == null ? string.Empty : emp.EmployeeNo,
|
|
EmployeeName = emp == null ? string.Empty : emp.Name
|
|
});
|
|
|
|
if (enumErrorType == EnumErrorType.ServiceException || enumErrorType == EnumErrorType.Exception)
|
|
{
|
|
oAttnRunSummary.ProcessStatus = EnumAttnProcessStatus.Error;
|
|
}
|
|
else
|
|
{
|
|
oAttnRunSummary.ProcessStatus = EnumAttnProcessStatus.SuccessWithError;
|
|
}
|
|
}
|
|
|
|
//private void CalcullateOTandWorkHour(DailyAttnProcess attnProcess, bool isOTEligable, DateTime Attdate)
|
|
//{
|
|
// attnProcess.OTHour = 0;
|
|
// attnProcess.WorkHour = 0;
|
|
|
|
// if (attnProcess.AttenType == EnumAttendanceType.Present || attnProcess.AttenType == EnumAttendanceType.Late)
|
|
// {
|
|
// if (attnProcess.InTime != null && attnProcess.InTime != DateTime.MinValue && attnProcess.OutTime != null && attnProcess.OutTime != DateTime.MinValue)
|
|
// {
|
|
// DateTime actualInTime = (DateTime)attnProcess.InTime;
|
|
|
|
// double actualHourWorked = ((DateTime)attnProcess.OutTime).Subtract((DateTime)attnProcess.InTime).TotalHours;
|
|
|
|
// //if (attnProcess.HasDualShift)
|
|
// //{
|
|
// // if (attnProcess.InTime2 != DateTime.MinValue && attnProcess.OutTime2 != DateTime.MinValue)
|
|
// // {
|
|
// // actualHourWorked += attnProcess.OutTime2.Subtract(attnProcess.InTime2).TotalHours;
|
|
// // }
|
|
// //}
|
|
// //else if (attnProcess.OutTime2 != DateTime.MinValue)
|
|
// //{
|
|
// // actualHourWorked = attnProcess.OutTime2.Subtract(attnProcess.InTime).TotalHours;
|
|
// //}
|
|
|
|
|
|
// double standardHourWorked = attnProcess.Shift.WorkHour + (attnProcess.Shift.LunchHour / 60.0);
|
|
// DateTime shiftInTime = ((DateTime)attnProcess.InTime).Date.Add(attnProcess.Shift.InTime.TimeOfDay);
|
|
// //DateTime shiftOutTime = shiftInTime.AddHours(standardHourWorked);
|
|
|
|
// if (attnProcess.WorkDayType == EnumWorkPlanDayType.WorkingDay)
|
|
// {
|
|
// if (actualHourWorked > standardHourWorked)
|
|
// {
|
|
// attnProcess.WorkHour = attnProcess.Shift.WorkHour;
|
|
// double minutesBeforeShiftTime = 0;
|
|
// double minutesAfterShiftTime = 0;
|
|
// double inOTMinutes, outOTMinutes;
|
|
// inOTMinutes = outOTMinutes = 0;
|
|
|
|
// if (actualInTime < shiftInTime)
|
|
// {
|
|
// minutesBeforeShiftTime = shiftInTime.Subtract(actualInTime).TotalMinutes;
|
|
// var minimumOtInMinutes = attnProcess.Shift.MinimumInOTHour;
|
|
|
|
// if (minimumOtInMinutes == 0)
|
|
// inOTMinutes = minutesBeforeShiftTime;
|
|
// else
|
|
// inOTMinutes = minimumOtInMinutes *
|
|
// Math.Floor((minutesBeforeShiftTime +
|
|
// attnProcess.Shift.MinimumInGraceTime) /
|
|
// minimumOtInMinutes);
|
|
// }
|
|
|
|
// if ((actualHourWorked * 60.0) - (standardHourWorked * 60.0) > minutesBeforeShiftTime)
|
|
// {
|
|
// minutesAfterShiftTime = (actualHourWorked * 60.0) - (standardHourWorked * 60.0) -
|
|
// minutesBeforeShiftTime;
|
|
// var minimumOtOutMinutes = attnProcess.Shift.MinimumOutOTHour;
|
|
|
|
// if (minimumOtOutMinutes == 0)
|
|
// outOTMinutes = minutesAfterShiftTime;
|
|
// else
|
|
// outOTMinutes = minimumOtOutMinutes *
|
|
// Math.Floor((minutesAfterShiftTime +
|
|
// attnProcess.Shift.MinimumOutGraceTime) /
|
|
// minimumOtOutMinutes);
|
|
// }
|
|
|
|
// if (inOTMinutes + outOTMinutes > 0)
|
|
// {
|
|
// attnProcess.OTHour = (inOTMinutes + outOTMinutes) / 60.0;
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// attnProcess.WorkHour = actualHourWorked - (attnProcess.Shift.LunchHour / 60.0);
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// double minutesBeforeShiftTime = 0;
|
|
// double minutesAfterShiftTime = 0;
|
|
// double inOTMinutes, outOTMinutes;
|
|
// inOTMinutes = outOTMinutes = 0;
|
|
|
|
// if (actualInTime < shiftInTime)
|
|
// {
|
|
// minutesBeforeShiftTime = shiftInTime.Subtract(actualInTime).TotalMinutes;
|
|
// var minimumOtInMinutes = attnProcess.Shift.MinimumInOTHour;
|
|
|
|
// if (minimumOtInMinutes == 0)
|
|
// inOTMinutes = minutesBeforeShiftTime;
|
|
// else
|
|
// inOTMinutes = minimumOtInMinutes *
|
|
// Math.Floor(
|
|
// (minutesBeforeShiftTime + attnProcess.Shift.MinimumInGraceTime) /
|
|
// minimumOtInMinutes);
|
|
// }
|
|
|
|
// if ((actualHourWorked * 60.0) - (standardHourWorked * 60.0) > minutesBeforeShiftTime)
|
|
// {
|
|
// minutesAfterShiftTime = (actualHourWorked * 60.0) - (standardHourWorked * 60.0) -
|
|
// minutesBeforeShiftTime;
|
|
// var minimumOtOutMinutes = attnProcess.Shift.MinimumOutOTHour;
|
|
|
|
// if (minimumOtOutMinutes == 0)
|
|
// outOTMinutes = minutesAfterShiftTime;
|
|
// else
|
|
// outOTMinutes = minimumOtOutMinutes *
|
|
// Math.Floor(
|
|
// (minutesAfterShiftTime + attnProcess.Shift.MinimumOutGraceTime) /
|
|
// minimumOtOutMinutes);
|
|
// }
|
|
|
|
// var regualarMinutes = (actualHourWorked * 60) - minutesBeforeShiftTime - minutesAfterShiftTime;
|
|
|
|
// //Holiday OT applicable after 6 Hours
|
|
// if (actualHourWorked >= 6)
|
|
// {
|
|
// attnProcess.OTHour = ((regualarMinutes + inOTMinutes + outOTMinutes) / 60.0) -
|
|
// (attnProcess.Shift.LunchHour / 60.0);
|
|
// }
|
|
// else
|
|
// {
|
|
// attnProcess.WorkHour = actualHourWorked;
|
|
// }
|
|
// }
|
|
|
|
|
|
// attnProcess.OTHour = attnProcess.OTHour > 0 && isOTEligable ? attnProcess.OTHour : 0;
|
|
// attnProcess.WorkHour = attnProcess.WorkHour < 0
|
|
// ? 0
|
|
// : attnProcess.WorkHour - (attnProcess.AttenType == EnumAttendanceType.Late ? 1 : 0);
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
private int GetAppropriateShiftID(List<Shift> oShifts, int currentShiftID, DateTime inTime)
|
|
{
|
|
int shiftID = currentShiftID;
|
|
var currentShift = oShifts.FirstOrDefault(x => x.ID == shiftID);
|
|
double minuteDifference = 24 * 60;
|
|
if (currentShift != null)
|
|
{
|
|
minuteDifference = Math.Abs((new DateTime(inTime.Year, inTime.Month, inTime.Day,
|
|
currentShift.InTime.Hour, currentShift.InTime.Minute, currentShift.InTime.Second) - inTime)
|
|
.TotalMinutes);
|
|
}
|
|
|
|
foreach (var shift in oShifts)
|
|
{
|
|
var shiftInTime = new DateTime(inTime.Year, inTime.Month, inTime.Day, shift.InTime.Hour,
|
|
shift.InTime.Minute, shift.InTime.Second);
|
|
// +/- 10 minutes
|
|
if ((Math.Abs((shiftInTime - inTime).TotalMinutes) + 10) < minuteDifference)
|
|
{
|
|
minuteDifference = Math.Abs((shiftInTime - inTime).TotalMinutes);
|
|
shiftID = shift.ID;
|
|
}
|
|
}
|
|
|
|
return shiftID;
|
|
}
|
|
|
|
private List<Shift> GetLocationTypewiseShifts(List<Shift> shifts, int shiftID)
|
|
{
|
|
List<Shift> oSameLocationShifts = new List<Shift>();
|
|
if (shifts.Any(x => x.ID == shiftID))
|
|
{
|
|
var locationType = shifts.First(x => x.ID == shiftID).Location;
|
|
oSameLocationShifts = shifts.Where(x => x.Location == locationType).ToList();
|
|
}
|
|
|
|
return oSameLocationShifts;
|
|
}
|
|
|
|
|
|
public static void GetAttendanceDateRange(out DateTime startDate, out DateTime endDate)
|
|
{
|
|
startDate = endDate = DateTime.MinValue;
|
|
startDate = DateTime.Today.AddDays(-7);
|
|
endDate = DateTime.Today;
|
|
}
|
|
|
|
|
|
public static List<DailyAttnProcess>
|
|
GetNotSubmittedAttnData(Employee oEmp, DateTime fromDate, DateTime toDate) //,bool isCurrentMonth)
|
|
{
|
|
if (oEmp == null)
|
|
{
|
|
throw new CustomException(EnumExceptionType.Validation, "No Employee selected.");
|
|
}
|
|
|
|
List<DailyAttnProcess> oNotYetSubmittedAttnDatas =
|
|
new DailyAttnProcessService().GetAttnDataByWFStatus(fromDate, toDate, oEmp.ID.ToString(),
|
|
EnumWFAttnStatus.None);
|
|
|
|
return oNotYetSubmittedAttnDatas;
|
|
}
|
|
|
|
|
|
//public List<AttnMonthlyBenefit> AttnMonthlyBenefitProcess(List<DailyAttnProcess> dailyattProcesses,
|
|
// bool IsManualEntry, int payrollTypeID)
|
|
//{
|
|
// List<DailyAttnProcess> tempATT = new List<DailyAttnProcess>();
|
|
// List<AttnNationalHoliday> attNHolidays = null;
|
|
// List<ActingResponsibilitySetup> _tempShiftEmployees = null;
|
|
// List<EmployeeWorkPlanSetup> _EmployeeWorkPlanSetups = null;
|
|
// EmployeeWorkPlanSetup ewps = null;
|
|
// AttnShiftWiseNationalHoliday attnShiftHoliday = null;
|
|
// List<MonthlyWorkPlan> _monthlyWorkPlan = null;
|
|
// MonthlyWorkPlan monthlyWorkPlanActual = null;
|
|
// MonthlyWorkPlan monthlyWorkPlanTemp = null;
|
|
// Shift temporaryShift = null;
|
|
// bool IsWorkingDay = true;
|
|
|
|
// #region AttnMonthlyBenefit Process
|
|
|
|
// string empids = string.Empty;
|
|
// //double totalOT = 0;
|
|
// DateTime tempIntime = DateTime.MinValue;
|
|
// DateTime tempOuttime = DateTime.MinValue;
|
|
// DateTime outTime = DateTime.MinValue;
|
|
// try
|
|
// {
|
|
// List<DailyAttnProcess> distinctEmployee = dailyattProcesses
|
|
// .GroupBy(p => p.EmployeeID)
|
|
// .Select(g => g.First())
|
|
// .ToList();
|
|
|
|
// List<DailyAttnProcess> distinctAttnDate = dailyattProcesses
|
|
// .GroupBy(p => p.AttnDate)
|
|
// .Select(g => g.First())
|
|
// .ToList();
|
|
// if (distinctEmployee.Count == 1)
|
|
// {
|
|
// empids = distinctEmployee[0].EmployeeID.ToString();
|
|
// }
|
|
// else
|
|
// {
|
|
// foreach (DailyAttnProcess dap in distinctEmployee)
|
|
// {
|
|
// empids += dap.EmployeeID.ToString() + ",";
|
|
// }
|
|
|
|
// empids = empids.Trim(',');
|
|
// }
|
|
|
|
// DateTime fromdate = GlobalFunctions.FirstDateOfMonth(distinctAttnDate[0].AttnDate.Date);
|
|
// DateTime todate = GlobalFunctions.LastDateOfMonth(distinctAttnDate[0].AttnDate.Date);
|
|
// attNHolidays =
|
|
// new AttnNationalHolidayService().GetByMonthAndPayrollType(fromdate, todate, payrollTypeID);
|
|
// List<Shift> shifts = new ShiftService().Get(string.Empty, string.Empty, EnumStatus.Regardless, payrollTypeID);
|
|
// string propertyName = string.Empty;
|
|
// bool isCalculatedValue = false;
|
|
// DateTime applicableMonth = DateTime.MinValue;
|
|
// double calculatedfValue = 0;
|
|
// _atnMonthlyBenifits = new List<AttnMonthlyBenefit>();
|
|
// _tempShiftEmployees = new List<ActingResponsibilitySetup>();
|
|
// _EmployeeWorkPlanSetups = new EmployeeWorkPlanSetupService().Get();
|
|
// _monthlyWorkPlan = new List<MonthlyWorkPlan>();
|
|
// if (distinctAttnDate.Count == 1)
|
|
// {
|
|
// // _monthlyWorkPlan = new MonthlyWorkPlanService().GetByDate(distinctAttnDate[0].AttnDate.Date);
|
|
// AttnMnthBenefitValueMapper obj_Mapper =
|
|
// new AttnMnthBenefitValueMapper(distinctAttnDate[0].AttnDate.Date, out applicableMonth);
|
|
// _atnMonthlyBenifits = new AttnMonthlyBenefitService().Get(empids, applicableMonth);
|
|
// }
|
|
// else
|
|
// {
|
|
// foreach (DailyAttnProcess daProcess in distinctAttnDate)
|
|
// {
|
|
// DateTime tempTime = DateTime.MinValue;
|
|
// AttnMnthBenefitValueMapper obj_Mapper =
|
|
// new AttnMnthBenefitValueMapper(daProcess.AttnDate.Date, out applicableMonth);
|
|
// List<AttnMonthlyBenefit> _atnMonthlyBenifitTemp =
|
|
// new AttnMonthlyBenefitService().Get(empids, applicableMonth);
|
|
// // _monthlyWorkPlan.AddRange(new MonthlyWorkPlanService().GetByDate(daProcess.AttnDate.Date));
|
|
// foreach (AttnMonthlyBenefit itemAMB in _atnMonthlyBenifitTemp)
|
|
// {
|
|
// if (!_atnMonthlyBenifits.Exists(o =>
|
|
// o.EmployeeID == itemAMB.EmployeeID && o.SalaryMonth == itemAMB.SalaryMonth &&
|
|
// o.ItemType == itemAMB.ItemType && o.ItemID == itemAMB.ItemID))
|
|
// {
|
|
// _atnMonthlyBenifits.Add(itemAMB);
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// AttnNationalHoliday oAttNHoliday = null;
|
|
// List<AttnWiseAllowance> oAttnWiseAllowances = new List<AttnWiseAllowance>();
|
|
// oAttnWiseAllowances = new AttnWiseAllowanceService().Get(payrollTypeID);
|
|
// Employee employee = null;
|
|
// List<Leave> oLeaves =
|
|
// new LeaveService().Get(EnumStatus.Regardless, string.Empty, string.Empty, payrollTypeID);
|
|
// foreach (DailyAttnProcess item in dailyattProcesses)
|
|
// {
|
|
// ewps = _EmployeeWorkPlanSetups.Where(o => o.EmployeeID == item.EmployeeID).FirstOrDefault();
|
|
// if (ewps == null)
|
|
// {
|
|
// //throw new Exception("Employee WorkPlan Not Defined for " + employee.EmployeeNo);
|
|
// continue;
|
|
// }
|
|
|
|
|
|
// //totalOT = 0;
|
|
// employee = item.Employee;
|
|
// attnShiftHoliday = null;
|
|
|
|
// monthlyWorkPlanActual = _monthlyWorkPlan.Where(o =>
|
|
// o.WorkPlanGroupID == ewps.WorkPlanGroupID && o.WorkDate == item.AttnDate.Date).FirstOrDefault();
|
|
// temporaryShift = null;
|
|
// PropertyInfo propertyInfo;
|
|
// PropertyInfo propertyInfoIs;
|
|
// AttnMnthBenefitValueMapper objMapper =
|
|
// new AttnMnthBenefitValueMapper(item.AttnDate.Date, out applicableMonth);
|
|
// propertyName = objMapper[item.AttnDate];
|
|
|
|
// if (attNHolidays.Count > 0)
|
|
// oAttNHoliday = attNHolidays.Where(o =>
|
|
// item.AttnDate.Date >= o.FromDate.Date && item.AttnDate.Date <= o.ToDate.Date)
|
|
// .FirstOrDefault();
|
|
// if (oAttNHoliday != null && oAttNHoliday.AttnShiftWiseNationalHolidays.Count > 0)
|
|
// {
|
|
// //if (item.TempShiftID != null)
|
|
// //{
|
|
// // monthlyWorkPlanTemp = _monthlyWorkPlan.Where(o =>
|
|
// // o.WorkDate == item.AttnDate.Date && o.Type == item.WorkDayType &&
|
|
// // o.ShiftID == item.TempShiftID).FirstOrDefault();
|
|
// // if (monthlyWorkPlanTemp != null)
|
|
// // attnShiftHoliday = oAttNHoliday.AttnShiftWiseNationalHolidays
|
|
// // .Where(o => o.WorkPlanGroupID == monthlyWorkPlanTemp.WorkPlanGroupID)
|
|
// // .FirstOrDefault();
|
|
// //}
|
|
// //else
|
|
// attnShiftHoliday = oAttNHoliday.AttnShiftWiseNationalHolidays
|
|
// .Where(o => o.WorkPlanGroupID == monthlyWorkPlanActual.WorkPlanGroupID)
|
|
// .FirstOrDefault();
|
|
|
|
// if (attnShiftHoliday == null)
|
|
// oAttNHoliday = null;
|
|
// }
|
|
|
|
// List<AttnWiseAllowance> itemAttnWiseAllowwances =
|
|
// AttnWiseAllowanceService.GetAllApplicableItem(oAttnWiseAllowances, item, oAttNHoliday, oLeaves,
|
|
// IsWorkingDay);
|
|
|
|
// if (itemAttnWiseAllowwances == null) continue;
|
|
|
|
// itemAttnWiseAllowwances = itemAttnWiseAllowwances
|
|
// .GroupBy(p => p.ID)
|
|
// .Select(g => g.First())
|
|
// .ToList();
|
|
// // Make Zero of Current Date
|
|
// propertyInfo = typeof(AttnMonthlyBenefit).GetProperties()
|
|
// .FirstOrDefault(p => p.Name == propertyName);
|
|
// propertyInfoIs = typeof(AttnMonthlyBenefit).GetProperties()
|
|
// .FirstOrDefault(p => p.Name == "Is" + propertyName);
|
|
|
|
// List<AttnMonthlyBenefit> _aMBenifits =
|
|
// _atnMonthlyBenifits.Where(o => o.EmployeeID == item.EmployeeID).ToList();
|
|
// if (IsManualEntry == true)
|
|
// {
|
|
// foreach (AttnMonthlyBenefit attnMB in _aMBenifits)
|
|
// {
|
|
// calculatedfValue = 0;
|
|
// propertyInfo.SetValue(attnMB, 0, null);
|
|
// propertyInfoIs.SetValue(attnMB, false, null);
|
|
// attnMB.Total = attnMB.Value1 + attnMB.Value2 + attnMB.Value3 + attnMB.Value4 +
|
|
// attnMB.Value5 + attnMB.Value6 + attnMB.Value7 + attnMB.Value8 +
|
|
// attnMB.Value9 + attnMB.Value10
|
|
// + attnMB.Value11 + attnMB.Value12 + attnMB.Value13 + attnMB.Value14 +
|
|
// attnMB.Value15 + attnMB.Value16 + attnMB.Value17 + attnMB.Value18 +
|
|
// attnMB.Value19 + attnMB.Value20
|
|
// + attnMB.Value21 + attnMB.Value22 + attnMB.Value23 + attnMB.Value24 +
|
|
// attnMB.Value25 + attnMB.Value26 + attnMB.Value27 + attnMB.Value28 +
|
|
// attnMB.Value29 + attnMB.Value30
|
|
// + attnMB.Value31 + attnMB.Adjustment;
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// foreach (AttnMonthlyBenefit attnMB in _aMBenifits)
|
|
// {
|
|
// calculatedfValue = 0;
|
|
// isCalculatedValue = (bool)propertyInfoIs.GetValue(attnMB, null);
|
|
// if (isCalculatedValue) continue;
|
|
// propertyInfo.SetValue(attnMB, 0, null);
|
|
// attnMB.Total = attnMB.Value1 + attnMB.Value2 + attnMB.Value3 + attnMB.Value4 +
|
|
// attnMB.Value5 + attnMB.Value6 + attnMB.Value7 + attnMB.Value8 +
|
|
// attnMB.Value9 + attnMB.Value10
|
|
// + attnMB.Value11 + attnMB.Value12 + attnMB.Value13 + attnMB.Value14 +
|
|
// attnMB.Value15 + attnMB.Value16 + attnMB.Value17 + attnMB.Value18 +
|
|
// attnMB.Value19 + attnMB.Value20
|
|
// + attnMB.Value21 + attnMB.Value22 + attnMB.Value23 + attnMB.Value24 +
|
|
// attnMB.Value25 + attnMB.Value26 + attnMB.Value27 + attnMB.Value28 +
|
|
// attnMB.Value29 + attnMB.Value30
|
|
// + attnMB.Value31 + attnMB.Adjustment;
|
|
// }
|
|
// }
|
|
|
|
// //if (totalOT > 0 && (item.AttenType == EnumAttendanceType.Leave || item.AttenType == EnumAttendanceType.Absent || item.AttenType == EnumAttendanceType.WeeklyHoliday))
|
|
// //{
|
|
// // if (!itemAttnWiseAllowwances.Exists(o => o.ProvisionType == enumPayrollComponentType.Allowance && o.ProvisionID == 82))
|
|
// // {
|
|
// // itemAttnWiseAllowwances.Add(oAttnWiseAllowances.Where(o => o.ProvisionType == enumPayrollComponentType.Allowance && o.ProvisionID == 82).FirstOrDefault());
|
|
// // }
|
|
// //}
|
|
|
|
// //if (item.TempShiftID != null)
|
|
// //{
|
|
// // if (totalOT == 0 && monthlyWorkPlanActual.Type == EnumWorkPlanDayType.WeeklyHoliday)
|
|
// // {
|
|
// // itemAttnWiseAllowwances.RemoveAll(o => o.ProvisionType == enumPayrollComponentType.Allowance && o.ProvisionID == 107);
|
|
// // }
|
|
// // if (monthlyWorkPlanActual.Type == EnumWorkPlanDayType.WorkingDay && monthlyWorkPlanActual.Shift.IsOverlapingDay == true && (item.AttenType == EnumAttendanceType.Present || item.AttenType == EnumAttendanceType.WeeklyHoliday) && item.AttenType != EnumAttendanceType.Absent)
|
|
// // {
|
|
// // if (!itemAttnWiseAllowwances.Exists(o => o.ProvisionType == enumPayrollComponentType.Allowance && o.ProvisionID == 107))
|
|
// // {
|
|
// // itemAttnWiseAllowwances.Add(oAttnWiseAllowances.Where(o => o.ProvisionType == enumPayrollComponentType.Allowance && o.ProvisionID == 107).FirstOrDefault());
|
|
// // }
|
|
// // }
|
|
// //}
|
|
|
|
// foreach (AttnWiseAllowance attSetup in itemAttnWiseAllowwances)
|
|
// {
|
|
// employee = item.Employee;
|
|
// AttnMonthlyBenefit oAttnWiseBenefit = _atnMonthlyBenifits
|
|
// .FirstOrDefault(x => x.EmployeeID == item.EmployeeID
|
|
// && attSetup.ProvisionID == x.ItemID
|
|
// && attSetup.ProvisionType == x.ItemType
|
|
// && x.SalaryMonth ==
|
|
// GlobalFunctions.AttendanceMonthEnd(item.AttnDate.Date));
|
|
// //if oAttnWiseBenefit is not null and IsEdited true for the selected date, then continue
|
|
|
|
// if (oAttnWiseBenefit == null)
|
|
// {
|
|
// oAttnWiseBenefit = new AttnMonthlyBenefit();
|
|
// oAttnWiseBenefit.EmployeeID = item.EmployeeID;
|
|
// oAttnWiseBenefit.ItemType = attSetup.ProvisionType;
|
|
// oAttnWiseBenefit.ItemID = attSetup.ProvisionID;
|
|
// oAttnWiseBenefit.SalaryMonth = GlobalFunctions.AttendanceMonthEnd(item.AttnDate.Date);
|
|
// _atnMonthlyBenifits.Add(oAttnWiseBenefit);
|
|
// }
|
|
|
|
// propertyInfo = typeof(AttnMonthlyBenefit).GetProperties()
|
|
// .FirstOrDefault(p => p.Name == propertyName);
|
|
// calculatedfValue = (double)propertyInfo.GetValue(oAttnWiseBenefit, null);
|
|
// propertyInfoIs = typeof(AttnMonthlyBenefit).GetProperties()
|
|
// .FirstOrDefault(p => p.Name == "Is" + propertyName);
|
|
// isCalculatedValue = (bool)propertyInfoIs.GetValue(oAttnWiseBenefit, null);
|
|
// if (IsManualEntry == false)
|
|
// {
|
|
// if (isCalculatedValue)
|
|
// {
|
|
// continue;
|
|
// }
|
|
// }
|
|
// //else
|
|
// //{
|
|
// //if (attSetup.ProvisionType == enumPayrollComponentType.Over_Time)
|
|
// //{
|
|
// // if (isCalculatedValue)
|
|
// // {
|
|
// // continue;
|
|
// // }
|
|
// //}
|
|
// //}
|
|
// //Shift sft = shifts.Where(o => o.ID == item.ShiftID).FirstOrDefault();
|
|
// //if (item.TempShiftID != null)
|
|
// // temporaryShift = shifts.Where(o => o.ID == item.TempShiftID).FirstOrDefault();
|
|
// //if (temporaryShift != null && attSetup.ProvisionType == enumPayrollComponentType.Ordinary_Hour)
|
|
// // calculatedfValue = attSetup.GetCalculatedHour(item, temporaryShift, oLeaves);
|
|
// //else
|
|
// // calculatedfValue = attSetup.GetCalculatedHour(item, sft, oLeaves);
|
|
|
|
// //#region InsurancePolicy
|
|
// //The reason behind this code block: Sometimes employee don't get their applicable conveyance even if he/she is present.
|
|
// //if (attSetup.ProvisionType == enumPayrollComponentType.Allowance && attSetup.ProvisionID == AttendanceBenefitTypeIDConstant.Conveyance_Allowance && calculatedfValue == 0)
|
|
// //{
|
|
// // if (item.AttenType == EnumAttendanceType.Present && item.InTime != DateTime.MinValue && item.OutTime != DateTime.MinValue)
|
|
// // {
|
|
// // calculatedfValue = 1;
|
|
// // propertyInfoIs.SetValue(oAttnWiseBenefit, true, null);
|
|
// // }
|
|
// //}
|
|
|
|
// //if (attSetup.ProvisionType == enumPayrollComponentType.Ordinary_Hour)
|
|
// // item.ORDHour = calculatedfValue;
|
|
|
|
// //#endregion
|
|
// //if (calculatedfValue > 0 || newValue >0)
|
|
// //{
|
|
|
|
// if (oAttnWiseBenefit.ItemType == enumPayrollComponentType.Over_Time)
|
|
// {
|
|
// calculatedfValue = new AttnMonthlyBenefitService().CalculateOvertimeValue(attSetup, item, payrollTypeID);
|
|
// }
|
|
|
|
// propertyInfo.SetValue(oAttnWiseBenefit, calculatedfValue, null);
|
|
// oAttnWiseBenefit.Total =
|
|
// oAttnWiseBenefit.Value1 + oAttnWiseBenefit.Value2 + oAttnWiseBenefit.Value3 +
|
|
// oAttnWiseBenefit.Value4 + oAttnWiseBenefit.Value5 + oAttnWiseBenefit.Value6 +
|
|
// oAttnWiseBenefit.Value7 + oAttnWiseBenefit.Value8 + oAttnWiseBenefit.Value9 +
|
|
// oAttnWiseBenefit.Value10
|
|
// + oAttnWiseBenefit.Value11 + oAttnWiseBenefit.Value12 + oAttnWiseBenefit.Value13 +
|
|
// oAttnWiseBenefit.Value14 + oAttnWiseBenefit.Value15 + oAttnWiseBenefit.Value16 +
|
|
// oAttnWiseBenefit.Value17 + oAttnWiseBenefit.Value18 + oAttnWiseBenefit.Value19 +
|
|
// oAttnWiseBenefit.Value20
|
|
// + oAttnWiseBenefit.Value21 + oAttnWiseBenefit.Value22 + oAttnWiseBenefit.Value23 +
|
|
// oAttnWiseBenefit.Value24 + oAttnWiseBenefit.Value25 + oAttnWiseBenefit.Value26 +
|
|
// oAttnWiseBenefit.Value27 + oAttnWiseBenefit.Value28 + oAttnWiseBenefit.Value29 +
|
|
// oAttnWiseBenefit.Value30
|
|
// + oAttnWiseBenefit.Value31 + oAttnWiseBenefit.Adjustment;
|
|
|
|
// if (oAttnWiseBenefit.ItemType == enumPayrollComponentType.Over_Time)
|
|
// {
|
|
// oAttnWiseBenefit.Amount =
|
|
// AttnMonthlyBenefitService.CalculateOvertimeAmount(attSetup, item,
|
|
// oAttnWiseBenefit.Total, payrollTypeID);
|
|
// }
|
|
|
|
// //}
|
|
// }
|
|
// }
|
|
|
|
// // process go here
|
|
// }
|
|
// catch (Exception ex)
|
|
// {
|
|
// throw new Exception(ex.Message);
|
|
// }
|
|
|
|
|
|
// return _atnMonthlyBenifits;
|
|
|
|
// #endregion
|
|
//}
|
|
|
|
public static void RefreshAttendanceRegularizationApplyObject(AttendanceRegularizationDTO attendanceRegularizationDTO, DailyAttnProcess dailyAttnProcess)
|
|
{
|
|
bool isChanged = false;
|
|
DateTime tempDateTime = DateTime.MinValue;
|
|
EnumAttendanceType previousStatus;
|
|
DateTime? previousInTime = DateTime.MinValue;
|
|
DateTime? previousOutTime = DateTime.MinValue;
|
|
previousInTime = dailyAttnProcess.InTime;
|
|
previousOutTime = dailyAttnProcess.OutTime;
|
|
previousStatus = dailyAttnProcess.AttenType;
|
|
dailyAttnProcess.IsManualEntry = true;
|
|
EnumAttendanceType value = attendanceRegularizationDTO.Status;
|
|
dailyAttnProcess.AttenType = value;
|
|
if (previousStatus != value)
|
|
isChanged = true;
|
|
if (!string.IsNullOrEmpty(attendanceRegularizationDTO.Comments))
|
|
{
|
|
dailyAttnProcess.Comments = attendanceRegularizationDTO.Comments;
|
|
isChanged = true;
|
|
}
|
|
|
|
if (attendanceRegularizationDTO.InTime != null && attendanceRegularizationDTO.InTime != DateTime.MinValue)
|
|
{
|
|
if (attendanceRegularizationDTO.InTime != null)
|
|
{
|
|
tempDateTime = (DateTime)attendanceRegularizationDTO.InTime;
|
|
dailyAttnProcess.InTime = new DateTime(dailyAttnProcess.AttnDate.Year, dailyAttnProcess.AttnDate.Month, dailyAttnProcess.AttnDate.Day, tempDateTime.Hour, tempDateTime.Minute, tempDateTime.Second);
|
|
}
|
|
}
|
|
|
|
if (attendanceRegularizationDTO.OutTime != DateTime.MinValue)
|
|
{
|
|
if (attendanceRegularizationDTO.OutTime != null)
|
|
{
|
|
dailyAttnProcess.OutTime = (DateTime)attendanceRegularizationDTO.OutTime;
|
|
}
|
|
}
|
|
if (previousInTime != dailyAttnProcess.InTime)
|
|
isChanged = true;
|
|
if (previousOutTime != dailyAttnProcess.OutTime)
|
|
isChanged = true;
|
|
|
|
if (isChanged == true)
|
|
{
|
|
dailyAttnProcess.ActualInTime = previousInTime;
|
|
dailyAttnProcess.ActualOutTime = previousOutTime;
|
|
dailyAttnProcess.WFStatus = EnumWFAttnStatus.EmpSubmitted;
|
|
}
|
|
else
|
|
{
|
|
dailyAttnProcess.WFStatus = EnumWFAttnStatus.NotApplicable;
|
|
}
|
|
}
|
|
|
|
public static void RefreshAttendanceRegularizationApproveOrRejectObject(AttendanceRegularizationDTO attendanceRegularizationDTO,
|
|
DailyAttnProcess dailyAttnProcess)
|
|
{
|
|
bool isChanged = false;
|
|
EnumAttendanceType previousStatus;
|
|
DateTime? previousInTime = dailyAttnProcess.InTime;
|
|
DateTime? previousOutTime = dailyAttnProcess.OutTime;
|
|
previousStatus = dailyAttnProcess.AttenType;
|
|
dailyAttnProcess.IsManualEntry = true;
|
|
EnumAttendanceType value = attendanceRegularizationDTO.Status;
|
|
dailyAttnProcess.AttenType = value;
|
|
if (previousStatus != value)
|
|
isChanged = true;
|
|
if (!string.IsNullOrEmpty(attendanceRegularizationDTO.LMRemarks))
|
|
{
|
|
dailyAttnProcess.LMRemarks = attendanceRegularizationDTO.LMRemarks;
|
|
isChanged = true;
|
|
}
|
|
|
|
if (attendanceRegularizationDTO.InTime != null && attendanceRegularizationDTO.InTime != DateTime.MinValue)
|
|
{
|
|
if (attendanceRegularizationDTO.InTime != null)
|
|
{
|
|
DateTime tempDateTime = (DateTime)attendanceRegularizationDTO.InTime;
|
|
dailyAttnProcess.InTime = new DateTime(dailyAttnProcess.AttnDate.Year, dailyAttnProcess.AttnDate.Month, dailyAttnProcess.AttnDate.Day, tempDateTime.Hour, tempDateTime.Minute, tempDateTime.Second);
|
|
}
|
|
}
|
|
|
|
if (attendanceRegularizationDTO.OutTime != DateTime.MinValue)
|
|
{
|
|
if (attendanceRegularizationDTO.OutTime != null)
|
|
{
|
|
dailyAttnProcess.OutTime = (DateTime)attendanceRegularizationDTO.OutTime;
|
|
}
|
|
}
|
|
if (previousInTime != dailyAttnProcess.InTime)
|
|
isChanged = true;
|
|
if (previousOutTime != dailyAttnProcess.OutTime)
|
|
isChanged = true;
|
|
dailyAttnProcess.WFStatus = attendanceRegularizationDTO.WFStatus;
|
|
if (isChanged == true)
|
|
{
|
|
dailyAttnProcess.ActualInTime = previousInTime;
|
|
dailyAttnProcess.ActualOutTime = previousOutTime;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
public static List<AttendanceRegularizationDTO> GetNotSubmittedAttnData(List<DailyAttnProcess> dailyAttnProcesses, int payrollTypeId)
|
|
{
|
|
List<AttendanceRegularizationDTO> attendanceRegularizationDTOs = new List<AttendanceRegularizationDTO>();
|
|
List<Shift> Shifts = new ShiftService().GetAllShift();
|
|
List<Leave> oLeaves = new LeaveService().GetAll();
|
|
List<AttnNationalHoliday> nationalHolidays = new AttnNationalHolidayService().Get(EnumStatus.Regardless, payrollTypeId);
|
|
|
|
foreach (DailyAttnProcess dailyAttnProcess in dailyAttnProcesses)
|
|
{
|
|
Shift shift = Shifts.FirstOrDefault(x => x.ID == dailyAttnProcess.ShiftID);
|
|
|
|
AttendanceRegularizationDTO attendanceRegularizationDTO = new AttendanceRegularizationDTO();
|
|
attendanceRegularizationDTO.DailyAttnProcessID = dailyAttnProcess.ID;
|
|
|
|
attendanceRegularizationDTO.AttendanceDate = dailyAttnProcess.AttnDate.ToString("dd MMM yyyy");
|
|
attendanceRegularizationDTO.Shift = shift != null ? shift.Name : string.Empty;
|
|
attendanceRegularizationDTO.InTime = dailyAttnProcess.InTime != null ? dailyAttnProcess.InTime : null;
|
|
attendanceRegularizationDTO.OutTime = dailyAttnProcess.OutTime != null ? dailyAttnProcess.OutTime : null;
|
|
attendanceRegularizationDTO.lateHour = dailyAttnProcess.LateHour;
|
|
attendanceRegularizationDTO.earlyHour = dailyAttnProcess.EarlyHour;
|
|
attendanceRegularizationDTO.workHour = dailyAttnProcess.WorkHour;
|
|
attendanceRegularizationDTO.otHour = dailyAttnProcess.OTHour;
|
|
attendanceRegularizationDTO.IsLate = dailyAttnProcess.IsLate;
|
|
|
|
|
|
|
|
|
|
attendanceRegularizationDTO.ActualInTime = dailyAttnProcess.ActualInTime != null ? dailyAttnProcess.ActualInTime : null;
|
|
attendanceRegularizationDTO.ActualOutTime = dailyAttnProcess.ActualOutTime != null ? dailyAttnProcess.ActualOutTime : null;
|
|
attendanceRegularizationDTO.WFStatus = dailyAttnProcess.WFStatus;
|
|
attendanceRegularizationDTO.WFStatusDescription = DailyAttnProcess.getWFstatusDescription(dailyAttnProcess.WFStatus);
|
|
attendanceRegularizationDTO.Status = dailyAttnProcess.AttenType;
|
|
attendanceRegularizationDTO.StatusDescription = dailyAttnProcess.AttenType.ToString();
|
|
attendanceRegularizationDTO.Comments = dailyAttnProcess.Comments;
|
|
attendanceRegularizationDTO.LMRemarks = dailyAttnProcess.LMRemarks;
|
|
attendanceRegularizationDTO.empRemarks = dailyAttnProcess.EmpRemarks;
|
|
if (dailyAttnProcess.AttenType == EnumAttendanceType.Leave && dailyAttnProcess.ReferenceID != null)
|
|
{
|
|
Leave oLeave = oLeaves.Where(o => o.ID == dailyAttnProcess.ReferenceID).FirstOrDefault();
|
|
attendanceRegularizationDTO.ReferenceId = (int)dailyAttnProcess.ReferenceID;
|
|
attendanceRegularizationDTO.Reference = oLeave == null ? "" : oLeave.Description;
|
|
}
|
|
else if (dailyAttnProcess.AttenType == EnumAttendanceType.Holiday && dailyAttnProcess.ReferenceID != null)
|
|
{
|
|
AttnNationalHoliday nationalHoliday = nationalHolidays.Where(o => o.ID == dailyAttnProcess.ReferenceID).FirstOrDefault();
|
|
attendanceRegularizationDTO.ReferenceId = (int)dailyAttnProcess.ReferenceID;
|
|
attendanceRegularizationDTO.Reference = nationalHoliday == null ? "" : nationalHoliday.Description;
|
|
}
|
|
else
|
|
{
|
|
attendanceRegularizationDTO.ReferenceId = 0;
|
|
attendanceRegularizationDTO.Reference = string.Empty;
|
|
}
|
|
attendanceRegularizationDTOs.Add(attendanceRegularizationDTO);
|
|
}
|
|
return attendanceRegularizationDTOs;
|
|
}
|
|
public static List<DailyAttnProcess> GetNotSubmittedAttnDataForLM(string oEmps, DateTime fromDate, DateTime toDate) //,bool isCurrentMonth)
|
|
{
|
|
if (oEmps == "")
|
|
{
|
|
throw new CustomException(EnumExceptionType.Validation, "No Employee selected.");
|
|
}
|
|
List<DailyAttnProcess> oNotYetSubmittedAttnDatas = new DailyAttnProcessService().GetAttnDataByWFStatusForLM(fromDate, toDate, oEmps, EnumWFAttnStatus.EmpSubmitted);
|
|
|
|
return oNotYetSubmittedAttnDatas;
|
|
}
|
|
|
|
|
|
public List<SalaryProcessStatus> BenifitProcess(int userid, int PayrollTypeId)
|
|
{
|
|
try
|
|
{
|
|
List<SalaryProcessStatus> ErrorList = new List<SalaryProcessStatus>();
|
|
List<ADParameterEmployee> AdparamEmployee = new List<ADParameterEmployee>();
|
|
List<EmployeeUnAuthorizeLeave> uleaves = new List<EmployeeUnAuthorizeLeave>();
|
|
List<EmployeeOverTime> EmpOverTimes = new List<EmployeeOverTime>();
|
|
DailyAttnProcessService dapService = new DailyAttnProcessService();
|
|
TermParameterService tps = new TermParameterService();
|
|
AttnWiseAllowance attnAllow = new AttnWiseAllowance();
|
|
|
|
// List<Employee> employees = new EmployeeService().GetByEmpIDs("352,70");
|
|
List<Employee> employees = new EmployeeService().GetAllEmps();
|
|
List<ADParameter> oadParameters = new ADParameterService().GetWithDetail(EnumStatus.Active, PayrollTypeId);
|
|
PayrollType oPayrollType = new PayrollTypeService().Get(PayrollTypeId);
|
|
List<TermParameter> termParameters = tps.GetwithDetail(oPayrollType.ID);
|
|
AttnParametarization oAttnParam = new AttnParametarizationService().Get(oPayrollType.ID);
|
|
|
|
DateTime attnStartDate = GlobalFunctions.AttendanceMonthStart(GlobalExtensions.FirstDateOfMonth(oPayrollType.NextPayProcessDate), oAttnParam.MonthStartDay);
|
|
DateTime attnEndDate = GlobalFunctions.AttendanceMonthEnd(attnStartDate.AddDays(1), oAttnParam.MonthStartDay);
|
|
|
|
List<UnAuthorizeLeaveParam> oauthParams = new UnAuthorizeLeaveParamService().Get(oPayrollType.ID, true);
|
|
DateTime nextPayMonth = oPayrollType.NextPayProcessDate;
|
|
|
|
if (oauthParams == null || oauthParams.Count == 0)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus("", "", " No Authorize Leave parameter found"));
|
|
}
|
|
|
|
#region Absent Deduct
|
|
|
|
DataSet EmpAbsentDays = dapService.GetUnauthorizeCount(attnStartDate, attnEndDate, oPayrollType.ID);
|
|
if (EmpAbsentDays != null
|
|
&& EmpAbsentDays.Tables[0] != null
|
|
&& EmpAbsentDays.Tables[0].Rows.Count > 0
|
|
&& oauthParams.Count > 0)
|
|
{
|
|
|
|
foreach (DataRow oRow in EmpAbsentDays.Tables[0].Rows)
|
|
{
|
|
Employee oemp = employees.FirstOrDefault(x => x.ID == Convert.ToInt32(oRow["EMPLOYEEID"].ToString()));
|
|
if (oemp == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus("", "", " Employee not found, Internal ID:" + oRow["EMPLOYEEID"].ToString()));
|
|
continue;
|
|
}
|
|
|
|
double tempAmount = 0;
|
|
double absentAcount = 0;
|
|
double provAbsent = 0;
|
|
if (oAttnParam.AbsentProvLeaveID != null && (oemp.ConfirDate == DateTime.MinValue || (oemp.ConfirDate >
|
|
attnStartDate && oemp.ConfirDate < attnEndDate)))
|
|
{
|
|
|
|
UnAuthorizeLeaveParam param = UnAuthorizeLeaveParam.GetParameter(oauthParams, (int)oemp.GradeID, (int)oAttnParam.AbsentProvLeaveID);
|
|
if (param == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus(oemp.EmployeeNo, oemp.Name, " Absent Provisional Parameter not found."));
|
|
continue;
|
|
}
|
|
absentAcount = dapService.AbsentCount(attnStartDate, (DateTime)oemp.ConfirDate == DateTime.MinValue ? attnEndDate : (DateTime)oemp.ConfirDate, oemp.ID, oPayrollType.ID);
|
|
|
|
if (absentAcount > 4)
|
|
{
|
|
tempAmount = absentAcount - 4;
|
|
absentAcount = 1;
|
|
}
|
|
provAbsent = absentAcount + tempAmount / 3;
|
|
EmployeeUnAuthorizeLeave uProvisionEmp = new EmployeeUnAuthorizeLeave(oemp.ID, (int)oAttnParam.AbsentProvLeaveID,
|
|
nextPayMonth, nextPayMonth, attnStartDate, attnEndDate, null,
|
|
provAbsent, param.ID, false);
|
|
uleaves.Add(uProvisionEmp);
|
|
}
|
|
|
|
tempAmount = 0;
|
|
if (oRow["TOTAL"] == DBNull.Value)
|
|
{
|
|
continue;
|
|
}
|
|
absentAcount = Convert.ToDouble(oRow["TOTAL"]);
|
|
|
|
if (absentAcount > 0)
|
|
{
|
|
UnAuthorizeLeaveParam param = UnAuthorizeLeaveParam.GetParameter(oauthParams, (int)oemp.GradeID, 1);
|
|
if (param == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus(oemp.EmployeeNo, oemp.Name, " Absent Parameter not found."));
|
|
continue;
|
|
}
|
|
EmployeeUnAuthorizeLeave uleave = new EmployeeUnAuthorizeLeave(oemp.ID, 1,
|
|
nextPayMonth, nextPayMonth, attnStartDate, attnEndDate, null,
|
|
absentAcount, param.ID, false);
|
|
uleaves.Add(uleave);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion Absent Deduct
|
|
|
|
if (oAttnParam.lwpLeaveTypeID != null)
|
|
{
|
|
DataSet EmpLWPDays = dapService.GetZandDocLeaveDays(attnStartDate, attnEndDate, EnumAttendanceType.Leave, oPayrollType.ID, oAttnParam.lwpLeaveTypeID);
|
|
#region LWP deduct
|
|
if (EmpLWPDays != null
|
|
&& EmpLWPDays.Tables[0] != null
|
|
&& EmpLWPDays.Tables[0].Rows.Count > 0
|
|
&& oauthParams.Count > 0
|
|
)
|
|
{
|
|
UnAuthorizeLeaveParam oprm = new BO.UnAuthorizeLeaveParam();
|
|
foreach (DataRow oRow in EmpLWPDays.Tables[0].Rows)
|
|
{
|
|
Employee oemp = employees.FirstOrDefault(x => x.ID == Convert.ToInt32(oRow["EMPLOYEEID"].ToString()));
|
|
if (oemp == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus("", "", " Employee not found, Internal ID:" + oRow["EMPLOYEEID"].ToString()));
|
|
continue;
|
|
}
|
|
|
|
int absentAcount = 0;
|
|
absentAcount = Convert.ToInt32(oRow["TOTAL"].ToString()) - absentAcount;
|
|
if (oAttnParam.lwpProvLeaveID > 0 && (oemp.ConfirDate == DateTime.MinValue || (oemp.ConfirDate >
|
|
attnStartDate && oemp.ConfirDate < attnEndDate)))
|
|
{
|
|
|
|
|
|
UnAuthorizeLeaveParam param = UnAuthorizeLeaveParam.GetParameter(oauthParams, (int)oemp.GradeID, (int)oAttnParam.lwpProvLeaveID);
|
|
if (param == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus(oemp.EmployeeNo, oemp.Name, " Absent Provisional Parameter not found."));
|
|
continue;
|
|
}
|
|
|
|
if (absentAcount > 0)
|
|
{
|
|
EmployeeUnAuthorizeLeave uProvisionEmp = new EmployeeUnAuthorizeLeave(oemp.ID, (int)oAttnParam.lwpProvLeaveID,
|
|
nextPayMonth, nextPayMonth, attnStartDate, attnEndDate, null,
|
|
absentAcount, param.ID, false);
|
|
uleaves.Add(uProvisionEmp);
|
|
}
|
|
absentAcount = Convert.ToInt32(oRow["TOTAL"].ToString()) - absentAcount;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (absentAcount > 0)
|
|
{
|
|
UnAuthorizeLeaveParam param = UnAuthorizeLeaveParam.GetParameter(oauthParams, (int)oemp.GradeID, (int)oAttnParam.lwpLeaveID);
|
|
if (param == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus(oemp.EmployeeNo, oemp.Name, " Absent Provisional Parameter not found."));
|
|
continue;
|
|
}
|
|
EmployeeUnAuthorizeLeave uleave = new EmployeeUnAuthorizeLeave(oemp.ID, (int)oAttnParam.lwpLeaveID,
|
|
nextPayMonth, nextPayMonth, attnStartDate, attnEndDate, null,
|
|
absentAcount, param.ID, false);
|
|
uleaves.Add(uleave);
|
|
}
|
|
}
|
|
}
|
|
#endregion LWP deduct
|
|
}
|
|
if (oAttnParam.MaternityLeaveTypeID != null)
|
|
{
|
|
DataSet EmpMaternitydays = dapService.GetZandDocLeaveDays(attnStartDate, attnEndDate, EnumAttendanceType.Leave, oPayrollType.ID, oAttnParam.MaternityLeaveTypeID);
|
|
#region Maternity Deduction
|
|
if (EmpMaternitydays != null
|
|
&& EmpMaternitydays.Tables[0] != null
|
|
&& EmpMaternitydays.Tables[0].Rows.Count > 0
|
|
&& oauthParams.Count > 0
|
|
)
|
|
{
|
|
UnAuthorizeLeaveParam oprm = new BO.UnAuthorizeLeaveParam();
|
|
foreach (DataRow oRow in EmpMaternitydays.Tables[0].Rows)
|
|
{
|
|
Employee oemp = employees.FirstOrDefault(x => x.ID == Convert.ToInt32(oRow["EMPLOYEEID"].ToString()));
|
|
if (oemp == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus("", "", " Employee not found, Internal ID:" + oRow["EMPLOYEEID"].ToString()));
|
|
continue;
|
|
}
|
|
|
|
int absentAcount = 0;
|
|
absentAcount = Convert.ToInt32(oRow["TOTAL"].ToString()) ;
|
|
|
|
|
|
if (absentAcount > 0)
|
|
{
|
|
UnAuthorizeLeaveParam param = UnAuthorizeLeaveParam.GetParameter(oauthParams, (int)oemp.GradeID, (int)oAttnParam.MaternityUnAuthLeaveID);
|
|
if (param == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus(oemp.EmployeeNo, oemp.Name, " Maternity Benifits Parameters not found."));
|
|
continue;
|
|
}
|
|
EmployeeUnAuthorizeLeave uleave = new EmployeeUnAuthorizeLeave(oemp.ID, (int)oAttnParam.MaternityLeaveTypeID,
|
|
nextPayMonth, nextPayMonth, attnStartDate, attnEndDate, null,
|
|
absentAcount, param.ID, false);
|
|
uleaves.Add(uleave);
|
|
}
|
|
}
|
|
}
|
|
#endregion Maternity Deduction
|
|
}
|
|
|
|
|
|
#region Late Deduct
|
|
// Late Calculation
|
|
if(oAttnParam.lateAbsentLeaveID != null)
|
|
{
|
|
DataSet LateDays = dapService.GetWorkingDayLateCount(attnStartDate, attnEndDate, oPayrollType.ID);
|
|
if (LateDays != null && LateDays.Tables[0] != null
|
|
&& LateDays.Tables[0].Rows.Count > 0 && oAttnParam.lateAbsentLeaveID > 0)
|
|
{
|
|
|
|
foreach (DataRow oRow in LateDays.Tables[0].Rows)
|
|
{
|
|
|
|
|
|
int nCount = Convert.ToInt32(oRow["TOTAL"].ToString());
|
|
if (nCount < oAttnParam.MonthlyLateForAbsent) continue;
|
|
if (oAttnParam.MonthlyLateForAbsent == 0) continue;
|
|
nCount = nCount / oAttnParam.MonthlyLateForAbsent;
|
|
|
|
Employee oemp = employees.FirstOrDefault(x => x.ID == Convert.ToInt32(oRow["EMPLOYEEID"].ToString()));
|
|
int ProvisionLateAcount = 0;
|
|
|
|
|
|
int lateAbsentCount = 0;
|
|
if (oAttnParam.lateAbsentProvLeaveID != null && (oemp.ConfirDate == DateTime.MinValue || (oemp.ConfirDate >
|
|
attnStartDate && oemp.ConfirDate < attnEndDate)))
|
|
{
|
|
ProvisionLateAcount = dapService.GetLateCount(attnStartDate, (DateTime)oemp.ConfirDate == DateTime.MinValue ? attnEndDate : (DateTime)oemp.ConfirDate, oemp.ID, oPayrollType.ID);
|
|
UnAuthorizeLeaveParam param = UnAuthorizeLeaveParam.GetParameter(oauthParams, oemp.ID, (int)oAttnParam.lateAbsentProvLeaveID);
|
|
if (param == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus(oemp.EmployeeNo, oemp.Name, " Late Absent Provisional Parameter not found."));
|
|
}
|
|
int tempAmount = 0;
|
|
if (ProvisionLateAcount > 4)
|
|
{
|
|
lateAbsentCount = 1;
|
|
tempAmount = ProvisionLateAcount - 4;
|
|
}
|
|
lateAbsentCount = lateAbsentCount + tempAmount / 3;
|
|
if (lateAbsentCount > 0)
|
|
{
|
|
EmployeeUnAuthorizeLeave uProvisionEmp = new EmployeeUnAuthorizeLeave(oemp.ID, (int)oAttnParam.lateAbsentProvLeaveID,
|
|
nextPayMonth, nextPayMonth, attnStartDate, attnEndDate, null,
|
|
lateAbsentCount, param.ID, false);
|
|
uleaves.Add(uProvisionEmp);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
int TotallateCount = Convert.ToInt32(oRow["TOTAL"].ToString()) - ProvisionLateAcount;
|
|
int lateAbsent = 0;
|
|
if (TotallateCount > 4)
|
|
{
|
|
lateAbsent = 1;
|
|
TotallateCount = TotallateCount - 4;
|
|
}
|
|
|
|
lateAbsent = lateAbsent + TotallateCount / 3;
|
|
|
|
if (lateAbsent > 0)
|
|
{
|
|
UnAuthorizeLeaveParam param = UnAuthorizeLeaveParam.GetParameter(oauthParams, (int)oemp.GradeID, (int)oAttnParam.lateAbsentLeaveID);
|
|
if (param == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus(oemp.EmployeeNo, oemp.Name, " Late Absent Parameter not found."));
|
|
}
|
|
EmployeeUnAuthorizeLeave ulateCount = new EmployeeUnAuthorizeLeave(oemp.ID, (int)oAttnParam.lateAbsentLeaveID,
|
|
nextPayMonth, nextPayMonth, attnStartDate, attnEndDate, null,
|
|
lateAbsent, param.ID, false);
|
|
uleaves.Add(ulateCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
#endregion
|
|
|
|
if (oAttnParam.AllPresentAllowanceID != null)
|
|
{
|
|
DataSet PresentDays = dapService.GetZandDocLeaveDays(attnStartDate, attnEndDate, EnumAttendanceType.Present, oPayrollType.ID, null);
|
|
|
|
foreach (Employee emp in employees)
|
|
{
|
|
if (emp.PayrollTypeID != oPayrollType.ID) continue;
|
|
if (emp.GradeID == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus(emp.EmployeeNo, emp.Name, " Employee Not yet Assigned to grade"));
|
|
continue;
|
|
|
|
}
|
|
List<ADParameter> applicableParams = new ADParameterService().GetApplicableParameters(emp, (int)emp.GradeID, oadParameters);
|
|
if (applicableParams == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus(emp.EmployeeNo, emp.Name, " No Alloance parameters found for Attendance Bonus"));
|
|
continue;
|
|
}
|
|
|
|
ADParameter applicableParam = new ADParameterService().GetApplicableParameter(emp, (int)emp.GradeID, oadParameters, (int)oAttnParam.AllPresentAllowanceID);
|
|
|
|
if (applicableParam != null)
|
|
{
|
|
DataRow pdr = PresentDays.Tables[0].AsEnumerable().FirstOrDefault(x =>
|
|
Convert.ToInt32(x["EmployeeID"].ToString()) == emp.ID);
|
|
if (pdr == null) continue;
|
|
double prdays = Convert.ToDouble(pdr["TOTAL"].ToString());
|
|
|
|
if (prdays >= oAttnParam.AllPresentAllowanceDays)
|
|
{
|
|
ADParameterEmployee adparamEmp = new ADParameterEmployee();
|
|
adparamEmp.EmployeeID = emp.ID;
|
|
adparamEmp.MonthlyAmount = prdays * applicableParam.FlatAmount;
|
|
adparamEmp.Days = prdays;
|
|
adparamEmp.Periodicity = EnumPeriodicity.Monthly;
|
|
adparamEmp.FormDate = GlobalFunctions.FirstDateOfMonth(oPayrollType.NextPayProcessDate);
|
|
adparamEmp.TillDate = GlobalFunctions.LastDateOfMonth(oPayrollType.NextPayProcessDate);
|
|
adparamEmp.ADParameterID = applicableParam.ID;
|
|
adparamEmp.ADEmpType = EnumADEmpType.AppliedToIndividual;
|
|
adparamEmp.AllowDeductID = (int)oAttnParam.AllPresentAllowanceID;
|
|
adparamEmp.Arreartype = EnumArrearType.NotPresent;
|
|
adparamEmp.CreatedBy = userid;
|
|
adparamEmp.CreatedDate = DateTime.Today;
|
|
AdparamEmployee.Add(adparamEmp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#region Attendance Allowance process
|
|
|
|
List<Shift> shifts = new List<Shift>();
|
|
DataTable dtDailyAttendanceAllowances = new DataTable();
|
|
|
|
shifts = new ShiftService().GetAllShiftByPayrollType(PayrollTypeId);
|
|
|
|
dtDailyAttendanceAllowances = new DailyAttendanceAllowanceService().GetByAttnbySalaryMonth(oPayrollType.NextPayProcessDate, PayrollTypeId);
|
|
if (dtDailyAttendanceAllowances != null && dtDailyAttendanceAllowances.Rows.Count > 0)
|
|
{
|
|
foreach (DataRow item in dtDailyAttendanceAllowances.Rows)
|
|
{
|
|
Employee tempEmployee = employees.Where(emp => emp.ID.ToString() == item["EmployeeID"].ToString()).FirstOrDefault();
|
|
EnumattnBeniftsType btype = (EnumattnBeniftsType)Convert.ToInt32(item["type"].ToString());
|
|
if (btype == EnumattnBeniftsType.Allowance)
|
|
AdparamEmployee = MakeADParameterEmployeeObj(ref AdparamEmployee, ref ErrorList, tempEmployee,
|
|
oadParameters,
|
|
oPayrollType, Convert.ToInt32(item["ItemID"].ToString()), Convert.ToInt32(item["value"].ToString()), userid);
|
|
else if(btype == EnumattnBeniftsType.OT)
|
|
EmpOverTimes = MakeEmployeeOvertimeObj(ref EmpOverTimes, ref ErrorList, tempEmployee, termParameters,
|
|
oPayrollType, Convert.ToInt32(item["ItemID"].ToString()), Convert.ToDouble(item["value"].ToString()), userid);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
List<Term> terms = new TermService().Get(EnumStatus.Active, PayrollTypeId);
|
|
foreach (Term trm in terms)
|
|
{
|
|
DataSet EmpOTHours = new ShiftTermService().GetEmpOT(oPayrollType.NextPayProcessDate, trm.ID);
|
|
foreach (DataRow Dr in EmpOTHours.Tables[0].Rows)
|
|
{
|
|
Employee tempEmployee = employees.Where(emp => emp.ID.ToString() == Dr["EmployeeID"].ToString()).FirstOrDefault();
|
|
if (tempEmployee == null) continue;
|
|
if (tempEmployee.GradeID == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus(tempEmployee.EmployeeNo, tempEmployee.Name, "Grade not assinged"));
|
|
continue;
|
|
|
|
}
|
|
if (Dr["TotalOT"] == DBNull.Value)
|
|
{
|
|
// ErrorList.Add(new SalaryProcessStatus(tempEmployee.EmployeeNo, tempEmployee.Name, "value can't be null "));
|
|
continue;
|
|
}
|
|
|
|
EmpOverTimes = MakeEmployeeOvertimeObj(ref EmpOverTimes, ref ErrorList, tempEmployee, termParameters,
|
|
oPayrollType, trm.ID, Convert.ToDouble(Dr["TotalOT"]), userid);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
if (ErrorList.Count == 0)
|
|
{
|
|
if (AdparamEmployee.Count > 0 || EmpOverTimes.Count > 0 || uleaves.Count > 0)
|
|
{
|
|
new AttnMonthlyBenefitService().SaveAsBenifits(oPayrollType.ID, AdparamEmployee, EmpOverTimes, uleaves);
|
|
|
|
}
|
|
else ErrorList.Add(new SalaryProcessStatus("", "", "There is nothing to process or Save. please check your Attandance data and related setups"));
|
|
}
|
|
|
|
return ErrorList;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception(ex.Message);
|
|
}
|
|
}
|
|
private List<ADParameterEmployee> MakeADParameterEmployeeObj(ref List<ADParameterEmployee> AdparamEmployee, ref List<SalaryProcessStatus> ErrorList,
|
|
Employee tempEmployee, List<ADParameter> oadParameters,
|
|
PayrollType oPayrollType, int allowanceId, double total, int userid)
|
|
{
|
|
List<ADParameter> applicableParams = new ADParameterService().GetApplicableParameters(tempEmployee, (int)tempEmployee.GradeID, oadParameters);
|
|
if (applicableParams == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus(tempEmployee.EmployeeNo, tempEmployee.Name, " No Alloance/Benifits parameters found in live allowance/Benifits list"));
|
|
return AdparamEmployee;
|
|
}
|
|
var AppliedIndvParam = applicableParams.Where(x => x.EntitleType == EnumEntitleType.Individual && x.IsDependsOnAttendance == true && x.Periodicity == EnumPeriodicity.Monthly && x.AllowDeductID == allowanceId).ToList();
|
|
if (AppliedIndvParam == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus(tempEmployee.EmployeeNo, tempEmployee.Name, " Individualy and depand on Attandance declared Alloance/Benifits parameters found in live allowance/Benifits list"));
|
|
return AdparamEmployee;
|
|
}
|
|
foreach (ADParameter indvParam in AppliedIndvParam)
|
|
{
|
|
ADParameterEmployee adparamEmp = new ADParameterEmployee();
|
|
adparamEmp.EmployeeID = tempEmployee.ID;
|
|
adparamEmp.MonthlyAmount = total * indvParam.FlatAmount;
|
|
adparamEmp.Periodicity = EnumPeriodicity.Monthly;
|
|
adparamEmp.Days = total;
|
|
adparamEmp.FormDate = GlobalFunctions.FirstDateOfMonth(oPayrollType.NextPayProcessDate);
|
|
adparamEmp.TillDate = GlobalFunctions.LastDateOfMonth(oPayrollType.NextPayProcessDate);
|
|
adparamEmp.ADParameterID = indvParam.ID;
|
|
adparamEmp.ADEmpType = EnumADEmpType.AppliedToIndividual;
|
|
adparamEmp.AllowDeductID = allowanceId;
|
|
adparamEmp.Arreartype = EnumArrearType.NotPresent;
|
|
adparamEmp.CreatedBy = userid;
|
|
adparamEmp.CreatedDate = DateTime.Today;
|
|
|
|
AdparamEmployee.Add(adparamEmp);
|
|
}
|
|
|
|
return AdparamEmployee;
|
|
}
|
|
private List<EmployeeOverTime> MakeEmployeeOvertimeObj(ref List<EmployeeOverTime> EmpOverTimes, ref List<SalaryProcessStatus> ErrorList, Employee tempEmployee,
|
|
List<TermParameter> oParameters, PayrollType oPayrollType, int termid, double total, int userid)
|
|
{
|
|
AttnWiseAllowance attnAllow = new AttnWiseAllowance();
|
|
if(oParameters.Count ==0) return EmpOverTimes;
|
|
|
|
TermParameter empTermParam = TermParameter.GetParameter(oParameters, (int) tempEmployee.GradeID, termid);
|
|
if (empTermParam == null)
|
|
{
|
|
ErrorList.Add(new SalaryProcessStatus(tempEmployee.EmployeeNo, tempEmployee.Name, "OT setup not found"));
|
|
return EmpOverTimes;
|
|
}
|
|
EmployeeOverTime empot = new EmployeeOverTime();
|
|
empot.EmployeeID = tempEmployee.ID;
|
|
empot.OTMonth = oPayrollType.NextPayProcessDate;
|
|
empot.PayrollTypeID = oPayrollType.ID;
|
|
empot.TermID = termid;
|
|
empot.TermParameterID = empTermParam.TermID;
|
|
empot.OTHours = total;
|
|
empot.Value = empTermParam.Amount;
|
|
empot.CreatedBy = userid;
|
|
empot.CreatedDate = DateTime.Today;
|
|
empot.MonthDate = oPayrollType.NextPayProcessDate;
|
|
EmpOverTimes.Add(empot);
|
|
return EmpOverTimes;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void echoTexProcess(DateTime Attdate, EnumProcessMode prMode, int payrolltypeid, int processUserID, List< Employee> employees)
|
|
{
|
|
|
|
AttnProcessRunSummary oAttnRunSummary = new AttnProcessRunSummary();
|
|
bool isInOutApplicable = false;
|
|
try
|
|
{
|
|
|
|
#region Load Attendence Raw Data
|
|
// AttnRawData.RunScriptCollectRawData(Attdate);
|
|
new AttnRawDataService().RunScriptCollectRawData(Attdate);
|
|
#endregion
|
|
|
|
#region Initialization for Attendence Process
|
|
|
|
isInOutApplicable = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "attendence", "inoutapplicable");
|
|
|
|
bool _IsOTFractionate = new SystemConfigarationService().GetconfigBooleanValue(EnumConfigurationType.Logic, "overtime", "fractionateothour");
|
|
|
|
var sinMissingHour = new SystemConfigarationService().GetconfigValue(EnumConfigurationType.Logic, "overtime", "inmissinghour" );
|
|
|
|
double inMissingHour = 0;
|
|
if (sinMissingHour != null) inMissingHour = Convert.ToDouble(sinMissingHour);
|
|
|
|
List<DailyAttnProcess> dailyattProcesses = new List<DailyAttnProcess>();
|
|
List<EmpFieldTrack> oEmpFieldTracks = new List<EmpFieldTrack>();
|
|
List<AccessCard> oAccessCards =new AccessCardService().Get(EnumCardStatus.Attached);
|
|
List<CardOperation> oCardOperations =new CardOperationService().Get();
|
|
|
|
DateTime startTime = new DateTime(Attdate.Year, Attdate.Month, Attdate.Day, 4, 0, 0);
|
|
DateTime ToTime = Attdate.AddDays(1);
|
|
ToTime = new DateTime(ToTime.Year, ToTime.Month, ToTime.Day, 10, 0, 0);
|
|
|
|
List<ShiftRotation> CounterClockRotation = new ShiftRotationService().Get(EnumStatus.Regardless, payrolltypeid);
|
|
|
|
List<EmployeeWorkPlanSetup> empWPGroups = new EmployeeWorkPlanSetupService().GetAll();
|
|
|
|
List<Shift> shifts =new ShiftService().GetAllShift();
|
|
List<WorkPlanGroup> workPlanGroups = new WorkPlanGroupService().GetAll();
|
|
if( employees == null) employees = new EmployeeService().GetAllLive();
|
|
List<Employee> discontinueEmps =new EmployeeService().GetDiscontinueEmp(Attdate, DateTime.Now, payrolltypeid);
|
|
|
|
//List<AttnRawData> attRawdata = new AttnRawDataService().Get(startTime, ToTime, payrolltypeid);// get raw data by a date and order by date, employee, punchTime
|
|
List<AttnRawData> attRawdata = new AttnRawDataService().GetWithoutMobileRawData(startTime, ToTime, payrolltypeid);// get raw data by a date without MobileRawData and order by date, employee, punchTime
|
|
List<EmployeeOutsideDuty> outSideDuties = new EmployeeOutsideDutyService().Get(Attdate); // get transaction by the a rate
|
|
List<LeaveEntry> leaves = new LeaveEntryService().Get(Attdate); // workplans by the date
|
|
|
|
// Short leave for a particullar Day Should be between 6:00 AM Current Day to 6:00 AM Next Day. [Change can be done according to business logic]
|
|
List<EmployeeShortLeave> shortLeaves = new EmployeeShortLeaveService().Get(Attdate.Date.AddHours(6), Attdate.Date.AddDays(1).AddHours(6));
|
|
|
|
//oEmpFieldTracks =new EmpFieldTrackService().Get().Where(obj => obj.TranDateTime.Date == Attdate.Date).ToList();
|
|
List<LeaveParameter> lvParameters = new LeaveParameterService().Get(true, payrolltypeid);
|
|
|
|
if (discontinueEmps != null && discontinueEmps.Count > 0)
|
|
{
|
|
foreach (Employee emp in discontinueEmps)
|
|
{
|
|
if (employees.FindIndex(x=>x.ID == emp.ID) != -1)
|
|
employees.Add(emp);
|
|
}
|
|
}
|
|
|
|
List<DailyAttnProcess> prvDayattns = new DailyAttnProcessService().GetshotList(Attdate.AddDays(-1));
|
|
|
|
|
|
|
|
List<DailyAttnProcess> manualAttnProcesses = new DailyAttnProcessService().GetManualProcess(payrolltypeid, Attdate);
|
|
|
|
//foreach (DailyAttnProcess item in manualAttnProcesses)
|
|
//{
|
|
// dailyattProcesses.Add(item);
|
|
//}
|
|
|
|
|
|
#endregion
|
|
|
|
foreach (Employee emp in employees)
|
|
{
|
|
|
|
//EmpTempid = emp.ID.Integer;
|
|
|
|
#region EmployeeWise Setup
|
|
|
|
// 1. If Joining date is after Attendendence date then no attendence
|
|
if (emp.JoiningDate > Attdate)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// 2. If End of Contract date is less than or equal Attendendence date then no attendence
|
|
if (emp.EndOfContractDate != null && emp.EndOfContractDate.Value <= Attdate)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
DailyAttnProcess attnProcess = new DailyAttnProcess();
|
|
DailyAttnProcess manualEntry = manualAttnProcesses
|
|
.FirstOrDefault(obj => obj.EmployeeID == emp.ID);
|
|
|
|
// 2. If Attendendence is manually enterred
|
|
if (manualEntry != null)
|
|
{
|
|
// 2.1 If Both In and Out are Manually Enterred then add the item
|
|
if (!manualEntry.OnlyManualInTime && !manualEntry.OnlyManualOutTime)
|
|
{
|
|
dailyattProcesses.Add(manualEntry);
|
|
continue;
|
|
}
|
|
|
|
attnProcess = manualEntry;
|
|
}
|
|
else
|
|
{
|
|
attnProcess.AttnDate = Attdate;
|
|
attnProcess.EmployeeID = emp.ID;
|
|
attnProcess.IsManualEntry = false;
|
|
}
|
|
|
|
|
|
attnProcess.AttenType = EnumAttendanceType.Present;
|
|
|
|
List<AttnRawData> empAttnData = null;
|
|
|
|
EmployeeOutsideDuty empOutsideDuty = null;
|
|
|
|
LeaveEntry empLeaveEntry = null;
|
|
|
|
|
|
#region Some fine tuning in Employee's attendence RawData
|
|
|
|
if (attRawdata != null && attRawdata.Count > 0)
|
|
{
|
|
empAttnData = attRawdata.Where(erd => erd.EmployeeID == emp.ID)
|
|
.OrderBy(erd => erd.PunchTime)
|
|
.ToList();
|
|
|
|
#region Remove Previously assigned Cards data in Current Date
|
|
|
|
if (emp.CardID != null && emp.CardID !=null)
|
|
{
|
|
AccessCard accessCardEmp = oAccessCards.FirstOrDefault(x => x.ID == emp.CardID);
|
|
|
|
if (accessCardEmp != null)
|
|
{
|
|
CardOperation oEmpCardOperation = oCardOperations
|
|
.FirstOrDefault(x => x.CardNumber.Trim().ToUpper() == accessCardEmp.CardNumber.Trim().ToUpper()
|
|
&& x.EmployeeID == emp.ID);
|
|
if (oEmpCardOperation != null)
|
|
{
|
|
// if Current Date is Greater than currently assigned Cards assingnDate
|
|
if (Attdate.Date > oEmpCardOperation.AssignDate)
|
|
{
|
|
// Remove Previously assigned Cards Data
|
|
empAttnData = empAttnData.Where(x => x.CardNo.Trim().ToUpper() == oEmpCardOperation.CardNumber.ToUpper()).ToList();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
// If empAttendence Data exist and
|
|
if (empAttnData.Count > 0)
|
|
{
|
|
// If empAttendence Data's first punchTime is greater than current date's last Time
|
|
if (empAttnData[0].PunchTime > new DateTime(ToTime.Year, ToTime.Month, ToTime.Day, 2, 0, 0))
|
|
{
|
|
// We Clear empAttendence Data
|
|
empAttnData = new List<AttnRawData>();
|
|
}
|
|
else
|
|
{
|
|
// Gets Employees Previous Days Attendence
|
|
DailyAttnProcess op = prvDayattns.Where(itm => itm.EmployeeID == emp.ID)
|
|
.OrderByDescending(itm => itm.OutTime)
|
|
.FirstOrDefault();
|
|
|
|
// if Previous day attendence exists
|
|
if (op != null)
|
|
|
|
{
|
|
// Previous Day's Out time Exists
|
|
if (op.OutTime != null)
|
|
{
|
|
|
|
while (empAttnData.Count > 0)
|
|
{
|
|
// Take the Current First Attndence Data
|
|
AttnRawData ordata = empAttnData[0];
|
|
// If PunchTime is less than Previous Date's OutTime OR
|
|
// Difference is less Than 10 minutes
|
|
if (ordata.PunchTime <= op.OutTime || Math.Abs((((DateTime)ordata.PunchTime - (DateTime)op.OutTime)).TotalMinutes) < 10)
|
|
{
|
|
// discard that attendence entry
|
|
empAttnData.Remove(ordata);
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// What to do??
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (isInOutApplicable)
|
|
{
|
|
empAttnData = empAttnData
|
|
.OrderBy(erd => (int)erd.EntryMode)
|
|
.ThenBy(erd => erd.PunchTime)
|
|
.ToList();
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
if (outSideDuties != null && outSideDuties.Count > 0)
|
|
{
|
|
empOutsideDuty = outSideDuties.Where(od => od.EmployeeID == emp.ID)
|
|
.FirstOrDefault();
|
|
|
|
}
|
|
|
|
|
|
|
|
EmployeeWorkPlanSetup oEmpWorkplan = empWPGroups.Where(oGr => oGr.EmployeeID == emp.ID)
|
|
.SingleOrDefault();
|
|
|
|
// 3. If There is no EmployeeWorkPlanSetup then no attendence
|
|
if (oEmpWorkplan == null)
|
|
{
|
|
//oAttnRunSummary.AddError(EnumErrorType.WorkGroupUndefine, "Employee WorkPlan Not Defined.", emp);
|
|
|
|
continue;
|
|
}
|
|
|
|
WorkPlanGroup oEmpWPlanGroup = workPlanGroups.Where(o => o.ID == oEmpWorkplan.WorkPlanGroupID)
|
|
.Single();
|
|
|
|
|
|
//oEmpWPlanGroup = workPlanGroups.Where(o => o.ID == 28)
|
|
// .Single();
|
|
#endregion
|
|
|
|
#region Calcullate ShiftID and WorkPlan Day Type
|
|
|
|
// not needed now
|
|
// _empWPtype = oEmpWPlanGroup.Type; // Set Workplan Type
|
|
// Get ShiftID from WorkPlan for Fixed workplan
|
|
|
|
if (oEmpWPlanGroup.Type == EnumWorkPlanGroup.Fixed)
|
|
{
|
|
switch (Attdate.DayOfWeek)
|
|
{
|
|
case DayOfWeek.Friday:
|
|
attnProcess.ShiftID = oEmpWorkplan.FridayShiftID;
|
|
break;
|
|
case DayOfWeek.Monday:
|
|
attnProcess.ShiftID = oEmpWorkplan.MondayShiftID;
|
|
break;
|
|
case DayOfWeek.Saturday:
|
|
attnProcess.ShiftID = oEmpWorkplan.SaturdayShiftID;
|
|
break;
|
|
case DayOfWeek.Sunday:
|
|
attnProcess.ShiftID = oEmpWorkplan.SundayShiftID;
|
|
break;
|
|
case DayOfWeek.Thursday:
|
|
attnProcess.ShiftID = oEmpWorkplan.ThursdayShiftID;
|
|
break;
|
|
case DayOfWeek.Tuesday:
|
|
attnProcess.ShiftID = oEmpWorkplan.TuesdayShiftID;
|
|
break;
|
|
case DayOfWeek.Wednesday:
|
|
attnProcess.ShiftID = oEmpWorkplan.WednesdayShiftID;
|
|
break;
|
|
default:
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
// Calcullate ShiftID for Rotation workplan
|
|
else
|
|
{
|
|
if (empAttnData != null && empAttnData.Count > 0)
|
|
{
|
|
DateTime inTime = empAttnData[0].PunchTime;
|
|
double nminutes = 10000;
|
|
List<ShiftRotation> osrs;
|
|
DateTime shiftInTime, shiftOutTime;
|
|
Shift oshift;
|
|
|
|
osrs = CounterClockRotation.Where(x => x.WorkPlanType == oEmpWPlanGroup.Type).ToList();
|
|
|
|
|
|
foreach (ShiftRotation sr in osrs)
|
|
{
|
|
oshift = shifts.Single(o => o.ID == sr.ShiftID);
|
|
|
|
shiftInTime = Attdate.Subtract(Attdate.TimeOfDay).Add(oshift.InTime.TimeOfDay);
|
|
|
|
TimeSpan ospan = (inTime - shiftInTime);
|
|
|
|
if (nminutes > Math.Abs(ospan.TotalMinutes))
|
|
{
|
|
nminutes = Math.Abs(ospan.TotalMinutes);
|
|
if(!attnProcess.IsManualEntry) //This Condition is added for manual Shift change
|
|
attnProcess.ShiftID = sr.ShiftID;
|
|
}
|
|
}
|
|
|
|
oshift = shifts.Single(o => o.ID == attnProcess.ShiftID);
|
|
shiftInTime = Attdate.Subtract(Attdate.TimeOfDay).Add(oshift.InTime.TimeOfDay);
|
|
shiftOutTime = Attdate.Subtract(Attdate.TimeOfDay).Add(oshift.OutTime.TimeOfDay);
|
|
if (shiftOutTime < shiftInTime) shiftOutTime = shiftOutTime.AddDays(1);
|
|
|
|
if (Math.Abs((shiftOutTime - shiftInTime).TotalMinutes) < nminutes)
|
|
{
|
|
attnProcess.ShiftID = null;
|
|
empAttnData = new List<AttnRawData>();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
CalcullateWorkdayType(attnProcess, oEmpWorkplan, oEmpWPlanGroup, 1);
|
|
|
|
#region Leave Calcullation
|
|
|
|
if (leaves != null && leaves.Count > 0)
|
|
{
|
|
empLeaveEntry = leaves.Where(lv => lv.EmpID == emp.ID
|
|
&& (lv.LeaveStatus == EnumLeaveStatus.Approved || lv.LeaveStatus == EnumLeaveStatus.Availed))
|
|
.FirstOrDefault();
|
|
if (empLeaveEntry != null)
|
|
{
|
|
// Check wether Ignore Holidays
|
|
if (lvParameters.Where(x => x.LeaveId == empLeaveEntry.LeaveID).Any(x => x.IgnoreHoliday))
|
|
{
|
|
if (attnProcess.WorkDayType == EnumWorkPlanDayType.WeeklyHoliday)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.WeeklyHoliday;
|
|
}
|
|
else if (attnProcess.WorkDayType == EnumWorkPlanDayType.NationalHoliday)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Holiday;
|
|
}
|
|
else
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Leave;
|
|
attnProcess.ReferenceID = empLeaveEntry.LeaveID;
|
|
dailyattProcesses.Add(attnProcess);
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Leave;
|
|
attnProcess.ReferenceID = empLeaveEntry.LeaveID;
|
|
dailyattProcesses.Add(attnProcess);
|
|
continue;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region calculate In/Out time and With Other Things
|
|
|
|
/*
|
|
* if ShiftID found and attendence data exists
|
|
* Calcullate InTime and OutTime
|
|
* If elligable for OT calcullate OT according to DayType(Holiday or Workday)
|
|
*/
|
|
|
|
if (empAttnData != null && empAttnData.Count > 0 && attnProcess.ShiftID != null && attnProcess.ShiftID != 0)
|
|
{
|
|
Shift oshift = shifts.FirstOrDefault(x=>x.ID == attnProcess.ShiftID);
|
|
|
|
|
|
oshift.OutTime = oshift.InTime.Date
|
|
.AddDays(oshift.OutTime.TimeOfDay < oshift.InTime.TimeOfDay ? 1 : 0)
|
|
.Add(oshift.OutTime.TimeOfDay);
|
|
|
|
#region Calcullate In Out
|
|
|
|
if (!isInOutApplicable)
|
|
{
|
|
|
|
attnProcess.InTime = attnProcess.IsManualEntry && attnProcess.OnlyManualInTime ?
|
|
attnProcess.InTime : empAttnData[0].PunchTime;
|
|
|
|
|
|
if (!(attnProcess.IsManualEntry && attnProcess.OnlyManualOutTime))
|
|
{
|
|
int outInitialIndex = attnProcess.IsManualEntry && attnProcess.OnlyManualInTime ?
|
|
0 : 1;
|
|
if (empAttnData.Count > outInitialIndex)
|
|
{
|
|
attnProcess.OutTime = empAttnData[empAttnData.Count - 1].PunchTime;
|
|
|
|
//TimeSpan otime = attnProcess.OutTime - attnProcess.InTime;
|
|
// here we defined that total working hour is 19 hour in a day.
|
|
for (int i = empAttnData.Count - 1; i >= outInitialIndex; i--)
|
|
{
|
|
TimeSpan ntime =(DateTime) empAttnData[i].PunchTime - (DateTime) attnProcess.InTime;
|
|
if (oEmpWPlanGroup.Type != EnumWorkPlanGroup.Fixed)
|
|
{
|
|
if (!oshift.IsOverlapingDay // if not overlapping days
|
|
&& empAttnData[i].PunchTime.Date > attnProcess.InTime // But it overlaps
|
|
&& empAttnData[i].PunchTime.Subtract(empAttnData[i].PunchTime.Date).TotalHours > 4) //then check weather it is more than 4 hour next Day
|
|
{
|
|
// then ignore
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
if (ntime.TotalHours <= 14)
|
|
{
|
|
attnProcess.OutTime = empAttnData[i].PunchTime;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
attnProcess.OutTime = null;
|
|
|
|
if (empAttnData[i].PunchTime.Date > attnProcess.InTime && ntime.TotalHours > 16)
|
|
continue;
|
|
else
|
|
{
|
|
attnProcess.OutTime = empAttnData[i].PunchTime;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (attnProcess.OutTime != null)
|
|
{
|
|
if (Math.Abs( ((DateTime)attnProcess.InTime - (DateTime)attnProcess.OutTime).TotalMinutes) < 10)
|
|
{
|
|
attnProcess.OutTime = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
List<AttnRawData> empInRawData = empAttnData.Where(rd => rd.EntryMode == EnumEntryMode.In)
|
|
.OrderBy(rd => rd.PunchTime)
|
|
.ToList();
|
|
List<AttnRawData> empOutRawData = empAttnData.Where(rd => rd.EntryMode == EnumEntryMode.Out)
|
|
.OrderByDescending(rd => rd.PunchTime)
|
|
.ToList();
|
|
|
|
if (empInRawData.Count > 0)
|
|
{
|
|
attnProcess.InTime = attnProcess.IsManualEntry && attnProcess.OnlyManualInTime ?
|
|
attnProcess.InTime : empInRawData[0].PunchTime;
|
|
|
|
if (!(attnProcess.IsManualEntry && attnProcess.OnlyManualOutTime))
|
|
{
|
|
if (empOutRawData.Count > 0)
|
|
{
|
|
attnProcess.OutTime = empOutRawData[0].PunchTime;
|
|
foreach (AttnRawData item in empOutRawData)
|
|
{
|
|
TimeSpan ntime = (DateTime) item.PunchTime - (DateTime) attnProcess.InTime;
|
|
|
|
if (oEmpWPlanGroup.Type != EnumWorkPlanGroup.Fixed)
|
|
{
|
|
if (ntime.TotalHours <= 16)
|
|
{
|
|
attnProcess.OutTime = item.PunchTime;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
attnProcess.OutTime = null;
|
|
if (item.PunchTime.Date > ((DateTime) attnProcess.InTime).Date && item.PunchTime.Hour > 5)
|
|
continue;
|
|
else
|
|
{
|
|
attnProcess.OutTime = item.PunchTime;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (attnProcess.OutTime != null)
|
|
{
|
|
if (Math.Abs(((DateTime)attnProcess.InTime - (DateTime)attnProcess.OutTime).TotalMinutes) < 10)
|
|
{
|
|
attnProcess.OutTime = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
CalcInOutCorrection(inMissingHour, shifts, attnProcess);
|
|
|
|
if (attnProcess.InTime != null)
|
|
{
|
|
oshift.InTime = ((DateTime) attnProcess.InTime).Date.Add(oshift.InTime.TimeOfDay);
|
|
oshift.OutTime = oshift.InTime.Date
|
|
.AddDays(oshift.OutTime.TimeOfDay < oshift.InTime.TimeOfDay ? 1 : 0)
|
|
.Add(oshift.OutTime.TimeOfDay);
|
|
oshift.AbsentTime = oshift.InTime.Date
|
|
.AddDays(oshift.AbsentTime.TimeOfDay < oshift.InTime.TimeOfDay ? 1 : 0)
|
|
.Add(oshift.AbsentTime.TimeOfDay);
|
|
|
|
#region Calcullate Late, Delay, Early & Absent
|
|
|
|
double lateOrDelayTime = ((DateTime) attnProcess.InTime).TimeOfDay.Subtract(oshift.InTime.TimeOfDay).TotalMinutes;
|
|
|
|
if (oshift.LateCalcualtion != 0 && lateOrDelayTime > oshift.LateCalcualtion)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Late;
|
|
attnProcess.IsLate = true;
|
|
attnProcess.LateHour = (lateOrDelayTime - oshift.LateCalcualtion) / 60;
|
|
}
|
|
if (oshift.DelayCalcualtion != 0 && lateOrDelayTime > oshift.DelayCalcualtion)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Delay;
|
|
attnProcess.IsLate = true;
|
|
attnProcess.LateHour = (lateOrDelayTime - oshift.DelayCalcualtion) / 60;
|
|
}
|
|
|
|
if (oshift.EarlyExitBefore != 0 && attnProcess.OutTime != null)
|
|
{
|
|
double minutesEarly;
|
|
minutesEarly = oshift.OutTime.Subtract(oshift.InTime).TotalMinutes - ((DateTime) attnProcess.OutTime).Subtract((DateTime)attnProcess.InTime).TotalMinutes;
|
|
if (minutesEarly > oshift.EarlyExitBefore)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Early;
|
|
attnProcess.EarlyHour = (minutesEarly - oshift.EarlyExitBefore) / 60;
|
|
}
|
|
}
|
|
|
|
|
|
//if(attnProcess.OutTime != DateTime.MinValue && oshift.HalfdayBarrierHour >0 && attnProcess.OutTime.Subtract(attnProcess.InTime).TotalHours <= oshift.HalfdayBarrierHour)
|
|
//{
|
|
// attnProcess.AttenType = EnumAttendanceType.HalfDay;
|
|
//}
|
|
|
|
if (attnProcess.OutTime != null && oshift.HalfdayBarrierHour > 0 &&
|
|
((DateTime)attnProcess.OutTime).Subtract((DateTime)attnProcess.InTime).TotalHours
|
|
<= oshift.HalfdayBarrierHour)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.HalfDay;
|
|
EmployeeShortLeave empShortLeave = shortLeaves.FirstOrDefault(x => x.EmployeeID == emp.ID);
|
|
double totalWorkingHour = 0;
|
|
if (empShortLeave != null)
|
|
{
|
|
// Mutually Exclusive
|
|
if (attnProcess.InTime >= empShortLeave.ToDate || attnProcess.OutTime <= empShortLeave.FromDate)
|
|
{
|
|
totalWorkingHour =((DateTime) attnProcess.OutTime).Subtract((DateTime)attnProcess.InTime).TotalHours + empShortLeave.ToDate.Subtract(empShortLeave.FromDate).TotalHours;
|
|
}
|
|
else
|
|
{
|
|
DateTime calStartTime =(DateTime) attnProcess.InTime <(DateTime) empShortLeave.FromDate ? (DateTime) attnProcess.InTime : empShortLeave.FromDate;
|
|
DateTime calEndTime =(DateTime) attnProcess.OutTime > empShortLeave.ToDate ? (DateTime) attnProcess.OutTime : empShortLeave.ToDate;
|
|
totalWorkingHour = calEndTime.Subtract(calStartTime).TotalHours;
|
|
}
|
|
|
|
if (totalWorkingHour >= oshift.HalfdayBarrierHour)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Present;
|
|
attnProcess.Comments = "Short Leave";
|
|
attnProcess.Reason = "Short Leave";
|
|
}
|
|
}
|
|
}
|
|
|
|
if (oshift.hasAbsentTime)
|
|
{
|
|
|
|
if (attnProcess.InTime > oshift.AbsentTime)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Absent;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
CalcullateOTEchoTex(emp.IsEligibleOT, attnProcess, oshift, Attdate, _IsOTFractionate);
|
|
//CalcullateOTEchoTex(!emp.IsEligibleOT, attnProcess, oshift, Attdate, true);
|
|
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Calcullate MobileAttendence if Not found in rawData
|
|
|
|
if (attnProcess.InTime == null && oEmpFieldTracks.Any(obj => obj.EmployeeID == attnProcess.EmployeeID))
|
|
{
|
|
List<EmpFieldTrack> oCurrentEmpFTracks = oEmpFieldTracks.Where(obj => obj.EmployeeID == attnProcess.EmployeeID).OrderBy(o => o.TranDateTime).ToList();
|
|
attnProcess.InTime = oCurrentEmpFTracks[0].TranDateTime;
|
|
if (oCurrentEmpFTracks.Count > 1)
|
|
attnProcess.OutTime = oCurrentEmpFTracks[oCurrentEmpFTracks.Count - 1].TranDateTime;
|
|
attnProcess.AttenType = EnumAttendanceType.Present;
|
|
}
|
|
|
|
#endregion
|
|
|
|
CalcInOutCorrection(inMissingHour, shifts, attnProcess);
|
|
|
|
#region Calcullate not present status
|
|
|
|
if (attnProcess.InTime == null && attnProcess.OutTime == null)
|
|
{
|
|
|
|
if (empOutsideDuty != null)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.OutSideDuty;
|
|
attnProcess.ReferenceID = empOutsideDuty.ID;
|
|
}
|
|
else if (attnProcess.WorkDayType == EnumWorkPlanDayType.WeeklyHoliday)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.WeeklyHoliday;
|
|
}
|
|
else if (attnProcess.WorkDayType == EnumWorkPlanDayType.NationalHoliday)
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Holiday;
|
|
}
|
|
else
|
|
{
|
|
attnProcess.AttenType = EnumAttendanceType.Absent;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
dailyattProcesses.Add(attnProcess); // Add the process to collection
|
|
}
|
|
|
|
//if (dailyattProcesses.Count == 0)
|
|
// throw new ServiceException("After process Raw data, no attandance found for the selected date.");
|
|
//DailyAttnProcess.Save(dailyattProcesses, false);
|
|
|
|
new DailyAttnProcessService().Save(dailyattProcesses, null);
|
|
}
|
|
catch (ServiceException ex)
|
|
{
|
|
throw new ServiceException(ex.Message, ex);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new ServiceException(e.Message, e);
|
|
}
|
|
|
|
}
|
|
private static void CalcInOutCorrection(double inMissingHour, List<Shift> shifts, DailyAttnProcess attnProcess)
|
|
{
|
|
// If There is InMissing Hour in Logic
|
|
if (inMissingHour > 0)
|
|
{
|
|
Shift oEmpshift = shifts.FirstOrDefault(x=>x.ID == attnProcess.ShiftID);
|
|
|
|
if (oEmpshift != null)
|
|
{
|
|
if(attnProcess.InTime != null )
|
|
oEmpshift.InTime = ((DateTime) attnProcess.InTime).Date.Add(oEmpshift.InTime.TimeOfDay);
|
|
|
|
if (attnProcess.InTime != null && oEmpshift.InTime.AddHours(inMissingHour) < attnProcess.InTime)
|
|
{
|
|
DateTime previousIn = (DateTime) attnProcess.InTime;
|
|
attnProcess.InTime = null;
|
|
attnProcess.LateHour = 0;
|
|
|
|
if (attnProcess.OutTime == null || oEmpshift.OutTime.AddHours(inMissingHour) < attnProcess.OutTime)
|
|
{
|
|
attnProcess.OutTime = previousIn;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
} |