/// <summary> /// Handles the Click event of the btnGive 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 btnGive_Click(object sender, EventArgs e) { Person person = FindPerson(); using (new UnitOfWorkScope()) { RockTransactionScope.WrapTransaction(() => { var groupLocationService = new GroupLocationService(); var groupMemberService = new GroupMemberService(); var phoneService = new PhoneNumberService(); var locationService = new LocationService(); var groupService = new GroupService(); GroupLocation groupLocation; Location homeAddress; Group familyGroup; var homeLocationType = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.LOCATION_TYPE_HOME); var addressList = locationService.Queryable().Where(l => l.Street1 == txtStreet.Text && l.City == txtCity.Text && l.State == ddlState.SelectedValue && l.Zip == txtZip.Text && l.LocationTypeValueId == homeLocationType.Id).ToList(); if (!addressList.Any()) { homeAddress = new Location(); locationService.Add(homeAddress, person.Id); } else { homeAddress = addressList.FirstOrDefault(); } homeAddress.Street1 = txtStreet.Text ?? homeAddress.Street1; homeAddress.City = txtCity.Text ?? homeAddress.City; homeAddress.State = ddlState.SelectedValue ?? homeAddress.State; homeAddress.Zip = txtZip.Text ?? homeAddress.Zip; homeAddress.IsActive = true; homeAddress.IsLocation = true; homeAddress.Country = "US"; homeAddress.LocationTypeValueId = homeLocationType.Id; locationService.Save(homeAddress, person.Id); GroupType familyGroupType = new GroupTypeService().Get(new Guid(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY)); var familyGroupList = groupMemberService.Queryable().Where(g => g.PersonId == person.Id && g.Group.GroupType.Guid == familyGroupType.Guid).Select(g => g.Group).ToList(); if (!familyGroupList.Any()) { familyGroup = new Group(); familyGroup.IsActive = true; familyGroup.IsSystem = false; familyGroup.IsSecurityRole = false; familyGroup.Name = "The " + txtLastName.Text + " Family"; familyGroup.GroupTypeId = familyGroupType.Id; groupService.Add(familyGroup, person.Id); groupService.Save(familyGroup, person.Id); var familyMember = new GroupMember(); familyMember.IsSystem = false; familyMember.GroupId = familyGroup.Id; familyMember.PersonId = person.Id; familyMember.GroupRoleId = new GroupRoleService().Get(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT)).Id; groupMemberService.Add(familyMember, person.Id); groupMemberService.Save(familyMember, person.Id); } else { familyGroup = familyGroupList.FirstOrDefault(); } var groupLocationList = groupLocationService.Queryable().Where(g => g.GroupLocationTypeValueId == familyGroupType.Id && g.GroupId == familyGroup.Id).ToList(); if (!groupLocationList.Any()) { groupLocation = new GroupLocation(); groupLocation.GroupId = familyGroup.Id; groupLocation.LocationId = homeAddress.Id; groupLocation.IsMailing = true; groupLocation.IsLocation = true; groupLocation.GroupLocationTypeValueId = homeLocationType.Id; groupLocationService.Add(groupLocation, person.Id); groupLocationService.Save(groupLocation, person.Id); } else { groupLocation = groupLocationList.FirstOrDefault(); } groupLocation.LocationId = homeAddress.Id; groupLocationService.Save(groupLocation, person.Id); var homePhoneType = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME); string phoneNumeric = txtPhone.Text.AsNumeric(); if (!phoneService.Queryable().Where(n => n.PersonId == person.Id && n.NumberTypeValueId == homePhoneType.Id && n.Number == phoneNumeric).Any()) { var homePhone = new PhoneNumber(); homePhone.Number = phoneNumeric; homePhone.PersonId = person.Id; homePhone.IsSystem = false; homePhone.IsMessagingEnabled = false; homePhone.IsUnlisted = false; homePhone.NumberTypeValueId = homePhoneType.Id; phoneService.Add(homePhone, person.Id); phoneService.Save(homePhone, person.Id); } }); } var amountList = (Dictionary <FinancialAccount, Decimal>)Session["CachedAmounts"]; var profileId = (int)Session["CachedProfileId"]; Location giftLocation = new Location(); var configValues = (Dictionary <string, object>)Session["CachedMergeFields"]; configValues.Add("Date", DateTimeOffset.Now.ToString("MM/dd/yyyy hh:mm tt")); var receiptTemplate = GetAttributeValue("ReceiptMessage"); lReceipt.Text = receiptTemplate.ResolveMergeFields(configValues); var summaryTemplate = GetAttributeValue("SummaryMessage"); string summaryMessage = summaryTemplate.ResolveMergeFields(configValues); // #TODO test card through gateway if (btnFrequency.SelectedIndex > -1 && btnFrequency.SelectedValueAsInt() > 0) { using (new UnitOfWorkScope()) { RockTransactionScope.WrapTransaction(() => { var scheduledTransactionDetailService = new FinancialScheduledTransactionDetailService(); var scheduledTransactionService = new FinancialScheduledTransactionService(); FinancialScheduledTransaction scheduledTransaction; var detailList = amountList.ToList(); if (profileId > 0) { scheduledTransaction = scheduledTransactionService.Get(profileId); } else { scheduledTransaction = new FinancialScheduledTransaction(); scheduledTransactionService.Add(scheduledTransaction, person.Id); } DateTime startDate = (DateTime)dtpStartDate.SelectedDate; if (startDate != null) { scheduledTransaction.StartDate = startDate; } scheduledTransaction.TransactionFrequencyValueId = (int)btnFrequency.SelectedValueAsInt(); scheduledTransaction.AuthorizedPersonId = person.Id; scheduledTransaction.IsActive = true; if (!string.IsNullOrEmpty(txtCreditCard.Text)) { scheduledTransaction.CardReminderDate = mypExpiration.SelectedDate; } if (chkLimitGifts.Checked && !string.IsNullOrWhiteSpace(txtLimitNumber.Text)) { scheduledTransaction.NumberOfPayments = Convert.ToInt32(txtLimitNumber.Text); } foreach (var detail in amountList.ToList()) { var scheduledTransactionDetail = new FinancialScheduledTransactionDetail(); scheduledTransactionDetail.AccountId = detail.Key.Id; scheduledTransactionDetail.Amount = detail.Value; scheduledTransactionDetail.ScheduledTransactionId = scheduledTransaction.Id; scheduledTransactionDetailService.Add(scheduledTransactionDetail, person.Id); scheduledTransactionDetailService.Save(scheduledTransactionDetail, person.Id); } // implement gateway charge() scheduledTransactionService.Save(scheduledTransaction, person.Id); }); } } else { using (new UnitOfWorkScope()) { RockTransactionScope.WrapTransaction(() => { var transactionService = new FinancialTransactionService(); var tdService = new FinancialTransactionDetailService(); var transaction = new FinancialTransaction(); var detailList = amountList.ToList(); transaction.Summary = summaryMessage; transaction.Amount = detailList.Sum(d => d.Value); transaction.TransactionTypeValueId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION).Id; transaction.TransactionDateTime = DateTimeOffset.Now.DateTime; transaction.AuthorizedPersonId = person.Id; transactionService.Add(transaction, person.Id); foreach (var detail in detailList) { var td = new FinancialTransactionDetail(); td.TransactionId = transaction.Id; td.AccountId = detail.Key.Id; td.Amount = detail.Value; td.TransactionId = transaction.Id; tdService.Add(td, person.Id); tdService.Save(td, person.Id); } // #TODO implement gateway.charge() transactionService.Save(transaction, person.Id); }); } } Session["CachedMergeFields"] = configValues; pnlConfirm.Visible = false; pnlComplete.Visible = true; pnlContribution.Update(); }
/// <summary> /// Gets the person. /// </summary> /// <param name="paymentInfo">The paymentInfo object to use as the base.</param> /// <param name="create">if set to <c>true</c> [create].</param> /// <returns></returns> private Person GetPerson(PaymentInfo paymentInfo, bool create) { Person person = null; var rockContext = new RockContext(); var personService = new PersonService(rockContext); Group familyGroup = null; int personId = ViewState["PersonId"] as int? ?? 0; if (personId == 0 && _targetPerson != null) { personId = _targetPerson.Id; } if (personId != 0) { person = personService.Get(personId); } if (create) { if (person == null) { // Check to see if there's only one person with same email, first name, and last name if (!string.IsNullOrWhiteSpace(paymentInfo.Email) && !string.IsNullOrWhiteSpace(paymentInfo.FirstName) && !string.IsNullOrWhiteSpace(paymentInfo.LastName)) { // Same logic as CreatePledge.ascx.cs var personMatches = personService.GetByMatch(paymentInfo.FirstName, paymentInfo.LastName, paymentInfo.Email); if (personMatches.Count() == 1) { person = personMatches.FirstOrDefault(); } else { person = null; } } if (person == null) { DefinedValueCache dvcConnectionStatus = DefinedValueCache.Read(GetAttributeValue("ConnectionStatus").AsGuid()); DefinedValueCache dvcRecordStatus = DefinedValueCache.Read(GetAttributeValue("RecordStatus").AsGuid()); // Create Person person = new Person(); person.FirstName = paymentInfo.FirstName; person.LastName = paymentInfo.LastName; person.IsEmailActive = true; person.EmailPreference = EmailPreference.EmailAllowed; person.RecordTypeValueId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()).Id; if (dvcConnectionStatus != null) { person.ConnectionStatusValueId = dvcConnectionStatus.Id; } if (dvcRecordStatus != null) { person.RecordStatusValueId = dvcRecordStatus.Id; } // Create Person/Family familyGroup = PersonService.SaveNewPerson(person, rockContext, null, false); } ViewState["PersonId"] = person != null ? person.Id : 0; } } if (create && person != null) // person should never be null at this point { person.Email = paymentInfo.Email; if (GetAttributeValue("DisplayPhone").AsBooleanOrNull() ?? false && !String.IsNullOrEmpty(paymentInfo.Phone)) { var numberTypeId = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME)).Id; var phone = person.PhoneNumbers.FirstOrDefault(p => p.NumberTypeValueId == numberTypeId); if (phone == null) { phone = new PhoneNumber(); person.PhoneNumbers.Add(phone); phone.NumberTypeValueId = numberTypeId; } phone.Number = paymentInfo.Phone; } if (familyGroup == null) { var groupLocationService = new GroupLocationService(rockContext); if (GroupLocationId.HasValue) { familyGroup = groupLocationService.Queryable() .Where(gl => gl.Id == GroupLocationId.Value) .Select(gl => gl.Group) .FirstOrDefault(); } else { familyGroup = personService.GetFamilies(person.Id).FirstOrDefault(); } } rockContext.SaveChanges(); if (familyGroup != null) { GroupService.AddNewGroupAddress( rockContext, familyGroup, GetAttributeValue("AddressType"), paymentInfo.Street1, paymentInfo.Street2, paymentInfo.City, paymentInfo.State, paymentInfo.PostalCode, paymentInfo.Country, true); } } return(person); }
/// <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) { var rockContext = new RockContext(); rockContext.WrapTransaction(() => { var personService = new PersonService(rockContext); var person = personService.Get(CurrentPersonId ?? 0); if (person != null) { int?orphanedPhotoId = null; if (person.PhotoId != imgPhoto.BinaryFileId) { orphanedPhotoId = person.PhotoId; person.PhotoId = imgPhoto.BinaryFileId; } person.TitleValueId = dvpTitle.SelectedValueAsInt();; person.FirstName = tbFirstName.Text; person.NickName = tbNickName.Text; person.LastName = tbLastName.Text; person.SuffixValueId = dvpSuffix.SelectedValueAsInt();; var birthMonth = person.BirthMonth; var birthDay = person.BirthDay; var birthYear = person.BirthYear; var birthday = bpBirthDay.SelectedDate; if (birthday.HasValue) { // If setting a future birthdate, subtract a century until birthdate is not greater than today. var today = RockDateTime.Today; while (birthday.Value.CompareTo(today) > 0) { birthday = birthday.Value.AddYears(-100); } person.BirthMonth = birthday.Value.Month; person.BirthDay = birthday.Value.Day; if (birthday.Value.Year != DateTime.MinValue.Year) { person.BirthYear = birthday.Value.Year; } else { person.BirthYear = null; } } else { person.SetBirthDate(null); } person.Gender = rblGender.SelectedValue.ConvertToEnum <Gender>();; var phoneNumberTypeIds = new List <int>(); bool smsSelected = false; foreach (RepeaterItem item in rContactInfo.Items) { HiddenField hfPhoneType = item.FindControl("hfPhoneType") as HiddenField; PhoneNumberBox pnbPhone = item.FindControl("pnbPhone") as PhoneNumberBox; CheckBox cbUnlisted = item.FindControl("cbUnlisted") as CheckBox; CheckBox cbSms = item.FindControl("cbSms") as CheckBox; if (hfPhoneType != null && pnbPhone != null && cbSms != null && cbUnlisted != null) { if (!string.IsNullOrWhiteSpace(PhoneNumber.CleanNumber(pnbPhone.Number))) { int phoneNumberTypeId; if (int.TryParse(hfPhoneType.Value, out phoneNumberTypeId)) { var phoneNumber = person.PhoneNumbers.FirstOrDefault(n => n.NumberTypeValueId == phoneNumberTypeId); if (phoneNumber == null) { phoneNumber = new PhoneNumber { NumberTypeValueId = phoneNumberTypeId }; person.PhoneNumbers.Add(phoneNumber); } phoneNumber.CountryCode = PhoneNumber.CleanNumber(pnbPhone.CountryCode); phoneNumber.Number = PhoneNumber.CleanNumber(pnbPhone.Number); // Only allow one number to have SMS selected if (smsSelected) { phoneNumber.IsMessagingEnabled = false; } else { phoneNumber.IsMessagingEnabled = cbSms.Checked; smsSelected = cbSms.Checked; } phoneNumber.IsUnlisted = cbUnlisted.Checked; phoneNumberTypeIds.Add(phoneNumberTypeId); } } } } // Remove any blank numbers var phoneNumberService = new PhoneNumberService(rockContext); foreach (var phoneNumber in person.PhoneNumbers .Where(n => n.NumberTypeValueId.HasValue && !phoneNumberTypeIds.Contains(n.NumberTypeValueId.Value)) .ToList()) { person.PhoneNumbers.Remove(phoneNumber); phoneNumberService.Delete(phoneNumber); } person.Email = tbEmail.Text.Trim(); person.EmailPreference = rblEmailPreference.SelectedValue.ConvertToEnum <EmailPreference>();; if (person.IsValid) { if (rockContext.SaveChanges() > 0) { if (orphanedPhotoId.HasValue) { BinaryFileService binaryFileService = new BinaryFileService(rockContext); var binaryFile = binaryFileService.Get(orphanedPhotoId.Value); if (binaryFile != null) { // marked the old images as IsTemporary so they will get cleaned up later binaryFile.IsTemporary = true; rockContext.SaveChanges(); } } // if they used the ImageEditor, and cropped it, the uncropped file is still in BinaryFile. So clean it up if (imgPhoto.CropBinaryFileId.HasValue) { if (imgPhoto.CropBinaryFileId != person.PhotoId) { BinaryFileService binaryFileService = new BinaryFileService(rockContext); var binaryFile = binaryFileService.Get(imgPhoto.CropBinaryFileId.Value); if (binaryFile != null && binaryFile.IsTemporary) { string errorMessage; if (binaryFileService.CanDelete(binaryFile, out errorMessage)) { binaryFileService.Delete(binaryFile); rockContext.SaveChanges(); } } } } } // save address if (pnlAddress.Visible) { Guid?familyGroupTypeGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuidOrNull(); if (familyGroupTypeGuid.HasValue) { var familyGroup = new GroupService(rockContext).Queryable() .Where(f => f.GroupType.Guid == familyGroupTypeGuid.Value && f.Members.Any(m => m.PersonId == person.Id)) .FirstOrDefault(); if (familyGroup != null) { Guid?addressTypeGuid = GetAttributeValue("LocationType").AsGuidOrNull(); if (addressTypeGuid.HasValue) { var groupLocationService = new GroupLocationService(rockContext); var dvHomeAddressType = DefinedValueCache.Get(addressTypeGuid.Value); var familyAddress = groupLocationService.Queryable().Where(l => l.GroupId == familyGroup.Id && l.GroupLocationTypeValueId == dvHomeAddressType.Id).FirstOrDefault(); if (familyAddress != null && string.IsNullOrWhiteSpace(acAddress.Street1)) { // delete the current address groupLocationService.Delete(familyAddress); rockContext.SaveChanges(); } else { if (!string.IsNullOrWhiteSpace(acAddress.Street1)) { if (familyAddress == null) { familyAddress = new GroupLocation(); groupLocationService.Add(familyAddress); familyAddress.GroupLocationTypeValueId = dvHomeAddressType.Id; familyAddress.GroupId = familyGroup.Id; familyAddress.IsMailingLocation = true; familyAddress.IsMappedLocation = true; } else if (hfStreet1.Value != string.Empty) { // user clicked move so create a previous address var previousAddress = new GroupLocation(); groupLocationService.Add(previousAddress); var previousAddressValue = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_PREVIOUS.AsGuid()); if (previousAddressValue != null) { previousAddress.GroupLocationTypeValueId = previousAddressValue.Id; previousAddress.GroupId = familyGroup.Id; Location previousAddressLocation = new Location(); previousAddressLocation.Street1 = hfStreet1.Value; previousAddressLocation.Street2 = hfStreet2.Value; previousAddressLocation.City = hfCity.Value; previousAddressLocation.State = hfState.Value; previousAddressLocation.PostalCode = hfPostalCode.Value; previousAddressLocation.Country = hfCountry.Value; previousAddress.Location = previousAddressLocation; } } familyAddress.IsMailingLocation = cbIsMailingAddress.Checked; familyAddress.IsMappedLocation = cbIsPhysicalAddress.Checked; var loc = new Location(); acAddress.GetValues(loc); familyAddress.Location = new LocationService(rockContext).Get( loc.Street1, loc.Street2, loc.City, loc.State, loc.PostalCode, loc.Country, familyGroup, true); rockContext.SaveChanges(); } } } } } } NavigateToParentPage(); } } }); }
/// <summary> /// Binds the grid. /// </summary> protected void BindGrid() { AddScheduleColumns(); var rockContext = new RockContext(); var groupLocationService = new GroupLocationService(rockContext); var groupTypeService = new GroupTypeService(rockContext); var groupService = new GroupService(rockContext); var groupLocationQry = groupLocationService.Queryable(); var templateGroupPaths = new Dictionary <int, List <GroupTypePath> >(); var currentAndDescendantGroupTypeIds = new List <int>(); foreach (var groupType in groupTypeService.Queryable().Where(a => this.LocalDeviceConfig.CurrentGroupTypeIds.Contains(a.Id))) { foreach (var parentGroupType in groupType.ParentGroupTypes) { if (!templateGroupPaths.ContainsKey(parentGroupType.Id)) { templateGroupPaths.Add(parentGroupType.Id, groupTypeService.GetAllAssociatedDescendentsPath(parentGroupType.Id).ToList()); } } currentAndDescendantGroupTypeIds.Add(groupType.Id); currentAndDescendantGroupTypeIds.AddRange(groupTypeService.GetAllAssociatedDescendents(groupType.Id).Select(a => a.Id).ToList()); } var groupPaths = new List <GroupTypePath>(); foreach (var path in templateGroupPaths) { groupPaths.AddRange(path.Value); } groupLocationQry = groupLocationQry.Where(a => currentAndDescendantGroupTypeIds.Contains(a.Group.GroupTypeId)); groupLocationQry = groupLocationQry.OrderBy(a => a.Group.Name).ThenBy(a => a.Location.Name); List <int> currentDeviceLocationIdList = this.GetGroupTypesLocations(rockContext).Select(a => a.Id).Distinct().ToList(); var qryList = groupLocationQry .Where(a => currentDeviceLocationIdList.Contains(a.LocationId)) .Select(a => new { GroupLocationId = a.Id, a.Location, GroupId = a.GroupId, GroupName = a.Group.Name, ScheduleIdList = a.Schedules.Select(s => s.Id), GroupTypeId = a.Group.GroupTypeId }).ToList(); var locationService = new LocationService(rockContext); // put stuff in a datatable so we can dynamically have columns for each Schedule DataTable dataTable = new DataTable(); dataTable.Columns.Add("GroupLocationId"); dataTable.Columns.Add("GroupId"); dataTable.Columns.Add("GroupName"); dataTable.Columns.Add("GroupPath"); dataTable.Columns.Add("LocationName"); dataTable.Columns.Add("LocationPath"); foreach (var field in gGroupLocationSchedule.Columns.OfType <CheckBoxEditableField>()) { dataTable.Columns.Add(field.DataField, typeof(bool)); } var locationPaths = new Dictionary <int, string>(); foreach (var row in qryList) { DataRow dataRow = dataTable.NewRow(); dataRow["GroupLocationId"] = row.GroupLocationId; dataRow["GroupName"] = groupService.GroupAncestorPathName(row.GroupId); dataRow["GroupPath"] = groupPaths.Where(gt => gt.GroupTypeId == row.GroupTypeId).Select(gt => gt.Path).FirstOrDefault(); dataRow["LocationName"] = row.Location.Name; if (row.Location.ParentLocationId.HasValue) { int locationId = row.Location.ParentLocationId.Value; if (!locationPaths.ContainsKey(locationId)) { var locationNames = new List <string>(); var parentLocation = locationService.Get(locationId); while (parentLocation != null) { locationNames.Add(parentLocation.Name); parentLocation = parentLocation.ParentLocation; } if (locationNames.Any()) { locationNames.Reverse(); locationPaths.Add(locationId, locationNames.AsDelimited(" > ")); } else { locationPaths.Add(locationId, string.Empty); } } dataRow["LocationPath"] = locationPaths[locationId]; } foreach (var field in gGroupLocationSchedule.Columns.OfType <CheckBoxEditableField>()) { int scheduleId = int.Parse(field.DataField.Replace("scheduleField_", string.Empty)); dataRow[field.DataField] = row.ScheduleIdList.Any(a => a == scheduleId); } dataTable.Rows.Add(dataRow); } gGroupLocationSchedule.EntityTypeId = EntityTypeCache.Get <GroupLocation>().Id; gGroupLocationSchedule.DataSource = dataTable; gGroupLocationSchedule.DataBind(); }
/// <summary> /// Binds the grid. /// </summary> private void BindGrid() { var rockContext = new RockContext(); var groupMemberService = new GroupMemberService(rockContext); var groupService = new GroupService(rockContext); var groupTypeService = new GroupTypeService(rockContext); var attributeService = new AttributeService(rockContext); var attributeValueService = new AttributeValueService(rockContext); var personService = new PersonService(rockContext); var personAliasService = new PersonAliasService(rockContext); var entityTypeService = new EntityTypeService(rockContext); var registrationRegistrantService = new RegistrationRegistrantService(rockContext); var eiogmService = new EventItemOccurrenceGroupMapService(rockContext); var groupLocationService = new GroupLocationService(rockContext); var locationService = new LocationService(rockContext); var signatureDocumentServce = new SignatureDocumentService(rockContext); var phoneNumberService = new PhoneNumberService(rockContext); int[] signatureDocumentIds = { }; if (!string.IsNullOrWhiteSpace(GetAttributeValue("SignatureDocumentTemplates"))) { signatureDocumentIds = Array.ConvertAll(GetAttributeValue("SignatureDocumentTemplates").Split(','), int.Parse); } int[] registrationInstanceIds = { }; if (!string.IsNullOrWhiteSpace(GetAttributeValue("RegistrationInstances"))) { registrationInstanceIds = Array.ConvertAll(GetAttributeValue("RegistrationInstances").Split(','), int.Parse); } Guid bbGroup = GetAttributeValue("Group").AsGuid(); var group = new GroupService(rockContext).Get(bbGroup); Guid hsmGroupTypeGuid = GetAttributeValue("MSMGroupType").AsGuid(); int? hsmGroupTypeId = groupTypeService.Queryable().Where(gt => gt.Guid == hsmGroupTypeGuid).Select(gt => gt.Id).FirstOrDefault(); int entityTypeId = entityTypeService.Queryable().Where(et => et.Name == typeof(Rock.Model.Group).FullName).FirstOrDefault().Id; var registrationTemplateIds = eiogmService.Queryable().Where(r => r.GroupId == group.Id).Select(m => m.RegistrationInstance.RegistrationTemplateId.ToString()).ToList(); hlGroup.NavigateUrl = "/group/" + group.Id; var attributeIds = attributeService.Queryable() .Where(a => (a.EntityTypeQualifierColumn == "GroupId" && a.EntityTypeQualifierValue == group.Id.ToString()) || (a.EntityTypeQualifierColumn == "GroupTypeId" && a.EntityTypeQualifierValue == group.GroupTypeId.ToString()) || (a.EntityTypeQualifierColumn == "RegistrationTemplateId" && registrationTemplateIds.Contains(a.EntityTypeQualifierValue))) .Select(a => a.Id).ToList(); var gmTmpqry = groupMemberService.Queryable() .Where(gm => (gm.GroupId == group.Id)); var qry = gmTmpqry .Join(personAliasService.Queryable(), obj => obj.PersonId, pa => pa.PersonId, (obj, pa) => new { GroupMember = obj, PersonAlias = pa } ) .Join(registrationRegistrantService.Queryable(), obj => obj.PersonAlias.Id, rr => rr.PersonAliasId, (obj, rr) => new { GroupMember = obj.GroupMember, Person = obj.GroupMember.Person, RegistrationRegistrant = rr }) .GroupJoin(attributeValueService.Queryable(), obj => new { PersonId = (int?)obj.Person.Id, AttributeId = 739 }, av => new { PersonId = av.EntityId, av.AttributeId }, (obj, av) => new { GroupMember = obj.GroupMember, Person = obj.Person, RegistrationRegistrant = obj.RegistrationRegistrant, School = av.Select(s => s.Value).FirstOrDefault() }) .GroupJoin(attributeValueService.Queryable(), obj => obj.GroupMember.Id, av => av.EntityId.Value, (obj, avs) => new { GroupMember = obj.GroupMember, Person = obj.Person, RegistrationRegistrant = obj.RegistrationRegistrant, GroupMemberAttributeValues = avs.Where(av => attributeIds.Contains(av.AttributeId)), School = obj.School /*, Location = obj.Location */ }) .GroupJoin(attributeValueService.Queryable(), obj => obj.RegistrationRegistrant.Id, av => av.EntityId.Value, (obj, avs) => new { GroupMember = obj.GroupMember, Person = obj.Person, RegistrationRegistrant = obj.RegistrationRegistrant, GroupMemberAttributeValues = obj.GroupMemberAttributeValues, RegistrationAttributeValues = avs.Where(av => attributeIds.Contains(av.AttributeId)), School = obj.School /*, Location = obj.Location */ }) .Where(obj => registrationInstanceIds.Contains(obj.RegistrationRegistrant.Registration.RegistrationInstanceId)); var qry2 = gmTmpqry .GroupJoin( groupMemberService.Queryable() .Join(groupService.Queryable(), gm => new { Id = gm.GroupId, GroupTypeId = 10 }, g => new { g.Id, g.GroupTypeId }, (gm, g) => new { GroupMember = gm, Group = g }) .Join(groupLocationService.Queryable(), obj => new { GroupId = obj.Group.Id, GroupLocationTypeValueId = (int?)19 }, gl => new { gl.GroupId, gl.GroupLocationTypeValueId }, (g, gl) => new { GroupMember = g.GroupMember, GroupLocation = gl }) .Join(locationService.Queryable(), obj => obj.GroupLocation.LocationId, l => l.Id, (obj, l) => new { GroupMember = obj.GroupMember, Location = l }), gm => gm.PersonId, glgm => glgm.GroupMember.PersonId, (obj, l) => new { GroupMember = obj, Location = l.Select(loc => loc.Location).FirstOrDefault() } ) .GroupJoin(signatureDocumentServce.Queryable() .Join(personAliasService.Queryable(), sd => sd.AppliesToPersonAliasId, pa => pa.Id, (sd, pa) => new { SignatureDocument = sd, Alias = pa }), obj => obj.GroupMember.PersonId, sd => sd.Alias.PersonId, (obj, sds) => new { GroupMember = obj.GroupMember, Location = obj.Location, SignatureDocuments = sds }) .GroupJoin(phoneNumberService.Queryable(), obj => obj.GroupMember.PersonId, p => p.PersonId, (obj, pn) => new { GroupMember = obj.GroupMember, Location = obj.Location, SignatureDocuments = obj.SignatureDocuments, PhoneNumbers = pn }); if (!String.IsNullOrWhiteSpace(GetUserPreference(string.Format("{0}PersonName", keyPrefix)))) { string personName = GetUserPreference(string.Format("{0}PersonName", keyPrefix)).ToLower(); qry = qry.ToList().Where(q => q.GroupMember.Person.FullName.ToLower().Contains(personName)).AsQueryable(); } decimal?lowerVal = GetUserPreference(string.Format("{0}BalanceOwedLower", keyPrefix)).AsDecimalOrNull(); decimal?upperVal = GetUserPreference(string.Format("{0}BalanceOwedUpper", keyPrefix)).AsDecimalOrNull(); if (lowerVal != null && upperVal != null) { qry = qry.ToList().Where(q => q.RegistrationRegistrant.Registration.BalanceDue >= lowerVal && q.RegistrationRegistrant.Registration.BalanceDue <= upperVal).AsQueryable(); } else if (lowerVal != null) { qry = qry.ToList().Where(q => q.RegistrationRegistrant.Registration.BalanceDue >= lowerVal).AsQueryable(); } else if (upperVal != null) { qry = qry.ToList().Where(q => q.RegistrationRegistrant.Registration.BalanceDue <= upperVal).AsQueryable(); } else if (!string.IsNullOrEmpty(cmpCampus.SelectedValue)) { CampusCache campus = CampusCache.Read(cmpCampus.SelectedCampusId.Value); qry = qry.ToList().Where(q => q.RegistrationAttributeValues.Where(ra => ra.AttributeKey == "Whichcampus" && ra.Value.Contains(campus.Name.Replace(" ", ""))).Any()).AsQueryable(); } var stopwatch = new Stopwatch(); stopwatch.Start(); var tmp = qry.ToList(); var tmp2 = qry2.ToList(); lStats.Text = "Query Runtime: " + stopwatch.Elapsed; stopwatch.Reset(); stopwatch.Start(); var newQry = tmp.Select(g => new { Id = g.GroupMember.Id, RegisteredBy = new ModelValue <Person>(g.RegistrationRegistrant.Registration.PersonAlias.Person), Registrant = new ModelValue <Person>(g.Person), Age = g.Person.Age, GraduationYear = g.Person.GraduationYear, RegistrationId = g.RegistrationRegistrant.RegistrationId, Group = new ModelValue <Rock.Model.Group>((Rock.Model.Group)g.GroupMember.Group), DOB = g.Person.BirthDate.HasValue ? g.Person.BirthDate.Value.ToShortDateString() : "", Address = new ModelValue <Rock.Model.Location>((Rock.Model.Location)tmp2.Where(gm => gm.GroupMember.Id == g.GroupMember.Id).Select(gm => gm.Location).FirstOrDefault()), Email = g.Person.Email, Gender = g.Person.Gender, // (B & B Registration) GraduationYearProfile = g.Person.GraduationYear, // (Person Profile) HomePhone = tmp2.Where(gm => gm.GroupMember.Id == g.GroupMember.Id).SelectMany(gm => gm.PhoneNumbers).Where(pn => pn.NumberTypeValue.Guid == Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME.AsGuid()).Select(pn => pn.NumberFormatted).FirstOrDefault(), CellPhone = tmp2.Where(gm => gm.GroupMember.Id == g.GroupMember.Id).SelectMany(gm => gm.PhoneNumbers).Where(pn => pn.NumberTypeValue.Guid == Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE.AsGuid()).Select(pn => pn.NumberFormatted).FirstOrDefault(), GroupMemberData = new Func <GroupMemberAttributes>(() => { GroupMemberAttributes gma = new GroupMemberAttributes(g.GroupMember, g.Person, g.GroupMemberAttributeValues); return(gma); })(), RegistrantData = new Func <RegistrantAttributes>(() => { RegistrantAttributes row = new RegistrantAttributes(g.RegistrationRegistrant, g.RegistrationAttributeValues); return(row); })(), School = string.IsNullOrEmpty(g.School)?"":DefinedValueCache.Read(g.School.AsGuid()) != null?DefinedValueCache.Read(g.School.AsGuid()).Value:"", LegalRelease = tmp2.Where(gm => gm.GroupMember.Id == g.GroupMember.Id).SelectMany(gm => gm.SignatureDocuments).OrderByDescending(sd => sd.SignatureDocument.CreatedDateTime).Where(sd => signatureDocumentIds.Contains(sd.SignatureDocument.SignatureDocumentTemplateId)).Select(sd => sd.SignatureDocument.SignatureDocumentTemplate.Name + " (" + sd.SignatureDocument.Status.ToString() + ")").FirstOrDefault(), Departure = g.GroupMemberAttributeValues.Where(av => av.AttributeKey == "Departure").Select(av => av.Value).FirstOrDefault(), Campus = group.Campus, // Role = group.ParentGroup.GroupType.Name.Contains("Serving") || group.Name.ToLower().Contains("leader")? "Leader":"Student", // MSMGroup = String.Join(", ", groupMemberService.Queryable().Where(gm => gm.PersonId == g.GroupMember.PersonId && gm.Group.GroupTypeId == hsmGroupTypeId && gm.GroupMemberStatus == GroupMemberStatus.Active).Select(gm => gm.Group.Name).ToList()), Person = g.Person, AddressStreet = tmp2.Where(gm => gm.GroupMember.Id == g.GroupMember.Id).Select(gm => gm.Location != null?gm.Location.Street1:"").FirstOrDefault(), AddressCityStateZip = tmp2.Where(gm => gm.GroupMember.Id == g.GroupMember.Id).Select(gm => gm.Location != null ? gm.Location.City + ", " + gm.Location.State + " " + gm.Location.PostalCode : "").FirstOrDefault(), RegistrantName = g.Person.FullName, }).OrderBy(w => w.Registrant.Model.LastName).ToList().AsQueryable(); lStats.Text += "<br />Object Build Runtime: " + stopwatch.Elapsed; stopwatch.Stop(); gReport.GetRecipientMergeFields += GReport_GetRecipientMergeFields; var mergeFields = new List <String>(); mergeFields.Add("Id"); mergeFields.Add("RegisteredBy"); mergeFields.Add("Group"); mergeFields.Add("Registrant"); mergeFields.Add("Age"); mergeFields.Add("GraduationYear"); mergeFields.Add("DOB"); mergeFields.Add("Address"); mergeFields.Add("Email"); mergeFields.Add("Gender"); mergeFields.Add("GraduationYearProfile"); mergeFields.Add("HomePhone"); mergeFields.Add("CellPhone"); mergeFields.Add("GroupMemberData"); mergeFields.Add("RegistrantData"); mergeFields.Add("LegalRelease"); mergeFields.Add("Departure"); mergeFields.Add("Campus"); mergeFields.Add("Role"); mergeFields.Add("MSMGroup"); gReport.CommunicateMergeFields = mergeFields; /* * if (!String.IsNullOrWhiteSpace(GetUserPreference(string.Format("{0}POA", keyPrefix)))) * { * string poa = GetUserPreference(string.Format("{0}POA", keyPrefix)); * if (poa == "[Blank]") * { * poa = ""; * } * newQry = newQry.Where(q => q.GroupMemberData.POA == poa); * } */ SortProperty sortProperty = gReport.SortProperty; if (sortProperty != null) { gReport.SetLinqDataSource(newQry.Sort(sortProperty)); } else { gReport.SetLinqDataSource(newQry.OrderBy(p => p.Registrant.Model.LastName)); } gReport.DataBind(); }
/// <summary> /// Raises the <see cref="E:System.Web.UI.Control.Init" /> event. /// </summary> /// <param name="e">An <see cref="T:System.EventArgs" /> object that contains the event data.</param> protected override void OnInit(EventArgs e) { base.OnInit(e); RockPage.AddCSSLink(ResolveRockUrl("~/Styles/fluidbox.css")); RockPage.AddScriptLink(ResolveRockUrl("~/Scripts/imagesloaded.min.js")); RockPage.AddScriptLink(ResolveRockUrl("~/Scripts/jquery.fluidbox.min.js")); if (CurrentPerson != null) { lName.Text = CurrentPerson.FullName; // Setup Image var imgTag = new LiteralControl(Rock.Model.Person.GetPersonPhotoImageTag(CurrentPerson, 188, 188)); if (CurrentPerson.PhotoId.HasValue) { var imgLink = new HyperLink(); imgLink.Attributes.Add("href", CurrentPerson.PhotoUrl); phImage.Controls.Add(imgLink); imgLink.Controls.Add(imgTag); } else { phImage.Controls.Add(imgTag); } if (CurrentPerson.BirthDate.HasValue) { var dtf = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat; string mdp = dtf.ShortDatePattern; mdp = mdp.Replace(dtf.DateSeparator + "yyyy", "").Replace("yyyy" + dtf.DateSeparator, ""); string ageText = (CurrentPerson.BirthYear.HasValue && CurrentPerson.BirthYear != DateTime.MinValue.Year) ? string.Format("{0} yrs old ", CurrentPerson.BirthDate.Value.Age()) : string.Empty; lAge.Text = string.Format("{0}<small>({1})</small><br/>", ageText, CurrentPerson.BirthDate.Value.ToMonthDayString()); } lGender.Text = CurrentPerson.Gender != Gender.Unknown ? CurrentPerson.Gender.ToString() : string.Empty; if (CurrentPerson.PhoneNumbers != null) { rptPhones.DataSource = CurrentPerson.PhoneNumbers.ToList(); rptPhones.DataBind(); } lEmail.Text = CurrentPerson.Email; Guid?locationTypeGuid = GetAttributeValue("LocationType").AsGuidOrNull(); if (locationTypeGuid.HasValue) { var addressTypeDv = DefinedValueCache.Read(locationTypeGuid.Value); var familyGroupTypeGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuidOrNull(); if (familyGroupTypeGuid.HasValue) { var familyGroupType = GroupTypeCache.Read(familyGroupTypeGuid.Value); RockContext rockContext = new RockContext(); var address = new GroupLocationService(rockContext).Queryable() .Where(l => l.Group.GroupTypeId == familyGroupType.Id && l.GroupLocationTypeValueId == addressTypeDv.Id && l.Group.Members.Any(m => m.PersonId == CurrentPerson.Id)) .Select(l => l.Location) .FirstOrDefault(); if (address != null) { lAddress.Text = string.Format("<div class='margin-b-md'><small>{0} Address</small><br />{1}</div>", addressTypeDv.Value, address.FormattedHtmlAddress); } } } if (GetAttributeValue("ShowHomeAddress").AsBoolean()) { var homeAddress = CurrentPerson.GetHomeLocation(); if (homeAddress != null) { } } } }
protected void btnSave_Click(object sender, EventArgs e) { hfAreaGroupClicked.Value = "true"; using (var rockContext = new RockContext()) { var attributeService = new AttributeService(rockContext); if (checkinArea.Visible) { var groupTypeService = new GroupTypeService(rockContext); var groupType = groupTypeService.Get(checkinArea.GroupTypeGuid); if (groupType != null) { groupType.LoadAttributes(rockContext); checkinArea.GetGroupTypeValues(groupType); if (groupType.IsValid) { rockContext.SaveChanges(); groupType.SaveAttributeValues(rockContext); bool AttributesUpdated = false; // rebuild the CheckinLabel attributes from the UI (brute-force) foreach (var labelAttribute in CheckinArea.GetCheckinLabelAttributes(groupType.Attributes)) { var attribute = attributeService.Get(labelAttribute.Value.Guid); Rock.Web.Cache.AttributeCache.Flush(attribute.Id); attributeService.Delete(attribute); AttributesUpdated = true; } // Make sure default role is set if (!groupType.DefaultGroupRoleId.HasValue && groupType.Roles.Any()) { groupType.DefaultGroupRoleId = groupType.Roles.First().Id; } rockContext.SaveChanges(); int labelOrder = 0; int binaryFileFieldTypeID = FieldTypeCache.Read(Rock.SystemGuid.FieldType.BINARY_FILE.AsGuid()).Id; foreach (var checkinLabelAttributeInfo in checkinArea.CheckinLabels) { var attribute = new Rock.Model.Attribute(); attribute.AttributeQualifiers.Add(new AttributeQualifier { Key = "binaryFileType", Value = Rock.SystemGuid.BinaryFiletype.CHECKIN_LABEL }); attribute.Guid = Guid.NewGuid(); attribute.FieldTypeId = binaryFileFieldTypeID; attribute.EntityTypeId = EntityTypeCache.GetId(typeof(GroupType)); attribute.EntityTypeQualifierColumn = "Id"; attribute.EntityTypeQualifierValue = groupType.Id.ToString(); attribute.DefaultValue = checkinLabelAttributeInfo.BinaryFileGuid.ToString(); attribute.Key = checkinLabelAttributeInfo.AttributeKey; attribute.Name = checkinLabelAttributeInfo.FileName; attribute.Order = labelOrder++; if (!attribute.IsValid) { return; } attributeService.Add(attribute); AttributesUpdated = true; } rockContext.SaveChanges(); GroupTypeCache.Flush(groupType.Id); Rock.CheckIn.KioskDevice.FlushAll(); if (AttributesUpdated) { AttributeCache.FlushEntityAttributes(); } nbSaveSuccess.Visible = true; BuildRows(); } else { ShowInvalidResults(groupType.ValidationResults); } } } if (checkinGroup.Visible) { var groupService = new GroupService(rockContext); var groupLocationService = new GroupLocationService(rockContext); var group = groupService.Get(checkinGroup.GroupGuid); if (group != null) { group.LoadAttributes(rockContext); checkinGroup.GetGroupValues(group); // populate groupLocations with whatever is currently in the grid, with just enough info to repopulate it and save it later var newLocationIds = checkinGroup.Locations.Select(l => l.LocationId).ToList(); foreach (var groupLocation in group.GroupLocations.Where(l => !newLocationIds.Contains(l.LocationId)).ToList()) { groupLocationService.Delete(groupLocation); group.GroupLocations.Remove(groupLocation); } var existingLocationIds = group.GroupLocations.Select(g => g.LocationId).ToList(); foreach (var item in checkinGroup.Locations.Where(l => !existingLocationIds.Contains(l.LocationId)).ToList()) { var groupLocation = new GroupLocation(); groupLocation.LocationId = item.LocationId; group.GroupLocations.Add(groupLocation); } // Set the new order foreach (var item in checkinGroup.Locations.OrderBy(l => l.Order).ToList()) { var groupLocation = group.GroupLocations.FirstOrDefault(gl => gl.LocationId == item.LocationId); groupLocation.Order = item.Order ?? 0; } if (group.IsValid) { rockContext.SaveChanges(); group.SaveAttributeValues(rockContext); Rock.CheckIn.KioskDevice.FlushAll(); nbSaveSuccess.Visible = true; BuildRows(); } else { ShowInvalidResults(group.ValidationResults); } } } } hfIsDirty.Value = "false"; }
/// <summary> /// Shows the edit person details. /// </summary> /// <param name="personGuid">The person's global unique identifier.</param> private void ShowEditPersonDetails(Person person) { var childGuid = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid(); RockContext rockContext = new RockContext(); RoleType = null; rblRole.DataSource = GroupTypeCache.GetFamilyGroupType().Roles.OrderBy(r => r.Order).ToList(); rblRole.DataBind(); rblRole.Visible = true; rblRole.Required = true; if (GetAttributeValue("DisableNameEdit").AsBoolean()) { tbFirstName.Enabled = false; tbLastName.Enabled = false; } imgPhoto.BinaryFileId = person.PhotoId; imgPhoto.NoPictureUrl = Person.GetPersonNoPictureUrl(person, 200, 200); ddlTitle.SelectedValue = person.TitleValueId.HasValue ? person.TitleValueId.Value.ToString() : string.Empty; tbFirstName.Text = person.FirstName; tbNickName.Text = person.NickName; tbLastName.Text = person.LastName; ddlSuffix.SelectedValue = person.SuffixValueId.HasValue ? person.SuffixValueId.Value.ToString() : string.Empty; bpBirthDay.SelectedDate = person.BirthDate; rblGender.SelectedValue = person.Gender.ConvertToString(); var familyRole = person.GetFamilyRole(); rblRole.SelectedValue = familyRole != null?familyRole.Id.ToString() : "0"; if (person.Id != 0 && person.GetFamilyRole().Guid == childGuid) { _IsEditRecordAdult = false; tbEmail.Required = false; // don't display campus selector to children. cpCampus.Visible = false; if (person.GraduationYear.HasValue) { ypGraduation.SelectedYear = person.GraduationYear.Value; } else { ypGraduation.SelectedYear = null; } ddlGradePicker.Visible = true; if (!person.HasGraduated ?? false) { int gradeOffset = person.GradeOffset.Value; var maxGradeOffset = ddlGradePicker.MaxGradeOffset; // keep trying until we find a Grade that has a gradeOffset that includes the Person's gradeOffset (for example, there might be combined grades) while (!ddlGradePicker.Items.OfType <ListItem>().Any(a => a.Value.AsInteger() == gradeOffset) && gradeOffset <= maxGradeOffset) { gradeOffset++; } ddlGradePicker.SetValue(gradeOffset); } else { ddlGradePicker.SelectedIndex = 0; } } else { _IsEditRecordAdult = true; bool requireEmail = GetAttributeValue("RequireAdultEmailAddress").AsBoolean(); tbEmail.Required = requireEmail; ddlGradePicker.Visible = false; // show/hide campus selector bool showCampus = GetAttributeValue("ShowCampusSelector").AsBoolean(); cpCampus.Visible = showCampus; if (showCampus) { cpCampus.Campuses = CampusCache.All(false); cpCampus.SetValue(person.GetCampus()); } } tbEmail.Text = person.Email; rblEmailPreference.SelectedValue = person.EmailPreference.ConvertToString(false); rblCommunicationPreference.Visible = this.GetAttributeValue("ShowCommunicationPreference").AsBoolean(); rblCommunicationPreference.SetValue(person.CommunicationPreference == CommunicationType.SMS ? "2" : "1"); // Family Attributes if (person.Id == CurrentPerson.Id) { Guid?locationTypeGuid = GetAttributeValue("AddressType").AsGuidOrNull(); if (locationTypeGuid.HasValue) { pnlAddress.Visible = true; var addressTypeDv = DefinedValueCache.Get(locationTypeGuid.Value); lAddressTitle.Text = addressTypeDv.Value + " Address"; var familyGroupTypeGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuidOrNull(); if (familyGroupTypeGuid.HasValue) { var familyGroupType = GroupTypeCache.Get(familyGroupTypeGuid.Value); var familyAddress = new GroupLocationService(rockContext).Queryable() .Where(l => l.Group.GroupTypeId == familyGroupType.Id && l.GroupLocationTypeValueId == addressTypeDv.Id && l.Group.Members.Any(m => m.PersonId == person.Id)) .FirstOrDefault(); if (familyAddress != null) { acAddress.SetValues(familyAddress.Location); } } } } else { pnlAddress.Visible = false; } BindPhoneNumbers(person); pnlEdit.Visible = true; if (GetAttributeValue(AttributeKeys.DisplayTerms).AsBoolean()) { cbTOS.Visible = true; cbTOS.Required = true; cbTOS.Text = GetAttributeValue(AttributeKeys.TermsOfServiceText); } }
/// <summary> /// Loads the kiosk locations. /// </summary> /// <param name="kioskDevice">The kiosk device.</param> /// <param name="location">The location.</param> /// <param name="campusId">The campus identifier.</param> /// <param name="rockContext">The rock context.</param> private static void LoadKioskLocations(KioskDevice kioskDevice, Location location, int?campusId, RockContext rockContext) { // Get the child locations and the selected location var allLocations = new LocationService(rockContext).GetAllDescendentIds(location.Id).ToList(); allLocations.Add(location.Id); DateTime currentDateTime = RockDateTime.Now; if (campusId.HasValue) { currentDateTime = CampusCache.Get(campusId.Value)?.CurrentDateTime ?? RockDateTime.Now; } kioskDevice.CampusId = campusId; var activeSchedules = new Dictionary <int, KioskSchedule>(); var groupLocationList = new GroupLocationService(rockContext) .GetActiveByLocations(allLocations) .Include(x => x.Location) .Include(x => x.Schedules) .OrderBy(l => l.Order).AsNoTracking() .ToList(); foreach (var groupLocation in groupLocationList) { var kioskLocation = new KioskLocation(groupLocation.Location); kioskLocation.CampusId = campusId; kioskLocation.Order = groupLocation.Order; // Populate each kioskLocation with its schedules (kioskSchedules) foreach (var schedule in groupLocation.Schedules.Where(s => s.CheckInStartOffsetMinutes.HasValue)) { if (activeSchedules.Keys.Contains(schedule.Id)) { kioskLocation.KioskSchedules.Add(activeSchedules[schedule.Id]); } else { var kioskSchedule = new KioskSchedule(schedule); kioskSchedule.CampusId = kioskLocation.CampusId; kioskSchedule.CheckInTimes = schedule.GetCheckInTimes(currentDateTime); if (kioskSchedule.IsCheckInActive || kioskSchedule.IsCheckOutActive || kioskSchedule.NextActiveDateTime.HasValue) { kioskLocation.KioskSchedules.Add(kioskSchedule); activeSchedules.Add(schedule.Id, kioskSchedule); } } } // If the group location has any active OR future schedules, add the group's group type to the kiosk's // list of group types if (kioskLocation.KioskSchedules.Count > 0) { KioskGroupType kioskGroupType = kioskDevice.KioskGroupTypes.Where(g => g.GroupType.Id == groupLocation.Group.GroupTypeId).FirstOrDefault(); if (kioskGroupType == null) { kioskGroupType = new KioskGroupType(groupLocation.Group.GroupTypeId); kioskDevice.KioskGroupTypes.Add(kioskGroupType); } KioskGroup kioskGroup = kioskGroupType.KioskGroups.Where(g => g.Group.Id == groupLocation.GroupId).FirstOrDefault(); if (kioskGroup == null) { kioskGroup = new KioskGroup(groupLocation.Group); kioskGroup.Group.LoadAttributes(rockContext); kioskGroupType.KioskGroups.Add(kioskGroup); } kioskGroup.KioskLocations.Add(kioskLocation); } } }
/// <summary> /// Binds the grid. /// </summary> protected void BindGrid() { AddScheduleColumns(); var rockContext = new RockContext(); var groupLocationService = new GroupLocationService(rockContext); var groupTypeService = new GroupTypeService(rockContext); IEnumerable <GroupTypePath> groupPaths = new List <GroupTypePath>(); var groupLocationQry = groupLocationService.Queryable(); int groupTypeId; // if this page has a PageParam for groupTypeId use that to limit which groupTypeId to see. Otherwise, use the groupTypeId specified in the filter int?groupTypeIdPageParam = this.PageParameter("groupTypeId").AsIntegerOrNull(); if (groupTypeIdPageParam.HasValue) { groupTypeId = groupTypeIdPageParam ?? Rock.Constants.All.Id; } else { groupTypeId = ddlGroupType.SelectedValueAsInt() ?? Rock.Constants.All.Id; } if (groupTypeId != Rock.Constants.All.Id) { var descendantGroupTypeIds = groupTypeService.GetAllAssociatedDescendents(groupTypeId).Select(a => a.Id); // filter to groups that either are of the GroupType or are of a GroupType that has the selected GroupType as a parent (ancestor) groupLocationQry = groupLocationQry.Where(a => a.Group.GroupType.Id == groupTypeId || descendantGroupTypeIds.Contains(a.Group.GroupTypeId)); groupPaths = groupTypeService.GetAllAssociatedDescendentsPath(groupTypeId); } else { // if no specific GroupType is specified, show all GroupTypes with GroupTypePurpose of Checkin Template and their descendents (since this blocktype is specifically for Checkin) int groupTypePurposeCheckInTemplateId = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.GROUPTYPE_PURPOSE_CHECKIN_TEMPLATE)).Id; List <int> descendantGroupTypeIds = new List <int>(); foreach (var templateGroupType in groupTypeService.Queryable().Where(a => a.GroupTypePurposeValueId == groupTypePurposeCheckInTemplateId)) { foreach (var childGroupType in groupTypeService.GetChildGroupTypes(templateGroupType.Id)) { descendantGroupTypeIds.Add(childGroupType.Id); descendantGroupTypeIds.AddRange(groupTypeService.GetAllAssociatedDescendents(childGroupType.Id).Select(a => a.Id).ToList()); } } groupLocationQry = groupLocationQry.Where(a => descendantGroupTypeIds.Contains(a.Group.GroupTypeId)); } if (gGroupLocationSchedule.SortProperty != null) { groupLocationQry = groupLocationQry.Sort(gGroupLocationSchedule.SortProperty); } else { groupLocationQry = groupLocationQry.OrderBy(a => a.Group.Name).ThenBy(a => a.Location.Name); } var qryList = groupLocationQry.Select(a => new { GroupLocationId = a.Id, GroupName = a.Group.Name, LocationName = a.Location.Name, ScheduleIdList = a.Schedules.Select(s => s.Id), a.LocationId, GroupTypeId = a.Group.GroupTypeId }).ToList(); int parentLocationId = pkrParentLocation.SelectedValueAsInt() ?? Rock.Constants.All.Id; if (parentLocationId != Rock.Constants.All.Id) { var descendantLocationIds = new LocationService(rockContext).GetAllDescendents(parentLocationId).Select(a => a.Id); qryList = qryList.Where(a => descendantLocationIds.Contains(a.LocationId)).ToList(); } // put stuff in a datatable so we can dynamically have columns for each Schedule DataTable dataTable = new DataTable(); dataTable.Columns.Add("GroupLocationId"); dataTable.Columns.Add("GroupName"); dataTable.Columns.Add("LocationName"); dataTable.Columns.Add("Path"); foreach (var field in gGroupLocationSchedule.Columns.OfType <CheckBoxEditableField>()) { dataTable.Columns.Add(field.DataField, typeof(bool)); } foreach (var row in qryList) { DataRow dataRow = dataTable.NewRow(); dataRow["GroupLocationId"] = row.GroupLocationId; dataRow["GroupName"] = row.GroupName; dataRow["LocationName"] = row.LocationName; dataRow["Path"] = groupPaths.Where(gt => gt.GroupTypeId == row.GroupTypeId).Select(gt => gt.Path).FirstOrDefault(); foreach (var field in gGroupLocationSchedule.Columns.OfType <CheckBoxEditableField>()) { int scheduleId = int.Parse(field.DataField.Replace("scheduleField_", string.Empty)); dataRow[field.DataField] = row.ScheduleIdList.Any(a => a == scheduleId); } dataTable.Rows.Add(dataRow); } gGroupLocationSchedule.DataSource = dataTable; gGroupLocationSchedule.DataBind(); }
/// <summary> /// Binds the grid. /// </summary> protected void BindGrid() { AddScheduleColumns(); var groupLocationService = new GroupLocationService(); var groupLocationQry = groupLocationService.Queryable(); int groupTypeId; // if this page has a PageParam for groupTypeId use that to limit which groupTypeId to see. Otherwise, use the groupTypeId specified in the filter int?groupTypeIdPageParam = this.PageParameter("groupTypeId").AsInteger(false); if (groupTypeIdPageParam.HasValue) { groupTypeId = groupTypeIdPageParam ?? Rock.Constants.All.Id; } else { groupTypeId = ddlGroupType.SelectedValueAsInt() ?? Rock.Constants.All.Id; } if (groupTypeId != Rock.Constants.All.Id) { // filter to groups that either are of the GroupType or are of a GroupType that has the selected GroupType as a parent groupLocationQry = groupLocationQry.Where(a => a.Group.GroupType.Id == groupTypeId || a.Group.GroupType.ParentGroupTypes.Select(p => p.Id).Contains(groupTypeId)); } var qryList = groupLocationQry.Select(a => new { GroupLocationId = a.Id, GroupName = a.Group.Name, LocationName = a.Location.Name, ScheduleIdList = a.Schedules.Select(s => s.Id), a.LocationId }).ToList(); int parentLocationId = ddlParentLocation.SelectedValueAsInt() ?? Rock.Constants.All.Id; if (parentLocationId != Rock.Constants.All.Id) { var descendantLocationIds = new LocationService().GetAllDescendents(parentLocationId).Select(a => a.Id); qryList = qryList.Where(a => descendantLocationIds.Contains(a.LocationId)).ToList(); } // put stuff in a datatable so we can dynamically have columns for each Schedule DataTable dataTable = new DataTable(); dataTable.Columns.Add("GroupLocationId"); dataTable.Columns.Add("GroupName"); dataTable.Columns.Add("LocationName"); foreach (var field in gGroupLocationSchedule.Columns.OfType <CheckBoxEditableField>()) { dataTable.Columns.Add(field.DataField, typeof(bool)); } foreach (var row in qryList) { DataRow dataRow = dataTable.NewRow(); dataRow["GroupLocationId"] = row.GroupLocationId; dataRow["GroupName"] = row.GroupName; dataRow["LocationName"] = row.LocationName; foreach (var field in gGroupLocationSchedule.Columns.OfType <CheckBoxEditableField>()) { int scheduleId = int.Parse(field.DataField.Replace("scheduleField_", string.Empty)); dataRow[field.DataField] = row.ScheduleIdList.Any(a => a == scheduleId); } dataTable.Rows.Add(dataRow); } gGroupLocationSchedule.DataSource = dataTable; gGroupLocationSchedule.DataBind(); }
/// <summary> /// Updates the list of group locations for the selected group /// </summary> private void UpdateGroupLocationList() { Group group = GetSelectedGroup(); if (group == null) { pnlScheduler.Visible = false; return; } if (group != null) { bool canSchedule = group.IsAuthorized(Authorization.EDIT, this.CurrentPerson) || group.IsAuthorized(Authorization.SCHEDULE, this.CurrentPerson); if (!canSchedule) { nbNotice.Heading = "Sorry"; nbNotice.Text = "<p>You're not authorized to schedule resources for the selected group.</p>"; nbNotice.NotificationBoxType = NotificationBoxType.Warning; nbNotice.Visible = true; pnlScheduler.Visible = false; return; } else { nbNotice.Visible = false; } pnlScheduler.Visible = true; int scheduleId = rblSchedule.SelectedValue.AsInteger(); var rockContext = new RockContext(); var groupLocationsQuery = new GroupLocationService(rockContext).Queryable() .Where(a => a.GroupId == group.Id && a.Schedules.Any(s => s.Id == scheduleId)) .OrderBy(a => new { a.Order, a.Location.Name }) .AsNoTracking(); var groupLocationsList = groupLocationsQuery.ToList(); if (!groupLocationsList.Any() && scheduleId != 0) { nbGroupWarning.Text = "Group does not have any locations for the selected schedule"; nbGroupWarning.Visible = true; } else if (scheduleId != 0) { nbGroupWarning.Visible = false; } // get the location ids of the selected group locations so that we can keep the selected locations even if the group changes var allSelectedLocationIds = hfAllSelectedLocationIds.Value.SplitDelimitedValues().AsIntegerList(); var selectedGroupLocationIds = allSelectedLocationIds; var selectedLocationIds = new GroupLocationService(new RockContext()).GetByIds(selectedGroupLocationIds).Select(a => a.LocationId).ToList(); cblGroupLocations.Items.Clear(); foreach (var groupLocation in groupLocationsList) { var groupLocationItem = new ListItem(groupLocation.Location.ToString(), groupLocation.Id.ToString()); groupLocationItem.Selected = selectedLocationIds.Contains(groupLocation.LocationId); cblGroupLocations.Items.Add(groupLocationItem); } // if there aren't any locations select, default to selecting all if (!cblGroupLocations.SelectedValues.Any()) { foreach (var item in cblGroupLocations.Items.OfType <ListItem>()) { item.Selected = true; } } } }
/// <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>(); // get person Person person = null; string personAttributeValue = GetAttributeValue(action, "Person"); Guid? guidPersonAttribute = personAttributeValue.AsGuidOrNull(); if (guidPersonAttribute.HasValue) { var attributePerson = AttributeCache.Get(guidPersonAttribute.Value, rockContext); if (attributePerson != null || attributePerson.FieldType.Class != "Rock.Field.Types.PersonFieldType") { string attributePersonValue = action.GetWorkflowAttributeValue(guidPersonAttribute.Value); if (!string.IsNullOrWhiteSpace(attributePersonValue)) { Guid personAliasGuid = attributePersonValue.AsGuid(); if (!personAliasGuid.IsEmpty()) { person = new PersonAliasService(rockContext).Queryable() .Where(a => a.Guid.Equals(personAliasGuid)) .Select(a => a.Person) .FirstOrDefault(); if (person == null) { errorMessages.Add(string.Format("Person could not be found for selected value ('{0}')!", guidPersonAttribute.ToString())); return(false); } } } } } if (person == null) { errorMessages.Add("The attribute used to provide the person was invalid, or not of type 'Person'."); return(false); } // determine the location type to edit DefinedValueCache locationType = null; var locationTypeAttributeValue = action.GetWorkflowAttributeValue(GetAttributeValue(action, "LocationTypeAttribute").AsGuid()); if (locationTypeAttributeValue != null) { locationType = DefinedValueCache.Get(locationTypeAttributeValue.AsGuid()); } if (locationType == null) { locationType = DefinedValueCache.Get(GetAttributeValue(action, "LocationType").AsGuid()); } if (locationType == null) { errorMessages.Add("The location type to be updated was not selected."); return(false); } // get the new phone number value Location location = null; string locationValue = GetAttributeValue(action, "Location"); Guid? locationGuid = locationValue.AsGuidOrNull(); if (!locationGuid.HasValue || locationGuid.Value.IsEmpty()) { string locationAttributeValue = GetAttributeValue(action, "LocationAttribute"); Guid? locationAttributeValueGuid = locationAttributeValue.AsGuidOrNull(); if (locationAttributeValueGuid.HasValue) { locationGuid = action.GetWorkflowAttributeValue(locationAttributeValueGuid.Value).AsGuidOrNull(); } } if (locationGuid.HasValue) { location = new LocationService(rockContext).Get(locationGuid.Value); } if (location == null) { errorMessages.Add("The location value could not be determined."); return(false); } // gets value indicating if location is a mailing location string mailingValue = GetAttributeValue(action, "IsMailing"); Guid? mailingValueGuid = mailingValue.AsGuidOrNull(); if (mailingValueGuid.HasValue) { mailingValue = action.GetWorkflowAttributeValue(mailingValueGuid.Value); } else { mailingValue = mailingValue.ResolveMergeFields(GetMergeFields(action)); } bool?mailing = mailingValue.AsBooleanOrNull(); // gets value indicating if location is a mapped location string mappedValue = GetAttributeValue(action, "IsMapped"); Guid? mappedValueGuid = mappedValue.AsGuidOrNull(); if (mappedValueGuid.HasValue) { mappedValue = action.GetWorkflowAttributeValue(mappedValueGuid.Value); } else { mappedValue = mappedValue.ResolveMergeFields(GetMergeFields(action)); } bool?mapped = mappedValue.AsBooleanOrNull(); var savePreviousAddress = GetAttributeValue(action, "SavePreviousAddress").AsBoolean(); var locationService = new LocationService(rockContext); locationService.Verify(location, false); var groupLocationService = new GroupLocationService(rockContext); foreach (var family in person.GetFamilies(rockContext).ToList()) { bool locationUpdated = false; if (savePreviousAddress) { // Get all existing addresses of the specified type var groupLocations = family.GroupLocations.Where(l => l.GroupLocationTypeValueId == locationType.Id).ToList(); // Create a new address of the specified type, saving all existing addresses of that type as Previous Addresses // Use the specified Is Mailing and Is Mapped values from the action's parameters if they are set, // otherwise set them to true if any of the existing addresses of that type have those values set to true GroupService.AddNewGroupAddress(rockContext, family, locationType.Guid.ToString(), location.Id, true, $"the {action.ActionTypeCache.ActivityType.WorkflowType.Name} workflow", mailing ?? groupLocations.Any(x => x.IsMailingLocation), mapped ?? groupLocations.Any(x => x.IsMappedLocation)); } else { var groupLocation = family.GroupLocations.FirstOrDefault(l => l.GroupLocationTypeValueId == locationType.Id); string oldValue = string.Empty; if (groupLocation == null) { groupLocation = new GroupLocation(); groupLocation.GroupId = family.Id; groupLocation.GroupLocationTypeValueId = locationType.Id; groupLocationService.Add(groupLocation); } else { oldValue = groupLocation.Location.ToString(); } locationUpdated = oldValue != location.ToString(); groupLocation.Location = location; if (mailing.HasValue) { if (((oldValue == string.Empty) ? null : groupLocation.IsMailingLocation.ToString()) != mailing.Value.ToString()) { locationUpdated = true; } groupLocation.IsMailingLocation = mailing.Value; } if (mapped.HasValue) { if (((oldValue == string.Empty) ? null : groupLocation.IsMappedLocation.ToString()) != mapped.Value.ToString()) { locationUpdated = true; } groupLocation.IsMappedLocation = mapped.Value; } } if (locationUpdated) { var groupChanges = new History.HistoryChangeList(); groupChanges.AddChange(History.HistoryVerb.Modify, History.HistoryChangeType.Record, "Location").SourceOfChange = $"{action.ActionTypeCache.ActivityType.WorkflowType.Name} workflow"; foreach (var fm in family.Members) { HistoryService.SaveChanges( rockContext, typeof(Person), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), fm.PersonId, groupChanges, family.Name, typeof(Group), family.Id, false, null, rockContext.SourceOfChange); } } rockContext.SaveChanges(); action.AddLogEntry(string.Format("Updated the {0} location for {1} (family: {2}) to {3}", locationType.Value, person.FullName, family.Name, location.ToString())); } return(true); }
/// <summary> /// Gets a list of assignment schedules. /// </summary> /// <param name="groupId"></param> /// <returns>A list of <see cref="AssignmentScheduleAndLocationBag"/> used to display on the preference page.</returns> private List <AssignmentScheduleAndLocationBag> GetAssignmentScheduleList(int?groupId) { using (var rockContext = new RockContext()) { var groupMember = GetGroupMemberRecord(rockContext, groupId.Value, CurrentPersonId); if (groupMember == null) { return(null); } var groupLocationService = new GroupLocationService(rockContext); var qryGroupLocations = groupLocationService .Queryable() .Where(g => g.GroupId == groupId); var groupMemberAssignmentService = new GroupMemberAssignmentService(rockContext); var groupMemberAssignmentQuery = groupMemberAssignmentService .Queryable() .AsNoTracking() .Where(x => x.GroupMemberId == groupMember.Id && ( !x.LocationId.HasValue || qryGroupLocations.Any(gl => gl.LocationId == x.LocationId && gl.Schedules.Any(s => s.Id == x.ScheduleId)) )); // Calculate the Next Start Date Time based on the start of the week so that schedule columns are in the correct order. var occurrenceDate = RockDateTime.Now.SundayDate().AddDays(1); var groupMemberAssignmentList = groupMemberAssignmentQuery .Include(a => a.Schedule) .Include(a => a.Location) .AsNoTracking() .ToList() .OrderBy(a => a.Schedule.Order) .ThenBy(a => a.Schedule.GetNextStartDateTime(occurrenceDate)) .ThenBy(a => a.Schedule.Name) .ThenBy(a => a.Schedule.Id) .ThenBy(a => a.LocationId.HasValue ? a.Location.ToString(true) : string.Empty) .ToList(); List <AssignmentScheduleAndLocationBag> assignmentScheduleAndLocations = new List <AssignmentScheduleAndLocationBag>(); // Loop through each assignment in the list. foreach (var groupMemberAssignment in groupMemberAssignmentList) { var scheduleListItem = new ListItemViewModel { Value = groupMemberAssignment.Schedule.Guid.ToStringSafe(), Text = groupMemberAssignment.Schedule.Name }; var locationListItem = new ListItemViewModel { Value = groupMemberAssignment.Location != null?groupMemberAssignment.Location.Guid.ToStringSafe() : string.Empty, Text = groupMemberAssignment.Location != null ? groupMemberAssignment.Location.Name : "No Location Preference" }; assignmentScheduleAndLocations.Add(new AssignmentScheduleAndLocationBag { GroupMemberAssignmentGuid = groupMemberAssignment.Guid, ScheduleListItem = scheduleListItem, LocationListItem = locationListItem }); } return(assignmentScheduleAndLocations); } }
/// <summary> /// Binds the grid. /// </summary> private void BindGrid() { if (HasFilterErrors()) { return; } var checkinAreaFilter = CheckinManagerHelper.GetCheckinAreaFilter(this); CampusCache campus = GetCampusFromContext(); var selectedScheduleIds = lbSchedules.SelectedValues.AsIntegerList(); if (selectedScheduleIds.Any()) { btnShowFilter.AddCssClass("criteria-exists bg-warning"); } else { btnShowFilter.RemoveCssClass("criteria-exists bg-warning"); } CheckinManagerHelper.SaveRoomListFilterToCookie(selectedScheduleIds.ToArray()); var rockContext = new RockContext(); var groupService = new GroupService(rockContext); var groupTypeService = new GroupTypeService(rockContext); IEnumerable <CheckinAreaPath> checkinAreaPaths; if (checkinAreaFilter != null) { checkinAreaPaths = groupTypeService.GetCheckinAreaDescendantsPath(checkinAreaFilter.Id); } else { checkinAreaPaths = groupTypeService.GetAllCheckinAreaPaths(); } var selectedGroupTypeIds = checkinAreaPaths.Select(a => a.GroupTypeId).Distinct().ToArray(); var groupLocationService = new GroupLocationService(rockContext); var groupLocationsQuery = groupLocationService.Queryable() .Where(gl => selectedGroupTypeIds.Contains(gl.Group.GroupTypeId) && gl.Group.IsActive && (!gl.Group.IsArchived)); var parentLocationIdParameter = PageParameter(PageParameterKey.ParentLocationId).AsIntegerOrNull(); var locationIdParameter = PageParameter(PageParameterKey.LocationId).AsIntegerOrNull(); var locationGridField = gRoomList.ColumnsOfType <RockLiteralField>().FirstOrDefault(a => a.ID == "lRoomName"); if (locationGridField != null && !locationGridField.Visible) { locationGridField.Visible = true; } List <int> locationIds; if (locationIdParameter.HasValue) { // If LocationId is specified in the URL, list only items for the specified location. // Also, hide the Location Grid Column and set the PanelTitle as the location's name // This will take precedence over the selected campus+locations and/or <seealso cref="ParentLocationId"/> var locationService = new LocationService(rockContext); lPanelTitle.Text = locationService.GetSelect(locationIdParameter.Value, s => s.Name); locationIds = new List <int>(); locationIds.Add(locationIdParameter.Value); if (locationGridField != null) { // since a LocationId parameter was specified, the LocationGrid field doesn't need to be shown locationGridField.Visible = false; } } else if (parentLocationIdParameter.HasValue) { // If parentLocationId is specified, show the direct (first level) child locations of the specified ParentLocationId. // This will take precedence over the selected campus+locations. var locationService = new LocationService(rockContext); locationIds = locationService.Queryable() .Where(a => a.ParentLocationId.HasValue && a.ParentLocationId.Value == parentLocationIdParameter.Value) .Select(a => a.Id).ToList(); lPanelTitle.Text = string.Format("{0} Child Locations", locationService.GetSelect(parentLocationIdParameter.Value, s => s.Name)); } else { // Limit locations (rooms) to locations within the selected campus. locationIds = new LocationService(rockContext).GetAllDescendentIds(campus.LocationId.Value).ToList(); locationIds.Add(campus.LocationId.Value, true); lPanelTitle.Text = "Room List"; } groupLocationsQuery = groupLocationsQuery.Where(a => locationIds.Contains(a.LocationId)); if (selectedScheduleIds.Any()) { groupLocationsQuery = groupLocationsQuery.Where(a => a.Schedules.Any(s => s.IsActive && s.CheckInStartOffsetMinutes.HasValue && selectedScheduleIds.Contains(s.Id))); } else { groupLocationsQuery = groupLocationsQuery.Where(a => a.Schedules.Any(s => s.IsActive && s.CheckInStartOffsetMinutes.HasValue)); } var groupLocationList = groupLocationsQuery.Select(a => new GroupLocationInfo { LocationId = a.LocationId, LocationName = a.Location.Name, ParentGroupId = a.Group.ParentGroupId, ParentGroupName = a.Group.ParentGroup.Name, GroupId = a.Group.Id, GroupName = a.Group.Name, GroupTypeId = a.Group.GroupTypeId }).ToList(); var startDateTime = RockDateTime.Today; DateTime currentDateTime; if (campus != null) { currentDateTime = campus.CurrentDateTime; } else { currentDateTime = RockDateTime.Now; } // Get all Attendance records for the current day and location. var attendanceQuery = new AttendanceService(rockContext).Queryable().Where(a => a.StartDateTime >= startDateTime && a.DidAttend == true && a.StartDateTime <= currentDateTime && a.PersonAliasId.HasValue && a.Occurrence.GroupId.HasValue && a.Occurrence.LocationId.HasValue && a.Occurrence.ScheduleId.HasValue); // Limit attendances (rooms) to the groupLocations' LocationId and GroupIds that we'll be showing var groupLocationLocationIds = groupLocationList.Select(a => a.LocationId).Distinct().ToList(); var groupLocationGroupsIds = groupLocationList.Select(a => a.GroupId).Distinct().ToList(); attendanceQuery = attendanceQuery.Where(a => groupLocationLocationIds.Contains(a.Occurrence.LocationId.Value) && groupLocationGroupsIds.Contains(a.Occurrence.GroupId.Value)); attendanceQuery = attendanceQuery.Where(a => selectedGroupTypeIds.Contains(a.Occurrence.Group.GroupTypeId)); if (selectedScheduleIds.Any()) { attendanceQuery = attendanceQuery.Where(a => selectedScheduleIds.Contains(a.Occurrence.ScheduleId.Value)); } var rosterAttendeeAttendanceList = RosterAttendeeAttendance.Select(attendanceQuery).ToList(); var groupTypeIdsWithAllowCheckout = selectedGroupTypeIds .Select(a => GroupTypeCache.Get(a)) .Where(a => a != null) .Where(gt => gt.GetCheckInConfigurationAttributeValue(Rock.SystemKey.GroupTypeAttributeKey.CHECKIN_GROUPTYPE_ALLOW_CHECKOUT).AsBoolean()) .Select(a => a.Id) .Distinct().ToList(); var groupTypeIdsWithEnablePresence = selectedGroupTypeIds .Select(a => GroupTypeCache.Get(a)) .Where(a => a != null) .Where(gt => gt.GetCheckInConfigurationAttributeValue(Rock.SystemKey.GroupTypeAttributeKey.CHECKIN_GROUPTYPE_ENABLE_PRESENCE).AsBoolean()) .Select(a => a.Id) .Distinct(); var scheduleIds = rosterAttendeeAttendanceList.Select(a => a.ScheduleId.Value).Distinct().ToList(); var scheduleList = new ScheduleService(rockContext).GetByIds(scheduleIds).ToList(); var scheduleIdsWasScheduleOrCheckInActiveForCheckOut = new HashSet <int>(scheduleList.Where(a => a.WasScheduleOrCheckInActiveForCheckOut(currentDateTime)).Select(a => a.Id).ToList()); rosterAttendeeAttendanceList = rosterAttendeeAttendanceList.Where(a => { var allowCheckout = groupTypeIdsWithAllowCheckout.Contains(a.GroupTypeId); if (!allowCheckout) { /* * If AllowCheckout is false, remove all Attendees whose schedules are not currently active. Per the 'WasSchedule...ActiveForCheckOut()' * method below: "Check-out can happen while check-in is active or until the event ends (start time + duration)." This will help to keep * the list of 'Present' attendees cleaned up and accurate, based on the room schedules, since the volunteers have no way to manually mark * an Attendee as 'Checked-out'. * * If, on the other hand, AllowCheckout is true, it will be the volunteers' responsibility to click the [Check-out] button when an * Attendee leaves the room, in order to keep the list of 'Present' Attendees in order. This will also allow the volunteers to continue * 'Checking-out' Attendees in the case that the parents are running late in picking them up. */ return(scheduleIdsWasScheduleOrCheckInActiveForCheckOut.Contains(a.ScheduleId.Value)); } else { return(true); } }).ToList(); var attendancesByLocationId = rosterAttendeeAttendanceList .GroupBy(a => a.LocationId.Value).ToDictionary(k => k.Key, v => v.ToList()); _attendancesByLocationIdAndGroupId = attendancesByLocationId.ToDictionary( k => k.Key, v => v.Value.GroupBy(x => x.GroupId.Value).ToDictionary(x => x.Key, xx => xx.ToList())); _checkinAreaPathsLookupByGroupTypeId = checkinAreaPaths.ToDictionary(k => k.GroupTypeId, v => v); _showOnlyParentGroup = this.GetAttributeValue(AttributeKey.ShowOnlyParentGroup).AsBoolean(); var roomList = new List <RoomInfo>(); foreach (var groupLocation in groupLocationList) { AddToRoomList(roomList, groupLocation); } List <RoomInfo> sortedRoomList; if (_showOnlyParentGroup) { sortedRoomList = roomList.OrderBy(a => a.LocationName).ToList(); } else { sortedRoomList = new List <RoomInfo>(); sortedRoomList.AddRange(roomList.OfType <RoomInfoByGroup>().OrderBy(a => a.LocationName).ThenBy(a => a.GroupName).ToList()); } var checkedInCountField = gRoomList.ColumnsOfType <RockLiteralField>().FirstOrDefault(a => a.ID == "lCheckedInCount"); var presentCountField = gRoomList.ColumnsOfType <RockLiteralField>().FirstOrDefault(a => a.ID == "lPresentCount"); var checkedOutCountField = gRoomList.ColumnsOfType <RockLiteralField>().FirstOrDefault(a => a.ID == "lCheckedOutCount"); checkedOutCountField.Visible = groupTypeIdsWithAllowCheckout.Any(); // Always show Present Count regardless of the 'Enable Presence' setting. (A person gets automatically marked present if 'Enable Presence' is disabled.) presentCountField.Visible = true; if (groupTypeIdsWithEnablePresence.Any()) { // Presence is enabled, so records could be in the 'Checked-in' state // and Present column should be labeled 'Present'. checkedInCountField.Visible = true; presentCountField.HeaderText = "Present"; } else { // https://app.asana.com/0/0/1199637795718017/f // 'Enable Presence' is disabled, so a person automatically gets marked present. // So, no records will be in the 'Checked-In (but no present)' state. // Also, a user thinks of 'Present' as 'Checked-In' if they don't use the 'Enable Presence' feature checkedInCountField.Visible = false; presentCountField.HeaderText = "Checked-In"; } if (_showOnlyParentGroup) { gRoomList.DataKeyNames = new string[1] { "LocationId" }; } else { gRoomList.DataKeyNames = new string[2] { "LocationId", "GroupId" }; } gRoomList.DataSource = sortedRoomList; gRoomList.DataBind(); }
/// <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) { using (var rockContext = new RockContext()) { GroupLocationService groupLocationService = new GroupLocationService(rockContext); ScheduleService scheduleService = new ScheduleService(rockContext); bool schedulesChanged = false; var gridViewRows = gGroupLocationSchedule.Rows; foreach (GridViewRow row in gridViewRows.OfType <GridViewRow>()) { int groupLocationId = int.Parse(gGroupLocationSchedule.DataKeys[row.RowIndex].Value as string); GroupLocation groupLocation = groupLocationService.Get(groupLocationId); if (groupLocation != null) { foreach (var fieldCell in row.Cells.OfType <DataControlFieldCell>()) { var checkBoxTemplateField = fieldCell.ContainingField as CheckBoxEditableField; if (checkBoxTemplateField != null) { CheckBox checkBox = fieldCell.Controls[0] as CheckBox; string dataField = (fieldCell.ContainingField as CheckBoxEditableField).DataField; int scheduleId = int.Parse(dataField.Replace("scheduleField_", string.Empty)); // update GroupLocationSchedule depending on if the Schedule is Checked or not if (checkBox.Checked) { // This schedule is selected, so if GroupLocationSchedule doesn't already have this schedule, add it if (!groupLocation.Schedules.Any(a => a.Id == scheduleId)) { var schedule = scheduleService.Get(scheduleId); groupLocation.Schedules.Add(schedule); schedulesChanged = true; } } else { // This schedule is not selected, so if GroupLocationSchedule has this schedule, delete it if (groupLocation.Schedules.Any(a => a.Id == scheduleId)) { groupLocation.Schedules.Remove(groupLocation.Schedules.FirstOrDefault(a => a.Id == scheduleId)); schedulesChanged = true; } } } } } } if (schedulesChanged) { rockContext.SaveChanges(); if (this.CurrentKioskId.HasValue) { KioskDevice.Flush(this.CurrentKioskId.Value); } } } NavigateToHomePage(); }
/// <summary> /// Shows the readonly details. /// </summary> /// <param name="groupType">The groupType.</param> private void ShowReadonlyDetails(GroupType groupType) { SetEditMode(false); if (groupType != null) { hfGroupTypeId.SetValue(groupType.Id); lReadOnlyTitle.Text = groupType.ToString().FormatAsHtmlTitle(); lDescription.Text = groupType.Description; groupType.LoadAttributes(); hlType.Text = groupType.GetAttributeValue("CheckInType"); hlType.Visible = true; DescriptionList mainDetailsDescList = new DescriptionList(); DescriptionList leftDetailsDescList = new DescriptionList(); DescriptionList rightDetailsDescList = new DescriptionList(); string scheduleList = string.Empty; using (var rockContext = new RockContext()) { var descendantGroupTypeIds = new GroupTypeService(rockContext).GetAllAssociatedDescendents(groupType.Id).Select(a => a.Id); scheduleList = new GroupLocationService(rockContext) .Queryable().AsNoTracking() .Where(a => a.Group.GroupType.Id == groupType.Id || descendantGroupTypeIds.Contains(a.Group.GroupTypeId)) .SelectMany(a => a.Schedules) .Select(s => s.Name) .Distinct() .OrderBy(s => s) .ToList() .AsDelimited(", "); } if (!string.IsNullOrWhiteSpace(scheduleList)) { mainDetailsDescList.Add("Scheduled Times", scheduleList); } groupType.LoadAttributes(); if (groupType.AttributeValues.ContainsKey("core_checkin_CheckInType")) { leftDetailsDescList.Add("Check-in Type", groupType.AttributeValues["core_checkin_CheckInType"].ValueFormatted); } if (groupType.AttributeValues.ContainsKey("core_checkin_SearchType")) { var searchType = groupType.AttributeValues["core_checkin_SearchType"]; rightDetailsDescList.Add("Search Type", searchType.ValueFormatted); var searchTypeGuid = searchType.Value.AsGuid(); if (searchTypeGuid.Equals(Rock.SystemGuid.DefinedValue.CHECKIN_SEARCH_TYPE_NAME_AND_PHONE.AsGuid()) || searchTypeGuid.Equals(Rock.SystemGuid.DefinedValue.CHECKIN_SEARCH_TYPE_PHONE_NUMBER.AsGuid())) { rightDetailsDescList.Add("Phone Number Compare", groupType.AttributeValues["core_checkin_PhoneSearchType"].ValueFormatted); } } lblMainDetails.Text = mainDetailsDescList.Html; lblLeftDetails.Text = leftDetailsDescList.Html; lblRightDetails.Text = rightDetailsDescList.Html; } }
/// <summary> /// Processes the NCOA results: Mark all 48 month move addresses as previous and processed if enabled, otherwise mark as manual update required. /// </summary> /// <param name="mark48MonthAsPrevious">if a 48 month move should be marked as previous, set to <c>true</c>.</param> /// <param name="previousValueId">The previous value identifier.</param> private void ProcessNcoaResults48MonthMove(bool mark48MonthAsPrevious, int?previousValueId) { List <int> ncoaIds = null; // Process the '48 Month Move' NCOA Types using (var rockContext = new RockContext()) { ncoaIds = new NcoaHistoryService(rockContext) .Queryable().AsNoTracking() .Where(n => n.Processed == Processed.NotProcessed && n.NcoaType == NcoaType.Month48Move) .Select(n => n.Id) .ToList(); } foreach (int id in ncoaIds) { using (var rockContext = new RockContext()) { var ncoaHistory = new NcoaHistoryService(rockContext).Get(id); if (ncoaHistory != null) { var groupService = new GroupService(rockContext); var groupLocationService = new GroupLocationService(rockContext); var changes = new History.HistoryChangeList(); // If configured to mark these as previous, and we're able to mark it as previous set the status to 'Complete' // otherwise set it to require a manual update if (mark48MonthAsPrevious && MarkAsPreviousLocation(ncoaHistory, groupLocationService, previousValueId, changes) != null) { ncoaHistory.Processed = Processed.Complete; // If there were any changes, write to history if (changes.Any()) { var family = groupService.Get(ncoaHistory.FamilyId); if (family != null) { foreach (var fm in family.Members) { HistoryService.SaveChanges( rockContext, typeof(Person), SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), fm.PersonId, changes, family.Name, typeof(Group), family.Id, false); } } } } else { ncoaHistory.Processed = Processed.ManualUpdateRequired; } rockContext.SaveChanges(); } } } }
/// <summary> /// Builds the status board. /// </summary> private void BuildStatusBoard() { lGroupStatusTableHTML.Text = string.Empty; int numberOfWeeks = GetSelectedNumberOfWeeks(); List <int> selectedGroupIds = GetSelectedGroupIds(); var rockContext = new RockContext(); var groupsQuery = new GroupService(rockContext).GetByIds(selectedGroupIds).Where(a => a.GroupType.IsSchedulingEnabled == true && a.DisableScheduling == false); nbGroupsWarning.Visible = false; if (!groupsQuery.Any()) { nbGroupsWarning.Text = "Please select at least one group."; nbGroupsWarning.NotificationBoxType = NotificationBoxType.Warning; nbGroupsWarning.Visible = true; return; } var groupLocationService = new GroupLocationService(rockContext); var groupLocationsQuery = groupLocationService.Queryable().Where(a => selectedGroupIds.Contains(a.GroupId) && a.Group.GroupType.IsSchedulingEnabled == true); // get all the schedules that are in use by at least one of the GroupLocations var groupsScheduleList = groupLocationsQuery.SelectMany(a => a.Schedules).Distinct().AsNoTracking().ToList(); if (!groupsScheduleList.Any()) { nbGroupsWarning.Text = "The selected groups don't have any location schedules configured."; nbGroupsWarning.NotificationBoxType = NotificationBoxType.Warning; nbGroupsWarning.Visible = true; return; } // get the next N sundayDates List <DateTime> sundayDateList = GetSundayDateList(numberOfWeeks); // build the list of scheduled times for the next n weeks List <ScheduleOccurrenceDate> scheduleOccurrenceDateList = new List <ScheduleOccurrenceDate>(); var currentDate = RockDateTime.Today; foreach (var sundayDate in sundayDateList) { foreach (var schedule in groupsScheduleList) { var sundayWeekStart = sundayDate.AddDays(-6); // get all the occurrences for the selected week for this scheduled (It could be more than once a week if it is a daily scheduled, or it might not be in the selected week if it is every 2 weeks, etc) var scheduledDateTimeList = schedule.GetScheduledStartTimes(sundayWeekStart, sundayDate.AddDays(1)); foreach (var scheduledDateTime in scheduledDateTimeList) { if (scheduledDateTime >= currentDate) { scheduleOccurrenceDateList.Add(new ScheduleOccurrenceDate { Schedule = schedule, ScheduledDateTime = scheduledDateTime }); } } } } scheduleOccurrenceDateList = scheduleOccurrenceDateList.OrderBy(a => a.ScheduledDateTime).ToList(); var latestOccurrenceDate = sundayDateList.Max(); var scheduledOccurrencesQuery = new AttendanceOccurrenceService(rockContext).Queryable().Where(a => a.GroupId.HasValue && a.LocationId.HasValue && a.ScheduleId.HasValue && selectedGroupIds.Contains(a.GroupId.Value)); scheduledOccurrencesQuery = scheduledOccurrencesQuery.Where(a => a.OccurrenceDate >= currentDate && a.OccurrenceDate <= latestOccurrenceDate); var occurrenceScheduledAttendancesList = scheduledOccurrencesQuery.Select(ao => new { Occurrence = ao, ScheduledAttendees = ao.Attendees.Where(a => a.RequestedToAttend == true || a.ScheduledToAttend == true).Select(a => new { ScheduledPerson = a.PersonAlias.Person, a.RequestedToAttend, a.ScheduledToAttend, a.RSVP }) }).ToList(); StringBuilder sbTable = new StringBuilder(); // start of table sbTable.AppendLine("<table class='table schedule-status-board js-schedule-status-board'>"); sbTable.AppendLine("<thead class='schedule-status-board-header js-schedule-status-board-header'>"); sbTable.AppendLine("<tr>"); var tableHeaderLavaTemplate = @" {%- comment -%}empty column for group/location names{%- endcomment -%} <th scope='col'></th> {% for scheduleOccurrenceDate in ScheduleOccurrenceDateList %} <th scope='col'> <span class='date'>{{ scheduleOccurrenceDate.ScheduledDateTime | Date:'MMM d, yyyy' }}</span> <br /> <span class='day-time'>{{ scheduleOccurrenceDate.Schedule.Name }}</span> </th> {% endfor %} "; var headerMergeFields = new Dictionary <string, object> { { "ScheduleOccurrenceDateList", scheduleOccurrenceDateList } }; string tableHeaderHtml = tableHeaderLavaTemplate.ResolveMergeFields(headerMergeFields); sbTable.Append(tableHeaderHtml); sbTable.AppendLine("</tr>"); sbTable.AppendLine("</thead>"); var groupLocationsList = groupsQuery.Where(g => g.GroupLocations.Any()).OrderBy(a => a.Order).ThenBy(a => a.Name).Select(g => new { Group = g, LocationScheduleCapacitiesList = g.GroupLocations.OrderBy(gl => gl.Order).ThenBy(gl => gl.Location.Name).Select(a => new { ScheduleCapacitiesList = a.GroupLocationScheduleConfigs.Select(sc => new ScheduleCapacities { ScheduleId = sc.ScheduleId, MinimumCapacity = sc.MinimumCapacity, DesiredCapacity = sc.DesiredCapacity, MaximumCapacity = sc.MaximumCapacity }), a.Location }).ToList() }).ToList(); var columnsCount = scheduleOccurrenceDateList.Count() + 1; foreach (var groupLocations in groupLocationsList) { var group = groupLocations.Group; StringBuilder sbGroupLocations = new StringBuilder(); sbGroupLocations.AppendLine(string.Format("<tbody class='group-locations js-group-locations' data-group-id='{0}' data-locations-expanded='1'>", group.Id)); // group header row sbGroupLocations.AppendLine("<tr class='group-heading js-group-header thead-dark clickable' >"); sbGroupLocations.AppendLine(string.Format("<th></th><th colspan='{0}'><i class='fa fa-chevron-down'></i> {1}</th>", columnsCount - 1, group.Name)); sbGroupLocations.AppendLine("</tr>"); // group/schedule+locations var locationScheduleCapacitiesList = groupLocations.LocationScheduleCapacitiesList; foreach (var locationScheduleCapacities in locationScheduleCapacitiesList) { var location = locationScheduleCapacities.Location; var scheduleCapacitiesLookup = locationScheduleCapacities.ScheduleCapacitiesList.ToDictionary(k => k.ScheduleId, v => v); sbGroupLocations.AppendLine("<tr class='location-row js-location-row'>"); sbGroupLocations.AppendLine(string.Format("<td class='location' scope='row' data-location-id='{0}'><div>{1}</div></td>", location.Id, location.Name)); foreach (var scheduleOccurrenceDate in scheduleOccurrenceDateList) { var capacities = scheduleCapacitiesLookup.GetValueOrNull(scheduleOccurrenceDate.Schedule.Id) ?? new ScheduleCapacities(); var scheduleLocationStatusHtmlFormat = @"<ul class='location-scheduled-list' data-capacity-min='{1}' data-capacity-desired='{2}' data-capacity-max='{3}' data-scheduled-count='{4}'> {0} </ul>"; StringBuilder sbScheduledListHtml = new StringBuilder(); var occurrenceScheduledAttendances = occurrenceScheduledAttendancesList .FirstOrDefault(ao => ao.Occurrence.OccurrenceDate == scheduleOccurrenceDate.OccurrenceDate && ao.Occurrence.GroupId == groupLocations.Group.Id && ao.Occurrence.ScheduleId == scheduleOccurrenceDate.Schedule.Id && ao.Occurrence.LocationId == location.Id); int scheduledCount = 0; if (occurrenceScheduledAttendances != null && occurrenceScheduledAttendances.ScheduledAttendees.Any()) { // sort so that it is Yes, then Pending, then Denied var scheduledPersonList = occurrenceScheduledAttendances .ScheduledAttendees .OrderBy(a => a.RSVP == RSVP.Yes ? 0 : 1) .ThenBy(a => (a.RSVP == RSVP.Maybe || a.RSVP == RSVP.Unknown) ? 0 : 1) .ThenBy(a => a.RSVP == RSVP.No ? 0 : 1) .ThenBy(a => a.ScheduledPerson.LastName) .ToList(); foreach (var scheduledPerson in scheduledPersonList) { ScheduledAttendanceItemStatus status = ScheduledAttendanceItemStatus.Pending; if (scheduledPerson.RSVP == RSVP.No) { status = ScheduledAttendanceItemStatus.Declined; } else if (scheduledPerson.ScheduledToAttend == true) { status = ScheduledAttendanceItemStatus.Confirmed; } sbScheduledListHtml.AppendLine(string.Format("<li class='slot person {0}' data-status='{0}'><i class='status-icon'></i><span class='person-name'>{1}</span></li>", status.ConvertToString(false).ToLower(), scheduledPerson.ScheduledPerson)); } scheduledCount = scheduledPersonList.Where(a => a.RSVP != RSVP.No).Count(); } if (capacities.DesiredCapacity.HasValue && scheduledCount < capacities.DesiredCapacity.Value) { var countNeeded = capacities.DesiredCapacity.Value - scheduledCount; sbScheduledListHtml.AppendLine(string.Format("<li class='slot persons-needed empty-slot'>{0} {1} needed</li>", countNeeded, "person".PluralizeIf(countNeeded != 1))); // add empty slots if we are under the desired count (not including the slot for the 'persons-needed' li) var emptySlotsToAdd = countNeeded - 1; while (emptySlotsToAdd > 0) { sbScheduledListHtml.AppendLine("<li class='slot empty-slot'></li>"); emptySlotsToAdd--; } } var scheduledLocationsStatusHtml = string.Format(scheduleLocationStatusHtmlFormat, sbScheduledListHtml, capacities.MinimumCapacity, capacities.DesiredCapacity, capacities.MaximumCapacity, scheduledCount); sbGroupLocations.AppendLine(string.Format("<td class='schedule-location js-schedule-location' data-schedule-id='{0}'><div>{1}</div></td>", scheduleOccurrenceDate.Schedule.Id, scheduledLocationsStatusHtml)); } sbGroupLocations.AppendLine("</tr>"); } sbGroupLocations.AppendLine("</tbody>"); sbTable.Append(sbGroupLocations.ToString()); } // closing divs for main header sbTable.AppendLine("</tr>"); sbTable.AppendLine("</thead>"); // closing divs for table sbTable.AppendLine("</table>"); lGroupStatusTableHTML.Text = sbTable.ToString(); }
/// <summary> /// Processes the NCOA results: Mark all family move addresses as previous, add the new address as current; and processed. /// If minMoveDistance is specified, mark the family as inactive if the family moved further than the specified distance. /// </summary> /// <param name="inactiveReason">The inactive reason.</param> /// <param name="minMoveDistance">The minimum move distance.</param> /// <param name="homeValueId">The home value identifier.</param> /// <param name="previousValueId">The previous value identifier.</param> private void ProcessNcoaResultsFamilyMove(DefinedValueCache inactiveReason, decimal?minMoveDistance, int?homeValueId, int?previousValueId) { List <int> ncoaIds = null; // Process 'Move' NCOA Types (The 'Family' move types will be processed first) using (var rockContext = new RockContext()) { ncoaIds = new NcoaHistoryService(rockContext) .Queryable().AsNoTracking() .Where(n => n.Processed == Processed.NotProcessed && n.NcoaType == NcoaType.Move && n.MoveType == MoveType.Family) .Select(n => n.Id) .ToList(); } foreach (int id in ncoaIds) { using (var rockContext = new RockContext()) { // Get the NCOA record and make sure it still hasn't been processed var ncoaHistory = new NcoaHistoryService(rockContext).Get(id); if (ncoaHistory != null && ncoaHistory.Processed == Processed.NotProcessed) { var ncoaHistoryService = new NcoaHistoryService(rockContext); var groupService = new GroupService(rockContext); var groupLocationService = new GroupLocationService(rockContext); var locationService = new LocationService(rockContext); var personService = new PersonService(rockContext); var familyChanges = new History.HistoryChangeList(); ncoaHistory.Processed = Processed.ManualUpdateRequired; // If we're able to mark the existing address as previous and successfully create a new home address.. var previousGroupLocation = MarkAsPreviousLocation(ncoaHistory, groupLocationService, previousValueId, familyChanges); if (previousGroupLocation != null) { if (AddNewHomeLocation(ncoaHistory, locationService, groupLocationService, homeValueId, familyChanges, previousGroupLocation.IsMailingLocation, previousGroupLocation.IsMappedLocation)) { // set the status to 'Complete' ncoaHistory.Processed = Processed.Complete; // Look for any other moves for the same family and to same address, and set their status to complete as well foreach (var ncoaIndividual in ncoaHistoryService .Queryable().Where(n => n.Processed == Processed.NotProcessed && n.NcoaType == NcoaType.Move && n.FamilyId == ncoaHistory.FamilyId && n.Id != ncoaHistory.Id && n.UpdatedStreet1 == ncoaHistory.UpdatedStreet1)) { ncoaIndividual.Processed = Processed.Complete; } // If there were any changes, write to history and check to see if person should be inactivated if (familyChanges.Any()) { var family = groupService.Get(ncoaHistory.FamilyId); if (family != null) { foreach (var fm in family.Members) { if (ncoaHistory.MoveDistance.HasValue && minMoveDistance.HasValue && ncoaHistory.MoveDistance.Value >= minMoveDistance.Value) { History.HistoryChangeList personChanges; personService.InactivatePerson(fm.Person, inactiveReason, $"Received a Change of Address (NCOA) notice that was for more than {minMoveDistance} miles away.", out personChanges); if (personChanges.Any()) { HistoryService.SaveChanges( rockContext, typeof(Person), SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(), fm.PersonId, personChanges, false); } } HistoryService.SaveChanges( rockContext, typeof(Person), SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), fm.PersonId, familyChanges, family.Name, typeof(Group), family.Id, false); } } } } } rockContext.SaveChanges(); } } } }
/// <summary> /// Updates GroupLocationHistorical for any group locations in groups that have data group history enabled /// </summary> /// <param name="context">The context.</param> public void UpdateGroupLocationHistorical(IJobExecutionContext context) { var rockContext = new RockContext(); var groupLocationHistoricalService = new GroupLocationHistoricalService(rockContext); var groupLocationService = new GroupLocationService(rockContext); var groupLocationsWithHistoryEnabledQuery = groupLocationService.Queryable().Where(a => a.Group.GroupType.EnableGroupHistory == true).AsNoTracking(); var groupLocationsHistoricalCurrentQuery = groupLocationHistoricalService.Queryable().Where(a => a.CurrentRowIndicator == true).AsNoTracking(); // Mark GroupLocationHistorical Rows as History ( CurrentRowIndicator = false, etc ) if any of the tracked field values change var groupLocationHistoricalNoLongerCurrentQuery = groupLocationsHistoricalCurrentQuery.Join( groupLocationsWithHistoryEnabledQuery, glh => glh.GroupLocationId, gl => gl.Id, (glh, gl) => new { GroupLocation = gl, GroupLocationHistorical = glh }) .Where(a => a.GroupLocation.GroupId != a.GroupLocationHistorical.GroupId || (a.GroupLocation.GroupLocationTypeValueId != a.GroupLocation.GroupLocationTypeValueId) || (a.GroupLocation.GroupLocationTypeValueId.HasValue && a.GroupLocation.GroupLocationTypeValue.Value != a.GroupLocationHistorical.GroupLocationTypeName) || a.GroupLocation.LocationId != a.GroupLocationHistorical.LocationId || a.GroupLocation.Location.ModifiedDateTime != a.GroupLocationHistorical.LocationModifiedDateTime || (a.GroupLocation.Schedules.Select(s => new { ScheduleId = s.Id, s.ModifiedDateTime }).Except(a.GroupLocationHistorical.GroupLocationHistoricalSchedules.Select(hs => new { hs.ScheduleId, ModifiedDateTime = hs.ScheduleModifiedDateTime }))).Any() ); var effectiveExpireDateTime = RockDateTime.Now; int groupLocationsLoggedToHistory = 0; int groupLocationsSaveToHistoryCurrent = 0; if (groupLocationHistoricalNoLongerCurrentQuery.Any()) { var groupLocationHistoricalNoLongerCurrent = groupLocationHistoricalNoLongerCurrentQuery.Select(a => a.GroupLocationHistorical).AsNoTracking(); groupLocationsLoggedToHistory = rockContext.BulkUpdate(groupLocationHistoricalNoLongerCurrent, glh => new GroupLocationHistorical { CurrentRowIndicator = false, ExpireDateTime = effectiveExpireDateTime }); } // Insert Group Locations (that have a group with GroupType.EnableGroupHistory) that don't have a CurrentRowIndicator row yet ( or don't have a CurrentRowIndicator because it was stamped with CurrentRowIndicator=false ) var groupLocationsToAddToHistoricalCurrentsQuery = groupLocationsWithHistoryEnabledQuery.Where(gl => !groupLocationsHistoricalCurrentQuery.Any(glh => glh.GroupLocationId == gl.Id)); if (groupLocationsToAddToHistoricalCurrentsQuery.Any()) { List <GroupLocationHistorical> groupLocationHistoricalCurrentsToInsert = groupLocationsToAddToHistoricalCurrentsQuery .Include(a => a.GroupLocationTypeValue) .Include(a => a.Location).ToList() .Select(gl => GroupLocationHistorical.CreateCurrentRowFromGroupLocation(gl, effectiveExpireDateTime)).ToList(); groupLocationsSaveToHistoryCurrent = groupLocationHistoricalCurrentsToInsert.Count(); // get the current max GroupLocatiionHistorical.Id to help narrow down which ones were inserted int groupLocationHistoricalStartId = groupLocationHistoricalService.Queryable().Max(a => ( int? )a.Id) ?? 0; rockContext.BulkInsert(groupLocationHistoricalCurrentsToInsert); // since we used BulkInsert, we'll need to go back and get the Ids and the associated GroupLocation's Schedules for the GroupLocationHistorical records that we just inserted var insertedGroupLocationHistoricalIdsWithSchedules = groupLocationHistoricalService.Queryable() .Where(a => a.Id > groupLocationHistoricalStartId && a.GroupLocation.Schedules.Any()).ToList() .Select(a => new { GroupLocationHistoricalId = a.Id, a.GroupLocation.Schedules }); List <GroupLocationHistoricalSchedule> groupLocationHistoricalScheduleCurrentsToInsert = new List <GroupLocationHistoricalSchedule>(); foreach (var insertedGroupLocationHistoricalIdWithSchedules in insertedGroupLocationHistoricalIdsWithSchedules) { foreach (Schedule schedule in insertedGroupLocationHistoricalIdWithSchedules.Schedules) { groupLocationHistoricalScheduleCurrentsToInsert.Add(new GroupLocationHistoricalSchedule { GroupLocationHistoricalId = insertedGroupLocationHistoricalIdWithSchedules.GroupLocationHistoricalId, ScheduleId = schedule.Id, ScheduleName = schedule.ToString(), ScheduleModifiedDateTime = schedule.ModifiedDateTime }); } } if (groupLocationHistoricalScheduleCurrentsToInsert.Any()) { rockContext.BulkInsert(groupLocationHistoricalScheduleCurrentsToInsert); } } if (groupLocationsLoggedToHistory > 0) { _jobStatusMessages.Add($"Logged {groupLocationsLoggedToHistory} {"group location history snapshot".PluralizeIf( groupLocationsLoggedToHistory != 0 )}"); } if (groupLocationsSaveToHistoryCurrent > 0) { int newGroupLocationsAddedToHistory = groupLocationsSaveToHistoryCurrent - groupLocationsLoggedToHistory; if (newGroupLocationsAddedToHistory > 0) { _jobStatusMessages.Add($"Added {newGroupLocationsAddedToHistory} new {"group location history snapshot".PluralizeIf( newGroupLocationsAddedToHistory != 0 )}"); } } }
/// <summary> /// Processes the NCOA results: Mark all individual move addresses as previous, add the new address as current; and processed. /// If minMoveDistance is specified, mark the individual as inactive if the individual moved further than the specified distance. /// </summary> /// <param name="inactiveReason">The inactive reason.</param> /// <param name="minMoveDistance">The minimum move distance.</param> /// <param name="homeValueId">The home value identifier.</param> /// <param name="previousValueId">The previous value identifier.</param> private void ProcessNcoaResultsIndividualMove(DefinedValueCache inactiveReason, decimal?minMoveDistance, int?homeValueId, int?previousValueId) { List <int> ncoaIds = null; // Process 'Move' NCOA Types (For the remaining Individual move types that weren't updated with the family move) using (var rockContext = new RockContext()) { ncoaIds = new NcoaHistoryService(rockContext) .Queryable().AsNoTracking() .Where(n => n.Processed == Processed.NotProcessed && n.NcoaType == NcoaType.Move && n.MoveType == MoveType.Individual) .Select(n => n.Id) .ToList(); } foreach (int id in ncoaIds) { using (var rockContext = new RockContext()) { // Get the NCOA record and make sure it still hasn't been processed var ncoaHistory = new NcoaHistoryService(rockContext).Get(id); if (ncoaHistory != null && ncoaHistory.Processed == Processed.NotProcessed) { var ncoaHistoryService = new NcoaHistoryService(rockContext); var groupMemberService = new GroupMemberService(rockContext); var personAliasService = new PersonAliasService(rockContext); var groupService = new GroupService(rockContext); var groupLocationService = new GroupLocationService(rockContext); var locationService = new LocationService(rockContext); var personService = new PersonService(rockContext); var changes = new History.HistoryChangeList(); // Default the status to requiring a manual update (we might change this though) ncoaHistory.Processed = Processed.ManualUpdateRequired; // Find the existing family var family = groupService.Get(ncoaHistory.FamilyId); // If there's only one person in the family if (family.Members.Count == 1) { // And that person is the same as the move record's person then we can process it. var personAlias = personAliasService.Get(ncoaHistory.PersonAliasId); var familyMember = family.Members.First(); if (personAlias != null && familyMember.PersonId == personAlias.PersonId) { // If were able to mark their existing address as previous and add a new updated Home address, // then set the status to complete (otherwise leave it as needing a manual update). var previousGroupLocation = MarkAsPreviousLocation(ncoaHistory, groupLocationService, previousValueId, changes); if (previousGroupLocation != null) { if (AddNewHomeLocation(ncoaHistory, locationService, groupLocationService, homeValueId, changes, previousGroupLocation.IsMailingLocation, previousGroupLocation.IsMappedLocation)) { ncoaHistory.Processed = Processed.Complete; // Look for any other moves for the same person to same address, and set their process to complete also foreach (var ncoaIndividual in ncoaHistoryService .Queryable().Where(n => n.Processed == Processed.NotProcessed && n.NcoaType == NcoaType.Move && n.MoveType == MoveType.Individual && n.PersonAliasId == ncoaHistory.PersonAliasId && n.Id != ncoaHistory.Id && n.UpdatedStreet1 == ncoaHistory.UpdatedStreet1)) { ncoaIndividual.Processed = Processed.Complete; } // If there were any changes, write to history and check to see if person should be inactivated if (changes.Any()) { if (ncoaHistory.MoveDistance.HasValue && minMoveDistance.HasValue && ncoaHistory.MoveDistance.Value >= minMoveDistance.Value) { History.HistoryChangeList personChanges; personService.InactivatePerson(familyMember.Person, inactiveReason, $"Received a Change of Address (NCOA) notice that was for more than {minMoveDistance} miles away.", out personChanges); if (personChanges.Any()) { HistoryService.SaveChanges( rockContext, typeof(Person), SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(), familyMember.PersonId, personChanges, false); } } HistoryService.SaveChanges( rockContext, typeof(Person), SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), familyMember.PersonId, changes, family.Name, typeof(Group), family.Id, false); } } } } } rockContext.SaveChanges(); } } } }
/// <summary> /// Handles the Click event of the lbSave 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 lbSave_Click(object sender, EventArgs e) { var rockContext = new RockContext(); var personService = new PersonService(rockContext); Person business = null; if (int.Parse(hfBusinessId.Value) != 0) { business = personService.Get(int.Parse(hfBusinessId.Value)); } if (business == null) { business = new Person(); personService.Add(business); tbBusinessName.Text = tbBusinessName.Text.FixCase(); } // Business Name business.LastName = tbBusinessName.Text; // Phone Number var businessPhoneTypeId = new DefinedValueService(rockContext).GetByGuid(new Guid(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_WORK)).Id; var phoneNumber = business.PhoneNumbers.FirstOrDefault(n => n.NumberTypeValueId == businessPhoneTypeId); if (!string.IsNullOrWhiteSpace(PhoneNumber.CleanNumber(pnbPhone.Number))) { if (phoneNumber == null) { phoneNumber = new PhoneNumber { NumberTypeValueId = businessPhoneTypeId }; business.PhoneNumbers.Add(phoneNumber); } phoneNumber.CountryCode = PhoneNumber.CleanNumber(pnbPhone.CountryCode); phoneNumber.Number = PhoneNumber.CleanNumber(pnbPhone.Number); phoneNumber.IsMessagingEnabled = cbSms.Checked; phoneNumber.IsUnlisted = cbUnlisted.Checked; } else { if (phoneNumber != null) { business.PhoneNumbers.Remove(phoneNumber); new PhoneNumberService(rockContext).Delete(phoneNumber); } } // Record Type - this is always "business". it will never change. business.RecordTypeValueId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_BUSINESS.AsGuid()).Id; // Record Status business.RecordStatusValueId = dvpRecordStatus.SelectedValueAsInt();; // Record Status Reason int?newRecordStatusReasonId = null; if (business.RecordStatusValueId.HasValue && business.RecordStatusValueId.Value == DefinedValueCache.Get(new Guid(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE)).Id) { newRecordStatusReasonId = dvpReason.SelectedValueAsInt(); } business.RecordStatusReasonValueId = newRecordStatusReasonId; // Email business.IsEmailActive = true; business.Email = tbEmail.Text.Trim(); business.EmailPreference = rblEmailPreference.SelectedValue.ConvertToEnum <EmailPreference>(); if (!business.IsValid) { // Controls will render the error messages return; } rockContext.WrapTransaction(() => { rockContext.SaveChanges(); // Add/Update Family Group var familyGroupType = GroupTypeCache.GetFamilyGroupType(); int adultRoleId = familyGroupType.Roles .Where(r => r.Guid.Equals(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid())) .Select(r => r.Id) .FirstOrDefault(); var adultFamilyMember = UpdateGroupMember(business.Id, familyGroupType, business.LastName + " Business", ddlCampus.SelectedValueAsInt(), adultRoleId, rockContext); business.GivingGroup = adultFamilyMember.Group; // Add/Update Known Relationship Group Type var knownRelationshipGroupType = GroupTypeCache.Get(Rock.SystemGuid.GroupType.GROUPTYPE_KNOWN_RELATIONSHIPS.AsGuid()); int knownRelationshipOwnerRoleId = knownRelationshipGroupType.Roles .Where(r => r.Guid.Equals(Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER.AsGuid())) .Select(r => r.Id) .FirstOrDefault(); var knownRelationshipOwner = UpdateGroupMember(business.Id, knownRelationshipGroupType, "Known Relationship", null, knownRelationshipOwnerRoleId, rockContext); // Add/Update Implied Relationship Group Type var impliedRelationshipGroupType = GroupTypeCache.Get(Rock.SystemGuid.GroupType.GROUPTYPE_PEER_NETWORK.AsGuid()); int impliedRelationshipOwnerRoleId = impliedRelationshipGroupType.Roles .Where(r => r.Guid.Equals(Rock.SystemGuid.GroupRole.GROUPROLE_PEER_NETWORK_OWNER.AsGuid())) .Select(r => r.Id) .FirstOrDefault(); var impliedRelationshipOwner = UpdateGroupMember(business.Id, impliedRelationshipGroupType, "Implied Relationship", null, impliedRelationshipOwnerRoleId, rockContext); rockContext.SaveChanges(); // Location int workLocationTypeId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_WORK).Id; var groupLocationService = new GroupLocationService(rockContext); var workLocation = groupLocationService.Queryable("Location") .Where(gl => gl.GroupId == adultFamilyMember.Group.Id && gl.GroupLocationTypeValueId == workLocationTypeId) .FirstOrDefault(); if (string.IsNullOrWhiteSpace(acAddress.Street1)) { if (workLocation != null) { groupLocationService.Delete(workLocation); } } else { var newLocation = new LocationService(rockContext).Get( acAddress.Street1, acAddress.Street2, acAddress.City, acAddress.State, acAddress.PostalCode, acAddress.Country); if (workLocation == null) { workLocation = new GroupLocation(); groupLocationService.Add(workLocation); workLocation.GroupId = adultFamilyMember.Group.Id; workLocation.GroupLocationTypeValueId = workLocationTypeId; } workLocation.Location = newLocation; workLocation.IsMailingLocation = true; } rockContext.SaveChanges(); hfBusinessId.Value = business.Id.ToString(); }); var queryParams = new Dictionary <string, string>(); queryParams.Add("businessId", hfBusinessId.Value); NavigateToCurrentPage(queryParams); }
/// <summary> /// Adds the new home location. /// </summary> /// <param name="ncoaHistory">The NCOA history.</param> /// <param name="locationService">The location service.</param> /// <param name="groupLocationService">The group location service.</param> /// <param name="homeValueId">The home value identifier.</param> /// <param name="changes">The changes.</param> /// <param name="isMailingLocation">Is the location a mailing location.</param> /// <param name="isMappedLocation">Is the location a mapped location.</param> /// <returns></returns> private bool AddNewHomeLocation(NcoaHistory ncoaHistory, LocationService locationService, GroupLocationService groupLocationService, int?homeValueId, History.HistoryChangeList changes, bool isMailingLocation, bool isMappedLocation) { if (homeValueId.HasValue) { var location = locationService.Get( ncoaHistory.UpdatedStreet1, ncoaHistory.UpdatedStreet2, ncoaHistory.UpdatedCity, ncoaHistory.UpdatedState, ncoaHistory.UpdatedPostalCode, ncoaHistory.UpdatedCountry); var groupLocation = new GroupLocation(); groupLocation.Location = location; groupLocation.IsMailingLocation = isMailingLocation; groupLocation.IsMappedLocation = isMappedLocation; groupLocation.GroupId = ncoaHistory.FamilyId; groupLocation.GroupLocationTypeValueId = homeValueId.Value; groupLocation.IsMailingLocation = true; groupLocationService.Add(groupLocation); changes.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Property, "Location").SetNewValue(groupLocation.Location.ToString()).SourceOfChange = "NCOA Request"; return(true); } return(false); }
/// <summary> /// Creates the person. /// </summary> /// <returns></returns> private Person CreatePerson() { var rockContext = new RockContext(); DefinedValueCache dvcConnectionStatus = DefinedValueCache.Read(GetAttributeValue("ConnectionStatus").AsGuid()); DefinedValueCache dvcRecordStatus = DefinedValueCache.Read(GetAttributeValue("RecordStatus").AsGuid()); Person person = new Person(); person.FirstName = tbFirstName.Text; person.LastName = tbLastName.Text; person.Email = tbEmail.Text; person.IsEmailActive = true; person.EmailPreference = EmailPreference.EmailAllowed; person.RecordTypeValueId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()).Id; if (dvcConnectionStatus != null) { person.ConnectionStatusValueId = dvcConnectionStatus.Id; } if (dvcRecordStatus != null) { person.RecordStatusValueId = dvcRecordStatus.Id; } switch (ddlGender.SelectedValue) { case "M": person.Gender = Gender.Male; break; case "F": person.Gender = Gender.Female; break; default: person.Gender = Gender.Unknown; break; } var birthday = bdaypBirthDay.SelectedDate; if (birthday.HasValue) { person.BirthMonth = birthday.Value.Month; person.BirthDay = birthday.Value.Day; if (birthday.Value.Year != DateTime.MinValue.Year) { person.BirthYear = birthday.Value.Year; } } bool smsSelected = false; foreach (RepeaterItem item in rPhoneNumbers.Items) { HiddenField hfPhoneType = item.FindControl("hfPhoneType") as HiddenField; PhoneNumberBox pnbPhone = item.FindControl("pnbPhone") as PhoneNumberBox; CheckBox cbUnlisted = item.FindControl("cbUnlisted") as CheckBox; CheckBox cbSms = item.FindControl("cbSms") as CheckBox; if (!string.IsNullOrWhiteSpace(PhoneNumber.CleanNumber(pnbPhone.Number))) { int phoneNumberTypeId; if (int.TryParse(hfPhoneType.Value, out phoneNumberTypeId)) { var phoneNumber = new PhoneNumber { NumberTypeValueId = phoneNumberTypeId }; person.PhoneNumbers.Add(phoneNumber); phoneNumber.CountryCode = PhoneNumber.CleanNumber(pnbPhone.CountryCode); phoneNumber.Number = PhoneNumber.CleanNumber(pnbPhone.Number); // Only allow one number to have SMS selected if (smsSelected) { phoneNumber.IsMessagingEnabled = false; } else { phoneNumber.IsMessagingEnabled = cbSms.Checked; smsSelected = cbSms.Checked; } phoneNumber.IsUnlisted = cbUnlisted.Checked; } } } PersonService.SaveNewPerson(person, rockContext, null, false); // save address if (pnlAddress.Visible) { if (acAddress.IsValid && !string.IsNullOrWhiteSpace(acAddress.Street1) && !string.IsNullOrWhiteSpace(acAddress.City) && !string.IsNullOrWhiteSpace(acAddress.PostalCode)) { Guid locationTypeGuid = GetAttributeValue("LocationType").AsGuid(); if (locationTypeGuid != Guid.Empty) { Guid familyGroupTypeGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid(); GroupService groupService = new GroupService(rockContext); GroupLocationService groupLocationService = new GroupLocationService(rockContext); var family = groupService.Queryable().Where(g => g.GroupType.Guid == familyGroupTypeGuid && g.Members.Any(m => m.PersonId == person.Id)).FirstOrDefault(); var groupLocation = new GroupLocation(); groupLocation.GroupId = family.Id; groupLocationService.Add(groupLocation); var location = new LocationService(rockContext).Get(acAddress.Street1, acAddress.Street2, acAddress.City, acAddress.State, acAddress.PostalCode, acAddress.Country); groupLocation.Location = location; groupLocation.GroupLocationTypeValueId = DefinedValueCache.Read(locationTypeGuid).Id; groupLocation.IsMailingLocation = true; groupLocation.IsMappedLocation = true; rockContext.SaveChanges(); } } } return(person); }
/// <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) { 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 (familyAddress.LocationIsDirty) { groupLocation.Location = new LocationService().Get( familyAddress.Street1, familyAddress.Street2, familyAddress.City, familyAddress.State, familyAddress.Zip); } 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> /// Creates a Linq Expression that can be applied to an IQueryable to filter the result set. /// </summary> /// <param name="entityType">The type of entity in the result set.</param> /// <param name="serviceInstance">A service instance that can be queried to obtain the result set.</param> /// <param name="parameterExpression">The input parameter that will be injected into the filter expression.</param> /// <param name="selection">A formatted string representing the filter settings.</param> /// <returns> /// A Linq Expression that can be used to filter an IQueryable. /// </returns> /// <exception cref="System.Exception">Filter issue(s): + errorMessages.AsDelimited( ; )</exception> public override Expression GetExpression(Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection) { var settings = new FilterSettings(selection); var context = ( RockContext )serviceInstance.Context; var locationService = new LocationService(context); var locationQuery = locationService.Queryable(); if (locationQuery != null) { if (!string.IsNullOrWhiteSpace(settings.Street1)) { locationQuery = locationQuery.Where(l => l.Street1.Contains(settings.Street1)); } if (!string.IsNullOrWhiteSpace(settings.City)) { locationQuery = locationQuery.Where(l => l.City == settings.City); } if (!string.IsNullOrWhiteSpace(settings.State)) { locationQuery = locationQuery.Where(l => l.State == settings.State); } if (!string.IsNullOrWhiteSpace(settings.PostalCode)) { locationQuery = locationQuery.Where(l => l.PostalCode.StartsWith(settings.PostalCode)); } if (!string.IsNullOrWhiteSpace(settings.Country)) { locationQuery = locationQuery.Where(l => l.Country == settings.Country); } } // Get all the Family Groups that have a Location matching one of the candidate Locations. int familyGroupTypeId = GroupTypeCache.Get(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid()).Id; var groupLocationsQuery = new GroupLocationService(context).Queryable() .Where(gl => gl.Group.GroupTypeId == familyGroupTypeId && locationQuery.Any(l => l.Id == gl.LocationId)); // If a Location Type is specified, apply the filter condition. if (settings.LocationTypeGuid.HasValue) { int groupLocationTypeId = DefinedValueCache.Get(settings.LocationTypeGuid.Value).Id; groupLocationsQuery = groupLocationsQuery.Where(x => x.GroupLocationTypeValue.Id == groupLocationTypeId); } // Get all of the Group Members of the qualifying Families. var groupMemberServiceQry = new GroupMemberService(context).Queryable() .Where(gm => groupLocationsQuery.Any(gl => gl.GroupId == gm.GroupId)); // Get all of the People corresponding to the qualifying Group Members. var qry = new PersonService(context).Queryable() .Where(p => groupMemberServiceQry.Any(gm => gm.PersonId == p.Id)); // Retrieve the Filter Expression. var extractedFilterExpression = FilterExpressionExtractor.Extract <Rock.Model.Person>(qry, parameterExpression, "p"); return(extractedFilterExpression); }
protected void btnSave_Click(object sender, EventArgs e) { if (lopAddress.Location == null || string.IsNullOrWhiteSpace(lopAddress.Location.Street1) || string.IsNullOrWhiteSpace(lopAddress.Location.PostalCode)) { nbValidation.Visible = true; ScriptManager.RegisterStartupScript(Page, this.GetType(), "ScrollPage", "setTimeout(function(){window.scroll(0,0);},200)", true); return; } else { nbValidation.Visible = false; } if (_group == null) { ShowMessage("There was an issue with the viewstate. Please reload and try again. If the problem perssits contact an administrator.", "Error", "panel panel-danger"); return; } GroupService groupService = new GroupService(_rockContext); //Add basic information Group group; if (_group.Id == 0) { group = new Group() { GroupTypeId = _groupType.Id }; var destinationGroup = groupService.Get(GetAttributeValue("DestinationGroup").AsGuid()); if (destinationGroup != null) { group.ParentGroupId = destinationGroup.Id; } var parentMapping = GetAttributeValue("CampusGroupMap").ToKeyValuePairList(); foreach (var pair in parentMapping) { if (pair.Key.AsInteger() == cpCampus.SelectedValueAsId()) { group.ParentGroupId = (( string )pair.Value).AsInteger(); } } var zip = "No Zip"; if (lopAddress.Location != null && !string.IsNullOrWhiteSpace(lopAddress.Location.PostalCode)) { zip = lopAddress.Location.PostalCode; } group.Name = string.Format("{0} - {1}", tbName.Text, zip); groupService.Add(group); group.CreatedByPersonAliasId = _person.PrimaryAliasId; group.IsActive = true; } else { group = groupService.Get(_group.Id); group.IsActive = true; } group.CampusId = cpCampus.SelectedValueAsId(); group.Description = tbDescription.Text; //Set location if (lopAddress.Location != null && lopAddress.Location.Id != 0) { if (group.GroupLocations != null && !group.GroupLocations.Select(gl => gl.LocationId).Contains(lopAddress.Location.Id)) { // Disassociate the old address(es) GroupLocationService groupLocationService = new GroupLocationService(_rockContext); var meetingLocationDv = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_MEETING_LOCATION); var homeLocationDv = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME); groupLocationService.DeleteRange(group.GroupLocations.Where(gl => gl.GroupLocationTypeValueId == meetingLocationDv.Id || gl.GroupLocationTypeValueId == homeLocationDv.Id || gl.GroupLocationTypeValueId == null)); group.GroupLocations.Add(new GroupLocation() { LocationId = lopAddress.Location.Id, GroupLocationTypeValueId = meetingLocationDv.Id }); } } //Set Schedule if (_groupType.AllowedScheduleTypes != ScheduleType.None) { switch (rblSchedule.SelectedValueAsEnum <ScheduleType>()) { case ScheduleType.None: group.ScheduleId = null; break; case ScheduleType.Weekly: var weeklySchedule = new Schedule() { WeeklyDayOfWeek = dowWeekly.SelectedDayOfWeek, WeeklyTimeOfDay = timeWeekly.SelectedTime }; group.Schedule = weeklySchedule; break; case ScheduleType.Custom: var customSchedule = new Schedule() { iCalendarContent = sbSchedule.iCalendarContent }; group.Schedule = customSchedule; break; case ScheduleType.Named: if (spSchedule.SelectedValue.AsInteger() != 0) { group.ScheduleId = spSchedule.SelectedValue.AsInteger(); } break; default: break; } } if (group.Members != null && group.Members.Any()) { foreach (var member in group.Members.Where(gm => gm.PersonId != _person.Id)) { member.GroupMemberStatus = GroupMemberStatus.Inactive; } foreach (int groupMemberId in gMembers.SelectedKeys) { var groupMember = group.Members.Where(m => m.Id == groupMemberId).FirstOrDefault(); if (groupMember != null) { groupMember.GroupMemberStatus = GroupMemberStatus.Active; } } } else { var groupRoleId = new GroupTypeRoleService(_rockContext).Get(GetAttributeValue("GroupRole").AsGuid()).Id; group.Members.Add(new GroupMember() { PersonId = _person.Id, GroupRoleId = groupRoleId }); } //Save attributes _rockContext.SaveChanges(); group.LoadAttributes(); Rock.Attribute.Helper.GetEditValues(phAttributes, group); var attributeGuid = GetAttributeValue("MultiSelectAttribute"); var multiselectAttribute = new AttributeService(_rockContext).Get(attributeGuid.AsGuid()); if (multiselectAttribute != null) { var attributeValue = group.GetAttributeValue(multiselectAttribute.Key) .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .ToList(); var newAttributeText = GetAttributeValue("AttributeText"); if (!attributeValue.Contains(newAttributeText)) { attributeValue.Add(newAttributeText); } group.SetAttributeValue(multiselectAttribute.Key, string.Join(",", attributeValue)); } group.SaveAttributeValues(); //Update cache var availableGroupIds = (List <int>)GetCacheItem(GetAttributeValue("DestinationGroup")); if (availableGroupIds != null) { availableGroupIds.Add(group.Id); AddCacheItem(GetAttributeValue("DestinationGroup"), availableGroupIds); } var workflowTypeService = new WorkflowTypeService(_rockContext); WorkflowType workflowType = null; Guid? workflowTypeGuid = GetAttributeValue("Workflow").AsGuidOrNull(); if (workflowTypeGuid.HasValue) { workflowType = workflowTypeService.Get(workflowTypeGuid.Value); } GroupMember currentGroupMember = group.Members.Where(gm => gm.PersonId == _person.Id).FirstOrDefault(); if (currentGroupMember != null && workflowType != null && (workflowType.IsActive ?? true)) { try { List <string> workflowErrors; var workflow = Workflow.Activate(workflowType, _person.FullName); if (workflow.AttributeValues.ContainsKey("Group")) { if (group != null) { workflow.AttributeValues["Group"].Value = group.Guid.ToString(); } } if (workflow.AttributeValues.ContainsKey("Person")) { if (_person != null) { workflow.AttributeValues["Person"].Value = _person.PrimaryAlias.Guid.ToString(); } } new WorkflowService(_rockContext).Process(workflow, currentGroupMember, out workflowErrors); } catch (Exception ex) { ExceptionLogService.LogException(ex, this.Context); } } ShowMessage(GetAttributeValue("SuccessText"), "Thank you!", "panel panel-success"); }
/// <summary> /// Shows the details. /// </summary> private void ShowDetails() { RockContext rockContext = new RockContext(); pnlAddress.Visible = GetAttributeValue("ShowAddress").AsBoolean(); acAddress.Required = GetAttributeValue("AddressRequired").AsBoolean(); var person = CurrentPerson; if (person != null) { imgPhoto.BinaryFileId = person.PhotoId; imgPhoto.NoPictureUrl = Person.GetPersonNoPictureUrl(person, 200, 200); dvpTitle.SelectedValue = person.TitleValueId.HasValue ? person.TitleValueId.Value.ToString() : string.Empty; tbFirstName.Text = person.FirstName; tbNickName.Text = person.NickName; tbLastName.Text = person.LastName; dvpSuffix.SelectedValue = person.SuffixValueId.HasValue ? person.SuffixValueId.Value.ToString() : string.Empty; bpBirthDay.SelectedDate = person.BirthDate; rblGender.SelectedValue = person.Gender.ConvertToString(); tbEmail.Text = person.Email; rblEmailPreference.SelectedValue = person.EmailPreference.ConvertToString(false); Guid?locationTypeGuid = GetAttributeValue("LocationType").AsGuidOrNull(); if (locationTypeGuid.HasValue) { var addressTypeDv = DefinedValueCache.Get(locationTypeGuid.Value); // if address type is home enable the move and is mailing/physical if (addressTypeDv.Guid == Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME.AsGuid()) { lbMoved.Visible = true; cbIsMailingAddress.Visible = true; cbIsPhysicalAddress.Visible = true; } else { lbMoved.Visible = false; cbIsMailingAddress.Visible = false; cbIsPhysicalAddress.Visible = false; } lAddressTitle.Text = addressTypeDv.Value + " Address"; var familyGroupTypeGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuidOrNull(); if (familyGroupTypeGuid.HasValue) { var familyGroupType = GroupTypeCache.Get(familyGroupTypeGuid.Value); var familyAddress = new GroupLocationService(rockContext).Queryable() .Where(l => l.Group.GroupTypeId == familyGroupType.Id && l.GroupLocationTypeValueId == addressTypeDv.Id && l.Group.Members.Any(m => m.PersonId == person.Id)) .FirstOrDefault(); if (familyAddress != null) { acAddress.SetValues(familyAddress.Location); cbIsMailingAddress.Checked = familyAddress.IsMailingLocation; cbIsPhysicalAddress.Checked = familyAddress.IsMappedLocation; } } } var mobilePhoneType = DefinedValueCache.Get(new Guid(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE)); var phoneNumbers = new List <PhoneNumber>(); var phoneNumberTypes = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.PERSON_PHONE_TYPE)); if (phoneNumberTypes.DefinedValues.Any()) { foreach (var phoneNumberType in phoneNumberTypes.DefinedValues) { var phoneNumber = person.PhoneNumbers.FirstOrDefault(n => n.NumberTypeValueId == phoneNumberType.Id); if (phoneNumber == null) { var numberType = new DefinedValue(); numberType.Id = phoneNumberType.Id; numberType.Value = phoneNumberType.Value; phoneNumber = new PhoneNumber { NumberTypeValueId = numberType.Id, NumberTypeValue = numberType }; phoneNumber.IsMessagingEnabled = mobilePhoneType != null && phoneNumberType.Id == mobilePhoneType.Id; } else { // Update number format, just in case it wasn't saved correctly phoneNumber.NumberFormatted = PhoneNumber.FormattedNumber(phoneNumber.CountryCode, phoneNumber.Number); } phoneNumbers.Add(phoneNumber); } rContactInfo.DataSource = phoneNumbers; rContactInfo.DataBind(); } } }
/// <summary> /// Gets a list of available schedules for the group the selected sign-up person belongs to. /// </summary> /// <param name="groupGuid"></param> /// <returns></returns> private PersonScheduleSignupBag GetScheduleSignupData(Guid groupGuid) { List <PersonScheduleSignupDataBag> personScheduleSignups = new List <PersonScheduleSignupDataBag>(); int numOfWeeks = FutureWeeksToShow; var startDate = RockDateTime.Now.AddDays(1).Date; var endDate = RockDateTime.Now.AddDays(numOfWeeks * 7); using (var rockContext = new RockContext()) { var scheduleService = new ScheduleService(rockContext); var attendanceService = new AttendanceService(rockContext); var groupLocationService = new GroupLocationService(rockContext); var groupService = new GroupService(rockContext); var personScheduleExclusionService = new PersonScheduleExclusionService(rockContext); var group = groupService.Get(groupGuid); var personGroupLocationList = GetApplicableGroupLocations(group, groupLocationService); var groupsThatHaveSchedulingRequirements = personGroupLocationList.Where(a => a.Group.SchedulingMustMeetRequirements).Select(a => a.Group).Distinct().ToList(); var personDoesntMeetSchedulingRequirementGroupIds = new HashSet <int>(); // If the person does not meet the scheduling requirements for the current group. var personDoesntMeetSchedulingRequirements = groupService.GroupMembersNotMeetingRequirements(group, false, false) .Where(a => a.Key.PersonId == CurrentPersonId) .Any(); if (personDoesntMeetSchedulingRequirements) { personDoesntMeetSchedulingRequirementGroupIds.Add(group.Id); } // For every location in the location list. foreach (var personGroupLocation in personGroupLocationList) { // Loop through each particular scheduling opportunity foreach (var schedule in personGroupLocation.Schedules) { // Find if this has max volunteers here. int maximumCapacitySetting = 0; int desiredCapacitySetting = 0; int minimumCapacitySetting = 0; int desiredOrMinimumNeeded = 0; if (personGroupLocation.GroupLocationScheduleConfigs.Any()) { var groupConfigs = personGroupLocationList.Where(x => x.GroupId == personGroupLocation.GroupId).Select(x => x.GroupLocationScheduleConfigs); foreach (var groupConfig in groupConfigs) { foreach (var config in groupConfig) { if (config.ScheduleId == schedule.Id) { maximumCapacitySetting += config.MaximumCapacity ?? 0; desiredCapacitySetting += config.DesiredCapacity ?? 0; minimumCapacitySetting += config.MinimumCapacity ?? 0; } } } desiredOrMinimumNeeded = Math.Max(desiredCapacitySetting, minimumCapacitySetting); } var startDateTimeList = schedule.GetScheduledStartTimes(startDate, endDate); // For every start date time in the schedule, loop through to check if it is applicable to the current person. If so, we can add it to the master list. foreach (var startDateTime in startDateTimeList) { var occurrenceDate = startDateTime.Date; bool alreadyScheduled = attendanceService.IsScheduled(occurrenceDate, schedule.Id, CurrentPersonId); if (alreadyScheduled) { continue; } // Don't show dates they have blacked out. if (personScheduleExclusionService.IsExclusionDate(RequestContext.CurrentPerson.PrimaryAlias.PersonId, personGroupLocation.GroupId, occurrenceDate)) { continue; } // Don't show groups that have scheduling requirements that the person hasn't met. if (personDoesntMeetSchedulingRequirementGroupIds.Contains(personGroupLocation.GroupId)) { continue; } // Get count of scheduled Occurrences with RSVP "Yes" for the group/schedule. int currentScheduled = attendanceService .Queryable() .Where(a => a.Occurrence.OccurrenceDate == startDateTime.Date && a.Occurrence.ScheduleId == schedule.Id && a.RSVP == RSVP.Yes && a.Occurrence.GroupId == personGroupLocation.GroupId) .Count(); bool maxScheduled = maximumCapacitySetting != 0 && currentScheduled >= maximumCapacitySetting; int peopleNeeded = desiredOrMinimumNeeded != 0 ? desiredOrMinimumNeeded - currentScheduled : 0; // Add to master list personScheduleSignups. personScheduleSignups.Add(new PersonScheduleSignupDataBag { GroupGuid = personGroupLocation.Group.Guid, GroupOrder = personGroupLocation.Group.Order, GroupName = personGroupLocation.Group.Name, LocationGuid = personGroupLocation.Location.Guid, LocationName = personGroupLocation.Location.Name, LocationOrder = personGroupLocation.Order, ScheduleGuid = schedule.Guid, ScheduleName = schedule.Name, ScheduledDateTime = startDateTime.ToRockDateTimeOffset(), MaxScheduled = maxScheduled, PeopleNeeded = peopleNeeded < 0 ? 0 : peopleNeeded }); } } } return(new PersonScheduleSignupBag { GroupName = group.Name, PersonScheduleSignups = personScheduleSignups }); } }