attendence manual entry corretion and monthly kpi report #52

Open
Mashfiq wants to merge 1 commits from dev_mashfiq into devqc
3 changed files with 406 additions and 121 deletions

View File

@ -1,6 +1,7 @@
using Ease.Core.DataAccess;
using System;
using HRM.BO;
using Microsoft.Data.SqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
@ -780,5 +781,63 @@ namespace HRM.DA
}
return monthlyDetail;
}
internal static DataSet GetMonthlyKPIDetail(TransactionContext tc, DateTime fromDate, DateTime toDate, List<int> empIds, List<Leave> leaves, string connectionString)
{
DataSet ds = new DataSet();
// Convert Employee IDs to DataTable
DataTable dtEmp = new DataTable();
dtEmp.Columns.Add("ID", typeof(int));
foreach (var id in empIds)
dtEmp.Rows.Add(id);
// Convert Leaves to DataTable
DataTable dtLeave = new DataTable();
dtLeave.Columns.Add("ID", typeof(int));
dtLeave.Columns.Add("Code", typeof(string));
foreach (var lv in leaves)
dtLeave.Rows.Add(lv.ID, lv.Code);
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = connection;
cmd.CommandText = "dbo.GetMonthlyKPIDetail";
cmd.CommandType = CommandType.StoredProcedure;
// Employee TVP
SqlParameter pEmp = cmd.Parameters.Add("@EmpIds", SqlDbType.Structured);
pEmp.Value = dtEmp;
pEmp.TypeName = "dbo.IntList";
// Leave TVP
SqlParameter pLeave = cmd.Parameters.Add("@Leaves", SqlDbType.Structured);
pLeave.Value = dtLeave;
pLeave.TypeName = "dbo.LeaveType";
// Dates
cmd.Parameters.Add("@FromDate", SqlDbType.DateTime).Value = fromDate;
cmd.Parameters.Add("@ToDate", SqlDbType.DateTime).Value = toDate;
// Execute
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
adapter.Fill(ds);
}
}
connection.Close();
}
if (ds.Tables.Count > 0)
ds.Tables[0].TableName = "MonthlyKPIDetail";
return ds;
}
}
}

View File

@ -33,6 +33,7 @@ namespace HRM.Report
string tempEmpID = string.Empty;
private int TotalEmp = 0;
int count = 1;
double _dExtraAllowanceHours = 0;
public rptEcho()
{
@ -2871,143 +2872,367 @@ namespace HRM.Report
#endregion
#region MonthlyKPI
//public byte[] ShowMonthlyKPI(DateTime dFromDate, DateTime dToDate, string sEmpID, string reportType, int payrollTypeID)
//{
// ReportProcessor reportProcessor = new ReportProcessor();
// DataSet oMonthlyKPIDetail = null;
// oMonthlyKPIDetail = new EchoTexExceptionReportService().GetMonthlyKPIDetail(dFromDate, dToDate, sEmpID);
// var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json");
// IConfiguration Configuration = builder.Build();
// string sExtraAllowanceHour = Configuration.GetSection("Attendance")["ExtraAllowanceHour"];
// //double dExtraAllowanceHours = 0;
// if (!double.TryParse(sExtraAllowanceHour, out _dExtraAllowanceHours))
// {
// _dExtraAllowanceHours = 13.5; // Default if Hour not given
// }
// #region Extra
// oMonthlyKPIDetail.Tables[0].Columns.Add("ExtraAllowance", typeof(double));
// if (oMonthlyKPIDetail != null && oMonthlyKPIDetail.Tables.Count > 0)
// {
// List<DailyAttnProcess> dAttnProcessess = dAttnProcessess = new DailyAttnProcessService().Get(sEmpID, dFromDate, dToDate);
// //List<AttnNationalHoliday> oNationalHolidays = AttnNationalHoliday.GetByMonth(dFromDate.FirstDateOfYear(), dFromDate.LastDateOfYear());
// List<Shift> oShifts = new ShiftService().Get(EnumStatus.Regardless, payrollTypeID);
// List<Employee> oemps = new EmployeeService().GetByEmpIDs(sEmpID);
// List<ADParameter> oAdparameters = new ADParameterService().Get(EnumStatus.Active, EnumAllowOrDeduct.Allowance, payrollTypeID).Where(x => x.AllowDeductID == 4).ToList(); // AllowDeductID = 4 is Extra Allowance in ALLOWANCEDEDUCTION table
// List<Grade> ogrades = new GradeService().Get(EnumStatus.Regardless);
// int count = 0;
// foreach (DataRow monthlyRow in oMonthlyKPIDetail.Tables[0].Rows)
// {
// count++;
// Employee emp = oemps.Find(x => x.EmployeeNo.ToString() == monthlyRow["IDNo"].ToString());
// if (emp == null) continue;
// DateTime attnDate = Convert.ToDateTime(monthlyRow["AttnDate"]);
// List<DailyAttnProcess> dEmpAttn = dAttnProcessess.FindAll(x => x.EmployeeID == emp.ID && x.AttnDate.Date == attnDate.Date).ToList();
// DataTable oDataTable = GetEmpDailyAttnNewKPI(emp.ID, dEmpAttn, emp, oShifts, oAdparameters, ogrades);
// if (oDataTable != null && oDataTable.Rows.Count > 0)
// {
// monthlyRow["ExtraAllowance"] = oDataTable.Rows[0]["ExtraAllowance"];
// }
// else
// {
// monthlyRow["ExtraAllowance"] = 0;
// }
// }
// }
// #endregion
// DataTable oMnthlyKPIDtlSummary = new AttendenceDataSet.MnthlyKPIDtlSummaryDataTable();
// #region Summary Parts
// if (oMonthlyKPIDetail.Tables.Count > 0 && oMonthlyKPIDetail.Tables[0].Rows.Count > 0)
// {
// var groupedData = oMonthlyKPIDetail.Tables[0]
// .AsEnumerable()
// .GroupBy(x => x.Field<string>("IDNo"))
// .Select(g => new { EmployeeNo = g.Key, OTSum = g.Sum(x => Convert.ToDouble(x["OTHour"].ToString())), OTAvg = g.Sum(x => Convert.ToDouble(x["OTHour"].ToString())) / g.Count(), OTGreaterThan5 = g.Count(x => Convert.ToDouble(x["OTHour"].ToString()) > 5), WH = g.Sum(x => Convert.ToDouble(x["Minutes"].ToString())) })
// .ToList();
// DataRow dRow = oMnthlyKPIDtlSummary.NewRow();
// dRow["ManPower"] = groupedData.Count();
// dRow["PerAvgOTGreater2"] = groupedData.Count(x => x.OTAvg > 2);
// dRow["PerSumOTGreater75"] = groupedData.Count(x => x.OTSum > 75);
// dRow["PerSumOTGreater100"] = groupedData.Count(x => x.OTSum > 100);
// dRow["PerSumOTGreater52"] = groupedData.Count(x => x.OTSum > 52);
// dRow["PerOneOTGreater5"] = groupedData.Count(x => x.OTGreaterThan5 > 0);
// double wh = groupedData.Sum(c => c.WH);
// oMnthlyKPIDtlSummary.Rows.Add(dRow);
// }
// #endregion
// oMnthlyKPIDtlSummary.TableName = "MnthlyKPIDtlSummary";
// oMonthlyKPIDetail.Tables.Add(oMnthlyKPIDtlSummary);
// string RDLC = "rptMonthlyKPI.rdlc";
// List<ReportParameter> _parameters = new List<ReportParameter>();
// ReportParameter rParam = new ReportParameter("FromDate", dFromDate.ToString("dd MMM yyyy"));
// _parameters.Add(rParam);
// rParam = new ReportParameter("ToDate", dToDate.LastDateOfMonth().ToString("dd MMM yyyy"));
// _parameters.Add(rParam);
// return reportProcessor.AttendanceReportsView(null, oMonthlyKPIDetail, null, RDLC, _parameters, true, payrollTypeID, reportType);
//}
//public DataTable GetEmpDailyAttnNewKPI(int EmpID, List<DailyAttnProcess> dAttnProcessess, Employee emp, List<Shift> oShifts, List<ADParameter> oADPrams, List<Grade> ogrades)
//{
// AttendenceDataSet.EmpDailyAttnDataTable dTable = new AttendenceDataSet.EmpDailyAttnDataTable();
// DateTime startTime, endTime;
// if (!(dAttnProcessess == null || dAttnProcessess.Count <= 0))
// {
// foreach (DailyAttnProcess dAttnProcess in dAttnProcessess)
// {
// DataRow Rowbody = dTable.NewRow();
// Rowbody["ExtraAllowance"] = 0;
// if (oADPrams != null && emp != null)
// {
// foreach (ADParameter adparam in oADPrams)
// {
// foreach (ADParameter.ADParameterGrade grn in adparam.ADParameterGrades)
// {
// //Grade gr = ogrades.GetItem(grn.GradeID);
// Grade gr = ogrades.Find(delegate (Grade item) { return item.ID == grn.GradeID; });
// if (gr != null && gr.ID == emp.GradeID)
// {
// if (dAttnProcess.InTime != null && dAttnProcess.InTime != DateTime.MinValue)
// {
// Shift sft = oShifts.FirstOrDefault(x => x.ID == dAttnProcess.ShiftID);
// startTime = dAttnProcess.InTime.Value.Date.Add(sft.InTime.TimeOfDay);
// startTime = (DateTime)startTime.AddMinutes(-15) > (DateTime)dAttnProcess.InTime ? (DateTime)startTime.AddMinutes(-15) : (DateTime)dAttnProcess.InTime;
// endTime = dAttnProcess.OutTime != null ? (DateTime)dAttnProcess.OutTime : DateTime.MinValue;
// if (endTime != DateTime.MinValue)
// {
// if (endTime.Subtract(startTime).Add(TimeSpan.FromMinutes(1)).TotalHours >= _dExtraAllowanceHours)
// {
// Rowbody["ExtraAllowance"] = 1;// ncount++;
// }
// }
// }
// }
// }
// }
// }
// dTable.Rows.Add(Rowbody);
// }
// }
// return dTable;
//}
public byte[] ShowMonthlyKPI(DateTime dFromDate, DateTime dToDate, string sEmpID, string reportType, int payrollTypeID)
{
ReportProcessor reportProcessor = new ReportProcessor();
DataSet oMonthlyKPIDetail = null;
oMonthlyKPIDetail = new EchoTexExceptionReportService().GetMonthlyKPIDetail(dFromDate, dToDate, sEmpID);
#region Extra
oMonthlyKPIDetail.Tables[0].Columns.Add("ExtraAllowance", typeof(double));
if (oMonthlyKPIDetail != null && oMonthlyKPIDetail.Tables.Count > 0)
int count = 0;
try
{
List<DailyAttnProcess> dAttnProcessess = dAttnProcessess = new DailyAttnProcessService().Get(sEmpID, dFromDate, dToDate);
//List<AttnNationalHoliday> oNationalHolidays = AttnNationalHoliday.GetByMonth(dFromDate.FirstDateOfYear(), dFromDate.LastDateOfYear());
List<Shift> oShifts = new ShiftService().Get(EnumStatus.Active, payrollTypeID);
List<Employee> oemps = new EmployeeService().GetByEmpIDs(sEmpID);
List<ADParameter> oAdparameters = new ADParameterService().Get(EnumStatus.Active, EnumAllowOrDeduct.Allowance, payrollTypeID).Where(x => x.AllowDeductID == 4).ToList(); // AllowDeductID = 4 is Extra Allowance in ALLOWANCEDEDUCTION table
List<Grade> ogrades = new GradeService().Get(EnumStatus.Regardless);
foreach (DataRow monthlyRow in oMonthlyKPIDetail.Tables[0].Rows)
ReportProcessor reportProcessor = new ReportProcessor();
DataSet oMonthlyKPIDetail = null;
oMonthlyKPIDetail = new EchoTexExceptionReportService().GetMonthlyKPIDetail(dFromDate, dToDate, sEmpID);
var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json");
IConfiguration Configuration = builder.Build();
string sExtraAllowanceHour = Configuration.GetSection("Attendance")["ExtraAllowanceHour"];
//double dExtraAllowanceHours = 0;
if (!double.TryParse(sExtraAllowanceHour, out _dExtraAllowanceHours))
{
Employee emp = oemps.Find(x => x.EmployeeNo.ToString() == monthlyRow["IDNo"].ToString());
if (emp == null) continue;
DateTime attnDate = Convert.ToDateTime(monthlyRow["AttnDate"]);
List<DailyAttnProcess> dEmpAttn = dAttnProcessess.FindAll(x => x.EmployeeID == emp.ID && x.AttnDate.Date == attnDate.Date).ToList();
DataTable oDataTable = new rptEcho().GetEmpDailyAttnNewKPI(emp.ID, dEmpAttn, emp, oShifts, oAdparameters, ogrades);
if (oDataTable != null && oDataTable.Rows.Count > 0)
{
monthlyRow["ExtraAllowance"] = oDataTable.Rows[0]["ExtraAllowance"];
}
else
{
monthlyRow["ExtraAllowance"] = 0;
}
_dExtraAllowanceHours = 13.5; // Default if Hour not given
}
}
#endregion
#region Extra
DataTable oMnthlyKPIDtlSummary = new AttendenceDataSet.MnthlyKPIDtlSummaryDataTable();
oMonthlyKPIDetail.Tables[0].Columns.Add("ExtraAllowance", typeof(double));
#region Summary Parts
if (oMonthlyKPIDetail.Tables.Count > 0 && oMonthlyKPIDetail.Tables[0].Rows.Count > 0)
{
var groupedData = oMonthlyKPIDetail.Tables[0]
.AsEnumerable()
.GroupBy(x => x.Field<string>("IDNo"))
.Select(g => new { EmployeeNo = g.Key, OTSum = g.Sum(x => Convert.ToDouble(x["OTHour"].ToString())), OTAvg = g.Sum(x => Convert.ToDouble(x["OTHour"].ToString())) / g.Count(), OTGreaterThan5 = g.Count(x => Convert.ToDouble(x["OTHour"].ToString()) > 5), WH = g.Sum(x => Convert.ToDouble(x["Minutes"].ToString())) })
.ToList();
DataRow dRow = oMnthlyKPIDtlSummary.NewRow();
dRow["ManPower"] = groupedData.Count();
dRow["PerAvgOTGreater2"] = groupedData.Count(x => x.OTAvg > 2);
dRow["PerSumOTGreater75"] = groupedData.Count(x => x.OTSum > 75);
dRow["PerSumOTGreater100"] = groupedData.Count(x => x.OTSum > 100);
dRow["PerSumOTGreater52"] = groupedData.Count(x => x.OTSum > 52);
dRow["PerOneOTGreater5"] = groupedData.Count(x => x.OTGreaterThan5 > 0);
double wh = groupedData.Sum(c => c.WH);
oMnthlyKPIDtlSummary.Rows.Add(dRow);
}
#endregion
oMnthlyKPIDtlSummary.TableName = "MnthlyKPIDtlSummary";
oMonthlyKPIDetail.Tables.Add(oMnthlyKPIDtlSummary);
string RDLC = "rptMonthlyKPI.rdlc";
List<ReportParameter> _parameters = new List<ReportParameter>();
ReportParameter rParam = new ReportParameter("FromDate", dFromDate.ToString("dd MMM yyyy"));
_parameters.Add(rParam);
rParam = new ReportParameter("ToDate", dToDate.LastDateOfMonth().ToString("dd MMM yyyy"));
_parameters.Add(rParam);
return reportProcessor.AttendanceReportsView(null, oMonthlyKPIDetail, null, RDLC, _parameters, true, payrollTypeID, reportType);
}
public DataTable GetEmpDailyAttnNewKPI(int EmpID, List<DailyAttnProcess> dAttnProcessess, Employee emp, List<Shift> oShifts, List<ADParameter> oADPrams, List<Grade> ogrades)
{
AttendenceDataSet.EmpDailyAttnDataTable dTable = new AttendenceDataSet.EmpDailyAttnDataTable();
var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json");
IConfiguration Configuration = builder.Build();
string sExtraAllowanceHour = Configuration.GetSection("Attendance")["ExtraAllowanceHour"];
double dExtraAllowanceHours = 0;
if (!double.TryParse(sExtraAllowanceHour, out dExtraAllowanceHours))
{
dExtraAllowanceHours = 13.5; // Default if Hour not given
}
DateTime startTime, endTime;
if (!(dAttnProcessess == null || dAttnProcessess.Count <= 0))
{
foreach (DailyAttnProcess dAttnProcess in dAttnProcessess)
if (oMonthlyKPIDetail != null && oMonthlyKPIDetail.Tables.Count > 0)
{
DataRow Rowbody = dTable.NewRow();
Rowbody["ExtraAllowance"] = 0;
if (oADPrams != null && emp != null)
List<DailyAttnProcess> dAttnProcessess = dAttnProcessess = new DailyAttnProcessService().Get(sEmpID, dFromDate, dToDate);
//List<AttnNationalHoliday> oNationalHolidays = AttnNationalHoliday.GetByMonth(dFromDate.FirstDateOfYear(), dFromDate.LastDateOfYear());
List<Shift> oShifts = new ShiftService().Get(EnumStatus.Regardless, payrollTypeID);
List<Employee> oemps = new EmployeeService().GetByEmpIDs(sEmpID);
List<ADParameter> oAdparameters = new ADParameterService().Get(EnumStatus.Active, EnumAllowOrDeduct.Allowance, payrollTypeID).Where(x => x.AllowDeductID == 4).ToList(); // AllowDeductID = 4 is Extra Allowance in ALLOWANCEDEDUCTION table
List<Grade> ogrades = new GradeService().Get(EnumStatus.Regardless);
var empDict = oemps.ToDictionary(x => x.EmployeeNo.ToString(), x => x);
var attnLookup = dAttnProcessess
.GroupBy(x => new { x.EmployeeID, Date = x.AttnDate.Date })
.ToDictionary(g => (g.Key.EmployeeID, g.Key.Date), g => g.ToList());
var shiftDict = oShifts.ToDictionary(x => x.ID, x => x);
var gradeEligible = new HashSet<int>();
foreach (var ad in oAdparameters)
{
foreach (ADParameter adparam in oADPrams)
foreach (var gr in ad.ADParameterGrades)
{
foreach (ADParameter.ADParameterGrade grn in adparam.ADParameterGrades)
{
//Grade gr = ogrades.GetItem(grn.GradeID);
Grade gr = ogrades.Find(delegate (Grade item) { return item.ID == grn.GradeID; });
if (gr != null && gr.ID == emp.GradeID)
{
if (dAttnProcess.InTime != null && dAttnProcess.InTime != DateTime.MinValue)
{
Shift sft = oShifts.FirstOrDefault(x => x.ID == dAttnProcess.ShiftID);
startTime = dAttnProcess.InTime.Value.Date.Add(sft.InTime.TimeOfDay);
startTime = (DateTime)startTime.AddMinutes(-15) > (DateTime)dAttnProcess.InTime ? (DateTime)startTime.AddMinutes(-15) : (DateTime)dAttnProcess.InTime;
endTime = dAttnProcess.OutTime != null ? (DateTime)dAttnProcess.OutTime : DateTime.MinValue;
if (endTime != DateTime.MinValue)
{
if (endTime.Subtract(startTime).Add(TimeSpan.FromMinutes(1)).TotalHours >= dExtraAllowanceHours)
{
Rowbody["ExtraAllowance"] = 1;// ncount++;
}
}
}
}
}
gradeEligible.Add(gr.GradeID);
}
}
foreach (DataRow monthlyRow in oMonthlyKPIDetail.Tables[0].Rows)
{
count++;
if(count == 341926)
{
dTable.Rows.Add(Rowbody);
}
string empNo = monthlyRow["IDNo"].ToString();
if (!empDict.TryGetValue(empNo, out var emp))
{
monthlyRow["ExtraAllowance"] = 0;
continue;
}
DateTime attnDate = Convert.ToDateTime(monthlyRow["AttnDate"]).Date;
if (!attnLookup.TryGetValue((emp.ID, attnDate), out var dEmpAttn))
{
monthlyRow["ExtraAllowance"] = 0;
continue;
}
// 👇 SAME method name used
var dt = GetEmpDailyAttnNewKPI(
emp.ID,
dEmpAttn,
emp,
oShifts,
oAdparameters,
ogrades
);
monthlyRow["ExtraAllowance"] =
(dt != null && dt.Rows.Count > 0)
? dt.Rows[0]["ExtraAllowance"]
: 0;
}
}
#endregion
DataTable oMnthlyKPIDtlSummary = new AttendenceDataSet.MnthlyKPIDtlSummaryDataTable();
#region Summary Parts
if (oMonthlyKPIDetail.Tables.Count > 0 && oMonthlyKPIDetail.Tables[0].Rows.Count > 0)
{
var groupedData = oMonthlyKPIDetail.Tables[0]
.AsEnumerable()
.GroupBy(x => x.Field<string>("IDNo"))
.Select(g => new { EmployeeNo = g.Key, OTSum = g.Sum(x => Convert.ToDouble(x["OTHour"].ToString())), OTAvg = g.Sum(x => Convert.ToDouble(x["OTHour"].ToString())) / g.Count(), OTGreaterThan5 = g.Count(x => Convert.ToDouble(x["OTHour"].ToString()) > 5), WH = g.Sum(x => Convert.ToDouble(x["Minutes"].ToString())) })
.ToList();
DataRow dRow = oMnthlyKPIDtlSummary.NewRow();
dRow["ManPower"] = groupedData.Count();
dRow["PerAvgOTGreater2"] = groupedData.Count(x => x.OTAvg > 2);
dRow["PerSumOTGreater75"] = groupedData.Count(x => x.OTSum > 75);
dRow["PerSumOTGreater100"] = groupedData.Count(x => x.OTSum > 100);
dRow["PerSumOTGreater52"] = groupedData.Count(x => x.OTSum > 52);
dRow["PerOneOTGreater5"] = groupedData.Count(x => x.OTGreaterThan5 > 0);
double wh = groupedData.Sum(c => c.WH);
oMnthlyKPIDtlSummary.Rows.Add(dRow);
}
#endregion
oMnthlyKPIDtlSummary.TableName = "MnthlyKPIDtlSummary";
oMonthlyKPIDetail.Tables.Add(oMnthlyKPIDtlSummary);
string RDLC = "rptMonthlyKPI.rdlc";
List<ReportParameter> _parameters = new List<ReportParameter>();
ReportParameter rParam = new ReportParameter("FromDate", dFromDate.ToString("dd MMM yyyy"));
_parameters.Add(rParam);
rParam = new ReportParameter("ToDate", dToDate.LastDateOfMonth().ToString("dd MMM yyyy"));
_parameters.Add(rParam);
return reportProcessor.AttendanceReportsView(null, oMonthlyKPIDetail, null, RDLC, _parameters, true, payrollTypeID, reportType);
}
catch(Exception e)
{
throw new ServiceException("Failed to Save Leave Year: " + e.Message, e);
var x = count;
}
}
public DataTable GetEmpDailyAttnNewKPI(
int EmpID,
List<DailyAttnProcess> dAttnProcessess,
Employee emp,
List<Shift> oShifts,
List<ADParameter> oADPrams,
List<Grade> ogrades)
{
AttendenceDataSet.EmpDailyAttnDataTable dTable =
new AttendenceDataSet.EmpDailyAttnDataTable();
DataRow row = dTable.NewRow();
row["ExtraAllowance"] = 0;
if (emp == null || dAttnProcessess == null || dAttnProcessess.Count == 0)
{
dTable.Rows.Add(row);
return dTable;
}
// 🔥 Precompute shift dictionary
var shiftDict = oShifts.ToDictionary(x => x.ID, x => x);
// 🔥 Precompute eligible grades
var gradeEligible = new HashSet<int>();
foreach (var ad in oADPrams)
{
foreach (var gr in ad.ADParameterGrades)
{
gradeEligible.Add(gr.GradeID);
}
}
if(emp.GradeID != null)
{
if (!gradeEligible.Contains((int)emp.GradeID))
{
dTable.Rows.Add(row);
return dTable;
}
}
else
{
}
foreach (var dAttnProcess in dAttnProcessess)
{
if (dAttnProcess.InTime == null || dAttnProcess.InTime == DateTime.MinValue)
continue;
if (!shiftDict.TryGetValue((int)dAttnProcess.ShiftID, out var shift))
continue;
DateTime shiftStart = dAttnProcess.InTime.Value.Date.Add(shift.InTime.TimeOfDay);
DateTime adjustedStart = shiftStart.AddMinutes(-15);
DateTime startTime = adjustedStart > dAttnProcess.InTime
? adjustedStart
: dAttnProcess.InTime.Value;
if (dAttnProcess.OutTime == null)
continue;
double workedHours = dAttnProcess.OutTime.Value
.Subtract(startTime)
.Add(TimeSpan.FromMinutes(1))
.TotalHours;
// 🚀 EARLY EXIT (biggest improvement)
if (workedHours >= _dExtraAllowanceHours)
{
row["ExtraAllowance"] = 1;
break;
}
}
dTable.Rows.Add(row);
return dTable;
}
#endregion
#endregion

View File

@ -63,7 +63,7 @@ export class AttendanceManualEditForMultipleEmployeeComponent implements OnInit
{ value: 5, name: "Natural Calamity" },
{ value: 2, name: "Forget To Punch" },
{ value: 9, name: 'LOA' },
//{ value: 11, name: 'Other' },
{ value: 11, name: 'Other' },
]
isOtherRemarks: boolean = false;
otherRemarks: string = "";
@ -207,6 +207,7 @@ export class AttendanceManualEditForMultipleEmployeeComponent implements OnInit
}
updateobject(type: number) {
debugger;
if (this.selectedRemarks != undefined) {
if (this.remarksList.find(y => y.value == this.selectedRemarks).name == "Other") {
this.isOtherRemarks = true;