Beispiel #1
0
    protected int ValidateApiResponse(ApiResponse response)
    {
        /*
         * if(content.apiResponse.error != null && content.apiResponse.error != "")
         * {
         * TRACE(PB error, msg = " + content.apiResponse.error);
         * return false;
         * }
         */

        if (response.error != 0)
        {
            DataErrorCode error = DataManager.instance.dataErrorCodeGroup.GetErrorCode(response.error);
            if (error.operation == 2)
            {
                return(0);
            }
            else
            {
                return(response.error);
            }

//			Trace.trace("PB error " + response.error, Trace.CHANNEL.INTEGRATION);
//			UIProcessErrorCode(response.error);
//
//			return false;
        }

        DisposeApiResponse(response);
        return(0);
    }
Beispiel #2
0
        public void CompleteComputingTask(Guid asynTaskID, Guid userID,
                                          int totalComputed, int totalProfile, DataErrorCode dataErrorCode)
        {
            #region Lưu Sys_AsynTask khi xử lý xong

            if (asynTaskID != Guid.Empty)
            {
                using (var taskContext = new VnrHrmDataContext())
                {
                    IUnitOfWork taskunitOfWork = new UnitOfWork(taskContext);
                    var         asynTask       = taskunitOfWork.CreateQueryable <Sys_AsynTask>(s => s.ID == asynTaskID).FirstOrDefault();

                    if (asynTask != null)
                    {
                        asynTask.PercentComplete = 1D;
                        asynTask.TimeEnd         = DateTime.Now;
                        asynTask.Status          = AsynTaskStatus.Done.ToString();

                        var time = asynTask.TimeEnd.Value.Subtract(asynTask.TimeStart).TotalMinutes;
                        asynTask.Description += " - Result: " + totalComputed + "/" + totalProfile;
                        asynTask.Description += " - Time: " + time.ToString("N2");

                        if (dataErrorCode == DataErrorCode.Locked)
                        {
                            asynTask.PercentComplete = 1D;//Không cần nhân với 100
                            asynTask.Description     = "Dữ Liệu Quẹt Thẻ Đã Bị Khóa";
                        }

                        dataErrorCode = taskunitOfWork.SaveChanges();
                    }
                }
            }

            #endregion
        }
Beispiel #3
0
        public void CompleteComputingTask(Guid asynTaskID, Guid userID,
            int totalComputed, int totalProfile, DataErrorCode dataErrorCode)
        {
            #region Lưu Sys_AsynTask khi xử lý xong

            if (asynTaskID != Guid.Empty)
            {
                using (var taskContext = new VnrHrmDataContext())
                {
                    IUnitOfWork taskunitOfWork = new UnitOfWork(taskContext);
                    var asynTask = taskunitOfWork.CreateQueryable<Sys_AsynTask>(s => s.ID == asynTaskID).FirstOrDefault();

                    if (asynTask != null)
                    {
                        asynTask.PercentComplete = 1D;
                        asynTask.TimeEnd = DateTime.Now;
                        asynTask.Status = AsynTaskStatus.Done.ToString();

                        var time = asynTask.TimeEnd.Value.Subtract(asynTask.TimeStart).TotalMinutes;
                        asynTask.Description += " - Result: " + totalComputed + "/" + totalProfile;
                        asynTask.Description += " - Time: " + time.ToString("N2");

                        if (dataErrorCode == DataErrorCode.Locked)
                        {
                            asynTask.PercentComplete = 1D;//Không cần nhân với 100
                            asynTask.Description = "Dữ Liệu Quẹt Thẻ Đã Bị Khóa";
                        }

                        dataErrorCode = taskunitOfWork.SaveChanges();
                    }
                }
            }

            #endregion
        }
Beispiel #4
0
        public DataError(DataErrorCode code)
        {
            this.Code = code;
            ErrorHandleAdvice advice;

            codeTypeDict.TryGetValue(this.Code, out advice);
            this.Advice = advice;
        }
        /// <summary>
        /// [Hieu.Van]
        /// Xử lý Gửi yêu cầu phê duyệt
        /// </summary>
        /// <param name="LoginID"></param>
        /// <param name="userApprovedID"></param>
        /// <param name="recordID"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public string ProcessSendRequest(string host, Guid LoginID, Guid userApprovedID, Guid recordID, string type)
        {
            DataErrorCode status = DataErrorCode.Success;

            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoFIN_PurchaseRequest = new CustomBaseRepository <FIN_PurchaseRequest>(unitOfWork);
                var repoSys_UserApprove     = new CustomBaseRepository <Sys_UserApprove>(unitOfWork);

                var record = repoFIN_PurchaseRequest.FindBy(s => s.ID == recordID).FirstOrDefault();
                if (record.UserCreateID != LoginID)
                {
                    return(DataErrorCode.NoPermission.ToString());
                }
                if (record.Status == EnumDropDown.Status.E_REJECTED.ToString())
                {
                    return(DataErrorCode.Error_Reject.ToString());
                }
                if (record.Status != null)
                {
                    return(DataErrorCode.Error_SendRequest.ToString());
                }
                var userApproved = repoSys_UserApprove.FindBy(s => s.ID == userApprovedID).FirstOrDefault();
                // Lấy status hiện tại của bản ghi
                string currentStatus = record.Status;

                // truyền từ Dropdownlist chọn người duyệt, lấy ra giá trị Status tiếp theo
                string nextStatus = userApproved.CurrentStatus;

                record.Status        = nextStatus;
                record.UserApproveID = userApprovedID;
                repoFIN_PurchaseRequest.Edit(record);
                status = repoFIN_PurchaseRequest.SaveChanges();


                if (status == DataErrorCode.Success)
                {
                    if (nextStatus != "Approved")
                    {
                        status = SendMail_ToNextApproved(host, recordID, userApprovedID, nextStatus, type);
                    }

                    var repoSys_ConfigProcessApprove = new CustomBaseRepository <Sys_ConfigProcessApprove>(unitOfWork);
                    var configProcess = repoSys_ConfigProcessApprove.FindBy(s => s.IsDelete == null && s.Function == type && s.CurrentStatus == record.Status).FirstOrDefault();
                    if (configProcess == null)
                    {
                        return(DataErrorCode.Success.ToString());
                    }
                    else
                    {
                        return(DataErrorCode.Success_Forward.ToString());
                    }
                }

                return(status.ToString());
            }
        }
    public void Load(string name)
    {
        byte[] bin     = DynamicFileControl.QueryFileContent(name);
        string content = StringHelper.ReadFromBytes(bin);

        LitJson.JSONNode json = LitJson.JSON.Parse(content);

        _dataErrorCodes = new Dictionary <int, DataErrorCode> ();

        foreach (LitJson.JSONNode subNode in json.Childs)
        {
            DataErrorCode data = new DataErrorCode();
            data.Load(subNode);
            _dataErrorCodes.Add(data.errorCode, data);
        }
    }
Beispiel #7
0
    public override void Open(params object[] parameters)
    {
        base.Open(parameters);

        int errorcodeId = (int)parameters [0];

        _errorCode = DataManager.instance.dataErrorCodeGroup.GetErrorCode(errorcodeId);

        if (_errorCode != null)
        {
            _message_text.text = _errorCode.message;
        }
        else
        {
            _message_text.text = "" + errorcodeId;
        }
    }
        /// <summary>
        /// [Hieu.Van]
        /// Xử lý Từ Chối
        /// </summary>
        /// <param name="LoginID"></param>
        /// <param name="userApprovedID"></param>
        /// <param name="recordID"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public string ProcessReject(string host, Guid LoginID, Guid recordID, string type)
        {
            DataErrorCode status = DataErrorCode.Success;

            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoFIN_PurchaseRequest = new CustomBaseRepository <FIN_PurchaseRequest>(unitOfWork);
                var repoSys_UserApprove     = new CustomBaseRepository <Sys_UserApprove>(unitOfWork);
                var repoSys_UserInfo        = new CustomBaseRepository <Sys_UserInfo>(unitOfWork);

                var record = repoFIN_PurchaseRequest.FindBy(s => s.ID == recordID).FirstOrDefault();
                if (record.Status == EnumDropDown.Status.E_REJECTED.ToString())
                {
                    return(DataErrorCode.Error_Reject.ToString());
                }
                var userApproved = repoSys_UserApprove.FindBy(s => s.ID == record.UserApproveID).FirstOrDefault();
                // Kiểm tra tài khoản login có được phép Duyệt hay ko?
                if (LoginID == Guid.Empty || userApproved.UserApproveID != LoginID)
                {
                    // kiểm tra nếu bản ghi có tk duyệt trống (tức bản ghi mới tạo) và tk login = tk tạo thì cho duyệt tiếp tục
                    if (record.UserApproveID == null && record.UserCreateID == LoginID)
                    {
                    }
                    else
                    {
                        return(DataErrorCode.NoPermission.ToString());
                    }
                }

                record.Status = EnumDropDown.Status.E_REJECTED.ToString();
                repoFIN_PurchaseRequest.Edit(record);
                status = repoFIN_PurchaseRequest.SaveChanges();

                return(status.ToString());
            }
        }
Beispiel #9
0
 public DataError(DataErrorCode code, string desc)
     : this(code)
 {
     this.Description = desc;
 }
        /// <summary>
        /// [Hieu.Van]
        /// Xử lý duyệt động đa cấp
        /// ProcessApproved (Tài khoản Login - LoginID, Value Dropdownlist - userApprovedID, Id Bản ghi - recordID, Enum màn hình - type)
        /// </summary>
        /// <param name="LoginID"></param>
        /// <param name="userApprovedID"></param>
        /// <param name="recordID"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public string ProcessApproved(string host, Guid LoginID, Guid userApprovedID, Guid recordID, string type)
        {
            DataErrorCode status   = DataErrorCode.Success;
            string        stt      = string.Empty;
            var           Services = new BaseService();

            using (var context = new VnrHrmDataContext())
            {
                var    unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var    repoFIN_PurchaseRequest      = new CustomBaseRepository <FIN_PurchaseRequest>(unitOfWork);
                var    repoSys_UserApprove          = new CustomBaseRepository <Sys_UserApprove>(unitOfWork);
                var    repoSys_ConfigProcessApprove = new CustomBaseRepository <Sys_ConfigProcessApprove>(unitOfWork);
                var    UserLogin                 = string.Empty;
                var    record                    = GetData <FIN_PurchaseRequestEntity>(recordID, ConstantSql.hrm_hr_sp_get_PurchaseRequestById, UserLogin, ref stt).FirstOrDefault();
                var    configProcess             = repoSys_ConfigProcessApprove.FindBy(s => s.IsDelete == null && s.Function == type && s.CurrentStatus == record.Status).FirstOrDefault();
                double total                     = record.Total != null ? record.Total.Value : 0.0;
                List <ElementFormula> listFomula = new List <ElementFormula>();
                ElementFormula        FomulaItem = new ElementFormula("Total", total, 0);
                ElementFormula        statusItem = new ElementFormula(configProcess.NextStatusFormular, configProcess.NextStatusFormular, 1);
                listFomula.Add(FomulaItem);
                listFomula.Add(statusItem);
                string nextStatus = Services.GetObjectValue(new List <Cat_ElementEntity>(), listFomula, configProcess.NextStatusFormular).ToString();


                if (configProcess != null && userApprovedID == Guid.Empty && nextStatus != "Approved")
                {
                    return(DataErrorCode.Error_NoUserApproved.ToString());
                }
                if (record.Status == EnumDropDown.Status.E_REJECTED.ToString())
                {
                    return(DataErrorCode.Error_Reject.ToString());
                }
                var recordEdit = repoFIN_PurchaseRequest.FindBy(s => s.ID == recordID).FirstOrDefault();
                // lấy UserInfoID hiện tại của bản ghi
                var userApprovedCurrent = repoSys_UserApprove.FindBy(s => s.ID == recordEdit.UserApproveID).FirstOrDefault();
                // Kiểm tra tài khoản login có được phép Duyệt hay ko?
                if (LoginID == Guid.Empty || userApprovedCurrent.UserApproveID != LoginID)
                {
                    // kiểm tra nếu bản ghi có tk duyệt trống (tức bản ghi mới tạo) và tk login = tk tạo thì cho duyệt tiếp tục
                    if (recordEdit.UserApproveID == null && record.UserCreateID == LoginID)
                    {
                    }
                    else
                    {
                        return(DataErrorCode.NoPermission.ToString());
                    }
                }
                recordEdit.Status = nextStatus;
                if (userApprovedID == Guid.Empty)
                {
                    recordEdit.UserApproveID = null;
                }
                else
                {
                    recordEdit.UserApproveID = userApprovedID;
                }
                repoFIN_PurchaseRequest.Edit(recordEdit);
                status = repoFIN_PurchaseRequest.SaveChanges();

                if (nextStatus != "Approved")
                {
                    status = SendMail_ToNextApproved(host, recordID, userApprovedID, nextStatus, type);
                }

                if (status == DataErrorCode.Success)
                {
                    //var configProcess = repoSys_ConfigProcessApprove.FindBy(s => s.IsDelete == null && s.Function == type && s.CurrentStatus == nextStatus).FirstOrDefault();
                    if (nextStatus == "Approved")
                    {
                        return(DataErrorCode.Success.ToString());
                    }
                    else
                    {
                        return(DataErrorCode.Success_Forward.ToString());
                    }
                }

                return(status.ToString());
            }
        }
        /// <summary>
        /// Button Tính Phép Bệnh
        /// </summary>
        /// <param name="Year"></param>
        /// <param name="orgStructure"></param>
        /// <param name="LstProfileStatus"></param>
        /// <returns></returns>
        public bool ComputeAnnualSickLeaveDetail(int Year, string orgStructure, string LstProfileStatus, string UserLogin)
        {
            var result = false;

            using (var context = new VnrHrmDataContext())
            {
                string status     = string.Empty;
                var    unitOfWork = (IUnitOfWork) new UnitOfWork(context);
                var    repoAtt_AnnualLeaveDetail = new CustomBaseRepository <Att_AnnualLeaveDetail>(unitOfWork);
                var    repoHre_Profile           = new CustomBaseRepository <Hre_Profile>(unitOfWork);
                var    repoHre_HDTJob            = new CustomBaseRepository <Hre_HDTJob>(unitOfWork);
                var    repoCat_DayOff            = new CustomBaseRepository <Cat_DayOff>(unitOfWork);
                var    repoCat_LeaveDayType      = new CustomBaseRepository <Cat_LeaveDayType>(unitOfWork);
                var    repoAtt_LeaveDay          = new CustomBaseRepository <Att_LeaveDay>(unitOfWork);
                var    repoCat_JobTitle          = new CustomBaseRepository <Cat_JobTitle>(unitOfWork);


                #region FilterInfo
                string E_SICK_LEAVE = AnnualLeaveDetailType.E_SICK_LEAVE.ToString();

                Att_AnnualLeaveDetail AnnualLeaveDetailTop = repoAtt_AnnualLeaveDetail
                                                             .FindBy(m => m.IsDelete == null && m.Type == E_SICK_LEAVE && m.Year == Year).FirstOrDefault();

                DateTime beginyear = (AnnualLeaveDetailTop == null || AnnualLeaveDetailTop.MonthStart == null) ? new DateTime(Year, 1, 1) : AnnualLeaveDetailTop.MonthStart.Value;
                DateTime endYear   = beginyear.AddYears(1).AddMinutes(-1);

                List <object> lstObj = new List <object>();
                lstObj.Add(orgStructure);
                lstObj.Add(null);
                lstObj.Add(null);
                var lstProfileQuery = GetData <Hre_ProfileEntity>(lstObj, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, UserLogin, ref status).ToList();

                if (LstProfileStatus != null)
                {
                    if (LstProfileStatus == StatusEmpLeaveDetail.E_NEWEMPINYEAR.ToString())
                    {
                        lstProfileQuery = lstProfileQuery.Where(m => m.DateHire != null && m.DateHire >= beginyear && m.DateHire <= endYear).ToList();
                    }
                    if (LstProfileStatus == StatusEmpLeaveDetail.E_RESIGNEMPINYEAR.ToString())
                    {
                        lstProfileQuery = lstProfileQuery.Where(m => m.DateQuit != null && m.DateQuit >= beginyear && m.DateQuit <= endYear).ToList();
                    }
                    if (LstProfileStatus == StatusEmpLeaveDetail.E_EMPOFHDT4.ToString())
                    {
                        string      Job4           = HDTJobType.E_Four.ToString();
                        List <Guid> lstprofileHDT4 = repoHre_HDTJob
                                                     .FindBy(m => m.IsDelete == null && m.Type == Job4 && m.DateFrom <= endYear && m.DateTo >= beginyear && m.ProfileID != null)
                                                     .Select(m => m.ProfileID.Value).ToList <Guid>();
                        lstProfileQuery = lstProfileQuery.Where(m => lstprofileHDT4.Contains(m.ID)).ToList();
                    }
                    if (LstProfileStatus == StatusEmpLeaveDetail.E_EMPOFHDT5.ToString())
                    {
                        string      Job5           = HDTJobType.E_Five.ToString();
                        List <Guid> lstprofileHDT5 = repoHre_HDTJob
                                                     .FindBy(m => m.IsDelete == null && m.Type == Job5 && m.DateFrom <= endYear && m.DateTo >= beginyear && m.ProfileID != null)
                                                     .Select(m => m.ProfileID.Value).ToList <Guid>();
                        lstProfileQuery = lstProfileQuery.Where(m => lstprofileHDT5.Contains(m.ID)).ToList();
                    }
                }

                List <Guid> lstProfileID = lstProfileQuery.Select(m => m.ID).Distinct().ToList <Guid>();
                #endregion
                #region get Data
                //string E_STANDARD_WORKDAY = AppConfig.E_STANDARD_WORKDAY.ToString();
                //Sys_AppConfig appconfig = EntityService.CreateQueryable<Sys_AppConfig>(false, GuidContext, Guid.Empty, m => m.Info == E_STANDARD_WORKDAY).FirstOrDefault();
                //if (appconfig == null || string.IsNullOrEmpty(appconfig.Value76) || string.IsNullOrEmpty(appconfig.Value77))
                //{
                //    Common.MessageBoxs(Messages.Msg, Messages.PleaseConfigSickLeaveAtTotalConfig, MessageBox.Icon.WARNING, string.Empty);
                //    return;
                //}

                string        HRM_ATT_ANNUALSICKLEAVE_ = AppConfig.HRM_ATT_ANNUALSICKLEAVE_.ToString();
                List <object> lstO = new List <object>();
                lstO.Add(HRM_ATT_ANNUALSICKLEAVE_);
                lstO.Add(null);
                lstO.Add(null);
                var config = GetData <Sys_AllSettingEntity>(lstO, ConstantSql.hrm_sys_sp_get_AllSetting, UserLogin, ref status);

                var formular1 = config.Where(s => s.Name == AppConfig.HRM_ATT_ANNUALSICKLEAVE_FORMULARCONFIG.ToString()).FirstOrDefault();
                var formular2 = config.Where(s => s.Name == AppConfig.HRM_ATT_ANNUALSICKLEAVE_FORMULARCOMPUTE.ToString()).FirstOrDefault();

                if (config == null || string.IsNullOrEmpty(formular1.Value1) || string.IsNullOrEmpty(formular2.Value1))
                {
                    //Common.MessageBoxs(Messages.Msg, Messages.PleaseConfigAnnualLeaveAtTotalConfig, MessageBox.Icon.WARNING, string.Empty);
                    return(result);
                }

                string formularConfig  = formular1.Value1;
                string formularCompute = formular2.Value1;

                ParamGetConfigANL configAnl = new ParamGetConfigANL();
                (new Att_AttendanceServices()).GetConfigANL(formularConfig, out configAnl);

                int           MonthBegin             = 1;
                List <string> lstCodeLeaveTypeNonAnl = new List <string>();
                if (configAnl != null && configAnl.monthBeginYear != null)
                {
                    MonthBegin = configAnl.monthBeginYear;
                }
                if (configAnl != null && configAnl.lstCodeLeaveNonANL != null)
                {
                    lstCodeLeaveTypeNonAnl = configAnl.lstCodeLeaveNonANL;
                }
                DateTime BeginYear = new DateTime(Year, MonthBegin, 1);
                DateTime EndYear   = BeginYear.AddYears(1).AddMinutes(-1);

                string          E_APPROVED = LeaveDayStatus.E_APPROVED.ToString();
                List <DateTime> lstDayOff  = repoCat_DayOff
                                             .FindBy(m => m.IsDelete == null && m.DateOff > BeginYear && m.DateOff <= EndYear)
                                             .Select(m => m.DateOff).Distinct().ToList <DateTime>();
                List <Hre_ProfileEntity> lstprofile = lstProfileQuery
                                                      .Where(m => m.DateQuit == null || (m.DateQuit != null && m.DateQuit > BeginYear))
                                                      .ToList <Hre_ProfileEntity>();
                List <Guid> lstLeavedayTypeNonAnl = repoCat_LeaveDayType
                                                    .FindBy(m => m.IsDelete == null && lstCodeLeaveTypeNonAnl.Contains(m.Code)).Select(m => m.ID).ToList <Guid>();
                List <Att_LeaveDay> lstleavedayNonANl = repoAtt_LeaveDay
                                                        .FindBy(m => m.IsDelete == null && m.Status == E_APPROVED && lstLeavedayTypeNonAnl.Contains(m.LeaveDayTypeID) &&
                                                                lstProfileID.Contains(m.ProfileID)).ToList <Att_LeaveDay>();
                List <Att_LeaveDay> lstleavedayNonANlInYear = lstleavedayNonANl.Where(m => m.DateStart <= EndYear && m.DateEnd >= BeginYear).ToList <Att_LeaveDay>();
                List <Hre_HDTJob>   lstHDTJob = repoHre_HDTJob
                                                .FindBy(m => m.IsDelete == null && m.ProfileID != null && lstProfileID.Contains(m.ProfileID.Value)).ToList <Hre_HDTJob>();
                List <Cat_JobTitle> lstJobtitle = repoCat_JobTitle.FindBy(s => s.IsDelete == null).ToList();
                #endregion

                List <Att_AnnualLeaveDetail> lstAnnualDetail = new List <Att_AnnualLeaveDetail>();
                foreach (var item in lstprofile)
                {
                    List <Att_LeaveDay> lstLeavedayNonAnlByProfile       = lstleavedayNonANl.Where(m => m.ProfileID == item.ID).ToList();
                    List <Att_LeaveDay> lstLeavedayNonAnlByProfileInYear = lstleavedayNonANlInYear.Where(m => m.ProfileID == item.ID).ToList();
                    List <Hre_HDTJob>   lstHDTJobByProfile = lstHDTJob.Where(m => m.ProfileID == item.ID).ToList();
                    double AvailabelInYear = (new Att_AttendanceServices()).GetAnnualLeaveAvailableAllYear(Year, null, item.DateHire,
                                                                                                           item.DateEndProbation, item.DateQuit, formularConfig,
                                                                                                           formularCompute, lstLeavedayNonAnlByProfileInYear, lstJobtitle, lstDayOff, lstHDTJobByProfile, lstLeavedayNonAnlByProfile);
                    Att_AnnualLeaveDetail annualProfile = new Att_AnnualLeaveDetail();
                    annualProfile.ID         = Guid.NewGuid();
                    annualProfile.ProfileID  = item.ID;
                    annualProfile.MonthStart = BeginYear;
                    annualProfile.MonthEnd   = EndYear;
                    annualProfile.Year       = Year;
                    annualProfile.Type       = E_SICK_LEAVE;
                    annualProfile.Month1     = AvailabelInYear;
                    annualProfile.Month2     = AvailabelInYear;
                    annualProfile.Month3     = AvailabelInYear;
                    annualProfile.Month4     = AvailabelInYear;
                    annualProfile.Month5     = AvailabelInYear;
                    annualProfile.Month6     = AvailabelInYear;
                    annualProfile.Month7     = AvailabelInYear;
                    annualProfile.Month8     = AvailabelInYear;
                    annualProfile.Month9     = AvailabelInYear;
                    annualProfile.Month10    = AvailabelInYear;
                    annualProfile.Month11    = AvailabelInYear;
                    annualProfile.Month12    = AvailabelInYear;
                    lstAnnualDetail.Add(annualProfile);
                }

                DataErrorCode DataErr = DataErrorCode.Unknown;

                if (lstAnnualDetail.Count > 0)
                {
                    #region lấy dữ liệu dưới DB xóa đi
                    List <Guid> lstProfileID_InDB = lstAnnualDetail.Where(m => m.ProfileID != null).Select(m => m.ProfileID.Value).ToList();


                    List <Att_AnnualLeaveDetail> lstAnnualLeaveDetail_InDB = repoAtt_AnnualLeaveDetail
                                                                             .FindBy(m => m.IsDelete == null && m.Year == Year && m.Type == E_SICK_LEAVE && m.ProfileID != null && lstProfileID_InDB.Contains(m.ProfileID.Value)).ToList <Att_AnnualLeaveDetail>();
                    foreach (var item in lstAnnualLeaveDetail_InDB)
                    {
                        item.IsDelete = true;
                    }
                    #endregion

                    repoAtt_AnnualLeaveDetail.Add(lstAnnualDetail);
                    try
                    {
                        repoAtt_AnnualLeaveDetail.SaveChanges();
                    }
                    catch (Exception)
                    {
                        return(false);
                    }

                    //EntityService.AddEntity<Att_AnnualLeaveDetail>(GuidContext, lstAnnualDetail.ToArray());
                    //DataErr = EntityService.SubmitChanges(GuidContext, LoginUserID);

                    //if (DataErr == DataErrorCode.Success)
                    //{
                    //    Common.MessageBoxs(Messages.Msg, Messages.SaveSuccess, MessageBox.Icon.INFO, string.Empty);
                    //}
                    //else
                    //{
                    //    Common.MessageBoxs(Messages.Msg, Messages.SaveUnSuccess, MessageBox.Icon.INFO, string.Empty);
                    //}
                }
                //else
                //{
                //    Common.MessageBoxs(Messages.Msg, Messages.NoDataToCompute, MessageBox.Icon.WARNING, string.Empty);
                //}
                result = true;
            }
            return(result);
        }
Beispiel #12
0
        public bool ComputeInsuranceLeaveDetail(int Year, string orgStructure, string LstProfileStatus, string UserLogin)
        {
            /*
             * -get leaveDetail : type , year
             *   - get List Profile :
             *      + Theo phong ban
             *      + Theo trạng thai StatusEmpleaveDetail
             *
             */

            var    result = false;
            string status = string.Empty;


            using (var context = new VnrHrmDataContext())
            {
                var unitOfWork = (IUnitOfWork)(new UnitOfWork(context));
                var repoAtt_AnnualLeaveDetail = new CustomBaseRepository <Att_AnnualLeaveDetail>(unitOfWork);
                var repoHre_Profile           = new CustomBaseRepository <Hre_Profile>(unitOfWork);
                var repoHre_HDTJob            = new CustomBaseRepository <Hre_HDTJob>(unitOfWork);
                var repoSys_AppConfig         = new CustomBaseRepository <Sys_AppConfig>(unitOfWork);
                var repoCat_DayOff            = new CustomBaseRepository <Cat_DayOff>(unitOfWork);
                var repoCat_LeaveDayType      = new CustomBaseRepository <Cat_LeaveDayType>(unitOfWork);
                var repoAtt_LeaveDay          = new CustomBaseRepository <Att_LeaveDay>(unitOfWork);
                var repoCat_JobTitle          = new CustomBaseRepository <Cat_JobTitle>(unitOfWork);

                #region get Data
                string        HRM_ATT_ANNUALINSURANCELEAVE_ = AppConfig.HRM_ATT_ANNUALINSURANCELEAVE_.ToString();
                List <object> lstO = new List <object>();
                lstO.Add(HRM_ATT_ANNUALINSURANCELEAVE_);
                lstO.Add(null);
                lstO.Add(null);
                var config = GetData <Sys_AllSettingEntity>(lstO, ConstantSql.hrm_sys_sp_get_AllSetting, UserLogin, ref status);

                var formular1 = config.Where(s => s.Name == AppConfig.HRM_ATT_ANNUALINSURANCELEAVE_FORMULARCONFIG.ToString()).FirstOrDefault();
                var formular2 = config.Where(s => s.Name == AppConfig.HRM_ATT_ANNUALINSURANCELEAVE_FORMULARCOMPUTE.ToString()).FirstOrDefault();

                if (config == null || string.IsNullOrEmpty(formular1.Value1) || string.IsNullOrEmpty(formular2.Value1))
                {
                    //Common.MessageBoxs(Messages.Msg, Messages.PleaseConfigAnnualLeaveAtTotalConfig, MessageBox.Icon.WARNING, string.Empty);
                    return(result);
                }


                List <object> lstPro = new List <object>();
                lstPro.Add(orgStructure);
                lstPro.Add(null);
                lstPro.Add(null);
                var lstProfileQuery = GetData <Hre_ProfileEntity>(lstPro, ConstantSql.hrm_hr_sp_get_ProfileIdsByOrg, UserLogin, ref status).ToList();

                string            formularConfig  = formular1.Value1;
                string            formularCompute = formular2.Value1;
                ParamGetConfigANL configAnl       = new ParamGetConfigANL();
                (new Att_AttendanceServices()).GetConfigANL(formularConfig, out configAnl);

                int           MonthBegin             = 1;
                List <string> lstCodeLeaveTypeNonAnl = new List <string>();
                if (configAnl != null && configAnl.monthBeginYear != null)
                {
                    MonthBegin = configAnl.monthBeginYear;
                }
                if (configAnl != null && configAnl.lstCodeLeaveNonANL != null)
                {
                    lstCodeLeaveTypeNonAnl = configAnl.lstCodeLeaveNonANL;
                }
                DateTime BeginYear = new DateTime(Year, MonthBegin, 1);
                DateTime EndYear   = BeginYear.AddYears(1).AddMinutes(-1);

                string          E_APPROVED = LeaveDayStatus.E_APPROVED.ToString();
                List <DateTime> lstDayOff  = repoCat_DayOff
                                             .FindBy(m => m.IsDelete == null && m.DateOff > BeginYear && m.DateOff <= EndYear)
                                             .Select(m => m.DateOff).Distinct().ToList <DateTime>();
                List <Hre_ProfileEntity> lstprofile = lstProfileQuery
                                                      .Where(m => m.DateQuit == null || (m.DateQuit != null && m.DateQuit > BeginYear)).ToList();
                List <Guid> lstProfileID          = lstprofile.Select(m => m.ID).ToList();
                List <Guid> lstLeavedayTypeNonAnl = repoCat_LeaveDayType
                                                    .FindBy(m => m.IsDelete == null && lstCodeLeaveTypeNonAnl.Contains(m.Code)).Select(m => m.ID).ToList <Guid>();
                List <Att_LeaveDay> lstleavedayNonANl = repoAtt_LeaveDay
                                                        .FindBy(m => m.IsDelete == null && m.Status == E_APPROVED && lstLeavedayTypeNonAnl.Contains(m.LeaveDayTypeID) && lstProfileID.Contains(m.ProfileID)).ToList <Att_LeaveDay>();
                List <Att_LeaveDay> lstleavedayNonANlInYear = lstleavedayNonANl.Where(m => m.DateStart <= EndYear && m.DateEnd >= BeginYear).ToList <Att_LeaveDay>();
                List <Hre_HDTJob>   lstHDTJob = repoHre_HDTJob
                                                .FindBy(m => m.IsDelete == null && m.ProfileID != null && lstProfileID.Contains(m.ProfileID.Value)).ToList <Hre_HDTJob>();
                List <Cat_JobTitle> lstJobtitle = repoCat_JobTitle.FindBy(s => s.IsDelete == null).ToList();
                string E_INSURANCE_LEAVE        = AnnualLeaveDetailType.E_INSURANCE_LEAVE.ToString();
                #endregion

                List <Att_AnnualLeaveDetail> lstInsDetail = new List <Att_AnnualLeaveDetail>();
                foreach (var item in lstprofile)
                {
                    List <Att_LeaveDay>   lstLeavedayNonAnlByProfile       = lstleavedayNonANl.Where(m => m.ProfileID == item.ID).ToList();
                    List <Att_LeaveDay>   lstLeavedayNonAnlByProfileInYear = lstleavedayNonANlInYear.Where(m => m.ProfileID == item.ID).ToList();
                    List <Hre_HDTJob>     lstHDTJobByProfile = lstHDTJob.Where(m => m.ProfileID == item.ID).ToList();
                    Att_AnnualLeaveDetail annualProfile      = new Att_AnnualLeaveDetail();
                    annualProfile.ID         = Guid.NewGuid();
                    annualProfile.ProfileID  = item.ID;
                    annualProfile.MonthStart = BeginYear;
                    annualProfile.MonthEnd   = EndYear;
                    annualProfile.Year       = Year;
                    annualProfile.Type       = E_INSURANCE_LEAVE;
                    for (DateTime Month = BeginYear; Month < EndYear; Month = Month.AddMonths(1))
                    {
                        double AvailabelInYear = (new Att_AttendanceServices()).GetAnnualLeaveAvailableAllYear(Year, Month.Month, item.DateHire,
                                                                                                               item.DateEndProbation, item.DateQuit, formularConfig,
                                                                                                               formularCompute, lstLeavedayNonAnlByProfileInYear, lstJobtitle, lstDayOff, lstHDTJobByProfile, lstLeavedayNonAnlByProfile);
                        if (Month.Month == 1)
                        {
                            annualProfile.Month1 = AvailabelInYear;
                        }
                        if (Month.Month == 2)
                        {
                            annualProfile.Month2 = AvailabelInYear;
                        }
                        if (Month.Month == 3)
                        {
                            annualProfile.Month3 = AvailabelInYear;
                        }
                        if (Month.Month == 4)
                        {
                            annualProfile.Month4 = AvailabelInYear;
                        }
                        if (Month.Month == 5)
                        {
                            annualProfile.Month5 = AvailabelInYear;
                        }
                        if (Month.Month == 6)
                        {
                            annualProfile.Month6 = AvailabelInYear;
                        }
                        if (Month.Month == 7)
                        {
                            annualProfile.Month7 = AvailabelInYear;
                        }
                        if (Month.Month == 8)
                        {
                            annualProfile.Month8 = AvailabelInYear;
                        }
                        if (Month.Month == 9)
                        {
                            annualProfile.Month9 = AvailabelInYear;
                        }
                        if (Month.Month == 10)
                        {
                            annualProfile.Month10 = AvailabelInYear;
                        }
                        if (Month.Month == 11)
                        {
                            annualProfile.Month11 = AvailabelInYear;
                        }
                        if (Month.Month == 12)
                        {
                            annualProfile.Month12 = AvailabelInYear;
                        }
                    }
                    lstInsDetail.Add(annualProfile);
                }

                DataErrorCode DataErr = DataErrorCode.Unknown;

                if (lstInsDetail.Count > 0)
                {
                    #region lấy dữ liệu dưới DB xóa đi
                    List <Guid> lstProfileID_InDB = lstInsDetail.Where(m => m.ProfileID != null).Select(m => m.ProfileID.Value).ToList();


                    List <Att_AnnualLeaveDetail> lstAnnualLeaveDetail_InDB = repoAtt_AnnualLeaveDetail
                                                                             .FindBy(m => m.IsDelete == null && m.Type == E_INSURANCE_LEAVE && m.Year == Year && m.ProfileID != null &&
                                                                                     lstProfileID_InDB.Contains(m.ProfileID.Value)).ToList();
                    foreach (var item in lstAnnualLeaveDetail_InDB)
                    {
                        item.IsDelete = true;
                    }
                    #endregion

                    repoAtt_AnnualLeaveDetail.Add(lstInsDetail);
                    try
                    {
                        repoAtt_AnnualLeaveDetail.SaveChanges();
                    }
                    catch (Exception)
                    {
                        return(false);
                    }

                    //EntityService.AddEntity<Att_AnnualLeaveDetail>(GuidContext, lstInsDetail.ToArray());
                    //DataErr = EntityService.SubmitChanges(GuidContext, LoginUserID);

                    //if (DataErr == DataErrorCode.Success)
                    //{
                    //    Common.MessageBoxs(Messages.Msg, Messages.SaveSuccess, MessageBox.Icon.INFO, string.Empty);
                    //}
                    //else
                    //{
                    //    Common.MessageBoxs(Messages.Msg, Messages.SaveUnSuccess, MessageBox.Icon.INFO, string.Empty);
                    //}
                }
                //else
                //{
                //    Common.MessageBoxs(Messages.Msg, Messages.NoDataToCompute, MessageBox.Icon.WARNING, string.Empty);
                //}
                result = true;
            }
            return(result);
        }
Beispiel #13
0
        private int ComputeAttendance(Guid userID, Guid asynTaskID, DateTime monthYear, Guid cutOffDurationID,
            out DataErrorCode dataErrorCode, int totalProfile, int totalComputed, params Hre_ProfileEntity[] listProfile)
        {
            using (var context = new VnrHrmDataContext())
            {
                IUnitOfWork unitOfWork = new UnitOfWork(context);
                int attendanceTableCount = 0;

                List<Guid> listProfileID = listProfile.Select(s => s.ID).ToList();
                totalProfile = totalProfile <= 0 ? listProfileID.Count() : totalProfile;

                #region Xóa bảng công cũ đã tính trước đó

                dataErrorCode = DeleteAttendance(monthYear,
                    cutOffDurationID, listProfileID);

                if (dataErrorCode == DataErrorCode.Locked
                    || dataErrorCode == DataErrorCode.Error)
                {
                    return attendanceTableCount;
                }

                #endregion

                #region Tính khoảng thời gian theo cutOffDurationID

                DateTime attendanceFrom = monthYear.AddDays(1 - monthYear.Day).Date;
                DateTime attendanceTo = attendanceFrom.AddMonths(1).AddSeconds(-1);

                var cutOffDuration = unitOfWork.CreateQueryable<Att_CutOffDuration>(Guid.Empty,
                    d => d.ID == cutOffDurationID).Select(d => new
                    {
                        d.DateStart,
                        d.DateEnd,
                        d.OvertimeStart,
                        d.OvertimeEnd,
                        d.LeavedayStart,
                        d.LeavedayEnd,
                    }).FirstOrDefault();

                if (cutOffDuration != null)
                {
                    attendanceFrom = cutOffDuration.DateStart;
                    attendanceTo = cutOffDuration.DateEnd;
                }

                #endregion

                #region Tải các thông tin danh mục có liên quan

                string overTimeMethod = MethodOption.E_CASHOUT.ToString();
                string overTimeStatus = OverTimeStatus.E_APPROVED.ToString();
                string pregnancyType = PregnancyType.E_LEAVE_EARLY.ToString();
                string leaveStatus = LeaveDayStatus.E_APPROVED.ToString();
                string hdtJobStatus = HDTJobStatus.E_APPROVE.ToString();
                string leavedayTypeNOPAY = LeavedayTypeCode.NOPAY.ToString();
                string leavedayTypeABS = LeavedayTypeCode.ABS.ToString();
                string leavedayTypeHLD = LeavedayTypeCode.HLD.ToString();
                string rosterStatus = RosterStatus.E_APPROVED.ToString();

                string NOTAUTOREGISTERHOLIDAYLEAVE = AppConfig.HRM_ATT_NOTAUTOREGISTERHOLIDAYLEAVE.ToString();
                string OT_HOLIDAYSCOMPUTE400 = AppConfig.HRM_ATT_OT_HOLIDAYSCOMPUTE400.ToString();
                string MISSTAM_LEAVETYPE = AppConfig.HRM_ATT_MISSTAM_LEAVETYPE.ToString();
                string HRM_ATT_OT_OVERTIMESTATUS = AppConfig.HRM_ATT_OT_OVERTIMESTATUS.ToString();

                var standardWorkdayConfig = unitOfWork.CreateQueryable<Sys_AllSetting>(d => d.Name == NOTAUTOREGISTERHOLIDAYLEAVE
                    || d.Name == OT_HOLIDAYSCOMPUTE400 || d.Name == MISSTAM_LEAVETYPE || d.Name == HRM_ATT_OT_OVERTIMESTATUS).ToList();

                var notAutoRegHolidayLeave = standardWorkdayConfig.Where(s => s.Name == NOTAUTOREGISTERHOLIDAYLEAVE).FirstOrDefault();
                var otholidayscompute400 = standardWorkdayConfig.Where(s => s.Name == OT_HOLIDAYSCOMPUTE400).FirstOrDefault();
                var missTAM_LeaveType = standardWorkdayConfig.Where(s => s.Name == MISSTAM_LEAVETYPE).FirstOrDefault();
                var statusOT = standardWorkdayConfig.Where(s => s.Name == HRM_ATT_OT_OVERTIMESTATUS).FirstOrDefault();

                if (statusOT != null)
                {
                    overTimeStatus = statusOT.Value1;
                }

                DateTime startYear = new DateTime(monthYear.Year, 1, 1).AddMonths(-1);//đầu năm
                DateTime endYear = new DateTime(monthYear.Year, 12, 31).Date.AddDays(1).AddSeconds(-1);
                DateTime preMonthYear = monthYear.AddMonths(-1);

                List<Cat_DayOff> listHoliday = unitOfWork.CreateQueryable<Cat_DayOff>(d =>
                    d.DateOff >= startYear && d.DateOff <= endYear).ToList();

                //Tất cả roster từ đầu năm đến thời điểm tính công - cần cho mục tính tính phép năm còn lại cho từng nhân viên.
                var listRoster = unitOfWork.CreateQueryable<Att_Roster>(d => d.DateStart <= attendanceTo && d.DateEnd >= startYear
                    && d.Status == rosterStatus && 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>(m => m.DateStart != null && m.DateEnd != null
                    && m.DateStart <= attendanceTo && m.DateEnd >= attendanceFrom).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 listWorkHistory = unitOfWork.CreateQueryable<Hre_WorkHistory>(d => d.DateEffective <= attendanceTo
                    && listProfileID.Contains(d.ProfileID)).ToList();

                List<Att_Roster> lstRosterTypeGroup = new List<Att_Roster>();
                List<Att_RosterGroup> lstRosterGroup = new List<Att_RosterGroup>();

                GetRosterGroup(listProfileID, startYear, attendanceTo, out lstRosterTypeGroup, out lstRosterGroup);
                var listLateEarlyRule = unitOfWork.CreateQueryable<Cat_LateEarlyRule>().ToList<Cat_LateEarlyRule>();
                var listShift = unitOfWork.CreateQueryable<Cat_Shift>().ToList<Cat_Shift>();

                var currentYear = unitOfWork.CreateQueryable<Att_AnnualDetail>(d => monthYear == d.MonthYear).Select(d => d.Year).FirstOrDefault();
                var monthStart = unitOfWork.CreateQueryable<Att_AnnualDetail>(d => d.Year == currentYear).OrderBy(d => d.MonthYear).Select(d => d.MonthYear).FirstOrDefault();

                var listAnnualDetail = unitOfWork.CreateQueryable<Att_AnnualDetail>(d => d.MonthYear == monthStart
                    && d.ProfileID.HasValue && listProfileID.Contains(d.ProfileID.Value));

                var listPreAttendanceTable = unitOfWork.CreateQueryable<Att_AttendanceTable>(d => d.MonthYear.HasValue
                    && d.MonthYear == preMonthYear && listProfileID.Contains(d.ProfileID)).Select(d =>
                        new Att_AttendanceTableEntity
                        {
                            ID = d.ID,
                            AnlDayTaken = d.AnlDayTaken,
                            AnlDayAdjacent = d.AnlDayAdjacent,
                            SickDayTaken = d.SickDayTaken,
                            SickDayAdjacent = d.SickDayAdjacent,
                            AnlDayAvailable = d.AnlDayAvailable,
                            SickDayAvailable = d.SickDayAvailable,
                            ProfileID = d.ProfileID
                        }).ToList<Att_AttendanceTableEntity>();

                var listPregnancy = unitOfWork.CreateQueryable<Att_Pregnancy>(d => d.DateEnd >= attendanceFrom && d.DateStart <= attendanceTo
                    && d.Type == pregnancyType && listProfileID.Contains(d.ProfileID)).Select(d => new Att_PregnancyEntity
                    {
                        ID = d.ID,
                        ProfileID = d.ProfileID,
                        DateStart = d.DateStart,
                        DateEnd = d.DateEnd,
                        TypePregnancyEarly = d.TypePregnancyEarly
                    }).ToList<Att_PregnancyEntity>();

                var listOvertime = unitOfWork.CreateQueryable<Att_Overtime>(d => d.Status == overTimeStatus
                    && (d.MethodPayment == null || d.MethodPayment == overTimeMethod) && d.WorkDateRoot >= attendanceFrom
                    && d.WorkDateRoot <= attendanceTo && listProfileID.Contains(d.ProfileID)).Select(d => new Att_OvertimeEntity
                    {
                        ID = d.ID,
                        ProfileID = d.ProfileID,
                        OvertimeTypeID = d.OvertimeTypeID,
                        DurationType = d.DurationType,
                        WorkDateRoot = d.WorkDateRoot,
                        WorkDate = d.WorkDate,
                        ApproveHours = d.ApproveHours,
                        ConfirmHours = d.ConfirmHours,
                        RegisterHours = d.RegisterHours
                    }).ToList<Att_OvertimeEntity>();

                List<Guid> listOvertimeTypeID = listOvertime.Select(o => o.OvertimeTypeID).Distinct().ToList();
                var listOvertimeType = unitOfWork.CreateQueryable<Cat_OvertimeType>(d => listOvertimeTypeID.Contains(d.ID)).ToList();

                var listLeaveDay = unitOfWork.CreateQueryable<Att_LeaveDay>(d => d.Status == leaveStatus && ((d.DateStart <= attendanceTo
                    && d.DateEnd >= attendanceFrom) || d.DateOvertimeOff >= attendanceFrom && d.DateOvertimeOff <= attendanceTo)
                    && listProfileID.Contains(d.ProfileID)).Select(d => new Att_LeaveDayEntity
                    {
                        ID = d.ID,
                        ProfileID = d.ProfileID,
                        DateStart = d.DateStart,
                        DateEnd = d.DateEnd,
                        DateOvertimeOff = d.DateOvertimeOff,
                        LeaveDayTypeID = d.LeaveDayTypeID,
                        DurationType = d.DurationType,
                        LeaveHours = d.LeaveHours,
                        LeaveDays = d.LeaveDays
                    }).ToList<Att_LeaveDayEntity>();

                List<Guid> listLeaveDayTypeID = listLeaveDay.Select(o => o.LeaveDayTypeID).Distinct().ToList();
                var listLeaveDayType = unitOfWork.CreateQueryable<Cat_LeaveDayType>(d => listLeaveDayTypeID.Contains(d.ID)
                    || d.Code == leavedayTypeABS || d.Code == leavedayTypeNOPAY || d.Code == leavedayTypeHLD).ToList();

                List<Hre_HDTJob> listHDTJob = new List<Hre_HDTJob>();
                foreach (var templstProfileIds in listProfileID.Chunk(1000))
                {
                    listHDTJob.AddRange(unitOfWork.CreateQueryable<Hre_HDTJob>(d => d.Status == hdtJobStatus && ((d.DateFrom <= attendanceTo && d.DateTo == null)
                    || (d.DateTo != null && d.DateFrom <= attendanceTo && d.DateTo >= attendanceFrom)) && templstProfileIds.Contains(d.ProfileID.Value)).ToList());
                }
                //var listHDTJob = unitOfWork.CreateQueryable<Hre_HDTJob>(d => d.Status == hdtJobStatus && ((d.DateFrom <= attendanceTo && d.DateTo == null)
                //    || (d.DateTo != null && d.DateFrom <= attendanceTo && d.DateTo >= attendanceFrom)) && listProfileID.Contains(d.ProfileID.Value)).ToList();

                //Danh sách cấu hình grade theo danh sách nhân viên có trong danh sách mã thẻ
                var listGrade = unitOfWork.CreateQueryable<Att_Grade>(d => d.MonthStart.HasValue && d.MonthStart <= attendanceTo
                    && listProfileID.Contains(d.ProfileID.Value)).Select(d => new
                    {
                        d.ProfileID,
                        d.MonthStart,
                        d.GradeAttendanceID
                    }).ToList();

                listGrade = listGrade.GroupBy(d => d.ProfileID).Select(d =>
                    d.OrderByDescending(p => p.MonthStart).FirstOrDefault()).ToList();

                //Danh sách cấu hình gradeCfg theo danh sách grade tìm được ở trên
                var listGradeCfgID = listGrade.Select(d => d.GradeAttendanceID).Distinct().ToList();
                var listGradeCfg = unitOfWork.CreateQueryable<Cat_GradeAttendance>(d => listGradeCfgID.Contains(d.ID)).ToList();

                var lstTimeOffInLieu = unitOfWork.CreateQueryable<Att_TimeOffInLieu>(d => d.Date != null
                    && d.Date >= attendanceFrom && d.Date <= attendanceTo).Select(m => new
                    {
                        m.ProfileID,
                        m.UnusualLeaves,
                        m.TakenLeaves
                    }).ToList();

                DateTime month3Ago = new DateTime(attendanceTo.Year, attendanceTo.Month, 1);
                month3Ago = month3Ago.AddMonths(-3);

                List<Att_TimeOffInLieuMonth> lstTimeOffInLieu_ByMonth_3Month = unitOfWork.CreateQueryable<Att_TimeOffInLieuMonth>(d =>
                    d.Month != null && d.Month >= month3Ago && d.Month <= attendanceTo && listProfileID.Contains(d.ProfileID)).ToList();

                List<Att_TimeOffInLieuMonth> lstTimeOffInLieuMonth = lstTimeOffInLieu_ByMonth_3Month.Where(d =>
                    d.Month != null && d.Month >= attendanceFrom && d.Month <= attendanceTo).ToList<Att_TimeOffInLieuMonth>();

                List<Att_TimeOffInLieuMonth> lstTimeOffInLieuMonthInsert = new List<Att_TimeOffInLieuMonth>();
                DateTime beginYear = new DateTime(attendanceTo.Year, 1, 1);

                #endregion

                #region Bắt đầu tính công cho từng người

                var listWorkDay = unitOfWork.CreateQueryable<Att_Workday>(d => d.WorkDate >= attendanceFrom
                    && d.WorkDate <= attendanceTo && listProfileID.Contains(d.ProfileID)).ToList();

                List<Att_TimeOffInLieu> lstTimeOffInLieu_3Month = unitOfWork.CreateQueryable<Att_TimeOffInLieu>(d =>
                    d.Date >= month3Ago && d.Date <= attendanceTo && listProfileID.Contains(d.ProfileID)).ToList();

                var listTimeOffInLieu = lstTimeOffInLieu_3Month.Where(s => listProfileID.Contains(s.ProfileID)
                    && attendanceFrom <= s.Date && s.Date <= attendanceTo).Select(s => new Att_TimeOffInLieuEntity
                    {
                        ID = s.ID,
                        Date = s.Date,
                        ProfileID = s.ProfileID,
                        OvertimeID = s.OvertimeID,
                        LeaveDayID = s.LeaveDayID,
                        UnusualLeaves = s.UnusualLeaves,
                        LeaveHours = s.LeaveHours,
                        TakenLeaves = s.TakenLeaves
                    }).ToList<Att_TimeOffInLieuEntity>();

                using (var taskContext = new VnrHrmDataContext())
                {
                    IUnitOfWork 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 = 50;
                    int totalComputedProfileForSubmit = 0;
                    int totalComputedProfileForTask = 0;

                    totalComputedProfileMustSubmitTask = totalProfile * 5 / 100;

                    if (totalComputedProfileMustSubmitTask > listProfile.Count())
                    {
                        totalComputedProfileMustSubmitTask = listProfile.Count();
                    }

                    foreach (var profileId in listProfileID)
                    {
                        try
                        {
                            #region Những dữ liệu liên quan tính công theo từng nhân viên

                            var profile = listProfile.Where(d => d.ID == profileId).FirstOrDefault();
                            var listAnnualDetailByProfile = listAnnualDetail.Where(d => d.ProfileID == profileId).ToList();
                            var listPreAttendanceTableByProfile = listPreAttendanceTable.Where(d => d.ProfileID == profileId).ToList();
                            var listWorkDayByProfile = listWorkDay.Where(d => d.ProfileID == profileId).OrderBy(d => d.WorkDate).ToList();
                            var listTimeOffInLieuByProfile = listTimeOffInLieu.Where(d => d.ProfileID == profileId).ToList();

                            var listHDTJobByProfile = listHDTJob.Where(d => d.ProfileID == profileId).ToList();
                            var listPregnancyByProfile = listPregnancy.Where(prg => prg.ProfileID == profileId && prg.DateEnd >= attendanceFrom && prg.DateStart <= attendanceTo).ToList();
                            var listLeaveDayByProfile = listLeaveDay.Where(d => d.ProfileID == profileId && ((d.DateStart <= attendanceTo && d.DateEnd >= attendanceFrom)
                                || (d.DateOvertimeOff.HasValue && d.DateOvertimeOff >= attendanceFrom && d.DateOvertimeOff <= attendanceTo))).ToList();

                            var listOvertimeByProfile = listOvertime.Where(d => d.ProfileID == profileId && d.WorkDate >= attendanceFrom && d.WorkDate <= attendanceTo).ToList();
                            var gradeCfgIDByProfile = listGrade.Where(d => d.ProfileID == profileId && d.MonthStart <= attendanceTo).Select(d => d.GradeAttendanceID).FirstOrDefault();
                            var gradeCfgByProfile = listGradeCfg.Where(d => d.ID == gradeCfgIDByProfile).FirstOrDefault();

                            List<Hre_WorkHistory> listWorkHistoryByProfile = listWorkHistory.Where(d => d.ProfileID == profileId).ToList();
                            var listRosterByProfile = listRoster.Where(d => d.ProfileID == profileId && d.DateStart <= attendanceTo && d.DateEnd >= attendanceFrom).ToList();
                            var listMonthShifts = Att_AttendanceLib.GetDailyShifts(attendanceFrom, attendanceTo, profile.ID, listRosterByProfile, listRosterGroup);

                            #endregion

                            attendanceTableCount += ComputeAttendance(unitOfWork, userID, monthYear, cutOffDurationID, attendanceFrom, attendanceTo, profile,
                                gradeCfgByProfile, listShift, listAnnualDetailByProfile, listHDTJobByProfile, listLeaveDayByProfile, listLeaveDayType,
                                listOvertimeByProfile, listOvertimeType, listPregnancyByProfile, listLateEarlyRule, listWorkDayByProfile,
                                listPreAttendanceTableByProfile, listTimeOffInLieuByProfile, notAutoRegHolidayLeave, otholidayscompute400,
                                missTAM_LeaveType, listMonthShifts, listHoliday);

                            #region Cập Nhật Dữ Liệu Cho Việc Tính TimeOffInLieuMonth and Year

                            double? balanceLeaves = (new Att_LeavedayServices()).CalculateTotalHourTimeOff(profileId, lstTimeOffInLieu_3Month.Where(m =>
                                m.ProfileID == profileId).ToList(), lstTimeOffInLieu_ByMonth_3Month.Where(m => m.ProfileID == profileId).ToList(), monthYear, 1);

                            double UnusualLeaves = lstTimeOffInLieu.Where(m => m.ProfileID == profileId).Sum(m => m.UnusualLeaves ?? 0);
                            double TakenLeaves = lstTimeOffInLieu.Where(m => m.ProfileID == profileId).Sum(m => m.TakenLeaves ?? 0);
                            double RemainLeaves = UnusualLeaves - TakenLeaves + (balanceLeaves ?? 0);

                            var timeOffInLieuMonth_ByProfile = lstTimeOffInLieuMonth.Where(m =>
                                m.ProfileID == profileId).FirstOrDefault();

                            if (timeOffInLieuMonth_ByProfile == null)
                            {
                                //tạo mới
                                timeOffInLieuMonth_ByProfile = new Att_TimeOffInLieuMonth();
                                timeOffInLieuMonth_ByProfile.ID = Guid.NewGuid();
                                timeOffInLieuMonth_ByProfile.ProfileID = profileId;
                                timeOffInLieuMonth_ByProfile.BalanceLeaves = balanceLeaves ?? 0;
                                timeOffInLieuMonth_ByProfile.UnusualLeaves = UnusualLeaves;
                                timeOffInLieuMonth_ByProfile.TakenLeaves = TakenLeaves;
                                timeOffInLieuMonth_ByProfile.RemainLeaves = RemainLeaves;
                                timeOffInLieuMonth_ByProfile.Month = new DateTime(attendanceTo.Year, attendanceTo.Month, 1);
                                unitOfWork.AddObject(typeof(Att_TimeOffInLieuMonth), timeOffInLieuMonth_ByProfile);
                            }
                            else
                            {
                                //chinh sua
                                timeOffInLieuMonth_ByProfile.BalanceLeaves = balanceLeaves ?? 0;
                                timeOffInLieuMonth_ByProfile.UnusualLeaves = UnusualLeaves;
                                timeOffInLieuMonth_ByProfile.TakenLeaves = TakenLeaves;
                                timeOffInLieuMonth_ByProfile.RemainLeaves = RemainLeaves;
                            }

                            #endregion

                            #region Chia thành nhiều giai đoạn lưu bảng công

                            if (asynTask != null)
                            {
                                totalComputedProfileForTask++;
                                double percent = (double)totalComputedProfileForTask / (double)totalProfile;

                                if (totalComputedProfileForTask >= totalComputedProfileMustSubmitTask)
                                {
                                    asynTask.PercentComplete = asynTask.PercentComplete + percent;
                                    dataErrorCode = taskUnitOfWork.SaveChanges(userID);
                                    totalComputedProfileForTask = 0;

                                    if (dataErrorCode == DataErrorCode.Locked)
                                    {
                                        break;
                                    }
                                }
                            }

                            //Nên submit lần đầu tiên khi đã tính được 5 profile
                            bool firstSubmit = listProfileID.ToList().IndexOf(profileId) == 5;
                            firstSubmit = totalComputed >= 5 ? false : firstSubmit;//đã chạy 1 lần
                            totalComputedProfileForSubmit++;

                            if (firstSubmit || totalComputedProfileForSubmit >= totalComputedProfileMustSubmit)
                            {
                                totalComputedProfileForSubmit = firstSubmit ? totalComputedProfileForSubmit : 0;
                                dataErrorCode = unitOfWork.SaveChanges(userID);

                                if (dataErrorCode == DataErrorCode.Locked)
                                {
                                    break;
                                }
                            }

                            #endregion
                        }
                        catch
                        {
                            throw new Exception(profileId.ToString());
                        }
                    }
                }

                #endregion

                //Lưu tất cả kết quả tính công
                dataErrorCode = unitOfWork.SaveChanges(userID);
                return attendanceTableCount;
            }
        }
Beispiel #14
0
        private void ComputeAttendance(Guid asynTaskID, Guid userID, DateTime monthYear,
            Guid cutOffDurationID, out DataErrorCode dataErrorCode, params Hre_ProfileEntity[] listProfile)
        {
            try
            {
                int resultCount = 0;
                int pageSize = 500;

                dataErrorCode = DataErrorCode.Success;
                int totalProfile = listProfile.Count();

                #region Xử lý cho những nhân viên được chọn

                //Vinhtran - 20140625: Chia theo pagesize để không bị quá tải ram
                foreach (var listProfileSplit in listProfile.Chunk(pageSize))
                {
                    if (dataErrorCode == DataErrorCode.Success)
                    {
                        resultCount += ComputeAttendance(userID, asynTaskID, monthYear, cutOffDurationID,
                            out dataErrorCode, totalProfile, resultCount, listProfileSplit.ToArray());
                    }
                    else
                    {
                        break;
                    }
                }

                #endregion

                #region Lưu Sys_AsynTask khi xử lý xong

                CompleteComputingTask(asynTaskID, userID,
                    resultCount, totalProfile, dataErrorCode);

                #endregion
            }
            catch (Exception)
            {
                throw;
            }
        }
Beispiel #15
0
        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();
        }