Exemplo n.º 1
0
        /// <summary>
        /// Handles the Click event of the DeleteGroupMember control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs" /> instance containing the event data.</param>
        protected void DeleteGroupMember_Click(object sender, Rock.Web.UI.Controls.RowEventArgs e)
        {
            RockContext        rockContext        = new RockContext();
            GroupMemberService groupMemberService = new GroupMemberService(rockContext);
            GroupMember        groupMember        = groupMemberService.Get(e.RowKeyId);

            if (groupMember != null)
            {
                string errorMessage;
                if (!groupMemberService.CanDelete(groupMember, out errorMessage))
                {
                    mdGridWarning.Show(errorMessage, ModalAlertType.Information);
                    return;
                }

                int groupId = groupMember.GroupId;

                groupMemberService.Delete(groupMember);
                rockContext.SaveChanges();

                Group group = new GroupService(rockContext).Get(groupId);
                if (group.IsSecurityRole || group.GroupType.Guid.Equals(Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid()))
                {
                    // person removed from SecurityRole, Flush
                    Rock.Security.Role.Flush(group.Id);
                    Rock.Security.Authorization.Flush();
                }
            }

            BindGroupMembersGrid();
        }
Exemplo n.º 2
0
        private void OptInOutPerson(RockContext rockContext, Person person, bool optIn)
        {
            var groupMemberService = new GroupMemberService(rockContext);
            var groupMembers       = groupMemberService
                                     .Queryable()
                                     .Where(m =>
                                            m.PersonId == person.Id &&
                                            m.Group.Guid.Equals(_optOutGroupGuid.Value))
                                     .ToList();

            if (!optIn && !groupMembers.Any())
            {
                var optOutGroup = new GroupService(rockContext).Get(_optOutGroupGuid.Value);
                if (optOutGroup != null)
                {
                    var groupMember = new GroupMember();
                    groupMember.GroupId     = optOutGroup.Id;
                    groupMember.PersonId    = person.Id;
                    groupMember.GroupRoleId = optOutGroup.GroupType.DefaultGroupRoleId ?? 0;
                    optOutGroup.Members.Add(groupMember);
                }
            }

            if (optIn && groupMembers.Any())
            {
                foreach (var groupMember in groupMembers)
                {
                    groupMemberService.Delete(groupMember);
                }
            }
        }
        /// <summary>
        /// Handles the Click event of the DeleteGroupMember control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs" /> instance containing the event data.</param>
        protected void DeleteGroupMember_Click(object sender, Rock.Web.UI.Controls.RowEventArgs e)
        {
            RockTransactionScope.WrapTransaction(() =>
            {
                GroupMemberService groupMemberService = new GroupMemberService();
                GroupMember groupMember = groupMemberService.Get(e.RowKeyId);
                if (groupMember != null)
                {
                    string errorMessage;
                    if (!groupMemberService.CanDelete(groupMember, out errorMessage))
                    {
                        mdGridWarning.Show(errorMessage, ModalAlertType.Information);
                        return;
                    }

                    int groupId = groupMember.GroupId;

                    groupMemberService.Delete(groupMember, CurrentPersonId);
                    groupMemberService.Save(groupMember, CurrentPersonId);

                    Group group = new GroupService().Get(groupId);
                    if (group.IsSecurityRole)
                    {
                        // person removed from SecurityRole, Flush
                        Rock.Security.Authorization.Flush();
                    }
                }
            });

            BindGroupMembersGrid();
        }
Exemplo n.º 4
0
        /// <summary>
        /// Removes the person RSVP.
        /// </summary>
        /// <param name="person">The person.</param>
        /// <param name="groupId">The group identifier.</param>
        /// <param name="scheduleId">The schedule identifier.</param>
        /// <param name="scheduleDate">The schedule date.</param>
        private void RemovePersonRsvp(Person person, int groupId, int scheduleId, DateTime?scheduleDate)
        {
            RockContext rockContext        = new RockContext();
            var         attendanceService  = new AttendanceService(rockContext);
            var         groupMemberService = new GroupMemberService(rockContext);

            // delete the RSVP
            var attendanceRecord = attendanceService.Queryable()
                                   .Where(a =>
                                          a.PersonAlias.PersonId == CurrentPersonId &&
                                          a.Occurrence.GroupId == groupId &&
                                          a.Occurrence.ScheduleId == scheduleId &&
                                          a.RSVP == RSVP.Yes &&
                                          DbFunctions.TruncateTime(a.StartDateTime) == DbFunctions.TruncateTime(scheduleDate.Value))
                                   .FirstOrDefault();

            if (attendanceRecord != null)
            {
                attendanceService.Delete(attendanceRecord);
            }

            // remove them from the group
            var groupMember = groupMemberService.Queryable().Where(m => m.PersonId == CurrentPersonId && m.GroupId == groupId).FirstOrDefault();

            if (groupMember != null)
            {
                groupMemberService.Delete(groupMember);
            }

            rockContext.SaveChanges();
        }
        void rGroupMembers_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e)
        {
            if (CanEdit)
            {
                int groupMemberId = int.MinValue;
                if (int.TryParse(e.CommandArgument.ToString(), out groupMemberId))
                {
                    var rockContext = new RockContext();
                    var service     = new GroupMemberService(rockContext);
                    var groupMember = service.Get(groupMemberId);
                    if (groupMember != null)
                    {
                        if (e.CommandName == "EditRole")
                        {
                            ShowModal(groupMember.Person, groupMember.GroupRoleId, groupMemberId);
                        }

                        else if (e.CommandName == "RemoveRole")
                        {
                            if (IsKnownRelationships)
                            {
                                var inverseGroupMember = service.GetInverseRelationship(groupMember, false, CurrentPersonAlias);
                                if (inverseGroupMember != null)
                                {
                                    service.Delete(inverseGroupMember);
                                }
                            }

                            service.Delete(groupMember);

                            rockContext.SaveChanges();

                            BindData();
                        }
                    }
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Deletes the group member.
        /// </summary>
        /// <param name="groupMemberId">The group member identifier.</param>
        private void DeleteGroupMember(int groupMemberId)
        {
            RockContext        rockContext        = new RockContext();
            GroupMemberService groupMemberService = new GroupMemberService(rockContext);

            var groupMember = groupMemberService.Get(groupMemberId);

            if (groupMember != null)
            {
                groupMemberService.Delete(groupMember);
            }

            rockContext.SaveChanges();
        }
Exemplo n.º 7
0
        /// <summary>
        /// Handles the ItemCommand event of the rGroupMembers control.
        /// </summary>
        /// <param name="source">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.RepeaterCommandEventArgs"/> instance containing the event data.</param>
        protected void rGroupMembers_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e)
        {
            if (CanEdit)
            {
                int groupMemberId = e.CommandArgument.ToString().AsIntegerOrNull() ?? 0;
                if (groupMemberId != 0)
                {
                    var rockContext = new RockContext();
                    var service     = new GroupMemberService(rockContext);
                    var groupMember = service.Get(groupMemberId);
                    if (groupMember != null)
                    {
                        if (e.CommandName == "EditRole")
                        {
                            ShowModal(groupMember.Person, groupMember.GroupRoleId, groupMemberId);
                        }
                        else if (e.CommandName == "RemoveRole")
                        {
                            if (IsInverseRelationshipsOwner)
                            {
                                var inverseGroupMember = service.GetInverseRelationship(groupMember, false);
                                if (inverseGroupMember != null)
                                {
                                    service.Delete(inverseGroupMember);
                                }
                            }

                            service.Delete(groupMember);

                            rockContext.SaveChanges();

                            BindData();
                        }
                    }
                }
            }
        }
        private void DeleteGroupMember(int groupMemberId)
        {
            RockContext        rockContext        = new RockContext();
            GroupMemberService groupMemberService = new GroupMemberService(rockContext);
            var groupMember = groupMemberService.Get(groupMemberId);

            if (groupMember != null &&
                groupMember.PersonId == Person.Id &&
                groupMember.Group.IsAuthorized(Authorization.EDIT, CurrentPerson))
            {
                groupMemberService.Delete(groupMember);
                rockContext.SaveChanges();
            }
            ShowEdit();
        }
Exemplo n.º 9
0
        public BlockActionResult RemoveMember(Guid groupMemberGuid)
        {
            using (var rockContext = new RockContext())
            {
                var groupMemberService = new GroupMemberService(rockContext);
                var member             = groupMemberService.Queryable()
                                         .Include(m => m.Group.GroupType)
                                         .FirstOrDefault(m => m.Guid == groupMemberGuid);

                if (member == null || (!member.Group.IsAuthorized(Authorization.EDIT, RequestContext.CurrentPerson) && !member.Group.IsAuthorized(Authorization.MANAGE_MEMBERS, RequestContext.CurrentPerson)))
                {
                    return(ActionBadRequest("You are not authorized to edit members of this group."));
                }

                var  groupMemberHistoricalService = new GroupMemberHistoricalService(rockContext);
                bool archive = false;

                if (member.Group.GroupType.EnableGroupHistory == true && groupMemberHistoricalService.Queryable().Any(a => a.GroupMemberId == member.Id))
                {
                    // if the group has GroupHistory enabled, and this group
                    // member has group member history snapshots, then we only
                    // archive.
                    archive = true;
                }
                else if (!groupMemberService.CanDelete(member, out var errorMessage))
                {
                    return(ActionBadRequest(errorMessage));
                }

                int groupId = member.GroupId;

                if (archive)
                {
                    // NOTE: Delete will AutoArchive, but since we know that we
                    // need to archive, we can call .Archive directly
                    groupMemberService.Archive(member, RequestContext.CurrentPerson?.PrimaryAliasId, true);
                }
                else
                {
                    groupMemberService.Delete(member, true);
                }

                rockContext.SaveChanges();

                return(ActionOk());
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute(RockContext rockContext, WorkflowAction action, object entity, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            Person        person    = GetEntityFromWorkflowAttributes(action, "Person", "PersonAttribute", new PersonAliasService(rockContext))?.Person;
            Group         group     = GetEntityFromWorkflowAttributes(action, "Group", "GroupAttribute", new GroupService(rockContext));
            GroupTypeRole groupRole = GetEntityFromWorkflowAttributes(action, "GroupRole", "GroupRoleAttribute", new GroupTypeRoleService(rockContext));


            if (person == null)
            {
                errorMessages.Add("Invalid Person.");
            }

            if (group == null)
            {
                errorMessages.Add("Invalid Group.");
            }

            if (person == null || group == null || errorMessages.Any())
            {
                errorMessages.ForEach(m => action.AddLogEntry(m, true));
                return(false);
            }


            var groupMemberService = new GroupMemberService(rockContext);

            IQueryable <GroupMember> groupMemberships = groupMemberService.Queryable().Where(gm => gm.GroupId == group.Id && gm.PersonId == person.Id);

            if (groupRole != null)
            {
                groupMemberships = groupMemberships.Where(gm => gm.GroupRoleId == groupRole.Id);
            }

            foreach (GroupMember groupMember in groupMemberships)
            {
                groupMemberService.Delete(groupMember);
            }

            rockContext.SaveChanges();


            errorMessages.ForEach(m => action.AddLogEntry(m, true));

            return(true);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Handles the Delete event of the gList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RowEventArgs"/> instance containing the event data.</param>
        protected void gList_Delete(object sender, RowEventArgs e)
        {
            RockTransactionScope.WrapTransaction(() =>
            {
                var groupMemberService = new GroupMemberService();
                int groupMemberId      = (int)e.RowKeyValue;

                GroupMember groupMember = groupMemberService.Get(groupMemberId);
                if (groupMember != null)
                {
                    // check if person can be removed from the Group and also check if person can be removed from all the person assigned competencies
                    string errorMessage;
                    if (!groupMemberService.CanDelete(groupMember, out errorMessage))
                    {
                        mdGridWarning.Show(errorMessage, ModalAlertType.Information);
                        return;
                    }

                    var competencyPersonService = new ResidencyService <CompetencyPerson>();
                    var personCompetencyList    = competencyPersonService.Queryable().Where(a => a.PersonId.Equals(groupMember.PersonId));
                    foreach (var item in personCompetencyList)
                    {
                        if (!competencyPersonService.CanDelete(item, out errorMessage))
                        {
                            mdGridWarning.Show(errorMessage, ModalAlertType.Information);
                            return;
                        }
                    }

                    // if you made it this far, delete all person's assigned competencies, and finally delete from Group
                    foreach (var item in personCompetencyList)
                    {
                        competencyPersonService.Delete(item, CurrentPersonId);
                        competencyPersonService.Save(item, CurrentPersonId);
                    }

                    groupMemberService.Delete(groupMember, CurrentPersonId);
                    groupMemberService.Save(groupMember, CurrentPersonId);
                }
            });

            BindGrid();
        }
Exemplo n.º 12
0
        /// <summary>
        /// Handles the Delete event of the gContactList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs"/> instance containing the event data.</param>
        protected void gContactList_Delete(object sender, Rock.Web.UI.Controls.RowEventArgs e)
        {
            int?businessId = hfBusinessId.Value.AsIntegerOrNull();

            if (businessId.HasValue)
            {
                var businessContactId = e.RowKeyId;

                var rockContext        = new RockContext();
                var groupMemberService = new GroupMemberService(rockContext);

                Guid businessContact = Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_BUSINESS_CONTACT.AsGuid();
                Guid business        = Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_BUSINESS.AsGuid();
                Guid ownerGuid       = Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER.AsGuid();
                foreach (var groupMember in groupMemberService.Queryable()
                         .Where(m =>
                                (
                                    // The contact person in the business's known relationships
                                    m.PersonId == businessContactId &&
                                    m.GroupRole.Guid.Equals(businessContact) &&
                                    m.Group.Members.Any(o =>
                                                        o.PersonId == businessId &&
                                                        o.GroupRole.Guid.Equals(ownerGuid))
                                ) ||
                                (
                                    // The business in the person's know relationships
                                    m.PersonId == businessId &&
                                    m.GroupRole.Guid.Equals(business) &&
                                    m.Group.Members.Any(o =>
                                                        o.PersonId == businessContactId &&
                                                        o.GroupRole.Guid.Equals(ownerGuid))
                                )
                                ))
                {
                    groupMemberService.Delete(groupMember);
                }

                rockContext.SaveChanges();

                BindContactListGrid(new PersonService(rockContext).Get(businessId.Value));
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Handles the Click event of the btnConfirmDelete control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void mdConfirmDelete_Click(object sender, EventArgs e)
        {
            mdConfirmDelete.Hide();

            if (GetAttributeValue("AllowGroupMemberDelete").AsBoolean())
            {
                RockContext        rockContext        = new RockContext();
                GroupMemberService groupMemberService = new GroupMemberService(rockContext);

                var groupMember = groupMemberService.Get(this.CurrentGroupMemberId);
                if (groupMember != null)
                {
                    groupMemberService.Delete(groupMember);
                }

                rockContext.SaveChanges();
            }

            DisplayViewGroup();
        }
Exemplo n.º 14
0
        /// <summary>
        /// Handles the Delete event of the gContactList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs"/> instance containing the event data.</param>
        protected void gContactList_Delete(object sender, Rock.Web.UI.Controls.RowEventArgs e)
        {
            var rockContext           = new RockContext();
            var personService         = new PersonService(rockContext);
            var business              = personService.Get(int.Parse(hfBusinessId.Value));
            int?businessContactRoleId = new GroupTypeRoleService(rockContext).Queryable()
                                        .Where(r =>
                                               r.Guid.Equals(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_BUSINESS_CONTACT)))
                                        .Select(r => r.Id)
                                        .FirstOrDefault();
            var groupMemberService = new GroupMemberService(rockContext);
            var groupMember        = business.GivingGroup.Members.Where(role => role.GroupRoleId == businessContactRoleId && role.PersonId == e.RowKeyId).FirstOrDefault();

            if (groupMember != null)
            {
                groupMemberService.Delete(groupMember);
                rockContext.SaveChanges();
            }

            BindContactListGrid(business);
        }
Exemplo n.º 15
0
        /// <summary>
        /// Handles the SaveClick event of the mdPlaceElsewhere control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void mdPlaceElsewhere_SaveClick(object sender, EventArgs e)
        {
            using (var rockContext = new RockContext())
            {
                var groupService       = new GroupService(rockContext);
                var groupMemberService = new GroupMemberService(rockContext);
                var groupMember        = groupMemberService.Get(hfPlaceElsewhereGroupMemberId.Value.AsInteger());
                if (groupMember != null)
                {
                    string errorMessage;
                    if (!groupMemberService.CanDelete(groupMember, out errorMessage))
                    {
                        nbPlaceElsewhereWarning.Text = errorMessage;
                        return;
                    }


                    var trigger = _group.GetGroupMemberWorkflowTriggers().FirstOrDefault(a => a.Id == hfPlaceElsewhereTriggerId.Value.AsInteger());
                    if (trigger != null)
                    {
                        // create a transaction for the selected trigger
                        var transaction = new Rock.Transactions.GroupMemberPlacedElsewhereTransaction(groupMember, tbPlaceElsewhereNote.Text, trigger);

                        // delete the group member from the current group
                        groupMemberService.Delete(groupMember);

                        rockContext.SaveChanges();

                        // queue up the transaction
                        Rock.Transactions.RockQueue.TransactionQueue.Enqueue(transaction);
                    }
                }

                mdPlaceElsewhere.Hide();
                mdPlaceElsewhere.Visible = false;
                BindGroupMembersGrid();
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        {
            if (RegistrantState != null)
            {
                RockContext            rockContext                        = new RockContext();
                var                    personService                      = new PersonService(rockContext);
                var                    registrantService                  = new RegistrationRegistrantService(rockContext);
                var                    registrantFeeService               = new RegistrationRegistrantFeeService(rockContext);
                var                    registrationTemplateFeeService     = new RegistrationTemplateFeeService(rockContext);
                var                    registrationTemplateFeeItemService = new RegistrationTemplateFeeItemService(rockContext);
                RegistrationRegistrant registrant = null;
                if (RegistrantState.Id > 0)
                {
                    registrant = registrantService.Get(RegistrantState.Id);
                }

                var previousRegistrantPersonIds = registrantService.Queryable().Where(a => a.RegistrationId == RegistrantState.RegistrationId)
                                                  .Where(r => r.PersonAlias != null)
                                                  .Select(r => r.PersonAlias.PersonId)
                                                  .ToList();

                bool newRegistrant     = false;
                var  registrantChanges = new History.HistoryChangeList();

                if (registrant == null)
                {
                    newRegistrant             = true;
                    registrant                = new RegistrationRegistrant();
                    registrant.RegistrationId = RegistrantState.RegistrationId;
                    registrantService.Add(registrant);
                    registrantChanges.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Record, "Registrant");
                }

                if (!registrant.PersonAliasId.Equals(ppPerson.PersonAliasId))
                {
                    string prevPerson = (registrant.PersonAlias != null && registrant.PersonAlias.Person != null) ?
                                        registrant.PersonAlias.Person.FullName : string.Empty;
                    string newPerson = ppPerson.PersonName;
                    newRegistrant = true;
                    History.EvaluateChange(registrantChanges, "Person", prevPerson, newPerson);
                }

                int?personId = ppPerson.PersonId.Value;
                registrant.PersonAliasId = ppPerson.PersonAliasId.Value;

                // Get the name of registrant for history
                string registrantName = "Unknown";
                if (ppPerson.PersonId.HasValue)
                {
                    var person = personService.Get(ppPerson.PersonId.Value);
                    if (person != null)
                    {
                        registrantName = person.FullName;
                    }
                }

                // set their status (wait list / registrant)
                registrant.OnWaitList = !tglWaitList.Checked;

                History.EvaluateChange(registrantChanges, "Cost", registrant.Cost, cbCost.Text.AsDecimal());
                registrant.Cost = cbCost.Text.AsDecimal();

                History.EvaluateChange(registrantChanges, "Discount Applies", registrant.DiscountApplies, cbDiscountApplies.Checked);
                registrant.DiscountApplies = cbDiscountApplies.Checked;

                if (!Page.IsValid)
                {
                    return;
                }

                // Remove/delete any registrant fees that are no longer in UI with quantity
                foreach (var dbFee in registrant.Fees.ToList())
                {
                    if (!RegistrantState.FeeValues.Keys.Contains(dbFee.RegistrationTemplateFeeId) ||
                        RegistrantState.FeeValues[dbFee.RegistrationTemplateFeeId] == null ||
                        !RegistrantState.FeeValues[dbFee.RegistrationTemplateFeeId]
                        .Any(f =>
                             f.RegistrationTemplateFeeItemId == dbFee.RegistrationTemplateFeeItemId &&
                             f.Quantity > 0))
                    {
                        var feeOldValue = string.Format("'{0}' Fee (Quantity:{1:N0}, Cost:{2:C2}, Option:{3}",
                                                        dbFee.RegistrationTemplateFee.Name, dbFee.Quantity, dbFee.Cost, dbFee.Option);

                        registrantChanges.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, "Fee").SetOldValue(feeOldValue);
                        registrant.Fees.Remove(dbFee);
                        registrantFeeService.Delete(dbFee);
                    }
                }

                // Add/Update any of the fees from UI
                foreach (var uiFee in RegistrantState.FeeValues.Where(f => f.Value != null))
                {
                    foreach (var uiFeeOption in uiFee.Value)
                    {
                        var dbFee = registrant.Fees
                                    .Where(f =>
                                           f.RegistrationTemplateFeeId == uiFee.Key &&
                                           f.RegistrationTemplateFeeItemId == uiFeeOption.RegistrationTemplateFeeItemId)
                                    .FirstOrDefault();

                        if (dbFee == null)
                        {
                            dbFee = new RegistrationRegistrantFee();
                            dbFee.RegistrationTemplateFeeId = uiFee.Key;
                            var registrationTemplateFeeItem = uiFeeOption.RegistrationTemplateFeeItemId != null?registrationTemplateFeeItemService.GetNoTracking(uiFeeOption.RegistrationTemplateFeeItemId.Value) : null;

                            if (registrationTemplateFeeItem != null)
                            {
                                dbFee.Option = registrationTemplateFeeItem.Name;
                            }

                            dbFee.RegistrationTemplateFeeItemId = uiFeeOption.RegistrationTemplateFeeItemId;
                            registrant.Fees.Add(dbFee);
                        }

                        var templateFee = dbFee.RegistrationTemplateFee;
                        if (templateFee == null)
                        {
                            templateFee = registrationTemplateFeeService.Get(uiFee.Key);
                        }

                        string feeName = templateFee != null ? templateFee.Name : "Fee";
                        if (!string.IsNullOrWhiteSpace(uiFeeOption.FeeLabel))
                        {
                            feeName = string.Format("{0} ({1})", feeName, uiFeeOption.FeeLabel);
                        }

                        if (dbFee.Id <= 0)
                        {
                            registrantChanges.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Record, "Fee").SetNewValue(feeName);
                        }

                        History.EvaluateChange(registrantChanges, feeName + " Quantity", dbFee.Quantity, uiFeeOption.Quantity);
                        dbFee.Quantity = uiFeeOption.Quantity;

                        History.EvaluateChange(registrantChanges, feeName + " Cost", dbFee.Cost, uiFeeOption.Cost);
                        dbFee.Cost = uiFeeOption.Cost;
                    }
                }

                if (this.RegistrationTemplate.RequiredSignatureDocumentTemplate != null)
                {
                    var person = new PersonService(rockContext).Get(personId.Value);

                    var documentService        = new SignatureDocumentService(rockContext);
                    var binaryFileService      = new BinaryFileService(rockContext);
                    SignatureDocument document = null;

                    int?signatureDocumentId = hfSignedDocumentId.Value.AsIntegerOrNull();
                    int?binaryFileId        = fuSignedDocument.BinaryFileId;
                    if (signatureDocumentId.HasValue)
                    {
                        document = documentService.Get(signatureDocumentId.Value);
                    }

                    if (document == null && binaryFileId.HasValue)
                    {
                        var instance = new RegistrationInstanceService(rockContext).Get(RegistrationInstanceId);

                        document = new SignatureDocument();
                        document.SignatureDocumentTemplateId = this.RegistrationTemplate.RequiredSignatureDocumentTemplate.Id;
                        document.AppliesToPersonAliasId      = registrant.PersonAliasId.Value;
                        document.AssignedToPersonAliasId     = registrant.PersonAliasId.Value;
                        document.Name = string.Format(
                            "{0}_{1}",
                            instance != null ? instance.Name : this.RegistrationTemplate.Name,
                            person != null ? person.FullName.RemoveSpecialCharacters() : string.Empty);
                        document.Status         = SignatureDocumentStatus.Signed;
                        document.LastStatusDate = RockDateTime.Now;
                        documentService.Add(document);
                    }

                    if (document != null)
                    {
                        int?origBinaryFileId = document.BinaryFileId;
                        document.BinaryFileId = binaryFileId;

                        if (origBinaryFileId.HasValue && origBinaryFileId.Value != document.BinaryFileId)
                        {
                            // if a new the binaryFile was uploaded, mark the old one as Temporary so that it gets cleaned up
                            var oldBinaryFile = binaryFileService.Get(origBinaryFileId.Value);
                            if (oldBinaryFile != null && !oldBinaryFile.IsTemporary)
                            {
                                oldBinaryFile.IsTemporary = true;
                            }
                        }

                        // ensure the IsTemporary is set to false on binaryFile associated with this document
                        if (document.BinaryFileId.HasValue)
                        {
                            var binaryFile = binaryFileService.Get(document.BinaryFileId.Value);
                            if (binaryFile != null && binaryFile.IsTemporary)
                            {
                                binaryFile.IsTemporary = false;
                            }
                        }
                    }
                }

                if (!registrant.IsValid)
                {
                    // Controls will render the error messages
                    return;
                }

                // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges()
                rockContext.WrapTransaction(() =>
                {
                    rockContext.SaveChanges();

                    registrant.LoadAttributes();
                    // NOTE: We will only have Registration Attributes displayed and editable on Registrant Detail.
                    // To Edit Person or GroupMember Attributes, they will have to go the PersonDetail or GroupMemberDetail blocks
                    foreach (var field in this.RegistrationTemplate.Forms
                             .SelectMany(f => f.Fields
                                         .Where(t =>
                                                t.FieldSource == RegistrationFieldSource.RegistrantAttribute &&
                                                t.AttributeId.HasValue)))
                    {
                        var attribute = AttributeCache.Get(field.AttributeId.Value);
                        if (attribute != null)
                        {
                            string originalValue = registrant.GetAttributeValue(attribute.Key);
                            var fieldValue       = RegistrantState.FieldValues
                                                   .Where(f => f.Key == field.Id)
                                                   .Select(f => f.Value.FieldValue)
                                                   .FirstOrDefault();
                            string newValue = fieldValue != null ? fieldValue.ToString() : string.Empty;

                            if ((originalValue ?? string.Empty).Trim() != (newValue ?? string.Empty).Trim())
                            {
                                string formattedOriginalValue = string.Empty;
                                if (!string.IsNullOrWhiteSpace(originalValue))
                                {
                                    formattedOriginalValue = attribute.FieldType.Field.FormatValue(null, originalValue, attribute.QualifierValues, false);
                                }

                                string formattedNewValue = string.Empty;
                                if (!string.IsNullOrWhiteSpace(newValue))
                                {
                                    formattedNewValue = attribute.FieldType.Field.FormatValue(null, newValue, attribute.QualifierValues, false);
                                }

                                History.EvaluateChange(registrantChanges, attribute.Name, formattedOriginalValue, formattedNewValue);
                            }

                            if (fieldValue != null)
                            {
                                registrant.SetAttributeValue(attribute.Key, fieldValue.ToString());
                            }
                        }
                    }

                    registrant.SaveAttributeValues(rockContext);
                });

                if (newRegistrant && this.RegistrationTemplate.GroupTypeId.HasValue && ppPerson.PersonId.HasValue)
                {
                    using (var newRockContext = new RockContext())
                    {
                        var reloadedRegistrant = new RegistrationRegistrantService(newRockContext).Get(registrant.Id);
                        if (reloadedRegistrant != null &&
                            reloadedRegistrant.Registration != null &&
                            reloadedRegistrant.Registration.Group != null &&
                            reloadedRegistrant.Registration.Group.GroupTypeId == this.RegistrationTemplate.GroupTypeId.Value)
                        {
                            int?groupRoleId = this.RegistrationTemplate.GroupMemberRoleId.HasValue ?
                                              this.RegistrationTemplate.GroupMemberRoleId.Value :
                                              reloadedRegistrant.Registration.Group.GroupType.DefaultGroupRoleId;
                            if (groupRoleId.HasValue)
                            {
                                var groupMemberService = new GroupMemberService(newRockContext);
                                var groupMember        = groupMemberService
                                                         .Queryable().AsNoTracking()
                                                         .Where(m =>
                                                                m.GroupId == reloadedRegistrant.Registration.Group.Id &&
                                                                m.PersonId == reloadedRegistrant.PersonId &&
                                                                m.GroupRoleId == groupRoleId.Value)
                                                         .FirstOrDefault();
                                if (groupMember == null)
                                {
                                    groupMember                   = new GroupMember();
                                    groupMember.GroupId           = reloadedRegistrant.Registration.Group.Id;
                                    groupMember.PersonId          = ppPerson.PersonId.Value;
                                    groupMember.GroupRoleId       = groupRoleId.Value;
                                    groupMember.GroupMemberStatus = this.RegistrationTemplate.GroupMemberStatus;
                                    groupMemberService.Add(groupMember);

                                    newRockContext.SaveChanges();

                                    registrantChanges.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Record, string.Format("Registrant to {0} group", reloadedRegistrant.Registration.Group.Name));
                                }
                                else
                                {
                                    registrantChanges.AddChange(History.HistoryVerb.Modify, History.HistoryChangeType.Record, string.Format("Registrant to existing person in {0} group", reloadedRegistrant.Registration.Group.Name));
                                }

                                if (reloadedRegistrant.GroupMemberId.HasValue && reloadedRegistrant.GroupMemberId.Value != groupMember.Id)
                                {
                                    groupMemberService.Delete(reloadedRegistrant.GroupMember);
                                    newRockContext.SaveChanges();
                                    registrantChanges.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, string.Format("Registrant to previous person in {0} group", reloadedRegistrant.Registration.Group.Name));
                                }

                                // Record this to the Person's and Registrants Notes and History...

                                reloadedRegistrant.GroupMemberId = groupMember.Id;
                            }
                        }
                        if (reloadedRegistrant.Registration.FirstName.IsNotNullOrWhiteSpace() && reloadedRegistrant.Registration.LastName.IsNotNullOrWhiteSpace())
                        {
                            reloadedRegistrant.Registration.SavePersonNotesAndHistory(reloadedRegistrant.Registration.FirstName, reloadedRegistrant.Registration.LastName, this.CurrentPersonAliasId, previousRegistrantPersonIds);
                        }
                        newRockContext.SaveChanges();
                    }
                }

                HistoryService.SaveChanges(
                    rockContext,
                    typeof(Registration),
                    Rock.SystemGuid.Category.HISTORY_EVENT_REGISTRATION.AsGuid(),
                    registrant.RegistrationId,
                    registrantChanges,
                    "Registrant: " + registrantName,
                    null,
                    null);
            }

            NavigateToRegistration();
        }
Exemplo n.º 17
0
        /// <summary>
        /// Handles the Delete event of the gGroups control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RowEventArgs" /> instance containing the event data.</param>
        protected void gGroups_Delete(object sender, RowEventArgs e)
        {
            var          rockContext  = new RockContext();
            GroupService groupService = new GroupService(rockContext);
            AuthService  authService  = new AuthService(rockContext);
            Group        group        = groupService.Get(e.RowKeyId);

            if (group != null)
            {
                string errorMessage;
                bool   isSecurityRoleGroup = group.IsSecurityRole || group.GroupType.Guid.Equals(Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid());
                int    personEntityTypeId  = EntityTypeCache.Read("Rock.Model.Person").Id;

                if (ContextTypesRequired.Any(a => a.Id == personEntityTypeId))
                {
                    var personContext = ContextEntity <Person>();
                    GroupMemberService            groupMemberService = new GroupMemberService(rockContext);
                    RegistrationRegistrantService registrantService  = new RegistrationRegistrantService(rockContext);
                    GroupMember groupMember = group.Members.SingleOrDefault(a => a.PersonId == personContext.Id);

                    if (!(group.IsAuthorized(Authorization.EDIT, this.CurrentPerson) || group.IsAuthorized(Authorization.MANAGE_MEMBERS, this.CurrentPerson)))
                    {
                        mdGridWarning.Show("You are not authorized to delete members from this group", ModalAlertType.Information);
                        return;
                    }

                    if (!groupMemberService.CanDelete(groupMember, out errorMessage))
                    {
                        mdGridWarning.Show(errorMessage, ModalAlertType.Information);
                        return;
                    }

                    foreach (var registrant in registrantService.Queryable().Where(r => r.GroupMemberId == groupMember.Id))
                    {
                        registrant.GroupMemberId = null;
                    }

                    if (group.IsSecurityRole || group.GroupType.Guid.Equals(Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid()))
                    {
                        // person removed from SecurityRole, Flush
                        Rock.Security.Role.Flush(group.Id);
                    }

                    groupMemberService.Delete(groupMember);
                }
                else
                {
                    if (!group.IsAuthorized(Authorization.EDIT, this.CurrentPerson))
                    {
                        mdGridWarning.Show("You are not authorized to delete this group", ModalAlertType.Information);
                        return;
                    }


                    if (!groupService.CanDelete(group, out errorMessage))
                    {
                        mdGridWarning.Show(errorMessage, ModalAlertType.Information);
                        return;
                    }


                    if (isSecurityRoleGroup)
                    {
                        Rock.Security.Role.Flush(group.Id);
                        foreach (var auth in authService.Queryable().Where(a => a.GroupId == group.Id).ToList())
                        {
                            authService.Delete(auth);
                        }
                    }

                    groupService.Delete(group);
                }

                rockContext.SaveChanges();

                if (isSecurityRoleGroup)
                {
                    Rock.Security.Authorization.Flush();
                }
            }

            BindGrid();
        }
Exemplo n.º 18
0
        /// <summary>
        /// Handles the Click event of the btnMoveGroupMember control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void btnMoveGroupMember_Click(object sender, EventArgs e)
        {
            var rockContext        = new RockContext();
            var groupMemberService = new GroupMemberService(rockContext);
            var groupMember        = groupMemberService.Get(hfGroupMemberId.Value.AsInteger());

            groupMember.LoadAttributes();
            int destGroupId = gpMoveGroupMember.SelectedValue.AsInteger();
            var destGroup   = new GroupService(rockContext).Get(destGroupId);

            var destGroupMember = groupMemberService.Queryable().Where(a =>
                                                                       a.GroupId == destGroupId &&
                                                                       a.PersonId == groupMember.PersonId &&
                                                                       a.GroupRoleId == grpMoveGroupMember.GroupRoleId).FirstOrDefault();

            if (destGroupMember != null)
            {
                nbMoveGroupMemberWarning.Visible = true;
                nbMoveGroupMemberWarning.Text    = string.Format("{0} is already in {1}", groupMember.Person, destGroupMember.Group);
                return;
            }

            if (!grpMoveGroupMember.GroupRoleId.HasValue)
            {
                nbMoveGroupMemberWarning.Visible = true;
                nbMoveGroupMemberWarning.Text    = string.Format("Please select a Group Role");
                return;
            }

            string canDeleteWarning;

            if (!groupMemberService.CanDelete(groupMember, out canDeleteWarning))
            {
                nbMoveGroupMemberWarning.Visible = true;
                nbMoveGroupMemberWarning.Text    = string.Format("Unable to remove {0} from {1}: {2}", groupMember.Person, groupMember.Group, canDeleteWarning);
                return;
            }

            destGroupMember             = new GroupMember();
            destGroupMember.GroupId     = destGroupId;
            destGroupMember.GroupRoleId = grpMoveGroupMember.GroupRoleId.Value;
            destGroupMember.PersonId    = groupMember.PersonId;
            destGroupMember.LoadAttributes();

            foreach (var attribute in groupMember.Attributes)
            {
                if (destGroupMember.Attributes.Any(a => a.Key == attribute.Key && a.Value.FieldTypeId == attribute.Value.FieldTypeId))
                {
                    destGroupMember.SetAttributeValue(attribute.Key, groupMember.GetAttributeValue(attribute.Key));
                }
            }

            // Un-link any registrant records that point to this group member.
            foreach (var registrant in new RegistrationRegistrantService(rockContext).Queryable()
                     .Where(r => r.GroupMemberId == groupMember.Id))
            {
                registrant.GroupMemberId = null;
            }

            rockContext.WrapTransaction(() =>
            {
                groupMemberService.Add(destGroupMember);
                rockContext.SaveChanges();
                destGroupMember.SaveAttributeValues(rockContext);

                // move any Note records that were associated with the old groupMember to the new groupMember record
                if (cbMoveGroupMemberMoveNotes.Checked)
                {
                    destGroupMember.Note        = groupMember.Note;
                    int groupMemberEntityTypeId = EntityTypeCache.GetId <Rock.Model.GroupMember>().Value;
                    var noteService             = new NoteService(rockContext);
                    var groupMemberNotes        = noteService.Queryable().Where(a => a.NoteType.EntityTypeId == groupMemberEntityTypeId && a.EntityId == groupMember.Id);
                    foreach (var note in groupMemberNotes)
                    {
                        note.EntityId = destGroupMember.Id;
                    }

                    rockContext.SaveChanges();
                }

                groupMemberService.Delete(groupMember);
                rockContext.SaveChanges();

                destGroupMember.CalculateRequirements(rockContext, true);
            });

            var queryString = new Dictionary <string, string>();

            queryString.Add("GroupMemberId", destGroupMember.Id.ToString());
            this.NavigateToPage(this.RockPage.Guid, queryString);
        }
Exemplo n.º 19
0
        /// <summary>
        /// Handles the Click event of the delete/archive button in the grid
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RowEventArgs" /> instance containing the event data.</param>
        protected void gGroups_DeleteOrArchive(object sender, RowEventArgs e)
        {
            var                rockContext        = new RockContext();
            GroupService       groupService       = new GroupService(rockContext);
            GroupMemberService groupMemberService = new GroupMemberService(rockContext);
            AuthService        authService        = new AuthService(rockContext);
            Group              group       = null;
            GroupMember        groupMember = null;

            if (GroupListGridMode == GridListGridMode.GroupsPersonMemberOf)
            {
                // the DataKey Id of the grid is GroupMemberId
                groupMember = groupMemberService.Get(e.RowKeyId);
                if (groupMember != null)
                {
                    group = groupMember.Group;
                }
            }
            else
            {
                // the DataKey Id of the grid is GroupId
                group = groupService.Get(e.RowKeyId);
            }

            if (group != null)
            {
                bool isSecurityRoleGroup = group.IsSecurityRole || group.GroupType.Guid.Equals(Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid());

                if (GroupListGridMode == GridListGridMode.GroupsPersonMemberOf)
                {
                    // Grid is in 'Groups that Person is member of' mode
                    GroupMemberHistoricalService groupMemberHistoricalService = new GroupMemberHistoricalService(rockContext);

                    bool archive = false;
                    if (group.GroupType.EnableGroupHistory == true && groupMemberHistoricalService.Queryable().Any(a => a.GroupMemberId == groupMember.Id))
                    {
                        // if the group has GroupHistory enabled, and this group member has group member history snapshots, they were prompted to Archive
                        archive = true;
                    }
                    else
                    {
                        if (!(group.IsAuthorized(Authorization.EDIT, this.CurrentPerson) || group.IsAuthorized(Authorization.MANAGE_MEMBERS, this.CurrentPerson)))
                        {
                            mdGridWarning.Show("You are not authorized to delete members from this group", ModalAlertType.Information);
                            return;
                        }

                        string errorMessage;
                        if (!groupMemberService.CanDelete(groupMember, out errorMessage))
                        {
                            mdGridWarning.Show(errorMessage, ModalAlertType.Information);
                            return;
                        }
                    }

                    int groupId = groupMember.GroupId;

                    if (archive)
                    {
                        // NOTE: Delete will AutoArchive, but since we know that we need to archive, we can call .Archive directly
                        groupMemberService.Archive(groupMember, this.CurrentPersonAliasId, true);
                    }
                    else
                    {
                        groupMemberService.Delete(groupMember, true);
                    }

                    rockContext.SaveChanges();
                }
                else
                {
                    // Grid is in 'Group List' mode
                    bool archive = false;
                    var  groupMemberHistoricalService = new GroupHistoricalService(rockContext);
                    if (group.GroupType.EnableGroupHistory == true && groupMemberHistoricalService.Queryable().Any(a => a.GroupId == group.Id))
                    {
                        // if the group has GroupHistory enabled and has history snapshots, and they were prompted to Archive
                        archive = true;
                    }

                    if (archive)
                    {
                        if (!group.IsAuthorized(Authorization.EDIT, this.CurrentPerson))
                        {
                            mdGridWarning.Show("You are not authorized to archive this group", ModalAlertType.Information);
                            return;
                        }

                        // NOTE: groupService.Delete will automatically Archive instead Delete if this Group has GroupHistory enabled, but since this block has UI logic for Archive vs Delete, we can do a direct Archive
                        groupService.Archive(group, this.CurrentPersonAliasId, true);
                    }
                    else
                    {
                        if (!group.IsAuthorized(Authorization.EDIT, this.CurrentPerson))
                        {
                            mdGridWarning.Show("You are not authorized to delete this group", ModalAlertType.Information);
                            return;
                        }

                        string errorMessage;
                        if (!groupService.CanDelete(group, out errorMessage))
                        {
                            mdGridWarning.Show(errorMessage, ModalAlertType.Information);
                            return;
                        }

                        groupService.Delete(group, true);
                    }
                }

                rockContext.SaveChanges();

                if (isSecurityRoleGroup)
                {
                    Rock.Security.Authorization.Clear();
                }
            }

            BindGrid();
        }
Exemplo n.º 20
0
        /// <summary>
        /// Job that will sync groups.
        ///
        /// Called by the <see cref="IScheduler" /> when a
        /// <see cref="ITrigger" /> fires that is associated with
        /// the <see cref="IJob" />.
        /// </summary>
        public virtual void Execute(IJobExecutionContext context)
        {
            // Get the job setting(s)
            JobDataMap dataMap = context.JobDetail.JobDataMap;
            bool       requirePasswordReset = dataMap.GetBoolean("RequirePasswordReset");
            var        commandTimeout       = dataMap.GetString("CommandTimeout").AsIntegerOrNull() ?? 180;

            // Counters for displaying results
            int    groupsSynced  = 0;
            int    groupsChanged = 0;
            string groupName     = string.Empty;
            string dataViewName  = string.Empty;
            var    errors        = new List <string>();

            try
            {
                // get groups set to sync
                var activeSyncIds = new List <int>();
                using (var rockContext = new RockContext())
                {
                    // Get groups that are not archived and are still active.
                    activeSyncIds = new GroupSyncService(rockContext)
                                    .Queryable().AsNoTracking()
                                    .Where(x => !x.Group.IsArchived && x.Group.IsActive)
                                    .Select(x => x.Id)
                                    .ToList();
                }

                foreach (var syncId in activeSyncIds)
                {
                    bool hasSyncChanged = false;

                    // Use a fresh rockContext per sync so that ChangeTracker doesn't get bogged down
                    using (var rockContext = new RockContext())
                    {
                        // increase the timeout just in case the data view source is slow
                        rockContext.Database.CommandTimeout = commandTimeout;
                        rockContext.SourceOfChange          = "Group Sync";

                        // Get the Sync
                        var sync = new GroupSyncService(rockContext)
                                   .Queryable().AsNoTracking()
                                   .FirstOrDefault(s => s.Id == syncId);

                        // Ensure that the group's Sync Data View is a person data view
                        if (sync != null && sync.SyncDataView.EntityTypeId == EntityTypeCache.Get(typeof(Person)).Id)
                        {
                            List <string> syncErrors = new List <string>();

                            dataViewName = sync.SyncDataView.Name;
                            groupName    = sync.Group.Name;

                            // Get the person id's from the data view (source)
                            var personService   = new PersonService(rockContext);
                            var sourcePersonIds = sync.SyncDataView.GetQuery(null, rockContext, commandTimeout, out syncErrors)
                                                  .Select(q => q.Id).ToList();

                            // If any error occurred trying get the 'where expression' from the sync-data-view,
                            // just skip trying to sync that particular group's Sync Data View for now.
                            if (syncErrors.Count > 0)
                            {
                                errors.AddRange(syncErrors);
                                ExceptionLogService.LogException(new Exception(string.Format("An error occurred while trying to GroupSync group '{0}' and data view '{1}' so the sync was skipped. Error: {2}", groupName, dataViewName, String.Join(",", syncErrors))));
                                continue;
                            }

                            // Get the person id's in the group (target) for the role being synced.
                            // Note: targetPersonIds must include archived group members
                            // so we don't try to delete anyone who's already archived, and
                            // it must include deceased members so we can remove them if they
                            // are no longer in the data view.
                            var targetPersonIds = new GroupMemberService(rockContext)
                                                  .Queryable(true, true).AsNoTracking()
                                                  .Where(gm => gm.GroupId == sync.GroupId)
                                                  .Where(gm => gm.GroupRoleId == sync.GroupTypeRoleId)
                                                  .Select(gm => new {
                                PersonId   = gm.PersonId,
                                IsArchived = gm.IsArchived
                            })
                                                  .ToList();

                            // Delete people from the group/role that are no longer in the data view --
                            // but not the ones that are already archived.
                            foreach (var targetPerson in targetPersonIds.Where(t => !sourcePersonIds.Contains(t.PersonId) && t.IsArchived != true))
                            {
                                try
                                {
                                    // Use a new context to limit the amount of change-tracking required
                                    using (var groupMemberContext = new RockContext())
                                    {
                                        // Delete the records for that person's group and role
                                        var groupMemberService = new GroupMemberService(groupMemberContext);
                                        foreach (var groupMember in groupMemberService
                                                 .Queryable(true, true)
                                                 .Where(m =>
                                                        m.GroupId == sync.GroupId &&
                                                        m.GroupRoleId == sync.GroupTypeRoleId &&
                                                        m.PersonId == targetPerson.PersonId)
                                                 .ToList())
                                        {
                                            groupMemberService.Delete(groupMember);
                                        }

                                        groupMemberContext.SaveChanges();

                                        // If the Group has an exit email, and person has an email address, send them the exit email
                                        if (sync.ExitSystemEmail != null)
                                        {
                                            var person = new PersonService(groupMemberContext).Get(targetPerson.PersonId);
                                            if (person.Email.IsNotNullOrWhiteSpace())
                                            {
                                                // Send the exit email
                                                var mergeFields = new Dictionary <string, object>();
                                                mergeFields.Add("Group", sync.Group);
                                                mergeFields.Add("Person", person);
                                                var emailMessage = new RockEmailMessage(sync.ExitSystemEmail);
                                                emailMessage.AddRecipient(new RecipientData(person.Email, mergeFields));
                                                var emailErrors = new List <string>();
                                                emailMessage.Send(out emailErrors);
                                                errors.AddRange(emailErrors);
                                            }
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    ExceptionLogService.LogException(ex);
                                    continue;
                                }

                                hasSyncChanged = true;
                            }

                            // Now find all the people in the source list who are NOT already in the target list
                            // or in the target list as archived (so we can restore them).
                            foreach (var personId in sourcePersonIds.Where(s => !targetPersonIds.Any(t => t.PersonId == s) ||
                                                                           targetPersonIds.Any(t => t.PersonId == s && t.IsArchived)))
                            {
                                try
                                {
                                    // Use a new context to limit the amount of change-tracking required
                                    using (var groupMemberContext = new RockContext())
                                    {
                                        var groupMemberService = new GroupMemberService(groupMemberContext);

                                        // If this person is currently archived...
                                        if (targetPersonIds.Any(t => t.PersonId == personId && t.IsArchived == true))
                                        {
                                            // ...then we'll just restore them;

                                            // NOTE: AddOrRestoreGroupMember will find the exact group member record and
                                            // sets their IsArchived back to false.
                                            var newGroupMember = groupMemberService.AddOrRestoreGroupMember(sync.Group, personId, sync.GroupTypeRoleId);
                                            newGroupMember.GroupMemberStatus = GroupMemberStatus.Active;
                                            groupMemberContext.SaveChanges();
                                        }
                                        else
                                        {
                                            // ...otherwise we will add a new person to the group with the role specified in the sync.
                                            var newGroupMember = new GroupMember {
                                                Id = 0
                                            };
                                            newGroupMember.PersonId          = personId;
                                            newGroupMember.GroupId           = sync.GroupId;
                                            newGroupMember.GroupMemberStatus = GroupMemberStatus.Active;
                                            newGroupMember.GroupRoleId       = sync.GroupTypeRoleId;

                                            if (newGroupMember.IsValidGroupMember(groupMemberContext))
                                            {
                                                groupMemberService.Add(newGroupMember);
                                                groupMemberContext.SaveChanges();
                                            }
                                            else
                                            {
                                                // Validation errors will get added to the ValidationResults collection. Add those results to the log and then move on to the next person.
                                                var ex = new GroupMemberValidationException(string.Join(",", newGroupMember.ValidationResults.Select(r => r.ErrorMessage).ToArray()));
                                                ExceptionLogService.LogException(ex);
                                                continue;
                                            }
                                        }

                                        // If the Group has a welcome email, and person has an email address, send them the welcome email and possibly create a login
                                        if (sync.WelcomeSystemEmail != null)
                                        {
                                            var person = new PersonService(groupMemberContext).Get(personId);
                                            if (person.Email.IsNotNullOrWhiteSpace())
                                            {
                                                // If the group is configured to add a user account for anyone added to the group, and person does not yet have an
                                                // account, add one for them.
                                                string newPassword = string.Empty;
                                                bool   createLogin = sync.AddUserAccountsDuringSync;

                                                // Only create a login if requested, no logins exist and we have enough information to generate a user name.
                                                if (createLogin && !person.Users.Any() && !string.IsNullOrWhiteSpace(person.NickName) && !string.IsNullOrWhiteSpace(person.LastName))
                                                {
                                                    newPassword = System.Web.Security.Membership.GeneratePassword(9, 1);
                                                    string username = Rock.Security.Authentication.Database.GenerateUsername(person.NickName, person.LastName);

                                                    UserLogin login = UserLoginService.Create(
                                                        groupMemberContext,
                                                        person,
                                                        AuthenticationServiceType.Internal,
                                                        EntityTypeCache.Get(Rock.SystemGuid.EntityType.AUTHENTICATION_DATABASE.AsGuid()).Id,
                                                        username,
                                                        newPassword,
                                                        true,
                                                        requirePasswordReset);
                                                }

                                                // Send the welcome email
                                                var mergeFields = new Dictionary <string, object>();
                                                mergeFields.Add("Group", sync.Group);
                                                mergeFields.Add("Person", person);
                                                mergeFields.Add("NewPassword", newPassword);
                                                mergeFields.Add("CreateLogin", createLogin);
                                                var emailMessage = new RockEmailMessage(sync.WelcomeSystemEmail);
                                                emailMessage.AddRecipient(new RecipientData(person.Email, mergeFields));
                                                var emailErrors = new List <string>();
                                                emailMessage.Send(out emailErrors);
                                                errors.AddRange(emailErrors);
                                            }
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    ExceptionLogService.LogException(ex);
                                    continue;
                                }

                                hasSyncChanged = true;
                            }

                            // Increment Groups Changed Counter (if people were deleted or added to the group)
                            if (hasSyncChanged)
                            {
                                groupsChanged++;
                            }

                            // Increment the Groups Synced Counter
                            groupsSynced++;
                        }
                    }
                }

                // Format the result message
                var resultMessage = string.Empty;
                if (groupsSynced == 0)
                {
                    resultMessage = "No groups to sync";
                }
                else if (groupsSynced == 1)
                {
                    resultMessage = "1 group was synced";
                }
                else
                {
                    resultMessage = string.Format("{0} groups were synced", groupsSynced);
                }

                resultMessage += string.Format(" and {0} groups were changed", groupsChanged);

                if (errors.Any())
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine();
                    sb.Append("Errors: ");
                    errors.ForEach(e => { sb.AppendLine(); sb.Append(e); });
                    string errorMessage = sb.ToString();
                    resultMessage += errorMessage;
                    throw new Exception(errorMessage);
                }

                context.Result = resultMessage;
            }
            catch (System.Exception ex)
            {
                HttpContext context2 = HttpContext.Current;
                ExceptionLogService.LogException(ex, context2);
                throw;
            }
        }
        /// <summary>
        /// Executes this instance.
        /// </summary>
        public void Execute()
        {
            using (var rockContext = new RockContext())
            {
                var relationshipGroupType = GroupTypeCache.Read(Rock.SystemGuid.GroupType.GROUPTYPE_KNOWN_RELATIONSHIPS.AsGuid());
                if (relationshipGroupType != null)
                {
                    var ownerRole = relationshipGroupType.Roles
                                    .Where(r => r.Guid.Equals(Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER.AsGuid()))
                                    .FirstOrDefault();

                    var friendRole = relationshipGroupType.Roles
                                     .Where(r => r.Guid.Equals(Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_FACEBOOK_FRIEND.AsGuid()))
                                     .FirstOrDefault();

                    if (ownerRole != null && friendRole != null)
                    {
                        var userLoginService   = new UserLoginService(rockContext);
                        var groupMemberService = new GroupMemberService(rockContext);

                        // Convert list of facebook ids into list of usernames
                        var friendUserNames = FacebookIds.Select(i => "FACEBOOK_" + i).ToList();

                        // Get the list of person ids associated with friends usernames
                        var friendPersonIds = userLoginService.Queryable()
                                              .Where(l =>
                                                     l.PersonId.HasValue &&
                                                     l.PersonId != PersonId &&
                                                     friendUserNames.Contains(l.UserName))
                                              .Select(l => l.PersonId.Value)
                                              .Distinct()
                                              .ToList();

                        // Get the person's group id
                        var personGroup = groupMemberService.Queryable()
                                          .Where(m =>
                                                 m.PersonId == PersonId &&
                                                 m.GroupRoleId == ownerRole.Id &&
                                                 m.Group.GroupTypeId == relationshipGroupType.Id)
                                          .Select(m => m.Group)
                                          .FirstOrDefault();

                        // Verify that a 'known relationships' type group existed for the person, if not create it
                        if (personGroup == null)
                        {
                            var groupMember = new GroupMember();
                            groupMember.PersonId    = PersonId;
                            groupMember.GroupRoleId = ownerRole.Id;

                            personGroup             = new Group();
                            personGroup.Name        = relationshipGroupType.Name;
                            personGroup.GroupTypeId = relationshipGroupType.Id;
                            personGroup.Members.Add(groupMember);

                            var groupService = new GroupService(rockContext);
                            groupService.Add(personGroup);
                            rockContext.SaveChanges();
                        }

                        // Get the person's relationship group id
                        var personGroupId = personGroup.Id;

                        // Get all of the friend's relationship group ids
                        var friendGroupIds = groupMemberService.Queryable()
                                             .Where(m =>
                                                    m.Group.GroupTypeId == relationshipGroupType.Id &&
                                                    m.GroupRoleId == ownerRole.Id &&
                                                    friendPersonIds.Contains(m.PersonId))
                                             .Select(m => m.GroupId)
                                             .Distinct()
                                             .ToList();

                        // Find all the existing friend relationships in Rock ( both directions )
                        var existingFriends = groupMemberService.Queryable()
                                              .Where(m =>
                                                     m.Group.GroupTypeId == relationshipGroupType.Id && (
                                                         (friendPersonIds.Contains(m.PersonId) && m.GroupId == personGroupId) ||
                                                         (m.PersonId == PersonId && m.GroupId != personGroupId)
                                                         ))
                                              .ToList();

                        // Create temp group members for current Facebook friends
                        var currentFriends = new List <GroupMember>();

                        // ( Person > Friend )
                        foreach (int personId in friendPersonIds)
                        {
                            var groupMember = new GroupMember();
                            groupMember.GroupId           = personGroupId;
                            groupMember.PersonId          = personId;
                            groupMember.GroupRoleId       = friendRole.Id;
                            groupMember.GroupMemberStatus = GroupMemberStatus.Active;
                            currentFriends.Add(groupMember);
                        }

                        // ( Friend > Person )
                        foreach (int familyId in friendGroupIds)
                        {
                            var groupMember = new GroupMember();
                            groupMember.GroupId           = familyId;
                            groupMember.PersonId          = PersonId;
                            groupMember.GroupRoleId       = friendRole.Id;
                            groupMember.GroupMemberStatus = GroupMemberStatus.Active;
                            currentFriends.Add(groupMember);
                        }

                        //  Add any current friends that do not exist in Rock yet
                        foreach (var groupMember in currentFriends
                                 .Where(f => !existingFriends.Any(e => e.IsEqualTo(f))))
                        {
                            groupMemberService.Add(groupMember);
                        }

                        // Delete any existing friends that are no longer facebook friends
                        foreach (var groupMember in existingFriends
                                 .Where(f => !currentFriends.Any(e => e.IsEqualTo(f))))
                        {
                            groupMemberService.Delete(groupMember);
                        }

                        rockContext.SaveChanges();
                    }
                }
            }
        }
Exemplo n.º 22
0
        /// <summary>
        /// Job that will sync groups.
        ///
        /// Called by the <see cref="IScheduler" /> when a
        /// <see cref="ITrigger" /> fires that is associated with
        /// the <see cref="IJob" />.
        /// </summary>
        public virtual void Execute(IJobExecutionContext context)
        {
            // Get the job setting(s)
            JobDataMap dataMap = context.JobDetail.JobDataMap;
            bool       requirePasswordReset = dataMap.GetBoolean("RequirePasswordReset");

            // Counters for displaying results
            int    groupsSynced  = 0;
            int    groupsChanged = 0;
            string groupName     = string.Empty;
            string dataViewName  = string.Empty;
            var    errors        = new List <string>();

            try
            {
                // get groups set to sync
                var activeSyncIds = new List <int>();
                using (var rockContext = new RockContext())
                {
                    activeSyncIds = new GroupSyncService(rockContext)
                                    .Queryable().AsNoTracking()
                                    .Select(x => x.Id)
                                    .ToList();
                }

                foreach (var syncId in activeSyncIds)
                {
                    bool hasSyncChanged = false;

                    // Use a fresh rockContext per syc so that ChangeTracker doesn't get bogged down
                    using (var rockContext = new RockContext())
                    {
                        // increase the timeout just in case the dataview source is slow
                        rockContext.Database.CommandTimeout = 180;
                        rockContext.SourceOfChange          = "Group Sync";

                        // Get the Sync
                        var sync = new GroupSyncService(rockContext)
                                   .Queryable().AsNoTracking()
                                   .FirstOrDefault(s => s.Id == syncId);

                        // Ensure that the group's Sync Data View is a person dataview
                        if (sync != null && sync.SyncDataView.EntityTypeId == EntityTypeCache.Get(typeof(Person)).Id)
                        {
                            List <string> syncErrors = new List <string>();

                            dataViewName = sync.SyncDataView.Name;
                            groupName    = sync.Group.Name;

                            // Get the person id's from the dataview (source)
                            var personService       = new PersonService(rockContext);
                            var parameterExpression = personService.ParameterExpression;
                            var whereExpression     = sync.SyncDataView.GetExpression(personService, parameterExpression, out syncErrors);
                            var sourcePersonIds     = new PersonService(rockContext)
                                                      .Get(parameterExpression, whereExpression)
                                                      .Select(q => q.Id)
                                                      .ToList();

                            // If any error occurred, just skip this sync for now.
                            if (syncErrors.Count > 0)
                            {
                                errors.AddRange(syncErrors);
                                ExceptionLogService.LogException(new Exception(string.Format("An error occurred while trying to GroupSync group '{0}' and data view '{1}' so the sync was skipped. Error: {2}", groupName, dataViewName, String.Join(",", syncErrors))));
                                continue;
                            }

                            // Get the person id's in the group (target)
                            var targetPersonIds = new GroupMemberService(rockContext)
                                                  .Queryable().AsNoTracking()
                                                  .Where(gm => gm.GroupId == sync.GroupId)
                                                  .Select(gm => gm.PersonId)
                                                  .ToList();

                            // Delete people from the group/role that are no longer in the dataview
                            foreach (var personId in targetPersonIds.Where(t => !sourcePersonIds.Contains(t)))
                            {
                                // Use a new context to limit the amount of change-tracking required
                                using (var groupMemberContext = new RockContext())
                                {
                                    // Delete any group members for the role with the person id
                                    var groupMemberService = new GroupMemberService(groupMemberContext);
                                    foreach (var groupMember in groupMemberService
                                             .Queryable()
                                             .Where(m =>
                                                    m.GroupId == sync.GroupId &&
                                                    m.GroupRoleId == sync.GroupTypeRoleId &&
                                                    m.PersonId == personId)
                                             .ToList())
                                    {
                                        groupMemberService.Delete(groupMember);
                                    }

                                    groupMemberContext.SaveChanges();

                                    // If the Group has an exit email, and person has an email address, send them the exit email
                                    if (sync.ExitSystemEmail != null)
                                    {
                                        var person = new PersonService(groupMemberContext).Get(personId);
                                        if (person.Email.IsNotNullOrWhiteSpace())
                                        {
                                            // Send the exit email
                                            var mergeFields = new Dictionary <string, object>();
                                            mergeFields.Add("Group", sync.Group);
                                            mergeFields.Add("Person", person);
                                            var emailMessage = new RockEmailMessage(sync.ExitSystemEmail);
                                            emailMessage.AddRecipient(new RecipientData(person.Email, mergeFields));
                                            var emailErrors = new List <string>();
                                            emailMessage.Send(out emailErrors);
                                            errors.AddRange(emailErrors);
                                        }
                                    }
                                }

                                hasSyncChanged = true;
                            }

                            foreach (var personId in sourcePersonIds.Where(s => !targetPersonIds.Contains(s)))
                            {
                                // Use a new context to limit the amount of change-tracking required
                                using (var groupMemberContext = new RockContext())
                                {
                                    // Add new person to the group with the role specified in the sync
                                    var groupMemberService = new GroupMemberService(groupMemberContext);
                                    var newGroupMember     = new GroupMember {
                                        Id = 0
                                    };
                                    newGroupMember.PersonId          = personId;
                                    newGroupMember.GroupId           = sync.GroupId;
                                    newGroupMember.GroupMemberStatus = GroupMemberStatus.Active;
                                    newGroupMember.GroupRoleId       = sync.GroupTypeRoleId;
                                    groupMemberService.Add(newGroupMember);
                                    groupMemberContext.SaveChanges();

                                    // If the Group has a welcome email, and person has an email address, send them the welcome email and possibly create a login
                                    if (sync.WelcomeSystemEmail != null)
                                    {
                                        var person = new PersonService(groupMemberContext).Get(personId);
                                        if (person.Email.IsNotNullOrWhiteSpace())
                                        {
                                            // If the group is configured to add a user account for anyone added to the group, and person does not yet have an
                                            // account, add one for them.
                                            string newPassword = string.Empty;
                                            bool   createLogin = sync.AddUserAccountsDuringSync;

                                            // Only create a login if requested, no logins exist and we have enough information to generate a username.
                                            if (createLogin && !person.Users.Any() && !string.IsNullOrWhiteSpace(person.NickName) && !string.IsNullOrWhiteSpace(person.LastName))
                                            {
                                                newPassword = System.Web.Security.Membership.GeneratePassword(9, 1);
                                                string username = Rock.Security.Authentication.Database.GenerateUsername(person.NickName, person.LastName);

                                                UserLogin login = UserLoginService.Create(
                                                    groupMemberContext,
                                                    person,
                                                    AuthenticationServiceType.Internal,
                                                    EntityTypeCache.Get(Rock.SystemGuid.EntityType.AUTHENTICATION_DATABASE.AsGuid()).Id,
                                                    username,
                                                    newPassword,
                                                    true,
                                                    requirePasswordReset);
                                            }

                                            // Send the welcome email
                                            var mergeFields = new Dictionary <string, object>();
                                            mergeFields.Add("Group", sync.Group);
                                            mergeFields.Add("Person", person);
                                            mergeFields.Add("NewPassword", newPassword);
                                            mergeFields.Add("CreateLogin", createLogin);
                                            var emailMessage = new RockEmailMessage(sync.WelcomeSystemEmail);
                                            emailMessage.AddRecipient(new RecipientData(person.Email, mergeFields));
                                            var emailErrors = new List <string>();
                                            emailMessage.Send(out emailErrors);
                                            errors.AddRange(emailErrors);
                                        }
                                    }
                                }

                                hasSyncChanged = true;
                            }

                            // Increment Groups Changed Counter (if people were deleted or added to the group)
                            if (hasSyncChanged)
                            {
                                groupsChanged++;
                            }

                            // Increment the Groups Synced Counter
                            groupsSynced++;
                        }
                    }
                }

                // Format the result message
                var resultMessage = string.Empty;
                if (groupsSynced == 0)
                {
                    resultMessage = "No groups to sync";
                }
                else if (groupsSynced == 1)
                {
                    resultMessage = "1 group was sync'ed";
                }
                else
                {
                    resultMessage = string.Format("{0} groups were sync'ed", groupsSynced);
                }

                resultMessage += string.Format(" and {0} groups were changed", groupsChanged);

                if (errors.Any())
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine();
                    sb.Append("Errors: ");
                    errors.ForEach(e => { sb.AppendLine(); sb.Append(e); });
                    string errorMessage = sb.ToString();
                    resultMessage += errorMessage;
                    throw new Exception(errorMessage);
                }

                context.Result = resultMessage;
            }
            catch (System.Exception ex)
            {
                HttpContext context2 = HttpContext.Current;
                ExceptionLogService.LogException(ex, context2);
                throw;
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// Job that will sync groups.
        ///
        /// Called by the <see cref="IScheduler" /> when a
        /// <see cref="ITrigger" /> fires that is associated with
        /// the <see cref="IJob" />.
        /// </summary>
        public virtual void Execute(IJobExecutionContext context)
        {
            JobDataMap dataMap = context.JobDetail.JobDataMap;

            bool requirePasswordReset = dataMap.GetBoolean("RequirePasswordReset");

            int groupsSynced  = 0;
            int groupsChanged = 0;

            try
            {
                // get groups set to sync
                GroupService groupService     = new GroupService(new RockContext());
                var          groupIdsThatSync = groupService.Queryable().Where(g => g.SyncDataViewId != null).Select(a => a.Id).ToList();

                foreach (var syncGroupId in groupIdsThatSync)
                {
                    bool hasGroupChanged = false;

                    // use a fresh rockContext per group so that ChangeTracker doesn't get bogged down
                    using (var rockContext = new RockContext())
                    {
                        var syncGroup = new GroupService(rockContext).Get(syncGroupId);
                        GroupMemberService groupMemberService = new GroupMemberService(rockContext);

                        // increase the timeout just in case the dataview source is slow
                        rockContext.Database.CommandTimeout = 180;

                        var syncSource = new DataViewService(rockContext).Get(syncGroup.SyncDataViewId.Value);

                        // ensure this is a person dataview
                        bool isPersonDataSet = syncSource.EntityTypeId == EntityTypeCache.Read(typeof(Rock.Model.Person)).Id;

                        if (isPersonDataSet)
                        {
                            SortProperty sortById = new SortProperty();
                            sortById.Property  = "Id";
                            sortById.Direction = System.Web.UI.WebControls.SortDirection.Ascending;
                            List <string> errorMessages = new List <string>();

                            var personService       = new PersonService(rockContext);
                            var parameterExpression = personService.ParameterExpression;
                            var whereExpression     = syncSource.GetExpression(personService, parameterExpression, out errorMessages);
                            var sourceItems         = personService.Get(parameterExpression, whereExpression).Select(q => q.Id).ToList();
                            var targetItems         = groupMemberService.Queryable().Where(gm => gm.GroupId == syncGroup.Id).ToList();

                            // delete items from the target not in the source
                            foreach (var targetItem in targetItems.Where(t => !sourceItems.Contains(t.PersonId)))
                            {
                                // made a clone of the person as it will be detached when the group member is deleted. Also
                                // saving the delete before the email is sent in case an exception occurs so the user doesn't
                                // get an email everytime the agent runs.
                                Person recipient = (Person)targetItem.Person.Clone();
                                groupMemberService.Delete(targetItem);

                                rockContext.SaveChanges();

                                hasGroupChanged = true;

                                if (syncGroup.ExitSystemEmailId.HasValue)
                                {
                                    SendExitEmail(syncGroup.ExitSystemEmailId.Value, recipient, syncGroup);
                                }
                            }

                            // add items not in target but in the source
                            foreach (var sourceItem in sourceItems.Where(s => !targetItems.Select(t => t.PersonId).Contains(s)))
                            {
                                // add source to target
                                var newGroupMember = new GroupMember {
                                    Id = 0
                                };
                                newGroupMember.PersonId          = sourceItem;
                                newGroupMember.Group             = syncGroup;
                                newGroupMember.GroupMemberStatus = GroupMemberStatus.Active;
                                newGroupMember.GroupRoleId       = syncGroup.GroupType.DefaultGroupRoleId ?? syncGroup.GroupType.Roles.FirstOrDefault().Id;
                                groupMemberService.Add(newGroupMember);

                                hasGroupChanged = true;

                                if (syncGroup.WelcomeSystemEmailId.HasValue)
                                {
                                    SendWelcomeEmail(syncGroup.WelcomeSystemEmailId.Value, sourceItem, syncGroup, syncGroup.AddUserAccountsDuringSync ?? false, requirePasswordReset);
                                }
                            }

                            if (hasGroupChanged)
                            {
                                groupsChanged++;
                            }

                            groupsSynced++;

                            rockContext.SaveChanges();

                            if (hasGroupChanged && (syncGroup.IsSecurityRole || syncGroup.GroupType.Guid.Equals(Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid())))
                            {
                                Rock.Security.Role.Flush(syncGroup.Id);
                            }
                        }
                    }
                }

                var resultMessage = string.Empty;
                if (groupsSynced == 0)
                {
                    resultMessage = "No groups to sync";
                }
                else if (groupsSynced == 1)
                {
                    resultMessage = "1 group was sync'ed";
                }
                else
                {
                    resultMessage = string.Format("{0} groups were sync'ed", groupsSynced);
                }

                resultMessage += string.Format(" and {0} groups where changed", groupsChanged);

                context.Result = resultMessage;
            }
            catch (System.Exception ex)
            {
                HttpContext context2 = HttpContext.Current;
                ExceptionLogService.LogException(ex, context2);
                throw;
            }
        }
Exemplo n.º 24
0
        private static void SyncAttendee(RockContext rockContext, Attendee attendee, Order order, Group group, GroupMemberService groupMemberService, PersonAliasService personAliasService, AttendanceOccurrence occ, long evntid, bool IsRSVPEvent, string gmPersonAttributeKey, bool updatePrimaryEmail, int recordStatusId = 5, int connectionStatusId = 66, bool EnableLogging = false)
        {
            if (string.IsNullOrWhiteSpace(attendee.Profile.Email))
            {
                attendee.Profile.Email = order.Email;
            }

            if (!string.IsNullOrWhiteSpace(attendee.Profile.First_Name) && !string.IsNullOrWhiteSpace(attendee.Profile.Last_Name) && !string.IsNullOrWhiteSpace(attendee.Profile.Email))
            {
                var person             = MatchOrAddPerson(rockContext, attendee.Profile, connectionStatusId, updatePrimaryEmail, EnableLogging);
                var matchedGroupMember = MatchGroupMember(group.Members, order, person.Id, gmPersonAttributeKey, rockContext, EnableLogging);
                if (matchedGroupMember == null && (order.Status != "deleted" || order.Status != "abandoned"))
                {
                    var member = new GroupMember
                    {
                        GroupId           = group.Id,
                        Person            = person,
                        GuestCount        = (order.Attendees != null) ? order.Attendees.Count : 1,
                        GroupRoleId       = group.GroupType.DefaultGroupRoleId.Value,
                        GroupMemberStatus = GroupMemberStatus.Active
                    };

                    groupMemberService.Add(member);

                    SetPersonData(rockContext, person, attendee, group, IsRSVPEvent && order.Attendees != null ? order.Attendees.Count : attendee.Quantity, EnableLogging);
                }
                else if (matchedGroupMember != null && order.Status == "deleted")
                {
                    matchedGroupMember.GroupMemberStatus = GroupMemberStatus.Inactive;
                    matchedGroupMember.Note = "Eventbrite order deleted!";

                    groupMemberService.Delete(matchedGroupMember);
                }
                else if (matchedGroupMember != null && order.Status == "refunded")
                {
                    matchedGroupMember.GroupMemberStatus = GroupMemberStatus.Inactive;
                    matchedGroupMember.Note = "Eventbrite order canceled/refunded!";
                }
                else if (matchedGroupMember != null)
                {
                    if (matchedGroupMember.Attributes == null)
                    {
                        matchedGroupMember.LoadAttributes(rockContext);
                    }
                    var attributeVal = matchedGroupMember.GetAttributeValue(gmPersonAttributeKey);
                    if (attributeVal.IsNotNullOrWhiteSpace())
                    {
                        // Attribute Values in our special eventBritePerson field type are stored as a delimited string Eventbrite Id^Ticket Class(es)^Eventbrite Order Id^RSVP/Ticket Count(s)
                        var splitVal      = attributeVal.SplitDelimitedValues("^");
                        var ticketClasses = splitVal[1].SplitDelimitedValues("||");
                        var ticketQtys    = splitVal[3].SplitDelimitedValues("||");
                        if (!ticketClasses.Contains(attendee.Ticket_Class_Name))
                        {
                            splitVal[1] += "||" + attendee.Ticket_Class_Name;
                            splitVal[3] += "||" + order.Attendees?.Count(a => a.Profile.First_Name == attendee.Profile.First_Name && a.Profile.Last_Name == attendee.Profile.Last_Name && a.Profile.Email == attendee.Profile.Email && a.Ticket_Class_Id == attendee.Ticket_Class_Id).ToString();
                        }
                        else
                        {
                            ticketQtys[Array.IndexOf(ticketClasses, attendee.Ticket_Class_Name)] = order.Attendees?.Count(a => a.Profile.First_Name == attendee.Profile.First_Name && a.Profile.Last_Name == attendee.Profile.Last_Name && a.Profile.Email == attendee.Profile.Email && a.Ticket_Class_Id == attendee.Ticket_Class_Id).ToString();
                            splitVal[3] = ticketQtys.JoinStrings("||");
                        }
                        matchedGroupMember.SetAttributeValue(gmPersonAttributeKey, splitVal.JoinStrings("^"));
                        matchedGroupMember.SaveAttributeValue(gmPersonAttributeKey);
                    }
                }

                //Record Attendance
                if (attendee.Checked_In)
                {
                    if (EnableLogging)
                    {
                        LogEvent(rockContext, "SyncAttendee", string.Format("Attendee.Checked_in", evntid), "True");
                    }

                    var attendance = occ.Attendees
                                     .Where(a => a.PersonAlias != null && a.PersonAlias.PersonId == person.Id)
                                     .FirstOrDefault();

                    if (attendance == null)
                    {
                        int?personAliasId = personAliasService.GetPrimaryAliasId(person.Id);
                        if (personAliasId.HasValue)
                        {
                            attendance = new Attendance
                            {
                                PersonAliasId = personAliasId,
                                StartDateTime = occ.Schedule != null && occ.Schedule.HasSchedule() ? occ.OccurrenceDate.Date.Add(occ.Schedule.StartTimeOfDay) : occ.OccurrenceDate,
                                DidAttend     = true
                            };

                            occ.Attendees.Add(attendance);
                        }
                    }
                    else
                    {
                        // Otherwise, only record that they attended -- don't change their attendance startDateTime
                        attendance.DidAttend = true;
                    }
                    rockContext.SaveChanges();
                }
            }
        }
Exemplo n.º 25
0
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            // Determine which group to add the person to
            Group group = null;

            var guidGroupAttribute = GetAttributeValue(action, "Group").AsGuidOrNull();

            if (guidGroupAttribute.HasValue)
            {
                var attributeGroup = AttributeCache.Get(guidGroupAttribute.Value, rockContext);
                if (attributeGroup != null)
                {
                    var groupGuid = action.GetWorkflowAttributeValue(guidGroupAttribute.Value).AsGuidOrNull();

                    if (groupGuid.HasValue)
                    {
                        group = new GroupService(rockContext).Get(groupGuid.Value);
                    }
                }
            }

            if (group == null)
            {
                errorMessages.Add("No group was provided");
            }

            // determine the person that will be added to the group
            Person person = null;

            // get the Attribute.Guid for this workflow's Person Attribute so that we can lookup the value
            var guidPersonAttribute = GetAttributeValue(action, "Person").AsGuidOrNull();

            if (guidPersonAttribute.HasValue)
            {
                var attributePerson = AttributeCache.Get(guidPersonAttribute.Value, rockContext);
                if (attributePerson != null)
                {
                    string attributePersonValue = action.GetWorkflowAttributeValue(guidPersonAttribute.Value);
                    if (!string.IsNullOrWhiteSpace(attributePersonValue))
                    {
                        if (attributePerson.FieldType.Class == typeof(Rock.Field.Types.PersonFieldType).FullName)
                        {
                            Guid personAliasGuid = attributePersonValue.AsGuid();
                            if (!personAliasGuid.IsEmpty())
                            {
                                person = new PersonAliasService(rockContext).Queryable()
                                         .Where(a => a.Guid.Equals(personAliasGuid))
                                         .Select(a => a.Person)
                                         .FirstOrDefault();
                            }
                        }
                        else
                        {
                            errorMessages.Add("The attribute used to provide the person was not of type 'Person'.");
                        }
                    }
                }
            }

            if (person == null)
            {
                errorMessages.Add(string.Format("Person could not be found for selected value ('{0}')!", guidPersonAttribute.ToString()));
            }

            // remove person from group
            if (!errorMessages.Any())
            {
                try
                {
                    var groupMemberService = new GroupMemberService(rockContext);
                    var groupMembers       = groupMemberService.Queryable().Where(m => m.PersonId == person.Id && m.GroupId == group.Id);

                    foreach (var groupMember in groupMembers)
                    {
                        groupMemberService.Delete(groupMember);
                    }

                    rockContext.SaveChanges();
                }
                catch (Exception ex)
                {
                    errorMessages.Add(string.Format("An error occurred while removing the group member: {0}", ex.Message));
                }
            }

            errorMessages.ForEach(m => action.AddLogEntry(m, true));

            return(true);
        }
Exemplo n.º 26
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        {
            // confirmation was disabled by btnSave on client-side.  So if returning without a redirect,
            // it should be enabled.  If returning with a redirect, the control won't be updated to reflect
            // confirmation being enabled, so it's ok to enable it here
            confirmExit.Enabled = true;

            if (Page.IsValid)
            {
                confirmExit.Enabled = true;

                using (new UnitOfWorkScope())
                {
                    var familyService       = new GroupService();
                    var familyMemberService = new GroupMemberService();
                    var personService       = new PersonService();

                    // SAVE FAMILY
                    _family          = familyService.Get(_family.Id);
                    _family.Name     = tbFamilyName.Text;
                    _family.CampusId = cpCampus.SelectedValueAsInt();

                    var familyGroupTypeId = _family.GroupTypeId;

                    familyService.Save(_family, CurrentPersonId);

                    // SAVE FAMILY MEMBERS
                    int?recordStatusValueID = ddlRecordStatus.SelectedValueAsInt();
                    int?reasonValueId       = ddlReason.SelectedValueAsInt();
                    var newFamilies         = new List <Group>();

                    foreach (var familyMember in FamilyMembers)
                    {
                        var role = familyRoles.Where(r => r.Guid.Equals(familyMember.RoleGuid)).FirstOrDefault();
                        if (role == null)
                        {
                            role = familyRoles.FirstOrDefault();
                        }

                        // People added to family (new or from other family)
                        if (!familyMember.ExistingFamilyMember)
                        {
                            var groupMember = new GroupMember();

                            if (familyMember.Id == -1)
                            {
                                // added new person
                                groupMember.Person           = new Person();
                                groupMember.Person.GivenName = familyMember.FirstName;
                                groupMember.Person.LastName  = familyMember.LastName;
                                groupMember.Person.Gender    = familyMember.Gender;
                                groupMember.Person.BirthDate = familyMember.BirthDate;
                            }
                            else
                            {
                                // added from other family
                                groupMember.Person = personService.Get(familyMember.Id);
                            }

                            groupMember.Person.RecordStatusValueId       = recordStatusValueID;
                            groupMember.Person.RecordStatusReasonValueId = reasonValueId;

                            groupMember.GroupId = _family.Id;
                            if (role != null)
                            {
                                groupMember.GroupRoleId = role.Id;
                            }

                            if (groupMember.Person != null)
                            {
                                familyMemberService.Add(groupMember, CurrentPersonId);
                                familyMemberService.Save(groupMember, CurrentPersonId);
                            }
                        }
                        else
                        {
                            // existing family members
                            var groupMember = familyMemberService.Queryable().Where(m =>
                                                                                    m.PersonId == familyMember.Id &&
                                                                                    m.Group.GroupTypeId == familyGroupTypeId &&
                                                                                    m.GroupId == _family.Id).FirstOrDefault();
                            if (groupMember != null)
                            {
                                if (familyMember.Removed)
                                {
                                    // Family member was removed and should be created in their own new family
                                    var newFamily = new Group();
                                    newFamily.Name        = familyMember.LastName + " Family";
                                    newFamily.GroupTypeId = familyGroupTypeId;
                                    newFamily.CampusId    = _family.CampusId;
                                    familyService.Add(newFamily, CurrentPersonId);
                                    familyService.Save(newFamily, CurrentPersonId);

                                    groupMember.Group = newFamily;
                                    familyMemberService.Save(groupMember, CurrentPersonId);

                                    newFamilies.Add(newFamily);
                                }
                                else
                                {
                                    // Existing member was not remvoved
                                    if (role != null)
                                    {
                                        groupMember.GroupRoleId = role.Id;
                                        groupMember.Person.RecordStatusValueId       = recordStatusValueID;
                                        groupMember.Person.RecordStatusReasonValueId = reasonValueId;
                                        familyMemberService.Save(groupMember, CurrentPersonId);
                                    }
                                }
                            }
                        }

                        // Remove anyone that was moved from another family
                        if (familyMember.RemoveFromOtherFamilies)
                        {
                            var otherFamilies = familyMemberService.Queryable()
                                                .Where(m =>
                                                       m.PersonId == familyMember.Id &&
                                                       m.Group.GroupTypeId == familyGroupTypeId &&
                                                       m.GroupId != _family.Id)
                                                .ToList();

                            foreach (var otherFamilyMember in otherFamilies)
                            {
                                var fm = familyMemberService.Get(otherFamilyMember.Id);
                                familyMemberService.Delete(fm, CurrentPersonId);
                                familyMemberService.Save(fm, CurrentPersonId);

                                var f = familyService.Queryable()
                                        .Where(g =>
                                               g.Id == otherFamilyMember.GroupId &&
                                               !g.Members.Any())
                                        .FirstOrDefault();

                                if (f != null)
                                {
                                    familyService.Delete(f, CurrentPersonId);
                                    familyService.Save(f, CurrentPersonId);
                                }
                            }
                        }
                    }

                    // SAVE LOCATIONS
                    var groupLocationService = new GroupLocationService();

                    // delete any group locations that were removed
                    var remainingLocationIds = FamilyAddresses.Where(a => a.Id > 0).Select(a => a.Id).ToList();
                    foreach (var removedLocation in groupLocationService.Queryable()
                             .Where(l => l.GroupId == _family.Id &&
                                    !remainingLocationIds.Contains(l.Id)))
                    {
                        groupLocationService.Delete(removedLocation, CurrentPersonId);
                        groupLocationService.Save(removedLocation, CurrentPersonId);
                    }

                    foreach (var familyAddress in FamilyAddresses)
                    {
                        Location updatedAddress = null;
                        if (familyAddress.LocationIsDirty)
                        {
                            updatedAddress = new LocationService().Get(
                                familyAddress.Street1, familyAddress.Street2, familyAddress.City,
                                familyAddress.State, familyAddress.Zip);
                        }

                        GroupLocation groupLocation = null;
                        if (familyAddress.Id > 0)
                        {
                            groupLocation = groupLocationService.Get(familyAddress.Id);
                        }
                        if (groupLocation == null)
                        {
                            groupLocation         = new GroupLocation();
                            groupLocation.GroupId = _family.Id;
                            groupLocationService.Add(groupLocation, CurrentPersonId);
                        }

                        groupLocation.GroupLocationTypeValueId = familyAddress.LocationTypeId;
                        groupLocation.IsMailing  = familyAddress.IsMailing;
                        groupLocation.IsLocation = familyAddress.IsLocation;
                        if (updatedAddress != null)
                        {
                            groupLocation.Location = updatedAddress;
                        }

                        groupLocationService.Save(groupLocation, CurrentPersonId);


                        // Add the same locations to any new families created by removing an existing family member
                        if (newFamilies.Any())
                        {
                            //reload grouplocation for access to child properties
                            groupLocation = groupLocationService.Get(groupLocation.Id);
                            foreach (var newFamily in newFamilies)
                            {
                                var newFamilyLocation = new GroupLocation();
                                newFamilyLocation.GroupId    = newFamily.Id;
                                newFamilyLocation.LocationId = groupLocation.LocationId;
                                newFamilyLocation.GroupLocationTypeValueId = groupLocation.GroupLocationTypeValueId;
                                newFamilyLocation.IsMailing  = groupLocation.IsMailing;
                                newFamilyLocation.IsLocation = groupLocation.IsLocation;
                                groupLocationService.Add(newFamilyLocation, CurrentPersonId);
                                groupLocationService.Save(newFamilyLocation, CurrentPersonId);
                            }
                        }
                    }

                    _family = familyService.Get(_family.Id);
                    if (_family.Members.Any(m => m.PersonId == Person.Id))
                    {
                        Response.Redirect(string.Format("~/Person/{0}", Person.Id), false);
                    }
                    else
                    {
                        var fm = _family.Members
                                 .Where(m =>
                                        m.GroupRole.Guid.Equals(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT)) &&
                                        m.Person.Gender == Gender.Male)
                                 .OrderByDescending(m => m.Person.Age)
                                 .FirstOrDefault();
                        if (fm == null)
                        {
                            fm = _family.Members
                                 .Where(m =>
                                        m.GroupRole.Guid.Equals(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT)))
                                 .OrderByDescending(m => m.Person.Age)
                                 .FirstOrDefault();
                        }
                        if (fm == null)
                        {
                            fm = _family.Members
                                 .OrderByDescending(m => m.Person.Age)
                                 .FirstOrDefault();
                        }
                        if (fm != null)
                        {
                            Response.Redirect(string.Format("~/Person/{0}", fm.PersonId), false);
                        }
                        else
                        {
                            Response.Redirect("~", false);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.Load" /> event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (!Page.IsPostBack)
            {
                RockContext rockContext = new RockContext();

                Group group      = null;
                Guid  personGuid = Guid.Empty;

                // get group id from url
                if (Request["GroupId"] != null)
                {
                    int groupId = 0;
                    if (Int32.TryParse(Request["GroupId"], out groupId))
                    {
                        group = new GroupService(rockContext).Queryable().Where(g => g.Id == groupId).FirstOrDefault();
                    }
                }
                else
                {
                    Guid groupGuid = Guid.Empty;
                    if (Guid.TryParse(GetAttributeValue("DefaultGroup"), out groupGuid))
                    {
                        group = new GroupService(rockContext).Queryable().Where(g => g.Guid == groupGuid).FirstOrDefault();;
                    }
                }

                if (group == null)
                {
                    lAlerts.Text = "Could not determine the group to add to.";
                    return;
                }

                // get person
                Person person = null;

                if (!string.IsNullOrWhiteSpace(Request["PersonGuid"]))
                {
                    person = new PersonService(rockContext).Get(Request["PersonGuid"].AsGuid());
                }

                if (person == null)
                {
                    lAlerts.Text += "A person could not be found for the identifier provided.";
                    return;
                }

                // hide alert
                divAlert.Visible = false;

                // get status
                var groupMemberStatus = this.GetAttributeValue("GroupMemberStatus").ConvertToEnum <GroupMemberStatus>(GroupMemberStatus.Active);

                // load merge fields
                var mergeFields = new Dictionary <string, object>();
                mergeFields.Add("Group", group);
                mergeFields.Add("Person", person);
                mergeFields.Add("CurrentPerson", CurrentPerson);

                // show debug info?
                bool enableDebug = GetAttributeValue("EnableDebug").AsBoolean();
                if (enableDebug && IsUserAuthorized(Authorization.EDIT))
                {
                    lDebug.Visible = true;
                    lDebug.Text    = mergeFields.lavaDebugInfo();
                }

                var groupMemberService = new GroupMemberService(rockContext);

                var groupMemberList = groupMemberService.Queryable()
                                      .Where(m => m.GroupId == group.Id && m.PersonId == person.Id)
                                      .ToList();

                if (groupMemberList.Count > 0)
                {
                    foreach (var groupMember in groupMemberList)
                    {
                        groupMemberService.Delete(groupMember);
                        rockContext.SaveChanges();
                    }

                    lContent.Text = GetAttributeValue("SuccessMessage").ResolveMergeFields(mergeFields);
                }
                else
                {
                    if (GetAttributeValue("WarnWhenNotInGroup").AsBoolean())
                    {
                        lContent.Text = GetAttributeValue("NotInGroupMessage").ResolveMergeFields(mergeFields);
                    }
                    else
                    {
                        lContent.Text = GetAttributeValue("SuccessMessage").ResolveMergeFields(mergeFields);
                    }
                }
            }
        }
Exemplo n.º 28
0
        /// <summary>
        /// Job that will sync groups.
        ///
        /// Called by the <see cref="IScheduler" /> when a
        /// <see cref="ITrigger" /> fires that is associated with
        /// the <see cref="IJob" />.
        /// </summary>
        public virtual void Execute(IJobExecutionContext context)
        {
            // Get the job setting(s)
            JobDataMap dataMap = context.JobDetail.JobDataMap;
            bool       requirePasswordReset = dataMap.GetBoolean("RequirePasswordReset");

            // Counters for displaying results
            int groupsSynced  = 0;
            int groupsChanged = 0;

            try
            {
                // get groups set to sync
                var groupIdsThatSync = new List <int>();
                using (var rockContext = new RockContext())
                {
                    groupIdsThatSync = new GroupService(rockContext)
                                       .Queryable().AsNoTracking()
                                       .Where(g => g.SyncDataViewId != null)
                                       .Select(a => a.Id)
                                       .ToList();
                }

                foreach (var syncGroupId in groupIdsThatSync)
                {
                    bool hasGroupChanged = false;

                    // Use a fresh rockContext per group so that ChangeTracker doesn't get bogged down
                    using (var rockContext = new RockContext())
                    {
                        // increase the timeout just in case the dataview source is slow
                        rockContext.Database.CommandTimeout = 180;

                        // Get the Group
                        var syncGroup = new GroupService(rockContext)
                                        .Queryable().AsNoTracking()
                                        .FirstOrDefault(t => t.Id == syncGroupId);

                        // Ensure that the group's Sync Data View is a person dataview
                        if (syncGroup.SyncDataView.EntityTypeId == EntityTypeCache.Read(typeof(Person)).Id)
                        {
                            List <string> errorMessages = new List <string>();

                            // Get the person id's from the dataview (source)
                            var personService       = new PersonService(rockContext);
                            var parameterExpression = personService.ParameterExpression;
                            var whereExpression     = syncGroup.SyncDataView.GetExpression(personService, parameterExpression, out errorMessages);
                            var sourcePersonIds     = new PersonService(rockContext)
                                                      .Get(parameterExpression, whereExpression)
                                                      .Select(q => q.Id)
                                                      .ToList();

                            // Get the person id's in the group (target)
                            var targetPersonIds = new GroupMemberService(rockContext)
                                                  .Queryable().AsNoTracking()
                                                  .Where(gm => gm.GroupId == syncGroup.Id)
                                                  .Select(gm => gm.PersonId)
                                                  .ToList();

                            // Delete people from the group that are no longer in the dataview
                            foreach (var personId in targetPersonIds.Where(t => !sourcePersonIds.Contains(t)))
                            {
                                // Use a new context to limit the amount of change-tracking required
                                using (var groupMemberContext = new RockContext())
                                {
                                    // Delete any group members with the person id
                                    var groupMemberService = new GroupMemberService(groupMemberContext);
                                    foreach (var groupMember in groupMemberService
                                             .Queryable()
                                             .Where(m =>
                                                    m.GroupId == syncGroupId &&
                                                    m.PersonId == personId)
                                             .ToList())
                                    {
                                        groupMemberService.Delete(groupMember);
                                    }
                                    groupMemberContext.SaveChanges();

                                    // If the Group has an exit email, and person has an email address, send them the exit email
                                    if (syncGroup.ExitSystemEmail != null)
                                    {
                                        var person = new PersonService(groupMemberContext).Get(personId);
                                        if (person.Email.IsNotNullOrWhitespace())
                                        {
                                            // Send the exit email
                                            var mergeFields = new Dictionary <string, object>();
                                            mergeFields.Add("Group", syncGroup);
                                            mergeFields.Add("Person", person);
                                            var emailMessage = new RockEmailMessage(syncGroup.ExitSystemEmail);
                                            emailMessage.AddRecipient(new RecipientData(person.Email, mergeFields));
                                            emailMessage.Send();
                                        }
                                    }
                                }

                                hasGroupChanged = true;
                            }

                            // Add people to the group that are in the dataview and not currently in the group
                            int groupRoleId = syncGroup.GroupType.DefaultGroupRoleId ?? syncGroup.GroupType.Roles.FirstOrDefault().Id;
                            foreach (var personId in sourcePersonIds.Where(s => !targetPersonIds.Contains(s)))
                            {
                                // Use a new context to limit the amount of change-tracking required
                                using (var groupMemberContext = new RockContext())
                                {
                                    // Add new person to the group
                                    var groupMemberService = new GroupMemberService(groupMemberContext);
                                    var newGroupMember     = new GroupMember {
                                        Id = 0
                                    };
                                    newGroupMember.PersonId          = personId;
                                    newGroupMember.GroupId           = syncGroup.Id;
                                    newGroupMember.GroupMemberStatus = GroupMemberStatus.Active;
                                    newGroupMember.GroupRoleId       = groupRoleId;
                                    groupMemberService.Add(newGroupMember);
                                    groupMemberContext.SaveChanges();

                                    // If the Group has a welcome email, and person has an email address, send them the welcome email and possibly create a login
                                    if (syncGroup.WelcomeSystemEmail != null)
                                    {
                                        var person = new PersonService(groupMemberContext).Get(personId);
                                        if (person.Email.IsNotNullOrWhitespace())
                                        {
                                            // If the group is configured to add a user account for anyone added to the group, and person does not yet have an
                                            // account, add one for them.
                                            string newPassword = string.Empty;
                                            bool   createLogin = syncGroup.AddUserAccountsDuringSync ?? false;

                                            // Only create a login if requested, no logins exist and we have enough information to generate a username.
                                            if (createLogin && !person.Users.Any() && !string.IsNullOrWhiteSpace(person.NickName) && !string.IsNullOrWhiteSpace(person.LastName))
                                            {
                                                newPassword = System.Web.Security.Membership.GeneratePassword(9, 1);
                                                string username = Rock.Security.Authentication.Database.GenerateUsername(person.NickName, person.LastName);

                                                UserLogin login = UserLoginService.Create(
                                                    groupMemberContext,
                                                    person,
                                                    AuthenticationServiceType.Internal,
                                                    EntityTypeCache.Read(Rock.SystemGuid.EntityType.AUTHENTICATION_DATABASE.AsGuid()).Id,
                                                    username,
                                                    newPassword,
                                                    true,
                                                    requirePasswordReset);
                                            }

                                            // Send the welcome email
                                            var mergeFields = new Dictionary <string, object>();
                                            mergeFields.Add("Group", syncGroup);
                                            mergeFields.Add("Person", person);
                                            mergeFields.Add("NewPassword", newPassword);
                                            mergeFields.Add("CreateLogin", createLogin);
                                            var emailMessage = new RockEmailMessage(syncGroup.WelcomeSystemEmail);
                                            emailMessage.AddRecipient(new RecipientData(person.Email, mergeFields));
                                            emailMessage.Send();
                                        }
                                    }
                                }

                                hasGroupChanged = true;
                            }

                            // Increment Groups Changed Counter (if people were deleted or added to the group)
                            if (hasGroupChanged)
                            {
                                groupsChanged++;
                            }

                            // Increment the Groups Synced Counter
                            groupsSynced++;

                            // If the group changed, and it was a security group, flush the security for the group
                            if (hasGroupChanged && (syncGroup.IsSecurityRole || syncGroup.GroupType.Guid.Equals(Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid())))
                            {
                                Rock.Security.Role.Flush(syncGroup.Id);
                            }
                        }
                    }
                }

                // Format the result message
                var resultMessage = string.Empty;
                if (groupsSynced == 0)
                {
                    resultMessage = "No groups to sync";
                }
                else if (groupsSynced == 1)
                {
                    resultMessage = "1 group was sync'ed";
                }
                else
                {
                    resultMessage = string.Format("{0} groups were sync'ed", groupsSynced);
                }
                resultMessage += string.Format(" and {0} groups were changed", groupsChanged);
                context.Result = resultMessage;
            }
            catch (System.Exception ex)
            {
                HttpContext context2 = HttpContext.Current;
                ExceptionLogService.LogException(ex, context2);
                throw;
            }
        }
Exemplo n.º 29
0
        /// <summary>
        /// Handles the SaveClick event of the modalAddPerson control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void modalAddPerson_SaveClick(object sender, EventArgs e)
        {
            if (CanEdit)
            {
                if (ppPerson.PersonId.HasValue)
                {
                    int?roleId = grpRole.GroupRoleId;
                    if (roleId.HasValue)
                    {
                        var rockContext   = new RockContext();
                        var memberService = new GroupMemberService(rockContext);

                        var group = memberService.Queryable(true)
                                    .Where(m =>
                                           m.PersonId == Person.Id &&
                                           m.GroupRole.Guid == ownerRoleGuid)
                                    .Select(m => m.Group)
                                    .FirstOrDefault();

                        if (group != null)
                        {
                            GroupMember groupMember   = null;
                            int?        groupMemberId = hfRoleId.Value.AsIntegerOrNull();
                            if (groupMemberId.HasValue)
                            {
                                groupMember = memberService.Queryable(true)
                                              .Where(m => m.Id == groupMemberId.Value)
                                              .FirstOrDefault();
                            }

                            if (groupMember == null)
                            {
                                groupMember         = new GroupMember();
                                groupMember.GroupId = group.Id;
                                memberService.Add(groupMember);
                            }

                            GroupMember formerInverseGroupMember = null;
                            if (IsKnownRelationships)
                            {
                                formerInverseGroupMember = memberService.GetInverseRelationship(groupMember, false);
                            }

                            groupMember.PersonId    = ppPerson.PersonId.Value;
                            groupMember.GroupRoleId = roleId.Value;

                            rockContext.SaveChanges();

                            if (IsKnownRelationships)
                            {
                                var inverseGroupMember = memberService.GetInverseRelationship(groupMember, GetAttributeValue("CreateGroup").AsBoolean());
                                if (inverseGroupMember != null)
                                {
                                    rockContext.SaveChanges();
                                    if (formerInverseGroupMember != null && formerInverseGroupMember.Id != inverseGroupMember.Id)
                                    {
                                        memberService.Delete(formerInverseGroupMember);
                                        rockContext.SaveChanges();
                                    }
                                }
                            }
                        }
                    }
                }

                HideDialog();

                BindData();
            }
        }
Exemplo n.º 30
0
        /// <summary>
        /// Job that will sync groups.
        ///
        /// Called by the <see cref="IScheduler" /> when a
        /// <see cref="ITrigger" /> fires that is associated with
        /// the <see cref="IJob" />.
        /// </summary>
        public virtual void Execute(IJobExecutionContext context)
        {
            // Get the job setting(s)
            JobDataMap dataMap = context.JobDetail.JobDataMap;
            bool       requirePasswordReset = dataMap.GetBoolean("RequirePasswordReset");
            var        commandTimeout       = dataMap.GetString("CommandTimeout").AsIntegerOrNull() ?? 180;

            // Counters for displaying results
            int    groupsSynced  = 0;
            int    groupsChanged = 0;
            string groupName     = string.Empty;
            string dataViewName  = string.Empty;
            var    errors        = new List <string>();

            try
            {
                // get groups set to sync
                var activeSyncList = new List <GroupSyncInfo>();
                using (var rockContext = new RockContext())
                {
                    // Get groups that are not archived and are still active.
                    activeSyncList = new GroupSyncService(rockContext)
                                     .Queryable()
                                     .AsNoTracking()
                                     .AreNotArchived()
                                     .AreActive()
                                     .NeedToBeSynced()
                                     .Select(x => new GroupSyncInfo {
                        SyncId = x.Id, GroupName = x.Group.Name
                    })
                                     .ToList();
                }

                foreach (var syncInfo in activeSyncList)
                {
                    int  syncId         = syncInfo.SyncId;
                    bool hasSyncChanged = false;
                    context.UpdateLastStatusMessage($"Syncing group {syncInfo.GroupName}");

                    // Use a fresh rockContext per sync so that ChangeTracker doesn't get bogged down
                    using (var rockContext = new RockContext())
                    {
                        // increase the timeout just in case the data view source is slow
                        rockContext.Database.CommandTimeout = commandTimeout;
                        rockContext.SourceOfChange          = "Group Sync";

                        // Get the Sync
                        var sync = new GroupSyncService(rockContext)
                                   .Queryable()
                                   .Include(a => a.Group)
                                   .Include(a => a.SyncDataView)
                                   .AsNoTracking()
                                   .FirstOrDefault(s => s.Id == syncId);

                        if (sync == null || sync.SyncDataView.EntityTypeId != EntityTypeCache.Get(typeof(Person)).Id)
                        {
                            // invalid sync or invalid SyncDataView
                            continue;
                        }

                        List <string> syncErrors = new List <string>();

                        dataViewName = sync.SyncDataView.Name;
                        groupName    = sync.Group.Name;

                        Stopwatch stopwatch = Stopwatch.StartNew();
                        // Get the person id's from the data view (source)
                        var dataViewQry     = sync.SyncDataView.GetQuery(null, rockContext, commandTimeout, out syncErrors);
                        var sourcePersonIds = dataViewQry.Select(q => q.Id).ToList();
                        stopwatch.Stop();
                        DataViewService.AddRunDataViewTransaction(sync.SyncDataView.Id,
                                                                  Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds));
                        // If any error occurred trying get the 'where expression' from the sync-data-view,
                        // just skip trying to sync that particular group's Sync Data View for now.
                        if (syncErrors.Count > 0)
                        {
                            errors.AddRange(syncErrors);
                            ExceptionLogService.LogException(new Exception(string.Format("An error occurred while trying to GroupSync group '{0}' and data view '{1}' so the sync was skipped. Error: {2}", groupName, dataViewName, String.Join(",", syncErrors))));
                            continue;
                        }

                        // Get the person id's in the group (target) for the role being synced.
                        // Note: targetPersonIds must include archived group members
                        // so we don't try to delete anyone who's already archived, and
                        // it must include deceased members so we can remove them if they
                        // are no longer in the data view.
                        var existingGroupMemberPersonList = new GroupMemberService(rockContext)
                                                            .Queryable(true, true).AsNoTracking()
                                                            .Where(gm => gm.GroupId == sync.GroupId)
                                                            .Where(gm => gm.GroupRoleId == sync.GroupTypeRoleId)
                                                            .Select(gm => new
                        {
                            PersonId   = gm.PersonId,
                            IsArchived = gm.IsArchived
                        })
                                                            .ToList();

                        var targetPersonIdsToDelete = existingGroupMemberPersonList.Where(t => !sourcePersonIds.Contains(t.PersonId) && t.IsArchived != true).ToList();
                        if (targetPersonIdsToDelete.Any())
                        {
                            context.UpdateLastStatusMessage($"Deleting {targetPersonIdsToDelete.Count()} group records in {syncInfo.GroupName} that are no longer in the sync data view");
                        }

                        int deletedCount = 0;

                        // Delete people from the group/role that are no longer in the data view --
                        // but not the ones that are already archived.
                        foreach (var targetPerson in targetPersonIdsToDelete)
                        {
                            deletedCount++;
                            if (deletedCount % 100 == 0)
                            {
                                context.UpdateLastStatusMessage($"Deleted {deletedCount} of {targetPersonIdsToDelete.Count()} group member records for group {syncInfo.GroupName}");
                            }

                            try
                            {
                                // Use a new context to limit the amount of change-tracking required
                                using (var groupMemberContext = new RockContext())
                                {
                                    // Delete the records for that person's group and role.
                                    // NOTE: just in case there are duplicate records, delete all group member records for that person and role
                                    var groupMemberService = new GroupMemberService(groupMemberContext);
                                    foreach (var groupMember in groupMemberService
                                             .Queryable(true, true)
                                             .Where(m =>
                                                    m.GroupId == sync.GroupId &&
                                                    m.GroupRoleId == sync.GroupTypeRoleId &&
                                                    m.PersonId == targetPerson.PersonId)
                                             .ToList())
                                    {
                                        groupMemberService.Delete(groupMember);
                                    }

                                    groupMemberContext.SaveChanges();

                                    // If the Group has an exit email, and person has an email address, send them the exit email
                                    if (sync.ExitSystemCommunication != null)
                                    {
                                        var person = new PersonService(groupMemberContext).Get(targetPerson.PersonId);
                                        if (person.CanReceiveEmail(false))
                                        {
                                            // Send the exit email
                                            var mergeFields = new Dictionary <string, object>();
                                            mergeFields.Add("Group", sync.Group);
                                            mergeFields.Add("Person", person);
                                            var emailMessage = new RockEmailMessage(sync.ExitSystemCommunication);
                                            emailMessage.AddRecipient(new RockEmailMessageRecipient(person, mergeFields));
                                            var emailErrors = new List <string>();
                                            emailMessage.Send(out emailErrors);
                                            errors.AddRange(emailErrors);
                                        }
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                ExceptionLogService.LogException(ex);
                                continue;
                            }

                            hasSyncChanged = true;
                        }


                        // Now find all the people in the source list who are NOT already in the target list (as Unarchived)
                        var targetPersonIdsToAdd = sourcePersonIds.Where(s => !existingGroupMemberPersonList.Any(t => t.PersonId == s && t.IsArchived == false)).ToList();

                        // Make a list of PersonIds that have an Archived group member record
                        // if this person isn't already a member of the list as an Unarchived member, we can Restore the group member for that PersonId instead
                        var archivedTargetPersonIds = existingGroupMemberPersonList.Where(t => t.IsArchived == true).Select(a => a.PersonId).ToList();

                        context.UpdateLastStatusMessage($"Adding {targetPersonIdsToAdd.Count()} group member records for group {syncInfo.GroupName}");
                        int addedCount    = 0;
                        int notAddedCount = 0;
                        foreach (var personId in targetPersonIdsToAdd)
                        {
                            if ((addedCount + notAddedCount) % 100 == 0)
                            {
                                string notAddedMessage = string.Empty;
                                if (notAddedCount > 0)
                                {
                                    notAddedMessage = $"{Environment.NewLine} There are {notAddedCount} members that could not be added due to group requirements.";
                                }
                                context.UpdateLastStatusMessage($"Added {addedCount} of {targetPersonIdsToAdd.Count()} group member records for group {syncInfo.GroupName}. {notAddedMessage}");
                            }
                            try
                            {
                                // Use a new context to limit the amount of change-tracking required
                                using (var groupMemberContext = new RockContext())
                                {
                                    var groupMemberService = new GroupMemberService(groupMemberContext);
                                    var groupService       = new GroupService(groupMemberContext);

                                    // If this person is currently archived...
                                    if (archivedTargetPersonIds.Contains(personId))
                                    {
                                        // ...then we'll just restore them;
                                        GroupMember archivedGroupMember = groupService.GetArchivedGroupMember(sync.Group, personId, sync.GroupTypeRoleId);

                                        if (archivedGroupMember == null)
                                        {
                                            // shouldn't happen, but just in case
                                            continue;
                                        }

                                        archivedGroupMember.GroupMemberStatus = GroupMemberStatus.Active;
                                        if (archivedGroupMember.IsValidGroupMember(groupMemberContext))
                                        {
                                            addedCount++;
                                            groupMemberService.Restore(archivedGroupMember);
                                            groupMemberContext.SaveChanges();
                                        }
                                        else
                                        {
                                            notAddedCount++;
                                            // Validation errors will get added to the ValidationResults collection. Add those results to the log and then move on to the next person.
                                            var ex = new GroupMemberValidationException(string.Join(",", archivedGroupMember.ValidationResults.Select(r => r.ErrorMessage).ToArray()));
                                            ExceptionLogService.LogException(ex);
                                            continue;
                                        }
                                    }
                                    else
                                    {
                                        // ...otherwise we will add a new person to the group with the role specified in the sync.
                                        var newGroupMember = new GroupMember {
                                            Id = 0
                                        };
                                        newGroupMember.PersonId          = personId;
                                        newGroupMember.GroupId           = sync.GroupId;
                                        newGroupMember.GroupMemberStatus = GroupMemberStatus.Active;
                                        newGroupMember.GroupRoleId       = sync.GroupTypeRoleId;

                                        if (newGroupMember.IsValidGroupMember(groupMemberContext))
                                        {
                                            addedCount++;
                                            groupMemberService.Add(newGroupMember);
                                            groupMemberContext.SaveChanges();
                                        }
                                        else
                                        {
                                            notAddedCount++;
                                            // Validation errors will get added to the ValidationResults collection. Add those results to the log and then move on to the next person.
                                            var ex = new GroupMemberValidationException(string.Join(",", newGroupMember.ValidationResults.Select(r => r.ErrorMessage).ToArray()));
                                            ExceptionLogService.LogException(ex);
                                            continue;
                                        }
                                    }

                                    // If the Group has a welcome email, and person has an email address, send them the welcome email and possibly create a login
                                    if (sync.WelcomeSystemCommunication != null)
                                    {
                                        var person = new PersonService(groupMemberContext).Get(personId);
                                        if (person.CanReceiveEmail(false))
                                        {
                                            // If the group is configured to add a user account for anyone added to the group, and person does not yet have an
                                            // account, add one for them.
                                            string newPassword = string.Empty;
                                            bool   createLogin = sync.AddUserAccountsDuringSync;

                                            // Only create a login if requested, no logins exist and we have enough information to generate a user name.
                                            if (createLogin && !person.Users.Any() && !string.IsNullOrWhiteSpace(person.NickName) && !string.IsNullOrWhiteSpace(person.LastName))
                                            {
                                                newPassword = System.Web.Security.Membership.GeneratePassword(9, 1);
                                                string username = Rock.Security.Authentication.Database.GenerateUsername(person.NickName, person.LastName);

                                                UserLogin login = UserLoginService.Create(
                                                    groupMemberContext,
                                                    person,
                                                    AuthenticationServiceType.Internal,
                                                    EntityTypeCache.Get(Rock.SystemGuid.EntityType.AUTHENTICATION_DATABASE.AsGuid()).Id,
                                                    username,
                                                    newPassword,
                                                    true,
                                                    requirePasswordReset);
                                            }

                                            // Send the welcome email
                                            var mergeFields = new Dictionary <string, object>();
                                            mergeFields.Add("Group", sync.Group);
                                            mergeFields.Add("Person", person);
                                            mergeFields.Add("NewPassword", newPassword);
                                            mergeFields.Add("CreateLogin", createLogin);
                                            var emailMessage = new RockEmailMessage(sync.WelcomeSystemCommunication);
                                            emailMessage.AddRecipient(new RockEmailMessageRecipient(person, mergeFields));
                                            var emailErrors = new List <string>();
                                            emailMessage.Send(out emailErrors);
                                            errors.AddRange(emailErrors);
                                        }
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                ExceptionLogService.LogException(ex);
                                continue;
                            }

                            hasSyncChanged = true;
                        }

                        // Increment Groups Changed Counter (if people were deleted or added to the group)
                        if (hasSyncChanged)
                        {
                            groupsChanged++;
                        }

                        // Increment the Groups Synced Counter
                        groupsSynced++;
                    }

                    // Update last refresh datetime in different context to avoid side-effects.
                    using (var rockContext = new RockContext())
                    {
                        var sync = new GroupSyncService(rockContext)
                                   .Queryable()
                                   .FirstOrDefault(s => s.Id == syncId);

                        sync.LastRefreshDateTime = RockDateTime.Now;

                        rockContext.SaveChanges();
                    }
                }

                // Format the result message
                var resultMessage = string.Empty;
                if (groupsSynced == 0)
                {
                    resultMessage = "No groups to sync";
                }
                else if (groupsSynced == 1)
                {
                    resultMessage = "1 group was synced";
                }
                else
                {
                    resultMessage = string.Format("{0} groups were synced", groupsSynced);
                }

                resultMessage += string.Format(" and {0} groups were changed", groupsChanged);

                if (errors.Any())
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine();
                    sb.Append("Errors: ");
                    errors.ForEach(e => { sb.AppendLine(); sb.Append(e); });
                    string errorMessage = sb.ToString();
                    resultMessage += errorMessage;
                    throw new Exception(errorMessage);
                }

                context.Result = resultMessage;
            }
            catch (System.Exception ex)
            {
                HttpContext context2 = HttpContext.Current;
                ExceptionLogService.LogException(ex, context2);
                throw;
            }
        }