protected virtual IEnumerable items()
        {
            CRPurgeFilter filter = Filter.Current;

            if (filter == null)
            {
                return(new Contact[0]);
            }

            if (setup.Current != null)
            {
                bool PurgeAgeOfNotConvertedLeadsWrongValue = setup.Current.PurgeAgeOfNotConvertedLeads == null || setup.Current.PurgeAgeOfNotConvertedLeads <= 0;
                bool PurgePeriodWithoutActivityWrongValue  = setup.Current.PurgePeriodWithoutActivity == null || setup.Current.PurgePeriodWithoutActivity <= 0;

                if (PurgeAgeOfNotConvertedLeadsWrongValue || PurgePeriodWithoutActivityWrongValue)
                {
                    string message = String.Empty;

                    if (PurgeAgeOfNotConvertedLeadsWrongValue)
                    {
                        message += "'" + PXUIFieldAttribute.GetDisplayName <CRSetup.purgeAgeOfNotConvertedLeads>(setup.Cache) + "' ";
                    }
                    if (PurgePeriodWithoutActivityWrongValue)
                    {
                        message += "'" + PXUIFieldAttribute.GetDisplayName <CRSetup.purgePeriodWithoutActivity>(setup.Cache) + "' ";
                    }

                    throw new PXSetupNotEnteredException(Messages.CRSetupFieldsAreEmpty, typeof(CRSetup), typeof(CRSetup).Name, message);
                }
            }

            return(PXSelectJoin <Contact,
                                 LeftJoin <BAccount, On <BAccount.bAccountID, Equal <Contact.bAccountID> > >,
                                 Where <Contact.contactType, Equal <ContactTypesAttribute.lead>, Or <Contact.contactType, Equal <ContactTypesAttribute.person> > > > .Select(this)
                   .Where(res =>
            {
                Contact contact = res;
                return (                                 //Purge Not Converted Leads that are older than
                    filter.PurgeOldNotConvertedLeads == true && filter.PurgeAgeOfNotConvertedLeads != null &&
                    contact.CreatedDateTime != null &&
                    contact.ContactType == ContactTypesAttribute.Lead &&
                    contact.Status != LeadStatusesAttribute.Closed &&
                    ((DateTime)contact.CreatedDateTime).AddMonths((int)filter.PurgeAgeOfNotConvertedLeads) < Accessinfo.BusinessDate
                    )
                ||
                (                                        //Purge Not Active Contacts with no activities for more than
                    filter.PurgeOldInertContacts == true && filter.PurgePeriodWithoutActivity != null &&
                    contact.LastActivity != null &&
                    contact.ContactType == ContactTypesAttribute.Person
                    &&
                    ((DateTime)contact.LastActivity).AddMonths((int)filter.PurgePeriodWithoutActivity) <
                    Accessinfo.BusinessDate &&
                    contact.IsActive != true
                )
                ||
                //Purge Closed Contacts
                (filter.PurgeClosedContacts == true && (contact.Status == LeadStatusesAttribute.Closed ||
                                                        (contact.IsActive != true && contact.DuplicateStatus == DuplicateStatusAttribute.Duplicated)));
            }));
        }
        protected virtual void CRPurgeFilter_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
        {
            CRPurgeFilter filter = (CRPurgeFilter)e.Row;

            if (filter == null)
            {
                return;
            }

            PXUIFieldAttribute.SetEnabled <CRPurgeFilter.purgeAgeOfNotConvertedLeads>(sender, filter, filter.PurgeOldNotConvertedLeads == true);
            PXUIFieldAttribute.SetEnabled <CRPurgeFilter.purgePeriodWithoutActivity>(sender, filter, filter.PurgeOldInertContacts == true);

            Items.SetProcessDelegate(delegate(PurgeContactsProcess graph, Contact contact)
            {
                BAccount bacct = PXSelect <BAccount, Where <BAccount.bAccountID, Equal <Current <Contact.bAccountID> > > > .SelectSingleBound(graph, new object[] { contact });
                if (bacct == null || bacct.DefAddressID != contact.DefAddressID)
                {
                    graph.Address.Delete(new Address {
                        AddressID = contact.DefAddressID
                    });
                }

                foreach (CRPMSMEmail activity in graph.Activities.Select(new object[] { contact.ContactID }))
                {
                    if (activity.IsBillable == true || !string.IsNullOrEmpty(activity.TimeCardCD) ||
                        activity.MPStatus == MailStatusListAttribute.InProcess)
                    {
                        throw new PXException(Messages.CannotDeleteActivity);
                    }
                    graph.Activities.Delete(activity);
                }

                // Relations, Marketing List members, Campaign members and Notifications delete by PXParentAttribute

                graph.Items.Delete(contact);
                graph.Actions.PressSave();
            }
                                     );
        }