/// <summary> /// Desassociates a Google Drive account /// </summary> /// <returns></returns> public ActionResult DesassociateGoogleDrive() { var dbGoogleAccountInfo = this.db.GoogleUserAccountInfo.FirstOrDefault(); if (dbGoogleAccountInfo != null) this.db.GoogleUserAccountInfo.DeleteObject(dbGoogleAccountInfo); var dbNotification = new Notification { CreatedOn = this.GetUtcNow(), PracticeId = this.DbPractice.Id, UserToId = this.DbUser.Id, Type = NotificationConstants.GOOGLE_DRIVE_DESASSOCIATED_NOTIFICATION_TYPE }; this.db.Notifications.AddObject(dbNotification); // mark all patients as not backed up foreach (var patient in this.db.Patients) patient.IsBackedUp = false; this.db.SaveChanges(); return this.RedirectToAction("Index"); }
/// <summary> /// Deprecated Method for adding a new object to the Notifications EntitySet. Consider using the .Add method of the associated ObjectSet<T> property instead. /// </summary> public void AddToNotifications(Notification notification) { base.AddObject("Notifications", notification); }
public void PatientArrived(int appointmentId, string time) { var appointment = this.db.Appointments.FirstOrDefault(p => p.Id == appointmentId); if (appointment == null) return; appointment.Status = (int)TypeAppointmentStatus.Accomplished; Debug.Assert(appointment.PatientId != null, "appointment.PatientId != null"); var notificationData = new PatientArrivedNotificationData() { PatientId = appointment.PatientId.Value, PatientName = appointment.Patient.Person.FullName, Time = time, PracticeIdentifier = appointment.Practice.UrlIdentifier, DoctorIdentifier = appointment.Doctor.UrlIdentifier }; var notificationDataString = new JavaScriptSerializer().Serialize(notificationData); var newNotification = new Notification() { CreatedOn = DateTime.UtcNow, IsClosed = false, UserToId = appointment.DoctorId, Type = NotificationConstants.PATIENT_ARRIVED_NOTIFICATION_TYPE, PracticeId = appointment.PracticeId, Data = notificationDataString }; this.db.Notifications.AddObject(newNotification); this.db.SaveChanges(); BroadcastDbNotification(newNotification, notificationData); }
/// <summary> /// Create a new Notification object. /// </summary> /// <param name="id">Initial value of the Id property.</param> /// <param name="createdOn">Initial value of the CreatedOn property.</param> /// <param name="practiceId">Initial value of the PracticeId property.</param> /// <param name="isClosed">Initial value of the IsClosed property.</param> /// <param name="type">Initial value of the Type property.</param> /// <param name="userToId">Initial value of the UserToId property.</param> public static Notification CreateNotification(global::System.Int32 id, global::System.DateTime createdOn, global::System.Int32 practiceId, global::System.Boolean isClosed, global::System.String type, global::System.Int32 userToId) { Notification notification = new Notification(); notification.Id = id; notification.CreatedOn = createdOn; notification.PracticeId = practiceId; notification.IsClosed = isClosed; notification.Type = type; notification.UserToId = userToId; return notification; }
public ActionResult CreateAccount(CreateAccountViewModel registrationData) { // If the user being edited is a medic, then we must check the fields that are required for medics. if (!registrationData.IsDoctor) { // Removing validation error of medic properties, because this user is not a medic. this.ModelState.ClearPropertyErrors(() => registrationData.MedicCRM); this.ModelState.ClearPropertyErrors(() => registrationData.MedicalEntityId); this.ModelState.ClearPropertyErrors(() => registrationData.MedicalSpecialtyId); this.ModelState.ClearPropertyErrors(() => registrationData.MedicalSpecialtyName); this.ModelState.ClearPropertyErrors(() => registrationData.MedicalEntityJurisdiction); } if (this.ModelState.Remove(e => e.ErrorMessage.Contains("requerido"))) this.ModelState.AddModelError("MultipleItems", "É necessário preencher todos os campos."); // Normalizing name properties. if (!string.IsNullOrEmpty(registrationData.PracticeName)) registrationData.PracticeName = Regex.Replace(registrationData.PracticeName, @"\s+", " ").Trim(); if (!string.IsNullOrEmpty(registrationData.FullName)) registrationData.FullName = Regex.Replace(registrationData.FullName, @"\s+", " ").Trim(); var urlPracticeId = StringHelper.GenerateUrlIdentifier(registrationData.PracticeName); var subscription = StringHelper.FirstNonEmpty(registrationData.Subscription, "trial"); if (!validSubscriptions.Contains(subscription) || registrationData.AsTrial == true) subscription = "trial"; // Note: Url identifier for the name of the user, don't need any verification. // The name of the user must be unique inside a practice, not the entire database. var alreadyLoggedUser = this.User as AuthenticatedPrincipal; Practice practiceToReuse = null; if (alreadyLoggedUser != null) { practiceToReuse = this.db.Practices .SingleOrDefault(p => p.UrlIdentifier == alreadyLoggedUser.Profile.PracticeIdentifier && p.AccountContract.IsPartialBillingInfo); } var alreadyExistingPractice = this.db.Practices.SingleOrDefault(p => p.UrlIdentifier == urlPracticeId); if (alreadyExistingPractice != null) { if (alreadyExistingPractice.AccountContract != null && alreadyExistingPractice.AccountContract.IsPartialBillingInfo) practiceToReuse = practiceToReuse ?? alreadyExistingPractice; else { // killing practice that already exists if it expires, and freeing the name for a new practice if (alreadyExistingPractice.AccountExpiryDate < this.GetUtcNow()) { alreadyExistingPractice.AccountDisabled = true; alreadyExistingPractice.UrlIdentifier += " !expired"; // change this, so that a new practice with this name can be created. this.db.SaveChanges(); } else { this.ModelState.AddModelError( () => registrationData.PracticeName, "Nome de consultório já está em uso."); } } } var utcNow = this.GetUtcNow(); // Creating the new user. User user; if (practiceToReuse == null) { var result = SecurityManager.CreateUser(out user, registrationData, this.db.Users, utcNow, null); if (result == CreateUserResult.InvalidUserNameOrPassword) { // Note: nothing to do because user-name and password fields are already validated. } if (result == CreateUserResult.UserNameAlreadyInUse) { this.ModelState.AddModelError( () => registrationData.UserName, // Todo: this message is also used in the App -> UsersController. "O nome de usuário não pode ser registrado pois já está em uso. " + "Note que nomes de usuário diferenciados por acentos, " + "maiúsculas/minúsculas ou por '.', '-' ou '_' não são permitidos." + "(Não é possível cadastrar 'MiguelAngelo' e 'miguel.angelo' no mesmo consultório."); } } else { user = this.db.Users.SingleOrDefault(u => u.Id == alreadyLoggedUser.Profile.Id && u.PracticeId == practiceToReuse.Id); SecurityManager.UpdateUser(user, registrationData, this.db.Users, utcNow); } if (user != null) { string timeZoneId = null; if (registrationData.PracticeProvince != null) timeZoneId = TimeZoneDataAttribute.GetAttributeFromEnumValue((TypeEstadoBrasileiro)registrationData.PracticeProvince.Value).Id; user.Practice = practiceToReuse ?? new Practice(); user.Practice.Name = registrationData.PracticeName; user.Practice.UrlIdentifier = urlPracticeId; user.Practice.CreatedOn = utcNow; user.Practice.WindowsTimeZoneId = timeZoneId; user.Practice.Province = registrationData.PracticeProvince; user.Practice.PhoneMain = registrationData.PracticePhone; // Setting the BirthDate of the user as a person. user.Person.DateOfBirth = PracticeController.ConvertToUtcDateTime(user.Practice, registrationData.DateOfBirth ?? new DateTime()); user.IsOwner = true; if (user.Administrator == null) user.Administrator = new Administrator { }; bool isNewDoctor = false; // when the user is a doctor, we need to fill the properties of the doctor if (registrationData.IsDoctor) { // if user is already a doctor, we just edit the properties // otherwise we create a new doctor instance if (user.Doctor == null) { user.Doctor = new Doctor(); isNewDoctor = true; } user.Doctor.CRM = registrationData.MedicCRM; if (registrationData.MedicalSpecialtyId != null) { var ms = this.db.SYS_MedicalSpecialty .Single(ms1 => ms1.Id == registrationData.MedicalSpecialtyId); user.Doctor.MedicalSpecialtyCode = ms.Code; user.Doctor.MedicalSpecialtyName = ms.Name; } if (registrationData.MedicalEntityId != null) { var me = this.db.SYS_MedicalEntity .Single(me1 => me1.Id == registrationData.MedicalEntityId); user.Doctor.MedicalEntityCode = me.Code; user.Doctor.MedicalEntityName = me.Name; } user.Doctor.MedicalEntityJurisdiction = ((TypeEstadoBrasileiro)registrationData.MedicalEntityJurisdiction).ToString(); // Creating an unique UrlIdentifier for this doctor. // This is the first doctor, so there will be no conflicts. var urlId = UsersController.GetUniqueDoctorUrlId(this.db.Doctors, registrationData.FullName, null); if (urlId == null) { this.ModelState.AddModelError( () => registrationData.FullName, // Todo: this message is also used in the UserController. "Quantidade máxima de homônimos excedida."); } user.Doctor.UrlIdentifier = urlId; } else { // todo: create a program that clears all orphaned Doctor objects user.Doctor = null; } if (practiceToReuse == null) this.db.Users.AddObject(user); if (this.ModelState.IsValid) { MailMessage emailMessageToUser = null; if (subscription == "trial") { // Creating confirmation email, with a token. emailMessageToUser = this.EmailMessageToUser(user, utcNow, subscription == "trial"); // Sending e-mail to tell us the good news. this.SendAccountCreatedSelfEmail(registrationData, user); } // If the ModelState is still valid, then save objects to the database, // and send confirmation email message to the user. using (emailMessageToUser) { // Saving changes to the DB. this.db.SaveChanges(); if (subscription == "trial") { // Creating a new trial account contract. var contract = user.Practice.AccountContract ?? new AccountContract(); contract.Practice = user.Practice; contract.ContractTypeId = (int)ContractTypes.TrialContract; contract.IsTrial = true; contract.IssuanceDate = utcNow; contract.StartDate = utcNow; contract.EndDate = null; // indeterminated contract.CustomText = null; contract.DoctorsLimit = null; contract.PatientsLimit = 50; // fixed limit for trial account // no billings contract.BillingAmount = null; contract.BillingDueDay = null; contract.BillingPaymentMethod = null; contract.BillingPeriodCount = null; contract.BillingPeriodSize = null; contract.BillingPeriodType = null; contract.BillingDiscountAmount = null; user.Practice.AccountExpiryDate = utcNow.AddHours(Constants.MAX_HOURS_TO_VERIFY_TRIAL_ACCOUNT); user.Practice.AccountContract = contract; if (practiceToReuse == null) this.db.AccountContracts.AddObject(contract); } else { // Creating a new account contract, getting info from the subscription string. var dicData = new Dictionary<string, dynamic>(StringComparer.InvariantCultureIgnoreCase) { { "1M", new { Price = Bus.Pro.PRICE_MONTH, PeriodSize = 1 } }, { "3M", new { Price = Bus.Pro.PRICE_QUARTER, PeriodSize = 3 } }, { "6M", new { Price = Bus.Pro.PRICE_SEMESTER, PeriodSize = 6 } }, { "12M", new { Price = Bus.Pro.PRICE_YEAR, PeriodSize = 12 } } }; var data = dicData[subscription]; var contract = user.Practice.AccountContract ?? new AccountContract(); contract.Practice = user.Practice; contract.ContractTypeId = (int)ContractTypes.ProfessionalContract; contract.IsTrial = false; contract.IssuanceDate = utcNow; contract.StartDate = null; // inderterminated (will be defined when user pays) contract.EndDate = null; // indeterminated contract.CustomText = null; contract.DoctorsLimit = null; // unknown at this moment (will be defined after user fills payment info) contract.PatientsLimit = null; // fixed limit for trial account // billings data can be redefined when the user fills payment info // for now these are the default values contract.IsPartialBillingInfo = true; // indicates that the billing info for this contract must be defined by the user contract.BillingAmount = Bus.Pro.PRICE_MONTH * (int)data.PeriodSize; contract.BillingDueDay = null; // payment method has no default (will be defined in the payment-info step) contract.BillingPaymentMethod = null; // payment method has no default (will be defined in the payment-info step) contract.BillingPeriodCount = null; contract.BillingPeriodSize = data.PeriodSize; contract.BillingPeriodType = "M"; contract.BillingDiscountAmount = (Bus.Pro.PRICE_MONTH * (int)data.PeriodSize) - data.Price; user.Practice.AccountExpiryDate = utcNow + Constants.MaxTimeToVerifyProfessionalAccount; user.Practice.AccountContract = contract; if (practiceToReuse == null) this.db.AccountContracts.AddObject(contract); } this.db.SaveChanges(); // if the new user is a doctor, create some other useful things // like some medical-certificates and a default health-insurance if (isNewDoctor) BusHelper.FillNewDoctorUtilityBelt(user.Doctor); if (practiceToReuse == null) { // adding message to the user so that he/she completes his/her profile informations // todo: add complete profile notification // If practice is being reused then notification was already sent. var notificationData = new CompletePracticeInfoNotificationData(); var notificationDataString = new JavaScriptSerializer().Serialize(notificationData); var dbNotification = new Notification { CreatedOn = this.GetUtcNow(), PracticeId = user.PracticeId, Data = notificationDataString, UserToId = user.Id, Type = NotificationConstants.COMPLETE_INFO_NOTIFICATION_TYPE, }; this.db.Notifications.AddObject(dbNotification); NotificationsHub.BroadcastDbNotification(dbNotification, notificationData); } if (practiceToReuse == null) { // If practice is being reused then these values were already set. user.Practice.Owner = user; user.Person.PracticeId = user.PracticeId; user.Administrator.PracticeId = user.PracticeId; if (user.Doctor != null) user.Doctor.PracticeId = user.PracticeId; } this.db.SaveChanges(); // Sending the confirmation e-mail to the new user. // This must be synchronous. // If practice is being reused then an email was already sent. if (practiceToReuse == null && emailMessageToUser != null) this.TrySendEmail(emailMessageToUser); // Log the user in. var loginModel = new LoginViewModel { Password = registrationData.Password, PracticeIdentifier = user.Practice.UrlIdentifier, RememberMe = false, UserNameOrEmail = registrationData.UserName, }; if (!SecurityManager.Login(this.HttpContext.Response.Cookies, loginModel, this.db.Users, out user, this.GetUtcNow())) { throw new Exception("Login cannot fail."); } if (subscription == "trial") return this.RedirectToAction("CreateAccountCompleted", new { practice = user.Practice.UrlIdentifier }); else return this.RedirectToAction("SetAccountPaymentInfo", new { practice = user.Practice.UrlIdentifier }); } } } this.ViewBag.MedicalSpecialtyOptions = this.db.SYS_MedicalSpecialty .ToList() .Select(me => new SelectListItem { Value = me.Id.ToString(), Text = me.Name }) .ToList(); this.ViewBag.MedicalEntityOptions = this.db.SYS_MedicalEntity .ToList() .Select(me => new SelectListItem { Value = me.Id.ToString(), Text = me.Name }) .ToList(); return this.View(registrationData); }
/// <summary> /// Generates notifications for new Medical Appointments /// </summary> private static void GenerateNotificationsForNewGenericAppointments( [NotNull] CerebelloEntities db, DateTime referenceTime, [NotNull] ICollection<Tuple<Notification, object>> notificationsToBeDispatched) { if (db == null) throw new ArgumentNullException("db"); if (notificationsToBeDispatched == null) throw new ArgumentNullException("notificationsToBeDispatched"); // check for appointments that have to be notified var timeOffset = referenceTime.AddMinutes(30); var unnotifiedAppointments = db.Appointments.Where( a => !a.Notified && a.Type == (int)TypeAppointment.GenericAppointment && a.Start >= referenceTime && a.Start < timeOffset).ToList(); foreach (var appointment in unnotifiedAppointments) { Debug.Assert(appointment.PatientId != null, "appointment.PatientId != null"); var genericAppointmentData = new GenericAppointmentNotificationData() { Text = appointment.Description, Time = DateTimeHelper.GetFormattedTime( PracticeController.ConvertToLocalDateTime(appointment.Practice, appointment.Start)) }; var genericAppointmentDataString = new JavaScriptSerializer().Serialize(genericAppointmentData); // notify the doctor var newNotification = new Notification() { CreatedOn = referenceTime, IsClosed = false, UserToId = appointment.DoctorId, Type = NotificationConstants.GENERIC_APPOINTMENT_NOTIFICATION_TYPE, PracticeId = appointment.PracticeId, Data = genericAppointmentDataString }; appointment.Doctor.Users.First().Notifications.Add(newNotification); notificationsToBeDispatched.Add(new Tuple<Notification, object>(newNotification, genericAppointmentData)); appointment.Notified = true; } db.SaveChanges(); }
/// <summary> /// Generates notifications for new Medical Appointments /// </summary> private static void GenerateNotificationsForNewMedicalAppointments( [NotNull] CerebelloEntities db, DateTime referenceTime, [NotNull] ICollection<Tuple<Notification, object>> notificationsToBeDispatched) { if (db == null) throw new ArgumentNullException("db"); if (notificationsToBeDispatched == null) throw new ArgumentNullException("notificationsToBeDispatched"); // check for appointments that have to be notified var timeOffset = referenceTime.AddMinutes(10); var unnotifiedAppointments = db.Appointments.Where( a => !a.Notified && a.Type == (int)TypeAppointment.MedicalAppointment && a.Start >= referenceTime && a.Start < timeOffset).ToList(); foreach (var appointment in unnotifiedAppointments) { Debug.Assert(appointment.PatientId != null, "appointment.PatientId != null"); var medicalAppointmentData = new MedicalAppointmentNotificationData { PatientId = appointment.PatientId.Value, PatientName = appointment.Patient.Person.FullName, DoctorName = appointment.Patient.Doctor.Users.First().Person.FullName, DoctorId = appointment.Patient.DoctorId, AppointmentId = appointment.Id, Time = DateTimeHelper.GetFormattedTime( PracticeController.ConvertToLocalDateTime(appointment.Practice, appointment.Start)), PracticeIdentifier = appointment.Practice.UrlIdentifier, DoctorIdentifier = appointment.Doctor.UrlIdentifier }; var medicalAppointmentDataString = new JavaScriptSerializer().Serialize(medicalAppointmentData); // for each secretary, I need to create a new notification foreach (var user in appointment.Practice.Users.Where(user => user.Secretary != null)) { var newNotification = new Notification() { CreatedOn = referenceTime, IsClosed = false, UserToId = user.Id, Type = NotificationConstants.MEDICAL_APPOINTMENT_NOTIFICATION_TYPE, PracticeId = appointment.PracticeId, Data = medicalAppointmentDataString }; user.Notifications.Add(newNotification); notificationsToBeDispatched.Add(new Tuple<Notification, object>(newNotification, medicalAppointmentData)); } appointment.Notified = true; } db.SaveChanges(); }
public ActionResult Edit(UserViewModel formModel) { var isEditingOrCreating = formModel.Id != null ? 'E' : 'C'; this.ViewBag.IsEditingOrCreating = isEditingOrCreating; var utcNow = this.GetUtcNow(); User user; // Normalizing the name of the person. if (!string.IsNullOrEmpty(formModel.FullName)) formModel.FullName = Regex.Replace(formModel.FullName, @"\s+", " ").Trim(); if (isEditingOrCreating == 'E') { // Note: User name cannot be edited, and should not be validated. this.ModelState.ClearPropertyErrors(() => formModel.UserName); user = this.db.Users.First(p => p.Id == formModel.Id); // TODO: suggest that r# use the attribute EdmScalarPropertyAttribute(IsNullable=false) // as a way to determine if a property can ever receive a null value or not // there was a bug in the line inside the following if, that could be detected by r# if it did consider that attribute. if (!string.IsNullOrWhiteSpace(formModel.FullName)) user.Person.FullName = formModel.FullName; user.Person.Gender = (short)formModel.Gender; // If there are model errors, we must return original user name to the view. formModel.UserName = user.UserName; } else { // UserName must not be null nor empty. if (string.IsNullOrWhiteSpace(formModel.UserName)) { this.ModelState.AddModelError(() => formModel.UserName, "Nome de usuário inválido."); } var loggedUser = this.DbUser; // Checking doctors limit of this account. if (formModel.IsDoctor) { var doctorsCount = this.DbPractice.Users.Count(u => u.DoctorId != null); if (doctorsCount >= this.DbPractice.AccountContract.DoctorsLimit) this.ModelState.AddModelError( "DoctorsLimit", "Essa conta está configurada para suportar até {0} médicos.", this.DbPractice.AccountContract.DoctorsLimit); } // Looking for another user with the same UserName or Email. var conflictingData = this.db.Users .Where(u => u.PracticeId == loggedUser.PracticeId) .Where(u => u.UserName == formModel.UserName || u.Person.Email == formModel.Email) .Select(u => new { u.UserName, u.Person.Email }) .ToList(); // Verifying wich fields are conflicting: Email. #warning [Validate] Must validate all emails. bool emailConflict = conflictingData.Any(c => c.Email == formModel.Email); // For every new user we must create a login, with a common // password used the first time the person logs in. // The only action allowed with this password, // is to change the password. var userData = new CreateAccountViewModel { UserName = formModel.UserName, Password = Constants.DEFAULT_PASSWORD, ConfirmPassword = Constants.DEFAULT_PASSWORD, EMail = formModel.Email, FullName = formModel.FullName, Gender = (short)formModel.Gender, }; // Creating the new user. // The user belongs to the same practice as the logged user. var result = SecurityManager.CreateUser(out user, userData, this.db.Users, utcNow, loggedUser.PracticeId); if (result == CreateUserResult.UserNameAlreadyInUse) { this.ModelState.AddModelError( () => formModel.UserName, // Todo: this message is also used in the AuthenticationController. "O nome de usuário não pode ser registrado pois já está em uso. " + "Note que nomes de usuário diferenciados por acentos, " + "maiúsculas/minúsculas ou por '.', '-' ou '_' não são permitidos." + "(Não é possível cadastrar 'MiguelAngelo' e 'miguel.angelo' no mesmo consultório."); } } #warning Must validade all emails, cannot repeat emails in the same practice. if (!formModel.IsDoctor && !formModel.IsAdministrador && !formModel.IsSecretary) this.ModelState.AddModelError("", "Usuário tem que ter pelo menos uma função: médico, administrador ou secretária."); // If the user being edited is a doctor, then we must check the fields that are required for medics. if (!formModel.IsDoctor) { // Removing validation error of medic properties, because this user is not a medic. this.ModelState.ClearPropertyErrors(() => formModel.MedicCRM); this.ModelState.ClearPropertyErrors(() => formModel.MedicalEntityId); this.ModelState.ClearPropertyErrors(() => formModel.MedicalSpecialtyId); this.ModelState.ClearPropertyErrors(() => formModel.MedicalSpecialtyName); this.ModelState.ClearPropertyErrors(() => formModel.MedicalEntityJurisdiction); } if (user != null) { if (formModel.DateOfBirth.HasValue) user.Person.DateOfBirth = ConvertToUtcDateTime(this.DbPractice, formModel.DateOfBirth.Value); user.Person.BirthPlace = formModel.BirthPlace; user.Person.CPF = formModel.Cpf; user.Person.CreatedOn = this.GetUtcNow(); user.Person.MaritalStatus = formModel.MaritalStatus; user.Person.Profession = formModel.Profissao; user.Person.Email = formModel.Email; user.Person.EmailGravatarHash = GravatarHelper.GetGravatarHash(formModel.Email); // handle address if (!user.Person.Addresses.Any()) user.Person.Addresses.Add( new Address { PracticeId = this.DbUser.PracticeId, CEP = formModel.Address.CEP, City = formModel.Address.City, Complement = formModel.Address.Complement, Neighborhood = formModel.Address.Neighborhood, StateProvince = formModel.Address.StateProvince, Street = formModel.Address.Street, }); // when the user is a doctor, we need to fill the properties of the doctor if (formModel.IsDoctor) { // Only administrators can change the role of an user. if (this.DbUser.AdministratorId != null) { // if user is already a doctor, we just edit the properties // otherwise we create a new doctor instance if (user.Doctor == null) { user.Doctor = new Doctor { PracticeId = this.DbUser.PracticeId, }; BusHelper.FillNewDoctorUtilityBelt(user.Doctor); } } // Changing the doctor's informations. if (!string.IsNullOrWhiteSpace(formModel.MedicCRM)) user.Doctor.CRM = formModel.MedicCRM; if (formModel.MedicalEntityId != null) { var me = this.db.SYS_MedicalEntity.First(me1 => me1.Id == formModel.MedicalEntityId); user.Doctor.MedicalEntityCode = me.Code; user.Doctor.MedicalEntityName = me.Name; } if (formModel.MedicalSpecialtyId != null) { var ms = this.db.SYS_MedicalSpecialty.First(ms1 => ms1.Id == formModel.MedicalSpecialtyId); user.Doctor.MedicalSpecialtyCode = ms.Code; user.Doctor.MedicalSpecialtyName = ms.Name; } if (formModel.MedicalEntityJurisdiction != null) user.Doctor.MedicalEntityJurisdiction = ((TypeEstadoBrasileiro)formModel.MedicalEntityJurisdiction.Value).ToString(); // Creating an unique UrlIdentifier for this doctor. // This does not consider UrlIdentifier's used by other kinds of objects. string urlId = GetUniqueDoctorUrlId(this.db.Doctors, formModel.FullName, this.DbPractice.Id); if (urlId == null && !string.IsNullOrWhiteSpace(formModel.FullName)) { this.ModelState.AddModelError( () => formModel.FullName, // Todo: this message is also used in the AuthenticationController. string.Format("Quantidade máxima de homônimos excedida para esta conta: {0}.", this.DbPractice.UrlIdentifier)); } if (!string.IsNullOrWhiteSpace(urlId)) user.Doctor.UrlIdentifier = urlId; } else { // Only administrators can change the role of an user. if (this.DbUser.AdministratorId != null) { if (user.Doctor != null) this.db.Doctors.DeleteObject(user.Doctor); // if the user is not a doctor, then we make sure // by assigning the doctor property to null user.Doctor = null; } } // when the user is an administrator if (formModel.IsAdministrador) { // Only administrators can change the role of an user. if (this.DbUser.AdministratorId != null) if (user.Administrator == null) user.Administrator = new Administrator { PracticeId = this.DbUser.PracticeId, }; } else { // Only administrators can change the role of an user. if (this.DbUser.AdministratorId != null) { if (user.Administrator != null) this.db.Administrators.DeleteObject(user.Administrator); user.Administrator = null; } } if (user.IsOwner) { if (!formModel.IsAdministrador) this.ModelState.AddModelError( () => formModel.IsAdministrador, "Não é possível remover o papel de administrador do proprietário da conta."); } // when the user is a secretary if (formModel.IsSecretary) { // Only administrators can change the role of an user. if (this.DbUser.AdministratorId != null) if (user.Secretary == null) user.Secretary = new Secretary { PracticeId = this.DbUser.PracticeId, }; } else { // Only administrators can change the role of an user. if (this.DbUser.AdministratorId != null) { if (user.Secretary != null) this.db.Secretaries.DeleteObject(user.Secretary); user.Secretary = null; } } } // If ModelState is still valid, save the objects to the database. if (this.ModelState.IsValid) { if (formModel.Id == null) { var notificationData = new NewUserCreatedNotificationData() { UserName = user.UserName }; var dbNotification = new Notification() { CreatedOn = this.GetUtcNow(), PracticeId = this.DbPractice.Id, UserToId = this.DbUser.Id, Type = NotificationConstants.NEW_USER_NOTIFICATION_TYPE, Data = new JavaScriptSerializer().Serialize(notificationData) }; this.db.Notifications.AddObject(dbNotification); this.db.SaveChanges(); NotificationsHub.BroadcastDbNotification(dbNotification, notificationData); } // Saving all the changes. this.db.SaveChanges(); return this.RedirectToAction("Details", new { id = user.Id }); } this.ViewBag.MedicalSpecialtyOptions = this.db.SYS_MedicalSpecialty .ToList() .Select(ms => new SelectListItem { Value = ms.Id.ToString(), Text = ms.Name }) .ToList(); this.ViewBag.MedicalEntityOptions = this.db.SYS_MedicalEntity .ToList() .Select(me => new SelectListItem { Value = me.Id.ToString(), Text = me.Name }) .ToList(); if (this.DbUser.AdministratorId != null || this.DbUser.IsOwner) this.ViewBag.CanEditRole = true; // Removes all duplicated messages. this.ModelState.RemoveDuplicates(); return this.View("Edit", formModel); }