/// <summary> /// Hàm lấy các phần tử là Enum /// </summary> /// <param name="TotalData">Class chứa tất cả các dữ liệu lấy lên để xử lý</param> /// <param name="listElementFormula">Lưu giá trị các thông thức đã tính rồi</param> /// <param name="profileItem">Nhân viên hiện tại được tính</param> /// <param name="CutOffDuration">Kỳ tính lương</param> /// <param name="formula">Công thức tính</param> /// <param name="listTmpDeduction">Biến tạm phục vụ cho tiền khấu trừ thâm niên của dự án SCV</param> /// <param name="DateClose">Ngày chốt lương</param> /// <returns></returns> public List<ElementFormula> GetStaticValues(ComputePayrollDataModel TotalData, List<ElementFormula> listElementFormula, Hre_ProfileEntity profileItem, Att_CutOffDurationEntity CutOffDuration, string ElementCode, Dictionary<Guid, ValueCount> listTmpDeduction) { Cat_ElementEntity formula = TotalData.listElement_All.Where(m => m.ElementCode == ElementCode).FirstOrDefault(); ElementFormula item = new ElementFormula(); #region Thêm các phần tử là loại phụ cấp if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUsualAllowance.Select(m => m.Code).ToArray())) { foreach (var t in TotalData.listUsualAllowance) { listElementFormula.Add(new ElementFormula(t.Code, t.Formula, 0)); } } #endregion #region Quy đổi tiền tệ if (CheckIsExistFormula(listElementFormula, formula, TotalData.listCurrency.Select(m => m.Code + "_BUYING").ToArray())) { //list lưu các element var ListExChangeRateElement = TotalData.listElement_All.Where(m => m.ElementCode.EndsWith("_BUYING") && m.GradePayrollID == null).ToList(); //list lưu giá trị tiền tệ var ListExChangeRateByGrade = TotalData.listExchangeRate.Where(m => m.MonthOfEffect >= CutOffDuration.DateStart && m.MonthOfEffect <= CutOffDuration.DateEnd).ToList(); foreach (var i in ListExChangeRateElement) { string[] arrCurrencyCode = i.ElementCode.Split('_').ToArray(); if (arrCurrencyCode.Count() != 3) { var ExChangeRateItem = ListExChangeRateByGrade.Where(m => m.CurrencyBaseCode == arrCurrencyCode[0] && m.CurrencyDestCode == arrCurrencyCode[1]).OrderByDescending(m => m.MonthOfEffect).FirstOrDefault(); if (ExChangeRateItem != null) { item = new ElementFormula(i.ElementCode, ExChangeRateItem.BuyingRate != null ? ExChangeRateItem.BuyingRate : 0, 0); listElementFormula.Add(item); } } } } if (CheckIsExistFormula(listElementFormula, formula, TotalData.listCurrency.Select(m => m.Code + "_SELLING").ToArray())) { //list lưu các element var ListExChangeRateElement = TotalData.listElement_All.Where(m => m.ElementCode.EndsWith("_SELLING") && m.GradePayrollID == null).ToList(); //list lưu giá trị tiền tệ var ListExChangeRateByGrade = TotalData.listExchangeRate.Where(m => m.MonthOfEffect >= CutOffDuration.DateStart && m.MonthOfEffect <= CutOffDuration.DateEnd).ToList(); foreach (var i in ListExChangeRateElement) { string[] arrCurrencyCode = i.ElementCode.Split('_').ToArray(); if (arrCurrencyCode.Count() != 3) { var ExChangeRateItem = ListExChangeRateByGrade.Where(m => m.CurrencyBaseCode == arrCurrencyCode[0] && m.CurrencyDestCode == arrCurrencyCode[1]).OrderByDescending(m => m.MonthOfEffect).FirstOrDefault(); if (ExChangeRateItem != null) { item = new ElementFormula(i.ElementCode, ExChangeRateItem.SellingRate != null ? ExChangeRateItem.SellingRate : 0, 0); listElementFormula.Add(item); } } } } #endregion #region Kiểm tra xem nhân viên này có phụ cấp phát sinh trong tháng đang tính lương hay không ? if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code + "_T3").ToArray()))//đã lấy lên chưa ? { List<Sal_UnusualAllowanceEntity> listSal_UnusualT3 = new List<Sal_UnusualAllowanceEntity>(); listSal_UnusualT3 = TotalData.listUnusualAllowanceT3.Where(m => m.ProfileID == profileItem.ID).ToList(); ElementFormula _tmpitem = new ElementFormula(); for (int j = 0; j < TotalData.listUnusualAllowanceCfg.Count; j++) { //lay phu cap thang 3 _tmpitem = new ElementFormula(); _tmpitem.VariableName = TotalData.listUnusualAllowanceCfg[j].Code + "_T3"; var Sal_UnusualItem = listSal_UnusualT3.Where(m => m.UnusualEDTypeID == TotalData.listUnusualAllowanceCfg[j].ID && m.MonthStart <= CutOffDuration.DateEnd && (m.MonthEnd == null || m.MonthEnd >= CutOffDuration.DateStart)).ToList(); if (Sal_UnusualItem != null) { _tmpitem.Value = Sal_UnusualItem.Sum(m => m.Amount != null ? m.Amount : 0); listElementFormula.Add(_tmpitem); } else { _tmpitem.Value = "0"; _tmpitem.ErrorMessage = "Không Có Phụ Cấp Trong Tháng 3"; listElementFormula.Add(_tmpitem); } } } if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code + "_DAYCLOSE_N_1").ToArray())) { DateTime Dateform = CutOffDuration.DateStart.AddMonths(-1); DateTime DateTo = CutOffDuration.DateEnd.AddMonths(-1); //Lấy các phần tử tính lương nằm trong Grade của nhân viên Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, Dateform, DateTo); //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault(); //ngày bắt đầu chốt lương DateTime DateClose = new DateTime(CutOffDuration.MonthYear.AddMonths(-1).Year, CutOffDuration.MonthYear.AddMonths(-1).Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1).AddDays(1).AddMonths(-1); //ngày kết thúc chốt lương DateTime DateEndClose = new DateTime(CutOffDuration.MonthYear.AddMonths(-1).Year, CutOffDuration.MonthYear.AddMonths(-1).Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1); List<Sal_UnusualAllowanceEntity> ListUnusualAllowanceByProfile = TotalData.listSalUnusualAllowance.Where(m => m.ProfileID == profileItem.ID && m.MonthStart != null && m.MonthStart <= DateEndClose && (m.MonthEnd == null || m.MonthEnd >= DateClose)).ToList(); ElementFormula _item = new ElementFormula(); foreach (var i in TotalData.listUnusualAllowanceCfg) { var listValue = ListUnusualAllowanceByProfile.Where(m => m.UnusualEDTypeID == i.ID).OrderByDescending(m => m.MonthStart).FirstOrDefault(); if (listValue != null) { _item = new ElementFormula(i.Code + "_DAYCLOSE_N_1", listValue.Amount != null ? listValue.Amount : 0, 0); listElementFormula.Add(_item); } else { _item = new ElementFormula(i.Code + "_DAYCLOSE_N_1", 0, 0); listElementFormula.Add(_item); } } } if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code + "_DAYCLOSE").ToArray())) { //Lấy các phần tử tính lương nằm trong Grade của nhân viên Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd); //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault(); //ngày bắt đầu chốt lương DateTime DateClose = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1).AddDays(1).AddMonths(-1); //ngày kết thúc chốt lương DateTime DateEndClose = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1); List<Sal_UnusualAllowanceEntity> ListUnusualAllowanceByProfile = TotalData.listSalUnusualAllowance.Where(m => m.ProfileID == profileItem.ID && m.MonthStart != null && m.MonthStart <= DateEndClose && (m.MonthEnd == null || m.MonthEnd >= DateClose)).ToList(); ElementFormula _item = new ElementFormula(); foreach (var i in TotalData.listUnusualAllowanceCfg) { var listValue = ListUnusualAllowanceByProfile.Where(m => m.UnusualEDTypeID == i.ID).OrderByDescending(m => m.MonthStart).FirstOrDefault(); if (listValue != null) { _item = new ElementFormula(i.Code + "_DAYCLOSE", listValue.Amount != null ? listValue.Amount : 0, 0); listElementFormula.Add(_item); } else { _item = new ElementFormula(i.Code + "_DAYCLOSE", 0, 0); listElementFormula.Add(_item); } } } if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code + "_AMOUNTOFOFFSET_N_1").ToArray())) { DateTime Dateform = CutOffDuration.DateStart.AddMonths(-1); DateTime DateTo = CutOffDuration.DateEnd.AddMonths(-1); //Lấy các phần tử tính lương nằm trong Grade của nhân viên Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, Dateform, DateTo); //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault(); //ngày bắt đầu chốt lương DateTime DateClose = new DateTime(CutOffDuration.MonthYear.AddMonths(-1).Year, CutOffDuration.MonthYear.AddMonths(-1).Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1).AddDays(1).AddMonths(-1); //ngày kết thúc chốt lương DateTime DateEndClose = new DateTime(CutOffDuration.MonthYear.AddMonths(-1).Year, CutOffDuration.MonthYear.AddMonths(-1).Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1); List<Sal_UnusualAllowanceEntity> listUnusualAllowanceByDateClose = TotalData.listSalUnusualAllowance.Where(m => m.MonthStart <= DateEndClose && (m.MonthEnd >= DateClose || m.MonthEnd == null) && m.ProfileID == profileItem.ID).ToList(); ElementFormula _item = new ElementFormula(); foreach (var i in TotalData.listUnusualAllowanceCfg) { var listValue = listUnusualAllowanceByDateClose.Where(m => m.UnusualEDTypeID == i.ID).ToList(); if (listValue != null) { _item = new ElementFormula(i.Code + "_AMOUNTOFOFFSET_N_1", listValue.Sum(m => m.AmountOfOffSet != null ? m.AmountOfOffSet : 0), 0); listElementFormula.Add(_item); } else { _item = new ElementFormula(i.Code + "_AMOUNTOFOFFSET_N_1", 0, 0); listElementFormula.Add(_item); } } } //lấy mức phụ cấp theo timeline tháng n-1 if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code + "_TIMELINE_N_1").ToArray())) { DateTime Dateform = CutOffDuration.DateStart.AddMonths(-1); DateTime DateTo = CutOffDuration.DateEnd.AddMonths(-1); //Lấy các phần tử tính lương nằm trong Grade của nhân viên Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, Dateform, DateTo); //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault(); //ngày bắt đầu chốt lương DateTime DateClose = new DateTime(CutOffDuration.MonthYear.AddMonths(-1).Year, CutOffDuration.MonthYear.AddMonths(-1).Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1).AddDays(1).AddMonths(-1); //ngày kết thúc chốt lương DateTime DateEndClose = new DateTime(CutOffDuration.MonthYear.AddMonths(-1).Year, CutOffDuration.MonthYear.AddMonths(-1).Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1); List<Cat_UnAllowCfgAmountEntity> listUnAllowCfgAmount = TotalData.listUnAllowCfgAmount.Where(m => m.FromDate <= DateEndClose && m.ToDate >= DateClose).ToList(); ElementFormula _item = new ElementFormula(); foreach (var i in TotalData.listUnusualAllowanceCfg) { var listValue = listUnAllowCfgAmount.Where(m => m.UnusualAllowanceID != null && (Guid)m.UnusualAllowanceID == i.ID).ToList(); if (listValue != null) { _item = new ElementFormula(i.Code + "_TIMELINE_N_1", listValue.Sum(m => m.Amount != null ? m.Amount : 0), 0); listElementFormula.Add(_item); } else { _item = new ElementFormula(i.Code + "_TIMELINE_N_1", 0, 0); listElementFormula.Add(_item); } } } //lấy mức phụ cấp theo timeline if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code + "_TIMELINE").ToArray())) { //Lấy các phần tử tính lương nằm trong Grade của nhân viên Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd); //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault(); //ngày bắt đầu chốt lương DateTime DateClose = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1).AddDays(1).AddMonths(-1); //ngày kết thúc chốt lương DateTime DateEndClose = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1); List<Cat_UnAllowCfgAmountEntity> listUnAllowCfgAmount = TotalData.listUnAllowCfgAmount.Where(m => m.FromDate <= DateEndClose && m.ToDate >= DateClose).ToList(); ElementFormula _item = new ElementFormula(); foreach (var i in TotalData.listUnusualAllowanceCfg) { var listValue = listUnAllowCfgAmount.Where(m => m.UnusualAllowanceID != null && (Guid)m.UnusualAllowanceID == i.ID).ToList(); if (listValue != null) { _item = new ElementFormula(i.Code + "_TIMELINE", listValue.Sum(m => m.Amount != null ? m.Amount : 0), 0); listElementFormula.Add(_item); } else { _item = new ElementFormula(i.Code + "_TIMELINE", 0, 0); listElementFormula.Add(_item); } } } if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code + "_N_1").ToArray()))//đã lấy lên chưa ? { List<Sal_UnusualAllowanceEntity> listSal_Unusual = new List<Sal_UnusualAllowanceEntity>(); ElementFormula _tmpitem = new ElementFormula(); listSal_Unusual = TotalData.listSalUnusualAllowance.Where(m => m.ProfileID == profileItem.ID).ToList(); //lấy các loại phụ cấp của 6 tháng trước tháng tính lương (Honda) for (int j = 0; j < TotalData.listUnusualAllowanceCfg.Count; j++) { for (int t = 1; t <= 6; t++) { _tmpitem = new ElementFormula(); _tmpitem.VariableName = TotalData.listUnusualAllowanceCfg[j].Code + "_N_" + t.ToString(); var Sal_UnusualItem = listSal_Unusual.Where(m => m.UnusualEDTypeID == TotalData.listUnusualAllowanceCfg[j].ID && m.MonthStart <= CutOffDuration.DateEnd.AddMonths(t * -1) && (m.MonthEnd == null || m.MonthEnd >= CutOffDuration.DateStart.AddMonths(t * -1))).ToList(); if (Sal_UnusualItem != null) { _tmpitem.Value = Sal_UnusualItem.Sum(m => m.Amount != null ? m.Amount : 0); listElementFormula.Add(_tmpitem); } else { _tmpitem.Value = "0"; _tmpitem.ErrorMessage = "Không Có Phụ Cấp Trong Tháng"; listElementFormula.Add(_tmpitem); } } } } if (CheckIsExistFormula(listElementFormula, formula, TotalData.listUnusualAllowanceCfg.Select(m => m.Code).ToArray()))//đã lấy lên chưa ? { List<Sal_UnusualAllowanceEntity> listSal_Unusual = new List<Sal_UnusualAllowanceEntity>(); // List<Sal_UnusualAllowanceEntity> listSal_UnusualT3 = new List<Sal_UnusualAllowanceEntity>(); listSal_Unusual = TotalData.listSalUnusualAllowance.Where(m => m.ProfileID == profileItem.ID).ToList(); // listSal_UnusualT3 = TotalData.listUnusualAllowanceT3.Where(m => m.ProfileID == profileItem.ID).ToList(); //add loại phụ cấp bất thường vào list phần tử(listElement), các loại phụ cấp nào không có thì cho formula = 0 for (int j = 0; j < TotalData.listUnusualAllowanceCfg.Count; j++) { ElementFormula _tmpitem = new ElementFormula(); _tmpitem.VariableName = TotalData.listUnusualAllowanceCfg[j].Code; var Sal_UnusualItem = listSal_Unusual.Where(m => m.UnusualEDTypeID == TotalData.listUnusualAllowanceCfg[j].ID && m.MonthStart <= CutOffDuration.DateEnd && (m.MonthEnd == null || m.MonthEnd >= CutOffDuration.DateStart)).ToList(); if (Sal_UnusualItem != null) { _tmpitem.Value = Sal_UnusualItem.Sum(m => m.Amount != null ? m.Amount : 0); listElementFormula.Add(_tmpitem); } else { _tmpitem.Value = "0"; _tmpitem.ErrorMessage = "Không Có Phụ Cấp Trong Tháng"; listElementFormula.Add(_tmpitem); } } } #endregion #region Lấy giá trị các phần tử là Enum var listAttendanceTableProCut = TotalData.listAttendanceTable.Where(m => m.ProfileID == profileItem.ID && m.DateStart <= CutOffDuration.DateEnd && m.DateEnd >= CutOffDuration.DateStart).FirstOrDefault(); #region Enum HRE if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.HR_WORKINGDAY.ToString(), PayrollElement.HR_LEAVEDAY.ToString(), PayrollElement.HR_IS_LEAVEDAY.ToString(), PayrollElement.HR_IS_WORKINGDAY.ToString() })) { //Ngày vào làm item = new ElementFormula(PayrollElement.HR_WORKINGDAY.ToString(), profileItem.DateHire, 0); listElementFormula.Add(item); //Ngày nghỉ việc item = new ElementFormula(PayrollElement.HR_LEAVEDAY.ToString(), profileItem.DateQuit != null ? profileItem.DateQuit : DateTime.MinValue, 0, profileItem.DateQuit != null ? "" : "Null"); listElementFormula.Add(item); //NV có ngày nghỉ việc trong tháng item = new ElementFormula(PayrollElement.HR_IS_LEAVEDAY.ToString(), (profileItem.DateQuit <= CutOffDuration.DateEnd && profileItem.DateQuit >= CutOffDuration.DateStart) == true ? 0 : 1, 0); listElementFormula.Add(item); //NV có ngày vào làm trong tháng item = new ElementFormula(PayrollElement.HR_IS_WORKINGDAY.ToString(), (profileItem.DateHire <= CutOffDuration.DateEnd && profileItem.DateHire >= CutOffDuration.DateStart) == true ? 1 : 0, 0); listElementFormula.Add(item); } ////Bậc / Hệ số lương (Code) //item = new ElementFormula(PayrollElement.HR_SALARYCLASSNAME.ToString(), profileItem.SalaryClassID != null ? profileItem.SalaryClassName : "", 0); //listElementFormula.Add(item); //Số ngày từ ngày vào đến cuối tháng, không tính những ngày dayoff từ ngày vào đến cuối tháng (VD: vào ngày 05/01, số ngày dayoff từ mùng 5 đến 31 = 6 => trả về: 31 (số ngày trong tháng) - 5 (ngày vào) + 1 (từ 5 đến 31 là 27 ngày nên phải + thêm 1) - 6 (số ngày dayoff từ ngày 05/01 đến 31/01) = 21) if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_COUNT_DAY_TO_DATEEND_CUTOFF.ToString())) { if (profileItem.DateHire != null && profileItem.DateHire >= new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, 1)) { DateTime DateStart = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, 1); DateTime DateEnd = DateStart.AddMonths(1).AddDays(-1); //số ngày trong tháng double dayInCutoff = DateEnd.Subtract(profileItem.DateHire.Value).TotalDays + 1; double dayOff = TotalData.listDayOff.Where(m => m.DateOff <= DateEnd && m.DateOff >= profileItem.DateHire.Value).Count(); item = new ElementFormula(PayrollElement.HR_COUNT_DAY_TO_DATEEND_CUTOFF.ToString(), dayInCutoff - dayOff, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.HR_COUNT_DAY_TO_DATEEND_CUTOFF.ToString(), 0, 0); listElementFormula.Add(item); } } //Số ngày trong tháng tính lương - tổng số ngày dayoff trong tháng tính lương (VD: tháng 1 có 31 ngày - 8 ngày dayoff = 23) if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_COUNT_DAY_IN_CUTOFF.ToString())) { DateTime DateStart = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, 1); DateTime DateEnd = DateStart.AddMonths(1).AddDays(-1); double dayInCutoff = DateEnd.Subtract(DateStart).TotalDays + 1; double dayOff = TotalData.listDayOff.Where(m => m.DateOff <= DateEnd && m.DateOff >= DateStart).Count(); item = new ElementFormula(PayrollElement.HR_COUNT_DAY_IN_CUTOFF.ToString(), dayInCutoff - dayOff, 0); listElementFormula.Add(item); } //Số ngày dayoff từ ngày 1 tháng tính lương đến ngày vào làm (VD: vào làm ngày 05/01, 01/01, 02/01 là ngày dayoff => trả về 2) if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_COUNT_DAYOFF_TO_DATEHIRE.ToString())) { //ngày đầu tháng tính lương DateTime DateStart = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, 1); //nếu ngày làm việc lớn hơn ngày đầu tháng if (profileItem.DateHire != null && profileItem.DateHire >= DateStart) { int DayNumber = TotalData.listDayOff.Where(m => m.DateOff <= profileItem.DateHire.Value && m.DateOff >= DateStart).Count(); item = new ElementFormula(PayrollElement.HR_COUNT_DAYOFF_TO_DATEHIRE.ToString(), DayNumber, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.HR_COUNT_DAYOFF_TO_DATEHIRE.ToString(), 0, 0); listElementFormula.Add(item); } } //Nhân viên có ngày vào làm hoặc ngày đi làm lại trong khoảng từ ngày 1 đến ngày chốt lương trong tháng tính lương thì trả về 1, nếu không trả về 0 if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_IS_BACK_TO_WORK.ToString())) { //Lấy các phần tử tính lương nằm trong Grade của nhân viên Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd); //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault(); //kiểm tra ngày đi làm if (profileItem.DateHire != null && profileItem.DateHire.Value.Month == CutOffDuration.MonthYear.Month && profileItem.DateHire.Value.Year == CutOffDuration.MonthYear.Year) { if (CatGrade.SalaryDayClose != null && profileItem.DateHire.Value.Day <= CatGrade.SalaryDayClose) { item = new ElementFormula(PayrollElement.HR_IS_BACK_TO_WORK.ToString(), 1, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.HR_IS_BACK_TO_WORK.ToString(), 0, 0); listElementFormula.Add(item); } } else//kiểm tra có ngày vào làm lại hay không { if (CatGrade.SalaryDayClose != null) { List<Hre_WorkHistoryEntity> listWorkHistoryByProfile = TotalData.listWorkHistory.Where(m => m.ProfileID == profileItem.ID && m.DateComeBack != null && m.DateComeBack <= new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, (int)CatGrade.SalaryDayClose)).ToList(); if (listWorkHistoryByProfile.Count > 0) { item = new ElementFormula(PayrollElement.HR_IS_BACK_TO_WORK.ToString(), 1, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.HR_IS_BACK_TO_WORK.ToString(), 0, 0); listElementFormula.Add(item); } } else { item = new ElementFormula(PayrollElement.HR_IS_BACK_TO_WORK.ToString(), 0, 0); listElementFormula.Add(item); } } } //Nhân viên có trong doanh sách kỷ luật trong tháng tính lương if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_NUMBER_DAY_BEFORE_WORK.ToString())) { double CountDay = 0; //nếu ngày vào làm lớn hơn if (profileItem.DateHire != null && profileItem.DateHire > CutOffDuration.DateStart && profileItem.DateHire <= CutOffDuration.DateEnd) { DateTime dateStart = new DateTime(profileItem.DateHire.Value.Year, profileItem.DateHire.Value.Month, 1); CountDay = profileItem.DateHire.Value.Subtract(dateStart).TotalDays; int DayOff = TotalData.listDayOff.Where(m => ((m.OrgStructureID == null || m.OrgStructureID == profileItem.OrgStructureID) || m.OrgStructureID == profileItem.OrgStructureID) && m.DateOff >= dateStart && m.DateOff < profileItem.DateHire).Count(); CountDay -= DayOff; } //kiểm tra xem có vào làm lại hay không Hre_StopWorkingEntity StopWorkingByProfile = TotalData.listHre_StopWorking.Where(m => m.ProfileID != null && m.DateComeBack != null && m.ProfileID == profileItem.ID && m.DateComeBack >= CutOffDuration.DateStart && m.DateComeBack <= CutOffDuration.DateEnd).OrderByDescending(m => m.DateComeBack).FirstOrDefault(); if (StopWorkingByProfile != null && StopWorkingByProfile.DateComeBack != null) { DateTime dateStart = new DateTime(StopWorkingByProfile.DateComeBack.Value.Year, StopWorkingByProfile.DateComeBack.Value.Month, 1); CountDay = StopWorkingByProfile.DateComeBack.Value.Subtract(dateStart).TotalDays; int DayOff = TotalData.listDayOff.Where(m => (m.OrgStructureID == null || m.OrgStructureID == profileItem.OrgStructureID) && m.DateOff >= dateStart && m.DateOff < profileItem.DateHire).Count(); CountDay -= DayOff; } item = new ElementFormula(PayrollElement.HR_NUMBER_DAY_BEFORE_WORK.ToString(), CountDay, 0); listElementFormula.Add(item); } //Nhân viên có trong doanh sách kỷ luật trong tháng tính lương if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_NUMBER_DAY_BEFORE_WORK_PREV.ToString())) { DateTime DateStartPrev = CutOffDuration.DateStart.AddMonths(-1); DateTime DateEndPrev = CutOffDuration.DateEnd.AddMonths(-1); double CountDay = 0; int DayClose = 1; //Lấy các phần tử tính lương nằm trong Grade của nhân viên Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd); Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault(); if (CatGrade != null && CatGrade.SalaryDayClose != null) { DayClose = (int)CatGrade.SalaryDayClose; } //nếu ngày vào làm lớn hơn if (profileItem.DateHire != null && profileItem.DateHire > DateStartPrev && profileItem.DateHire <= DateEndPrev && profileItem.DateHire.Value.Day > DayClose) { CountDay = new DateTime(profileItem.DateHire.Value.Year, profileItem.DateHire.Value.Month, 1).AddMonths(1).AddDays(-1).Subtract(profileItem.DateHire.Value).TotalDays + 1; DateStartPrev = new DateTime(profileItem.DateHire.Value.Year, profileItem.DateHire.Value.Month, 1).AddMonths(1).AddDays(-1); int DayOff = TotalData.listDayOff.Where(m => (m.OrgStructureID == null || m.OrgStructureID == profileItem.OrgStructureID) && m.DateOff <= DateStartPrev && m.DateOff >= profileItem.DateHire).Count(); CountDay -= DayOff; } //kiểm tra xem có vào làm lại hay không Hre_StopWorkingEntity StopWorkingByProfile = TotalData.listHre_StopWorking.Where(m => m.ProfileID != null && m.DateComeBack != null && m.ProfileID == profileItem.ID && m.DateComeBack >= DateStartPrev && m.DateComeBack <= DateEndPrev).OrderByDescending(m => m.DateComeBack).FirstOrDefault(); if (StopWorkingByProfile != null && StopWorkingByProfile.DateComeBack != null) { CountDay = new DateTime(StopWorkingByProfile.DateComeBack.Value.Year, StopWorkingByProfile.DateComeBack.Value.Month, 1).AddMonths(1).AddDays(-1).Subtract(StopWorkingByProfile.DateComeBack.Value).TotalDays + 1; DateStartPrev = new DateTime(profileItem.DateHire.Value.Year, profileItem.DateHire.Value.Month, 1).AddMonths(1).AddDays(-1); int DayOff = TotalData.listDayOff.Where(m => (m.OrgStructureID == null || m.OrgStructureID == profileItem.OrgStructureID) && m.DateOff <= DateStartPrev && m.DateOff >= profileItem.DateHire).Count(); CountDay -= DayOff; } item = new ElementFormula(PayrollElement.HR_NUMBER_DAY_BEFORE_WORK_PREV.ToString(), CountDay, 0); listElementFormula.Add(item); } //Nhân viên có trong doanh sách kỷ luật trong tháng tính lương if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_IS_DISCIPLINE.ToString()))//đã lấy lên chưa ? { DateTime datefrom = new DateTime(CutOffDuration.MonthYear.Year - 1, 4, 1); DateTime dateto = new DateTime(CutOffDuration.MonthYear.Year, 3, 31); var listDisciplineProfile = TotalData.listDiscipline.Where(m => m.ProfileID == profileItem.ID && m.DateOfEffective >= datefrom && m.DateOfEffective <= dateto).FirstOrDefault(); item = new ElementFormula(PayrollElement.HR_IS_DISCIPLINE.ToString(), listDisciplineProfile != null ? 1 : 0, 0); listElementFormula.Add(item); } //Phần tử tổng thời gian tạm hoãn công việc tính tới cuối kỳ lương if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_TOTAL_DAY_STOP_WORKING.ToString()))//đã lấy lên chưa ? { item = new ElementFormula(PayrollElement.HR_TOTAL_DAY_STOP_WORKING.ToString(), SumStopWorkingDay(TotalData.listHre_StopWorking.Where(m => m.ProfileID == profileItem.ID).ToList(), CutOffDuration.DateEnd), 0); listElementFormula.Add(item); } //Nhân viên có được tính trợ cấp hay không (Có ngày vào làm từ 1996<=N<=31/12/2008) if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_IS_COMPUTE_SUBSIDIZE.ToString())) { DateTime from = new DateTime(1996, 1, 1); DateTime to = new DateTime(2008, 12, 31); item = new ElementFormula(PayrollElement.HR_IS_COMPUTE_SUBSIDIZE.ToString(), (profileItem.DateHire <= to && profileItem.DateHire >= from) == true ? 1 : 0, 0); listElementFormula.Add(item); } //Lấy thông tin hợp đồng if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_CONSTRACT_TYPE.ToString())) { //TotalData. } #region HDT JOB #region Ngày vào làm và ngày kết thúc HDT JOB tháng N if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_START_DATE_HDTJOB.ToString()) || CheckIsExistFormula(listElementFormula, formula, PayrollElement.HR_END_DATE_HDTJOB.ToString()))//đã lấy lên chưa ? { Hre_HDTJobEntity HDTJOB_DateFrom = new Hre_HDTJobEntity(); //Ngày vào làm HDT JOB HDTJOB_DateFrom = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.DateFrom <= CutOffDuration.DateEnd && (m.DateTo >= CutOffDuration.DateStart || m.DateTo == null) && m.Status == HDTJobStatus.E_APPROVE.ToString()).OrderBy(m => m.DateFrom).FirstOrDefault(); if (HDTJOB_DateFrom != null) { DateTime form = HDTJOB_DateFrom.DateFrom != null ? (DateTime)HDTJOB_DateFrom.DateFrom : DateTime.MinValue; DateTime to = HDTJOB_DateFrom.DateTo != null ? (DateTime)HDTJOB_DateFrom.DateTo : CutOffDuration.DateEnd; item = new ElementFormula(PayrollElement.HR_START_DATE_HDTJOB.ToString(), form, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.HR_END_DATE_HDTJOB.ToString(), to, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.HR_START_DATE_HDTJOB.ToString(), DateTime.MinValue, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.HR_END_DATE_HDTJOB.ToString(), DateTime.MinValue, 0, "Null"); listElementFormula.Add(item); } } #endregion #region Ngày vào làm và ngày kết thúc HDT JOB tháng N-1 if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.HR_END_DATE_HDTJOB_PREV.ToString(), PayrollElement.HR_START_DATE_HDTJOB_PREV.ToString() })) { var CutOffDuration_Prev = TotalData.listCutOffDuration.Where(m => m.MonthYear == CutOffDuration.MonthYear.AddMonths(-1)).OrderByDescending(m => m.MonthYear).FirstOrDefault(); if (CutOffDuration_Prev != null) { List<Hre_HDTJobEntity> listHre_HDTJob_Prev = new List<Hre_HDTJobEntity>(); Hre_HDTJobEntity HDTJOB_DateFrom = new Hre_HDTJobEntity(); //Ngày vào làm HDT JOB HDTJOB_DateFrom = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.DateFrom <= CutOffDuration_Prev.DateEnd && (m.DateTo >= CutOffDuration_Prev.DateStart || m.DateTo == null) && m.Status == HDTJobStatus.E_APPROVE.ToString()).OrderBy(m => m.DateFrom).FirstOrDefault(); if (HDTJOB_DateFrom != null) { DateTime form = HDTJOB_DateFrom.DateFrom != null ? (DateTime)HDTJOB_DateFrom.DateFrom : DateTime.MinValue; DateTime to = HDTJOB_DateFrom.DateTo != null ? (DateTime)HDTJOB_DateFrom.DateTo : CutOffDuration.DateEnd; item = new ElementFormula(PayrollElement.HR_START_DATE_HDTJOB_PREV.ToString(), form, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.HR_END_DATE_HDTJOB_PREV.ToString(), to, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.HR_START_DATE_HDTJOB_PREV.ToString(), DateTime.MinValue, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.HR_END_DATE_HDTJOB_PREV.ToString(), DateTime.MinValue, 0, "Null"); listElementFormula.Add(item); } } else { item = new ElementFormula(PayrollElement.HR_START_DATE_HDTJOB_PREV.ToString(), DateTime.MinValue, 0, "Không tồn tại kỳ N-1"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.HR_END_DATE_HDTJOB_PREV.ToString(), DateTime.MinValue, 0, "Không tồn tại kỳ N-1"); listElementFormula.Add(item); } } #endregion #region Tính số ngày công đi làm HDT JOB Tháng N if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.ATT_WORKDAY_HDTJOB_4.ToString()) || CheckIsExistFormula(listElementFormula, formula, PayrollElement.ATT_WORKDAY_HDTJOB_5.ToString()))//đã lấy lên chưa ? { double HDTJobDay = 0; if (listAttendanceTableProCut != null) { if (listAttendanceTableProCut.HDTJobType1 != null && listAttendanceTableProCut.HDTJobType1 == EnumDropDown.HDTJobType.E_TYPE4.ToString()) { HDTJobDay += listAttendanceTableProCut.HDTJobDayCount1 != null ? (int)listAttendanceTableProCut.HDTJobDayCount1 : 0; } if (listAttendanceTableProCut.HDTJobType2 != null && listAttendanceTableProCut.HDTJobType2 == EnumDropDown.HDTJobType.E_TYPE4.ToString()) { HDTJobDay += listAttendanceTableProCut.HDTJobDayCount2 != null ? (int)listAttendanceTableProCut.HDTJobDayCount2 : 0; } if (listAttendanceTableProCut.HDTJobType3 != null && listAttendanceTableProCut.HDTJobType3 == EnumDropDown.HDTJobType.E_TYPE4.ToString()) { HDTJobDay += listAttendanceTableProCut.HDTJobDayCount3 != null ? (int)listAttendanceTableProCut.HDTJobDayCount3 : 0; } } //Số ngày công làm HDT Job Loại 4 (tháng N) item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDTJOB_4.ToString(), HDTJobDay, 0); listElementFormula.Add(item); HDTJobDay = 0; if (listAttendanceTableProCut != null) { if (listAttendanceTableProCut.HDTJobType1 != null && listAttendanceTableProCut.HDTJobType1 == EnumDropDown.HDTJobType.E_TYPE5.ToString()) { HDTJobDay += listAttendanceTableProCut.HDTJobDayCount1 != null ? (int)listAttendanceTableProCut.HDTJobDayCount1 : 0; } if (listAttendanceTableProCut.HDTJobType2 != null && listAttendanceTableProCut.HDTJobType2 == EnumDropDown.HDTJobType.E_TYPE5.ToString()) { HDTJobDay += listAttendanceTableProCut.HDTJobDayCount2 != null ? (int)listAttendanceTableProCut.HDTJobDayCount2 : 0; } if (listAttendanceTableProCut.HDTJobType3 != null && listAttendanceTableProCut.HDTJobType3 == EnumDropDown.HDTJobType.E_TYPE5.ToString()) { HDTJobDay += listAttendanceTableProCut.HDTJobDayCount3 != null ? (int)listAttendanceTableProCut.HDTJobDayCount3 : 0; } } //Số ngày công làm HDT Job Loại 5 (tháng N) item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDTJOB_5.ToString(), HDTJobDay, 0); listElementFormula.Add(item); } #endregion #region Tính số ngày công đi làm HDT JOB Tháng N-1 if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_WORKDAY_HDTJOB_PREV_4.ToString(), PayrollElement.ATT_WORKDAY_HDTJOB_PREV_5.ToString() })) { //lấy dữ liệu công tháng N-1 var listAttendanceTableProCut_Prev = TotalData.Att_AttendanceTable_Prev.Where(m => m.ProfileID == profileItem.ID).FirstOrDefault(); double HDTJobDay = 0; if (listAttendanceTableProCut_Prev != null && listAttendanceTableProCut_Prev.HDTJobType1 != null && listAttendanceTableProCut_Prev.HDTJobType1 == EnumDropDown.HDTJobType.E_TYPE4.ToString()) { HDTJobDay += listAttendanceTableProCut_Prev.HDTJobDayCount1 != null ? (int)listAttendanceTableProCut_Prev.HDTJobDayCount1 : 0; } if (listAttendanceTableProCut_Prev != null && listAttendanceTableProCut_Prev.HDTJobType2 != null && listAttendanceTableProCut_Prev.HDTJobType2 == EnumDropDown.HDTJobType.E_TYPE4.ToString()) { HDTJobDay += listAttendanceTableProCut_Prev.HDTJobDayCount2 != null ? (int)listAttendanceTableProCut_Prev.HDTJobDayCount2 : 0; } if (listAttendanceTableProCut_Prev != null && listAttendanceTableProCut_Prev.HDTJobType3 != null && listAttendanceTableProCut_Prev.HDTJobType3 == EnumDropDown.HDTJobType.E_TYPE4.ToString()) { HDTJobDay += listAttendanceTableProCut_Prev.HDTJobDayCount3 != null ? (int)listAttendanceTableProCut_Prev.HDTJobDayCount3 : 0; } //Số ngày công làm HDT Job Loại 4 (tháng N) item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDTJOB_PREV_4.ToString(), HDTJobDay, 0); listElementFormula.Add(item); HDTJobDay = 0; if (listAttendanceTableProCut_Prev != null && listAttendanceTableProCut_Prev.HDTJobType1 != null && listAttendanceTableProCut_Prev.HDTJobType1 == EnumDropDown.HDTJobType.E_TYPE5.ToString()) { HDTJobDay += listAttendanceTableProCut_Prev.HDTJobDayCount1 != null ? (int)listAttendanceTableProCut_Prev.HDTJobDayCount1 : 0; } if (listAttendanceTableProCut_Prev != null && listAttendanceTableProCut_Prev.HDTJobType2 != null && listAttendanceTableProCut_Prev.HDTJobType2 == EnumDropDown.HDTJobType.E_TYPE5.ToString()) { HDTJobDay += listAttendanceTableProCut_Prev.HDTJobDayCount2 != null ? (int)listAttendanceTableProCut_Prev.HDTJobDayCount2 : 0; } if (listAttendanceTableProCut_Prev != null && listAttendanceTableProCut_Prev.HDTJobType3 != null && listAttendanceTableProCut_Prev.HDTJobType3 == EnumDropDown.HDTJobType.E_TYPE5.ToString()) { HDTJobDay += listAttendanceTableProCut_Prev.HDTJobDayCount3 != null ? (int)listAttendanceTableProCut_Prev.HDTJobDayCount3 : 0; } //Số ngày công làm HDT Job Loại 5 (tháng N) item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDTJOB_PREV_5.ToString(), HDTJobDay, 0); listElementFormula.Add(item); } #endregion #region Phần tử kiểm tra có ngày ra HDT hay không tháng N và tháng N-1 if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_HDT_IS_DATE_END.ToString(), PayrollElement.ATT_HDT_IS_DATE_END_N_1.ToString() })) { #region Tháng N List<Hre_HDTJobEntity> HDTJOBByProfile = new List<Hre_HDTJobEntity>(); HDTJOBByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.DateFrom <= CutOffDuration.DateEnd && (m.DateTo >= CutOffDuration.DateStart || m.DateTo == null) && m.Status == HDTJobStatus.E_APPROVE.ToString()).ToList(); if (HDTJOBByProfile.Any(m => m.DateTo == null)) { item = new ElementFormula(PayrollElement.ATT_HDT_IS_DATE_END.ToString(), 1, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.ATT_HDT_IS_DATE_END.ToString(), 0, 0); listElementFormula.Add(item); } #endregion #region Tháng N-1 DateTime DateStartN1 = CutOffDuration.DateStart.AddMonths(-1); DateTime DateEndN1 = CutOffDuration.DateEnd.AddMonths(-1); HDTJOBByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.DateFrom <= DateEndN1 && (m.DateTo >= DateStartN1 || m.DateTo == null) && m.Status == HDTJobStatus.E_APPROVE.ToString()).ToList(); if (HDTJOBByProfile.Any(m => m.DateTo == null)) { item = new ElementFormula(PayrollElement.ATT_HDT_IS_DATE_END.ToString(), 1, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.ATT_HDT_IS_DATE_END.ToString(), 0, 0); listElementFormula.Add(item); } #endregion } #endregion #region Số ngày làm HDT loại 4 và 5 trừ ngày DayOff (tháng N và tháng N-1) if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_4.ToString(), PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_5.ToString(), PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_4_N_1.ToString(), PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_5_N_1.ToString() })) { DateTime DateStartN1 = CutOffDuration.DateStart.AddMonths(-1); DateTime DateEndN1 = CutOffDuration.DateEnd.AddMonths(-1); List<Hre_HDTJobEntity> ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString()).ToList(); List<Hre_HDTJobEntity> ListHDTByProfileN = ListHDTByProfile.Where(m => m.DateFrom <= CutOffDuration.DateEnd && (m.DateTo >= CutOffDuration.DateStart || m.DateTo == null)).ToList(); List<Hre_HDTJobEntity> ListHDTByProfileN1 = ListHDTByProfile.Where(m => m.DateFrom <= DateEndN1 && (m.DateTo >= DateStartN1 || m.DateTo == null)).ToList(); double ListDayOff = TotalData.listDayOff.Count(m => m.DateOff <= CutOffDuration.DateEnd && m.DateOff >= CutOffDuration.DateStart); double ListDayOffN1 = TotalData.listDayOff.Count(m => m.DateOff <= DateEndN1 && m.DateOff >= DateStartN1); #region tính số ngày làm HDT loại 4 List<Hre_HDTJobEntity> ListHDTByProfileN_Type4 = ListHDTByProfileN.Where(m => m.Type == EnumDropDown.HDTJobType.E_TYPE4.ToString()).ToList(); double Day_Type4 = 0; DateTime _tmp = new DateTime(); foreach (var i in ListHDTByProfileN_Type4) { _tmp = i.DateTo != null ? i.DateTo.Value : CutOffDuration.DateEnd; if (i.DateFrom != null) { Day_Type4 += _tmp.Subtract(i.DateFrom.Value).TotalDays + 1; } } item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_4.ToString(), Day_Type4, 0); listElementFormula.Add(item); #endregion #region tính số ngày làm HDT loại 5 List<Hre_HDTJobEntity> ListHDTByProfileN_Type5 = ListHDTByProfileN.Where(m => m.Type == EnumDropDown.HDTJobType.E_TYPE5.ToString()).ToList(); double Day_Type5 = 0; foreach (var i in ListHDTByProfileN_Type5) { _tmp = i.DateTo != null ? i.DateTo.Value : CutOffDuration.DateEnd; if (i.DateFrom != null) { Day_Type5 += _tmp.Subtract(i.DateFrom.Value).TotalDays + 1; } } item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_5.ToString(), Day_Type5, 0); listElementFormula.Add(item); #endregion #region tính số ngày làm HDT loại 4 tháng N-1 ListHDTByProfileN_Type4 = ListHDTByProfileN1.Where(m => m.Type == EnumDropDown.HDTJobType.E_TYPE4.ToString()).ToList(); Day_Type4 = 0; _tmp = new DateTime(); foreach (var i in ListHDTByProfileN_Type4) { _tmp = i.DateTo != null ? i.DateTo.Value : CutOffDuration.DateEnd; if (i.DateFrom != null) { Day_Type4 += _tmp.Subtract(i.DateFrom.Value).TotalDays + 1; } } item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_4_N_1.ToString(), Day_Type4, 0); listElementFormula.Add(item); #endregion #region tính số ngày làm HDT loại 5 tháng N-1 ListHDTByProfileN_Type5 = ListHDTByProfileN1.Where(m => m.Type == EnumDropDown.HDTJobType.E_TYPE5.ToString()).ToList(); Day_Type5 = 0; foreach (var i in ListHDTByProfileN_Type5) { _tmp = i.DateTo != null ? i.DateTo.Value : CutOffDuration.DateEnd; if (i.DateFrom != null) { Day_Type5 += _tmp.Subtract(i.DateFrom.Value).TotalDays + 1; } } item = new ElementFormula(PayrollElement.ATT_WORKDAY_HDT_NOT_DAYOFF_5_N_1.ToString(), Day_Type5, 0); listElementFormula.Add(item); #endregion } #endregion #region Số ngày Day Off từ đầu tháng đến ngày vào HDT if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_DAYOFF_STARTMONTH_STARTHDT.ToString(), PayrollElement.ATT_DAYOFF_STARTMONTH_STARTHDT_N_1.ToString() })) { #region Tháng N Hre_HDTJobEntity ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= CutOffDuration.DateEnd && m.DateTo >= CutOffDuration.DateStart).OrderBy(m => m.DateFrom).FirstOrDefault(); if (ListHDTByProfile != null) { double DayOff = TotalData.listDayOff.Count(m => m.DateOff <= ListHDTByProfile.DateFrom && m.DateOff >= CutOffDuration.DateStart); item = new ElementFormula(PayrollElement.ATT_DAYOFF_STARTMONTH_STARTHDT.ToString(), DayOff, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.ATT_DAYOFF_STARTMONTH_STARTHDT.ToString(), 0, 0, "null"); listElementFormula.Add(item); } #endregion #region Tháng N-1 DateTime DateStartN1 = CutOffDuration.DateStart.AddMonths(-1); DateTime DateEndN1 = CutOffDuration.DateEnd.AddMonths(-1); ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= DateEndN1 && m.DateTo >= DateStartN1).OrderBy(m => m.DateFrom).FirstOrDefault(); if (ListHDTByProfile != null) { double DayOff = TotalData.listDayOff.Count(m => m.DateOff <= ListHDTByProfile.DateFrom && m.DateOff >= DateStartN1); item = new ElementFormula(PayrollElement.ATT_DAYOFF_STARTMONTH_STARTHDT_N_1.ToString(), DayOff, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.ATT_DAYOFF_STARTMONTH_STARTHDT_N_1.ToString(), 0, 0, "null"); listElementFormula.Add(item); } #endregion } #endregion #region số ngày từ ngày vào hdt đến cuối tháng trừ số ngày dayoff từ ngày vào đến cuối tháng(tháng N và tháng N-1) if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_WORKDAY_STARTHDT_MONTHEND.ToString(), PayrollElement.ATT_WORKDAY_STARTHDT_MONTHEND_N_1.ToString() })) { double WorkDay = 0; double DayOff = 0; #region Tháng N List<Hre_HDTJobEntity> ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= CutOffDuration.DateEnd && m.DateTo >= CutOffDuration.DateStart).OrderBy(m => m.DateFrom).ToList(); if (ListHDTByProfile.Count > 0) { foreach (var i in ListHDTByProfile) { if (i.DateFrom != null && i.DateTo != null) { if (i.DateTo < CutOffDuration.DateEnd) { WorkDay += i.DateTo.Value.Subtract(i.DateFrom.Value).TotalDays + 1; } else { WorkDay += CutOffDuration.DateEnd.Subtract(i.DateFrom.Value).TotalDays + 1; } } } DayOff = TotalData.listDayOff.Count(m => m.DateOff >= ListHDTByProfile.FirstOrDefault().DateFrom && m.DateOff <= CutOffDuration.DateEnd); item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_MONTHEND.ToString(), WorkDay - DayOff, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_MONTHEND.ToString(), 0, 0, "null"); listElementFormula.Add(item); } #endregion #region Tháng N-1 DateTime DateStartN1 = CutOffDuration.DateStart.AddMonths(-1); DateTime DateEndN1 = CutOffDuration.DateEnd.AddMonths(-1); WorkDay = 0; DayOff = 0; ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= DateEndN1 && m.DateTo >= DateStartN1).OrderBy(m => m.DateFrom).ToList(); if (ListHDTByProfile.Count > 0) { foreach (var i in ListHDTByProfile) { if (i.DateFrom != null && i.DateTo != null) { if (i.DateTo < CutOffDuration.DateEnd) { WorkDay += i.DateTo.Value.Subtract(i.DateFrom.Value).TotalDays + 1; } else { WorkDay += CutOffDuration.DateEnd.Subtract(i.DateFrom.Value).TotalDays + 1; } } } DayOff = TotalData.listDayOff.Count(m => m.DateOff >= ListHDTByProfile.FirstOrDefault().DateFrom && m.DateOff <= CutOffDuration.DateEnd); item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_MONTHEND_N_1.ToString(), WorkDay - DayOff, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_MONTHEND_N_1.ToString(), 0, 0, "null"); listElementFormula.Add(item); } #endregion } #endregion #region số ngày từ ngày vào hdt tháng N-1 đến ngày ra hdt tháng N-1 trừ ngày dayoff tháng N-1 và N-2 if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_1.ToString(), PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_2.ToString() })) { DateTime DateStartN1 = CutOffDuration.DateStart.AddMonths(-1); DateTime DateEndN1 = CutOffDuration.DateEnd.AddMonths(-1); DateTime DateStartN2 = CutOffDuration.DateStart.AddMonths(-2); DateTime DateEndN2 = CutOffDuration.DateEnd.AddMonths(-2); double workDayHDT = 0; double DayOff = TotalData.listDayOff.Count(m => m.DateOff <= DateEndN1 && m.DateOff >= DateStartN1); #region Tháng N-1 List<Hre_HDTJobEntity> ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= DateEndN1 && m.DateTo >= DateStartN1).OrderBy(m => m.DateFrom).ToList(); foreach (var i in ListHDTByProfile) { workDayHDT += i.DateTo.Value.Subtract(i.DateFrom.Value).TotalDays + 1; } item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_1.ToString(), workDayHDT - DayOff, 0); listElementFormula.Add(item); #endregion #region Tháng N-2 workDayHDT = 0; DayOff = TotalData.listDayOff.Count(m => m.DateOff <= DateEndN2 && m.DateOff >= DateStartN2); ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= DateEndN2 && m.DateTo >= DateStartN2).OrderBy(m => m.DateFrom).ToList(); foreach (var i in ListHDTByProfile) { workDayHDT += i.DateTo.Value.Subtract(i.DateFrom.Value).TotalDays + 1; } item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_2.ToString(), workDayHDT - DayOff, 0); listElementFormula.Add(item); #endregion } #endregion #region Ngày vào HDT tháng N-1 và N-2 if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_STARTDATE_HDT_N_1.ToString(), PayrollElement.ATT_STARTDATE_HDT_N_2.ToString() })) { DateTime DateStartN1 = CutOffDuration.DateStart.AddMonths(-1); DateTime DateEndN1 = CutOffDuration.DateEnd.AddMonths(-1); DateTime DateStartN2 = CutOffDuration.DateStart.AddMonths(-2); DateTime DateEndN2 = CutOffDuration.DateEnd.AddMonths(-2); Hre_HDTJobEntity ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= DateEndN1 && m.DateTo >= DateStartN1).OrderBy(m => m.DateFrom).FirstOrDefault(); if (ListHDTByProfile != null) { item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_1.ToString(), ListHDTByProfile.DateFrom, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_1.ToString(), 0, 0); listElementFormula.Add(item); } ListHDTByProfile = TotalData.listHre_HDTJob_All.Where(m => m.ProfileID == profileItem.ID && m.Status == HDTJobStatus.E_APPROVE.ToString() && m.DateTo != null && m.DateFrom != null && m.DateFrom <= DateEndN2 && m.DateTo >= DateStartN2).OrderBy(m => m.DateFrom).FirstOrDefault(); if (ListHDTByProfile != null) { item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_2.ToString(), ListHDTByProfile.DateFrom, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.ATT_WORKDAY_STARTHDT_ENDHDT_N_2.ToString(), 0, 0); listElementFormula.Add(item); } } #endregion #endregion #endregion #region Enum phần tử lương //Có tham gia công đoàn if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.IS_HRE_TRADEUNION.ToString())) { var ProfilePartyUnion = TotalData.listProfilePartyUnion.Where(m => m.ProfileID == profileItem.ID && m.IsTradeUnionist == true && m.TradeUnionistEnrolledDate != null && m.TradeUnionistEnrolledDate.Value <= CutOffDuration.DateEnd).FirstOrDefault(); item = new ElementFormula(PayrollElement.IS_HRE_TRADEUNION.ToString(), ProfilePartyUnion != null ? 1 : 0, 0); listElementFormula.Add(item); } //Người phụ thuộc if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_DEPENDENT.ToString())) { item = new ElementFormula(PayrollElement.SAL_DEPENDENT.ToString(), GetDependantNumber(TotalData.listDependant, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd), 0); listElementFormula.Add(item); } //Mức lương HDT if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_SALARY_HDT.ToString(), PayrollElement.SAL_SALARY_HDT_N_1.ToString() })) { var Insurence = TotalData.listInsurance.Where(m => m.ProfileID == profileItem.ID && m.MonthYear != null && m.MonthYear.Value.Year == CutOffDuration.MonthYear.Year && m.MonthYear.Value.Month == CutOffDuration.MonthYear.Month).FirstOrDefault(); item = new ElementFormula(PayrollElement.SAL_SALARY_HDT.ToString(), Insurence != null && Insurence.AmountChargeIns != null ? Insurence.AmountChargeIns : 0, 0); listElementFormula.Add(item); DateTime MonthYearPrev = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CutOffDuration.MonthYear.Day).AddMonths(-1); Insurence = TotalData.listInsurance.Where(m => m.ProfileID == profileItem.ID && m.MonthYear != null && m.MonthYear.Value.Year == MonthYearPrev.Year && m.MonthYear.Value.Month == MonthYearPrev.Month).FirstOrDefault(); item = new ElementFormula(PayrollElement.SAL_SALARY_HDT_N_1.ToString(), Insurence != null && Insurence.AmountChargeIns != null ? Insurence.AmountChargeIns : 0, 0); listElementFormula.Add(item); } //Luong co ban thang 3 if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_BASIC_SALARY_T3.ToString())) { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_T3.ToString(), TotalData.listBasicSalaryT3.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).FirstOrDefault().GrossAmount, 0); listElementFormula.Add(item); } //Bậc lương if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_SALARY_RANK_NAME.ToString())) { Sal_BasicSalaryEntity BasicSalarybyProfile = new Sal_BasicSalaryEntity(); BasicSalarybyProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).FirstOrDefault(); item = new ElementFormula(PayrollElement.SAL_SALARY_RANK_NAME.ToString(), BasicSalarybyProfile != null ? BasicSalarybyProfile.SalaryRankName : "", 0); listElementFormula.Add(item); } //Bậc lương (class) if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_SALARY_CLASS_NAME.ToString())) { Sal_BasicSalaryEntity BasicSalarybyProfile = new Sal_BasicSalaryEntity(); BasicSalarybyProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).FirstOrDefault(); item = new ElementFormula(PayrollElement.SAL_SALARY_CLASS_NAME.ToString(), BasicSalarybyProfile != null ? BasicSalarybyProfile.SalaryClassName : "", 0); listElementFormula.Add(item); } //Hệ số lương nhân viên if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_BASIC_PERSONALRATE.ToString())) { List<Sal_BasicSalaryEntity> SalaryProfile = new List<Sal_BasicSalaryEntity>(); SalaryProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).ToList(); item = new ElementFormula(PayrollElement.SAL_BASIC_PERSONALRATE.ToString(), SalaryProfile.FirstOrDefault().PersonalRate != null ? SalaryProfile.FirstOrDefault().PersonalRate : 0, 0, "Null"); listElementFormula.Add(item); } if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_BASIC_SALARY_DATECLOSE.ToString(), PayrollElement.SAL_BASIC_SALARY_DATECLOSE_N_1.ToString() })) { List<Sal_BasicSalaryEntity> ListSalaryProfile = new List<Sal_BasicSalaryEntity>(); ListSalaryProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).ToList(); if (ListSalaryProfile.Count > 0) { //Lấy các phần tử tính lương nằm trong Grade của nhân viên Sal_GradeEntity Grade = FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd); //loại bỏ nhân viên có ngày vào làm sau ngày chốt lương Cat_GradePayrollEntity CatGrade = TotalData.listCat_GradePayroll.Where(m => m.ID == Grade.GradePayrollID).FirstOrDefault(); //ngày bắt đầu chốt lương DateTime DateClose = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1).AddDays(1).AddMonths(-1); //ngày kết thúc chốt lương DateTime DateEndClose = new DateTime(CutOffDuration.MonthYear.Year, CutOffDuration.MonthYear.Month, CatGrade.SalaryDayClose != null ? (int)CatGrade.SalaryDayClose : 1); //lọc lại lương cơ bản theo kỳ chốt ListSalaryProfile = ListSalaryProfile.Where(m => m.DateOfEffect <= DateEndClose).ToList(); //lương cơ bản gần nhất Sal_BasicSalaryEntity SalaryProfile = ListSalaryProfile.FirstOrDefault(); //nếu ngày thay đổi lương nằm trong kỳ chốt lương thì lấy 2 mức if (SalaryProfile.DateOfEffect >= DateClose && SalaryProfile.DateOfEffect <= DateEndClose) { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_DATECLOSE.ToString(), SalaryProfile.GrossAmount, 0); listElementFormula.Add(item); Sal_BasicSalaryEntity SalaryProfile_Prev = ListSalaryProfile.Where(m => m.DateOfEffect < DateClose).OrderByDescending(m => m.DateOfEffect).FirstOrDefault(); item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_DATECLOSE_N_1.ToString(), SalaryProfile_Prev != null ? SalaryProfile_Prev.GrossAmount : "0", 0); listElementFormula.Add(item); } else//chỉ áp dụng 1 mức lương { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_DATECLOSE.ToString(), SalaryProfile.GrossAmount, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_DATECLOSE_N_1.ToString(), SalaryProfile.GrossAmount, 0); listElementFormula.Add(item); } } else { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_DATECLOSE.ToString(), 0, 0, "Không có lương cơ bản !"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_DATECLOSE_N_1.ToString(), 0, 0, "Không có thay đổi lương trong tháng !"); listElementFormula.Add(item); } } //Lương cơ bản if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_BASIC_SALARY.ToString(), PayrollElement.HR_SALARYCLASSNAME.ToString(), PayrollElement.SAL_BASIC_SALARY2.ToString(), PayrollElement.SAL_BASIC_SALARY1.ToString(), PayrollElement.SAL_BASIC_SALARY_N_1.ToString(), PayrollElement.SAL_BASIC_SALARY_N_2.ToString(), PayrollElement.SAL_BASIC_SALARY_N_3.ToString(), PayrollElement.SAL_BASIC_SALARY_N_4.ToString(), PayrollElement.SAL_BASIC_SALARY_N_5.ToString(), PayrollElement.SAL_BASIC_SALARY_N_6.ToString(), PayrollElement.SAL_INCENTIVE.ToString() })) { using (var context = new VnrHrmDataContext()) { var unitOfWork = (IUnitOfWork)(new UnitOfWork(context)); List<Sal_BasicSalaryEntity> SalaryProfile = new List<Sal_BasicSalaryEntity>(); SalaryProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).ToList(); if (SalaryProfile != null && SalaryProfile.Count > 0)//có lương cơ bản { //bật lương item = new ElementFormula(PayrollElement.HR_SALARYCLASSNAME.ToString(), SalaryProfile.FirstOrDefault().SalaryClassCode, 0, "Null"); listElementFormula.Add(item); //lương cơ bản tháng hiện tại if (SalaryProfile.FirstOrDefault().DateOfEffect <= CutOffDuration.DateStart)//chỉ có 1 mức lương trong tháng { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY.ToString(), SalaryProfile.OrderByDescending(m => m.DateOfEffect).FirstOrDefault().GrossAmount, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_INCENTIVE.ToString(), 0, 0); listElementFormula.Add(item); } else//2 mức lương trong tháng { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY2.ToString(), SalaryProfile.FirstOrDefault().GrossAmount, 0); listElementFormula.Add(item); if (SalaryProfile.Count > 1) { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY1.ToString(), SalaryProfile[1].GrossAmount, 0); } else { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY1.ToString(), 0, 0, "Null"); } listElementFormula.Add(item); #region Tính số ngày thay đổi lương List<Att_RosterEntity> listRosterProfile = new List<Att_RosterEntity>(); //Lọc ra các roster thuộc nhân viên và nằm trong tháng tính lương listRosterProfile = TotalData.listRoster.Where(m => m.ProfileID == profileItem.ID).ToList(); int totalLeave = 0; foreach (var j in listRosterProfile) { DateTime _tmp = j.DateStart; while (true) { if (_tmp > CutOffDuration.DateEnd) { break; } if (_tmp >= SalaryProfile.FirstOrDefault().DateOfEffect) { int day = (int)_tmp.DayOfWeek; switch (day) { case 0://CN if (j.SunShiftID != null) { totalLeave++; } break; case 1://T2 if (j.MonShiftID != null) { totalLeave++; } break; case 2: if (j.TueShiftID != null) { totalLeave++; } break; case 3: if (j.WedShiftID != null) { totalLeave++; } break; case 4: if (j.ThuShiftID != null) { totalLeave++; } break; case 5: if (j.FriShiftID != null) { totalLeave++; } break; case 6: if (j.SatShiftID != null) { totalLeave++; } break; default: break; } } _tmp = _tmp.AddDays(1); } } //cập nhật lại giá trị cho enum số ngày thay đổi lương int days = (CutOffDuration.DateEnd - SalaryProfile.FirstOrDefault().DateOfEffect).Days; days = days - totalLeave; item = new ElementFormula(PayrollElement.SAL_INCENTIVE.ToString(), days, 0); listElementFormula.Add(item); //item = listElementFormula.Where(m => m.VariableName == PayrollElement.SAL_INCENTIVE.ToString()).FirstOrDefault(); //item.Value = days; #endregion } #region lương cơ bản 6 tháng trước đó var _basicsalaryPrevCurrentMonth = SalaryProfile.Where(m => m.DateOfEffect <= CutOffDuration.DateEnd.AddMonths(-1)).OrderByDescending(m => m.DateOfEffect).ToList(); if (_basicsalaryPrevCurrentMonth.Count > 0) { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_1.ToString(), _basicsalaryPrevCurrentMonth.FirstOrDefault().GrossAmount, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_1.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } _basicsalaryPrevCurrentMonth = SalaryProfile.Where(m => m.DateOfEffect <= CutOffDuration.DateEnd.AddMonths(-2)).OrderByDescending(m => m.DateOfEffect).ToList(); if (_basicsalaryPrevCurrentMonth.Count > 0) { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_2.ToString(), _basicsalaryPrevCurrentMonth.FirstOrDefault().GrossAmount, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_2.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } _basicsalaryPrevCurrentMonth = SalaryProfile.Where(m => m.DateOfEffect <= CutOffDuration.DateEnd.AddMonths(-3)).OrderByDescending(m => m.DateOfEffect).ToList(); if (_basicsalaryPrevCurrentMonth.Count > 0) { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_3.ToString(), _basicsalaryPrevCurrentMonth.FirstOrDefault().GrossAmount, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_3.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } _basicsalaryPrevCurrentMonth = SalaryProfile.Where(m => m.DateOfEffect <= CutOffDuration.DateEnd.AddMonths(-4)).OrderByDescending(m => m.DateOfEffect).ToList(); if (_basicsalaryPrevCurrentMonth.Count > 0) { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_4.ToString(), _basicsalaryPrevCurrentMonth.FirstOrDefault().GrossAmount, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_4.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } _basicsalaryPrevCurrentMonth = SalaryProfile.Where(m => m.DateOfEffect <= CutOffDuration.DateEnd.AddMonths(-5)).OrderByDescending(m => m.DateOfEffect).ToList(); if (_basicsalaryPrevCurrentMonth.Count > 0) { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_5.ToString(), _basicsalaryPrevCurrentMonth.FirstOrDefault().GrossAmount, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_5.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } _basicsalaryPrevCurrentMonth = SalaryProfile.Where(m => m.DateOfEffect <= CutOffDuration.DateEnd.AddMonths(-6)).OrderByDescending(m => m.DateOfEffect).ToList(); if (_basicsalaryPrevCurrentMonth.Count > 0) { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_6.ToString(), _basicsalaryPrevCurrentMonth.FirstOrDefault().GrossAmount, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_6.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } #endregion } else//không có lương cơ bản { item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY.ToString(), 0, 0, "Không có lương cơ bản tháng N"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_1.ToString(), 0, 0, "Không có lương cơ bản tháng N-1"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_2.ToString(), 0, 0, "Không có lương cơ bản tháng N-2"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_3.ToString(), 0, 0, "Không có lương cơ bản tháng N-3"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_4.ToString(), 0, 0, "Không có lương cơ bản tháng N-4"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_5.ToString(), 0, 0, "Không có lương cơ bản tháng N-5"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY_N_6.ToString(), 0, 0, "Không có lương cơ bản tháng N-6"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY1.ToString(), 0, 0, "Không có lương cơ bản tháng N"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_BASIC_SALARY2.ToString(), 0, 0, "Không có lương cơ bản tháng N"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_INCENTIVE.ToString(), 0, 0, "Không có thay đổi lương tháng N"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.HR_SALARYCLASSNAME.ToString(), 0, 0, "Không có Bậc / Hệ số lương tháng N"); listElementFormula.Add(item); } } } if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_UNUSUALALLOWANCE_MONTHSTART.ToString(), PayrollElement.SAL_UNUSUALALLOWANCE_MONTHEND.ToString(), PayrollElement.SAL_UNUSUALALLOWANCE_YEARSTART.ToString(), PayrollElement.SAL_UNUSUALALLOWANCE_YEAREND.ToString(), PayrollElement.SAL_UNUSUALALLOWANCE_NOCOMPENSATION.ToString() })) { Sal_UnusualAllowanceEntity SalUnusualAllowanceProfile = TotalData.listSalUnusualAllowance.Where(m => m.ProfileID == profileItem.ID && m.MonthStart <= CutOffDuration.DateEnd && (m.MonthEnd == null || m.MonthEnd >= CutOffDuration.DateStart)).FirstOrDefault(); //Tháng bắt đầu hưởng PC item = new ElementFormula(PayrollElement.SAL_UNUSUALALLOWANCE_MONTHSTART.ToString(), SalUnusualAllowanceProfile != null ? SalUnusualAllowanceProfile.MonthStart != null ? SalUnusualAllowanceProfile.MonthStart : DateTime.MinValue : DateTime.MinValue, 0); listElementFormula.Add(item); //Tháng kết thúc hưởng PC item = new ElementFormula(PayrollElement.SAL_UNUSUALALLOWANCE_MONTHEND.ToString(), SalUnusualAllowanceProfile != null ? SalUnusualAllowanceProfile.MonthEnd != null ? SalUnusualAllowanceProfile.MonthEnd : DateTime.MinValue : DateTime.MinValue, 0); listElementFormula.Add(item); //Năm bắt đầu hưởng PC item = new ElementFormula(PayrollElement.SAL_UNUSUALALLOWANCE_YEARSTART.ToString(), SalUnusualAllowanceProfile != null ? SalUnusualAllowanceProfile.MonthStart != null ? SalUnusualAllowanceProfile.MonthStart.Value.Year : 0 : 0, 0); listElementFormula.Add(item); //Năm kết thúc hưởng PC item = new ElementFormula(PayrollElement.SAL_UNUSUALALLOWANCE_YEAREND.ToString(), SalUnusualAllowanceProfile != null ? SalUnusualAllowanceProfile.MonthEnd != null ? SalUnusualAllowanceProfile.MonthEnd.Value.Year : 0 : 0, 0); listElementFormula.Add(item); //Số tháng bù item = new ElementFormula(PayrollElement.SAL_UNUSUALALLOWANCE_NOCOMPENSATION.ToString(), SalUnusualAllowanceProfile != null ? SalUnusualAllowanceProfile.NoCompensation != null ? SalUnusualAllowanceProfile.NoCompensation : 0 : 0, 0); listElementFormula.Add(item); } //// Mức phụ cấp con nhỏ mỗi tháng //item = new ElementFormula(PayrollElement.SAL_UNUSUALALLOWANCE_NOCOMPENSATION.ToString(), 0, 0); //listElementFormula.Add(item); //Thánh tính lương if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.ATT_CUTOFFDURATION_MONTH.ToString())) { item = new ElementFormula(PayrollElement.ATT_CUTOFFDURATION_MONTH.ToString(), CutOffDuration.DateStart, 0); listElementFormula.Add(item); } //Tổng lương bộ phận của nhân viên if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_SALARY_DEPARTMENT.ToString())) { if (TotalData.listSal_SalaryDepartmentItem.Any(m => m.ProfileID == profileItem.ID)) { var AmountSalary = TotalData.listSal_SalaryDepartmentItem.Where(m => m.ProfileID == profileItem.ID).FirstOrDefault().AmoutSalary; item = new ElementFormula(PayrollElement.SAL_SALARY_DEPARTMENT.ToString(), AmountSalary != null ? AmountSalary : 0, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.SAL_SALARY_DEPARTMENT.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } } if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_SALARY_DATE_CLOSE.ToString())) { Cat_GradePayrollEntity CatGradePayrollItem = TotalData.listCat_GradePayroll.Where(m => m.ID == FindGradePayrollByProfileAndMonthYear(TotalData.listGrade, profileItem.ID, CutOffDuration.DateStart, CutOffDuration.DateEnd).ID).FirstOrDefault(); if (CatGradePayrollItem != null && CatGradePayrollItem.SalaryDayClose != null) { item = new ElementFormula(PayrollElement.SAL_SALARY_DATE_CLOSE.ToString(), CatGradePayrollItem.SalaryDayClose, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.SAL_SALARY_DATE_CLOSE.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } } //Giữ lương if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_HOLD_SALARY.ToString(), PayrollElement.SAL_HOLD_SALARY_AFTERTAX.ToString() })) { DateTime _tmpCutoffDuration = CutOffDuration.MonthYear.AddMonths(-1); Sal_HoldSalaryEntity holdSalaryItem = TotalData.listSal_HoldSalary.Where(m => m.ProfileID == profileItem.ID && m.MonthEndSalary != null && m.Status == EnumDropDown.WorkdayStatus.E_APPROVED.ToString() && m.MonthEndSalary.Value.Month == _tmpCutoffDuration.Month && m.MonthEndSalary.Value.Year == _tmpCutoffDuration.Year).FirstOrDefault(); if (holdSalaryItem != null) { item = new ElementFormula(PayrollElement.SAL_HOLD_SALARY.ToString(), holdSalaryItem.AmountSalary, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_HOLD_SALARY_AFTERTAX.ToString(), holdSalaryItem.AmountSalaryAfterTax, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.SAL_HOLD_SALARY.ToString(), 0, 0, "null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_HOLD_SALARY_AFTERTAX.ToString(), 0, 0, "null"); listElementFormula.Add(item); } } if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_SALARY_ACCOUNT_NO.ToString(), PayrollElement.SAL_SALARY_GROUP_BANK.ToString(), PayrollElement.SAL_SALARY_BANK_NAME.ToString() })) { Sal_SalaryInformationEntity SalaryInfomationByProfile = TotalData.listSalaryInformation.FirstOrDefault(m => m.ProfileID == profileItem.ID); if (SalaryInfomationByProfile != null) { item = new ElementFormula(PayrollElement.SAL_SALARY_ACCOUNT_NO.ToString(), SalaryInfomationByProfile.AccountNo, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_SALARY_GROUP_BANK.ToString(), SalaryInfomationByProfile.GroupBank, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_SALARY_BANK_NAME.ToString(), SalaryInfomationByProfile.BankName, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.SAL_SALARY_ACCOUNT_NO.ToString(), "", 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_SALARY_GROUP_BANK.ToString(), "", 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_SALARY_BANK_NAME.ToString(), "", 0, "Null"); listElementFormula.Add(item); } } #endregion #region Enum phần tử công #region Phần tử công tháng trước (N-1) if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_WORKING_DAY_PREV.ToString(), PayrollElement.ATT_STD_DAY_PREV.ToString() })) { if (TotalData.Att_AttendanceTable_Prev != null) { Att_AttendanceTableEntity _tmp = TotalData.Att_AttendanceTable_Prev.Where(m => m.ProfileID == profileItem.ID).FirstOrDefault(); if (_tmp != null) { item = new ElementFormula(PayrollElement.ATT_WORKING_DAY_PREV.ToString(), _tmp.RealWorkDayCount, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_STD_DAY_PREV.ToString(), _tmp.StdWorkDayCount, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.ATT_WORKING_DAY_PREV.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_STD_DAY_PREV.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } } else { item = new ElementFormula(PayrollElement.ATT_WORKING_DAY_PREV.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_STD_DAY_PREV.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } } #endregion #region Ngày công đi làm thực tế if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_WORKING_DAY.ToString(), PayrollElement.ATT_WORKING_DAY_AFTER.ToString() })) { using (var context = new VnrHrmDataContext()) { var unitOfWork = (IUnitOfWork)new UnitOfWork(context); //lấy lương cơ bản của nhân viên List<Sal_BasicSalaryEntity> SalaryProfile = new List<Sal_BasicSalaryEntity>(); SalaryProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).ToList(); if (SalaryProfile.Count > 0 && SalaryProfile.FirstOrDefault().DateOfEffect > CutOffDuration.DateStart)//có thay đổi lương trong tháng { //ngày bắt đầu mức lương 1 và ngày bắt đầu mức lương 2 DateTime dateStart1 = CutOffDuration.DateStart; DateTime dateStart2 = SalaryProfile.FirstOrDefault().DateOfEffect; //lấy dữ liệu công theo cutoff List<Att_AttendanceTableItemEntity> listAttTableItem = TotalData.listAttendanceTableItem.Where(m => m.ProfileID == profileItem.ID).ToList(); item = new ElementFormula(PayrollElement.ATT_WORKING_DAY.ToString(), listAttTableItem.Where(m => m.WorkDate < dateStart2).Count(), 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_WORKING_DAY_AFTER.ToString(), listAttTableItem.Where(m => m.WorkDate >= dateStart2).Count(), 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.ATT_WORKING_DAY.ToString(), listAttendanceTableProCut.RealWorkDayCount, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_WORKING_DAY_AFTER.ToString(), 0, 0); listElementFormula.Add(item); } } } #endregion #region Ngày công đi làm tính lương if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_WORKING_PAIDLEAVE_DAY.ToString(), PayrollElement.ATT_WORKING_PAIDLEAVE_DAY_AFTER.ToString() })) { using (var context = new VnrHrmDataContext()) { var unitOfWork = (IUnitOfWork)new UnitOfWork(context); //lấy lương cơ bản của nhân viên List<Sal_BasicSalaryEntity> SalaryProfile = new List<Sal_BasicSalaryEntity>(); SalaryProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).ToList(); if (SalaryProfile.Count > 0 && SalaryProfile.FirstOrDefault().DateOfEffect > CutOffDuration.DateStart)//có thay đổi lương trong tháng { //ngày bắt đầu mức lương 1 và ngày bắt đầu mức lương 2 DateTime dateStart1 = CutOffDuration.DateStart; DateTime dateStart2 = SalaryProfile.FirstOrDefault().DateOfEffect; //lưu số ngày công tính lương trước và sau khi thay đổi lương double workpaid = 0; double workpaid_after = 0; //lấy dữ liệu công theo cutoff List<Att_AttendanceTableItemEntity> listAttTableItem = TotalData.listAttendanceTableItem.Where(m => m.ProfileID == profileItem.ID).ToList(); //duyệt wa tất cả các dòng foreach (var tableItem in listAttTableItem) { if (tableItem.WorkDate < dateStart2)//trước khi điều chỉnh { workpaid += tableItem.WorkPaidHours / tableItem.AvailableHours; } if (tableItem.WorkDate >= dateStart2)//sau khi điều chỉnh { workpaid_after += tableItem.WorkPaidHours / tableItem.AvailableHours; } } item = new ElementFormula(PayrollElement.ATT_WORKING_PAIDLEAVE_DAY.ToString(), listAttTableItem.Where(m => m.WorkDate < dateStart2).Count(), 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_WORKING_PAIDLEAVE_DAY_AFTER.ToString(), listAttTableItem.Where(m => m.WorkDate >= dateStart2).Count(), 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.ATT_WORKING_PAIDLEAVE_DAY.ToString(), listAttendanceTableProCut.RealWorkDayCount, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_WORKING_PAIDLEAVE_DAY_AFTER.ToString(), 0, 0); listElementFormula.Add(item); } } } #endregion #region Số ngày phép năm cộng dồn - Số ngày phép ốm cộng dồn if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_ANNUAL_INCREMENTAL.ToString(), PayrollElement.ATT_SICK_INCREMENTAL.ToString() })) { List<Att_AnnualDetailEntity> AnnualDetailByProfile = TotalData.listAnnualDetail.Where(m => m.ProfileID == profileItem.ID).ToList(); if (AnnualDetailByProfile != null && AnnualDetailByProfile.Count <= 0) { var ANNUAL = AnnualDetailByProfile.FirstOrDefault(m => m.Type == AnnualLeaveDetailType.E_ANNUAL_LEAVE.ToString()); var SICK = AnnualDetailByProfile.FirstOrDefault(m => m.Type == AnnualLeaveDetailType.E_SICK_LEAVE.ToString()); item = new ElementFormula(PayrollElement.ATT_ANNUAL_INCREMENTAL.ToString(), ANNUAL != null ? ANNUAL.InitAvailable != null ? ANNUAL.InitAvailable : 0 : 0, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_SICK_INCREMENTAL.ToString(), SICK != null ? SICK.InitAvailable != null ? SICK.InitAvailable : 0 : 0, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.ATT_ANNUAL_INCREMENTAL.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_SICK_INCREMENTAL.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } } #endregion //Phần tử công tháng hiện tại if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_STD_DAY.ToString(), PayrollElement.ATT_HOURS_PER_DAY.ToString(), PayrollElement.ATT_OVERTIME_PIT_HOURS.ToString(), PayrollElement.ATT_TOTAL_ANNUALLEAVE_AVAILABLE.ToString(), PayrollElement.ATT_ANNUALLEAVE_ADJACENT.ToString(), PayrollElement.ATT_TOTAL_SICK_AVAILABLE.ToString(), PayrollElement.ATT_SICK_ADJACENT.ToString(), PayrollElement.ATT_ANNUALLEAVE.ToString(), PayrollElement.ATT_SICKLEAVE.ToString(), PayrollElement.ATT_WORKING_NIGHTSHIFT.ToString() })) { if (listAttendanceTableProCut != null) { //item = new ElementFormula(PayrollElement.ATT_WORKING_DAY.ToString(), listAttendanceTableProCut.RealWorkDayCount, 0); //listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_STD_DAY.ToString(), listAttendanceTableProCut.StdWorkDayCount, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_HOURS_PER_DAY.ToString(), listAttendanceTableProCut.HourPerDay, 0); listElementFormula.Add(item); //item = new ElementFormula(PayrollElement.ATT_WORKING_PAIDLEAVE_DAY.ToString(), listAttendanceTableProCut.TotalPaidWorkDayCount, 0); //listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_WORKING_NIGHTSHIFT.ToString(), listAttendanceTableProCut.NightShiftHours, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_TOTAL_ANNUALLEAVE_AVAILABLE.ToString(), listAttendanceTableProCut.TotalAnlDayAvailable != null ? listAttendanceTableProCut.TotalAnlDayAvailable : 0, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_ANNUALLEAVE_ADJACENT.ToString(), listAttendanceTableProCut.AnlDayAdjacent, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_ANNUALLEAVE.ToString(), listAttendanceTableProCut.AnlDayTaken, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_SICKLEAVE.ToString(), listAttendanceTableProCut.SickDayTaken, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_TOTAL_SICK_AVAILABLE.ToString(), listAttendanceTableProCut.TotalSickDayAvailable, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_SICK_ADJACENT.ToString(), listAttendanceTableProCut.SickDayAdjacent, 0); listElementFormula.Add(item); } else { //item = new ElementFormula(PayrollElement.ATT_WORKING_DAY.ToString(), 0, 0, "Null"); //listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_STD_DAY.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_HOURS_PER_DAY.ToString(), 0, 0, "Null"); listElementFormula.Add(item); //item = new ElementFormula(PayrollElement.ATT_WORKING_PAIDLEAVE_DAY.ToString(), 0, 0, "Null"); //listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_WORKING_NIGHTSHIFT.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_TOTAL_ANNUALLEAVE_AVAILABLE.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_ANNUALLEAVE_ADJACENT.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_TOTAL_SICK_AVAILABLE.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_SICK_ADJACENT.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_SICKLEAVE.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_ANNUALLEAVE.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } } //Số ngày nghỉ có trả lương if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_DAY.ToString(), PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_DAY_NOT_PAY.ToString() })) { using (var context = new VnrHrmDataContext()) { var unitOfWork = (IUnitOfWork)new UnitOfWork(context); //Guid AttendanceTableItemByAttID = Guid.Empty; double Total_LeaveDay = 0; double Total_LeaveDay_NotPay = 0; if (listAttendanceTableProCut != null) { // AttendanceTableItemByAtt = repoAttendanceTable.FindBy(m => m.IsDelete != true && m.ID == listAttendanceTableProCut.ID).FirstOrDefault(); //AttendanceTableItemByAttID = unitOfWork.CreateQueryable<Att_AttendanceTable>(m => m.ID == listAttendanceTableProCut.ID).Select(m => m.ID).FirstOrDefault(); // var AttendanceTableItem = repoAttendanceTableItem.FindBy(m => m.IsDelete != true && m.AttendanceTableID == AttendanceTableItemByAttID).ToList(); var AttendanceTableItem = TotalData.listAttendanceTableItem.Where(m => m.AttendanceTableID == listAttendanceTableProCut.ID).ToList(); for (int j = 0; j < AttendanceTableItem.Count; j++) { if (AttendanceTableItem[j].LeaveTypeID != null) { var LeaveDay = TotalData.listLeavedayType.Where(m => m.ID == AttendanceTableItem[j].LeaveTypeID).FirstOrDefault(); if (LeaveDay != null) { //code của là so sánh với IsWorkDay if (LeaveDay.IsAnnualLeave || LeaveDay.PaidRate >= 1) { Total_LeaveDay += AttendanceTableItem[j].PaidLeaveHours / AttendanceTableItem[j].AvailableHours; } else if (!LeaveDay.IsAnnualLeave && LeaveDay.PaidRate <= 0) { //Total_LeaveDay_NotPay += AttendanceTableItem[j].PaidLeaveHours / AttendanceTableItem[j].AvailableHours; Total_LeaveDay_NotPay++; } } } } } item = new ElementFormula(PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_DAY.ToString(), Total_LeaveDay, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_DAY_NOT_PAY.ToString(), Total_LeaveDay_NotPay, 0); listElementFormula.Add(item); } } //Tổng số ngày công trong năm if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_TOTAL_WORKDAY_IN_YEAR.ToString() })) { var Attantendence = TotalData.listAttendanceTable.Where(m => m.ProfileID == profileItem.ID).ToList(); item = new ElementFormula(PayrollElement.ATT_TOTAL_WORKDAY_IN_YEAR.ToString(), Attantendence.Sum(m => m.StdWorkDayCount), 0); listElementFormula.Add(item); } //Tổng số ngày công thực tế trong năm if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_TOTAL_REALITYWORKDAY_IN_YEAR.ToString() })) { var Attantendence = TotalData.listAttendanceTable.Where(m => m.ProfileID == profileItem.ID).ToList(); item = new ElementFormula(PayrollElement.ATT_TOTAL_REALITYWORKDAY_IN_YEAR.ToString(), Attantendence.Sum(m => m.RealWorkDayCount), 0); listElementFormula.Add(item); } //Tổng số ngày làm việc trong năm (365-dayoff) if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_TOTAL_DAY_NOT_DAYOFF_IN_YEAR.ToString() })) { DateTime form = new DateTime(CutOffDuration.MonthYear.Year - 1, 4, 1); DateTime to = new DateTime(CutOffDuration.MonthYear.Year, 3, 31); int days = new DateTime(CutOffDuration.MonthYear.Year, 12, 31).DayOfYear; int dayOff = TotalData.listDayOff.Where(m => m.DateOff >= form && m.DateOff <= to && m.OrgStructureID == null).Count(); item = new ElementFormula(PayrollElement.ATT_TOTAL_DAY_NOT_DAYOFF_IN_YEAR.ToString(), days - dayOff, 0); listElementFormula.Add(item); } #endregion #region Enum phần tử bảo hiểm if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.INS_HEALTH_INSURANCE.ToString(), PayrollElement.INS_SALARY_INSURANCE.ToString(), PayrollElement.INS_SOCIAL_INSURANCE.ToString(), PayrollElement.INS_UNEMP_INSURANCE.ToString(), PayrollElement.INS_SOCIAL_INSURANCE_PROFILE.ToString(), PayrollElement.INS_SOCIAL_INSURANCE_COMPANY.ToString(), PayrollElement.INS_UNEMP_INSURANCE_PROFILE.ToString(), PayrollElement.INS_UNEMP_INSURANCE_COMPANY.ToString(), PayrollElement.INS_HEALTH_INSURANCE_PROFILE.ToString(), PayrollElement.INS_HEALTH_INSURANCE_COMPANY.ToString() })) { Ins_ProfileInsuranceMonthlyEntity InsItem = TotalData.listInsurance.Where(m => m.ProfileID == profileItem.ID && m.MonthYear != null && m.MonthYear.Value.Year == CutOffDuration.MonthYear.Year && m.MonthYear.Value.Month == CutOffDuration.MonthYear.Month).FirstOrDefault(); if (InsItem != null) { item = new ElementFormula(PayrollElement.INS_HEALTH_INSURANCE.ToString(), InsItem.MoneyHealthInsurance == null ? null : InsItem.MoneyHealthInsurance, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_SALARY_INSURANCE.ToString(), InsItem.SalaryInsurance == null ? null : InsItem.SalaryInsurance, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_SOCIAL_INSURANCE.ToString(), InsItem.MoneySocialInsurance == null ? null : InsItem.MoneySocialInsurance, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_UNEMP_INSURANCE.ToString(), InsItem.MoneyUnEmpInsurance == null ? null : InsItem.MoneyUnEmpInsurance, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_SOCIAL_INSURANCE_PROFILE.ToString(), InsItem.SocialInsEmpAmount == null ? null : InsItem.SocialInsEmpAmount, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_SOCIAL_INSURANCE_COMPANY.ToString(), InsItem.SocialInsComAmount == null ? null : InsItem.SocialInsComAmount, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_UNEMP_INSURANCE_PROFILE.ToString(), InsItem.UnemployEmpAmount == null ? null : InsItem.UnemployEmpAmount, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_UNEMP_INSURANCE_COMPANY.ToString(), InsItem.UnemployComAmount == null ? null : InsItem.UnemployComAmount, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_HEALTH_INSURANCE_PROFILE.ToString(), InsItem.HealthInsEmpAmount == null ? null : InsItem.HealthInsEmpAmount, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_HEALTH_INSURANCE_COMPANY.ToString(), InsItem.HealthInsComAmount == null ? null : InsItem.HealthInsComAmount, 0); listElementFormula.Add(item); } else//nếu không có bảo hiểm thì cập nhất value = 0 { item = new ElementFormula(PayrollElement.INS_HEALTH_INSURANCE.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_SALARY_INSURANCE.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_SOCIAL_INSURANCE.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_UNEMP_INSURANCE.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_SOCIAL_INSURANCE_PROFILE.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_SOCIAL_INSURANCE_COMPANY.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_UNEMP_INSURANCE_PROFILE.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_UNEMP_INSURANCE_COMPANY.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_HEALTH_INSURANCE_PROFILE.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.INS_HEALTH_INSURANCE_COMPANY.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } } #endregion #region Enum phần tử hoa hồng //Lấy taget & actual của shop if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_COM_TAGET_SHOP.ToString(), PayrollElement.SAL_COM_ACTUAL_SHOP.ToString(), PayrollElement.SAL_COM_PRECENT_REVENUE.ToString() })) { Sal_RevenueForShopEntity RevenueForShopItem = TotalData.listRevenueForShop.Where(m => m.ShopID == profileItem.ShopID && m.KPIBonusID == TotalData.listKPIBonus.Where(t => t.IsTotalRevenue == true).FirstOrDefault().ID && m.DateFrom <= CutOffDuration.DateEnd && m.DateTo >= CutOffDuration.DateStart).FirstOrDefault(); if (RevenueForShopItem != null) { item = new ElementFormula(PayrollElement.SAL_COM_TAGET_SHOP.ToString(), RevenueForShopItem.Target, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_COM_ACTUAL_SHOP.ToString(), RevenueForShopItem.Actual, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_COM_PRECENT_REVENUE.ToString(), RevenueForShopItem.Actual / RevenueForShopItem.Target, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.SAL_COM_TAGET_SHOP.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_COM_ACTUAL_SHOP.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_COM_PRECENT_REVENUE.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } } //Lấy tên cửa hàng if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_COM_SHOPNAME.ToString())) { item = new ElementFormula(PayrollElement.SAL_COM_SHOPNAME.ToString(), profileItem.ShopName == null ? "" : profileItem.ShopName, 0); listElementFormula.Add(item); } //Lấy taget & actual của nhân viên if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_COM_TAGET_CUSTOMER.ToString(), PayrollElement.SAL_COM_ACTUAL_CUSTOMER.ToString() })) { Sal_RevenueForProfileEntity RevenueForProfileItem = new Sal_RevenueForProfileEntity(); RevenueForProfileItem = TotalData.listRevenueForProfile.Where(m => m.ProfileID == profileItem.ID && m.DateFrom <= CutOffDuration.DateEnd && m.DateTo >= CutOffDuration.DateStart).FirstOrDefault(); if (RevenueForProfileItem != null) { item = new ElementFormula(PayrollElement.SAL_COM_TAGET_CUSTOMER.ToString(), RevenueForProfileItem.Target, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_COM_ACTUAL_CUSTOMER.ToString(), RevenueForProfileItem.Actual, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.SAL_COM_TAGET_CUSTOMER.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_COM_ACTUAL_CUSTOMER.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } } //Số tháng làm việc if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_COM_WORKINGMONTH.ToString())) { double CountMonth = ((CutOffDuration.MonthYear.Year - profileItem.DateHire.Value.Year) * 12) + CutOffDuration.MonthYear.Month - profileItem.DateHire.Value.Month + (profileItem.DateHire.Value.Day < CutOffDuration.DateEnd.Day ? 1 : 0); item = new ElementFormula(PayrollElement.SAL_COM_WORKINGMONTH.ToString(), CountMonth, 0); listElementFormula.Add(item); } //tổng số nhân viên của cửa hàng if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_COM_COUNT_SHOPMEMBER.ToString())) { using (var context = new VnrHrmDataContext()) { var unitOfWork = (IUnitOfWork)(new UnitOfWork(context)); var repoProfile = new CustomBaseRepository<Hre_Profile>(unitOfWork); int TotalProfileForShop = repoProfile.FindBy(m => m.ShopID == profileItem.ShopID).Count(); item = new ElementFormula(PayrollElement.SAL_COM_COUNT_SHOPMEMBER.ToString(), TotalProfileForShop, 0); listElementFormula.Add(item); } } //Chức danh if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_COM_JOBTITLE.ToString())) { item = new ElementFormula(PayrollElement.SAL_COM_JOBTITLE.ToString(), profileItem.PositionCode == null ? "" : profileItem.PositionCode, 0); listElementFormula.Add(item); } //Số lượng ca trưởng trong cửa hàng if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_COM_COUNT_SL.ToString(), PayrollElement.SAL_COM_RANK.ToString() })) { if (profileItem.ShopID != null) { int Count_SL = (int)TotalData.listShop.Single(m => m.ID == profileItem.ShopID).NoShiftLeader; item = new ElementFormula(PayrollElement.SAL_COM_COUNT_SL.ToString(), Count_SL, 0); listElementFormula.Add(item); //cấp bậc của cửa hàng item = new ElementFormula(PayrollElement.SAL_COM_RANK.ToString(), TotalData.listShop.Single(m => m.ID == profileItem.ShopID).Rank, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.SAL_COM_COUNT_SL.ToString(), 0, 0, "Null"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.SAL_COM_RANK.ToString(), 0, 0, "Null"); listElementFormula.Add(item); } } //Tổng doanh thu của tất cả nhân viên trong shop if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_TOTAL_ACTUAL_PROFILE_SHOP.ToString())) { using (var context = new VnrHrmDataContext()) { var unitOfWork = (IUnitOfWork)(new UnitOfWork(context)); var repoProfile = new CustomBaseRepository<Hre_Profile>(unitOfWork); var TotalPRofileInShop = repoProfile.FindBy(m => m.ShopID == profileItem.ShopID).ToList(); var RevenueForProfileInShop = TotalData.listRevenueForProfile.Where(m => TotalPRofileInShop.Any(t => t.ID == m.ProfileID) && m.DateFrom <= CutOffDuration.DateEnd && m.DateTo >= CutOffDuration.DateStart).ToList(); item = new ElementFormula(PayrollElement.SAL_TOTAL_ACTUAL_PROFILE_SHOP.ToString(), RevenueForProfileInShop.Sum(m => m.Actual), 0); listElementFormula.Add(item); } } #endregion #region Enum phần tử đánh giá //Loại đánh giá if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.EVA_PERFORMANCE_TYPE_CODE.ToString(), PayrollElement.EVA_PERFORMANCE_LEVEL_NAME.ToString() })) { var PerformentceProfile = TotalData.listEva_Performance.Where(m => m.ProfileID == profileItem.ID && m.PeriodFromDate <= CutOffDuration.DateEnd && m.PeriodToDate >= CutOffDuration.DateStart).FirstOrDefault(); item = new ElementFormula(PayrollElement.EVA_PERFORMANCE_TYPE_CODE.ToString(), PerformentceProfile != null ? PerformentceProfile.PerformanceTypeCode : "", 0); listElementFormula.Add(item); //Cấp độ đánh giá item = new ElementFormula(PayrollElement.EVA_PERFORMANCE_LEVEL_NAME.ToString(), PerformentceProfile != null ? PerformentceProfile.Level1Name : "", 0); listElementFormula.Add(item); } if (CheckIsExistFormula(listElementFormula, formula, CatElementType.Evaluation.ToString().ToUpper() + "_PERFORMANCETYPE_", TotalData.listPerformanceType.Select(m => m.Code).ToArray())) { DateTime YearStart = new DateTime(CutOffDuration.MonthYear.Year, 1, 1); DateTime YearEnd = new DateTime(CutOffDuration.MonthYear.Year, 12, 31); var PerformentceByProfile = TotalData.listEva_Performance.Where(m => m.ProfileID == profileItem.ID && m.DateEffect <= YearEnd && m.DateEffect >= YearStart).OrderByDescending(m => m.DateEffect).ToList(); if (PerformentceByProfile != null) { foreach (var i in TotalData.listPerformanceType) { var PerformentceByProfileAndType = PerformentceByProfile.FirstOrDefault(m => m.PerformanceTypeID == i.ID); if (PerformentceByProfileAndType != null) { item = new ElementFormula(CatElementType.Evaluation.ToString().ToUpper() + "_PERFORMANCETYPE_" + i.Code, PerformentceByProfileAndType.Level1Name != null ? PerformentceByProfileAndType.Level1Name : "", 0); listElementFormula.Add(item); } else { item = new ElementFormula(CatElementType.Evaluation.ToString().ToUpper() + "_PERFORMANCETYPE_" + i.Code, "", 0, "null"); listElementFormula.Add(item); } } } else { foreach (var i in TotalData.listPerformanceType) { item = new ElementFormula(CatElementType.Evaluation.ToString().ToUpper() + "_PERFORMANCETYPE_" + i.Code, "", 0, "null"); listElementFormula.Add(item); } } } #endregion #region Enum phần tử CanTeen if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.CAN_SUMAMOUNT_N_1.ToString(), PayrollElement.CAN_AMOUNTEATNOTSTANDAR_N_1.ToString(), PayrollElement.CAN_AMOUNTCARDMORE_N_1.ToString(), PayrollElement.CAN_AMOUNTNOTWORKHASEAT_N_1.ToString(), PayrollElement.CAN_AMOUNTHDTJOB_N_1.ToString(), PayrollElement.CAN_AMOUNTNOTWORKBUTHASHDT_N_1.ToString(), PayrollElement.CAN_AMOUNTSUBTRACTWRONGSTANDARHDT_N_1.ToString() })) { DateTime DateStart = CutOffDuration.DateStart.AddMonths(-1); DateTime DateEnd = CutOffDuration.DateEnd.AddMonths(-1); var SumryMealRecordByRrofile = TotalData.listSumryMealRecord.Where(m => m.ProfileID == profileItem.ID && (m.DateFrom != null && m.DateTo != null) && m.DateFrom <= DateEnd && m.DateTo >= DateStart).OrderByDescending(m => m.DateFrom).FirstOrDefault(); if (SumryMealRecordByRrofile != null) { item = new ElementFormula(PayrollElement.CAN_SUMAMOUNT_N_1.ToString(), SumryMealRecordByRrofile.SumAmount != null ? SumryMealRecordByRrofile.SumAmount : 0, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTEATNOTSTANDAR_N_1.ToString(), SumryMealRecordByRrofile.AmountEatNotStandar != null ? SumryMealRecordByRrofile.AmountEatNotStandar : 0, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTCARDMORE_N_1.ToString(), SumryMealRecordByRrofile.SumAmountCardMore != null ? SumryMealRecordByRrofile.SumAmountCardMore : 0, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKHASEAT_N_1.ToString(), SumryMealRecordByRrofile.AmountNotWorkHasEat != null ? SumryMealRecordByRrofile.AmountNotWorkHasEat : 0, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTHDTJOB_N_1.ToString(), SumryMealRecordByRrofile.AmountHDTJob != null ? SumryMealRecordByRrofile.AmountHDTJob : 0, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKBUTHASHDT_N_1.ToString(), SumryMealRecordByRrofile.AmountNotWorkButHasHDT != null ? SumryMealRecordByRrofile.AmountNotWorkButHasHDT : 0, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTSUBTRACTWRONGSTANDARHDT_N_1.ToString(), SumryMealRecordByRrofile.AmountSubtractWorngStandarHDT != null ? SumryMealRecordByRrofile.AmountSubtractWorngStandarHDT : 0, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.CAN_SUMAMOUNT_N_1.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTEATNOTSTANDAR_N_1.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTCARDMORE_N_1.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKHASEAT_N_1.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTHDTJOB_N_1.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKBUTHASHDT_N_1.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTSUBTRACTWRONGSTANDARHDT_N_1.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !"); listElementFormula.Add(item); } } if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.CAN_SUMAMOUNT.ToString(), PayrollElement.CAN_AMOUNTEATNOTSTANDAR.ToString(), PayrollElement.CAN_AMOUNTCARDMORE.ToString(), PayrollElement.CAN_AMOUNTNOTWORKHASEAT.ToString(), PayrollElement.CAN_AMOUNTHDTJOB.ToString(), PayrollElement.CAN_AMOUNTNOTWORKBUTHASHDT.ToString(), PayrollElement.CAN_AMOUNTSUBTRACTWRONGSTANDARHDT.ToString() })) { var SumryMealRecordByRrofile = TotalData.listSumryMealRecord.Where(m => m.ProfileID == profileItem.ID && (m.DateFrom != null && m.DateTo != null) && m.DateFrom <= CutOffDuration.DateEnd && m.DateTo >= CutOffDuration.DateStart).OrderByDescending(m => m.DateFrom).FirstOrDefault(); if (SumryMealRecordByRrofile != null) { item = new ElementFormula(PayrollElement.CAN_SUMAMOUNT.ToString(), SumryMealRecordByRrofile.SumAmount != null ? SumryMealRecordByRrofile.SumAmount : 0, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTEATNOTSTANDAR.ToString(), SumryMealRecordByRrofile.AmountEatNotStandar != null ? SumryMealRecordByRrofile.AmountEatNotStandar : 0, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTCARDMORE.ToString(), SumryMealRecordByRrofile.SumAmountCardMore != null ? SumryMealRecordByRrofile.SumAmountCardMore : 0, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKHASEAT.ToString(), SumryMealRecordByRrofile.AmountNotWorkHasEat != null ? SumryMealRecordByRrofile.AmountNotWorkHasEat : 0, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTHDTJOB.ToString(), SumryMealRecordByRrofile.AmountHDTJob != null ? SumryMealRecordByRrofile.AmountHDTJob : 0, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKBUTHASHDT.ToString(), SumryMealRecordByRrofile.AmountNotWorkButHasHDT != null ? SumryMealRecordByRrofile.AmountNotWorkButHasHDT : 0, 0); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTSUBTRACTWRONGSTANDARHDT.ToString(), SumryMealRecordByRrofile.AmountSubtractWorngStandarHDT != null ? SumryMealRecordByRrofile.AmountSubtractWorngStandarHDT : 0, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.CAN_SUMAMOUNT.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTEATNOTSTANDAR.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTCARDMORE.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKHASEAT.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTHDTJOB.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTNOTWORKBUTHASHDT.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !"); listElementFormula.Add(item); item = new ElementFormula(PayrollElement.CAN_AMOUNTSUBTRACTWRONGSTANDARHDT.ToString(), 0, 0, "Không có dữ liệu trong kỳ tính lương !"); listElementFormula.Add(item); } } #endregion #endregion #region Các phần tử động if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.DYN_COUNTDAYOVERTIMEBYTYPE_.ToString(), new string[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" })) { using (var context = new VnrHrmDataContext()) { var unitOfWork = (IUnitOfWork)new UnitOfWork(context); //var repoAttendanceTable = new CustomBaseRepository<Att_AttendanceTable>(unitOfWork); //var repoAttOvertime = new CustomBaseRepository<Att_Overtime>(unitOfWork); //tách phần tử ra để lấy tham số string Parameter = string.Empty; var ttt = ParseFormulaToList(formula.Formula); List<string> ListFormula = ParseFormulaToList(formula.Formula).Where(m => m.IndexOf('[') != -1 && m.IndexOf(']') != -1 && m.StartsWith("[" + PayrollElement.DYN_COUNTDAYOVERTIMEBYTYPE_.ToString())).ToList(); //Att_AttendanceTable listAttTable = TotalData.listAttendanceTable.Where(m => m.CutOffDurationID == CutOffDuration.ID && m.ProfileID == profileItem.ID && m.IsDelete != true).FirstOrDefault(); List<Att_AttendanceTableItemEntity> listAttTableItem = TotalData.listAttendanceTableItem.Where(m => m.AttendanceTableID == listAttendanceTableProCut.ID).ToList(); //lấy danh sách đăng ký tăng ca List<Att_OvertimeEntity> listOverTime = TotalData.listOverTime.Where(m => m.ProfileID == profileItem.ID).ToList(); //duyệt qua các phần tử động để lấy tham số foreach (var i in ListFormula) { string[] listParam = i.Split('_'); if (listParam.Count() >= 3)//nếu là 3 phần tử là đúng công thức, ngược lại là sai { string OtTypeCode = i.Replace(PayrollElement.DYN_COUNTDAYOVERTIMEBYTYPE_.ToString(), "").Replace("_" + listParam.LastOrDefault(), "").Replace("]", "").Replace("[", ""); double number = 0; double CountOtDay = 0; Cat_OvertimeTypeEntity OTType = TotalData.listOvertimeType.Where(m => m.Code == OtTypeCode).FirstOrDefault(); List<Att_OvertimeEntity> listOverTimeByTableItem = new List<Att_OvertimeEntity>(); Att_OvertimeEntity OverTimeItem = new Att_OvertimeEntity(); Cat_Shift ShiftItem = new Cat_Shift(); if (double.TryParse(listParam.LastOrDefault().Replace("]", "").Replace("[", ""), out number) && OTType != null) { number = number / 10; CountOtDay = 0; //lọc ra các loại OT theo loại foreach (var tableItem in listAttTableItem) { listOverTimeByTableItem = listOverTime.Where(m => m.WorkDate.Date == tableItem.WorkDate.Date).ToList(); if (tableItem.OvertimeTypeID != null && tableItem.OvertimeTypeID == OTType.ID) { OverTimeItem = listOverTimeByTableItem.Where(m => m.OvertimeTypeID == (Guid)tableItem.OvertimeTypeID).FirstOrDefault(); if (OverTimeItem != null && OverTimeItem.ShiftID != null) { ShiftItem = TotalData.listCat_Shift.Where(m => m.ID == (Guid)OverTimeItem.ShiftID).FirstOrDefault().Copy<Cat_Shift>(); CountOtDay += tableItem.OvertimeHours / ShiftItem.udAvailableHours >= number ? 1 : 0; } } else if (tableItem.ExtraOvertimeTypeID != null && tableItem.ExtraOvertimeTypeID == OTType.ID) { OverTimeItem = listOverTimeByTableItem.Where(m => m.OvertimeTypeID == (Guid)tableItem.ExtraOvertimeTypeID).FirstOrDefault(); if (OverTimeItem != null && OverTimeItem.ShiftID != null) { ShiftItem = TotalData.listCat_Shift.Where(m => m.ID == (Guid)OverTimeItem.ShiftID).FirstOrDefault().Copy<Cat_Shift>(); CountOtDay += tableItem.ExtraOvertimeHours / ShiftItem.udAvailableHours >= number ? 1 : 0; } } else if (tableItem.ExtraOvertimeType2ID != null && tableItem.ExtraOvertimeType2ID == OTType.ID) { OverTimeItem = listOverTimeByTableItem.Where(m => m.OvertimeTypeID == (Guid)tableItem.ExtraOvertimeType2ID).FirstOrDefault(); if (OverTimeItem != null && OverTimeItem.ShiftID != null) { ShiftItem = TotalData.listCat_Shift.Where(m => m.ID == (Guid)OverTimeItem.ShiftID).FirstOrDefault().Copy<Cat_Shift>(); CountOtDay += tableItem.ExtraOvertimeHours2 / ShiftItem.udAvailableHours >= number ? 1 : 0; } } else if (tableItem.ExtraOvertimeType3ID != null && tableItem.ExtraOvertimeType3ID == OTType.ID) { OverTimeItem = listOverTimeByTableItem.Where(m => m.OvertimeTypeID == (Guid)tableItem.ExtraOvertimeType3ID).FirstOrDefault(); if (OverTimeItem != null && OverTimeItem.ShiftID != null) { ShiftItem = TotalData.listCat_Shift.Where(m => m.ID == (Guid)OverTimeItem.ShiftID).FirstOrDefault().Copy<Cat_Shift>(); CountOtDay += tableItem.ExtraOvertimeHours3 / ShiftItem.udAvailableHours >= number ? 1 : 0; } } } item = new ElementFormula(i.Replace("]", "").Replace("[", ""), CountOtDay, 0); listElementFormula.Add(item); } else//sai công thức , không convert đc số giờ { item = new ElementFormula(i.Replace("]", "").Replace("[", ""), 0, 0, "Công thức động sai !"); listElementFormula.Add(item); } } else { item = new ElementFormula(i.Replace("]", "").Replace("[", ""), 0, 0, "Công thức động sai !"); listElementFormula.Add(item); } } } } #endregion #region Lấy giá trị cho các phần tử là các loại OT và LeaveDay #region Lấy OT theo từng loại và lấy tổng số giờ tăng ca đã quy đổi ra hệ số 1 #region OT tháng N List<Cat_ElementEntity> listElement_OT = new List<Cat_ElementEntity>(); if (CheckIsExistFormula(listElementFormula, formula, "ATT_OVERTIME_", "_HOURS")) { using (var context = new VnrHrmDataContext()) { var unitOfWork = (IUnitOfWork)new UnitOfWork(context); //var repoAttendanceTable = new CustomBaseRepository<Att_AttendanceTable>(unitOfWork); //double SumOvertime = 0; //double SumOvertimeInsurance = 0; //lấy lương cơ bản của nhân viên List<Sal_BasicSalaryEntity> SalaryProfile = new List<Sal_BasicSalaryEntity>(); SalaryProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).ToList(); //có thay đổi lương trong tháng if (SalaryProfile.Count > 0 && SalaryProfile.FirstOrDefault().DateOfEffect > CutOffDuration.DateStart)//có thay đổi lương trong tháng { double OtHour = 0; //ngày bắt đầu mức lương 1 và ngày bắt đầu mức lương 2 DateTime dateStart1 = CutOffDuration.DateStart; DateTime dateStart2 = SalaryProfile.FirstOrDefault().DateOfEffect; //lấy dữ liệu công theo cutoff List<Att_AttendanceTableItemEntity> listAttTableItem = TotalData.listAttendanceTableItem.Where(m => m.ProfileID == profileItem.ID).ToList(); if (listAttTableItem != null && listAttTableItem.Count > 0) { listAttTableItem = listAttTableItem.Where(m => m.WorkDate < dateStart2).ToList(); //duyệt wa các loại ot foreach (var OTType in TotalData.listOvertimeType) { OtHour = 0; //tính số giờ OT của từng loại foreach (var tableItem in listAttTableItem) { if (tableItem.OvertimeTypeID != null && tableItem.OvertimeTypeID == OTType.ID) { OtHour += tableItem.OvertimeHours; } else if (tableItem.ExtraOvertimeTypeID != null && tableItem.ExtraOvertimeTypeID == OTType.ID) { OtHour += tableItem.ExtraOvertimeHours; } else if (tableItem.ExtraOvertimeType2ID != null && tableItem.ExtraOvertimeType2ID == OTType.ID) { OtHour += tableItem.ExtraOvertimeHours2; } else if (tableItem.ExtraOvertimeType3ID != null && tableItem.ExtraOvertimeType3ID == OTType.ID) { OtHour += tableItem.ExtraOvertimeHours3; } } item = new ElementFormula("ATT_OVERTIME_" + OTType.Code + "_HOURS", OtHour, 0); listElementFormula.Add(item); } } else { foreach (var OTType in TotalData.listOvertimeType) { item = new ElementFormula("ATT_OVERTIME_" + OTType.Code + "_HOURS", 0, 0); listElementFormula.Add(item); } } } else//không thay đổi lương trong tháng { listElement_OT = TotalData.listElement_All.Where(m => m.ElementCode.StartsWith("ATT_OVERTIME_") && m.ElementCode.EndsWith("_HOURS")).ToList(); foreach (var OT in listElement_OT) { var itemOverTime = TotalData.listOvertimeType.Where(m => m.Code == OT.ElementCode.Replace("ATT_OVERTIME_", "").Replace("_HOURS", "")).FirstOrDefault(); double value = 0; if (itemOverTime != null && listAttendanceTableProCut != null) { if (listAttendanceTableProCut.Overtime1Type != null && listAttendanceTableProCut.Overtime1Type == itemOverTime.ID) { value += listAttendanceTableProCut.Overtime1Hours; } if (listAttendanceTableProCut.Overtime2Type != null && listAttendanceTableProCut.Overtime2Type == itemOverTime.ID) { value += listAttendanceTableProCut.Overtime2Hours; } if (listAttendanceTableProCut.Overtime3Type != null && listAttendanceTableProCut.Overtime3Type == itemOverTime.ID) { value += listAttendanceTableProCut.Overtime3Hours; } if (listAttendanceTableProCut.Overtime4Type != null && listAttendanceTableProCut.Overtime4Type == itemOverTime.ID) { value += listAttendanceTableProCut.Overtime4Hours; } if (listAttendanceTableProCut.Overtime5Type != null && listAttendanceTableProCut.Overtime5Type == itemOverTime.ID) { value += listAttendanceTableProCut.Overtime5Hours; } if (listAttendanceTableProCut.Overtime6Type != null && listAttendanceTableProCut.Overtime6Type == itemOverTime.ID) { value += listAttendanceTableProCut.Overtime6Hours; } } item = new ElementFormula(OT.ElementCode, value, 0); listElementFormula.Add(item); //if (itemOverTime != null) //{ // SumOvertimeInsurance += value * itemOverTime.TaxRate;//Tính số giờ tăng ca có chịu thuế // SumOvertime += value * itemOverTime.Rate;//tính hệ số và lưu vào biến tổng số giờ tăng ca //} } ////Lưu giá trị cho Enum tổng số giớ tăng ca trong tháng //item = new ElementFormula(PayrollElement.ATT_OVERTIME_HOURS.ToString(), SumOvertime, 0); //listElementFormula.Add(item); ////Lưu giá trị cho Enum tổng số giớ tăng ca trong tháng có tính thuế //item = new ElementFormula(PayrollElement.ATT_OVERTIME_PIT_HOURS.ToString(), SumOvertimeInsurance, 0); //listElementFormula.Add(item); } } } #endregion #region Tổng giờ tăng ca trong tháng và tổng giờ tăng ca trong tháng có tính thuế if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_OVERTIME_PIT_HOURS.ToString(), PayrollElement.ATT_OVERTIME_HOURS.ToString() })) { double SumOvertime = 0; double SumOvertimeInsurance = 0; foreach (var itemOverTime in TotalData.listOvertimeType) { double value = 0; if (itemOverTime != null && listAttendanceTableProCut != null) { if (listAttendanceTableProCut.Overtime1Type != null && listAttendanceTableProCut.Overtime1Type == itemOverTime.ID) { value += listAttendanceTableProCut.Overtime1Hours; } if (listAttendanceTableProCut.Overtime2Type != null && listAttendanceTableProCut.Overtime2Type == itemOverTime.ID) { value += listAttendanceTableProCut.Overtime2Hours; } if (listAttendanceTableProCut.Overtime3Type != null && listAttendanceTableProCut.Overtime3Type == itemOverTime.ID) { value += listAttendanceTableProCut.Overtime3Hours; } if (listAttendanceTableProCut.Overtime4Type != null && listAttendanceTableProCut.Overtime4Type == itemOverTime.ID) { value += listAttendanceTableProCut.Overtime4Hours; } if (listAttendanceTableProCut.Overtime5Type != null && listAttendanceTableProCut.Overtime5Type == itemOverTime.ID) { value += listAttendanceTableProCut.Overtime5Hours; } if (listAttendanceTableProCut.Overtime6Type != null && listAttendanceTableProCut.Overtime6Type == itemOverTime.ID) { value += listAttendanceTableProCut.Overtime6Hours; } } if (itemOverTime != null) { SumOvertimeInsurance += value * itemOverTime.TaxRate;//Tính số giờ tăng ca có chịu thuế SumOvertime += value * itemOverTime.Rate;//tính hệ số và lưu vào biến tổng số giờ tăng ca } } //Lưu giá trị cho Enum tổng số giớ tăng ca trong tháng item = new ElementFormula(PayrollElement.ATT_OVERTIME_HOURS.ToString(), SumOvertime, 0); listElementFormula.Add(item); //Lưu giá trị cho Enum tổng số giớ tăng ca trong tháng có tính thuế item = new ElementFormula(PayrollElement.ATT_OVERTIME_PIT_HOURS.ToString(), SumOvertimeInsurance, 0); listElementFormula.Add(item); } #endregion #region Các loại OT nếu có thay đổi lương trong tháng if (CheckIsExistFormula(listElementFormula, formula, "ATT_OVERTIME_", "_HOURS_AFTER")) { using (var context = new VnrHrmDataContext()) { var unitOfWork = (IUnitOfWork)new UnitOfWork(context); //var repoAttendanceTable = new CustomBaseRepository<Att_AttendanceTable>(unitOfWork); //lấy lương cơ bản của nhân viên List<Sal_BasicSalaryEntity> SalaryProfile = new List<Sal_BasicSalaryEntity>(); SalaryProfile = TotalData.listBasicSalary.Where(m => m.ProfileID == profileItem.ID).OrderByDescending(m => m.DateOfEffect).ToList(); if (SalaryProfile.Count > 0 && SalaryProfile.FirstOrDefault().DateOfEffect > CutOffDuration.DateStart)//có thay đổi lương trong tháng { double OtHour = 0; //ngày bắt đầu mức lương 1 và ngày bắt đầu mức lương 2 DateTime dateStart1 = CutOffDuration.DateStart; DateTime dateStart2 = SalaryProfile.FirstOrDefault().DateOfEffect; //lấy dữ liệu công theo cutoff List<Att_AttendanceTableItemEntity> listAttTableItem = TotalData.listAttendanceTableItem.Where(m => m.ProfileID == profileItem.ID).ToList(); if (listAttTableItem != null && listAttTableItem.Count > 0) { listAttTableItem = listAttTableItem.Where(m => m.WorkDate >= dateStart2).ToList(); //duyệt wa các loại ot foreach (var OTType in TotalData.listOvertimeType) { OtHour = 0; //tính số giờ OT của từng loại foreach (var tableItem in listAttTableItem) { if (tableItem.OvertimeTypeID != null && tableItem.OvertimeTypeID == OTType.ID) { OtHour += tableItem.OvertimeHours; } else if (tableItem.ExtraOvertimeTypeID != null && tableItem.ExtraOvertimeTypeID == OTType.ID) { OtHour += tableItem.ExtraOvertimeHours; } else if (tableItem.ExtraOvertimeType2ID != null && tableItem.ExtraOvertimeType2ID == OTType.ID) { OtHour += tableItem.ExtraOvertimeHours2; } else if (tableItem.ExtraOvertimeType3ID != null && tableItem.ExtraOvertimeType3ID == OTType.ID) { OtHour += tableItem.ExtraOvertimeHours3; } } item = new ElementFormula("ATT_OVERTIME_" + OTType.Code + "_HOURS_AFTER", OtHour, 0); listElementFormula.Add(item); } } else { foreach (var OTType in TotalData.listOvertimeType) { item = new ElementFormula("ATT_OVERTIME_" + OTType.Code + "_HOURS_AFTER", 0, 0); listElementFormula.Add(item); } } } else//không có lương cơ bản hoặc không có thay đổi lương trong tháng { foreach (var OTType in TotalData.listOvertimeType) { item = new ElementFormula("ATT_OVERTIME_" + OTType.Code + "_HOURS_AFTER", 0, 0); listElementFormula.Add(item); } } } } #endregion #region OT tháng N-1 if (CheckIsExistFormula(listElementFormula, formula, "ATT_OVERTIME_", "_HOURS_PREV")) { listElement_OT = TotalData.listElement_All.Where(m => m.ElementCode.StartsWith("ATT_OVERTIME_") && m.ElementCode.EndsWith("_HOURS_PREV")).ToList(); if (listElement_OT != null && listElement_OT.Count > 0) { foreach (var OT in listElement_OT) { var itemOverTime = TotalData.listOvertimeType.Where(m => m.Code == OT.ElementCode.Replace("ATT_OVERTIME_", "").Replace("_HOURS_PREV", "")).FirstOrDefault(); double value = 0; var _tmpAttendanceTable = TotalData.Att_AttendanceTable_Prev.Where(m => m.ProfileID == profileItem.ID).FirstOrDefault(); if (itemOverTime != null && _tmpAttendanceTable != null) { if (_tmpAttendanceTable.Overtime1Type != null && _tmpAttendanceTable.Overtime1Type == itemOverTime.ID) { value += _tmpAttendanceTable.Overtime1Hours; } if (_tmpAttendanceTable.Overtime2Type != null && _tmpAttendanceTable.Overtime2Type == itemOverTime.ID) { value += _tmpAttendanceTable.Overtime2Hours; } if (_tmpAttendanceTable.Overtime3Type != null && _tmpAttendanceTable.Overtime3Type == itemOverTime.ID) { value += _tmpAttendanceTable.Overtime3Hours; } if (_tmpAttendanceTable.Overtime4Type != null && _tmpAttendanceTable.Overtime4Type == itemOverTime.ID) { value += _tmpAttendanceTable.Overtime4Hours; } if (_tmpAttendanceTable.Overtime5Type != null && _tmpAttendanceTable.Overtime5Type == itemOverTime.ID) { value += _tmpAttendanceTable.Overtime5Hours; } if (_tmpAttendanceTable.Overtime6Type != null && _tmpAttendanceTable.Overtime6Type == itemOverTime.ID) { value += _tmpAttendanceTable.Overtime6Hours; } } item = new ElementFormula(OT.ElementCode, value, 0); listElementFormula.Add(item); } } } #endregion #endregion #region Lấy LeaveDay theo từng loại và lấy tổng nghỉ double SumLeaveday = 0; double SumLeavedayIsSalary = 0; //N-1 double SumLeaveday_Prev = 0; double SumLeavedayIsSalary_Prev = 0; List<Cat_ElementEntity> listElement_Leave = new List<Cat_ElementEntity>(); if (CheckIsExistFormula(listElementFormula, formula, "ATT_LEAVE_", "_HOURS") || CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_LEAVE_HOURS.ToString(), PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_HOURS.ToString() })) { listElement_Leave = TotalData.listElement_All.Where(m => m.ElementCode.StartsWith("ATT_LEAVE_") && m.ElementCode.EndsWith("_HOURS")).ToList(); foreach (var LD in listElement_Leave) { var itemLeaveday = TotalData.listLeavedayType.Where(m => m.Code == LD.ElementCode.Replace("ATT_LEAVE_", "").Replace("_HOURS", "")).FirstOrDefault(); double value = 0; if (itemLeaveday != null && listAttendanceTableProCut != null) { if (listAttendanceTableProCut.LeaveDay1Type != null && listAttendanceTableProCut.LeaveDay1Type == itemLeaveday.ID) { value += listAttendanceTableProCut.LeaveDay1Hours; } if (listAttendanceTableProCut.LeaveDay2Type != null && listAttendanceTableProCut.LeaveDay2Type == itemLeaveday.ID) { value += listAttendanceTableProCut.LeaveDay2Hours; } if (listAttendanceTableProCut.LeaveDay3Type != null && listAttendanceTableProCut.LeaveDay3Type == itemLeaveday.ID) { value += listAttendanceTableProCut.LeaveDay3Hours; } if (listAttendanceTableProCut.LeaveDay4Type != null && listAttendanceTableProCut.LeaveDay4Type == itemLeaveday.ID) { value += listAttendanceTableProCut.LeaveDay4Hours; } } item = new ElementFormula(LD.ElementCode, value, 0); listElementFormula.Add(item); SumLeaveday += value;//Tổng giờ nghỉ trong tháng if (itemLeaveday != null) { SumLeavedayIsSalary += value * itemLeaveday.PaidRate;//tổng giờ nghỉ có trả lương } #region Lấy LeaveDay theo từng lại và lấy tổng ngày nghỉ tháng N - 1 value = 0; var _tmpAttendanceTable = TotalData.Att_AttendanceTable_Prev.Where(m => m.ProfileID == profileItem.ID).FirstOrDefault(); if (itemLeaveday != null && _tmpAttendanceTable != null) { if (_tmpAttendanceTable.LeaveDay1Type != null && _tmpAttendanceTable.LeaveDay1Type == itemLeaveday.ID) { value += _tmpAttendanceTable.LeaveDay1Hours; } if (_tmpAttendanceTable.LeaveDay2Type != null && _tmpAttendanceTable.LeaveDay2Type == itemLeaveday.ID) { value += _tmpAttendanceTable.LeaveDay2Hours; } if (_tmpAttendanceTable.LeaveDay3Type != null && _tmpAttendanceTable.LeaveDay3Type == itemLeaveday.ID) { value += _tmpAttendanceTable.LeaveDay3Hours; } if (_tmpAttendanceTable.LeaveDay4Type != null && _tmpAttendanceTable.LeaveDay4Type == itemLeaveday.ID) { value += _tmpAttendanceTable.LeaveDay4Hours; } } SumLeaveday_Prev += value;//Tổng giờ nghỉ trong tháng if (itemLeaveday != null) { SumLeavedayIsSalary_Prev += value * itemLeaveday.PaidRate;//tổng giờ nghỉ có trả lương } #endregion } //tạo phần tử Enum tổng số giờ nghỉ trong tháng item = new ElementFormula(PayrollElement.ATT_LEAVE_HOURS.ToString(), SumLeaveday, 0); listElementFormula.Add(item); //tạo phần tử Enum tổng số giờ nghỉ trong tháng có tính lương item = new ElementFormula(PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_HOURS.ToString(), SumLeavedayIsSalary, 0); listElementFormula.Add(item); } //Số ngày nghỉ tháng N-1 if (CheckIsExistFormula(listElementFormula, formula, "ATT_LEAVE_", "_DAY_PREV")) { listElement_Leave = TotalData.listElement_All.Where(m => m.ElementCode.StartsWith("ATT_LEAVE_") && m.ElementCode.EndsWith("_DAY_PREV")).ToList(); var _tmpAttendanceTable = TotalData.Att_AttendanceTable_Prev.Where(m => m.ProfileID == profileItem.ID).FirstOrDefault(); foreach (var LD in listElement_Leave) { var itemLeaveday = TotalData.listLeavedayType.Where(m => m.Code == LD.ElementCode.Replace("ATT_LEAVE_", "").Replace("_DAY_PREV", "")).FirstOrDefault(); double value = 0; if (itemLeaveday != null && _tmpAttendanceTable != null) { if (_tmpAttendanceTable.LeaveDay1Type != null && _tmpAttendanceTable.LeaveDay1Type == itemLeaveday.ID) { value += _tmpAttendanceTable.LeaveDay1Days != null ? (double)_tmpAttendanceTable.LeaveDay1Days : 0; } if (_tmpAttendanceTable.LeaveDay2Type != null && _tmpAttendanceTable.LeaveDay2Type == itemLeaveday.ID) { value += _tmpAttendanceTable.LeaveDay2Days != null ? (double)_tmpAttendanceTable.LeaveDay2Days : 0; } if (_tmpAttendanceTable.LeaveDay3Type != null && _tmpAttendanceTable.LeaveDay3Type == itemLeaveday.ID) { value += _tmpAttendanceTable.LeaveDay3Days != null ? (double)_tmpAttendanceTable.LeaveDay3Days : 0; } if (_tmpAttendanceTable.LeaveDay4Type != null && _tmpAttendanceTable.LeaveDay4Type == itemLeaveday.ID) { value += _tmpAttendanceTable.LeaveDay4Days != null ? (double)_tmpAttendanceTable.LeaveDay4Days : 0; } } item = new ElementFormula(LD.ElementCode, value, 0); listElementFormula.Add(item); } } //Tổng số Ngày Nghỉ từng loại trong năm if (CheckIsExistFormula(listElementFormula, formula, "ATT_LEAVE_", "_DAY_INYEAR")) { using (var context = new VnrHrmDataContext()) { string status = string.Empty; var unitOfWork = (IUnitOfWork)new UnitOfWork(context); var repoSys_AttendanceTable = new CustomBaseRepository<Att_AttendanceTable>(unitOfWork); var repoSys_AttendanceTableItem = new CustomBaseRepository<Att_AttendanceTableItem>(unitOfWork); DateTime from = new DateTime(CutOffDuration.MonthYear.Year - 1, 4, 1); DateTime to = new DateTime(CutOffDuration.MonthYear.Year, 3, 31); List<Att_AttendanceTable> listAttendanceTableByProfile = repoSys_AttendanceTable.FindBy(m => m.IsDelete != true && m.ProfileID == profileItem.ID && m.MonthYear != null && m.MonthYear.Value >= from && m.MonthYear.Value <= to).ToList(); listElement_Leave = TotalData.listElement_All.Where(m => m.ElementCode.StartsWith("ATT_LEAVE_") && m.ElementCode.EndsWith("_DAY_INYEAR")).ToList(); foreach (var LD in listElement_Leave) { var itemLeaveday = TotalData.listLeavedayType.Where(m => m.Code == LD.ElementCode.Replace("ATT_LEAVE_", "").Replace("_DAY_INYEAR", "")).FirstOrDefault(); double value = 0; foreach (var _tmpAttendanceTable in listAttendanceTableByProfile) { if (itemLeaveday != null && _tmpAttendanceTable != null) { if (_tmpAttendanceTable.LeaveDay1Type != null && _tmpAttendanceTable.LeaveDay1Type == itemLeaveday.ID) { value += _tmpAttendanceTable.LeaveDay1Days != null ? (double)_tmpAttendanceTable.LeaveDay1Days : 0; } if (_tmpAttendanceTable.LeaveDay2Type != null && _tmpAttendanceTable.LeaveDay2Type == itemLeaveday.ID) { value += _tmpAttendanceTable.LeaveDay2Days != null ? (double)_tmpAttendanceTable.LeaveDay2Days : 0; } if (_tmpAttendanceTable.LeaveDay3Type != null && _tmpAttendanceTable.LeaveDay3Type == itemLeaveday.ID) { value += _tmpAttendanceTable.LeaveDay3Days != null ? (double)_tmpAttendanceTable.LeaveDay3Days : 0; } if (_tmpAttendanceTable.LeaveDay4Type != null && _tmpAttendanceTable.LeaveDay4Type == itemLeaveday.ID) { value += _tmpAttendanceTable.LeaveDay4Days != null ? (double)_tmpAttendanceTable.LeaveDay4Days : 0; } } } item = new ElementFormula(LD.ElementCode, value, 0); listElementFormula.Add(item); } } } #region N-1 if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.ATT_LEAVE_HOURS_PREV.ToString(), PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_HOURS_PREV.ToString() })) { //Tổng số giờ nghỉ trong tháng N-1 item = new ElementFormula(PayrollElement.ATT_LEAVE_HOURS_PREV.ToString(), SumLeaveday_Prev, 0); listElementFormula.Add(item); //Tổng số giờ nghỉ trong tháng có tính lương N-1 item = new ElementFormula(PayrollElement.ATT_TOTAL_PAID_LEAVEDAY_HOURS_PREV.ToString(), SumLeavedayIsSalary_Prev, 0); listElementFormula.Add(item); } #endregion #endregion #endregion #region Honda - tổng số ngày làm việc theo từng ca của nhân viên trong tháng if (CheckIsExistFormula(listElementFormula, formula, "ATT_SHIFT_", "_HOURS")) { using (var context = new VnrHrmDataContext()) { string status = string.Empty; var unitOfWork = (IUnitOfWork)new UnitOfWork(context); //var repoAtt_AttendanceTableItem = new CustomBaseRepository<Att_AttendanceTableItem>(unitOfWork); List<Att_AttendanceTableItemEntity> listAttTableItemByShift = new List<Att_AttendanceTableItemEntity>(); List<Att_AttendanceTableItemEntity> listAttendanceTableItemByAtt = TotalData.listAttendanceTableItem.Where(m => m.AttendanceTableID == listAttendanceTableProCut.ID).ToList(); for (int j = 0; j < TotalData.listCat_Shift.Count; j++) { listAttTableItemByShift = listAttendanceTableItemByAtt.Where(m => m.ShiftID != null && m.ShiftID == TotalData.listCat_Shift[j].ID).ToList(); item = new ElementFormula("ATT_SHIFT_" + TotalData.listCat_Shift[j].Code + "_HOURS", listAttTableItemByShift.Sum(m => m.AvailableHours), 0); listElementFormula.Add(item); } } } if (CheckIsExistFormula(listElementFormula, formula, "ATT_SHIFT_", "_DAY")) { using (var context = new VnrHrmDataContext()) { string status = string.Empty; var unitOfWork = (IUnitOfWork)new UnitOfWork(context); //var repoAtt_AttendanceTableItem = new CustomBaseRepository<Att_AttendanceTableItem>(unitOfWork); List<Att_AttendanceTableItemEntity> listAttTableItemByShift = new List<Att_AttendanceTableItemEntity>(); List<Att_AttendanceTableItemEntity> listAttendanceTableItemByAtt = TotalData.listAttendanceTableItem.Where(m => m.AttendanceTableID == listAttendanceTableProCut.ID).ToList(); List<Att_AttendanceTableItemEntity> listAttendanceTableItemByAtt_Prev = new List<Att_AttendanceTableItemEntity>(); if (TotalData.Att_AttendanceTable_Prev.Count() >= 0) { Att_AttendanceTableEntity _tmp = TotalData.Att_AttendanceTable_Prev.Where(t => t.ProfileID == profileItem.ID).FirstOrDefault(); Guid _tmpID = Guid.Empty; if (_tmp != null) { _tmpID = _tmp.ID; } listAttendanceTableItemByAtt_Prev = TotalData.listAttendanceTableItem.Where(m => m.AttendanceTableID == _tmpID).ToList(); } for (int j = 0; j < TotalData.listCat_Shift.Count; j++) { listAttTableItemByShift = listAttendanceTableItemByAtt.Where(m => m.ShiftID != null && m.ShiftID == TotalData.listCat_Shift[j].ID).ToList(); if (listAttTableItemByShift != null && listAttTableItemByShift.Count > 0) { item = new ElementFormula("ATT_SHIFT" + "_" + TotalData.listCat_Shift[j].Code + "_" + "DAY", listAttTableItemByShift.Where(d => d.AvailableHours > 0).Sum(d => (d.WorkPaidHours + d.LateEarlyMinutes / 60.0) / d.AvailableHours), 0); listElementFormula.Add(item); } else { item = new ElementFormula("ATT_SHIFT" + "_" + TotalData.listCat_Shift[j].Code + "_" + "DAY", 0, 0); listElementFormula.Add(item); } //tháng N-1 listAttTableItemByShift = listAttendanceTableItemByAtt_Prev.Where(m => m.ShiftID != null && m.ShiftID == TotalData.listCat_Shift[j].ID).ToList(); if (listAttTableItemByShift != null && listAttTableItemByShift.Count > 0) { item = new ElementFormula("ATT_SHIFT" + "_" + TotalData.listCat_Shift[j].Code + "_" + "DAY_PREV", listAttTableItemByShift.Where(d => d.AvailableHours > 0).Sum(d => (d.WorkPaidHours + d.LateEarlyMinutes / 60.0) / d.AvailableHours), 0); listElementFormula.Add(item); } else { item = new ElementFormula("ATT_SHIFT" + "_" + TotalData.listCat_Shift[j].Code + "_" + "DAY_PREV", 0, 0); listElementFormula.Add(item); } } } } #endregion #region Lấy giá trị cho các loại phần tử là Hoa Hồng if (CheckIsExistFormula(listElementFormula, formula, CatElementType.Comission.ToString().ToUpper(), "")) { //lấy doanh thu của shop trong tháng List<Sal_RevenueRecordEntity> revenueShopInMonth = new List<Sal_RevenueRecordEntity>(); if (profileItem.ShopID != null) { revenueShopInMonth = TotalData.listRevenueRecord.Where(m => m.ShopID == profileItem.ShopID).ToList(); } if (TotalData.listKPIBonus != null && TotalData.listKPIBonus.Count > 0) { foreach (var j in TotalData.listKPIBonus) { if (revenueShopInMonth.Any(m => m.KPIBonusID == j.ID)) { listElementFormula.Add(new ElementFormula(CatElementType.Comission.ToString().ToUpper() + "_" + j.Code, revenueShopInMonth.Where(m => m.KPIBonusID == j.ID).FirstOrDefault().Amount, 0)); } else { listElementFormula.Add(new ElementFormula(CatElementType.Comission.ToString().ToUpper() + "_" + j.Code, 0, 0)); } } } } #region Phần tử lương hoa hồng đã tính được, trong bảng Sal_PaycCommission if (CheckIsExistFormula(listElementFormula, formula, "ELEMENT" + CatElementType.Comission.ToString().ToUpper() + "_", "")) { List<Cat_ElementEntity> listElementByCommission = TotalData.listElement_All.Where(m => m.GradePayrollID == null && m.MethodPayroll == MethodPayroll.E_COMMISSION_PAYMENT.ToString()).ToList(); if (TotalData.listPayCommissionItem != null) { //duyệt wa tất cả các phần tử foreach (var element in listElementByCommission) { string elementCode = element.ElementCode.Replace("ELEMENT" + CatElementType.Comission.ToString().ToUpper() + "_", ""); Sal_PayCommissionItemEntity PayCommissionItem = TotalData.listPayCommissionItem.Where(m => m.ProfileID != null && m.Code.ReplaceSpace() == elementCode.ReplaceSpace()).FirstOrDefault(); if (PayCommissionItem != null) { item = new ElementFormula(element.ElementCode, PayCommissionItem.Value, 0); listElementFormula.Add(item); } else { item = new ElementFormula(element.ElementCode, 0, 0); listElementFormula.Add(item); } } } else { foreach (var element in listElementByCommission) { item = new ElementFormula(element.ElementCode, 0, 0); listElementFormula.Add(item); } } } #endregion #region Lấy dữ liệu các phần tử là tổng số lượng chức vụ (Position) trong shop if (CheckIsExistFormula(listElementFormula, formula, CatElementType.Comission.ToString().ToUpper() + "_COUNTPOSITION_", "")) { using (var context = new VnrHrmDataContext()) { var unitOfWork = (IUnitOfWork)(new UnitOfWork(context)); var repoProfile = new CustomBaseRepository<Hre_Profile>(unitOfWork); if (TotalData.listPosition != null && TotalData.listPosition.Count > 0) { var lstProfile = repoProfile.FindBy(m => m.ShopID == profileItem.ShopID).ToList(); foreach (var j in TotalData.listPosition) { listElementFormula.Add(new ElementFormula(CatElementType.Comission.ToString().ToUpper() + "_COUNTPOSITION_" + j.Code, lstProfile.Where(m => m.PositionID == j.ID).Count(), 0)); } } } } #endregion #region Lấy giá trị cho 2 enum là dòng sản phẩm và sản phẩm if (CheckIsExistFormula(listElementFormula, formula, new string[] { PayrollElement.SAL_COM_PERCENT_SHOP_LINEITEM.ToString(), PayrollElement.SAL_COM_PERCENT_SHOP_ITEM.ToString() })) { //lấy doanh thu của shop trong tháng List<Sal_RevenueRecordEntity> revenueShopInMonth = new List<Sal_RevenueRecordEntity>(); if (profileItem.ShopID != null) { revenueShopInMonth = TotalData.listRevenueRecord.Where(m => m.ShopID == profileItem.ShopID).ToList(); } //SAL_COM_PERCENT_SHOP_5 if (revenueShopInMonth.Any(m => m.Type == EnumDropDown.SalesType.E_LINEITEM_MAJOR.ToString())) { listElementFormula.Add(new ElementFormula(PayrollElement.SAL_COM_PERCENT_SHOP_LINEITEM.ToString(), revenueShopInMonth.Where(m => m.Type == EnumDropDown.SalesType.E_LINEITEM_MAJOR.ToString()).FirstOrDefault().Amount, 0)); } else { listElementFormula.Add(new ElementFormula(PayrollElement.SAL_COM_PERCENT_SHOP_LINEITEM.ToString(), 0, 0)); } //SAL_COM_PERCENT_SHOP_6 if (revenueShopInMonth.Any(m => m.Type == EnumDropDown.SalesType.E_ITEM_MAJOR.ToString())) { listElementFormula.Add(new ElementFormula(PayrollElement.SAL_COM_PERCENT_SHOP_ITEM.ToString(), revenueShopInMonth.Where(m => m.Type == EnumDropDown.SalesType.E_ITEM_MAJOR.ToString()).FirstOrDefault().Amount, 0)); } else { listElementFormula.Add(new ElementFormula(PayrollElement.SAL_COM_PERCENT_SHOP_ITEM.ToString(), 0, 0)); } } #endregion #region Tính giá trị cho phần tử khấu trừ khi có nhân viên ko đủ thâm niên trong shop if (CheckIsExistFormula(listElementFormula, formula, PayrollElement.SAL_COM_BONUS_SCV.ToString())) { using (var context = new VnrHrmDataContext()) { var unitOfWork = (IUnitOfWork)(new UnitOfWork(context)); var repoProfile = new CustomBaseRepository<Hre_Profile>(unitOfWork); if (profileItem.ShopID != null) { //tính tiền khấu trừ khi khong đủ thâm niên double Money_Deduction = 0; try { //Hiện tại đang lấy trong webconfig, sau này sẻ lấy trong bảng setting Money_Deduction = (double)GetObjectValue(TotalData.listElement_All, listElementFormula, TotalData.listElement_All.Where(m => m.ElementCode == ConstantPathWeb.Hrm_Sal_ElementName_Comission).FirstOrDefault().Formula); } catch { } if (Money_Deduction != 0)//nhân viên này không đủ thâm niên { if (listTmpDeduction.Any(m => m.Key == profileItem.ShopID))//đã có nhân viên ko đủ thâm niên trong shop trước đó { double _tmp = listTmpDeduction.Single(m => m.Key == profileItem.ShopID).Value.Value; int countValue = listTmpDeduction.Single(m => m.Key == profileItem.ShopID).Value.Count; listTmpDeduction.Remove((Guid)profileItem.ShopID);//xóa phần tử trước đó listTmpDeduction.Add((Guid)profileItem.ShopID, new ValueCount(Money_Deduction + _tmp, countValue++));//thêm lại phần tử đó và cập nhật lại value } else//là nhân viên ko đủ thâm niên đầu tiên trong shop { listTmpDeduction.Add((Guid)profileItem.ShopID, new ValueCount(Money_Deduction, 1));//thêm lại phần tử đó và cập nhật lại value } item = new ElementFormula(PayrollElement.SAL_COM_BONUS_SCV.ToString(), 0, 0); listElementFormula.Add(item); } else//nhân viên này đủ thâm niên, kiểm tra xem shop của nhân viên này có nhân viên nào ko đủ thâm niên hay không { if (listTmpDeduction.Any(m => m.Key == profileItem.ShopID))//đã có nhân viên ko đủ thâm niên trong shop trước đó { int CountProfile = repoProfile.FindBy(m => m.ShopID == profileItem.ShopID).Count() - listTmpDeduction.Single(m => m.Key == profileItem.ShopID).Value.Count; item = new ElementFormula(PayrollElement.SAL_COM_BONUS_SCV.ToString(), listTmpDeduction.Single(m => m.Key == profileItem.ShopID).Value.Value / CountProfile, 0); listElementFormula.Add(item); } else { item = new ElementFormula(PayrollElement.SAL_COM_BONUS_SCV.ToString(), 0, 0); listElementFormula.Add(item); } } } else { item = new ElementFormula(PayrollElement.SAL_COM_BONUS_SCV.ToString(), 0, 0); listElementFormula.Add(item); } } } #endregion #endregion #region lấy các phần tử Đánh Giá if (CheckIsExistFormula(listElementFormula, formula, CatElementType.Evaluation.ToString().ToUpper(), "")) { IList<string> List_EvaBonusType = Enum.GetValues(typeof(EvaBonusType)) .Cast<EvaBonusType>() .Select(x => x.ToString()) .ToList(); if (TotalData.listSalesType != null && TotalData.listSalesType.Count > 0) { foreach (var j in TotalData.listSalesType) { foreach (var t in List_EvaBonusType) { try { Eva_BonusSalaryEntity BonusSalaryITem = TotalData.listEva_BonusSalary.Where(m => m.ProfileID == profileItem.ID && m.SalesTypeID == j.ID && m.Type == t).FirstOrDefault(); if (BonusSalaryITem != null && BonusSalaryITem.Bonus != null) { item = new ElementFormula(CatElementType.Evaluation.ToString().ToUpper() + "_" + j.Code + "_" + t, BonusSalaryITem.Bonus, 0); listElementFormula.Add(item); } else { item = new ElementFormula(CatElementType.Evaluation.ToString().ToUpper() + "_" + j.Code + "_" + t, 0, 0); listElementFormula.Add(item); } } catch { item = new ElementFormula(CatElementType.Evaluation.ToString().ToUpper() + "_" + j.Code + "_" + t, 0, 0); listElementFormula.Add(item); } } } } } #endregion #region Vietject #region Lấy các phần tử đơn giá theo vai trò (Vietject) if (CheckIsExistFormula(listElementFormula, formula, CatElementType.FLIGHT.ToString() + "_", "_HOURS") || CheckIsExistFormula(listElementFormula, formula, CatElementType.FLIGHT.ToString() + "_", "_ROUTES") || CheckIsExistFormula(listElementFormula, formula, CatElementType.FLIGHT.ToString() + "_", "_AMOUNT")) { List<Att_TimeSheetEntity> Att_TimeSheetItem = TotalData.listAtt_TimeSheet.Where(m => m.ProfileID == profileItem.ID && m.Date <= CutOffDuration.DateEnd && m.Date >= CutOffDuration.DateStart).OrderByDescending(m => m.Date).ToList(); List<Cat_UnitPriceEntity> Cat_UnitPrice = TotalData.listCat_UnitPrice.Where(m => m.Date <= CutOffDuration.DateEnd).OrderByDescending(m => m.Date).ToList(); if (TotalData.listCat_Role != null && TotalData.listCat_Role.Count > 0 && TotalData.listCat_JobType != null && TotalData.listCat_JobType.Count > 0) { foreach (var Role in TotalData.listCat_Role) { foreach (var JobType in TotalData.listCat_JobType) { var Att_TimeSheetItemByItem = Att_TimeSheetItem.Where(m => m.RoleID == Role.ID && m.JobTypeID == JobType.ID).OrderByDescending(m => m.Date).ToList(); var Cat_UnitPriceByItem = Cat_UnitPrice.Where(m => m.RoleID == Role.ID && m.JobTypeID == JobType.ID).OrderByDescending(m => m.Date).FirstOrDefault(); //số giờ bay item = new ElementFormula(CatElementType.FLIGHT.ToString() + "_" + Role.Code.ReplaceSpace() + "_" + JobType.Code.ReplaceSpace() + "_HOURS", Att_TimeSheetItemByItem.Sum(m => m.NoHour), 0); listElementFormula.Add(item); //số chặn bay item = new ElementFormula(CatElementType.FLIGHT.ToString() + "_" + Role.Code.ReplaceSpace() + "_" + JobType.Code.ReplaceSpace() + "_ROUTES", Att_TimeSheetItemByItem.Sum(m => m.Sector), 0); listElementFormula.Add(item); //số tiền double Amount = Cat_UnitPriceByItem != null && Cat_UnitPriceByItem.Amount != null ? (double)Cat_UnitPriceByItem.Amount : 0; item = new ElementFormula(CatElementType.FLIGHT.ToString() + "_" + Role.Code.ReplaceSpace() + "_" + JobType.Code.ReplaceSpace() + "_AMOUNT", Amount, 0); listElementFormula.Add(item); } } } } #endregion #endregion return listElementFormula.Distinct().ToList(); }
private bool IsHaveLateEarly(DateTime ShiftIn, DateTime ShiftOut, DateTime InTime, DateTime OutTime, ref bool BeLate, ref bool BeEarly, ref double HourLate, ref double HourEarly, Dictionary<DateTime, DateTime> TimeLeave, Cat_Shift Shift) { #region Xử lý vấn đề Ca có giờ linh động cho VE VietNam Esports (Thái phụ trách) - Tính giờ làm việc linh động theo Ca Làm Việc if (Shift != null && Shift.InOutDynamic != null && Shift.InOutDynamic > 0) { if (InTime > ShiftIn) { double HourDynamicLate = (InTime - ShiftIn).TotalHours; HourDynamicLate = HourDynamicLate > Shift.InOutDynamic.Value ? Shift.InOutDynamic.Value : HourDynamicLate; InTime = InTime.AddHours(HourDynamicLate); OutTime = OutTime.AddHours(HourDynamicLate); } } #endregion if (InTime <= ShiftIn) { BeLate = false; HourLate = 0; } else { double Late = (InTime - ShiftIn).TotalHours; foreach (var item in TimeLeave.Keys) { DateTime Start = item; DateTime End = TimeLeave[item]; if (InTime >= Start && ShiftIn >= End)//neu co giao nhau { //Tinh thoi gian giao nhau if (ShiftIn > Start) { Start = ShiftIn; } if (InTime < End) { End = InTime; } Late -= (End - Start).TotalHours; } } if (HourLate == 0 || Late < HourLate) { HourLate = Late; } } if (OutTime >= ShiftOut) { BeEarly = false; HourEarly = 0; } else { double Early = (ShiftOut - OutTime).TotalHours; foreach (var item in TimeLeave.Keys) { DateTime Start = item; DateTime End = TimeLeave[item]; if (OutTime <= Start && ShiftOut >= Start)//neu co giao nhau { //Tinh thoi gian giao nhau if (ShiftOut < End) { End = ShiftOut; } if (Start < OutTime) { Start = OutTime; } Early -= (End - Start).TotalHours; } } if (HourEarly == 0 || Early < HourEarly) { HourEarly = Early; } } if (BeLate == false && BeEarly == false) { return false; } else { return true; } }
private Att_RptExceptionDataEntity SetExceptionData(Att_InOut InOut, Hre_Profile profile, Cat_Shift shift, DateTime idx,string userExport) { Att_RptExceptionDataEntity exceptionData = new Att_RptExceptionDataEntity(); exceptionData.ID = Guid.NewGuid(); exceptionData.InOutID = InOut == null ? Guid.Empty : InOut.ID; //exceptionData.EntityType = ClassNames.Att_InOut; exceptionData.EntityType = "Att_InOut"; exceptionData.CodeEmp = profile.CodeEmp; exceptionData.ShiftID = shift == null ? Guid.Empty : shift.ID; exceptionData.ProfileID = profile.ID; exceptionData.ProfileName = profile.ProfileName; exceptionData.UserExport = userExport; exceptionData.DateExport = DateTime.Today; //exceptionData.Position = profile.Cat_Position == null ? string.Empty : profile.Cat_Position.PositionName; //string[] strDepartment = GradeCfgDAO.getLinkDepartment(ListCacheOrgStructure, profile.Cat_OrgStructure, true); //exceptionData.Department = strDepartment[1]; exceptionData.Date = idx; return exceptionData; }
private static WorkDay CreateWorkDay(Hre_Profile profile, List<Att_Workday> listInOutByWorkDate, Cat_OrgStructure orgLine, Cat_Shift shift, List<Cat_ShiftItem> listShiftItem, Att_Pregnancy pregnancyByWorkDay, Cat_GradeAttendance graCfgPro, string userLogin) { WorkDay result = null; listInOutByWorkDate = listInOutByWorkDate.Where(d => d.InTime1 != null && d.OutTime1 != null).OrderBy(d => d.WorkDate).ThenBy(d => d.InTime1).ToList(); if (listInOutByWorkDate != null && listInOutByWorkDate.Count() > 0) { #region Khởi tạo result = new WorkDay(); result.Cat_Shift = shift; result.WorkDuration = 0D; result.WorkDate = listInOutByWorkDate.Select(d => d.WorkDate).FirstOrDefault();//ngày làm việc DateTime timeShiftStart = result.WorkDate.Date.Add(shift.InTime.TimeOfDay);//thời gian bắt đầu của ca làm việc DateTime timeShiftEnd = timeShiftStart.AddHours(shift.CoOut);////thời gian kết thúc của ca làm việc (date + time) double totalTimeShift = timeShiftEnd.Subtract(timeShiftStart).TotalHours; //LamLe - 20121017 - Lay gio lam viec trong grade hay trong Shift double workingStandardHour = graCfgPro.GetWorkHouPerDay(result.WorkDate); //if (shift != null && graCfgPro != null && graCfgPro.WorkHoursType == GradeHoursType.E_SHIFT_HOURS.ToString()) if (shift != null && graCfgPro != null) { workingStandardHour = shift.WorkHours != null ? shift.WorkHours.Value : 0D; } listShiftItem = listShiftItem.Where(sh => sh.ShiftItemType == ShiftItemType.E_SHIFTBREAK.ToString()).OrderBy(p => p.CoFrom).ToList(); Guid? lineID = orgLine != null ? orgLine.ID : profile.OrgStructureID;//LamLe - 20121030 - Xu ly truong hop co Line org trong Roster Cat_ShiftItem shiftItemFlex = listShiftItem.Where(p => p.OrgStructureID == lineID).FirstOrDefault(); double realCoBreakStart = 0D; double realCoBreakEnd = 0D; //Vinhtran: Kiểm tra có giờ nghỉ giữa ca làm việc hay không? if (shift.ShiftBreakType == ShiftBreakType.E_FLEXIBLE.ToString() && totalTimeShift > workingStandardHour && shiftItemFlex != null && shiftItemFlex.CoFrom > 0 && shiftItemFlex.CoTo > shiftItemFlex.CoFrom) { if (!shift.IsBreakAsWork.HasValue || !shift.IsBreakAsWork.Value) { shift.udCoBreakStart = shiftItemFlex.CoFrom; shift.udCoBreakEnd = shiftItemFlex.CoTo; } realCoBreakStart = shiftItemFlex.CoFrom; realCoBreakEnd = shiftItemFlex.CoTo; } else if (shift.CoBreakIn > 0 && shift.CoBreakOut > shift.CoBreakIn) { if (!shift.IsBreakAsWork.HasValue || !shift.IsBreakAsWork.Value) { shift.udCoBreakStart = shift.CoBreakIn; shift.udCoBreakEnd = shift.CoBreakOut; } realCoBreakStart = shift.CoBreakIn; realCoBreakEnd = shift.CoBreakOut; } if (realCoBreakEnd > realCoBreakStart) { totalTimeShift -= realCoBreakEnd - realCoBreakStart; } //Thời gian bắt đầu và kết thúc nghỉ giữa ca - dùng cho tính toán DateTime timeShiftBreakIn = timeShiftStart.AddHours(shift.udCoBreakStart); DateTime timeShiftBreakOut = timeShiftStart.AddHours(shift.udCoBreakEnd); //Khoảng thời gian của nửa ca đầu DateTime firstHalfShiftStart = timeShiftStart; DateTime firstHalfShiftEnd = timeShiftEnd; //Khoảng thời gian của nửa ca sau DateTime lastHalfShiftStart = timeShiftStart; DateTime lastHalfShiftEnd = timeShiftEnd; if (shift.udCoBreakEnd > shift.udCoBreakStart && shift.udCoBreakStart > 0) { firstHalfShiftStart = timeShiftStart; firstHalfShiftEnd = timeShiftBreakIn; lastHalfShiftStart = timeShiftBreakOut; lastHalfShiftEnd = timeShiftEnd; } if (timeShiftBreakIn > timeShiftStart && listInOutByWorkDate.Count() > 1) { //Lần quẹt thẻ vào đầu tiên và lần quẹt thẻ ra cuối cùng của nửa ca đâu if (listInOutByWorkDate.Any(d => d.InTime1 < timeShiftBreakIn)) { result.FirstInTime = listInOutByWorkDate.Where(d => d.InTime1 < timeShiftBreakIn).OrderBy(d => d.WorkDate).ThenBy(d => d.InTime1).Select(d => d.InTime1.Value).FirstOrDefault(); result.FirstOutTime = listInOutByWorkDate.Where(d => d.InTime1 < timeShiftBreakIn).OrderBy(d => d.WorkDate).ThenBy(d => d.OutTime1).Select(d => d.OutTime1.Value).LastOrDefault(); } else { result.FirstInTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.InTime1).Select(d => d.InTime1.Value).FirstOrDefault(); result.FirstOutTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.OutTime1).Select(d => d.OutTime1.Value).FirstOrDefault(); } //Lần quẹt thẻ vào đầu tiên và lần quẹt thẻ ra cuối cùng của nửa ca sau if (listInOutByWorkDate.Any(d => d.OutTime1 > timeShiftBreakOut)) { result.LastInTime = listInOutByWorkDate.Where(d => d.OutTime1 > timeShiftBreakOut).OrderBy(d => d.WorkDate).ThenBy(d => d.InTime1).Select(d => d.InTime1.Value).FirstOrDefault(); result.LastOutTime = listInOutByWorkDate.Where(d => d.OutTime1 > timeShiftBreakOut).OrderBy(d => d.WorkDate).ThenBy(d => d.OutTime1).Select(d => d.OutTime1.Value).LastOrDefault(); } else { result.LastInTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.InTime1).Select(d => d.InTime1.Value).LastOrDefault(); result.LastOutTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.OutTime1).Select(d => d.OutTime1.Value).LastOrDefault(); } } else { //Lần quẹt thẻ vào đầu tiên và lần quẹt thẻ ra cuối cùng của nửa ca đâu result.FirstInTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.InTime1).Select(d => d.InTime1.Value).FirstOrDefault(); result.FirstOutTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.OutTime1).Select(d => d.OutTime1.Value).LastOrDefault(); //Lần quẹt thẻ vào đầu tiên và lần quẹt thẻ ra cuối cùng của nửa ca sau result.LastInTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.InTime1).Select(d => d.InTime1.Value).FirstOrDefault(); result.LastOutTime = listInOutByWorkDate.OrderBy(d => d.WorkDate).ThenBy(d => d.OutTime1).Select(d => d.OutTime1.Value).LastOrDefault(); } DateTime nightTimeStart = result.WorkDate.Date.AddHours(21); DateTime nightTimeEnd = result.WorkDate.Date.AddDays(1).AddHours(5); double nightDuration = 0D; double firstDuration = 0D; double lastDuration = 0D; if (shift.IsNightShift) { if (shift.NightTimeStart == null || shift.NightTimeEnd == null) { string appConfigName = AppConfig.HRM_ATT_OT_.ToString(); double startHour = 21D; double endHour = 5D; List<object> lstParamSys = new List<object>(); lstParamSys.Add(appConfigName); lstParamSys.Add(null); lstParamSys.Add(null); string status = string.Empty; BaseService baseService = new BaseService(); var lstAppConfig = baseService.GetData<Sys_AllSetting>(lstParamSys, ConstantSql.hrm_sys_sp_get_AllSetting, userLogin, ref status); Sys_AllSetting appConfig13 = lstAppConfig.Where(s => s.IsDelete == null && s.Name == AppConfig.HRM_ATT_OT_NIGHTSHIFTFROM.ToString()).FirstOrDefault(); Sys_AllSetting appConfig14 = lstAppConfig.Where(s => s.IsDelete == null && s.Name == AppConfig.HRM_ATT_OT_NIGHTSHIFTTO.ToString()).FirstOrDefault(); //Sys_AppConfig appConfig = EntityService.Instance.GetEntityList<Sys_AppConfig>(false, // EntityService.Instance.GuidMainContext, Guid.Empty, d => d.Info == appConfigName).FirstOrDefault(); if (lstAppConfig != null && appConfig13 != null && appConfig14 != null) { double.TryParse(appConfig13.Value1, out startHour); double.TryParse(appConfig14.Value1, out endHour); } nightTimeStart = shift.NightTimeStart == null ? result.WorkDate.Date.AddHours(startHour) : result.WorkDate.Date.Add(shift.NightTimeStart.Value.TimeOfDay); nightTimeEnd = shift.NightTimeEnd == null ? result.WorkDate.Date.AddHours(endHour) : result.WorkDate.Date.Add(shift.NightTimeEnd.Value.TimeOfDay); } else { nightTimeStart = result.WorkDate.Date.Add(shift.NightTimeStart.Value.TimeOfDay); nightTimeEnd = result.WorkDate.Date.Add(shift.NightTimeEnd.Value.TimeOfDay); } nightTimeEnd = nightTimeStart > nightTimeEnd ? nightTimeEnd.AddDays(1) : nightTimeEnd; } #endregion foreach (Att_Workday objInOut in listInOutByWorkDate) { if (objInOut.InTime1.HasValue && objInOut.OutTime1.HasValue) { #region Tính work duration DateTime inTime = objInOut.InTime1.Value; DateTime outTime = objInOut.OutTime1.Value; firstDuration += GetIntersectAmountMinutes(inTime, outTime, firstHalfShiftStart, firstHalfShiftEnd); if (timeShiftBreakIn > timeShiftStart) { //Nếu có giờ nghỉ giữa ca lastDuration += GetIntersectAmountMinutes(inTime, outTime, lastHalfShiftStart, lastHalfShiftEnd); } #endregion #region Tính night shift if (shift.IsNightShift) { if (pregnancyByWorkDay != null) { if ((pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_FIRST.ToString() || pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_FIRST_OUT_BEARK.ToString()) && Common.IsOverlap(inTime, outTime, nightTimeStart, nightTimeEnd)) { nightTimeStart = nightTimeStart.AddHours(1); } else if ((pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_LAST.ToString() || pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_LAST_IN_BEARK.ToString()) && Common.IsOverlap(inTime, outTime, nightTimeStart, nightTimeEnd)) { nightTimeEnd = nightTimeEnd.AddHours(-1); } } //Truong hop nghi giua ca nam trong khoang bat dau ca dem if (nightTimeStart >= timeShiftBreakIn && nightTimeStart <= timeShiftBreakOut) { nightDuration += GetIntersectAmountMinutes(inTime, outTime, timeShiftBreakOut, nightTimeEnd); } else if (nightTimeEnd >= timeShiftBreakIn && nightTimeEnd <= timeShiftBreakOut) { nightDuration += GetIntersectAmountMinutes(inTime, outTime, nightTimeStart, timeShiftBreakIn); } else if (nightTimeEnd > timeShiftBreakOut && nightTimeStart < timeShiftBreakIn) { nightDuration += GetIntersectAmountMinutes(inTime, outTime, nightTimeStart, timeShiftBreakIn); nightDuration += GetIntersectAmountMinutes(inTime, outTime, timeShiftBreakOut, nightTimeEnd); } else { nightDuration += GetIntersectAmountMinutes(inTime, outTime, nightTimeStart, nightTimeEnd); } } #endregion } } if (shift.ReduceNightShift != null && shift.ReduceNightShift >= 0) { Int32 reduceNightMinutes = Convert.ToInt32(shift.ReduceNightShift.Value * 60); nightDuration = nightDuration > reduceNightMinutes ? reduceNightMinutes : nightDuration; } nightDuration = nightDuration > 0 ? nightDuration / 60 : 0D; firstDuration = firstDuration > 0 ? firstDuration / 60 : 0D; lastDuration = lastDuration > 0 ? lastDuration / 60 : 0D; //Vinhtran: Tổng thời gian làm việc - tính theo giờ result.WorkDuration = firstDuration + lastDuration; result.NightShiftDuration = nightDuration; result.FirstDuration = firstDuration; result.LastDuration = lastDuration; if (result.WorkDuration > workingStandardHour) { result.WorkDuration = workingStandardHour; } if (result.NightShiftDuration > workingStandardHour) { result.NightShiftDuration = workingStandardHour; } if (shift.IsDoubleShift.Get_Boolean()) { //Vinh.Tran: Xử lý trường hợp ca ghép totalTimeShift = shift.WorkHours.Get_Double(); } //Vinhtran: Tổng thời gian bị đi trễ hoặc về sớm - tính theo giờ result.LateEarlyDuration = totalTimeShift - result.WorkDuration; #region Tính trễ sớm //Có đi trễ hoặc về sớm if (result.LateEarlyDuration > 0) { if (timeShiftBreakIn > timeShiftStart) { if (result.FirstInTime > firstHalfShiftStart && result.FirstInTime < firstHalfShiftEnd) { //thời gian đi trễ nửa ca đầu result.FirstLateDuration = result.FirstInTime.Value.Subtract(firstHalfShiftStart).TotalHours; } if (result.LastInTime > lastHalfShiftStart) { //thời gian đi trễ nửa ca sau result.LastLateDuration = result.LastInTime.Value.Subtract(lastHalfShiftStart).TotalHours; } result.FirstEarlyDuration = firstHalfShiftEnd.Subtract(firstHalfShiftStart).TotalHours - firstDuration - result.FirstLateDuration; result.LastEarlyDuration = lastHalfShiftEnd.Subtract(lastHalfShiftStart).TotalHours - lastDuration - result.LastLateDuration; result.LateDuration = result.FirstLateDuration + result.LastLateDuration; result.EarlyDuration = result.FirstEarlyDuration + result.LastEarlyDuration; } else { if (result.FirstInTime > timeShiftStart) { //thời gian đi trễ nửa ca đầu result.LateDuration = result.FirstInTime.Value.Subtract(timeShiftStart).TotalHours; result.FirstLateDuration = result.LateDuration; result.LastLateDuration = 0; } result.EarlyDuration = timeShiftEnd.Subtract(timeShiftStart).TotalHours - result.WorkDuration - result.LateDuration; result.FirstEarlyDuration = result.EarlyDuration; result.LastEarlyDuration = 0; } if (pregnancyByWorkDay != null) { //Thời gian làm việc lớn nhất có thể xảy ra double maxWorkDuration = totalTimeShift - result.LateEarlyDuration + 1; maxWorkDuration += shift.IsDoubleShift.Get_Boolean() ? 1 : 0;//Ca ghép thì thêm 1 giờ maxWorkDuration = maxWorkDuration > totalTimeShift ? totalTimeShift : maxWorkDuration; if (pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_FIRST.ToString()) { //Chỉ được đi trễ 1 giờ đầu của nửa ca trước, không được về sớm trong nữa ca đầu. result.WorkDuration += result.FirstLateDuration <= 1 ? result.FirstLateDuration : 1; result.FirstLateDuration = result.FirstLateDuration <= 1 ? 0 : result.FirstLateDuration - 1; if (shift.IsDoubleShift.Get_Boolean()) { result.WorkDuration += result.LastLateDuration <= 1 ? result.LastLateDuration : 1; result.LastLateDuration = result.LastLateDuration <= 1 ? 0 : result.LastLateDuration - 1; result.LateDuration = result.LateDuration <= 2 ? 0 : result.LateDuration - 2; } else { result.LateDuration = result.LateDuration <= 1 ? 0 : result.LateDuration - 1; } result.WorkDuration = result.WorkDuration > maxWorkDuration ? maxWorkDuration : result.WorkDuration; } else if (pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_FIRST_OUT_BEARK.ToString()) { //Được đi trễ hoặc về sớm 1 giờ bất kỳ của nửa ca trước, nếu là ca ghép thì được 1 tiếng trễ sớm ở mỗi ca (tổng là 2 tiếng) double firstLatetEarly = timeShiftBreakIn > timeShiftStart ? result.FirstLateDuration + result.FirstEarlyDuration : result.LateDuration + result.EarlyDuration; double lastLatetEarly = (shift.IsDoubleShift.Get_Boolean() && timeShiftBreakIn > timeShiftStart) ? result.LastLateDuration + result.LastEarlyDuration : 0; double totalLatetEarly = firstLatetEarly + lastLatetEarly; if (shift.IsDoubleShift.Get_Boolean()) { result.WorkDuration += totalLatetEarly <= 2 ? totalLatetEarly : 2; result.LateDuration = result.LateDuration <= 2 ? 0 : result.LateDuration - 2; } else { result.WorkDuration += totalLatetEarly <= 1 ? totalLatetEarly : 1; result.LateDuration = result.LateDuration <= 1 ? 0 : result.LateDuration - 1; } if (timeShiftBreakIn > timeShiftStart) { result.FirstLateDuration = result.FirstLateDuration <= 1 ? 0 : result.FirstLateDuration - 1; result.FirstEarlyDuration = firstLatetEarly - result.FirstLateDuration; if (shift.IsDoubleShift.Get_Boolean()) { result.LastLateDuration = result.LastLateDuration <= 1 ? 0 : result.LastLateDuration - 1; result.LastEarlyDuration = lastLatetEarly - result.LastLateDuration; } } result.EarlyDuration = totalLatetEarly - result.LateDuration; } else if (pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_LAST_IN_BEARK.ToString()) { //Được đi trễ hoặc về sớm 1 giờ bất kỳ của nửa ca sau, nếu là ca ghép thì được 1 tiếng trễ sớm ở mỗi ca (tổng là 2 tiếng) double lastLatetEarly = timeShiftBreakIn > timeShiftStart ? result.LastLateDuration + result.LastEarlyDuration : result.LateDuration + result.EarlyDuration; double firstLatetEarly = (shift.IsDoubleShift.Get_Boolean() && timeShiftBreakIn > timeShiftStart) ? result.FirstLateDuration + result.FirstEarlyDuration : 0; double totalLatetEarly = firstLatetEarly + lastLatetEarly; if (shift.IsDoubleShift.Get_Boolean()) { result.WorkDuration += totalLatetEarly <= 2 ? totalLatetEarly : 2; result.LateDuration = result.LateDuration <= 2 ? 0 : result.LateDuration - 2; } else { result.WorkDuration += totalLatetEarly <= 1 ? totalLatetEarly : 1; result.LateDuration = result.LateDuration <= 1 ? 0 : result.LateDuration - 1; } if (timeShiftBreakIn > timeShiftStart) { result.LastLateDuration = result.LastLateDuration <= 1 ? 0 : result.LastLateDuration - 1; result.LastEarlyDuration = lastLatetEarly - result.LastLateDuration; if (shift.IsDoubleShift.Get_Boolean()) { result.FirstLateDuration = result.FirstLateDuration <= 1 ? 0 : result.FirstLateDuration - 1; result.FirstEarlyDuration = firstLatetEarly - result.FirstLateDuration; } } result.EarlyDuration = totalLatetEarly - result.LateDuration; } else if (pregnancyByWorkDay.TypePregnancyEarly == PregnancyLeaveEarlyType.E_LAST.ToString()) { //Chỉ được về sớm 1 giờ cuối của nửa ca trước, không được đi trễ trong nữa ca sau. if (timeShiftBreakIn > timeShiftStart) { result.WorkDuration += result.LastEarlyDuration <= 1 ? result.LastEarlyDuration : 1; result.LastEarlyDuration = result.LastEarlyDuration <= 1 ? 0 : result.LastEarlyDuration - 1; if (shift.IsDoubleShift.Get_Boolean()) { result.WorkDuration += result.FirstEarlyDuration <= 1 ? result.FirstEarlyDuration : 1; result.FirstEarlyDuration = result.FirstEarlyDuration <= 1 ? 0 : result.FirstEarlyDuration - 1; } } else { if (shift.IsDoubleShift.Get_Boolean()) { result.WorkDuration += result.EarlyDuration <= 2 ? result.EarlyDuration : 2; } else { result.WorkDuration += result.EarlyDuration <= 1 ? result.EarlyDuration : 1; } } if (shift.IsDoubleShift.Get_Boolean()) { result.EarlyDuration = result.EarlyDuration <= 2 ? 0 : result.EarlyDuration - 2; } else { result.EarlyDuration = result.EarlyDuration <= 1 ? 0 : result.EarlyDuration - 1; } result.WorkDuration = result.WorkDuration > maxWorkDuration ? maxWorkDuration : result.WorkDuration; } } } #endregion //Vinhtran: Tổng thời gian bị đi trễ hoặc về sớm - tính theo phút result.LateDuration = result.LateDuration > 0 ? result.LateDuration * 60 : 0D; result.EarlyDuration = result.EarlyDuration > 0 ? result.EarlyDuration * 60 : 0D; result.FirstLateDuration = result.FirstLateDuration > 0 ? result.FirstLateDuration * 60 : 0D; result.FirstEarlyDuration = result.FirstEarlyDuration > 0 ? result.FirstEarlyDuration * 60 : 0D; result.LastLateDuration = result.LastLateDuration > 0 ? result.LastLateDuration * 60 : 0D; result.LastEarlyDuration = result.LastEarlyDuration > 0 ? result.LastEarlyDuration * 60 : 0D; result.LateEarlyDuration = result.LateEarlyDuration > 0 ? result.LateEarlyDuration * 60 : 0D; //Vinhtran: Tổng thời gian (h) làm ca đêm lớn nhất có thể => làm tròn trễ sớm result.MaxNightDuration = nightTimeEnd.Subtract(nightTimeStart).TotalHours; //Thời gian bắt đầu và kết thúc nghỉ giữa ca - giá trị thực tế result.ShiftBreakInTime = timeShiftStart.AddHours(realCoBreakStart); result.ShiftBreakOutTime = timeShiftStart.AddHours(realCoBreakEnd); //Khoản thời gian làm việc của ca result.ShiftInTime = timeShiftStart; result.ShiftOutTime = timeShiftEnd; if (shift != null && shift.IsNotApplyWorkHoursReal != null && shift.IsNotApplyWorkHoursReal.Value == true) { result.WorkDuration = workingStandardHour - Math.Abs(result.LateDuration / 60) - Math.Abs(result.EarlyDuration / 60); } } return result; }
public static Double GetInOutWorkingHour(Att_InOut inout, Cat_Shift shift) { DateTime workdate = new DateTime(inout.WorkDate.Year, inout.WorkDate.Month, inout.WorkDate.Day , shift.InTime.Hour, shift.InTime.Minute, shift.InTime.Second); DateTime shiftStart = workdate; DateTime shiftEnd = workdate.AddHours(shift.CoOut); return GetIntersectAmount(inout.InTime.Value, inout.OutTime.Value, shiftStart, shiftEnd).TotalHours; }
/// <summary> /// /// </summary> /// <param name="inout"></param> /// <param name="shift"></param> /// <returns></returns> public static Double GetShiftRosterShiftInOutHour(Att_InOut inout, Cat_Shift shift) { DateTime workdate = new DateTime(inout.WorkDate.Year, inout.WorkDate.Month, inout.WorkDate.Day , shift.InTime.Hour, shift.InTime.Minute, shift.InTime.Second); DateTime shiftStart = workdate; DateTime shiftEnd = workdate.AddHours(shift.CoOut); DateTime dateIn = inout.InTime.Value; DateTime dateOut = inout.OutTime.Value; Double _hrs = 0; if (dateIn.CompareTo(shiftStart) > 0) _hrs += dateIn.Subtract(shiftStart).TotalHours; else _hrs += shiftStart.Subtract(dateIn).TotalHours; if (dateOut.CompareTo(shiftEnd) > 0) _hrs += dateOut.Subtract(shiftEnd).TotalHours; else _hrs += shiftEnd.Subtract(dateOut).TotalHours; return _hrs; }
private Att_Workday CreateWorkday(IUnitOfWork unitOfWork, DateTime date, Hre_ProfileEntity profile, WorkdayConfig inOutConfig, List<Cat_DayOffEntity> listHoliday, List<Att_Workday> listWorkday, Att_Workday workday, bool isFromShift2, Guid? shiftID, Cat_Shift shiftInfo, List<Cat_Shift> listShift, Dictionary<DateTime, List<Guid?>> listMonthShifts, out Guid? actualShiftID, List<Att_TAMScanLogEntity> listTamScanLogByCardCode, List<Att_TAMScanLogEntity> listTamScanLogByCardCodeUnchecked) { #region Trường hợp có lịch làm việc #region Kiểm tra dữ liệu quẹt theo theo ngày (ca) var listTamScanLogByShift = GetTamScanLogByShift(date, listShift, shiftID, listMonthShifts, listTamScanLogByCardCodeUnchecked.ToArray()); //Checked = true để không tự detect shift cho nó listTamScanLogByShift.ForEach(d => d.Checked = true); actualShiftID = null; if (workday == null) { workday = new Att_Workday(); unitOfWork.AddObject(typeof(Att_Workday), workday); } #endregion if (inOutConfig == null || inOutConfig.TypeLoadData.IsNullOrEmpty() || inOutConfig.TypeLoadData == TypeLoadData.E_DEFAULT.ToString() || inOutConfig.TypeLoadData == TypeLoadData.E_MAXMIN.ToString()) { if (listTamScanLogByShift.Count() >= 2) { #region Trường hợp có ít nhất 2 dòng quẹt thẻ thuộc ca đang xét var inTime = listTamScanLogByShift.Select(d => d.TimeLog).FirstOrDefault(); var outTime = listTamScanLogByShift.Select(d => d.TimeLog).LastOrDefault(); //Khi phát hiện 2 quẹt thẻ hợp lệ với ca đăng ký thì nhân luôn - không detect shift workday.FirstInTime = !workday.FirstInTime.HasValue || workday.FirstInTime > inTime ? inTime : workday.FirstInTime; workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < outTime ? outTime : workday.LastOutTime; if (isFromShift2) { workday.InTime2 = inTime; workday.OutTime2 = outTime; } else { workday.InTime1 = inTime; workday.OutTime1 = outTime; } if (inOutConfig.DetectWrongShift == Boolean.TrueString) { //Trường hợp wrong-shift và detected-shift thì phải check lại actualShiftID actualShiftID = GetDetectedShiftID(inTime, outTime, listShift, null); if (actualShiftID != Guid.Empty && actualShiftID != shiftID) { var listTest = GetTamScanLogByShift(inTime.Value.Date, listShift, actualShiftID, listMonthShifts, listTamScanLogByShift.ToArray()); if (listTest != null && listTest.Count() >= 2 && listTest.Any(d => d.TimeLog.HasValue && d.TimeLog.Value.Date == date)) { workday.Type = WorkdayType.E_WRONG_SHIFT.ToString(); } else { actualShiftID = null; } } } #endregion } else if (listTamScanLogByShift.Count() == 1) { #region Trường hợp có 1 dòng quẹt thẻ thuộc ca đang xét if (listTamScanLogByShift.Any(d => d.SrcType == TAMScanType.E_OUT.ToString())) { //Dữ liệu quẹt thẻ được lấy từ máy chấm công ra - có option máy vào máy ra workday.Type = WorkdayType.E_MISS_IN.ToString(); if (isFromShift2) { workday.OutTime2 = listTamScanLogByShift.Select(d => d.TimeLog).LastOrDefault(); } else { workday.OutTime1 = listTamScanLogByShift.Select(d => d.TimeLog).LastOrDefault(); } } else { //So sanh độ lệch với thời gian của ca -> gần bên nào thì tính theo bên đó var timeLog = listTamScanLogByShift.Select(d => d.TimeLog).FirstOrDefault(); var shiftInTime = date.Add(shiftInfo.InTime.TimeOfDay); if (timeLog.Value <= shiftInTime || timeLog.Value.Subtract(shiftInTime) < shiftInTime.AddHours(shiftInfo.CoOut).Subtract(timeLog.Value)) { //1 dòng quẹt thẻ rơi vào nửa đầu của ca workday.Type = WorkdayType.E_MISS_OUT.ToString(); if (isFromShift2) { workday.InTime2 = timeLog; } else { workday.InTime1 = timeLog; } } if (inOutConfig.DetectWrongShift == Boolean.TrueString) { #region Tìm quẹt thẻ phía trước //Quẹt thẻ gần với thời gian vào của ca -> miss-out hoặc làm sai ca //Tìm ca làm việc trước gần nhất và dòng quẹt thẻ trước gần nhất của nhân viên đang xét var preShift = listMonthShifts.Where(d => d.Key >= date.AddDays(-1) && d.Key < date).OrderByDescending(d => d.Key).FirstOrDefault(); var preShiftValue = preShift.Value != null && preShift.Value.Count() > 0 ? preShift.Value.LastOrDefault() : null; //Lấy dòng quẹt thẻ hiện tại và 2 dòng quẹt thẻ phía trước gần nhất của nhân viên đang xét để kiểm tra ca trước var listPreTamScanLog = listTamScanLogByCardCode.Where(d => d.TimeLog <= timeLog).OrderByDescending(d => d.TimeLog).Take(3).ToList(); var listTamScanLogByPreShift = GetTamScanLogByShift(preShift.Key, listShift, preShiftValue, listMonthShifts, listPreTamScanLog.ToArray()); //Nếu 2 dòng quẹt thẻ phía trước không thuộc một ca khác trong lịch của nhân viên if (listTamScanLogByPreShift == null || listTamScanLogByPreShift.Count() < 2) { var preTamScanLog = listPreTamScanLog.Where(d => d.TimeLog < timeLog).FirstOrDefault(); var currentShiftDuration = shiftInfo.MinIn + shiftInfo.CoOut + shiftInfo.MaxOut; if (preTamScanLog != null && listWorkday.Any(d => d.ProfileID == profile.ID && (d.InTime1 == preTamScanLog.TimeLog || d.InTime2 == preTamScanLog.TimeLog || d.InTime3 == preTamScanLog.TimeLog || d.InTime4 == preTamScanLog.TimeLog || d.OutTime1 == preTamScanLog.TimeLog || d.OutTime2 == preTamScanLog.TimeLog || d.OutTime3 == preTamScanLog.TimeLog || d.OutTime4 == preTamScanLog.TimeLog))) { //Trường hợp quẹt thẻ này đã sử dụng preTamScanLog = null; } //Nếu quẹt thẻ hiện tại kết với quẹt thẻ tiếp theo mà phù hợp duration thì ghép sai ca if (preTamScanLog != null && preTamScanLog.TimeLog.HasValue && timeLog.Value .Subtract(preTamScanLog.TimeLog.Value).TotalHours <= currentShiftDuration) { //Trường hợp wrong-shift và detected-shift thì phải check lại actualShiftID actualShiftID = GetDetectedShiftID(preTamScanLog.TimeLog, timeLog, listShift, null); var listTest = GetTamScanLogByShift(preTamScanLog.TimeLog.Value.Date, listShift, actualShiftID, listMonthShifts, new Att_TAMScanLogEntity[] { preTamScanLog, listTamScanLogByShift.FirstOrDefault() }); if (preTamScanLog.TimeLog.Value.Date == date.Date && listTest != null && listTest.Count() >= 2 && !listTest.Any(d => d.TimeLog.HasValue && d.TimeLog.Value.Date < date.Date)) { if (isFromShift2) { workday.InTime2 = preTamScanLog.TimeLog; workday.OutTime2 = timeLog; } else { workday.InTime1 = preTamScanLog.TimeLog; workday.OutTime1 = timeLog; } workday.FirstInTime = !workday.FirstInTime.HasValue || workday.FirstInTime > preTamScanLog.TimeLog ? preTamScanLog.TimeLog : workday.FirstInTime; workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < timeLog ? timeLog : workday.LastOutTime; workday.Type = WorkdayType.E_WRONG_SHIFT.ToString(); preTamScanLog.Checked = true; } else { actualShiftID = null; } } } #endregion #region Tìm quẹt thẻ phía sau if (workday.Type == WorkdayType.E_MISS_OUT.ToString() || string.IsNullOrWhiteSpace(workday.Type)) { if (string.IsNullOrWhiteSpace(workday.Type)) { //1 dòng quẹt thẻ rơi vào nửa sau của ca workday.Type = WorkdayType.E_MISS_IN.ToString(); if (isFromShift2) { workday.OutTime2 = timeLog; } else { workday.OutTime1 = timeLog; } } //Quẹt thẻ gần với thời gian ra của ca -> miss-in hoặc làm sai ca //Tìm ca làm việc tiếp theo gần nhất và dòng quẹt thẻ tiếp theo gần nhất của nhân viên đang xét var nextShift = listMonthShifts.Where(d => d.Key > date && d.Key <= date.AddDays(1)).OrderBy(d => d.Key).FirstOrDefault(); var nextShiftValue = nextShift.Value != null && nextShift.Value.Count() > 0 ? nextShift.Value.FirstOrDefault() : null; //Lấy dòng quẹt thẻ hiện tại và 2 dòng quẹt thẻ tiếp theo gần nhất của nhân viên đang xét để kiểm tra ca tiếp theo var listNextTamScanLog = listTamScanLogByCardCodeUnchecked.Where(d => d.TimeLog >= timeLog).OrderBy(d => d.TimeLog).Take(3).ToList(); var listTamScanLogByNextShift = GetTamScanLogByShift(nextShift.Key, listShift, nextShiftValue, listMonthShifts, listNextTamScanLog.ToArray()); //Nếu 2 dòng quẹt thẻ tiếp theo không thuộc một ca khác trong lịch của nhân viên if (listTamScanLogByNextShift == null || listTamScanLogByNextShift.Count() < 2) { var nextTamScanLog = listNextTamScanLog.Where(d => d.TimeLog > timeLog).FirstOrDefault(); var currentShiftDuration = shiftInfo.MinIn + shiftInfo.CoOut + shiftInfo.MaxOut; //Nếu quẹt thẻ hiện tại kết với quẹt thẻ tiếp theo mà phù hợp duration thì ghép sai ca if (nextTamScanLog != null && nextTamScanLog.TimeLog.HasValue && nextTamScanLog .TimeLog.Value.Subtract(timeLog.Value).TotalHours <= currentShiftDuration) { //Trường hợp wrong-shift và detected-shift thì phải check lại actualShiftID actualShiftID = GetDetectedShiftID(timeLog, nextTamScanLog.TimeLog, listShift, null); var listTest = GetTamScanLogByShift(timeLog.Value.Date, listShift, actualShiftID, listMonthShifts, new Att_TAMScanLogEntity[] { listTamScanLogByShift.FirstOrDefault(), nextTamScanLog }); if (timeLog.Value.Date == date.Date && listTest != null && listTest.Count() >= 2 && !listTest.Any(d => d.TimeLog.HasValue && d.TimeLog.Value.Date < date.Date)) { if (isFromShift2) { workday.InTime1 = timeLog; workday.OutTime1 = nextTamScanLog.TimeLog; } else { workday.InTime1 = timeLog; workday.OutTime1 = nextTamScanLog.TimeLog; } workday.FirstInTime = !workday.FirstInTime.HasValue || workday.FirstInTime > timeLog ? timeLog : workday.FirstInTime; workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < nextTamScanLog.TimeLog ? nextTamScanLog.TimeLog : workday.LastOutTime; workday.Type = WorkdayType.E_WRONG_SHIFT.ToString(); nextTamScanLog.Checked = true; } else { actualShiftID = null; } } } } #endregion } else { if (IsInTime(date, timeLog, shiftInfo)) { if (isFromShift2) { workday.InTime2 = timeLog; } else { workday.InTime1 = timeLog; } workday.Type = WorkdayType.E_MISS_OUT.ToString(); } else { if (isFromShift2) { workday.OutTime2 = timeLog; } else { workday.OutTime1 = timeLog; } workday.Type = WorkdayType.E_MISS_IN.ToString(); } } } #endregion } else { #region Trường hợp không có dòng quẹt thẻ thuộc ca đang xét var listTamScanLogByDate = listTamScanLogByCardCodeUnchecked.Where(d => d.TimeLog.Value.Date == date).ToList(); var shiftInTime = date.Add(shiftInfo.InTime.TimeOfDay); var listTimeLog = new List<Att_TAMScanLogEntity>(); bool isWrongShiftDetected = false; foreach (var item in listTamScanLogByDate) { if (item.TimeLog < shiftInTime) { //Quẹt thẻ gần với thời gian vào của ca -> miss-out hoặc làm sai ca //Tìm ca làm việc trước gần nhất và dòng quẹt thẻ trước gần nhất của nhân viên đang xét var preShift = listMonthShifts.Where(d => d.Key >= date.AddDays(-1) && d.Key < date).OrderByDescending(d => d.Key).FirstOrDefault(); var preShiftValue = preShift.Value != null && preShift.Value.Count() > 0 ? preShift.Value.LastOrDefault() : null; //Lấy dòng quẹt thẻ hiện tại và 2 dòng quẹt thẻ phía trước gần nhất của nhân viên đang xét để kiểm tra ca trước var listPreTamScanLog = listTamScanLogByCardCode.Where(d => d.TimeLog <= item.TimeLog).OrderByDescending(d => d.TimeLog).Take(3).ToList(); var listTamScanLogByPreShift = GetTamScanLogByShift(preShift.Key, listShift, preShiftValue, listMonthShifts, listPreTamScanLog.ToArray()); //Nếu 2 dòng quẹt thẻ phía trước không thuộc một ca khác trong lịch của nhân viên if (listTamScanLogByPreShift == null || listTamScanLogByPreShift.Count() < 2) { var preTamScanLog = listPreTamScanLog.Where(d => d.TimeLog < item.TimeLog).FirstOrDefault(); var currentShiftDuration = shiftInfo.MinIn + shiftInfo.CoOut + shiftInfo.MaxOut; if (preTamScanLog != null && listWorkday.Any(d => d.ProfileID == profile.ID && (d.InTime1 == preTamScanLog.TimeLog || d.InTime2 == preTamScanLog.TimeLog || d.InTime3 == preTamScanLog.TimeLog || d.InTime4 == preTamScanLog.TimeLog || d.OutTime1 == preTamScanLog.TimeLog || d.OutTime2 == preTamScanLog.TimeLog || d.OutTime3 == preTamScanLog.TimeLog || d.OutTime4 == preTamScanLog.TimeLog))) { //Trường hợp quẹt thẻ này đã sử dụng preTamScanLog = null; } //Nếu quẹt thẻ hiện tại kết với quẹt thẻ trước đó mà phù hợp duration thì ghép sai ca if (preTamScanLog != null && preTamScanLog.TimeLog.HasValue && item.TimeLog.Value .Subtract(preTamScanLog.TimeLog.Value).TotalHours <= currentShiftDuration) { //Trường hợp wrong-shift và detected-shift thì phải check lại actualShiftID actualShiftID = GetDetectedShiftID(preTamScanLog.TimeLog, item.TimeLog, listShift, null); var listTest = GetTamScanLogByShift(preTamScanLog.TimeLog.Value.Date, listShift, actualShiftID, listMonthShifts, new Att_TAMScanLogEntity[] { preTamScanLog, item }); if (preTamScanLog.TimeLog.Value.Date == date.Date && listTest != null && listTest.Count() >= 2 && listTest.Any(d => d.TimeLog.HasValue && d.TimeLog.Value.Date < date.Date)) { if (isFromShift2) { workday.InTime2 = preTamScanLog.TimeLog; workday.OutTime2 = item.TimeLog; } else { workday.InTime1 = preTamScanLog.TimeLog; workday.OutTime1 = item.TimeLog; } workday.FirstInTime = !workday.FirstInTime.HasValue || workday.FirstInTime > preTamScanLog.TimeLog ? preTamScanLog.TimeLog : workday.FirstInTime; workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < item.TimeLog ? item.TimeLog : workday.LastOutTime; workday.Type = WorkdayType.E_WRONG_SHIFT.ToString(); preTamScanLog.Checked = true; isWrongShiftDetected = true; break;//chỉ hỗ trợ 1 ca } else { actualShiftID = null; } } else { listTimeLog.Add(item); } } else { if (!listTamScanLogByPreShift.Any(d => d.TimeLog == item.TimeLog)) { listTimeLog.Add(item); } listTimeLog = listTimeLog.Where(d => !listTamScanLogByPreShift.Contains(d)).ToList(); } } else if (item.TimeLog > shiftInTime) { //Quẹt thẻ gần với thời gian ra của ca -> miss-in hoặc làm sai ca //Tìm ca làm việc tiếp theo gần nhất và dòng quẹt thẻ tiếp theo gần nhất của nhân viên đang xét var nextShift = listMonthShifts.Where(d => d.Key > date && d.Key <= date.AddDays(1)).OrderBy(d => d.Key).FirstOrDefault(); var nextShiftValue = nextShift.Value != null && nextShift.Value.Count() > 0 ? nextShift.Value.FirstOrDefault() : null; //Lấy dòng quẹt thẻ hiện tại và 2 dòng quẹt thẻ tiếp theo gần nhất của nhân viên đang xét để kiểm tra ca tiếp theo var listNextTamScanLog = listTamScanLogByCardCodeUnchecked.Where(d => d.TimeLog >= item.TimeLog).OrderBy(d => d.TimeLog).Take(3).ToList(); var listTamScanLogByNextShift = GetTamScanLogByShift(nextShift.Key, listShift, nextShiftValue, listMonthShifts, listNextTamScanLog.ToArray()); //Nếu 2 dòng quẹt thẻ tiếp theo không thuộc một ca khác trong lịch của nhân viên if (listTamScanLogByNextShift == null || listTamScanLogByNextShift.Count() < 2) { var nextTamScanLog = listNextTamScanLog.Where(d => d.TimeLog > item.TimeLog).FirstOrDefault(); var currentShiftDuration = shiftInfo.MinIn + shiftInfo.CoOut + shiftInfo.MaxOut; //Nếu quẹt thẻ hiện tại kết với quẹt thẻ tiếp theo mà phù hợp duration thì ghép sai ca if (nextTamScanLog != null && nextTamScanLog.TimeLog.HasValue && nextTamScanLog .TimeLog.Value.Subtract(item.TimeLog.Value).TotalHours <= currentShiftDuration) { //Trường hợp wrong-shift và detected-shift thì phải check lại actualShiftID actualShiftID = GetDetectedShiftID(item.TimeLog, nextTamScanLog.TimeLog, listShift, null); var listTest = GetTamScanLogByShift(item.TimeLog.Value.Date, listShift, actualShiftID, listMonthShifts, new Att_TAMScanLogEntity[] { item, nextTamScanLog }); if (item.TimeLog.Value.Date == date.Date && listTest != null && listTest.Count() >= 2 && listTest.Any(d => d.TimeLog.HasValue && d.TimeLog.Value.Date < date.Date)) { if (isFromShift2) { workday.InTime2 = item.TimeLog; workday.OutTime2 = nextTamScanLog.TimeLog; } else { workday.InTime1 = item.TimeLog; workday.OutTime1 = nextTamScanLog.TimeLog; } workday.FirstInTime = !workday.FirstInTime.HasValue || workday.FirstInTime > item.TimeLog ? item.TimeLog : workday.FirstInTime; workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < nextTamScanLog.TimeLog ? nextTamScanLog.TimeLog : workday.LastOutTime; workday.Type = WorkdayType.E_WRONG_SHIFT.ToString(); nextTamScanLog.Checked = true; isWrongShiftDetected = true; break;//chỉ hỗ trợ 1 ca } else { actualShiftID = null; } } else { listTimeLog.Add(item); } } else { if (!listTamScanLogByNextShift.Any(d => d.TimeLog == item.TimeLog)) { listTimeLog.Add(item); } listTimeLog = listTimeLog.Where(d => !listTamScanLogByNextShift.Contains(d)).ToList(); } } } if (!isWrongShiftDetected) { var listRemove = new List<Att_TAMScanLogEntity>(); if (listTimeLog.Count() >= 2) { var currentShiftDuration = shiftInfo.MinIn + shiftInfo.CoOut + shiftInfo.MaxOut; var timeLog1 = listTimeLog.OrderBy(d => d.TimeLog).FirstOrDefault(); var timeLog2 = listTimeLog.OrderBy(d => d.TimeLog).LastOrDefault(); if (isFromShift2) { workday.InTime2 = timeLog1.TimeLog; workday.OutTime2 = timeLog2.TimeLog; } else { workday.InTime1 = timeLog1.TimeLog; workday.OutTime1 = timeLog2.TimeLog; } workday.FirstInTime = !workday.FirstInTime.HasValue || workday.FirstInTime > timeLog1.TimeLog ? timeLog1.TimeLog : workday.FirstInTime; workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < timeLog2.TimeLog ? timeLog2.TimeLog : workday.LastOutTime; isWrongShiftDetected = true; if (timeLog2.TimeLog.HasValue && timeLog1.TimeLog.HasValue && timeLog2.TimeLog.Value .Subtract(timeLog1.TimeLog.Value).TotalHours <= currentShiftDuration) { //Trường hợp wrong-shift và detected-shift thì phải check lại actualShiftID actualShiftID = GetDetectedShiftID(timeLog1.TimeLog, timeLog2.TimeLog, listShift, null); var listTest = GetTamScanLogByShift(timeLog1.TimeLog.Value.Date, listShift, actualShiftID, listMonthShifts, new Att_TAMScanLogEntity[] { timeLog1, timeLog2 }); if (listTest != null && listTest.Count() >= 2 && listTest.Any(d => d.TimeLog.HasValue && d.TimeLog.Value.Date < date.Date)) { workday.Type = WorkdayType.E_WRONG_SHIFT.ToString(); } else { workday.Type = WorkdayType.E_LONGIN_SHIFT.ToString(); } } else { foreach (var item in listTimeLog.Where(d => d.TimeLog > timeLog1.TimeLog).OrderByDescending(d => d.TimeLog)) { if (isFromShift2) { workday.OutTime2 = item.TimeLog; } else { workday.OutTime1 = item.TimeLog; } workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < item.TimeLog ? item.TimeLog : workday.LastOutTime; if (item.TimeLog > timeLog1.TimeLog && item.TimeLog.HasValue && timeLog1.TimeLog.HasValue && item.TimeLog.Value.Subtract(timeLog1.TimeLog.Value).TotalHours <= currentShiftDuration) { workday.Type = WorkdayType.E_DETECTED_SHIFT.ToString(); break; } else { workday.Type = WorkdayType.E_LONGIN_SHIFT.ToString(); } } listRemove = listTimeLog.Where(d => d.TimeLog > workday.LastOutTime).ToList(); } } else if (listTimeLog.Count() == 1) { if (listTimeLog.Any(d => d.TimeLog < shiftInTime)) { var inTimeValue = listTimeLog.Select(d => d.TimeLog).FirstOrDefault(); if (isFromShift2) { workday.InTime2 = inTimeValue; } else { workday.InTime1 = inTimeValue; } workday.FirstInTime = !workday.FirstInTime.HasValue || workday.FirstInTime > inTimeValue ? inTimeValue : workday.FirstInTime; workday.Type = WorkdayType.E_MISS_OUT.ToString();//miss-in hay miss-out cũng như nhau } else { var outTimeValue = listTimeLog.Select(d => d.TimeLog).FirstOrDefault(); if (isFromShift2) { workday.OutTime2 = outTimeValue; } else { workday.OutTime1 = outTimeValue; } workday.LastOutTime = !workday.LastOutTime.HasValue || workday.LastOutTime < outTimeValue ? outTimeValue : workday.LastOutTime; workday.Type = WorkdayType.E_MISS_IN.ToString();//miss-in hay miss-out cũng như nhau } isWrongShiftDetected = true; } listTimeLog.Where(d => !listRemove.Contains(d)).ToList().ForEach(d => d.Checked = true); } if (!isWrongShiftDetected) { if (listHoliday.Any(d => d.DateOff.Date == date.Date)) { //Có ca mà không inout thì xem có phải holiday workday.Type = WorkdayType.E_HOLIDAY.ToString(); } else { workday.Type = WorkdayType.E_MISS_IN_OUT.ToString(); } } #endregion } } else if (inOutConfig.TypeLoadData == TypeLoadData.E_TYPEINOUT.ToString()) { //Xử lý cho các loại khác } return workday; #endregion }
private bool IsInTime(DateTime date, DateTime? timeLog, Cat_Shift shiftInfo) { bool result = true; if (timeLog.HasValue && shiftInfo != null) { DateTime inTime = date.Date.Add(shiftInfo.InTime.TimeOfDay); DateTime outTime = inTime.AddHours(shiftInfo.CoOut); double inMinutes = timeLog.Value.Subtract(inTime).TotalMinutes; double outMinutes = timeLog.Value.Subtract(outTime).TotalMinutes; result = VnResource.Helper.Data.DataHelper.GetPositiveDouble(inMinutes) <= VnResource.Helper.Data.DataHelper.GetPositiveDouble(outMinutes); } return result; }