public Att_LeaveDayModel Post([Bind]Att_LeaveDayModel model) { Att_LeavedayServices services = new Att_LeavedayServices(); model.ActionStatus = services.UpdateTotalDuration(model.lstLeaveIDs); return model; }
public List<Sal_HoldSalaryEntity> ComputeHoldSalary(Guid? cutOffDurationID, Guid[] ProfileIDs, string orgStructureID, Guid TimeAnalyze, string userLoginName) { using (var context = new VnrHrmDataContext()) { #region Get Data string status = string.Empty; List<Sal_HoldSalaryEntity> lstHoldSalaryEntity = new List<Sal_HoldSalaryEntity>(); //ds kỳ công var cutOffServies = new Att_CutOffDurationServices(); var lstObjCutOff = new List<object>(); lstObjCutOff.Add(null); lstObjCutOff.Add(1); lstObjCutOff.Add(int.MaxValue - 1); var lstCutOff = cutOffServies.GetData<Att_CutOffDurationEntity>(Common.DotNetToOracle(cutOffDurationID.Value.ToString()), ConstantSql.hrm_att_sp_get_CutOffDurationById, userLoginName, ref status).FirstOrDefault(); //ds nv var hrService = new Hre_ProfileServices(); List<object> strOrgIDs = new List<object>(); strOrgIDs.AddRange(new object[3]); strOrgIDs[0] = (object)orgStructureID; var lstProfile = hrService.GetData<Hre_ProfileEntity>(strOrgIDs, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, userLoginName, ref status); if (ProfileIDs != null) { lstProfile = lstProfile.Where(s => ProfileIDs.Contains(s.ID)).ToList(); } //ds ngày nghỉ var leaveDayServices = new Att_LeavedayServices(); var lstObjLeaveDay = new List<object>(); lstObjLeaveDay.AddRange(new object[11]); lstObjLeaveDay[4] = lstCutOff.DateStart; lstObjLeaveDay[5] = lstCutOff.DateEnd; lstObjLeaveDay[9] = 1; lstObjLeaveDay[10] = int.MaxValue - 1; var lstLeaveDay = leaveDayServices.GetData<Att_LeaveDayEntity>(lstObjLeaveDay, ConstantSql.hrm_att_sp_get_Leaveday,userLoginName, ref status); //ds loại ngày nghỉ var leavedayTypeServices = new Cat_LeaveDayTypeServices(); var lstObjLeavedayType = new List<object>(); lstObjLeavedayType.Add(null); lstObjLeavedayType.Add(null); lstObjLeavedayType.Add(1); lstObjLeavedayType.Add(int.MaxValue - 1); var lstLeavedayType = leavedayTypeServices.GetData<Cat_LeaveDayTypeEntity>(lstObjLeavedayType, ConstantSql.hrm_cat_sp_get_LeaveDayType,userLoginName, ref status); lstObjLeavedayType = new List<object>(); lstObjLeavedayType.Add(null); lstObjLeavedayType.Add(EnumDropDown.EntityType.E_CountAnalyzeHoldSalary.ToString()); lstObjLeavedayType.Add(1); lstObjLeavedayType.Add(int.MaxValue - 1); var ListNameEntity = leavedayTypeServices.GetData<Cat_NameEntityEntity>(lstObjLeavedayType, ConstantSql.hrm_cat_sp_get_NameEntityByKPI,userLoginName, ref status); ////ds chế độ lương //var Sal_GradeServices = new Sal_GradeServices(); //var lstObjSal_Grade = new List<object>(); //lstObjSal_Grade.AddRange(new object[7]); //lstObjSal_Grade[3] = lstCutOff.DateStart; //lstObjSal_Grade[4] = lstCutOff.DateEnd;//sửa lại store lấy lên tất cả các grade mà ko có ngày kết thúc //lstObjSal_Grade[5] = 1; //lstObjSal_Grade[6] = int.MaxValue - 1; //var lstSal_Grade = Sal_GradeServices.GetData<Sal_GradeEntity>(lstObjSal_Grade, ConstantSql.hrm_sal_sp_get_Sal_Grade, ref status).ToList(); Sys_AttOvertimePermitConfigServices Sys_Services = new Sys_AttOvertimePermitConfigServices(); double DATECLOSE_SALARY = Sys_Services.GetConfigValue<double>(AppConfig.HRM_SAL_DATECLOSE_SALARY); foreach (var profile in lstProfile) { Sal_HoldSalaryEntity entity = new Sal_HoldSalaryEntity(); entity.ProfileID = profile.ID; entity.CodeEmp = profile.CodeEmp; entity.ProfileName = profile.ProfileName; entity.CodeAttendance = profile.CodeAttendance; entity.EmployeeTypeName = profile.EmployeeTypeName; entity.WorkPlaceName = profile.WorkPlaceName; entity.IDNo = profile.IDNo; entity.MonthSalary = lstCutOff.MonthYear; entity.TimeAnalyzeID = TimeAnalyze; entity.CatNameEntity = ListNameEntity.FirstOrDefault(m => m.ID == TimeAnalyze) != null ? ListNameEntity.FirstOrDefault(m => m.ID == TimeAnalyze).NameEntityName : ""; var lstLeavedayByProfileID = lstLeaveDay.Where(s => profile.ID == s.ProfileID).ToList(); #region NV Nghỉ việc trước ngày 18 if (profile.DateQuit != null) { if (profile.DateQuit.Value <= lstCutOff.DateEnd && profile.IsSettlement != true) { //if (profile.DateQuit.Value.Day <= 18) //{ entity.Terminate = true; lstHoldSalaryEntity.Add(entity); continue; //} } } #endregion #region kiểm tra nghỉ quá 12 ngày if (lstLeavedayByProfileID.Count > 0) { var lstLeavedayTypeBy12 = lstLeavedayType.Where(m => m.Code == "SP" || m.Code == "SC" || m.Code == "DSP" || m.Code == "DL" || m.Code == "M").ToList(); var _tmp = lstLeavedayByProfileID.Where(m => !lstLeavedayTypeBy12.Any(t => t.ID == m.LeaveDayTypeID)).ToList(); double count = 0; foreach (var i in _tmp) { count += i.LeaveDays != null ? (double)i.LeaveDays : 0; } if (count >= 12) { entity.DayLeave = (int)count; lstHoldSalaryEntity.Add(entity); continue; } } #endregion #region trường hợp đăng ký thai sản trước ngày 18 if (lstLeavedayByProfileID.Count > 0) { var lstLeavedayTypeBy12 = lstLeavedayType.Where(m => m.Code == "M").ToList(); var _tmp = lstLeavedayByProfileID.FirstOrDefault(m => lstLeavedayTypeBy12.Any(t => t.ID == m.LeaveDayTypeID) && m.DateStart.Day < 18); if (_tmp != null) { entity.IsLeaveM = true; lstHoldSalaryEntity.Add(entity); continue; } } #endregion #region Nghỉ liên tục 3 ngày if (lstLeavedayByProfileID.Count > 0) { var lstLeavedayTypeBy3 = lstLeavedayType.Where(m => m.Code == "D").ToList(); //lấy ngày nghỉ theo loại ngày nghỉ D var lstLeavedayByProfileID3 = lstLeavedayByProfileID.Where(m => lstLeavedayTypeBy3.Any(t => t.ID == m.LeaveDayTypeID)).ToList(); lstLeavedayByProfileID3 = lstLeavedayByProfileID3.Where(m => m.DateEnd.Day <= DATECLOSE_SALARY).ToList(); double count = 0; //còn 1 bug đó là khi đăng ký 3 dòng liền kế ngày nhau foreach (var i in lstLeavedayByProfileID3) { count = i.LeaveDays != null ? (double)i.LeaveDays : 0; if (count >= 3) { entity.IsLeaveContinuous = true; break; } } if (entity.IsLeaveContinuous != null && entity.IsLeaveContinuous == true) { lstHoldSalaryEntity.Add(entity); continue; } } #endregion } return lstHoldSalaryEntity; #endregion } }
public Att_LeaveDayModel Post([Bind]Att_LeaveDayModel model) { string status = ""; string message = string.Empty; //truong hop edit 1 nhan vien if (model.ProfileID != Guid.Empty) { model.ProfileIds = model.ProfileID.ToString(); } BaseService baseService = new BaseService(); List<Guid> lstProfileIDs = new List<Guid>(); #region Xu ly lay lst nhan vien cuoi cung //xu ly chon nhan vien hay chon phong ban if (!string.IsNullOrEmpty(model.ProfileIds)) { List<Guid> lstMulti = new List<Guid>(); var lst = model.ProfileIds.Split(','); foreach (var item in lst) { Guid _Id = new Guid(item); lstMulti.Add(_Id); } lstProfileIDs = lstMulti; } else { if (model.strOrgStructureIDs == "") { model.strOrgStructureIDs = null; } List<object> lstObj = new List<object>(); lstObj.Add(model.strOrgStructureIDs); lstObj.Add(null); lstObj.Add(null); List<Hre_ProfileEntity> lstOrg = baseService.GetData<Hre_ProfileEntity>(lstObj, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, UserLogin, ref status).ToList(); lstProfileIDs = lstOrg.Select(d => d.ID).ToList(); //neu co loai tru if(!string.IsNullOrEmpty(model.ProfileIDsExclude) && lstProfileIDs.Count>0) { List<Guid> lstProfileIDsExclude = new List<Guid>(); var lst = model.ProfileIDsExclude.Split(','); foreach (var item in lst) { Guid _Id = new Guid(item); lstProfileIDsExclude.Add(_Id); } lstProfileIDs = lstProfileIDs.Where(d => !lstProfileIDsExclude.Contains(d)).ToList(); } } if (lstProfileIDs.Count()==0) { message = string.Format(ConstantMessages.FieldNotAllowNull.TranslateString(), ("ProfileID").TranslateString()); model.ActionStatus = message; return model; } #endregion if (model.HoursFrom != null) { model.DateStart = new DateTime(model.DateStart.Year, model.DateStart.Month, model.DateStart.Day, model.HoursFrom.Value.Hour, model.HoursFrom.Value.Minute, 0); } if (model.HoursTo != null) { model.DateEnd = new DateTime(model.DateStart.Year, model.DateStart.Month, model.DateStart.Day, model.HoursTo.Value.Hour, model.HoursTo.Value.Minute, 0); } #region Validate var checkValidate = true; if(model.IsPortal ==true) { checkValidate = HRM.Business.Main.Domain.ValidatorService.OnValidateData<Att_LeaveDayModel>(model, "Att_LeaveDayPortal", ref message); } else { checkValidate = HRM.Business.Main.Domain.ValidatorService.OnValidateData<Att_LeaveDayModel>(model, "Att_LeaveDay", ref message); } if (!checkValidate) { model.ActionStatus = message; return model; } if (model.LeaveDays == 0 && model.LeaveHours == 0) { model.ActionStatus = ConstantMessages.AccessDenied.TranslateString(); return model; } #endregion //TimeSpan ts = new TimeSpan(model.HoursFrom.Value.Hour, model.HoursFrom.Value.Minute, 0); //model.DateStart = model.DateStart + ts; if (model.DurationType != LeaveDayDurationType.E_FULLSHIFT.ToString()) { if (model.HoursFrom.HasValue) model.DateStart = new DateTime(model.DateStart.Year, model.DateStart.Month, model.DateStart.Day, model.HoursFrom.Value.Hour, model.HoursFrom.Value.Minute, model.HoursFrom.Value.Second); if (model.HoursTo.HasValue) model.DateEnd = new DateTime(model.DateEnd.Year, model.DateEnd.Month, model.DateEnd.Day, model.HoursTo.Value.Hour, model.HoursTo.Value.Minute, model.HoursTo.Value.Second); if (model.DurationType == LeaveDayDurationType.E_FIRSTHALFSHIFT.ToString() || model.DurationType == LeaveDayDurationType.E_LASTHALFSHIFT.ToString()) { model.LeaveDays = 0.5; } } ActionService service = new ActionService(UserLogin); List<object> lstobject = new List<object>(); lstobject.AddRange(new object[11]); //lstobject[4] = DateTime.MinValue; //DateFrom //lstobject[5] = DateTime.MaxValue; //DateTo lstobject[9] = 1; //lstobject[10] = int.MaxValue; lstobject[10] = Int32.MaxValue - 1; string strMessages = ""; var _catLeaveDay = new Att_LeavedayServices(); List<Att_LeaveDayEntity> lstLeaveDayInDbUpdate = _catLeaveDay.GetData<Att_LeaveDayEntity>(lstobject, ConstantSql.hrm_att_sp_get_Leaveday, UserLogin, ref status); #region [Hien.Nguyen] - Kiểm tra trùng khi đăng kí cùng một ngày và cùng loại ngày nghỉ //if (lstLeaveDayInDbUpdate != null) //{ // if (model.ID == Guid.Empty) // { // if (lstLeaveDayInDbUpdate.Any(m => m.ProfileID == model.ProfileID && m.DateStart <= model.DateEnd && m.DateEnd >= model.DateStart && m.LeaveDayTypeID == model.LeaveDayTypeID)) // { // model.SetPropertyValue(Constant.ActionStatus, NotificationType.Error + "," + strMessages + ConstantMessages.FieldDuplicate); // return model; // } // } // else // { // var leaveDay = _catLeaveDay.GetData<Att_LeaveDayEntity>(model.ID, ConstantSql.hrm_att_sp_get_LeaveDayById, ref status).FirstOrDefault(); // if (leaveDay != null) // { // if (leaveDay.LeaveDayTypeID != model.LeaveDayTypeID || leaveDay.DateStart != model.DateStart || leaveDay.DateEnd != model.DateEnd || leaveDay.ProfileID != model.ProfileID) // { // if (lstLeaveDayInDbUpdate.Any(m => m.ProfileID == model.ProfileID && m.DateStart <= model.DateEnd && m.DateEnd >= model.DateStart && m.LeaveDayTypeID == model.LeaveDayTypeID)) // { // model.SetPropertyValue(Constant.ActionStatus, NotificationType.Error + "," + strMessages + ConstantMessages.FieldDuplicate); // return model; // } // } // } // } //} #endregion #region Kiểm tra đăng ký trùng 1 ngày chỉ 1 loại ngày nghỉ nếu là Loại Toàn Ca, Còn lại thì 2 loại ngày nghỉ if (model.ID != Guid.Empty)//nếu là chỉnh sửa thì loại bỏ dòng đó ra khỏi list tổng { lstLeaveDayInDbUpdate = lstLeaveDayInDbUpdate.Where(m => m.ID != model.ID).ToList(); } if (model.DurationType == LeaveDayDurationType.E_FULLSHIFT.ToString())//Toàn ca chỉ được dk 1 dòng { if (lstLeaveDayInDbUpdate.Any(m => lstProfileIDs.Contains(m.ProfileID) && m.DateStart <= model.DateEnd && m.DateEnd >= model.DateStart)) { //model.SetPropertyValue(Constant.ActionStatus, NotificationType.Error + "," + strMessages + ConstantMessages.FieldDuplicate); model.SetPropertyValue(Constant.ActionStatus, NotificationType.Error + "," + string.Format(ConstantMessages.FieldDuplicate.TranslateString(), ConstantDisplay.HRM_Evaluation_Information.TranslateString())); return model; } } else//Ngược lại thì đk 2 dòng { if (lstLeaveDayInDbUpdate.Any(m => lstProfileIDs.Contains(m.ProfileID) && m.DateStart <= model.DateEnd && m.DateEnd >= model.DateStart && m.DurationType == LeaveDayDurationType.E_FULLSHIFT.ToString())) { // model.SetPropertyValue(Constant.ActionStatus, NotificationType.Error + "," + strMessages + ConstantMessages.FieldDuplicate); model.SetPropertyValue(Constant.ActionStatus, NotificationType.Error + "," + string.Format(ConstantMessages.FieldDuplicate.TranslateString(), ConstantDisplay.HRM_Evaluation_Information.TranslateString())); return model; } else if (lstLeaveDayInDbUpdate.Where(m => lstProfileIDs.Contains(m.ProfileID) && m.DateStart <= model.DateEnd && m.DateEnd >= model.DateStart && m.DurationType != LeaveDayDurationType.E_FULLSHIFT.ToString()).Count() > 1) { // model.SetPropertyValue(Constant.ActionStatus, NotificationType.Error + "," + strMessages + ConstantMessages.FieldDuplicate); model.SetPropertyValue(Constant.ActionStatus, NotificationType.Error + "," + string.Format(ConstantMessages.FieldDuplicate.TranslateString(), ConstantDisplay.HRM_Evaluation_Information.TranslateString())); return model; } } #endregion #region Triet.Mai Kiểm tra vượt giới hạn cho 1 tháng //string[] ProfileArr = model.ProfileIds.Split(','); //List<Guid> lstProfileID = new List<Guid>(); //foreach (var item in lstProfileIDs) //{ // Guid ProfileID = item; // //Guid.TryParse(item, out ProfileID); // if (ProfileID != Guid.Empty) // lstProfileID.Add(ProfileID); //} var LeaveDayEntity = model.CopyData<Att_LeaveDayEntity>(); string Error = (new Att_LeavedayServices()).ValidateOverDayInMonth(LeaveDayEntity, lstProfileIDs); if (Error != string.Empty) { model.SetPropertyValue(Constant.ActionStatus, Error); return model; } #endregion List<Att_LeaveDayEntity> lstSM = new List<Att_LeaveDayEntity>(); Att_ProcessApprovedServices smService = new Att_ProcessApprovedServices(); if (!string.IsNullOrEmpty(model.ProfileIds)) { //string[] arrProfileIds = model.ProfileIds.Split(','); strMessages = ""; if (strMessages != "") { // model.SetPropertyValue(Constant.ActionStatus, NotificationType.Error + "," + strMessages + ConstantMessages.FieldDuplicate); model.SetPropertyValue(Constant.ActionStatus, NotificationType.Error + "," + string.Format(ConstantMessages.FieldDuplicate.TranslateString(), ConstantDisplay.HRM_Evaluation_Information.TranslateString())); return model; } else { var leavedayTypeServices = new Cat_LeaveDayTypeServices(); var lstLeavedayType = leavedayTypeServices.GetData<Cat_LeaveDayTypeEntity>(model.LeaveDayTypeID, ConstantSql.hrm_cat_sp_get_LeaveDayTypeById, UserLogin, ref status).FirstOrDefault(); if (lstProfileIDs.Count()==1) { var guiId = lstProfileIDs[0]; Att_LeaveDayModel modelSave = model.CopyData<Att_LeaveDayModel>(); modelSave.ProfileID = guiId; #region Kiểm tra Tổng Số Ngày Nghỉ if (lstLeavedayType != null) { if (model.LeaveDays > lstLeavedayType.MaxPerTimes) { modelSave.ActionStatus = "ErrorTotalLeave"; return modelSave; } if (model.LeaveDays > lstLeavedayType.MaxPerYear) { modelSave.ActionStatus = "ErrorTotalLeave"; return modelSave; } } #endregion modelSave = service.UpdateOrCreate<Att_LeaveDayEntity, Att_LeaveDayModel>(modelSave); if (modelSave.ActionStatus == NotificationType.Success.ToString()) { lstSM.Add(modelSave.Copy<Att_LeaveDayEntity>()); } smService.GetEmailToSend_LeaveDay(lstSM, UserLogin); return modelSave; } foreach (var ProfileId in lstProfileIDs) { var guiId = ProfileId; Att_LeaveDayModel modelSave = model.CopyData<Att_LeaveDayModel>(); modelSave.ProfileID = guiId; #region Kiểm tra Tổng Số Ngày Nghỉ if (lstLeavedayType != null) { if (model.LeaveDays > lstLeavedayType.MaxPerTimes) { modelSave.ActionStatus = "ErrorTotalLeave"; return modelSave; } if (model.LeaveDays > lstLeavedayType.MaxPerYear) { modelSave.ActionStatus = "ErrorTotalLeave"; return modelSave; } } #endregion modelSave = service.UpdateOrCreate<Att_LeaveDayEntity, Att_LeaveDayModel>(modelSave); if (modelSave.ActionStatus == NotificationType.Success.ToString()) { lstSM.Add(modelSave.Copy<Att_LeaveDayEntity>()); } else { smService.GetEmailToSend_LeaveDay(lstSM, UserLogin); return modelSave; } } } smService.GetEmailToSend_LeaveDay(lstSM, UserLogin); model.SetPropertyValue(Constant.ActionStatus, NotificationType.Success.ToString()); return model; } else { //Đã kiểm tra ở trên , nên không cần kt dưới này - [hien.nguyen] //if (lstLeaveDayInDbUpdate != null && lstLeaveDayInDbUpdate.Any(d => d.ID != model.ID && d.ProfileID == model.ProfileID && d.DateStart <= model.DateEnd && d.DateEnd >= model.DateStart)) //{ // strMessages = lstLeaveDayInDbUpdate.Where(d => d.ProfileID == model.ProfileID).FirstOrDefault().ProfileName; // model.SetPropertyValue(Constant.ActionStatus, NotificationType.Error + "," + strMessages + ConstantMessages.FieldDuplicate); // return model; //} //else model = service.UpdateOrCreate<Att_LeaveDayEntity, Att_LeaveDayModel>(model); if (model.ActionStatus == NotificationType.Success.ToString()) { lstSM.Add(model.Copy<Att_LeaveDayEntity>()); smService.GetEmailToSend_LeaveDay(lstSM, UserLogin); } return model; } }
public string SaveLeaveDay(Att_Workday Workday, string LeaveTypeCode, string UserLogin) { if (Workday == null) return string.Empty; using (var context = new VnrHrmDataContext()) { var unitOfWork = (IUnitOfWork)(new UnitOfWork(context)); var repoCat_Shift = new CustomBaseRepository<Cat_Shift>(unitOfWork); var repoCat_LeaveDayType = new CustomBaseRepository<Cat_LeaveDayType>(unitOfWork); var repoAtt_LeaveDay = new CustomBaseRepository<Att_LeaveDay>(unitOfWork); var repoHre_Profile = new CustomBaseRepository<Hre_Profile>(unitOfWork); var repoAtt_Grade = new CustomBaseRepository<Att_Grade>(unitOfWork); var repoCat_GradeAttendance = new CustomBaseRepository<Cat_GradeAttendance>(unitOfWork); var repoHre_WorkHistory = new CustomBaseRepository<Hre_WorkHistory>(unitOfWork); var repoAtt_Roster = new CustomBaseRepository<Att_Roster>(unitOfWork); var repoAtt_RosterGroup = new CustomBaseRepository<Att_RosterGroup>(unitOfWork); var repoCat_DayOff = new CustomBaseRepository<Cat_DayOff>(unitOfWork); var shifts = repoCat_Shift.FindBy(s => s.IsDelete == null).ToList(); Att_LeavedayServices leavedayServices = new Att_LeavedayServices(); LeaveTypeCode = LeaveTypeCode.Replace("...", string.Empty); Guid? ShiftID = Workday.ShiftApprove ?? Workday.ShiftID; double DurationHour = 8; var shift = repoCat_Shift.FindBy(m => m.ID == ShiftID).FirstOrDefault(); //Cat_Shift shift = EntityService.CreateQueryable<Cat_Shift>(false, GuidContext, Guid.Empty, m => m.ID == ShiftID).FirstOrDefault(); if (shift != null) DurationHour = shift.WorkHours ?? 8; var leaveType = new List<Cat_LeaveDayType>().Select(m => new { m.ID, m.Code, m.CodeStatistic }).FirstOrDefault(); if (!string.IsNullOrEmpty(LeaveTypeCode)) { leaveType = repoCat_LeaveDayType.FindBy(m => m.Code == LeaveTypeCode).Select(m => new { m.ID, m.Code, m.CodeStatistic }).FirstOrDefault(); //leaveType = EntityService.CreateQueryable<Cat_LeaveDayType>(false, GuidContext, Guid.Empty, m => m.CodeStatistic == LeaveTypeCode).Select(m => new { m.ID, m.Code, m.CodeStatistic }).FirstOrDefault(); } DateTime workday = Workday.WorkDate; DateTime beginDate = workday.Date; DateTime endDate = beginDate.AddDays(1).AddMinutes(-1); DateTime beginShift = workday.AddHours(shift.InTime.Hour).AddMinutes(shift.InTime.Minute); DateTime endShift = beginShift.AddHours(shift.CoOut); string E_APPROVED = LeaveDayStatus.E_APPROVED.ToString(); string E_REJECTED = LeaveDayStatus.E_REJECTED.ToString(); List<Att_LeaveDay> lstLeaveDayInDbUpdate = repoAtt_LeaveDay.FindBy(m => m.DateStart <= endDate && m.DateEnd >= beginDate && m.ProfileID == Workday.ProfileID && m.Status != E_REJECTED).ToList<Att_LeaveDay>(); List<Att_LeaveDay> lstLeaveDayInsert = new List<Att_LeaveDay>(); if (lstLeaveDayInDbUpdate.Count > 0) { if (!lstLeaveDayInDbUpdate.Any(m => m.Status == LeaveDayStatus.E_APPROVED.ToString())) { if (leaveType != null) { lstLeaveDayInDbUpdate.ForEach(m => m.LeaveDayTypeID = leaveType.ID); } else { lstLeaveDayInDbUpdate.ForEach(m => m.IsDelete = true); } } else lstLeaveDayInDbUpdate = new List<Att_LeaveDay>(); } else { if (leaveType != null) { Att_LeaveDay LeavedayInsert = new Att_LeaveDay(); LeavedayInsert.ID = Guid.Empty; LeavedayInsert.ProfileID = Workday.ProfileID; LeavedayInsert.TotalDuration = 1; LeavedayInsert.LeaveDays = 1; LeavedayInsert.Duration = shift.WorkHours ?? 8; LeavedayInsert.LeaveHours = shift.WorkHours ?? 8; LeavedayInsert.DurationType = LeaveDayDurationType.E_FULLSHIFT.ToString(); LeavedayInsert.DateStart = workday; LeavedayInsert.DateEnd = workday; LeavedayInsert.LeaveDayTypeID = leaveType.ID; LeavedayInsert.Status = LeaveDayStatus.E_SUBMIT.ToString(); lstLeaveDayInsert.Add(LeavedayInsert); } } //Cap nhat leavedayID cho workday o day if (lstLeaveDayInsert.Count > 0) { if (lstLeaveDayInsert.Count > 1) { Workday.LeaveDayID1 = lstLeaveDayInsert[0].ID; Workday.LeaveDayID2 = lstLeaveDayInsert[1].ID; //Workday.udLeavedayCode1 = LeaveTypeCode; //Workday.udLeavedayCode2 = LeaveTypeCode; //Workday.udLeavedayStatus1 = lstLeaveDayInsert.FirstOrDefault().Status.TranslateString(); //Workday.udLeavedayStatus2 = lstLeaveDayInsert.FirstOrDefault().Status.TranslateString(); } else { Workday.LeaveDayID1 = lstLeaveDayInsert[0].ID; //Workday.udLeavedayCode1 = LeaveTypeCode; //Workday.udLeavedayStatus1 = lstLeaveDayInsert.FirstOrDefault().Status.TranslateString(); } } //else if (lstLeaveDayInDbUpdate.Count > 0) //{ // if (lstLeaveDayInDbUpdate.Count >= 2) // { // Workday.udLeavedayCode1 = LeaveTypeCode; // Workday.udLeavedayCode2 = LeaveTypeCode; // Workday.udLeavedayStatus1 = lstLeaveDayInDbUpdate.FirstOrDefault().Status.TranslateString(); // Workday.udLeavedayStatus2 = lstLeaveDayInDbUpdate.FirstOrDefault().Status.TranslateString(); // } // else // { // Workday.udLeavedayCode1 = LeaveTypeCode; // Workday.udLeavedayStatus1 = lstLeaveDayInDbUpdate.FirstOrDefault().Status.TranslateString(); // Workday.udLeavedayStatus2 = lstLeaveDayInDbUpdate.FirstOrDefault().Status.TranslateString(); // } //} #region Triet.Mai Validate Nghỉ Bù if (lstLeaveDayInsert.Count > 0) { List<Guid> LeaveTypeDayOffID = repoCat_LeaveDayType.FindBy(m => m.IsTimeOffInLieu == true).Select(m => m.ID).ToList<Guid>(); //List<Guid> LeaveTypeDayOffID = EntityService.CreateQueryable<Cat_LeaveDayType>(false, GuidContext, Guid.Empty, m => m.IsTimeOffInLieu == true).Select(m => m.ID).ToList<Guid>(); if (lstLeaveDayInsert.FirstOrDefault().Status != OverTimeStatus.E_CANCEL.ToString() && LeaveTypeDayOffID.Any(m => m == lstLeaveDayInsert.FirstOrDefault().LeaveDayTypeID)) { string Error = leavedayServices.ValidateLeaveDayTimeOff(lstLeaveDayInsert.Select(m => m.ProfileID).Distinct().ToList(), lstLeaveDayInsert); if (Error != string.Empty) { return Error; } } } #endregion #region triet.mai validate vấn đề ngày nghỉ dành cho nhân viên thực tập string E_STANDARD_WORKDAY = AppConfig.E_STANDARD_WORKDAY.ToString(); string status = string.Empty; List<object> lstO = new List<object>(); lstO.Add(E_STANDARD_WORKDAY); lstO.Add(null); lstO.Add(null); Sys_AllSetting config = GetData<Sys_AllSetting>(lstO, ConstantSql.hrm_sys_sp_get_AllSetting, UserLogin, ref status).FirstOrDefault(); //Sys_AppConfig config = EntityService.GetEntity<Sys_AppConfig>(false, GuidContext, Guid.Empty, m => m.Info == E_STANDARD_WORKDAY); string validateEmpProbation = leavedayServices.ValidateLeaveTypeByNewEmployee(config, lstLeaveDayInsert); if (validateEmpProbation != string.Empty) { return validateEmpProbation; } #endregion #region triet.mai cap nhat leaveDays va leaveHours lstLeaveDayInsert.AddRange(lstLeaveDayInDbUpdate); if (lstLeaveDayInsert.Count > 0) { List<Cat_LeaveDayType> lstLeaveDayType = repoCat_LeaveDayType.FindBy(m => m.IsDelete == null).ToList<Cat_LeaveDayType>(); //List<Cat_LeaveDayType> lstLeaveDayType = EntityService.CreateQueryable<Cat_LeaveDayType>(false, GuidContext, Guid.Empty).ToList<Cat_LeaveDayType>(); List<Guid> lstProfileID1 = lstLeaveDayInsert.Select(m => m.ProfileID).Distinct().ToList<Guid>(); List<Hre_Profile> lstProfile = repoHre_Profile.FindBy(m => lstProfileID1.Contains(m.ID)).ToList<Hre_Profile>(); //List<Hre_Profile> lstProfile = EntityService.CreateQueryable<Hre_Profile>(false, GuidContext, Guid.Empty, m => lstProfileID1.Contains(m.ID)).ToList<Hre_Profile>(); DateTime dateMin1 = lstLeaveDayInsert.Min(m => m.DateStart).Date; DateTime dateMax1 = lstLeaveDayInsert.Max(m => m.DateEnd); List<Att_Roster> lstRosterTypeGroup = new List<Att_Roster>(); List<Att_RosterGroup> lstRosterGroup = new List<Att_RosterGroup>(); var lstGrade = repoAtt_Grade.FindBy(m => lstProfileID1.Contains(m.ProfileID.Value)) .Select(m => new { m.ID, m.ProfileID, m.MonthStart, m.GradeAttendanceID }) .OrderByDescending(m => m.MonthStart).ToList(); //var lstGrade = EntityService.CreateQueryable<Sal_Grade>(false, GuidContext, Guid.Empty, m => lstProfileID1.Contains(m.ProfileID)) // .Select(m => new { m.ID, m.ProfileID, m.MonthStart, m.GradeID }) // .OrderByDescending(m => m.MonthStart) // .Execute(); List<Cat_GradeAttendance> lstGradeAttendance = repoCat_GradeAttendance.FindBy(m => m.IsDelete == null).ToList(); //List<Cat_GradeCfg> lstGradeCfg = EntityService.CreateQueryable<Cat_GradeCfg>(false, GuidContext, Guid.Empty).ToList<Cat_GradeCfg>(); List<Hre_WorkHistory> listWorkHistory = repoHre_WorkHistory.FindBy(m => m.DateEffective <= dateMax1 && lstProfileID1.Contains(m.ProfileID)).OrderByDescending(m => m.DateEffective).ToList<Hre_WorkHistory>(); //List<Hre_WorkHistory> listWorkHistory = EntityService.CreateQueryable<Hre_WorkHistory>(false, GuidContext, Guid.Empty, m => m.DateEffective <= dateMax1 && lstProfileID1.Contains(m.ProfileID)).OrderByDescending(m => m.DateEffective).ToList<Hre_WorkHistory>(); E_APPROVED = RosterStatus.E_APPROVED.ToString(); string E_ROSTERGROUP = RosterType.E_ROSTERGROUP.ToString(); if (dateMin1 == null || dateMax1 == null) { lstRosterTypeGroup = repoAtt_Roster.FindBy(m => lstProfileID1.Contains(m.ProfileID) && m.Status == E_APPROVED && m.Type == E_ROSTERGROUP).ToList<Att_Roster>(); //lstRosterTypeGroup = EntityService.Instance.CreateQueryable<Att_Roster>(false, guidContext, Guid.Empty, m => lstProfileID.Contains(m.ProfileID) && m.Status == E_APPROVED && m.Type == E_ROSTERGROUP).ToList<Att_Roster>(); lstRosterGroup = repoAtt_RosterGroup.FindBy(m => m.DateStart != null && m.DateEnd != null).ToList<Att_RosterGroup>(); //lstRosterGroup = EntityService.Instance.CreateQueryable<Att_RosterGroup>(false, guidContext, Guid.Empty, m => m.DateStart != null && m.DateEnd != null).ToList<Att_RosterGroup>(); } else { lstRosterTypeGroup = repoAtt_Roster.FindBy(m => lstProfileID1.Contains(m.ProfileID) && m.Status == E_APPROVED && m.Type == E_ROSTERGROUP && m.DateStart <= dateMax1).ToList<Att_Roster>(); //lstRosterTypeGroup = EntityService.Instance.CreateQueryable<Att_Roster>(false, guidContext, Guid.Empty, m => lstProfileID.Contains(m.ProfileID) && m.Status == E_APPROVED && m.Type == E_ROSTERGROUP && m.DateStart <= DateTo).ToList<Att_Roster>(); lstRosterGroup = repoAtt_RosterGroup.FindBy(m => m.DateStart != null && m.DateEnd != null && m.DateStart <= dateMax1 && m.DateEnd >= dateMin1).ToList<Att_RosterGroup>(); //lstRosterGroup = EntityService.Instance.CreateQueryable<Att_RosterGroup>(false, guidContext, Guid.Empty, m => m.DateStart != null && m.DateEnd != null && m.DateStart <= DateTo && m.DateEnd >= DateFrom).ToList<Att_RosterGroup>(); } //RosterDAO.GetRosterGroup(GuidContext, lstProfileID1, dateMin1, dateMax1, out lstRosterTypeGroup, out lstRosterGroup); List<Cat_DayOff> lstHoliday = repoCat_DayOff.FindBy(m => m.IsDelete == null).ToList<Cat_DayOff>(); //List<Cat_DayOff> lstHoliday = EntityService.CreateQueryable<Cat_DayOff>(false, GuidContext, Guid.Empty).ToList<Cat_DayOff>(); string E_APPROVED1 = RosterStatus.E_APPROVED.ToString(); E_ROSTERGROUP = RosterType.E_ROSTERGROUP.ToString(); List<Att_Roster> lstRoster = repoAtt_Roster.FindBy(m => m.Status == E_APPROVED1 && m.DateStart <= dateMax1 && m.DateEnd >= dateMin1 && lstProfileID1.Contains(m.ProfileID)).ToList<Att_Roster>(); //List<Att_Roster> lstRoster = EntityService.CreateQueryable<Att_Roster>(false, GuidContext, Guid.Empty, m => m.Status == E_APPROVED1 && m.DateStart <= dateMax1 && m.DateEnd >= dateMin1 && lstProfileID1.Contains(m.ProfileID)).ToList<Att_Roster>(); List<DateTime> lstHolidayType = lstHoliday.Select(m => m.DateOff).ToList<DateTime>(); //LeaveDayDAO ldDao = new LeaveDayDAO(); foreach (var item in lstLeaveDayInsert) { if (item.DurationType != null && item.DurationType != LeaveDayDurationType.E_FULLSHIFT.ToString()) continue; Cat_LeaveDayType leaveDayType = lstLeaveDayType.Where(m => m.ID == item.LeaveDayTypeID).FirstOrDefault(); if (leaveDayType == null) continue; Hre_Profile profileInLeave = lstProfile.Where(m => m.ID == item.ProfileID).FirstOrDefault(); if (profileInLeave == null) continue; DateTime dateFrom = item.DateStart; DateTime dateTo = item.DateEnd; dateTo = dateTo.AddDays(1).AddMinutes(-1); Guid GradeAttendanceID = lstGrade.Where(m => m.ProfileID == profileInLeave.ID && m.MonthStart <= dateMax1 && m.GradeAttendanceID.HasValue).Select(m => m.GradeAttendanceID.Value).FirstOrDefault(); Cat_GradeAttendance gradeAttendance = lstGradeAttendance.Where(m => m.ID == GradeAttendanceID).FirstOrDefault(); List<Att_Roster> lstRosterByProfile = lstRoster.Where(m => m.ProfileID == profileInLeave.ID).ToList(); List<Hre_WorkHistory> listWorkHistoryByProfile = listWorkHistory.Where(m => m.ProfileID == profileInLeave.ID && m.DateEffective < dateTo).ToList(); List<Att_Roster> lstRosterByProfileTypeGroup = lstRosterByProfile.Where(m => m.Type == E_ROSTERGROUP).ToList(); leavedayServices.AnalyseTotalLeaveDaysAndHours(item, leaveDayType, profileInLeave, gradeAttendance, lstRosterByProfile, lstRosterGroup, listWorkHistoryByProfile, lstHoliday, shifts); if (item.ID == Guid.Empty) { item.ID = Guid.NewGuid(); repoAtt_LeaveDay.Add(item); } else repoAtt_LeaveDay.Edit(item); } } #endregion //repoAtt_LeaveDay.Add(lstLeaveDayInsert); repoAtt_LeaveDay.SaveChanges(); //EntityService.AddEntity<Att_LeaveDay>(GuidContext, lstLeaveDayInsert.ToArray()); return string.Empty; } }
private int ComputeWorkday(Guid asynTaskID, Guid userID, int totalProfile, int totalComputed, double timeoutMinutes, DateTime dateFrom, DateTime dateTo, out DataErrorCode dataErrorCode, params Hre_ProfileEntity[] listProfile) { List<Att_Workday> listWorkday = new List<Att_Workday>(); List<Att_Workday> listWorkdayChecked = new List<Att_Workday>(); List<Att_Workday> listWorkdayAnalyze = new List<Att_Workday>(); dateFrom = dateFrom <= DateTime.MinValue ? DateTime.Now : dateFrom; dateTo = dateTo <= DateTime.MinValue ? DateTime.Now : dateTo; DateTime dateStart = dateFrom.AddDays(-1); DateTime dateEnd = dateTo.AddDays(1); using (var context = new VnrHrmDataContext()) { var workHistoryServices = new Hre_WorkHistoryServices(); var leavedayServices = new Att_LeavedayServices(); var unitOfWork = new UnitOfWork(context); string waitStatus = ProfileStatusSyn.E_WAITING.ToString(); string rosterStatus = RosterStatus.E_APPROVED.ToString(); string leaveDayStatus = LeaveDayStatus.E_APPROVED.ToString(); String appConfigInfo = AppConfig.E_SERVER_TAM.ToString(); string E_LEAVE_EARLY = PregnancyType.E_LEAVE_EARLY.ToString(); string workdaySrcType = WorkdaySrcType.E_MANUAL.ToString(); string workdayStatus1 = WorkdayStatus.E_APPROVED.ToString(); string workdayStatus2 = WorkdayStatus.E_WAIT_APPROVED.ToString(); var listProfileID = listProfile.Select(d => d.ID).ToArray(); #region Delete Workday đã tổng hợp trước đó if (unitOfWork.CheckLock(typeof(Att_Workday), dateFrom, dateTo)) { dataErrorCode = DataErrorCode.Locked; CompleteComputingTask(asynTaskID, userID, totalComputed, totalProfile, dataErrorCode); return listWorkday.Count(); } else { Task task = Task.Run(() => DeleteWorkday(userID, dateFrom, dateTo, workdaySrcType, workdayStatus1, workdayStatus2, listProfileID)); } #endregion #region Khởi tạo dữ liệu cho lần tổng hợp var tamScanLogQueryable = unitOfWork.CreateQueryable<Att_TAMScanLog>(Guid.Empty, d => d.ProfileID.HasValue && listProfileID.Contains(d.ProfileID.Value) && d.TimeLog.HasValue && d.TimeLog >= dateStart && d.TimeLog <= dateEnd); //Danh sách quẹt thẻ theo điều kiện được chọn var listAllTamScanLog = tamScanLogQueryable.Select(d => new Att_TAMScanLogEntity { ID = d.ID, ProfileID = d.ProfileID, CardCode = d.CardCode, CodeEmp = d.CodeEmp, TimeLog = d.TimeLog, SrcType = d.SrcType, Type = d.Type }).ToList(); var listRoster = unitOfWork.CreateQueryable<Att_Roster>(Guid.Empty, d => d.Status == rosterStatus && d.DateStart <= dateEnd && d.DateEnd >= dateStart.Date && listProfileID.Contains(d.ProfileID)).Select(d => new Att_RosterEntity { ID = d.ID, ProfileID = d.ProfileID, RosterGroupName = d.RosterGroupName, Type = d.Type, Status = d.Status, DateEnd = d.DateEnd, DateStart = d.DateStart, MonShiftID = d.MonShiftID, TueShiftID = d.TueShiftID, WedShiftID = d.WedShiftID, ThuShiftID = d.ThuShiftID, FriShiftID = d.FriShiftID, SatShiftID = d.SatShiftID, SunShiftID = d.SunShiftID, MonShift2ID = d.MonShiftID, TueShift2ID = d.TueShift2ID, WedShift2ID = d.WedShift2ID, ThuShift2ID = d.ThuShift2ID, FriShift2ID = d.FriShift2ID, SatShift2ID = d.SatShift2ID, SunShift2ID = d.SunShift2ID }).ToList(); var listRosterGroup = unitOfWork.CreateQueryable<Att_RosterGroup>(Guid.Empty, m => m.DateStart != null && m.DateEnd != null && m.DateStart <= dateEnd && m.DateEnd >= dateStart.Date).Select(d => new Att_RosterGroupEntity { ID = d.ID, DateEnd = d.DateEnd, DateStart = d.DateStart, MonShiftID = d.MonShiftID, TueShiftID = d.TueShiftID, WedShiftID = d.WedShiftID, ThuShiftID = d.ThuShiftID, FriShiftID = d.FriShiftID, SatShiftID = d.SatShiftID, SunShiftID = d.SunShiftID, RosterGroupName = d.RosterGroupName }).ToList(); var listShift = unitOfWork.CreateQueryable<Cat_Shift>(Guid.Empty).ToList(); var listHoliday = unitOfWork.CreateQueryable<Cat_DayOff>(Guid.Empty, d => d.DateOff >= dateFrom.Date && d.DateOff <= dateTo).Select(d => new Cat_DayOffEntity { ID = d.ID, DateOff = d.DateOff, Type = d.Type }).ToList(); var listWorkdayExisting = unitOfWork.CreateQueryable<Att_Workday>(Guid.Empty, d => d.WorkDate >= dateStart && d.WorkDate <= dateEnd && (d.SrcType == workdaySrcType || d.Status == workdayStatus1 || d.Status == workdayStatus2) && listProfileID.Contains(d.ProfileID)).ToList(); var listLeaveDay = unitOfWork.CreateQueryable<Att_LeaveDay>(Guid.Empty, d => d.Status == leaveDayStatus && d.DateStart <= dateTo && d.DateEnd >= dateFrom.Date && listProfileID.Contains(d.ID)).Select(d => new { d.ID, d.ProfileID, d.LeaveDayTypeID, d.DateOvertimeOff, d.DateStart, d.DateEnd }).ToList(); var listLeaveDayType = unitOfWork.CreateQueryable<Cat_LeaveDayType>(Guid.Empty).Select(d => new { d.ID, d.Code, d.MissInOutReasonID }).ToList(); var listAllSetting = unitOfWork.CreateQueryable<Sys_AllSetting>(Guid.Empty, i => i.Name == AppConfig.HRM_ATT_WORKDAY_SUMMARY_MAXHOURSONESHIFT.ToString() || i.Name == AppConfig.HRM_ATT_WORKDAY_SUMMARY_MAXHOURSNEXTINOUT.ToString() || i.Name == AppConfig.HRM_ATT_WORKDAY_SUMMARY_MINMINUTESSAMEATT.ToString() || i.Name == AppConfig.HRM_ATT_WORKDAY_SUMMARY_SYMBOL.ToString() || i.Name == AppConfig.HRM_ATT_WORKDAY_SUMMARY_DETECTSHIFT.ToString() || i.Name == AppConfig.HRM_ATT_WORKDAY_SUMMARY_TYPELOADDATA.ToString()).Select(d => new { d.Name, d.Value1, d.Value2 }).ToList(); var inOutConfigMaxHoursOneShift = listAllSetting.Where(i => i.Name == AppConfig.HRM_ATT_WORKDAY_SUMMARY_MAXHOURSONESHIFT.ToString()).FirstOrDefault(); var inOutConfigMaxHoursNextInOut = listAllSetting.Where(i => i.Name == AppConfig.HRM_ATT_WORKDAY_SUMMARY_MAXHOURSNEXTINOUT.ToString()).FirstOrDefault(); var inOutConfigMinMinutesSameAtt = listAllSetting.Where(i => i.Name == AppConfig.HRM_ATT_WORKDAY_SUMMARY_MINMINUTESSAMEATT.ToString()).FirstOrDefault(); var inOutConfigSymbol = listAllSetting.Where(i => i.Name == AppConfig.HRM_ATT_WORKDAY_SUMMARY_SYMBOL.ToString()).FirstOrDefault(); var inOutConfigDetectShift = listAllSetting.Where(i => i.Name == AppConfig.HRM_ATT_WORKDAY_SUMMARY_DETECTSHIFT.ToString()).FirstOrDefault(); var inOutConfigTypeLoadData = listAllSetting.Where(i => i.Name == AppConfig.HRM_ATT_WORKDAY_SUMMARY_TYPELOADDATA.ToString()).FirstOrDefault(); var inOutConfig = new string[] { string.Empty }.Select(d => new WorkdayConfig { MaxHoursOneShift = inOutConfigMaxHoursOneShift != null ? inOutConfigMaxHoursOneShift.Value1 : string.Empty, MaxHoursNextInOut = inOutConfigMaxHoursNextInOut != null ? inOutConfigMaxHoursNextInOut.Value1 : string.Empty, MinMinutesSameAtt = inOutConfigMinMinutesSameAtt != null ? inOutConfigMinMinutesSameAtt.Value1 : string.Empty, TypeLoadData = inOutConfigTypeLoadData != null ? inOutConfigTypeLoadData.Value1 : string.Empty, SymbolIn = inOutConfigSymbol != null ? inOutConfigTypeLoadData.Value1 : string.Empty, SymbolOut = inOutConfigSymbol != null ? inOutConfigTypeLoadData.Value2 : string.Empty, DetectShift = inOutConfigDetectShift != null ? inOutConfigTypeLoadData.Value1 : string.Empty, DetectWrongShift = inOutConfigDetectShift != null ? inOutConfigTypeLoadData.Value2 : string.Empty, }).FirstOrDefault(); List<Att_Pregnancy> lstPrenancy = unitOfWork.CreateQueryable<Att_Pregnancy>(Guid.Empty, m => m.Type == E_LEAVE_EARLY && m.DateEnd >= dateFrom && m.DateStart < dateTo && listProfileID.Contains(m.ProfileID)).ToList(); List<Cat_LateEarlyRule> lstLateEarlyRule = unitOfWork.CreateQueryable<Cat_LateEarlyRule>(Guid.Empty).ToList(); List<Cat_GradeAttendance> lstGradeConfig = unitOfWork.CreateQueryable<Cat_GradeAttendance>(Guid.Empty).ToList(); List<Att_Grade> lstGrade = unitOfWork.CreateQueryable<Att_Grade>(Guid.Empty, m => m.ProfileID.HasValue && listProfileID.Contains(m.ProfileID.Value)).ToList(); List<DateTime> lstDayOff = unitOfWork.CreateQueryable<Cat_DayOff>(Guid.Empty, m => m.DateOff >= dateStart && m.DateOff <= dateEnd).Select(m => m.DateOff).ToList<DateTime>(); #endregion #region Bắt đầu xử lý tổng hợp in out string sameAttConfig = inOutConfig != null ? inOutConfig.MinMinutesSameAtt : string.Empty; var minMinutesSameAtt = VnResource.Helper.Data.DataHelper.TryGetValue<double>(sameAttConfig); //Loại bỏ những dòng quẹt thẻ liền kề nhau trong khoảng thời gian như cấu hình var listTamScanLog = RemoveSameTimeLog(listAllTamScanLog, minMinutesSameAtt); //Giữ danh sách những quẹt thẻ tạm thời được cho là trùng với những quẹt thẻ khác để xử lý sau var listTamScanLogRemove = listAllTamScanLog.Where(d => !listTamScanLog.Contains(d)).ToList(); using (var taskContext = new VnrHrmDataContext()) { var taskUnitOfWork = new UnitOfWork(taskContext); Sys_AsynTask asynTask = null; if (asynTaskID != Guid.Empty) { asynTask = taskUnitOfWork.CreateQueryable<Sys_AsynTask>(s => s.ID == asynTaskID).FirstOrDefault(); } int totalComputedProfileMustSubmitTask = 50; int totalComputedProfileMustSubmit = 200; int totalComputedProfileForSubmit = 0; int totalComputedProfileForTask = 0; totalComputedProfileMustSubmitTask = totalProfile * 5 / 100; if (totalComputedProfileMustSubmitTask > listProfile.Count()) { totalComputedProfileMustSubmitTask = listProfile.Count(); } foreach (var profile in listProfile) { #region Cập nhật thời gian tính timeout cho task if (asynTask != null) { bool mustSaveTask = false; if (asynTask.TimeEnd.HasValue) { var timeoutDate = DateTime.Now.AddMinutes(-timeoutMinutes); if (timeoutDate.AddMinutes(1) >= asynTask.TimeEnd.Value) { asynTask.TimeEnd = DateTime.Now; mustSaveTask = true; } } totalComputedProfileForTask++; double percent = totalComputedProfileForTask / (double)totalProfile; if (totalComputedProfileForTask >= totalComputedProfileMustSubmitTask) { var totalPercent = asynTask.PercentComplete + percent; asynTask.PercentComplete = totalPercent; asynTask.TimeEnd = DateTime.Now; mustSaveTask = true; } if (mustSaveTask) { taskUnitOfWork.SaveChanges(userID); totalComputedProfileForTask = 0; } } #endregion #region Những dữ liệu liên quan theo từng nhân viên var listRosterByProfile = listRoster.Where(d => d.ProfileID == profile.ID).ToList(); var listMonthShifts = Att_AttendanceLib.GetDailyShifts(dateStart, dateEnd, profile.ID, listRosterByProfile, listRosterGroup); #endregion #region Xử lý tổng hợp in out theo từng ngày for (DateTime date = dateFrom.Date; date <= dateTo; date = date.AddDays(1)) { Att_Workday workday = listWorkdayExisting.Where(d => d.ProfileID == profile.ID && d.WorkDate == date).FirstOrDefault(); var shiftByDate = listMonthShifts.Where(d => d.Key == date).Select(d => d.Value).FirstOrDefault(); Guid? shiftID1 = Guid.Empty; Guid? shiftID2 = Guid.Empty; if (shiftByDate != null) { if (shiftByDate.Count() > 0) { shiftID1 = shiftByDate[0]; } if (shiftByDate.Count() > 1) { shiftID2 = shiftByDate[1]; } } var shiftInfo1 = listShift.Where(d => d.ID == shiftID1).FirstOrDefault(); var shiftInfo2 = listShift.Where(d => d.ID == shiftID2).FirstOrDefault(); if ((profile.DateQuit.HasValue && profile.DateQuit.Value.Date <= date) || (profile.DateHire.HasValue && profile.DateHire.Value.Date > date)) { if (workday != null) { workday.IsDelete = true; } continue; } if (workday != null) { if (shiftByDate == null) { shiftByDate = new List<Guid?>(); } if ((!shiftID1.HasValue || shiftID1 == Guid.Empty)) { if (workday.ShiftActual.HasValue) { shiftByDate.Insert(0, workday.ShiftActual); } } if ((!shiftID2.HasValue || shiftID2 == Guid.Empty)) { if (workday.ShiftActual2.HasValue) { if (shiftByDate.Count() == 0) { shiftByDate.Add(Guid.Empty); } shiftByDate.Add(workday.ShiftActual2); } } if (listMonthShifts.ContainsKey(date)) { listMonthShifts[date] = shiftByDate; } else { listMonthShifts.Add(date, shiftByDate); } if ((workday.SrcType == workdaySrcType || workday.Status == workdayStatus1 || workday.Status == workdayStatus2)) { listWorkday.Add(workday); continue; } } Guid? actualShiftID1 = null; Guid? actualShiftID2 = null; bool isPreWorkday = false; var listTamScanLogByCardCode = listTamScanLog.Where(d => d.ProfileID == profile.ID).OrderBy(d => d.TimeLog).ToList(); var listTamScanLogByCardCodeUnchecked = listTamScanLogByCardCode.Where(d => !d.Checked && d.TimeLog.HasValue).ToList(); if (shiftID1.HasValue && shiftID1 != Guid.Empty) { #region Trường hợp có lịch làm việc - ca thứ nhất workday = CreateWorkday(unitOfWork, date, profile, inOutConfig, listHoliday, listWorkday, workday, false, shiftID1, shiftInfo1, listShift, listMonthShifts, out actualShiftID1, listTamScanLogByCardCode, listTamScanLogByCardCodeUnchecked); #endregion } else if (shiftID2.HasValue && shiftID2 != Guid.Empty) { #region Trường hợp có lịch làm việc - ca thứ hai workday = CreateWorkday(unitOfWork, date, profile, inOutConfig, listHoliday, listWorkday, workday, true, shiftID2, shiftInfo2, listShift, listMonthShifts, out actualShiftID2, listTamScanLogByCardCode, listTamScanLogByCardCodeUnchecked); #endregion } else if (inOutConfig != null && inOutConfig.DetectShift == Boolean.TrueString) { #region Trường hợp không có lịch làm việc var listTamScanLogByDate = listTamScanLogByCardCodeUnchecked.Where(d => d.TimeLog.Value.Date == date).ToList(); if (listTamScanLogByDate.Count() > 0) { var shiftInTime = date.Date.AddHours(12); 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 = 12;//cho ca tối đa được 12 tiếng đồng hồ 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) { if (preTamScanLog.TimeLog < date) { if (preShiftValue.HasValue) { workday = listWorkday.Where(d => d.ProfileID == profile.ID && d.WorkDate == date.AddDays(-1)).FirstOrDefault(); if (workday == null) { if (preTamScanLog.TimeLog.Value.Date >= dateFrom.Date && preTamScanLog.TimeLog.Value.Date <= dateTo.Date) { workday = new Att_Workday(); unitOfWork.AddObject(typeof(Att_Workday), workday); workday.WorkDate = preTamScanLog.TimeLog.Value.Date; workday.FirstInTime = workday.InTime1 = preTamScanLog.TimeLog; workday.LastOutTime = workday.OutTime1 = item.TimeLog; workday.Type = WorkdayType.E_DETECTED_SHIFT.ToString(); isPreWorkday = true; preTamScanLog.Checked = true; isWrongShiftDetected = true; break;//chỉ hỗ trợ 1 ca } } else { listTimeLog.Add(item); } } else { listTimeLog.Add(item); } } else { if (workday == null) { workday = new Att_Workday(); unitOfWork.AddObject(typeof(Att_Workday), workday); } workday.FirstInTime = workday.InTime1 = preTamScanLog.TimeLog; workday.LastOutTime = workday.OutTime1 = item.TimeLog; workday.Type = WorkdayType.E_DETECTED_SHIFT.ToString(); preTamScanLog.Checked = true; isWrongShiftDetected = true; break;//chỉ hỗ trợ 1 ca } } 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) { listTimeLog.Add(item); foreach (var nextTamScanLog in listNextTamScanLog.Where(d => d.TimeLog > item.TimeLog)) { var currentShiftDuration = 12;//cho ca tối đa được 12 tiếng đồng hồ //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) { listTimeLog.Add(nextTamScanLog); } } } else { if (!listTamScanLogByNextShift.Any(d => d.TimeLog == item.TimeLog)) { listTimeLog.Add(item); } listTimeLog = listTimeLog.Where(d => !listTamScanLogByNextShift.Contains(d)).ToList(); } } } if (!isWrongShiftDetected) { if (listTimeLog.Count() > 0) { var listRemove = new List<Att_TAMScanLogEntity>(); if (workday == null) { workday = new Att_Workday(); unitOfWork.AddObject(typeof(Att_Workday), workday); } if (listTimeLog.Count() >= 2) { workday.FirstInTime = workday.InTime1 = listTimeLog.OrderBy(d => d.TimeLog).Select(d => d.TimeLog).FirstOrDefault(); workday.LastOutTime = workday.OutTime1 = listTimeLog.OrderBy(d => d.TimeLog).Select(d => d.TimeLog).LastOrDefault(); var currentShiftDuration = 16;//cho ca tối đa được 12 tiếng đồng hồ isWrongShiftDetected = true; if (workday.LastOutTime.HasValue && workday.FirstInTime.HasValue && workday.LastOutTime.Value .Subtract(workday.FirstInTime.Value).TotalHours <= currentShiftDuration) { workday.Type = WorkdayType.E_DETECTED_SHIFT.ToString(); } else { foreach (var item in listTimeLog.Where(d => d.TimeLog > workday.FirstInTime).OrderByDescending(d => d.TimeLog)) { workday.LastOutTime = workday.OutTime1 = item.TimeLog; if (item.TimeLog > workday.FirstInTime && item.TimeLog.HasValue && workday.FirstInTime.HasValue && item.TimeLog.Value.Subtract(workday.FirstInTime.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)) { workday.FirstInTime = workday.InTime1 = listTimeLog.Select(d => d.TimeLog).FirstOrDefault(); workday.Type = WorkdayType.E_MISS_OUT.ToString();//miss-in hay miss-out cũng như nhau } else { workday.LastOutTime = workday.OutTime1 = listTimeLog.Select(d => d.TimeLog).FirstOrDefault(); 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 (workday != null) { //Trường hợp wrong-shift và detected-shift thì phải check lại actualShiftID actualShiftID1 = GetDetectedShiftID(workday.InTime1, workday.OutTime1, listShift, null); } } #endregion } if (workday != null) { if (string.IsNullOrWhiteSpace(workday.Type)) { workday.Type = WorkdayType.E_NORMAL.ToString(); } workday.SrcType = WorkdaySrcType.E_NORMAL.ToString(); workday.ProfileID = profile.ID; listTamScanLogByCardCode = listTamScanLogRemove.Where(d => d.ProfileID == profile.ID).OrderBy(d => d.TimeLog).ToList(); listTamScanLogByCardCodeUnchecked = listTamScanLogByCardCode.Where(d => !d.Checked && d.TimeLog.HasValue).ToList(); workday.FirstInTime = workday.InTime1 = FindTimeLogAvailable(listTamScanLogByCardCode, workday.InTime1, minMinutesSameAtt, false); workday.LastOutTime = workday.OutTime1 = FindTimeLogAvailable(listTamScanLogByCardCode, workday.OutTime1, minMinutesSameAtt, true); if (!isPreWorkday) { workday.WorkDate = date; workday.InTimeRoot = workday.InTime1; workday.OutTimeRoot = workday.OutTime1; } if (shiftID1 != null && shiftID1 != Guid.Empty) { workday.ShiftID = shiftID1.Value; workday.ShiftActual = shiftID1.Value; workday.ShiftApprove = shiftID1.Value; } if (shiftID2 != null && shiftID2 != Guid.Empty) { workday.Shift2ID = shiftID2.Value; workday.ShiftActual2 = shiftID2.Value; workday.ShiftApprove2 = shiftID2.Value; } if (actualShiftID1.HasValue && actualShiftID1 != Guid.Empty) { workday.ShiftActual = actualShiftID1; workday.ShiftApprove = actualShiftID1; } if (actualShiftID2.HasValue && actualShiftID2 != Guid.Empty) { workday.ShiftActual2 = actualShiftID2; workday.ShiftApprove2 = actualShiftID2; } var listLeaveDayByProfile = listLeaveDay.Where(d => d.ProfileID == profile.ID).ToList(); var leaveDayID1 = listLeaveDayByProfile.Where(d => workday.WorkDate >= d.DateStart && workday.WorkDate <= d.DateEnd).Select(d => d.ID).FirstOrDefault(); var leaveDayID2 = listLeaveDayByProfile.Where(d => d.ID != workday.LeaveDayID1 && workday.WorkDate >= d.DateStart && workday.WorkDate <= d.DateEnd).Select(d => d.ID).FirstOrDefault(); workday.LeaveDayID1 = leaveDayID1 != Guid.Empty ? (Guid?)leaveDayID1 : null; workday.LeaveDayID2 = leaveDayID2 != Guid.Empty ? (Guid?)leaveDayID2 : null; workday.MissInOutReason = listLeaveDayType.Where(d => listLeaveDayByProfile.Any(p => p.LeaveDayTypeID == d.ID) && d.MissInOutReasonID != null).Select(d => d.MissInOutReasonID).FirstOrDefault(); listWorkday.Add(workday); } } #endregion #region Chia thành nhiều giai đoạn lưu ngày công //Nên submit lần đầu tiên khi đã tính được 5 profile bool firstSubmit = listProfile.ToList().IndexOf(profile) == 5; firstSubmit = totalComputed >= 5 ? false : firstSubmit;//đã chạy 1 lần totalComputedProfileForSubmit++; totalComputed++; if (firstSubmit || totalComputedProfileForSubmit >= totalComputedProfileMustSubmit) { listWorkdayAnalyze = listWorkday.Where(d => !listWorkdayChecked.Contains(d)).ToList(); listWorkdayChecked.AddRange(listWorkdayAnalyze); leavedayServices.AnalyzeLeaveLate(listWorkdayAnalyze, lstPrenancy, lstLateEarlyRule, listShift, lstGrade, lstGradeConfig, lstDayOff); totalComputedProfileForSubmit = firstSubmit ? totalComputedProfileForSubmit : 0; dataErrorCode = unitOfWork.SaveChanges(userID); if (dataErrorCode == DataErrorCode.Locked) { break; } } #endregion } } #endregion #region Lưu kết quả tổng hợp in out listWorkdayAnalyze = listWorkday.Where(d => !listWorkdayChecked.Contains(d)).ToList(); listWorkdayChecked.AddRange(listWorkdayAnalyze); leavedayServices.AnalyzeLeaveLate(listWorkdayAnalyze, lstPrenancy, lstLateEarlyRule, listShift, lstGrade, lstGradeConfig, lstDayOff); unitOfWork.SetCorrectOrgStructureID(listWorkday); dataErrorCode = unitOfWork.SaveChanges(userID); #endregion } return listWorkday.Count(); }