public static AddEditAccountViewModel SetPermissionFlags(this AddEditAccountViewModel model)
        {
            model.EditingSelf = model.UserId == Permission.GetCurrentUserId();
            bool permission = !model.EditingSelf &&
                              UserContext.GetUserContext().ContextName == UserContext.UserContextName.Administration;

            model.CanEditProviderOrganisation = permission;
            model.CanEditRole     = !model.EditingSelf;
            model.CanEditUserType = permission;

            return(model);
        }
        /// <summary>
        ///     Populate an add user view model.
        /// </summary>
        /// <param name="model">
        ///     The model.
        /// </param>
        /// <param name="db">
        ///     The db.
        /// </param>
        /// <param name="userId">
        ///     The user ID or email address.
        /// </param>
        /// <returns>
        ///     The <see cref="AddEditAccountViewModel" />.
        /// </returns>
        public static AddEditAccountViewModel Populate(this AddEditAccountViewModel model, ProviderPortalEntities db, string userId = null)
        {
            model.SetPermissionFlags();

            model.UserTypes = GetUserTypes(db);

            AspNetUser user = null;

            if (userId != null)
            {
                user = db.AspNetUsers.FirstOrDefault(x => x.Id == userId || x.Email == userId || x.UserName == userId);

                if (user == null)
                {
                    throw new ArgumentOutOfRangeException("User " + userId + " not found.");
                }

                model.Roles       = GetRoles();
                model.AspNetRoles = GetAspNetRoles(db, model.Roles);
            }

            if (user != null)
            {
                model.UserId             = user.Id;
                model.EditingSelf        = model.UserId == Permission.GetCurrentUserId();
                model.Email              = user.Email;
                model.RoleId             = user.AspNetRoles.First().Name;
                model.UserTypeId         = user.ProviderUserTypeId;
                model.UserType           = user.ProviderUserType.ProviderUserTypeName;
                model.Name               = user.Name;
                model.Address            = user.Address == null ? new AddressViewModel() : new AddressViewModel(user.Address);
                model.PhoneNumber        = user.PhoneNumber;
                model.IsDeleted          = user.IsDeleted;
                model.IsSecureAccessUser = user.IsSecureAccessUser;

                if (user.Providers2.Any())
                {
                    Provider provider = user.Providers2.First();
                    model.ProviderId = "P" + provider.ProviderId;
                    model.Provider   = provider.ProviderName;
                }
                else if (user.Organisations2.Any())
                {
                    Organisation organisation = user.Organisations2.First();
                    model.ProviderId   = "O" + organisation.OrganisationId;
                    model.Organisation = organisation.OrganisationName;
                }
                else
                {
                    model.ProviderId = string.Empty;
                    model.Provider   = string.Empty;
                }
            }
            else
            {
                model.RoleId      = string.Empty;
                model.UserTypeId  = 0;
                model.Roles       = GetRoles();
                model.AspNetRoles = GetAspNetRoles(db, model.Roles);
            }

            model.Address = model.Address ?? new AddressViewModel();
            model.Address.Populate(db);
            return(model);
        }
        /// <summary>
        ///     Validate an <see cref="AddEditAccountViewModel" />. Base validation is done via model annotations this does
        ///     additional sanity checks.
        /// </summary>
        /// <param name="model">
        ///     The model.
        /// </param>
        /// <param name="db">
        ///     The db.
        /// </param>
        /// <param name="state">
        ///     The state.
        /// </param>
        public static void Validate(this AddEditAccountViewModel model, ProviderPortalEntities db,
                                    ModelStateDictionary state)
        {
            model.SetPermissionFlags();

            if (model.CanEditRole && model.RoleId == null)
            {
                state.AddModelError("RoleId",
                                    AppGlobal.Language.GetText("Account_Role_MustSpecifyRole", "The Role field is required"));
            }

            if (!model.EditingSelf && model.CanEditRole && model.RoleId != null &&
                GetRoles().All(x => x.Value != model.RoleId.ToString(CultureInfo.InvariantCulture)))
            {
                state.AddModelError("RoleId", AppGlobal.Language.GetText("Account_Role_InvalidRole", "Invalid role"));
            }

            if (model.CanEditUserType &&
                GetUserTypes(db).All(x => x.Value != model.UserTypeId.ToString(CultureInfo.InvariantCulture)))
            {
                state.AddModelError(
                    "UserTypeId",
                    AppGlobal.Language.GetText("Account_Role_InvalidUserType", "Invalid user type"));
            }

            var user = db.AspNetUsers.FirstOrDefault(x => x.Id == model.UserId);

            model.Email = String.IsNullOrEmpty(model.Email) ? String.Empty : model.Email.Trim();
            if (model.UserId != null && user == null)
            {
                state.AddModelError("Email",
                                    AppGlobal.Language.GetText("Account_Role_AccountNotFound", "User account not found"));
            }
            else if (user == null || !model.Email.Equals(user.Email, StringComparison.CurrentCultureIgnoreCase))
            {
                var inUse = db.AspNetUsers.Any(x => x.Email == model.Email);
                if (inUse)
                {
                    state.AddModelError("Email",
                                        AppGlobal.Language.GetText("Account_Role_EmailInUse",
                                                                   "That email address is already in use for another account"));
                }
            }

            if (model.CanEditProviderOrganisation)
            {
                var roleInContext = db.AspNetRoles.FirstOrDefault(x => x.Name.Equals(model.RoleId));
                if (roleInContext != null && String.IsNullOrWhiteSpace(model.ProviderId))
                {
                    var roleContext = (UserContext.UserContextName)roleInContext.UserContextId;
                    if (roleContext == UserContext.UserContextName.Provider)
                    {
                        state.AddModelError("Provider",
                                            String.IsNullOrWhiteSpace(model.Provider)
                                ? AppGlobal.Language.GetText("Account_Provider_RequiredMessage", "Provider is required")
                                : AppGlobal.Language.GetText("Account_Provider_InvalidProvider", "Invalid provider"));
                    }
                    else if (roleContext == UserContext.UserContextName.Organisation)
                    {
                        state.AddModelError("Organisation",
                                            String.IsNullOrWhiteSpace(model.Provider)
                                ? AppGlobal.Language.GetText("Account_Organisation_RequiredMessage",
                                                             "Organisation is required")
                                : AppGlobal.Language.GetText("Account_OPrganisation_InvalidOrganisation",
                                                             "Invalid organisation"));
                    }
                }
            }

            // SA users do not have addresses
            if (!model.IsSecureAccessUser)
            {
                model.Address.Validate(db, state);
            }
        }