private static void CreatePersonWithPrimaryEmailButDifferentName() { var rockContext = new RockContext(); var personService = new PersonService(rockContext); var person = personService.Get(PersonGuid.PersonWithPrimaryEmailButDifferentNameGuid); if (person != null) { new PersonAliasService(rockContext).DeleteRange(person.Aliases); new PersonSearchKeyService(rockContext).DeleteRange(person.GetPersonSearchKeys(rockContext).ToList()); personService.Delete(person); rockContext.SaveChanges(); } person = new Person() { RecordTypeValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()), FirstName = "I Have A", LastName = "DifferentLastName", Guid = PersonGuid.PersonWithPrimaryEmailButDifferentNameGuid, Email = Email.PrimaryEmail }; Group newPersonFamily = PersonService.SaveNewPerson(person, rockContext); rockContext.SaveChanges(); }
/// <summary> /// Handles the RowDataBound event of the gDevice control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="GridViewRowEventArgs"/> instance containing the event data.</param> protected void gDevice_RowDataBound(object sender, GridViewRowEventArgs e) { DeviceInfo device = e.Row.DataItem as DeviceInfo; if (device == null) { return; } var deviceTypeValueIdKiosk = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.DEVICE_TYPE_CHECKIN_KIOSK.AsGuid()); if (device.DeviceTypeValueId != deviceTypeValueIdKiosk) { // Print settings only apply to Checkin Kiosks, so if this isn't a Check-in Kiosk, don't populate the Printer settings columns return; } var lPrintToOverride = e.Row.FindControl("lPrintToOverride") as Literal; var lPrintFrom = e.Row.FindControl("lPrintFrom") as Literal; var lPrinterDeviceName = e.Row.FindControl("lPrinterDeviceName") as Literal; lPrintToOverride.Text = device.PrintToOverride.ConvertToString(); lPrintFrom.Text = device.PrintFrom.ConvertToString(); lPrinterDeviceName.Text = device.PrinterDeviceName; }
/// <summary> /// Sets the status. /// </summary> /// <param name="scheduledTransaction">The scheduled transaction.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public bool GetStatus(FinancialScheduledTransaction scheduledTransaction, out string errorMessages) { if (scheduledTransaction != null && scheduledTransaction.FinancialGateway != null && scheduledTransaction.FinancialGateway.IsActive) { var rockContext = this.Context as RockContext; if (scheduledTransaction.FinancialGateway.Attributes == null) { scheduledTransaction.FinancialGateway.LoadAttributes(rockContext); } var gateway = scheduledTransaction.FinancialGateway.GetGatewayComponent(); if (gateway != null) { var result = gateway.GetScheduledPaymentStatus(scheduledTransaction, out errorMessages); var scheduledTransactionId = scheduledTransaction.Id; var lastTransactionDate = new FinancialTransactionService(rockContext).Queryable().Where(a => a.ScheduledTransactionId.HasValue && a.ScheduledTransactionId == scheduledTransactionId && a.TransactionDateTime.HasValue).Max(t => ( DateTime? )t.TransactionDateTime.Value); scheduledTransaction.NextPaymentDate = gateway.GetNextPaymentDate(scheduledTransaction, lastTransactionDate); if (scheduledTransaction.TransactionFrequencyValueId == DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME.AsGuid())) { if (!scheduledTransaction.NextPaymentDate.HasValue || scheduledTransaction.NextPaymentDate < RockDateTime.Now) { scheduledTransaction.IsActive = false; } } return(result); } } errorMessages = "Gateway is invalid or not active"; return(false); }
/// <summary> /// Adds the scheduled payment. /// </summary> /// <param name="financialGateway">The financial gateway.</param> /// <param name="schedule">The schedule.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override FinancialScheduledTransaction AddScheduledPayment(FinancialGateway financialGateway, PaymentSchedule schedule, PaymentInfo paymentInfo, out string errorMessage) { errorMessage = string.Empty; if (ValidateCard(financialGateway, paymentInfo, out errorMessage)) { var scheduledTransaction = new FinancialScheduledTransaction(); scheduledTransaction.IsActive = true; scheduledTransaction.StartDate = schedule.StartDate; scheduledTransaction.NextPaymentDate = schedule.StartDate; scheduledTransaction.TransactionCode = "T" + RockDateTime.Now.ToString("yyyyMMddHHmmssFFF"); scheduledTransaction.GatewayScheduleId = "Subscription_" + RockDateTime.Now.ToString("yyyyMMddHHmmssFFF"); scheduledTransaction.LastStatusUpdateDateTime = RockDateTime.Now; scheduledTransaction.Status = FinancialScheduledTransactionStatus.Active; scheduledTransaction.StatusMessage = "active"; scheduledTransaction.FinancialPaymentDetail = new FinancialPaymentDetail() { ExpirationMonth = (paymentInfo as ReferencePaymentInfo)?.PaymentExpirationDate?.Month, ExpirationYear = (paymentInfo as ReferencePaymentInfo)?.PaymentExpirationDate?.Year, CurrencyTypeValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD.AsGuid()), AccountNumberMasked = paymentInfo.MaskedNumber, CreditCardTypeValueId = CreditCardPaymentInfo.GetCreditCardTypeFromCreditCardNumber(paymentInfo.MaskedNumber)?.Id ?? DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.CREDITCARD_TYPE_VISA.AsGuid()) }; return(scheduledTransaction); } return(null); }
private static void CreatePersonWithPrimaryEmailAndProtectionProfile(Guid guid, string email, AccountProtectionProfile accountProtectionProfile) { var rockContext = new RockContext(); var personService = new PersonService(rockContext); var person = personService.Get(guid); if (person != null) { person.AccountProtectionProfile = accountProtectionProfile; new PersonAliasService(rockContext).DeleteRange(person.Aliases); new PersonSearchKeyService(rockContext).DeleteRange(person.GetPersonSearchKeys(rockContext).ToList()); personService.Delete(person); rockContext.SaveChanges(); } person = new Person() { RecordTypeValueId = DefinedValueCache.GetId(SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()), FirstName = "I Have A", LastName = "CommonLastName", Guid = guid, Email = email, AccountProtectionProfile = accountProtectionProfile }; PersonService.SaveNewPerson(person, rockContext); }
private static AttendanceCache LoadByAttendance(Attendance attendance) { //We don't want to cache attendances created before today. if (!attendance.CreatedDateTime.HasValue || attendance.CreatedDateTime < Rock.RockDateTime.Today) { Remove(attendance.Id); return(null); } var attendanceCache = new AttendanceCache { Id = attendance.Id, OccurrenceAccessKey = OccurrenceCache.GetByOccurrence(attendance.Occurrence)?.AccessKey ?? "None", Code = attendance.AttendanceCode?.Code, CreatedDateTime = attendance.CreatedDateTime, StartDateTime = attendance.StartDateTime, EndDateTime = attendance.EndDateTime, PersonId = attendance.PersonAlias.PersonId, PersonName = attendance.PersonAlias.Person.FullName, GroupId = attendance.Occurrence.GroupId, LocationId = attendance.Occurrence.LocationId, ScheduleId = attendance.Occurrence.ScheduleId, IsVolunteer = OccurrenceCache.GetVolunteerOccurrences().Select(o => o.GroupId).Contains(attendance.Occurrence.GroupId ?? 0), IsChildren = OccurrenceCache.GetChildrenOccurrences().Select(o => o.GroupId).Contains(attendance.Occurrence.GroupId ?? 0), WithParent = false }; if (attendance.EndDateTime.HasValue) //End date means checked out { attendanceCache.AttendanceState = AttendanceState.CheckedOut; } else //has not been checked out yet { if (attendance.DidAttend == false && attendance.QualifierValueId.HasValue) { attendanceCache.AttendanceState = AttendanceState.MobileReserve; } else if (attendance.DidAttend == true) { attendanceCache.AttendanceState = AttendanceState.InRoom; if (attendance.QualifierValueId == DefinedValueCache.GetId(Constants.DEFINED_VALUE_ATTENDANCE_STATUS_WITH_PARENT.AsGuid())) { attendanceCache.WithParent = true; } } else { attendanceCache.AttendanceState = AttendanceState.EnRoute; } } return(attendanceCache); }
/// <summary> /// Gets the list source. /// </summary> /// <value> /// The list source. /// </value> internal override Dictionary <string, string> GetListSource(Dictionary <string, ConfigurationValue> configurationValues) { GroupTypeService groupTypeService = new GroupTypeService(new RockContext()); int?groupTypePurposeCheckinTemplateValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.GROUPTYPE_PURPOSE_CHECKIN_TEMPLATE.AsGuid()); return(groupTypeService.Queryable() .Where(a => a.GroupTypePurposeValueId.HasValue && a.GroupTypePurposeValueId.Value == groupTypePurposeCheckinTemplateValueId) .OrderBy(a => a.Order) .ThenBy(a => a.Name) .ToDictionary(k => k.Guid.ToString(), v => v.Name)); }
private void SendTextMessage(List <Person> smsRecipients, Dictionary <string, object> mergeFields) { var rockContext = new RockContext(); var communicationService = new CommunicationService(rockContext); var communicationRecipientService = new CommunicationRecipientService(rockContext); var communication = new Rock.Model.Communication(); communication.Status = CommunicationStatus.Approved; communication.SenderPersonAliasId = CurrentPerson.PrimaryAliasId; communicationService.Add(communication); communication.EnabledLavaCommands = GetAttributeValue("EnabledLavaCommands"); communication.IsBulkCommunication = false; communication.CommunicationType = CommunicationType.SMS; communication.ListGroup = null; communication.ListGroupId = null; communication.ExcludeDuplicateRecipientAddress = true; communication.CommunicationTemplateId = null; communication.FromName = mergeFields["FromName"].ToString().TrimForMaxLength(communication, "FromName"); communication.FromEmail = mergeFields["FromEmail"].ToString().TrimForMaxLength(communication, "FromEmail"); communication.Subject = GetAttributeValue("Subject"); communication.Message = GetAttributeValue("MessageBody"); communication.SMSFromDefinedValueId = DefinedValueCache.GetId(GetAttributeValue("SMSFromNumber").AsGuid()); communication.SMSMessage = GetAttributeValue("SMSMessageBody"); communication.FutureSendDateTime = null; communicationService.Add(communication); rockContext.SaveChanges(); foreach (var smsPerson in smsRecipients) { communication.Recipients.Add(new CommunicationRecipient() { PersonAliasId = smsPerson.PrimaryAliasId, MediumEntityTypeId = EntityTypeCache.Get(Rock.SystemGuid.EntityType.COMMUNICATION_MEDIUM_SMS.AsGuid()).Id, AdditionalMergeValues = mergeFields }); } rockContext.SaveChanges(); var transaction = new Rock.Transactions.SendCommunicationTransaction(); transaction.CommunicationId = communication.Id; transaction.PersonAlias = CurrentPersonAlias; Rock.Transactions.RockQueue.TransactionQueue.Enqueue(transaction); }
/// <summary> /// Binds the checkin types. /// </summary> /// <param name="selectedValue">The selected value.</param> private void BindCheckinTypes(int?checkinTypeId) { ddlCheckinType.Items.Clear(); if (ddlKiosk.SelectedValue != None.IdValue) { using (var rockContext = new RockContext()) { var groupTypeService = new GroupTypeService(rockContext); var checkinTemplateTypeId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.GROUPTYPE_PURPOSE_CHECKIN_TEMPLATE.AsGuid()); ddlCheckinType.DataSource = groupTypeService .Queryable().AsNoTracking() .Where(t => t.GroupTypePurposeValueId.HasValue && t.GroupTypePurposeValueId == checkinTemplateTypeId) .OrderBy(t => t.Name) .Select(t => new { t.Name, t.Id }) .ToList(); ddlCheckinType.DataBind(); } if (checkinTypeId.HasValue) { ddlCheckinType.SetValue(checkinTypeId); } else { if (LocalDeviceConfig.CurrentCheckinTypeId.HasValue) { ddlCheckinType.SetValue(LocalDeviceConfig.CurrentCheckinTypeId); } else { var groupType = GroupTypeCache.Get(Rock.SystemGuid.GroupType.GROUPTYPE_WEEKLY_SERVICE_CHECKIN_AREA.AsGuid()); if (groupType != null) { ddlCheckinType.SetValue(groupType.Id); } } } } }
/// <summary> /// Gets a list of IDs for all devices of type CheckinKiosk /// </summary> /// <returns></returns> private static List <string> GetAllIds() { int?kioskDeviceTypeValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.DEVICE_TYPE_CHECKIN_KIOSK.AsGuid()); using (var rockContext = new RockContext()) { var deviceService = new DeviceService(rockContext); var ids = deviceService.Queryable().Where(d => d.DeviceTypeValueId == kioskDeviceTypeValueId).Select(d => d.Id).ToList().ConvertAll(d => d.ToString()); if (ids.Any()) { return(ids); } } return(null); }
public static void SetWithParent(int personId) { var attendanceIds = All() .Where(a => a.PersonId == personId && a.AttendanceState == AttendanceState.InRoom) .Select(a => a.Id) .ToList(); RockContext rockContext = new RockContext(); AttendanceService attendanceService = new AttendanceService(rockContext); var attendances = attendanceService.Queryable() .Where(a => attendanceIds.Contains(a.Id)) .ToList(); attendances.ForEach(a => a.QualifierValueId = DefinedValueCache.GetId(Constants.DEFINED_VALUE_ATTENDANCE_STATUS_WITH_PARENT.AsGuid())); rockContext.SaveChanges(); attendances.ForEach(a => AddOrUpdate(a)); }
/// <summary> /// /// </summary> /// <returns></returns> private static WorkflowActionForm CreateNewWorkflowForm() { var workflowActionForm = new WorkflowActionForm(); workflowActionForm.PersonEntryConnectionStatusValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.PERSON_CONNECTION_STATUS_VISITOR.AsGuid()); workflowActionForm.PersonEntryRecordStatusValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_PENDING.AsGuid()); workflowActionForm.PersonEntryGroupLocationTypeValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME.AsGuid()); workflowActionForm.Actions = "Submit^^^Your information has been submitted successfully."; var systemEmail = new SystemCommunicationService(new RockContext()).Get(SystemGuid.SystemCommunication.WORKFLOW_FORM_NOTIFICATION.AsGuid()); if (systemEmail != null) { workflowActionForm.NotificationSystemCommunicationId = systemEmail.Id; } return(workflowActionForm); }
/// <summary> /// Binds the devices. /// </summary> private void BindDevices() { int?kioskDeviceTypeValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.DEVICE_TYPE_CHECKIN_KIOSK.AsGuid()); var rockContext = new RockContext(); DeviceService deviceService = new DeviceService(rockContext); var devices = deviceService.Queryable().AsNoTracking().Where(d => d.DeviceTypeValueId == kioskDeviceTypeValueId) .OrderBy(a => a.Name) .Select(a => new { a.Id, a.Name }).ToList(); lbDevices.Items.Clear(); lbDevices.Items.Add(new ListItem()); lbDevices.Items.AddRange(devices.Select(a => new ListItem(a.Name, a.Id.ToString())).ToArray()); }
/// <summary> /// Binds the grid. /// </summary> private void BindGrid() { RockContext rockContext = new RockContext(); PersonService personService = new PersonService(rockContext); var namelessPersonRecordTypeId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_NAMELESS.AsGuid()); var currentMergeRequestQry = PersonService.GetMergeRequestQuery(rockContext); var qry = personService .Queryable(new PersonService.PersonQueryOptions() { IncludeNameless = true }) .Where(p => p.RecordTypeValueId == namelessPersonRecordTypeId) .Where(p => !currentMergeRequestQry.Any(mr => mr.Items.Any(i => i.EntityId == p.Id))) .AsNoTracking(); int?namelessPersonId = PageParameter(PageParameterKey.NamelessPersonId).AsIntegerOrNull(); if (namelessPersonId.HasValue) { qry = qry.Where(a => a.Id == namelessPersonId.Value); } // sort the query based on the column that was selected to be sorted var sortProperty = gNamelessPersonList.SortProperty; if (gNamelessPersonList.AllowSorting && sortProperty != null) { qry = qry.Sort(sortProperty); } else { qry = qry.OrderByDescending(a => a.CreatedDateTime); } // set the datasource as a query. This allows the grid to only fetch the records that need to be shown based on the grid page and page size gNamelessPersonList.SetLinqDataSource(qry); gNamelessPersonList.DataBind(); }
public BlockActionResult DeclineAttend(Guid attendanceGuid, Guid?declineReasonGuid) { using (var rockContext = new RockContext()) { // We cannot operate without a logged in person. if (RequestContext.CurrentPerson == null) { return(ActionStatusCode(System.Net.HttpStatusCode.Unauthorized)); } var attendanceService = new AttendanceService(rockContext); var attendanceId = attendanceService.GetId(attendanceGuid); // If the specified attendance Id can't be fetched by Guid, let's return an error. if (!attendanceId.HasValue) { return(ActionBadRequest("Unable to fetch the corresponding attendance from the Guid.")); } // If the Group Type requires a decline reason. var requiresDeclineReason = attendanceService.Get(attendanceId.Value).Occurrence.Group.GroupType.RequiresReasonIfDeclineSchedule; // If a decline reason is required and not provided. if (!declineReasonGuid.HasValue && requiresDeclineReason) { return(ActionBadRequest("Please enter a decline reason.")); } // If the decline reason Guid has a value, let's fetch it. Otherwise, let's assign it to null. int?declineReason = declineReasonGuid.HasValue ? DefinedValueCache.GetId(declineReasonGuid.Value) : null; // Mark the attendance as declined. attendanceService.ScheduledPersonDecline(attendanceId.Value, declineReason); rockContext.SaveChanges(); return(ActionOk()); } }
public void RockCleanup_Execute_ShouldUpdatePeopleWithFinancialScheduledTransactionToAccountProtectionProfileHigh() { var personGuid = Guid.NewGuid(); var personWithFinancialScheduledTransaction = new Person { FirstName = "Test", LastName = personGuid.ToString(), Email = $"{personGuid}@test.com", Guid = personGuid }; using (var rockContext = new RockContext()) { var personService = new PersonService(rockContext); personService.Add(personWithFinancialScheduledTransaction); rockContext.SaveChanges(); personWithFinancialScheduledTransaction = personService.Get(personWithFinancialScheduledTransaction.Id); var financialScheduledTransaction = new FinancialScheduledTransaction { AuthorizedPersonAliasId = personWithFinancialScheduledTransaction.PrimaryAliasId.Value, TransactionFrequencyValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME.AsGuid()) ?? 0 }; var service = new FinancialScheduledTransactionService(rockContext); service.Add(financialScheduledTransaction); rockContext.SaveChanges(); } ExecuteRockCleanupJob(); using (var rockContext = new RockContext()) { var actualPerson = new PersonService(rockContext).Get(personGuid); Assert.That.AreEqual(AccountProtectionProfile.High, actualPerson.AccountProtectionProfile); } }
/// <summary> /// Charges the specified payment info. /// </summary> /// <param name="financialGateway">The financial gateway.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override FinancialTransaction Charge(FinancialGateway financialGateway, PaymentInfo paymentInfo, out string errorMessage) { errorMessage = string.Empty; if (ValidateCard(financialGateway, paymentInfo, out errorMessage)) { var transaction = new FinancialTransaction(); transaction.TransactionCode = "T" + RockDateTime.Now.ToString("yyyyMMddHHmmssFFF"); transaction.FinancialPaymentDetail = new FinancialPaymentDetail() { ExpirationMonth = (paymentInfo as ReferencePaymentInfo)?.PaymentExpirationDate?.Month, ExpirationYear = (paymentInfo as ReferencePaymentInfo)?.PaymentExpirationDate?.Year, CurrencyTypeValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD.AsGuid()), AccountNumberMasked = paymentInfo.MaskedNumber, CreditCardTypeValueId = CreditCardPaymentInfo.GetCreditCardTypeFromCreditCardNumber(paymentInfo.MaskedNumber ?? string.Empty)?.Id ?? DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.CREDITCARD_TYPE_VISA.AsGuid()) }; return(transaction); } return(null); }
private void BindData() { int?groupTypePurposeCheckinTemplateValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.GROUPTYPE_PURPOSE_CHECKIN_TEMPLATE.AsGuid()); using (var rockContext = new RockContext()) { var checkinAreaTypeQuery = new GroupTypeService(rockContext) .Queryable() .Where(g => g.GroupTypePurposeValueId.HasValue && g.GroupTypePurposeValueId.Value == groupTypePurposeCheckinTemplateValueId); var checkinAreaTypeGuids = this.GetAttributeValues(AttributeKey.CheckinConfigurationTypes).AsGuidList(); if (checkinAreaTypeGuids.Any()) { checkinAreaTypeQuery = checkinAreaTypeQuery.Where(a => checkinAreaTypeGuids.Contains(a.Guid)); } rptNavItems.DataSource = checkinAreaTypeQuery.ToList() .OrderBy(g => g.Name) .ToList(); rptNavItems.DataBind(); } }
/// <summary> /// Binds the checkin types. /// </summary> private void BindCheckinTypes() { using (var rockContext = new RockContext()) { var groupTypeService = new GroupTypeService(rockContext); var checkinTemplateTypeId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.GROUPTYPE_PURPOSE_CHECKIN_TEMPLATE.AsGuid()); var checkinTypes = groupTypeService .Queryable().AsNoTracking() .Where(t => t.GroupTypePurposeValueId.HasValue && t.GroupTypePurposeValueId == checkinTemplateTypeId) .OrderBy(t => t.Name) .Select(t => new { t.Name, t.Guid }) .ToList(); ddlCheckinType.Items.Clear(); ddlCheckinType.Items.Add(new ListItem()); ddlCheckinType.Items.AddRange(checkinTypes.Select(a => new ListItem(a.Name, a.Guid.ToString())).ToArray()); } }
protected void btnSave_Click(object sender, EventArgs e) { RockContext rockContext = new RockContext(); var person = GetPerson(); var personAliasEntityType = EntityTypeCache.Get(typeof(PersonAlias)); var changeRequest = new ChangeRequest { EntityTypeId = personAliasEntityType.Id, EntityId = person.PrimaryAliasId ?? 0, RequestorAliasId = CurrentPersonAliasId ?? 0, RequestorComment = tbComments.Text }; changeRequest.EvaluatePropertyChange(person, "PhotoId", iuPhoto.BinaryFileId); changeRequest.EvaluatePropertyChange(person, "TitleValue", DefinedValueCache.Get(ddlTitle.SelectedValueAsInt() ?? 0)); changeRequest.EvaluatePropertyChange(person, "FirstName", tbFirstName.Text); changeRequest.EvaluatePropertyChange(person, "NickName", tbNickName.Text); changeRequest.EvaluatePropertyChange(person, "MiddleName", tbMiddleName.Text); changeRequest.EvaluatePropertyChange(person, "LastName", tbLastName.Text); changeRequest.EvaluatePropertyChange(person, "SuffixValue", DefinedValueCache.Get(ddlSuffix.SelectedValueAsInt() ?? 0)); var families = person.GetFamilies(); if (families.Count() == 1) { var groupMember = person.PrimaryFamily.Members.Where(gm => gm.PersonId == person.Id).FirstOrDefault(); if (groupMember != null) { GroupTypeRole groupTypeRole = null; GroupTypeRoleService groupTypeRoleService = new GroupTypeRoleService(rockContext); if (ddlFamilyRole.SelectedValue == "A") { groupTypeRole = groupTypeRoleService.Get(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid()); } else if (ddlFamilyRole.SelectedValue == "C") { groupTypeRole = groupTypeRoleService.Get(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid()); } changeRequest.EvaluatePropertyChange(groupMember, "GroupRole", groupTypeRole, true); } } //Evaluate PhoneNumbers 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) { int phoneNumberTypeId; if (int.TryParse(hfPhoneType.Value, out phoneNumberTypeId)) { var phoneNumber = person.PhoneNumbers.FirstOrDefault(n => n.NumberTypeValueId == phoneNumberTypeId); string oldPhoneNumber = string.Empty; if (phoneNumber == null && pnbPhone.Number.IsNotNullOrWhiteSpace()) //Add number { phoneNumber = new PhoneNumber { PersonId = person.Id, NumberTypeValueId = phoneNumberTypeId, CountryCode = PhoneNumber.CleanNumber(pnbPhone.CountryCode), IsMessagingEnabled = !smsSelected && cbSms.Checked, Number = PhoneNumber.CleanNumber(pnbPhone.Number) }; var phoneComment = string.Format("{0}: {1}.", DefinedValueCache.Get(phoneNumberTypeId).Value, pnbPhone.Number); changeRequest.AddEntity(phoneNumber, rockContext, true, phoneComment); } else if (phoneNumber != null && pnbPhone.Text.IsNullOrWhiteSpace()) // delete number { var phoneComment = string.Format("{0}: {1}.", phoneNumber.NumberTypeValue.Value, phoneNumber.NumberFormatted); changeRequest.DeleteEntity(phoneNumber, true, phoneComment); } else if (phoneNumber != null && pnbPhone.Text.IsNotNullOrWhiteSpace()) // update number { changeRequest.EvaluatePropertyChange(phoneNumber, "Number", PhoneNumber.CleanNumber(pnbPhone.Number), true); changeRequest.EvaluatePropertyChange(phoneNumber, "IsMessagingEnabled", (!smsSelected && cbSms.Checked), true); changeRequest.EvaluatePropertyChange(phoneNumber, "IsUnlisted", cbUnlisted.Checked, true); } if (hfPhoneType.Value.AsInteger() == DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE.AsGuid())) { var validationInfo = ValidateMobilePhoneNumber(PhoneNumber.CleanNumber(pnbPhone.Number)); if (validationInfo.IsNotNullOrWhiteSpace()) { changeRequest.RequestorComment += "<h4>Dynamically Generated Warnings:</h4>" + validationInfo; } } } } } changeRequest.EvaluatePropertyChange(person, "Email", tbEmail.Text); changeRequest.EvaluatePropertyChange(person, "IsEmailActive", cbIsEmailActive.Checked); changeRequest.EvaluatePropertyChange(person, "EmailPreference", rblEmailPreference.SelectedValueAsEnum <EmailPreference>()); changeRequest.EvaluatePropertyChange(person, "CommunicationPreference", rblCommunicationPreference.SelectedValueAsEnum <CommunicationType>()); var birthday = bpBirthday.SelectedDate; if (birthday.HasValue) { changeRequest.EvaluatePropertyChange(person, "BirthMonth", birthday.Value.Month); changeRequest.EvaluatePropertyChange(person, "BirthDay", birthday.Value.Day); if (birthday.Value.Year != DateTime.MinValue.Year) { changeRequest.EvaluatePropertyChange(person, "BirthYear", birthday.Value.Year); } else { int?year = null; changeRequest.EvaluatePropertyChange(person, "BirthYear", year); } } changeRequest.EvaluatePropertyChange(person, "Gender", ddlGender.SelectedValueAsEnum <Gender>()); changeRequest.EvaluatePropertyChange(person, "MaritalStatusValue", DefinedValueCache.Get(ddlMaritalStatus.SelectedValueAsInt() ?? 0)); changeRequest.EvaluatePropertyChange(person, "AnniversaryDate", dpAnniversaryDate.SelectedDate); changeRequest.EvaluatePropertyChange(person, "GraduationYear", ypGraduation.SelectedYear); var groupEntity = EntityTypeCache.Get(typeof(Group)); var groupLocationEntity = EntityTypeCache.Get(typeof(GroupLocation)); var family = person.GetFamily(); var familyChangeRequest = new ChangeRequest() { EntityTypeId = groupEntity.Id, EntityId = family.Id, RequestorAliasId = CurrentPersonAliasId ?? 0 }; familyChangeRequest.EvaluatePropertyChange(family, "Campus", CampusCache.Get(ddlCampus.SelectedValueAsInt() ?? 0)); var currentLocation = person.GetHomeLocation(); Location location = new Location { Street1 = acAddress.Street1, Street2 = acAddress.Street2, City = acAddress.City, State = acAddress.State, PostalCode = acAddress.PostalCode, }; var globalAttributesCache = GlobalAttributesCache.Get(); location.Country = globalAttributesCache.OrganizationCountry; location.Country = string.IsNullOrWhiteSpace(location.Country) ? "US" : location.Country; if ((currentLocation == null && location.Street1.IsNotNullOrWhiteSpace()) || (currentLocation != null && currentLocation.Street1 != location.Street1)) { LocationService locationService = new LocationService(rockContext); locationService.Add(location); rockContext.SaveChanges(); var previousLocationType = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_PREVIOUS.AsGuid()); var homeLocationType = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME.AsGuid()); GroupLocation groupLocation = new GroupLocation { CreatedByPersonAliasId = CurrentPersonAliasId, ModifiedByPersonAliasId = CurrentPersonAliasId, GroupId = family.Id, LocationId = location.Id, GroupLocationTypeValueId = homeLocationType.Id, IsMailingLocation = true, IsMappedLocation = true }; var newGroupLocation = familyChangeRequest.AddEntity(groupLocation, rockContext, true, location.ToString()); var homelocations = family.GroupLocations.Where(gl => gl.GroupLocationTypeValueId == homeLocationType.Id); foreach (var homelocation in homelocations) { familyChangeRequest.EvaluatePropertyChange( homelocation, "GroupLocationTypeValue", previousLocationType, true, homelocation.Location.ToString()); familyChangeRequest.EvaluatePropertyChange( homelocation, "IsMailingLocation", false, true, homelocation.Location.ToString()); } } //Adding a new family member if (pAddPerson.SelectedValue.HasValue) { PersonService personService = new PersonService(rockContext); var insertPerson = personService.Get(pAddPerson.SelectedValue.Value); if (insertPerson != null) { GroupMemberService groupMemberService = new GroupMemberService(rockContext); var familyGroupTypeId = GroupTypeCache.Get(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid()).Id; //Remove all other group members if (cbRemovePerson.Checked) { var members = groupMemberService.Queryable() .Where(m => m.PersonId == pAddPerson.SelectedValue.Value && m.Group.GroupTypeId == familyGroupTypeId); foreach (var member in members) { var comment = string.Format("Removed {0} from {1}", insertPerson.FullName, member.Group.Name); familyChangeRequest.DeleteEntity(member, true, comment); } } var personFamilies = person.GetFamilies().ToList(); GroupTypeRoleService groupTypeRoleService = new GroupTypeRoleService(rockContext); var roleId = groupTypeRoleService.Get(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid()).Id; if (insertPerson.Age.HasValue && insertPerson.Age.Value < 18) { roleId = groupTypeRoleService.Get(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid()).Id; } foreach (var personFamily in personFamilies) { //Make a new group member GroupMember familyMember = new GroupMember { PersonId = pAddPerson.SelectedValue.Value, GroupId = personFamily.Id, GroupMemberStatus = GroupMemberStatus.Active, Guid = Guid.NewGuid(), GroupRoleId = roleId }; var insertComment = string.Format("Added {0} to {1}", insertPerson.FullName, personFamily.Name); familyChangeRequest.AddEntity(familyMember, rockContext, true, insertComment); } } } bool autoApply = CanAutoApply(person); List <string> errors; if (changeRequest.ChangeRecords.Any() || (!familyChangeRequest.ChangeRecords.Any() && tbComments.Text.IsNotNullOrWhiteSpace())) { ChangeRequestService changeRequestService = new ChangeRequestService(rockContext); changeRequestService.Add(changeRequest); rockContext.SaveChanges(); if (autoApply) { changeRequest.CompleteChanges(rockContext, out errors); } changeRequest.LaunchWorkflow(GetAttributeValue("Workflow").AsGuidOrNull()); } if (familyChangeRequest.ChangeRecords.Any()) { familyChangeRequest.RequestorComment = tbComments.Text; ChangeRequestService changeRequestService = new ChangeRequestService(rockContext); changeRequestService.Add(familyChangeRequest); rockContext.SaveChanges(); if (autoApply) { familyChangeRequest.CompleteChanges(rockContext, out errors); } familyChangeRequest.LaunchWorkflow(GetAttributeValue("Workflow").AsGuidOrNull()); } if (autoApply) { NavigateToPerson(); } else { pnlMain.Visible = false; pnlNoPerson.Visible = false; pnlDone.Visible = true; } }
/// <summary> /// Gets the person search details. /// </summary> /// <param name="personSearchResult">The person search result.</param> /// <param name="person">The person.</param> private void GetPersonSearchDetails(PersonSearchResult personSearchResult, Person person) { var rockContext = this.Service.Context as Rock.Data.RockContext; var appPath = System.Web.VirtualPathUtility.ToAbsolute("~"); var familyGroupType = GroupTypeCache.Get(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid()); int adultRoleId = familyGroupType.Roles.First(a => a.Guid == Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid()).Id; int groupTypeFamilyId = GroupTypeCache.Get(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid()).Id; // figure out Family, Address, Spouse GroupMemberService groupMemberService = new GroupMemberService(rockContext); Guid?recordTypeValueGuid = null; if (person.RecordTypeValueId.HasValue) { recordTypeValueGuid = DefinedValueCache.Get(person.RecordTypeValueId.Value).Guid; } personSearchResult.ImageHtmlTag = Person.GetPersonPhotoImageTag(person, 50, 50); personSearchResult.Age = person.Age.HasValue ? person.Age.Value : -1; personSearchResult.ConnectionStatus = person.ConnectionStatusValueId.HasValue ? DefinedValueCache.Get(person.ConnectionStatusValueId.Value).Value : string.Empty; personSearchResult.Gender = person.Gender.ConvertToString(); personSearchResult.Email = person.Email; string imageHtml = string.Format( "<div class='person-image' style='background-image:url({0}&width=65);'></div>", Person.GetPersonPhotoUrl(person, 200, 200)); StringBuilder personInfoHtmlBuilder = new StringBuilder(); int? groupLocationTypeValueId; bool isBusiness = person.IsBusiness(); if (isBusiness) { groupLocationTypeValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_WORK.AsGuid()); } else { groupLocationTypeValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME.AsGuid()); } int?personAge = person.Age; if (isBusiness) { personInfoHtmlBuilder.Append("Business"); } else if (person.AgeClassification != AgeClassification.Unknown) { personInfoHtmlBuilder.Append("<span class='role'>" + person.AgeClassification.ConvertToString() + "</span>"); } if (personAge != null) { personInfoHtmlBuilder.Append(" <em class='age'>(" + person.FormatAge() + " old)</em>"); } if (person.AgeClassification == AgeClassification.Adult) { var personService = this.Service as PersonService; var spouse = personService.GetSpouse(person, a => new { a.Person.NickName, a.Person.LastName, a.Person.SuffixValueId }); if (spouse != null) { string spouseFullName = Person.FormatFullName(spouse.NickName, spouse.LastName, spouse.SuffixValueId); personInfoHtmlBuilder.Append("<p class='spouse'><strong>Spouse:</strong> " + spouseFullName + "</p>"); personSearchResult.SpouseName = spouseFullName; } } var primaryLocation = groupMemberService.Queryable() .Where(a => a.PersonId == person.Id) .Where(a => a.Group.GroupTypeId == groupTypeFamilyId) .OrderBy(a => a.GroupOrder ?? int.MaxValue) .Select(s => s.Group.GroupLocations.Where(a => a.GroupLocationTypeValueId == groupLocationTypeValueId).Select(a => a.Location).FirstOrDefault() ).AsNoTracking().FirstOrDefault(); if (primaryLocation != null) { var fullStreetAddress = primaryLocation.GetFullStreetAddress(); string addressHtml = $"<dl class='address'><dt>Address</dt><dd>{fullStreetAddress.ConvertCrLfToHtmlBr()}</dd></dl>"; personSearchResult.Address = fullStreetAddress; personInfoHtmlBuilder.Append(addressHtml); } // Generate the HTML for Email and PhoneNumbers if (!string.IsNullOrWhiteSpace(person.Email) || person.PhoneNumbers.Any()) { StringBuilder sbEmailAndPhoneHtml = new StringBuilder(); sbEmailAndPhoneHtml.Append("<div class='margin-t-sm'>"); sbEmailAndPhoneHtml.Append("<span class='email'>" + person.Email + "</span>"); string phoneNumberList = "<ul class='phones list-unstyled'>"; foreach (var phoneNumber in person.PhoneNumbers) { var phoneType = DefinedValueCache.Get(phoneNumber.NumberTypeValueId ?? 0); phoneNumberList += string.Format( "<li x-ms-format-detection='none'>{0} <small>{1}</small></li>", phoneNumber.IsUnlisted ? "Unlisted" : phoneNumber.NumberFormatted, phoneType != null ? phoneType.Value : string.Empty); } sbEmailAndPhoneHtml.Append(phoneNumberList + "</ul></div>"); personInfoHtmlBuilder.Append(sbEmailAndPhoneHtml.ToString()); } // force the link to open a new scrollable, re-sizable browser window (and make it work in FF, Chrome and IE) http://stackoverflow.com/a/2315916/1755417 personInfoHtmlBuilder.Append($"<p class='margin-t-sm'><small><a href='/person/{person.Id}' class='cursor-pointer' onclick=\"javascript: window.open('/person/{person.Id}', '_blank', 'scrollbars=1,resizable=1,toolbar=1'); return false;\" data-toggle=\"tooltip\" title=\"View Profile\" tabindex=\"-1\">View Profile</a></small></p>"); personSearchResult.PickerItemDetailsImageHtml = imageHtml; personSearchResult.PickerItemDetailsPersonInfoHtml = personInfoHtmlBuilder.ToString(); string itemDetailHtml = $@" <div class='picker-select-item-details js-picker-select-item-details clearfix' style='display: none;'> {imageHtml} <div class='contents'> {personSearchResult.PickerItemDetailsPersonInfoHtml} </div> </div> "; personSearchResult.PickerItemDetailsHtml = itemDetailHtml; }
/// <summary> /// BulkInserts Interaction Records /// </summary> /// <remarks> /// If any PersonAliasId references a PersonAliasId record that doesn't exist, the field value will be set to null. /// Also, if the InteractionComponent Id (or Guid) is specified, but references a Interaction Component record that doesn't exist /// the Interaction will not be recorded. /// </remarks> /// <param name="interactionsImport">The interactions import.</param> internal static void BulkInteractionImport(InteractionsImport interactionsImport) { if (interactionsImport == null) { throw new Exception("InteractionsImport must be assigned a value."); } var interactionImportList = interactionsImport.Interactions; if (interactionImportList == null || !interactionImportList.Any()) { // if there aren't any return return; } /* 2020-05-14 MDP * Make sure that all the PersonAliasIds in the import exist in the database. * For performance reasons, look them up all at one and keep a list of valid ones. * * If there are any PersonAliasIds that aren't valid, * we decided that just set the PersonAliasId to null (we want ignore bad data). */ HashSet <int> validPersonAliasIds = interactionsImport.GetValidPersonAliasIds(); List <Interaction> interactionsToInsert = new List <Interaction>(); foreach (InteractionImport interactionImport in interactionImportList) { if (interactionImport.Interaction == null) { throw new ArgumentNullException("InteractionImport.Interaction can not be null"); } // Determine which Channel this should be set to if (interactionImport.InteractionChannelId.HasValue) { // make sure it is a valid Id interactionImport.InteractionChannelId = InteractionChannelCache.Get(interactionImport.InteractionChannelId.Value)?.Id; } // Determine which Channel Type Medium this should be set to if (interactionImport.InteractionChannelChannelTypeMediumValueId.HasValue) { // make sure it is a valid Id interactionImport.InteractionChannelChannelTypeMediumValueId = DefinedValueCache.Get(interactionImport.InteractionChannelChannelTypeMediumValueId.Value)?.Id; } if (!interactionImport.InteractionChannelChannelTypeMediumValueId.HasValue) { if (interactionImport.InteractionChannelChannelTypeMediumValueGuid.HasValue) { interactionImport.InteractionChannelChannelTypeMediumValueId = DefinedValueCache.GetId(interactionImport.InteractionChannelChannelTypeMediumValueGuid.Value); } } if (!interactionImport.InteractionChannelId.HasValue) { if (interactionImport.InteractionChannelGuid.HasValue) { interactionImport.InteractionChannelId = InteractionChannelCache.GetId(interactionImport.InteractionChannelGuid.Value); } // if InteractionChannelId is still null, lookup (or create) an InteractionChannel from InteractionChannelForeignKey (if it is specified) if (interactionImport.InteractionChannelId == null && interactionImport.InteractionChannelForeignKey.IsNotNullOrWhiteSpace()) { interactionImport.InteractionChannelId = InteractionChannelCache.GetCreateChannelIdByForeignKey(interactionImport.InteractionChannelForeignKey, interactionImport.InteractionChannelName, interactionImport.InteractionChannelChannelTypeMediumValueId); } else { /* 2020-05-14 MDP * Discussed this and decided that if we tried InteractionChannelId and InteractionChannelGuid, and InteractionChannelForeignKey was not specified, * we'll just skip over this record */ continue; } } // Determine which Component this should be set to if (interactionImport.InteractionComponentId.HasValue) { // make sure it is a valid Id interactionImport.InteractionComponentId = InteractionComponentCache.Get(interactionImport.InteractionComponentId.Value)?.Id; } if (!interactionImport.InteractionComponentId.HasValue) { if (interactionImport.InteractionComponentGuid.HasValue) { interactionImport.InteractionComponentId = InteractionComponentCache.GetId(interactionImport.InteractionComponentGuid.Value); } // if InteractionComponentId is still null, lookup (or create) an InteractionComponent from the ForeignKey and ChannelId if (interactionImport.InteractionComponentForeignKey.IsNotNullOrWhiteSpace()) { interactionImport.InteractionComponentId = InteractionComponentCache.GetComponentIdByForeignKeyAndChannelId( interactionImport.InteractionComponentForeignKey, interactionImport.InteractionChannelId.Value, interactionImport.InteractionComponentName); } else { /* 2020-05-14 MDP * Discussed this and decided that and if we tried InteractionComponentId and InteractionComponentGuid, and InteractionComponentForeignKey was not specified, * we'll just skip over this record */ continue; } } } foreach (InteractionImport interactionImport in interactionImportList.Where(a => a.InteractionComponentId.HasValue)) { Interaction interaction = new Interaction { InteractionComponentId = interactionImport.InteractionComponentId.Value }; interaction.InteractionDateTime = interactionImport.Interaction.InteractionDateTime; // if operation is over 25, truncate it interaction.Operation = interactionImport.Interaction.Operation.Truncate(25); interaction.InteractionComponentId = interactionImport.InteractionComponentId.Value; interaction.EntityId = interactionImport.Interaction.EntityId; if (interactionImport.Interaction.RelatedEntityTypeId.HasValue) { /* 2020-05-14 MDP * We want to ignore bad data, so first see if the RelatedEntityTypeId exists by looking it up in a cache. * If it doesn't exist, it'll set RelatedEntityTypeId to null (so that we don't get a database constraint error) */ interaction.RelatedEntityTypeId = EntityTypeCache.Get(interactionImport.Interaction.RelatedEntityTypeId.Value)?.Id; } interaction.RelatedEntityId = interactionImport.Interaction.RelatedEntityId; if (interactionImport.Interaction.PersonAliasId.HasValue) { /* 2020-05-14 MDP * We want to ignore bad data, so see if the specified PersonAliasId exists in the validPersonAliasIds that we lookup up * If it doesn't exist, we'll leave interaction.PersonAliasId null (so that we don't get a database constraint error) */ if (validPersonAliasIds.Contains(interactionImport.Interaction.PersonAliasId.Value)) { interaction.PersonAliasId = interactionImport.Interaction.PersonAliasId.Value; } } // BulkImport doesn't include Session information TODO??? interaction.InteractionSessionId = null; // if the summary is over 500 chars, truncate with addEllipsis=true interaction.InteractionSummary = interactionImport.Interaction.InteractionSummary.Truncate(500, true); interaction.InteractionData = interactionImport.Interaction.InteractionData; interaction.PersonalDeviceId = interactionImport.Interaction.PersonalDeviceId; interaction.InteractionEndDateTime = interactionImport.Interaction.InteractionEndDateTime; // Campaign related fields, we'll truncate those if they are too long interaction.Source = interactionImport.Interaction.Source.Truncate(25); interaction.Medium = interactionImport.Interaction.Medium.Truncate(25); interaction.Campaign = interactionImport.Interaction.Campaign.Truncate(50); interaction.Content = interactionImport.Interaction.Content.Truncate(50); interaction.Term = interactionImport.Interaction.Term.Truncate(50); interaction.ForeignId = interactionImport.Interaction.ForeignId; interaction.ForeignKey = interactionImport.Interaction.ForeignKey; interaction.ForeignGuid = interactionImport.Interaction.ForeignGuid; interaction.ChannelCustom1 = interactionImport.Interaction.ChannelCustom1.Truncate(500, true); interaction.ChannelCustom2 = interactionImport.Interaction.ChannelCustom2.Truncate(2000, true); interaction.ChannelCustomIndexed1 = interactionImport.Interaction.ChannelCustomIndexed1.Truncate(500, true); interaction.InteractionLength = interactionImport.Interaction.InteractionLength; interaction.InteractionTimeToServe = interactionImport.Interaction.InteractionTimeToServe; interactionsToInsert.Add(interaction); } using (var rockContext = new RockContext()) { rockContext.BulkInsert(interactionsToInsert); } // This logic is normally handled in the Interaction.PostSave method, but since the BulkInsert bypasses those // model hooks, streaks need to be updated here. Also, it is not necessary for this logic to complete before this // transaction can continue processing and exit, so update the streak using a task. // Only launch this task if there are StreakTypes configured that have interactions. Otherwise several // database calls are made only to find out there are no streak types defined. if (StreakTypeCache.All().Any(s => s.IsInteractionRelated)) { // Ids do not exit for the interactions in the collection since they were bulk imported. // Read their ids from their guids and append the id. var insertedGuids = interactionsToInsert.Select(i => i.Guid).ToList(); var interactionIds = new InteractionService(new RockContext()).Queryable() .Where(i => insertedGuids.Contains(i.Guid)) .Select(i => new { i.Id, i.Guid }) .ToList(); foreach (var interactionId in interactionIds) { var interaction = interactionsToInsert.Where(i => i.Guid == interactionId.Guid).FirstOrDefault(); if (interaction != null) { interaction.Id = interactionId.Id; } } // Launch task interactionsToInsert.ForEach(i => Task.Run(() => StreakTypeService.HandleInteractionRecord(i.Id))); } }
private static void CreatePersonWithPrimaryAndPreviousEmails() { var rockContext = new RockContext(); var personService = new PersonService(rockContext); var person = personService.Get(PersonGuid.PersonWithPrimaryAndPreviousEmailsGuid); if (person != null) { new PersonAliasService(rockContext).DeleteRange(person.Aliases); new PersonSearchKeyService(rockContext).DeleteRange(person.GetPersonSearchKeys(rockContext).ToList()); personService.Delete(person); rockContext.SaveChanges(); } person = new Person() { RecordTypeValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()), FirstName = "I Have A", LastName = "CommonLastName", Guid = PersonGuid.PersonWithPrimaryAndPreviousEmailsGuid, Email = Email.PrimaryEmail }; Group newPersonFamily = PersonService.SaveNewPerson(person, rockContext); person = personService.Get(PersonGuid.PersonWithPrimaryAndPreviousEmailsGuid); var primaryAliasId = person.PrimaryAliasId; var personSearchKeyService = new PersonSearchKeyService(rockContext); var searchTypeValue = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_SEARCH_KEYS_EMAIL.AsGuid()); PersonSearchKey personSearchKeyPreviousEmail1 = new PersonSearchKey() { PersonAliasId = primaryAliasId, SearchTypeValueId = searchTypeValue.Id, SearchValue = Email.PreviousEmail1 }; personSearchKeyService.Add(personSearchKeyPreviousEmail1); PersonSearchKey personSearchKeyPreviousEmail2 = new PersonSearchKey() { PersonAliasId = primaryAliasId, SearchTypeValueId = searchTypeValue.Id, SearchValue = Email.PreviousEmail2 }; personSearchKeyService.Add(personSearchKeyPreviousEmail2); PersonSearchKey personSearchKeyPreviousEmail3 = new PersonSearchKey() { PersonAliasId = primaryAliasId, SearchTypeValueId = searchTypeValue.Id, SearchValue = Email.PreviousEmail3 }; personSearchKeyService.Add(personSearchKeyPreviousEmail3); rockContext.SaveChanges(); }
/// <summary> /// Job that will run quick SQL queries on a schedule. /// /// Called by the <see cref="IScheduler" /> when a /// <see cref="ITrigger" /> fires that is associated with /// the <see cref="IJob" />. /// </summary> public virtual void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; Guid?entryWorkflowType = dataMap.GetString("EraEntryWorkflow").AsGuidOrNull(); Guid?exitWorkflowType = dataMap.GetString("EraExitWorkflow").AsGuidOrNull(); bool updateVisitDates = dataMap.GetBooleanValue("SetVisitDates"); int commandTimeout = dataMap.GetString("CommandTimeout").AsIntegerOrNull() ?? 3600; // configuration // // giving int exitGivingCount = 1; // attendance int exitAttendanceCountShort = 1; int exitAttendanceCountLong = 8; // get era dataset from stored proc var resultContext = new RockContext(); var eraAttribute = AttributeCache.Get(SystemGuid.Attribute.PERSON_ERA_CURRENTLY_AN_ERA.AsGuid()); var eraStartAttribute = AttributeCache.Get(SystemGuid.Attribute.PERSON_ERA_START_DATE.AsGuid()); var eraEndAttribute = AttributeCache.Get(SystemGuid.Attribute.PERSON_ERA_END_DATE.AsGuid()); if (eraAttribute == null || eraStartAttribute == null || eraEndAttribute == null) { throw new Exception("Family analytic attributes could not be found"); } resultContext.Database.CommandTimeout = commandTimeout; context.UpdateLastStatusMessage("Getting Family Analytics Era Dataset..."); var results = resultContext.Database.SqlQuery <EraResult>("spCrm_FamilyAnalyticsEraDataset").ToList(); int personEntityTypeId = EntityTypeCache.Get("Rock.Model.Person").Id; int attributeEntityTypeId = EntityTypeCache.Get("Rock.Model.Attribute").Id; int eraAttributeId = eraAttribute.Id; int personAnalyticsCategoryId = CategoryCache.Get(SystemGuid.Category.HISTORY_PERSON_ANALYTICS.AsGuid()).Id; int progressPosition = 0; int progressTotal = results.Count; foreach (var result in results) { progressPosition++; // create new rock context for each family (https://weblog.west-wind.com/posts/2014/Dec/21/Gotcha-Entity-Framework-gets-slow-in-long-Iteration-Loops) RockContext updateContext = new RockContext(); updateContext.SourceOfChange = SOURCE_OF_CHANGE; updateContext.Database.CommandTimeout = commandTimeout; var attributeValueService = new AttributeValueService(updateContext); var historyService = new HistoryService(updateContext); // if era ensure it still meets requirements if (result.IsEra) { // This process will not remove eRA status from a single inactive family member if the family is considered eRA, even if the person record status is inactive. // It removes eRA status from all family members if the family no longer meets the eRA requirements. if (result.ExitGiftCountDuration < exitGivingCount && result.ExitAttendanceCountDurationShort < exitAttendanceCountShort && result.ExitAttendanceCountDurationLong < exitAttendanceCountLong) { // exit era (delete attribute value from each person in family) var family = new GroupService(updateContext).Queryable("Members, Members.Person").AsNoTracking().Where(m => m.Id == result.FamilyId).FirstOrDefault(); if (family != null) { foreach (var person in family.Members.Select(m => m.Person)) { // remove the era flag var eraAttributeValue = attributeValueService.Queryable().Where(v => v.AttributeId == eraAttribute.Id && v.EntityId == person.Id).FirstOrDefault(); if (eraAttributeValue != null) { attributeValueService.Delete(eraAttributeValue); } // set end date var eraEndAttributeValue = attributeValueService.Queryable().Where(v => v.AttributeId == eraEndAttribute.Id && v.EntityId == person.Id).FirstOrDefault(); if (eraEndAttributeValue == null) { eraEndAttributeValue = new AttributeValue(); eraEndAttributeValue.EntityId = person.Id; eraEndAttributeValue.AttributeId = eraEndAttribute.Id; attributeValueService.Add(eraEndAttributeValue); } eraEndAttributeValue.Value = RockDateTime.Now.ToString(); // add a history record if (personAnalyticsCategoryId != 0 && personEntityTypeId != 0 && attributeEntityTypeId != 0 && eraAttributeId != 0) { History historyRecord = new History(); historyService.Add(historyRecord); historyRecord.EntityTypeId = personEntityTypeId; historyRecord.EntityId = person.Id; historyRecord.CreatedDateTime = RockDateTime.Now; historyRecord.CreatedByPersonAliasId = person.PrimaryAliasId; historyRecord.Caption = "eRA"; historyRecord.Verb = "EXITED"; historyRecord.ChangeType = History.HistoryChangeType.Attribute.ConvertToString(); historyRecord.ValueName = "eRA"; historyRecord.NewValue = "Exited"; historyRecord.RelatedEntityTypeId = attributeEntityTypeId; historyRecord.RelatedEntityId = eraAttributeId; historyRecord.CategoryId = personAnalyticsCategoryId; historyRecord.SourceOfChange = SOURCE_OF_CHANGE; } updateContext.SaveChanges(); } // launch exit workflow if (exitWorkflowType.HasValue) { LaunchWorkflow(exitWorkflowType.Value, family); } } } } else { // entered era var family = new GroupService(updateContext).Queryable("Members").AsNoTracking().Where(m => m.Id == result.FamilyId).FirstOrDefault(); if (family != null) { // The stored procedure does not filter out inactive users because we want to exit the family from eRA if they are not active. // So check the status for each person here and do not add the person if they are inactive. If the system defined value for // an inactive person is not available then use "-1" as every record should pass != -1. int inactiveStatusId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE.AsGuid()) ?? -1; var familyMembers = family.Members .Where(m => !m.Person.IsDeceased) .Where(m => m.Person.RecordStatusValueId != inactiveStatusId) .Select(m => m.Person); foreach (var person in familyMembers) { // set era attribute to true var eraAttributeValue = attributeValueService.Queryable().Where(v => v.AttributeId == eraAttribute.Id && v.EntityId == person.Id).FirstOrDefault(); if (eraAttributeValue == null) { eraAttributeValue = new AttributeValue(); eraAttributeValue.EntityId = person.Id; eraAttributeValue.AttributeId = eraAttribute.Id; attributeValueService.Add(eraAttributeValue); } eraAttributeValue.Value = bool.TrueString; // add start date var eraStartAttributeValue = attributeValueService.Queryable().Where(v => v.AttributeId == eraStartAttribute.Id && v.EntityId == person.Id).FirstOrDefault(); if (eraStartAttributeValue == null) { eraStartAttributeValue = new AttributeValue(); eraStartAttributeValue.EntityId = person.Id; eraStartAttributeValue.AttributeId = eraStartAttribute.Id; attributeValueService.Add(eraStartAttributeValue); } eraStartAttributeValue.Value = RockDateTime.Now.ToString(); // delete end date if it exists var eraEndAttributeValue = attributeValueService.Queryable().Where(v => v.AttributeId == eraEndAttribute.Id && v.EntityId == person.Id).FirstOrDefault(); if (eraEndAttributeValue != null) { attributeValueService.Delete(eraEndAttributeValue); } // add a history record if (personAnalyticsCategoryId != 0 && personEntityTypeId != 0 && attributeEntityTypeId != 0 && eraAttributeId != 0) { History historyRecord = new History(); historyService.Add(historyRecord); historyRecord.EntityTypeId = personEntityTypeId; historyRecord.EntityId = person.Id; historyRecord.CreatedDateTime = RockDateTime.Now; historyRecord.CreatedByPersonAliasId = person.PrimaryAliasId; historyRecord.Caption = "eRA"; historyRecord.Verb = "ENTERED"; historyRecord.ChangeType = History.HistoryChangeType.Attribute.ConvertToString(); historyRecord.RelatedEntityTypeId = attributeEntityTypeId; historyRecord.RelatedEntityId = eraAttributeId; historyRecord.CategoryId = personAnalyticsCategoryId; historyRecord.SourceOfChange = SOURCE_OF_CHANGE; } updateContext.SaveChanges(); } // launch entry workflow if (entryWorkflowType.HasValue) { LaunchWorkflow(entryWorkflowType.Value, family); } } } // update stats context.UpdateLastStatusMessage($"Updating eRA {progressPosition} of {progressTotal}"); } // load giving attributes context.UpdateLastStatusMessage("Updating Giving..."); resultContext.Database.ExecuteSqlCommand("spCrm_FamilyAnalyticsGiving"); // load attendance attributes context.UpdateLastStatusMessage("Updating Attendance..."); resultContext.Database.ExecuteSqlCommand("spCrm_FamilyAnalyticsAttendance"); // process visit dates if (updateVisitDates) { context.UpdateLastStatusMessage("Updating Visit Dates..."); resultContext.Database.ExecuteSqlCommand("spCrm_FamilyAnalyticsUpdateVisitDates"); } context.UpdateLastStatusMessage(""); }
/// <summary> /// Shows the details. /// </summary> private void ShowDetails() { var rockContext = new RockContext(); var scheduledTransaction = this.GetFinancialScheduledTransaction(rockContext); if (scheduledTransaction == null) { // Note: Also verified in OnInit ShowConfigurationMessage(NotificationBoxType.Warning, "Warning", "Scheduled Transaction not found."); return; } var financialScheduledTransactionService = new FinancialScheduledTransactionService(rockContext); string errorMessages; if (!financialScheduledTransactionService.GetStatus(scheduledTransaction, out errorMessages)) { ShowConfigurationMessage(NotificationBoxType.Danger, "Error", errorMessages); return; } hfScheduledTransactionGuid.Value = scheduledTransaction.Guid.ToString(); List <int> selectableAccountIds = new FinancialAccountService(rockContext).GetByGuids(this.GetAttributeValues(AttributeKey.AccountsToDisplay).AsGuidList()).Select(a => a.Id).ToList(); CampusAccountAmountPicker.AccountIdAmount[] accountAmounts = scheduledTransaction.ScheduledTransactionDetails.Select(a => new CampusAccountAmountPicker.AccountIdAmount(a.AccountId, a.Amount)).ToArray(); // if the scheduledTransaction already has Multiple Account, enabled multi account mode. Otherwise, only enabled multi account based on the block setting. var hasMultipleAccounts = accountAmounts.Length > 1; bool enableMultiAccount = hasMultipleAccounts || this.GetAttributeValue(AttributeKey.EnableMultiAccount).AsBoolean(); if (enableMultiAccount) { caapPromptForAccountAmounts.AmountEntryMode = CampusAccountAmountPicker.AccountAmountEntryMode.MultipleAccounts; } else { caapPromptForAccountAmounts.AmountEntryMode = CampusAccountAmountPicker.AccountAmountEntryMode.SingleAccount; } caapPromptForAccountAmounts.AskForCampusIfKnown = this.GetAttributeValue(AttributeKey.AskForCampusIfKnown).AsBoolean(); caapPromptForAccountAmounts.SelectableAccountIds = selectableAccountIds.ToArray(); if (!caapPromptForAccountAmounts.SelectableAccountIds.Any()) { ShowConfigurationMessage(NotificationBoxType.Warning, "Configuration", "At least one Financial Account must be selected in the configuration for this block."); pnlPromptForChanges.Visible = false; return; } if (this.FinancialGateway == null) { ShowConfigurationMessage(NotificationBoxType.Warning, "Configuration", "Unable to determine the financial gateway for this scheduled transaction."); pnlPromptForChanges.Visible = false; return; } if (this.FinancialGatewayComponent == null || !(this.FinancialGatewayComponent is IHostedGatewayComponent)) { ShowConfigurationMessage(NotificationBoxType.Danger, "Configuration", "This page is not configured to allow edits for the payment gateway associated with the selected transaction."); pnlPromptForChanges.Visible = false; return; } caapPromptForAccountAmounts.AccountAmounts = accountAmounts; var targetPerson = scheduledTransaction.AuthorizedPersonAlias.Person; SetAccountPickerCampus(targetPerson); int oneTimeFrequencyId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME.AsGuid()) ?? 0; ddlFrequency.Items.Clear(); var supportedFrequencies = this.FinancialGatewayComponent.SupportedPaymentSchedules; foreach (var supportedFrequency in supportedFrequencies) { // If this isn't a one-time scheduled transaction, don't allow changing scheduled transaction to a one-time, if (scheduledTransaction.TransactionFrequencyValueId == oneTimeFrequencyId || supportedFrequency.Id != oneTimeFrequencyId) { ddlFrequency.Items.Add(new ListItem(supportedFrequency.Value, supportedFrequency.Id.ToString())); } } ddlFrequency.SetValue(scheduledTransaction.TransactionFrequencyValueId); /* 2020-02-26 MDP: Payment prompt behavior.. * - No Saved Accounts * - Show text with existing payment method with a 'Change' link. * - If 'Change' is clicked, existing payment info prompt will disappear and hosted payment will be displayed * - Has Saved Accounts * - Show RadioButtons with first item with the existing payment as the option, followed by saved accounts * - Then under the RadioButtons show a 'Add Method'. * - If 'Add Method' is clicked, RadioButtons will disappear and hosted payment will be displayed */ string paymentName; if (scheduledTransaction.FinancialPaymentDetail.FinancialPersonSavedAccountId.HasValue) { paymentName = scheduledTransaction.FinancialPaymentDetail.FinancialPersonSavedAccount.Name; } else { paymentName = scheduledTransaction.FinancialPaymentDetail.CurrencyTypeValue?.Value; } string existingPaymentInfoDisplayText; if (scheduledTransaction.FinancialPaymentDetail.ExpirationDate.IsNotNullOrWhiteSpace()) { existingPaymentInfoDisplayText = $"Existing Payment Method - {paymentName} ({scheduledTransaction.FinancialPaymentDetail.AccountNumberMasked} Expires: {scheduledTransaction.FinancialPaymentDetail.ExpirationDate})"; } else { existingPaymentInfoDisplayText = $"Existing Payment Method - {paymentName} ({scheduledTransaction.FinancialPaymentDetail.AccountNumberMasked})"; } lUseExistingPaymentMethodNoSavedAccounts.Text = existingPaymentInfoDisplayText; var personSavedAccountList = GetSavedAccounts(); pnlHostedPaymentControl.Visible = false; if (personSavedAccountList.Any()) { pnlUseExistingPaymentWithSavedAccounts.Visible = true; pnlUseExistingPaymentNoSavedAccounts.Visible = false; BindPersonSavedAccounts(personSavedAccountList); rblExistingPaymentOrPersonSavedAccount.Items.Insert(0, new ListItem(existingPaymentInfoDisplayText, "0")); // default to using existing payment method rblExistingPaymentOrPersonSavedAccount.SetValue(0); } else { // no saved account, so just prompt for payment info (or using existing payment info) pnlUseExistingPaymentNoSavedAccounts.Visible = true; pnlUseExistingPaymentWithSavedAccounts.Visible = false; } dtpStartDate.SelectedDate = scheduledTransaction.NextPaymentDate; // NOTE: Depending on the Gateway, the earliest date could be more than 1-2+ days in the future var earliestScheduledStartDate = FinancialGatewayComponent.GetEarliestScheduledStartDate(FinancialGateway); if (dtpStartDate.SelectedDate.HasValue && dtpStartDate.SelectedDate.Value < earliestScheduledStartDate) { dtpStartDate.SelectedDate = earliestScheduledStartDate; } var person = scheduledTransaction.AuthorizedPersonAlias.Person; Location billingLocation = null; // default to the billing location of the scheduled transaction, or the mailing location if unable to get a billing location from the scheduled transaction. if (scheduledTransaction.FinancialPaymentDetail != null) { billingLocation = scheduledTransaction.FinancialPaymentDetail.BillingLocation; } if (billingLocation == null) { billingLocation = person.GetMailingLocation(); } acBillingAddress.SetValues(billingLocation); }
/// <summary> /// Shows the detail. /// </summary> private void ShowDetail() { // just in case the local device config had some overrides (from the MobileLauncher Block) LocalDeviceConfig.ClearOverrides(); SaveState(); bool enableLocationSharing = GetAttributeValue(AttributeKey.EnableLocationSharing).AsBoolean(); bool allowManualSetup = GetAttributeValue(AttributeKey.AllowManualSetup).AsBoolean(true); // 1. Match by IP/DNS first. AttemptKioskMatchByIpOrName(); // 2. Then attempt to match by Geo location if enabled. if (enableLocationSharing) { lbRetry.Visible = true; // We'll re-enable things if the geo lookup fails. pnlManualConfig.AddCssClass("hidden"); lbOk.AddCssClass("hidden"); // Inject script used for geo location determination AddGeoLocationScript(); } // 3. Allow manual setup if enabled. if (allowManualSetup) { pnlManualConfig.Visible = true; lbOk.Visible = true; } // // If neither location sharing nor manual setup are enabled // then display a friendly message. // if (!enableLocationSharing && !allowManualSetup) { lbRetry.Visible = true; nbGeoMessage.NotificationBoxType = NotificationBoxType.Danger; nbGeoMessage.Text = "Manual configuration is not currently enabled."; } ddlTheme.Items.Clear(); DirectoryInfo di = new DirectoryInfo(this.Page.Request.MapPath(ResolveRockUrl("~~"))); foreach (var themeDir in di.Parent.EnumerateDirectories().OrderBy(a => a.Name)) { ddlTheme.Items.Add(new ListItem(themeDir.Name, themeDir.Name.ToLower())); } if (!string.IsNullOrWhiteSpace(LocalDeviceConfig.CurrentTheme)) { ddlTheme.SetValue(LocalDeviceConfig.CurrentTheme); SetSelectedTheme(LocalDeviceConfig.CurrentTheme); } else { ddlTheme.SetValue(RockPage.Site.Theme.ToLower()); } int?kioskDeviceTypeValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.DEVICE_TYPE_CHECKIN_KIOSK.AsGuid()); ddlKiosk.Items.Clear(); using (var rockContext = new RockContext()) { ddlKiosk.DataSource = new DeviceService(rockContext) .Queryable().AsNoTracking() .Where(d => d.DeviceTypeValueId == kioskDeviceTypeValueId && d.IsActive) .OrderBy(d => d.Name) .Select(d => new { d.Id, d.Name }) .ToList(); } ddlKiosk.DataBind(); ddlKiosk.Items.Insert(0, new ListItem(None.Text, None.IdValue)); ddlKiosk.SetValue(this.LocalDeviceConfig.CurrentKioskId); BindCheckinTypes(this.LocalDeviceConfig.CurrentCheckinTypeId); BindGroupTypes(this.LocalDeviceConfig.CurrentGroupTypeIds); }
/// <summary> /// Shows the details. /// </summary> private void ShowDetails() { var scheduledTransaction = this.GetFinancialScheduledTransaction(new RockContext()); if (scheduledTransaction == null) { // todo: show a warning return; } hfScheduledTransactionId.Value = scheduledTransaction.Id.ToString(); var accountAmounts = scheduledTransaction.ScheduledTransactionDetails.Select(a => new CampusAccountAmountPicker.AccountIdAmount(a.AccountId, a.Amount)).ToArray(); // if the scheduledTransaction already has Multiple Account, enabled multi account mode. Otherwise, only enabled multi account based on the block setting. var hasMultipleAccounts = accountAmounts.Length > 1; bool enableMultiAccount = hasMultipleAccounts || this.GetAttributeValue(AttributeKey.EnableMultiAccount).AsBoolean(); if (enableMultiAccount) { caapPromptForAccountAmounts.AmountEntryMode = CampusAccountAmountPicker.AccountAmountEntryMode.MultipleAccounts; } else { caapPromptForAccountAmounts.AmountEntryMode = CampusAccountAmountPicker.AccountAmountEntryMode.SingleAccount; } caapPromptForAccountAmounts.AskForCampusIfKnown = this.GetAttributeValue(AttributeKey.AskForCampusIfKnown).AsBoolean(); caapPromptForAccountAmounts.AccountAmounts = accountAmounts; int oneTimeFrequencyId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME.AsGuid()) ?? 0; ddlFrequency.Items.Clear(); var supportedFrequencies = this.FinancialGatewayComponent.SupportedPaymentSchedules; foreach (var supportedFrequency in supportedFrequencies.Where(a => a.Id != oneTimeFrequencyId)) { ddlFrequency.Items.Add(new ListItem(supportedFrequency.Value, supportedFrequency.Id.ToString())); } ddlFrequency.SetValue(scheduledTransaction.TransactionFrequencyValueId); BindPersonSavedAccounts(); dtpStartDate.SelectedDate = scheduledTransaction.NextPaymentDate; var person = scheduledTransaction.AuthorizedPersonAlias.Person; Location billingLocation = null; // default to the billing location of the scheduled transaction, or the mailing location if unable to get a billing location from the scheduled transaction. if (scheduledTransaction.FinancialPaymentDetail != null) { billingLocation = scheduledTransaction.FinancialPaymentDetail.BillingLocation; } if (billingLocation == null) { billingLocation = person.GetMailingLocation(); } acBillingAddress.SetValues(billingLocation); }
/// <summary> /// Handles the Click event of the btnMigrateScheduledTransactions 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 btnMigrateScheduledTransactions_Click(object sender, EventArgs e) { var rockContext = new RockContext(); var binaryFileService = new BinaryFileService(rockContext); var binaryFileId = fuScheduleImportFile.BinaryFileId; BinaryFile binaryFile = null; if (binaryFileId.HasValue) { binaryFile = binaryFileService.Get(binaryFileId.Value); } Dictionary <string, string> subscriptionImportRecordLookup = null; var importData = binaryFile.ContentsToString(); StringReader stringReader = new StringReader(importData); CsvReader csvReader = new CsvReader(stringReader); csvReader.Configuration.HasHeaderRecord = false; subscriptionImportRecordLookup = csvReader.GetRecords <SubscriptionCustomerImportRecord>().ToDictionary(k => k.NMISubscriptionId, v => v.PiCustomerId); var financialGatewayService = new FinancialGatewayService(rockContext); var nmiFinancialGatewayId = ddlNMIGateway.SelectedValue.AsInteger(); var nmiFinancialGateway = financialGatewayService.Get(nmiFinancialGatewayId); var nmiGatewayComponent = nmiFinancialGateway.GetGatewayComponent(); var piFinancialGatewayId = ddlPiGateway.SelectedValue.AsInteger(); var piFinancialGateway = financialGatewayService.Get(piFinancialGatewayId); var piGatewayComponent = piFinancialGateway.GetGatewayComponent() as IHostedGatewayComponent; var financialScheduledTransactionService = new FinancialScheduledTransactionService(rockContext); // Get the ScheduledTransaction with NoTracking. If we need to update it, we'll track it with a different rockContext then save it. // Limit to active subscriptions that have a NextPaymentDate (onetime or canceled schedules might not have a NextPaymentDate) var scheduledTransactions = financialScheduledTransactionService.Queryable().Where(a => a.FinancialGatewayId == nmiFinancialGatewayId & a.IsActive && a.NextPaymentDate.HasValue).AsNoTracking().ToList(); var earliestPiStartDate = piGatewayComponent.GetEarliestScheduledStartDate(piFinancialGateway); var oneTimeFrequencyId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME.AsGuid()); string errorMessage; var scheduledTransactionResultsBuilder = new StringBuilder(); var scheduledTransactionCount = scheduledTransactions.Count(); var scheduledTransactionProgress = 0; // Migrating Scheduled Transactions might take a while. Each migrated Scheduled Payment may take a half second or so to create on the Pi Gateway. var importTask = new Task(() => { // wait a little so the browser can render and start listening to events Task.Delay(1000).Wait(); _hubContext.Clients.All.setButtonVisibilty(this.SignalRNotificationKey, false); foreach (var scheduledTransaction in scheduledTransactions) { System.Threading.Thread.Sleep(1000); UpdateProgressMessage(string.Format("Migrating Scheduled Transactions: {0} of {1}", scheduledTransactionProgress, scheduledTransactionCount), " "); scheduledTransactionProgress++; var nmiSubscriptionId = scheduledTransaction.GatewayScheduleId; var nmiCustomerId = scheduledTransaction.ForeignKey; var piCustomerId = subscriptionImportRecordLookup.GetValueOrNull(nmiSubscriptionId); if (piCustomerId == null) { scheduledTransactionResultsBuilder.AppendFormat( "WARNING: No Pi CustomerId found for Financial Scheduled Transaction with Id: {0} which is associated NMI SubscriptionId: '{1}'" + Environment.NewLine, scheduledTransaction.Id, nmiSubscriptionId ); continue; } // Pi requires that NextPaymentDate is in the Future (using UTC). That math is done in the gateway implementation... // if the NextPayment null or earlier than whatever Pi considers the earliest start date, see if we can fix that up by calling GetStatus if (scheduledTransaction.NextPaymentDate == null || scheduledTransaction.NextPaymentDate < earliestPiStartDate) { financialScheduledTransactionService.GetStatus(scheduledTransaction, out errorMessage); } if (scheduledTransaction.NextPaymentDate == null) { // Shouldn't happen, but just in case scheduledTransactionResultsBuilder.AppendFormat( "WARNING: Unknown NextPaymentDate for FinancialScheduledTransaction.Id: {0} NMI SubscriptionId: '{1}'" + Environment.NewLine, scheduledTransaction.Id, nmiSubscriptionId ); continue; } if (scheduledTransaction.NextPaymentDate < earliestPiStartDate) { if ((scheduledTransaction.NextPaymentDate > RockDateTime.Today) && earliestPiStartDate.Subtract(scheduledTransaction.NextPaymentDate.Value).TotalDays <= 2) { // if the NextPaymentDate is after Today but before the Earliest Pi Start Date, it'll be off by less than 24 hrs, so just reschedule it for the Earliest Pi Start Date scheduledTransaction.NextPaymentDate = earliestPiStartDate; } else { // if the NextPaymentDate is still too early AFTER getting the most recent status, then we can't safely figure it out, so report it scheduledTransactionResultsBuilder.AppendFormat( "WARNING: NextPaymentDate of {0} for FinancialScheduledTransaction.Id: {1} and NMI SubscriptionId: '{2}' must have a NextPaymentDate of at least {3}." + Environment.NewLine, scheduledTransaction.NextPaymentDate, scheduledTransaction.Id, nmiSubscriptionId, earliestPiStartDate ); } } // create a subscription in the Pi System, then cancel the one on the NMI system PaymentSchedule paymentSchedule = new PaymentSchedule { TransactionFrequencyValue = DefinedValueCache.Get(scheduledTransaction.TransactionFrequencyValueId), StartDate = scheduledTransaction.NextPaymentDate.Value, PersonId = scheduledTransaction.AuthorizedPersonAlias.PersonId }; ReferencePaymentInfo referencePaymentInfo = new ReferencePaymentInfo { GatewayPersonIdentifier = piCustomerId, Description = string.Format("Migrated from NMI SubscriptionID:{0}", nmiSubscriptionId) }; var piGateway = (piGatewayComponent as PiGateway); string alreadyMigratedPiSubscriptionId = null; if (piGateway != null) { var customerPiSubscriptions = piGateway.SearchCustomerSubscriptions(piFinancialGateway, piCustomerId); alreadyMigratedPiSubscriptionId = customerPiSubscriptions.Data.Where(a => a.Description.Contains(referencePaymentInfo.Description)).Select(a => a.Customer.Id).FirstOrDefault(); } if (string.IsNullOrEmpty(alreadyMigratedPiSubscriptionId)) { // hasn't already been migrated, so go ahead and migrate it var tempFinancialScheduledTransaction = piGatewayComponent.AddScheduledPayment(piFinancialGateway, paymentSchedule, referencePaymentInfo, out errorMessage); if (tempFinancialScheduledTransaction != null) { ////////////#### DISABLE this when debugger ##### nmiGatewayComponent.CancelScheduledPayment(scheduledTransaction, out errorMessage); // update the scheduled transaction to point to the Pi scheduled transaction using (var updateRockContext = new RockContext()) { // Attach the person to the updateRockContext so that it'll be tracked/saved using updateRockContext updateRockContext.FinancialScheduledTransactions.Attach(scheduledTransaction); scheduledTransaction.TransactionCode = tempFinancialScheduledTransaction.TransactionCode; scheduledTransaction.GatewayScheduleId = tempFinancialScheduledTransaction.GatewayScheduleId; scheduledTransaction.FinancialGatewayId = tempFinancialScheduledTransaction.FinancialGatewayId; updateRockContext.SaveChanges(); } scheduledTransactionResultsBuilder.AppendFormat( "SUCCESS: Scheduled Transaction migration succeeded. (FinancialScheduledTransaction.Id: {0}, NMI SubscriptionId: '{1}', Pi CustomerId: {2}, Pi SubscriptionId: {3})" + Environment.NewLine, scheduledTransaction.Id, nmiSubscriptionId, piCustomerId, scheduledTransaction.GatewayScheduleId ); } else { scheduledTransactionResultsBuilder.AppendFormat( "ERROR: Scheduled Transaction migration failed. ErrorMessage: {0}, FinancialScheduledTransaction.Id: {1}, NMI SubscriptionId: '{2}', Pi CustomerId: {3}" + Environment.NewLine, errorMessage, scheduledTransaction.Id, nmiSubscriptionId, piCustomerId ); } } else { scheduledTransactionResultsBuilder.AppendFormat( "INFO: Scheduled Transaction already migrated to PI. FinancialScheduledTransaction.Id: {0}, NMI SubscriptionId: '{1}', Pi SubscriptionId: '{2}', Pi CustomerId: {3}" + Environment.NewLine, scheduledTransaction.Id, nmiSubscriptionId, alreadyMigratedPiSubscriptionId, piCustomerId ); } } }); string importResult = string.Empty; importTask.ContinueWith((c) => { if (c.Exception != null) { ExceptionLogService.LogException(c.Exception); scheduledTransactionResultsBuilder.AppendLine(string.Format("EXCEPTION: {0}", c.Exception.Flatten().Message)); importResult = "EXCEPTION"; UpdateProgressMessage(importResult, scheduledTransactionResultsBuilder.ToString()); } else { importResult = "Migrate Scheduled Transactions Completed Successfully"; UpdateProgressMessage(importResult, scheduledTransactionResultsBuilder.ToString()); } this.SetBlockUserPreference("MigrateScheduledTransactionsResultSummary", importResult); this.SetBlockUserPreference("MigrateScheduledTransactionsResultDetails", scheduledTransactionResultsBuilder.ToString()); }); importTask.Start(); nbMigrateScheduledTransactions.Visible = false; // wait for 5 seconds to see if this happens fast enough to do without Signal R. Otherwise, let the importTask continue and send progress to Signal R. var waitResult = importTask.Wait(5000); if (waitResult) { // wait just a little bit to make sure the importResult gets set System.Threading.Thread.Sleep(1000); nbMigrateScheduledTransactions.Visible = true; nbMigrateScheduledTransactions.Title = "Success"; nbMigrateScheduledTransactions.NotificationBoxType = Rock.Web.UI.Controls.NotificationBoxType.Success; var resultDetails = scheduledTransactionResultsBuilder.ToString(); if (resultDetails.Contains("ERROR") || resultDetails.Contains("WARNING")) { nbMigrateScheduledTransactions.Title = "Completed with Warnings"; nbMigrateScheduledTransactions.NotificationBoxType = Rock.Web.UI.Controls.NotificationBoxType.Info; } nbMigrateScheduledTransactions.Text = importResult; nbMigrateScheduledTransactions.Details = resultDetails.ConvertCrLfToHtmlBr(); } }
/// <summary> /// Shows the edit details. /// </summary> /// <param name="financialStatementTemplate">The financial statement template.</param> private void ShowEditDetails(FinancialStatementTemplate financialStatementTemplate) { if (financialStatementTemplate.Id == 0) { lTitle.Text = ActionTitle.Add(FinancialStatementTemplate.FriendlyTypeName).FormatAsHtmlTitle(); // hide the panel drawer that show created and last modified dates pdAuditDetails.Visible = false; } else { lTitle.Text = financialStatementTemplate.Name.FormatAsHtmlTitle(); } hlInactive.Visible = !financialStatementTemplate.IsActive; SetEditMode(true); LoadDropDowns(); tbName.Text = financialStatementTemplate.Name; cbIsActive.Checked = financialStatementTemplate.IsActive; tbDescription.Text = financialStatementTemplate.Description; ceReportTemplate.Text = financialStatementTemplate.ReportTemplate; ceFooterTemplateHtmlFragment.Text = financialStatementTemplate.FooterSettings.HtmlFragment; imgTemplateLogo.BinaryFileId = financialStatementTemplate.LogoBinaryFileId; nbMarginTopMillimeters.IntegerValue = financialStatementTemplate.ReportSettings.PDFSettings.MarginTopMillimeters; nbMarginBottomMillimeters.IntegerValue = financialStatementTemplate.ReportSettings.PDFSettings.MarginBottomMillimeters; nbMarginLeftMillimeters.IntegerValue = financialStatementTemplate.ReportSettings.PDFSettings.MarginLeftMillimeters; nbMarginRightMillimeters.IntegerValue = financialStatementTemplate.ReportSettings.PDFSettings.MarginRightMillimeters; ddlPaperSize.SetValue(financialStatementTemplate.ReportSettings.PDFSettings.PaperSize.ConvertToInt()); var transactionSetting = financialStatementTemplate.ReportSettings.TransactionSettings; cbHideRefundedTransactions.Checked = transactionSetting.HideRefundedTransactions; cbHideModifiedTransactions.Checked = transactionSetting.HideCorrectedTransactionOnSameData; dvpCurrencyTypesCashGifts.SetValues(transactionSetting.CurrencyTypesForCashGiftGuids.Select(a => DefinedValueCache.GetId(a)).Where(a => a.HasValue).Select(a => a.Value).ToList()); dvpCurrencyTypesNonCashGifts.SetValues(transactionSetting.CurrencyTypesForNonCashGuids.Select(a => DefinedValueCache.GetId(a)).Where(a => a.HasValue).Select(a => a.Value).ToList()); dvpTransactionType.SetValues(transactionSetting.TransactionTypeGuids.Select(a => DefinedValueCache.GetId(a)).Where(a => a.HasValue).Select(a => a.Value).ToList()); rbAllTaxDeductibleAccounts.Checked = transactionSetting.AccountSelectionOption == FinancialStatementTemplateTransactionSettingAccountSelectionOption.AllTaxDeductibleAccounts; rbUseCustomAccountIds.Checked = transactionSetting.AccountSelectionOption != FinancialStatementTemplateTransactionSettingAccountSelectionOption.AllTaxDeductibleAccounts; if (transactionSetting.SelectedAccountIds.Any()) { var accountList = new FinancialAccountService(new RockContext()) .GetByIds(transactionSetting.SelectedAccountIds) .Where(a => a.IsActive) .ToList(); apTransactionAccountsCustom.SetValues(accountList); } cbIncludeChildAccountsCustom.Checked = transactionSetting.AccountSelectionOption == FinancialStatementTemplateTransactionSettingAccountSelectionOption.SelectedAccountsIncludeChildren; apTransactionAccountsCustom.Visible = transactionSetting.AccountSelectionOption != FinancialStatementTemplateTransactionSettingAccountSelectionOption.AllTaxDeductibleAccounts; cbIncludeChildAccountsCustom.Visible = apTransactionAccountsCustom.Visible; var pledgeSetting = financialStatementTemplate.ReportSettings.PledgeSettings; cbIncludeGiftsToChildAccounts.Checked = pledgeSetting.IncludeGiftsToChildAccounts; cbIncludeNonCashGifts.Checked = pledgeSetting.IncludeNonCashGifts; if (pledgeSetting.AccountIds.Any()) { var accountList = new FinancialAccountService(new RockContext()) .GetByIds(pledgeSetting.AccountIds) .Where(a => a.IsActive) .ToList(); apPledgeAccounts.SetValues(accountList); } }
/// <summary> /// Shows the details. /// </summary> private void ShowDetails() { var rockContext = new RockContext(); var scheduledTransaction = this.GetFinancialScheduledTransaction(rockContext); if (scheduledTransaction == null) { // Note: Also verified in OnInit ShowConfigurationMessage(NotificationBoxType.Warning, "Warning", "Scheduled Transaction not found."); return; } hfScheduledTransactionId.Value = scheduledTransaction.Id.ToString(); List <int> selectableAccountIds = new FinancialAccountService(rockContext).GetByGuids(this.GetAttributeValues(AttributeKey.AccountsToDisplay).AsGuidList()).Select(a => a.Id).ToList(); CampusAccountAmountPicker.AccountIdAmount[] accountAmounts = scheduledTransaction.ScheduledTransactionDetails.Select(a => new CampusAccountAmountPicker.AccountIdAmount(a.AccountId, a.Amount)).ToArray(); // if the scheduledTransaction already has Multiple Account, enabled multi account mode. Otherwise, only enabled multi account based on the block setting. var hasMultipleAccounts = accountAmounts.Length > 1; bool enableMultiAccount = hasMultipleAccounts || this.GetAttributeValue(AttributeKey.EnableMultiAccount).AsBoolean(); if (enableMultiAccount) { caapPromptForAccountAmounts.AmountEntryMode = CampusAccountAmountPicker.AccountAmountEntryMode.MultipleAccounts; } else { caapPromptForAccountAmounts.AmountEntryMode = CampusAccountAmountPicker.AccountAmountEntryMode.SingleAccount; } caapPromptForAccountAmounts.AskForCampusIfKnown = this.GetAttributeValue(AttributeKey.AskForCampusIfKnown).AsBoolean(); caapPromptForAccountAmounts.SelectableAccountIds = selectableAccountIds.ToArray(); if (!caapPromptForAccountAmounts.SelectableAccountIds.Any()) { ShowConfigurationMessage(NotificationBoxType.Warning, "Configuration", "At least one Financial Account must be selected in the configuration for this block."); pnlPromptForChanges.Visible = false; return; } caapPromptForAccountAmounts.AccountAmounts = accountAmounts; var targetPerson = scheduledTransaction.AuthorizedPersonAlias.Person; SetAccountPickerCampus(targetPerson); int oneTimeFrequencyId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME.AsGuid()) ?? 0; ddlFrequency.Items.Clear(); var supportedFrequencies = this.FinancialGatewayComponent.SupportedPaymentSchedules; foreach (var supportedFrequency in supportedFrequencies.Where(a => a.Id != oneTimeFrequencyId)) { ddlFrequency.Items.Add(new ListItem(supportedFrequency.Value, supportedFrequency.Id.ToString())); } ddlFrequency.SetValue(scheduledTransaction.TransactionFrequencyValueId); BindPersonSavedAccounts(); dtpStartDate.SelectedDate = scheduledTransaction.NextPaymentDate; // NOTE: Depending on the Gateway, the earliest date could be more than 1-2+ days in the future var earliestScheduledStartDate = FinancialGatewayComponent.GetEarliestScheduledStartDate(FinancialGateway); if (dtpStartDate.SelectedDate.HasValue && dtpStartDate.SelectedDate.Value < earliestScheduledStartDate) { dtpStartDate.SelectedDate = earliestScheduledStartDate; } var person = scheduledTransaction.AuthorizedPersonAlias.Person; Location billingLocation = null; // default to the billing location of the scheduled transaction, or the mailing location if unable to get a billing location from the scheduled transaction. if (scheduledTransaction.FinancialPaymentDetail != null) { billingLocation = scheduledTransaction.FinancialPaymentDetail.BillingLocation; } if (billingLocation == null) { billingLocation = person.GetMailingLocation(); } acBillingAddress.SetValues(billingLocation); }