public ActionResult Edit(int id, ContactLevelInfoModel modelCache = null)
        {
            var user = UserContext.GetCurrentUser();
            if (user == null) return RedirectToAction("FilterContactToday", "ContactFilter", new { area = "Admin" });

            var contactInfo = ContactRepository.GetInfo(id);
            if (contactInfo == null) return RedirectToAction("FilterContactToday", "ContactFilter", new { area = "Admin" });

            if (user.GroupConsultantType == (int)GroupConsultantType.Consultant && user.UserID != contactInfo.UserConsultantId)
                return RedirectToAction("FilterContactToday", "ContactFilter", new { area = "Admin" });

            ViewBag.Id = id;
            ViewBag.IsView = user.UserID != contactInfo.UserConsultantId ? 1 : 0;
            //List Products
            ViewBag.Products = CatalogRepository.GetAll<ProductInfo>();

            if (user.GroupConsultantType == (int)GroupConsultantType.ManagerConsultant)
                ViewBag.IsView = 0;
            var contactLevelInfo = ContactLevelInfoRepository.GetInfoByContactId(id) ?? new ContactLevelInfo();
            var model = InitModel(contactInfo, contactLevelInfo);
            if (model.ContactInfo != null)
            {
                if (modelCache != null && modelCache.ContactInfo != null)
                {
                    model.ContactInfo.QualityId = modelCache.ContactInfo.QualityId;
                    model.ContactInfo.CallInfoConsultant = modelCache.ContactInfo.CallInfoConsultant;
                    model.ContactInfo.StatusMapConsultantId = modelCache.ContactInfo.StatusMapConsultantId;
                    model.ContactInfo.StatusCareConsultantId = modelCache.ContactInfo.StatusCareConsultantId;
                }
                else
                {
                    model.ContactInfo.QualityId = 0;
                    model.ContactInfo.StatusMapConsultantId = 0;
                    model.ContactInfo.StatusCareConsultantId = 0;
                    model.ContactInfo.CallInfoConsultant = string.Empty;
                }
            }
            return View(model);
        }
        public ActionResult Edit(ContactLevelInfoModel model)
        {
            try
            {
                model.ContactInfo.Mobile1 = Util.CleanAlphabetAndFirstZero(model.ContactInfo.Mobile1);
                model.ContactInfo.Mobile2 = Util.CleanAlphabetAndFirstZero(model.ContactInfo.Mobile2);
                model.ContactInfo.Mobile3 = Util.CleanAlphabetAndFirstZero(model.ContactInfo.Mobile3);
                var duplicateId = CheckDuplicateProvider.Instance().IsDuplicate(string.Empty, model.ContactInfo.Mobile2, string.Empty, string.Empty, string.Empty, model.ContactInfo.Id);
                if (duplicateId == 0) duplicateId = CheckDuplicateProvider.Instance().IsDuplicate(string.Empty, string.Empty, model.ContactInfo.Mobile3, string.Empty, string.Empty, model.ContactInfo.Id);
                if (duplicateId == 0) duplicateId = CheckDuplicateProvider.Instance().IsDuplicate(string.Empty, string.Empty, string.Empty, model.ContactInfo.Email, string.Empty, model.ContactInfo.Id);
                if (duplicateId == 0) duplicateId = CheckDuplicateProvider.Instance().IsDuplicate(string.Empty, string.Empty, string.Empty, string.Empty, model.ContactInfo.Email2, model.ContactInfo.Id);
                if (duplicateId == 0) duplicateId = ContactRepository.ContactIsDuplicate(model.ContactInfo.Mobile1, model.ContactInfo.Mobile2, model.ContactInfo.Mobile3, model.ContactInfo.Email, model.ContactInfo.Email2, model.ContactInfo.Id);
                if (duplicateId > 0 && duplicateId != model.ContactInfo.Id)
                {
                    var contactInfoDb = ContactRepository.GetInfo(duplicateId);
                    if (contactInfoDb == null)
                        ViewBag.Message = "Cập nhật contact bị lỗi do trùng với contact khác trong hệ thống";
                    else
                    {
                        var user = StoreData.ListUser.FirstOrDefault(c => c.UserID == contactInfoDb.UserConsultantId) ??
                                       UserRepository.GetInfo(contactInfoDb.UserConsultantId);

                        ViewBag.Message = user == null
                                              ? "Sđt hoặc Email bạn nhập đã bị trùng với Ứng viên: " + contactInfoDb.Id + " - " + contactInfoDb.Fullname + " - Level " + contactInfoDb.LevelId + " - TVTS: chưa có ai chăm sóc"
                                              : "Sđt hoặc Email bạn nhập đã bị trùng với Ứng viên: " + contactInfoDb.Id + " - " + contactInfoDb.Fullname + " - Level " + contactInfoDb.LevelId + " - TVTS: " + user.FullName;
                    }
                    return Edit(model.ContactInfo.Id, model);
                }

                // Get statusmap
                var statusMapInfo = GetStatusMap(model, EmployeeType.Consultant);
                if (statusMapInfo == null)
                {
                    ViewBag.Message = "Cập nhật contact bị lỗi do không tìm thấy trạng thái chăm sóc";
                    return Edit(model.ContactInfo.Id, model);
                }

                // Delete Redis
                StoreData.DeleteRedis(model.ContactInfo.Id);

                // Update
                var entity = new ContactAllInfo
                                 {
                                     Mobile1 = model.ContactInfo.Mobile1,
                                     Mobile2 = model.ContactInfo.Mobile2,
                                     Mobile3 = model.ContactInfo.Mobile3,
                                     ContactInfo = model.ContactInfo,
                                     ContactLevelInfo = model.ContactLevelInfo,
                                 };
                UpdateContactLevelInfo(entity, model, EmployeeType.Consultant);
                UpdateCallHistoryInfo(entity, model, statusMapInfo, EmployeeType.Consultant);
                UpdateContactInfo(entity, model, statusMapInfo, EmployeeType.Consultant);
                UpdateMissedCallInfo(entity);
                var contactId = ContactAllRepository.Update(entity, EmployeeType.Consultant);
                if (contactId > 0)
                {
                    ViewBag.Close = 1;
                    ViewBag.Message = "Cập nhật contact thành công";

                    // Redis
                    StoreData.LoadRedis(entity.ContactInfo.Id);
                }
                else
                {
                    ViewBag.Close = 0;
                    ViewBag.Message = "Cập nhật contact bị lỗi, vui lòng thử lại sau";

                    // Redis
                    StoreData.DeleteRedis(model.ContactInfo.Mobile1, model.ContactInfo.Mobile2, model.ContactInfo.Mobile3, model.ContactInfo.Email, model.ContactInfo.Email2, model.ContactInfo.Id);
                }

                // Repair call
                try
                {
                    StoreData.WsUpdateCallHistoryInfo(entity.CallHistoryInfo.CallHistoryId);
                }
                catch
                {

                }

                // Return
                return Edit(model.ContactInfo.Id, model);
            }
            catch
            {
                ViewBag.Close = 0;
                ViewBag.Message = "Cập nhật contact bị lỗi, vui lòng thử lại sau";

                // Redis
                try
                {
                    StoreData.DeleteRedis(model.ContactInfo.Mobile1, model.ContactInfo.Mobile2,
                        model.ContactInfo.Mobile3, model.ContactInfo.Email, model.ContactInfo.Email2,
                        model.ContactInfo.Id);
                }
                catch
                {

                }
                return Edit(model.ContactInfo.Id, model);
            }
        }
        private ContactLevelInfoModel InitModel(ContactInfo contactInfo, ContactLevelInfo contactLevelInfo)
        {
            var model = new ContactLevelInfoModel
            {
                ContactInfo = contactInfo,
                ContactLevelInfo = contactLevelInfo,
            };
            if (model.ContactLevelInfo != null)
            {
                // AppointmentTime
                if (model.ContactLevelInfo.AppointmentTime != null)
                    model.AppointmentTime = model.ContactLevelInfo.AppointmentTime.Value.ToString("dd/MM/yyyy");

                // CasecAccountInfo
                var casecAccounts = CasecAccountRepository.GetAllByContactId(contactLevelInfo.ContactId) ?? new List<CasecAccountInfo>();
                model.CasecAccountInfo = casecAccounts.FirstOrDefault(c => c.StatusCasecAccountId == (int)StatusCasecType.Used);
                model.ContactLevelInfo.HasCasecAccount = model.CasecAccountInfo != null;
                model.ContactLevelInfo.HasCasecAccountHidden = model.ContactLevelInfo.HasCasecAccount;

                // TestResultCasecInfo
                model.TestResultCasecInfo = TestResultRepository.GetResultCasecCurent(contactLevelInfo.ContactId);
                if (model.TestResultCasecInfo != null)
                {
                    if (model.TestResultCasecInfo.FullName.IsStringNullOrEmpty())
                        model.TestResultCasecInfo.FullName = model.ContactInfo.Fullname;
                    model.ContactLevelInfo.HasPointTestCasec = true;
                    var casecAccount = casecAccounts.FirstOrDefault(c => c.Id == model.TestResultCasecInfo.CasecAccountId) ?? new CasecAccountInfo();
                    model.TestResultCasecInfo.Account = casecAccount.Account;
                    model.TestResultCasecInfo.Password = casecAccount.Password;
                }
                else model.ContactLevelInfo.HasPointTestCasec = false;
                model.ContactLevelInfo.HasPointTestCasecHidden = model.ContactLevelInfo.HasPointTestCasec;

                // TestResultInterviewInfo
                model.TestResultInterviewInfo = TestResultRepository.GetResultInterviewCurent(contactLevelInfo.ContactId);
                if (model.TestResultInterviewInfo != null)
                {
                    if (model.TestResultInterviewInfo.FullName.IsStringNullOrEmpty())
                        model.TestResultInterviewInfo.FullName = model.ContactInfo.Fullname;
                    model.ContactLevelInfo.HasPointInterview = true;
                }
                else model.ContactLevelInfo.HasPointInterview = false;
                model.ContactLevelInfo.HasPointInterviewHidden = model.ContactLevelInfo.HasPointInterview;

                // TestResultLinkSb100Info
                model.TestResultLinkSb100Info = TestResultRepository.GetResultLinkSb100Curent(contactLevelInfo.ContactId);
                if (model.TestResultLinkSb100Info != null)
                {
                    if (model.TestResultLinkSb100Info.FullName.IsStringNullOrEmpty())
                        model.TestResultLinkSb100Info.FullName = model.ContactInfo.Fullname;
                    model.ContactLevelInfo.HasLinkSb100 = true;
                }
                else model.ContactLevelInfo.HasLinkSb100 = false;
                model.ContactLevelInfo.HasLinkSb100Hidden = model.ContactLevelInfo.HasLinkSb100;

                // AppointmentInterviewInfo
                model.AppointmentInterviewInfo = AppointmentInterviewRepository.GetInfo(contactLevelInfo.ContactId);
                model.ContactLevelInfo.HasAppointmentInterview = model.AppointmentInterviewInfo != null;
                //if (model.AppointmentInterviewInfo != null &&
                //    model.AppointmentInterviewInfo.StatusInterviewId == (int)StatusInterviewType.HocVienHuyPhongVan)
                //{
                //    model.AppointmentInterviewInfo = null;
                //    model.ContactLevelInfo.HasAppointmentInterview = false;
                //}
                model.ContactLevelInfo.HasAppointmentInterviewHidden = model.ContactLevelInfo.HasAppointmentInterview;

                // SB100
                model.ContactLevelInfo.HasSetSb100Hidden = model.ContactLevelInfo.HasSetSb100;
            }

            if (model.ContactInfo != null)
            {
                // Phone
                var listPhone = PhoneRepository.GetByContact(contactInfo.Id);
                if (listPhone != null)
                {
                    model.ContactInfo.Mobile1 = listPhone.Count > 0 ? listPhone[0].PhoneNumber : string.Empty;
                    model.ContactInfo.Mobile2 = listPhone.Count > 1 ? listPhone[1].PhoneNumber : string.Empty;
                    model.ContactInfo.Mobile3 = listPhone.Count > 2 ? listPhone[2].PhoneNumber : string.Empty;
                }

                // Birthday
                if (model.ContactInfo.Birthday != null)
                    model.Birthday = model.ContactInfo.Birthday.Value.ToString("dd/MM/yyyy");
            }
            else model.ContactInfo = new ContactInfo();

            // StatusMaps
            List<StatusMapInfo> statusMaps;
            if (StoreData.ListStatusMap != null && StoreData.ListStatusMap.Count > 0)
            {
                statusMaps = model.ContactInfo == null
                                     ? StoreData.ListStatusMap
                                     : StoreData.ListStatusMap.Where(c => c.LevelId == model.ContactInfo.LevelId).ToList();
            }
            else
            {
                statusMaps = model.ContactInfo == null
                                         ? StatusMapRepository.GetAll()
                                         : StatusMapRepository.GetAllByLevelId(model.ContactInfo.LevelId);
            }
            ViewBag.StatusMaps = statusMaps != null && statusMaps.Count > 0
                                     ? statusMaps.Where(c => c.StatusMapType == (int)EmployeeType.Consultant).ToList()
                                     : new List<StatusMapInfo>();
            return model;
        }
        private static void UpdateContactLevelInfo(ContactAllInfo entity, ContactLevelInfoModel model, EmployeeType type)
        {
            if (model == null ||
                entity == null ||
                entity.ContactInfo == null ||
                entity.ContactLevelInfo == null)
                return;

            entity.ContactLevelInfo.ContactId = entity.ContactInfo.Id;
            if (!string.IsNullOrEmpty(model.AppointmentTime))
                entity.ContactLevelInfo.AppointmentTime = model.AppointmentTime.ToDateTime();
            switch (type)
            {
                case EmployeeType.Consultant:
                    if (!entity.ContactLevelInfo.HasAppointmentInterview)
                        entity.ContactLevelInfo.HasAppointmentInterview = entity.ContactLevelInfo.HasAppointmentInterviewHidden;
                    if (!entity.ContactLevelInfo.HasPointTestCasec)
                        entity.ContactLevelInfo.HasPointTestCasec = entity.ContactLevelInfo.HasPointTestCasecHidden;
                    if (!entity.ContactLevelInfo.HasPointInterview)
                        entity.ContactLevelInfo.HasPointInterview = entity.ContactLevelInfo.HasPointInterviewHidden;
                    if (!entity.ContactLevelInfo.HasCasecAccount)
                        entity.ContactLevelInfo.HasCasecAccount = entity.ContactLevelInfo.HasCasecAccountHidden;
                    if (!entity.ContactLevelInfo.HasLinkSb100)
                        entity.ContactLevelInfo.HasLinkSb100 = entity.ContactLevelInfo.HasLinkSb100Hidden;
                    if (!entity.ContactLevelInfo.HasSetSb100)
                        entity.ContactLevelInfo.HasSetSb100 = entity.ContactLevelInfo.HasSetSb100Hidden;
                    break;
            }
        }
        private static void UpdateContactInfo(ContactAllInfo entity, ContactLevelInfoModel model, StatusMapInfo statusMapInfo, EmployeeType type)
        {
            // Check
            if (model == null || entity == null || entity.ContactInfo == null)
                return;
            if (entity.ContactLevelInfo == null) entity.ContactLevelInfo = new ContactLevelInfo();

            // Get in Db
            entity.ContactInfo = ContactRepository.GetInfo(model.ContactInfo.Id);

            // AppointmentDate
            var datetime = string.IsNullOrEmpty(model.RecallTime) ? string.Empty : model.RecallTime;
            if (!datetime.IsStringNullOrEmpty())
                datetime += string.IsNullOrEmpty(model.RecallTime24h) ? " 00:00:00" : " " + model.RecallTime24h;
            var appointmentDate = string.IsNullOrEmpty(datetime) ? null : datetime.ToDateTime("dd/MM/yyyy HH:mm:ss");

            switch (type)
            {
                case EmployeeType.Collector:
                    break;
                case EmployeeType.Collaborator:
                    entity.ContactInfo.StatusCareCollaboratorId = statusMapInfo.StatusCareId;
                    entity.ContactInfo.CallCollaboratorDate = entity.CallHistoryInfo.CallTime;
                    entity.ContactInfo.CallInfoCollaborator = model.ContactInfo.CallInfoCollaborator;
                    entity.ContactInfo.StatusMapCollaboratorId = model.ContactInfo.StatusMapCollaboratorId;
                    entity.ContactInfo.CallCount = entity.ContactInfo.StatusCareCollaboratorId == (int)StatusCareType.UnKnown
                                        ? entity.ContactInfo.CallCount + 1
                                        : 0;
                    entity.ContactInfo.AppointmentCollaboratorDate = appointmentDate;
                    break;
                case EmployeeType.Consultant:
                    entity.ContactInfo.StatusCareConsultantId = statusMapInfo.StatusCareId;
                    entity.ContactInfo.CallConsultantDate = entity.CallHistoryInfo.CallTime;
                    entity.ContactInfo.CallInfoConsultant = model.ContactInfo.CallInfoConsultant;
                    entity.ContactInfo.StatusMapConsultantId = model.ContactInfo.StatusMapConsultantId;
                    entity.ContactInfo.CallCount = entity.ContactInfo.StatusCareConsultantId == (int)StatusCareType.UnKnown
                                        ? entity.ContactInfo.CallCount + 1
                                        : 0;
                    entity.ContactInfo.AppointmentConsultantDate = appointmentDate;
                    entity.ContactInfo.ProductSoldId = model.ContactInfo.ProductSoldId;
                    break;
            }
            entity.ContactInfo.Id = model.ContactInfo.Id;
            entity.ContactInfo.Email = model.ContactInfo.Email;
            entity.ContactInfo.Notes = model.ContactInfo.Notes;
            entity.ContactInfo.Email2 = model.ContactInfo.Email2;
            entity.ContactInfo.Gender = model.ContactInfo.Gender;
            entity.ContactInfo.Address = model.ContactInfo.Address;
            entity.ContactInfo.StatusId = statusMapInfo.StatusIdNext;
            entity.ContactInfo.Fullname = model.ContactInfo.Fullname;
            entity.ContactInfo.Birthday = model.Birthday.ToDateTime();
            entity.ContactInfo.CallCount = model.ContactInfo.CallCount;
            entity.ContactInfo.QualityId = model.ContactInfo.QualityId;
            entity.ContactInfo.ProductSellId = model.ContactInfo.ProductSellId;
            entity.ContactInfo.CreatedBy = UserContext.GetCurrentUser().UserID;
            if (statusMapInfo.LevelIdNext > 0) entity.ContactInfo.LevelId = statusMapInfo.LevelIdNext;
            entity.ContactInfo.HandoverHistoryConsultantId = model.ContactInfo.HandoverHistoryConsultantId;
        }
        private static void UpdateCallHistoryInfo(ContactAllInfo entity, ContactLevelInfoModel model, StatusMapInfo statusMapInfo, EmployeeType type)
        {
            if (model == null || entity == null || entity.ContactInfo == null)
                return;
            if (entity.ContactLevelInfo == null) entity.ContactLevelInfo = new ContactLevelInfo();

            var user = UserContext.GetCurrentUser();

            // Datetime
            var datetime = string.IsNullOrEmpty(model.RecallTime)
                               ? DateTime.Now.ToString("dd/MM/yyyy")
                               : model.RecallTime;
            datetime += string.IsNullOrEmpty(model.RecallTime24h)
                            ? " 00:00:00"
                            : " " + model.RecallTime24h;

            // CallInfo
            var callInfo = string.Empty;
            switch (type)
            {
                case EmployeeType.Collector:
                    break;
                case EmployeeType.Collaborator:
                    callInfo = model.ContactInfo.CallInfoCollaborator;
                    break;
                case EmployeeType.Consultant:
                    callInfo = model.ContactInfo.CallInfoConsultant;
                    break;
            }
            entity.CallHistoryInfo = new CallHistoryInfo
                                         {
                                             StatusUpdate = 1,
                                             UserLogType = (int)type,
                                             CreatedBy = user.UserID,
                                             CallTime = DateTime.Now,
                                             CallCenterInfo = callInfo,
                                             CreatedDate = DateTime.Now,
                                             StatusMapId = statusMapInfo.Id,
                                             ContactId = model.ContactInfo.Id,
                                             CallType = (int)CallType.Outcoming,
                                             LevelId = statusMapInfo.LevelIdNext,
                                             CallHistoryId = model.CallHistoryId,
                                             StatusCareId = statusMapInfo.StatusCareId,
                                             RecallTime = datetime.ToDateTime("dd/MM/yyyy HH:mm:ss"),
                                         };
        }
 private static StatusMapInfo GetStatusMap(ContactLevelInfoModel model, EmployeeType type)
 {
     if (model.ContactInfo == null) return null;
     var statusMaps = StoreData.ListStatusMap.Count == 0
                          ? StatusMapRepository.GetAll() ?? new List<StatusMapInfo>()
                          : StoreData.ListStatusMap;
     switch (type)
     {
         case EmployeeType.Collector:
             break;
         case EmployeeType.Collaborator:
             return statusMaps.FirstOrDefault(c => c.Id == model.ContactInfo.StatusMapCollaboratorId);
         case EmployeeType.Consultant:
             return statusMaps.FirstOrDefault(c => c.Id == model.ContactInfo.StatusMapConsultantId);
     }
     return null;
 }