/// <summary> /// Get a list of all inherited Attributes that should be applied to this entity. /// </summary> /// <returns>A list of all inherited AttributeCache objects.</returns> public override List <AttributeCache> GetInheritedAttributes(Rock.Data.RockContext rockContext) { var entityTypeCache = EntityTypeCache.Read(TypeId); // Get the registration var registration = this.Registration; if (registration == null && this.RegistrationId > 0) { registration = new RegistrationService(rockContext) .Queryable().AsNoTracking() .FirstOrDefault(r => r.Id == this.RegistrationId); } if (entityTypeCache == null || registration == null) { return(null); } // Get the instance var registrationInstance = registration.RegistrationInstance; if (registrationInstance == null && registration.RegistrationInstanceId > 0) { registrationInstance = new RegistrationInstanceService(rockContext) .Queryable().AsNoTracking() .FirstOrDefault(r => r.Id == registration.RegistrationInstanceId); } if (registrationInstance == null) { return(null); } // Get all attributes there were defined for instance's template. var attributes = new List <Rock.Web.Cache.AttributeCache>(); foreach (var entityAttributes in AttributeCache.GetByEntity(entityTypeCache.Id) .Where(e => e.EntityTypeQualifierColumn == "RegistrationTemplateId" && e.EntityTypeQualifierValue.AsInteger() == registrationInstance.RegistrationTemplateId)) { foreach (int attributeId in entityAttributes.AttributeIds) { attributes.Add(Rock.Web.Cache.AttributeCache.Read(attributeId)); } } return(attributes); }
/// <summary> /// Handles the Click event of the btnSendReminders 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 btnSendReminders_Click( object sender, EventArgs e ) { var registrationsSelected = new List<int>(); int sendCount = 0; gRegistrations.SelectedKeys.ToList().ForEach( r => registrationsSelected.Add( r.ToString().AsInteger() ) ); if ( registrationsSelected.Any() ) { var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read().GetValue( "ExternalApplicationRoot" ); if ( _registrationInstance == null ) { int? registrationInstanceId = PageParameter( "RegistrationInstanceId" ).AsIntegerOrNull(); using ( RockContext rockContext = new RockContext() ) { RegistrationInstanceService registrationInstanceService = new RegistrationInstanceService( rockContext ); _registrationInstance = registrationInstanceService.Queryable( "RegistrationTemplate" ).AsNoTracking() .Where( r => r.Id == registrationInstanceId ).FirstOrDefault(); } foreach( var registrationId in registrationsSelected ) { // use a new rockContext for each registration so that ChangeTracker doesn't get bogged down using ( RockContext rockContext = new RockContext() ) { var registrationService = new RegistrationService( rockContext ); var registration = registrationService.Get( registrationId ); if ( registration != null && !string.IsNullOrWhiteSpace(registration.ConfirmationEmail) ) { var recipients = new List<string>(); Dictionary<string, object> mergeObjects = new Dictionary<string, object>(); mergeObjects.Add( "Registration", registration ); mergeObjects.Add( "RegistrationInstance", _registrationInstance ); recipients.Add( registration.ConfirmationEmail ); string message = ceEmailMessage.Text.ResolveMergeFields( mergeObjects ); Email.Send( txtFromEmail.Text, txtFromName.Text, txtFromSubject.Text, recipients, message, appRoot ); registration.LastPaymentReminderDateTime = RockDateTime.Now; rockContext.SaveChanges(); sendCount++; } } } } } pnlSend.Visible = false; pnlComplete.Visible = true; nbResult.Text = string.Format("Payment reminders have been sent to {0}.", "individuals".ToQuantity( sendCount )); }
/// <summary> /// Creates or update a registration session. This method operates /// inside a database lock to prevent other sessions from being /// modified at the same time. /// </summary> /// <param name="sessionGuid">The session unique identifier.</param> /// <param name="createSession">The method to call to get a new <see cref="RegistrationSession"/> object that will be persisted to the database.</param> /// <param name="updateSession">The method to call to update an existing <see cref="RegistrationSession"/> object with any new information.</param> /// <param name="errorMessage">The error message.</param> /// <returns>The <see cref="RegistrationSession"/> that was created or updated; or <c>null</c> if an error occurred.</returns> public static RegistrationSession CreateOrUpdateSession(Guid sessionGuid, Func <RegistrationSession> createSession, Action <RegistrationSession> updateSession, out string errorMessage) { using (var rockContext = new RockContext()) { var registrationSessionService = new RegistrationSessionService(rockContext); RegistrationSession registrationSession = null; string internalErrorMessage = null; rockContext.WrapTransactionIf(() => { /* * This is an anti-pattern. Do not just copy this and use it * as a pattern elsewhere. Discuss with the team before trying * to use this anywhere else. * * This single use-case was discussed between Jon and Daniel on * 9/17/2021 and deemed the best choice for the moment. In the * future we might convert this to a helper method that doesn't * require custom SQL each place it is used - but we really * shouldn't do full table locks as a matter of practice. * * Daniel Hazelbaker 9/17/2021 */ // Initiate a full table lock so nothing else can query data, // otherwise they might get a count that will no longer be // valid after our transaction is committed. rockContext.Database.ExecuteSqlCommand("SELECT TOP 1 Id FROM [RegistrationSession] WITH (TABLOCKX, HOLDLOCK)"); var registrationService = new RegistrationService(rockContext); // Load the registration session and determine if it was expired already. registrationSession = registrationSessionService.Get(sessionGuid); var wasExpired = registrationSession != null && registrationSession.ExpirationDateTime < RockDateTime.Now; var oldRegistrationCount = registrationSession?.RegistrationCount ?? 0; // If the session didn't exist then create a new one, otherwise // update the existing one. if (registrationSession == null) { registrationSession = createSession(); registrationSessionService.Add(registrationSession); } else { updateSession(registrationSession); } // Get the context information about the registration, specifically // the timeout and spots available. var context = registrationService.GetRegistrationContext(registrationSession.RegistrationInstanceId, out internalErrorMessage); if (internalErrorMessage.IsNotNullOrWhiteSpace()) { return(false); } // Set the new expiration date. registrationSession.ExpirationDateTime = context.RegistrationSettings.TimeoutMinutes.HasValue ? RockDateTime.Now.AddMinutes(context.RegistrationSettings.TimeoutMinutes.Value) : RockDateTime.Now.AddDays(1); // Determine the number of registrants. If the registration was // expired then we need all spots requested again. Otherwise we // just need to be able to reserve the number of new spots since // the last session save. var newRegistrantCount = wasExpired ? registrationSession.RegistrationCount : (registrationSession.RegistrationCount - oldRegistrationCount); // Handle the possibility that there is a change in the number of // registrants in the session. if (context.SpotsRemaining.HasValue && context.SpotsRemaining.Value < newRegistrantCount) { internalErrorMessage = "There is not enough capacity remaining for this many registrants."; return(false); } rockContext.SaveChanges(); internalErrorMessage = string.Empty; return(true); }); errorMessage = internalErrorMessage; return(errorMessage.IsNullOrWhiteSpace() ? registrationSession : null); } }
private void SetHasPayments( int registrationInstanceId, RockContext rockContext ) { var registrationIdQry = new RegistrationService( rockContext ) .Queryable().AsNoTracking() .Where( r => r.RegistrationInstanceId == registrationInstanceId ) .Select( r => r.Id ); var registrationEntityType = EntityTypeCache.Read( typeof( Rock.Model.Registration ) ); hfHasPayments.Value = new FinancialTransactionDetailService( rockContext ) .Queryable().AsNoTracking() .Where( d => d.EntityTypeId.HasValue && d.EntityId.HasValue && d.EntityTypeId.Value == registrationEntityType.Id && registrationIdQry.Contains( d.EntityId.Value ) ) .Any().ToString(); }
/// <summary> /// Executes this instance. /// </summary> public void Execute() { using ( var rockContext = new RockContext() ) { var registration = new RegistrationService( rockContext ) .Queryable( "RegistrationInstance.RegistrationTemplate" ).AsNoTracking() .FirstOrDefault( r => r.Id == RegistrationId ); if ( registration != null && registration.RegistrationInstance != null && !string.IsNullOrEmpty( registration.ConfirmationEmail ) ) { var template = registration.RegistrationInstance.RegistrationTemplate; if ( template != null && !string.IsNullOrWhiteSpace( template.ConfirmationEmailTemplate ) ) { var currentPersonOverride = ( registration.RegistrationInstance.ContactPersonAlias != null ) ? registration.RegistrationInstance.ContactPersonAlias.Person : null; var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields( null, currentPersonOverride ); mergeFields.Add( "RegistrationInstance", registration.RegistrationInstance ); mergeFields.Add( "Registration", registration ); string from = template.ConfirmationFromEmail.ResolveMergeFields( mergeFields ); string fromName = template.ConfirmationFromName.ResolveMergeFields( mergeFields ); string subject = template.ConfirmationSubject.ResolveMergeFields( mergeFields ); string message = template.ConfirmationEmailTemplate.ResolveMergeFields( mergeFields, currentPersonOverride ); var recipients = new List<string> { registration.ConfirmationEmail }; Email.Send( from, fromName, subject, recipients, message, AppRoot, ThemeRoot ); } } } }
/// <summary> /// Gets the discount by the code if valid. This checks if the code exists, is within it's defined date range, and /// has usages remaining. /// </summary> /// <param name="registrationInstanceId">The registration instance identifier.</param> /// <param name="code">The code.</param> /// <returns></returns> public RegistrationTemplateDiscountWithUsage GetDiscountByCodeIfValid(int registrationInstanceId, string code) { if (code.IsNullOrWhiteSpace()) { return(null); } using (var rockContext = new RockContext()) { var discount = Queryable() .FirstOrDefault(d => d.RegistrationTemplate.Instances.Any(i => i.Id == registrationInstanceId) && d.Code.Equals(code, StringComparison.OrdinalIgnoreCase)); if (discount == null) { // The code is not found return(null); } // Validate the date range var today = RockDateTime.Today; if (discount.StartDate.HasValue && today < discount.StartDate.Value) { // Before the discount starts return(null); } if (discount.EndDate.HasValue && today.AddDays(1) > discount.EndDate.Value) { // Discount has expired return(null); } int?usagesRemaining = null; if (discount.MaxUsage.HasValue) { // Check the number of people that have already used this code var usageCount = new RegistrationService(Context as RockContext) .Queryable() .AsNoTracking() .Count(r => r.RegistrationInstanceId == registrationInstanceId && r.DiscountCode.Equals(code, StringComparison.OrdinalIgnoreCase)); usagesRemaining = discount.MaxUsage.Value - usageCount; if (usagesRemaining <= 0) { // Discount has been used up return(null); } } return(new RegistrationTemplateDiscountWithUsage { RegistrationTemplateDiscount = discount, UsagesRemaining = usagesRemaining }); } }
private void LoadState() { int? registrantId = PageParameter( "RegistrantId" ).AsIntegerOrNull(); int? registrationId = PageParameter( "RegistrationId" ).AsIntegerOrNull(); if ( RegistrantState == null ) { var rockContext = new RockContext(); RegistrationRegistrant registrant = null; if ( registrantId.HasValue && registrantId.Value != 0 ) { registrant = new RegistrationRegistrantService( rockContext ) .Queryable( "Registration.RegistrationInstance.RegistrationTemplate.Forms.Fields,Registration.RegistrationInstance.RegistrationTemplate.Fees,PersonAlias.Person,Fees" ).AsNoTracking() .Where( r => r.Id == registrantId.Value ) .FirstOrDefault(); if ( registrant != null && registrant.Registration != null && registrant.Registration.RegistrationInstance != null && registrant.Registration.RegistrationInstance.RegistrationTemplate != null ) { RegistrantState = new RegistrantInfo( registrant, rockContext ); TemplateState = registrant.Registration.RegistrationInstance.RegistrationTemplate; RegistrationInstanceId = registrant.Registration.RegistrationInstanceId; lWizardTemplateName.Text = registrant.Registration.RegistrationInstance.RegistrationTemplate.Name; lWizardInstanceName.Text = registrant.Registration.RegistrationInstance.Name; lWizardRegistrationName.Text = registrant.Registration.ToString(); lWizardRegistrantName.Text = registrant.ToString(); } } if ( TemplateState == null && registrationId.HasValue && registrationId.Value != 0 ) { var registration = new RegistrationService( rockContext ) .Queryable( "RegistrationInstance.RegistrationTemplate.Forms.Fields,RegistrationInstance.RegistrationTemplate.Fees" ).AsNoTracking() .Where( r => r.Id == registrationId.Value ) .FirstOrDefault(); if ( registration != null && registration.RegistrationInstance != null && registration.RegistrationInstance.RegistrationTemplate != null ) { TemplateState = registration.RegistrationInstance.RegistrationTemplate; RegistrationInstanceId = registration.RegistrationInstanceId; lWizardTemplateName.Text = registration.RegistrationInstance.RegistrationTemplate.Name; lWizardInstanceName.Text = registration.RegistrationInstance.Name; lWizardRegistrationName.Text = registration.ToString(); lWizardRegistrantName.Text = "New Registrant"; } } if ( TemplateState != null && RegistrantState == null ) { RegistrantState = new RegistrantInfo(); RegistrantState.RegistrationId = registrationId ?? 0; RegistrantState.Cost = TemplateState.Cost; } if ( registrant != null && registrant.PersonAlias != null && registrant.PersonAlias.Person != null ) { ppPerson.SetValue( registrant.PersonAlias.Person ); } else { ppPerson.SetValue( null ); } if ( RegistrantState != null ) { cbCost.Text = RegistrantState.Cost.ToString( "N2" ); } } }
/// <summary> /// Loads the content. /// </summary> protected void LoadContent() { RockContext rockContext = new RockContext(); var registrationService = new RegistrationService( rockContext ); var qryRegistrations = registrationService.Queryable(); // only show Active registrations qryRegistrations = qryRegistrations .Where( a => a.RegistrationInstance.IsActive == true && !a.IsTemporary ); // limit to the current person int currentPersonId = this.CurrentPersonId ?? 0; qryRegistrations = qryRegistrations.Where( a => a.PersonAlias.PersonId == currentPersonId ); // bring into a list so we can filter on non-database columns var registrationList = qryRegistrations.ToList(); List<Registration> hasDates = registrationList.Where(a => a.RegistrationInstance.Linkages.Any(x => x.EventItemOccurrenceId.HasValue && x.EventItemOccurrence.NextStartDateTime.HasValue)).ToList(); List<Registration> noDates = registrationList.Where( a => !hasDates.Any( d => d.Id == a.Id ) ).OrderBy( x => x.RegistrationInstance.Name ).ToList(); hasDates = hasDates.OrderBy(a => a.RegistrationInstance.Linkages.OrderBy(b => b.EventItemOccurrence.NextStartDateTime).FirstOrDefault().EventItemOccurrence.NextStartDateTime).ToList(); // filter by date range var requestDateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues( GetAttributeValue( "DateRange" ) ?? "-1||" ); if ( requestDateRange.Start.HasValue ) { hasDates = hasDates.Where( a => a.RegistrationInstance.Linkages.OrderBy( b => b.EventItemOccurrence.NextStartDateTime ).FirstOrDefault().EventItemOccurrence.NextStartDateTime >= requestDateRange.Start ).ToList(); } if ( requestDateRange.End.HasValue ) { hasDates = hasDates.Where( a => a.RegistrationInstance.Linkages.OrderBy( b => b.EventItemOccurrence.NextStartDateTime ).FirstOrDefault().EventItemOccurrence.NextStartDateTime < requestDateRange.End ).ToList(); } registrationList = hasDates; registrationList.AddRange(noDates); if ( this.GetAttributeValue( "LimitToOwed" ).AsBooleanOrNull() ?? true ) { registrationList = registrationList.Where( a => a.BalanceDue != 0 ).ToList(); } int? maxResults = GetAttributeValue( "MaxResults" ).AsIntegerOrNull(); if ( maxResults.HasValue && maxResults > 0 ) { registrationList = registrationList.Take( maxResults.Value ).ToList(); } var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields( this.RockPage, this.CurrentPerson ); mergeFields.Add( "Registrations", registrationList ); string template = GetAttributeValue( "LavaTemplate" ); lContent.Text = template.ResolveMergeFields( mergeFields ); // show debug info if ( GetAttributeValue( "EnableDebug" ).AsBoolean() && IsUserAuthorized( Authorization.EDIT ) ) { lDebug.Visible = true; lDebug.Text = mergeFields.lavaDebugInfo( rockContext ); } }
/// <summary> /// Cleans up temporary registrations. /// </summary> private int CleanUpTemporaryRegistrations() { var registrationRockContext = new Rock.Data.RockContext(); int totalRowsDeleted = 0; // clean out any temporary registrations RegistrationService registrationService = new RegistrationService( registrationRockContext ); foreach ( var registration in registrationService.Queryable().Where( bf => bf.IsTemporary == true ).ToList() ) { if ( registration.ModifiedDateTime < RockDateTime.Now.AddHours( -1 ) ) { string errorMessage; if ( registrationService.CanDelete( registration, out errorMessage ) ) { registrationService.Delete( registration ); registrationRockContext.SaveChanges(); totalRowsDeleted++; } } } return totalRowsDeleted; }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click( object sender, EventArgs e ) { if ( RegistrationId.HasValue ) { Registration registration = null; RockContext rockContext = new RockContext(); var registrationService = new RegistrationService( rockContext ); bool newRegistration = false; var changes = new List<string>(); if ( RegistrationId.Value != 0 ) { registration = registrationService.Queryable().Where( g => g.Id == RegistrationId.Value ).FirstOrDefault(); } if ( registration == null ) { registration = new Registration { RegistrationInstanceId = RegistrationInstanceId ?? 0 }; registrationService.Add( registration ); newRegistration = true; changes.Add( "Created Registration" ); } if ( registration != null && RegistrationInstanceId > 0 ) { if ( !registration.PersonAliasId.Equals( ppPerson.PersonAliasId ) ) { string prevPerson = ( registration.PersonAlias != null && registration.PersonAlias.Person != null ) ? registration.PersonAlias.Person.FullName : string.Empty; string newPerson = ppPerson.PersonName; History.EvaluateChange( changes, "Registrar", prevPerson, newPerson ); } registration.PersonAliasId = ppPerson.PersonAliasId; History.EvaluateChange( changes, "First Name", registration.FirstName, tbFirstName.Text ); registration.FirstName = tbFirstName.Text; History.EvaluateChange( changes, "Last Name", registration.LastName, tbLastName.Text ); registration.LastName = tbLastName.Text; History.EvaluateChange( changes, "Confirmation Email", registration.ConfirmationEmail, ebConfirmationEmail.Text ); registration.ConfirmationEmail = ebConfirmationEmail.Text; bool groupChanged = !registration.GroupId.Equals( ddlGroup.SelectedValueAsInt() ); if ( groupChanged ) { History.EvaluateChange( changes, "Group", registration.GroupId, ddlGroup.SelectedValueAsInt() ); registration.GroupId = ddlGroup.SelectedValueAsInt(); } History.EvaluateChange( changes, "Discount Code", registration.DiscountCode, ddlDiscountCode.SelectedValue ); registration.DiscountCode = ddlDiscountCode.SelectedValue; History.EvaluateChange( changes, "Discount Percentage", registration.DiscountPercentage, nbDiscountPercentage.Text.AsDecimal() * 0.01m ); registration.DiscountPercentage = nbDiscountPercentage.Text.AsDecimal() * 0.01m; History.EvaluateChange( changes, "Discount Amount", registration.DiscountAmount, cbDiscountAmount.Text.AsDecimal() ); registration.DiscountAmount = cbDiscountAmount.Text.AsDecimal(); if ( !Page.IsValid ) { return; } if ( !registration.IsValid ) { // Controls will render the error messages return; } // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges() rockContext.WrapTransaction( () => { rockContext.SaveChanges(); HistoryService.SaveChanges( rockContext, typeof( Registration ), Rock.SystemGuid.Category.HISTORY_EVENT_REGISTRATION.AsGuid(), registration.Id, changes ); } ); if ( newRegistration ) { var pageRef = CurrentPageReference; pageRef.Parameters.AddOrReplace("RegistrationId", registration.Id.ToString()); NavigateToPage( pageRef ); } else { // Reload registration Registration = GetRegistration( Registration.Id ); if ( groupChanged && Registration.GroupId.HasValue ) { foreach( var registrant in Registration.Registrants.Where( r => !r.GroupMemberId.HasValue ) ) { AddRegistrantToGroup( registrant.Id ); } // ...Add, reload again Registration = GetRegistration( Registration.Id ); } lWizardRegistrationName.Text = Registration.ToString(); ShowReadonlyDetails( Registration ); } } } }
protected void btnMoveRegistration_Click( object sender, EventArgs e ) { // set the new registration id using ( var rockContext = new RockContext() ) { var registrationService = new RegistrationService( rockContext ); var groupMemberService = new GroupMemberService( rockContext ); var registration = registrationService.Get( Registration.Id ); registration.RegistrationInstanceId = ddlNewRegistrationInstance.SelectedValue.AsInteger(); // Move registrants to new group int? groupId = ddlMoveGroup.SelectedValueAsInt(); if ( groupId.HasValue ) { registration.GroupId = groupId; rockContext.SaveChanges(); var group = new GroupService( rockContext ).Get( groupId.Value ); if ( group != null ) { int? groupRoleId = null; var template = registration.RegistrationInstance.RegistrationTemplate; if ( group.GroupTypeId == template.GroupTypeId && template.GroupMemberRoleId.HasValue ) { groupRoleId = template.GroupMemberRoleId.Value; } if ( !groupRoleId.HasValue ) { groupRoleId = group.GroupType.DefaultGroupRoleId; } if ( !groupRoleId.HasValue ) { groupRoleId = group.GroupType.Roles.OrderBy( r => r.Order ).Select( r => r.Id ).FirstOrDefault(); } if ( groupRoleId.HasValue ) { foreach ( var registrant in registration.Registrants.Where( r => r.PersonAlias != null ) ) { var newGroupMembers = groupMemberService.GetByGroupIdAndPersonId( groupId.Value, registrant.PersonAlias.PersonId ); if ( !newGroupMembers.Any() ) { // Get any existing group member attribute values var existingAttributeValues = new Dictionary<string, string>(); if ( registrant.GroupMemberId.HasValue ) { var existingGroupMember = groupMemberService.Get( registrant.GroupMemberId.Value ); if ( existingGroupMember != null ) { existingGroupMember.LoadAttributes( rockContext ); foreach ( var attributeValue in existingGroupMember.AttributeValues ) { existingAttributeValues.Add( attributeValue.Key, attributeValue.Value.Value ); } } registrant.GroupMember = null; groupMemberService.Delete( existingGroupMember ); } var newGroupMember = new GroupMember(); groupMemberService.Add( newGroupMember ); newGroupMember.Group = group; newGroupMember.PersonId = registrant.PersonAlias.PersonId; newGroupMember.GroupRoleId = groupRoleId.Value; rockContext.SaveChanges(); newGroupMember = groupMemberService.Get( newGroupMember.Id ); newGroupMember.LoadAttributes(); foreach( var attr in newGroupMember.Attributes ) { if ( existingAttributeValues.ContainsKey( attr.Key ) ) { newGroupMember.SetAttributeValue( attr.Key, existingAttributeValues[attr.Key] ); } } newGroupMember.SaveAttributeValues( rockContext ); registrant.GroupMember = newGroupMember; rockContext.SaveChanges(); } } } } } // Reload registration Registration = GetRegistration( Registration.Id ); lWizardInstanceName.Text = Registration.RegistrationInstance.Name; ShowReadonlyDetails( Registration ); } mdMoveRegistration.Hide(); }
/// <summary> /// Handles the Click event of the btnDelete 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 btnDelete_Click( object sender, EventArgs e ) { RockContext rockContext = new RockContext(); if ( RegistrationId.HasValue ) { var registrationService = new RegistrationService( rockContext ); Registration registration = registrationService.Get( RegistrationId.Value ); if ( registration != null ) { if ( !UserCanEdit && !registration.IsAuthorized( Authorization.EDIT, this.CurrentPerson ) ) { mdDeleteWarning.Show( "You are not authorized to delete this registration.", ModalAlertType.Information ); return; } string errorMessage; if ( !registrationService.CanDelete( registration, out errorMessage ) ) { mdDeleteWarning.Show( errorMessage, ModalAlertType.Information ); return; } var changes = new List<string>(); changes.Add( "Deleted registration" ); rockContext.WrapTransaction( () => { HistoryService.SaveChanges( rockContext, typeof( Registration ), Rock.SystemGuid.Category.HISTORY_EVENT_REGISTRATION.AsGuid(), registration.Id, changes ); registrationService.Delete( registration ); rockContext.SaveChanges(); } ); } var pageParams = new Dictionary<string, string>(); pageParams.Add( "RegistrationInstanceId", RegistrationInstanceId.ToString() ); NavigateToParentPage( pageParams ); } }
/// <summary> /// Handles the Click event of the lbDiscountApply 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 lbDiscountApply_Click( object sender, EventArgs e ) { if ( RegistrationState != null ) { RegistrationState.Registrants.ForEach( r => r.DiscountApplies = true ); RegistrationTemplateDiscount discount = null; bool validDiscount = true; string discountCode = tbDiscountCode.Text; if ( !string.IsNullOrWhiteSpace( discountCode ) ) { discount = RegistrationTemplate.Discounts .Where( d => d.Code.Equals( discountCode, StringComparison.OrdinalIgnoreCase ) ) .FirstOrDefault(); if ( discount == null ) { validDiscount = false; nbDiscountCode.Text = string.Format( "'{1}' is not a valid {1}.", discountCode, DiscountCodeTerm ); nbDiscountCode.Visible = true; } if ( validDiscount && discount.MinRegistrants.HasValue && RegistrationState.RegistrantCount < discount.MinRegistrants.Value ) { nbDiscountCode.Text = string.Format( "The '{0}' {1} requires at least {2} registrants.", discountCode, DiscountCodeTerm, discount.MinRegistrants.Value ); nbDiscountCode.Visible = true; validDiscount = false; } if ( validDiscount && discount.StartDate.HasValue && RockDateTime.Today < discount.StartDate.Value ) { nbDiscountCode.Text = string.Format( "The '{0}' {1} is not available yet.", discountCode, DiscountCodeTerm ); nbDiscountCode.Visible = true; validDiscount = false; } if ( validDiscount && discount.EndDate.HasValue && RockDateTime.Today > discount.EndDate.Value ) { nbDiscountCode.Text = string.Format( "The '{0}' {1} has expired.", discountCode, DiscountCodeTerm ); nbDiscountCode.Visible = true; validDiscount = false; } if ( validDiscount && discount.MaxUsage.HasValue && RegistrationInstanceState != null ) { using ( var rockContext = new RockContext() ) { var instances = new RegistrationService( rockContext ) .Queryable().AsNoTracking() .Where( r => r.RegistrationInstanceId == RegistrationInstanceState.Id && ( !RegistrationState.RegistrationId.HasValue || r.Id != RegistrationState.RegistrationId.Value ) && r.DiscountCode == discountCode ) .Count(); if ( instances >= discount.MaxUsage.Value ) { nbDiscountCode.Text = string.Format( "The '{0}' {1} is no longer available.", discountCode, DiscountCodeTerm ); nbDiscountCode.Visible = true; validDiscount = false; } } } if ( validDiscount && discount.MaxRegistrants.HasValue ) { for ( int i = 0; i < RegistrationState.Registrants.Count; i++ ) { RegistrationState.Registrants[i].DiscountApplies = i < discount.MaxRegistrants.Value; } } } else { validDiscount = false; } RegistrationState.DiscountCode = validDiscount ? discountCode : string.Empty; RegistrationState.DiscountPercentage = validDiscount ? discount.DiscountPercentage : 0.0m; RegistrationState.DiscountAmount = validDiscount ? discount.DiscountAmount : 0.0m; CreateDynamicControls( true ); } }
private void ProcessPostSave( bool isNewRegistration, Registration registration, List<int> previousRegistrantIds, RockContext rockContext ) { try { SavePersonNotes( rockContext, previousRegistrantIds, registration ); AddRegistrantsToGroup( rockContext, registration ); string appRoot = ResolveRockUrl( "~/" ); string themeRoot = ResolveRockUrl( "~~/" ); if ( isNewRegistration ) { var confirmation = new Rock.Transactions.SendRegistrationConfirmationTransaction(); confirmation.RegistrationId = registration.Id; confirmation.AppRoot = appRoot; confirmation.ThemeRoot = themeRoot; Rock.Transactions.RockQueue.TransactionQueue.Enqueue( confirmation ); var notification = new Rock.Transactions.SendRegistrationNotificationTransaction(); notification.RegistrationId = registration.Id; notification.AppRoot = appRoot; notification.ThemeRoot = themeRoot; Rock.Transactions.RockQueue.TransactionQueue.Enqueue( notification ); } var registrationService = new RegistrationService( new RockContext() ); var newRegistration = registrationService.Get( registration.Id ); if ( newRegistration != null ) { if ( isNewRegistration ) { if ( RegistrationTemplate.RequiredSignatureDocumentTemplateId.HasValue ) { string email = newRegistration.ConfirmationEmail; if ( string.IsNullOrWhiteSpace( email ) && newRegistration.PersonAlias != null && newRegistration.PersonAlias.Person != null ) { email = newRegistration.PersonAlias.Person.Email; } Guid? adultRole = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid(); var groupMemberService = new GroupMemberService( rockContext ); foreach ( var registrant in newRegistration.Registrants.Where( r => r.PersonAlias != null && r.PersonAlias.Person != null ) ) { var assignedTo = registrant.PersonAlias.Person; var registrantIsAdult = adultRole.HasValue && groupMemberService .Queryable().AsNoTracking() .Any( m => m.PersonId == registrant.PersonAlias.PersonId && m.GroupRole.Guid.Equals( adultRole.Value ) ); if ( !registrantIsAdult && newRegistration.PersonAlias != null && newRegistration.PersonAlias.Person != null ) { assignedTo = newRegistration.PersonAlias.Person; } else { if ( !string.IsNullOrWhiteSpace( registrant.PersonAlias.Person.Email ) ) { email = registrant.PersonAlias.Person.Email; } } if ( DigitalSignatureComponent != null ) { var sendDocumentTxn = new Rock.Transactions.SendDigitalSignatureRequestTransaction(); sendDocumentTxn.SignatureDocumentTemplateId = RegistrationTemplate.RequiredSignatureDocumentTemplateId.Value; sendDocumentTxn.AppliesToPersonAliasId = registrant.PersonAlias.Id; sendDocumentTxn.AssignedToPersonAliasId = assignedTo.PrimaryAliasId ?? 0; sendDocumentTxn.DocumentName = string.Format( "{0}_{1}", RegistrationInstanceState.Name.RemoveSpecialCharacters(), registrant.PersonAlias.Person.FullName.RemoveSpecialCharacters() ); sendDocumentTxn.Email = email; Rock.Transactions.RockQueue.TransactionQueue.Enqueue( sendDocumentTxn ); } } } newRegistration.LaunchWorkflow( RegistrationTemplate.RegistrationWorkflowTypeId, newRegistration.ToString() ); newRegistration.LaunchWorkflow( RegistrationInstanceState.RegistrationWorkflowTypeId, newRegistration.ToString() ); } RegistrationInstanceState = newRegistration.RegistrationInstance; RegistrationState = new RegistrationInfo( newRegistration, rockContext ); RegistrationState.PreviousPaymentTotal = registrationService.GetTotalPayments( registration.Id ); } } catch ( Exception postSaveEx ) { ShowWarning( "The following occurred after processing your " + RegistrationTerm, postSaveEx.Message ); ExceptionLogService.LogException( postSaveEx, Context, RockPage.PageId, RockPage.Layout.SiteId, CurrentPersonAlias ); } }
/// <summary> /// Saves the registration. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="hasPayment">if set to <c>true</c> [has payment].</param> /// <returns></returns> private Registration SaveRegistration( RockContext rockContext, bool hasPayment ) { var registrationService = new RegistrationService( rockContext ); var registrantService = new RegistrationRegistrantService( rockContext ); var personService = new PersonService( rockContext ); var groupMemberService = new GroupMemberService( rockContext ); // variables to keep track of the family that new people should be added to int? singleFamilyId = null; var multipleFamilyGroupIds = new Dictionary<Guid, int>(); var dvcConnectionStatus = DefinedValueCache.Read( GetAttributeValue( "ConnectionStatus" ).AsGuid() ); var dvcRecordStatus = DefinedValueCache.Read( GetAttributeValue( "RecordStatus" ).AsGuid() ); var familyGroupType = GroupTypeCache.Read( Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY ); var adultRoleId = familyGroupType.Roles .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid() ) ) .Select( r => r.Id ) .FirstOrDefault(); var childRoleId = familyGroupType.Roles .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid() ) ) .Select( r => r.Id ) .FirstOrDefault(); var registration = new Registration(); registrationService.Add( registration ); registration.RegistrationInstanceId = RegistrationInstanceState.Id; registration.GroupId = GroupId; registration.FirstName = RegistrationState.FirstName; registration.LastName = RegistrationState.LastName; registration.ConfirmationEmail = RegistrationState.ConfirmationEmail; registration.DiscountCode = RegistrationState.DiscountCode; registration.DiscountAmount = RegistrationState.DiscountAmount; registration.DiscountPercentage = RegistrationState.DiscountPercentage; // If the 'your name' value equals the currently logged in person, use their person alias id if ( CurrentPerson != null && ( CurrentPerson.NickName.Trim().Equals( registration.FirstName.Trim(), StringComparison.OrdinalIgnoreCase ) || CurrentPerson.FirstName.Trim().Equals( registration.FirstName.Trim(), StringComparison.OrdinalIgnoreCase ) ) && CurrentPerson.LastName.Trim().Equals( registration.LastName.Trim(), StringComparison.OrdinalIgnoreCase ) ) { registration.PersonAliasId = CurrentPerson.PrimaryAliasId; } else { // otherwise look for one and one-only match by name/email var personMatches = personService.GetByMatch( registration.FirstName, registration.LastName, registration.ConfirmationEmail ); if ( personMatches.Count() == 1 ) { registration.PersonAliasId = personMatches.First().PrimaryAliasId; } } // If the registration includes a payment, make sure there's an actual person associated to registration if ( hasPayment && !registration.PersonAliasId.HasValue ) { // If a match was not found, create a new person var person = new Person(); person.FirstName = registration.FirstName; person.LastName = registration.LastName; person.IsEmailActive = true; person.Email = registration.ConfirmationEmail; 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; } registration.PersonAliasId = SavePerson( rockContext, person, Guid.NewGuid(), null, null, adultRoleId, childRoleId, multipleFamilyGroupIds, singleFamilyId ); } // Save the registration ( so we can get an id ) rockContext.SaveChanges(); // If the Registration Instance linkage specified a group, load it now Group group = null; if ( GroupId.HasValue ) { group = new GroupService( rockContext ).Get( GroupId.Value ); } // Get each registrant foreach ( var registrantInfo in RegistrationState.Registrants ) { var changes = new List<string>(); var familyChanges = new List<string>(); Person person = null; // Try to find a matching person based on name and email address string firstName = registrantInfo.GetFirstName( RegistrationTemplate ); string lastName = registrantInfo.GetLastName( RegistrationTemplate ); string email = registrantInfo.GetEmail( RegistrationTemplate ); var personMatches = personService.GetByMatch( firstName, lastName, email ); if ( personMatches.Count() == 1 ) { person = personMatches.First(); } if ( person == null ) { // If a match was not found, create a new person person = new Person(); person.FirstName = firstName; person.LastName = lastName; person.IsEmailActive = true; person.Email = email; 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; } } int? campusId = null; Location location = null; // Set any of the template's person fields foreach ( var field in RegistrationTemplate.Forms .SelectMany( f => f.Fields .Where( t => t.FieldSource == RegistrationFieldSource.PersonField ) ) ) { // Find the registrant's value var fieldValue = registrantInfo.FieldValues .Where( f => f.Key == field.Id ) .Select( f => f.Value ) .FirstOrDefault(); if ( fieldValue != null ) { switch ( field.PersonFieldType ) { case RegistrationPersonFieldType.Campus: { if ( fieldValue != null ) { campusId = fieldValue.ToString().AsIntegerOrNull(); } break; } case RegistrationPersonFieldType.Address: { location = fieldValue.ToString().FromJsonOrNull<Location>(); break; } case RegistrationPersonFieldType.Birthdate: { var birthMonth = person.BirthMonth; var birthDay = person.BirthDay; var birthYear = person.BirthYear; person.SetBirthDate( fieldValue as DateTime? ); History.EvaluateChange( changes, "Birth Month", birthMonth, person.BirthMonth ); History.EvaluateChange( changes, "Birth Day", birthDay, person.BirthDay ); History.EvaluateChange( changes, "Birth Year", birthYear, person.BirthYear ); break; } case RegistrationPersonFieldType.Gender: { var newGender = fieldValue.ToString().ConvertToEnumOrNull<Gender>() ?? Gender.Unknown; History.EvaluateChange( changes, "Gender", person.Gender, newGender ); person.Gender = newGender; break; } case RegistrationPersonFieldType.MaritalStatus: { if ( fieldValue != null ) { int? newMaritalStatusId = fieldValue.ToString().AsIntegerOrNull(); History.EvaluateChange( changes, "Marital Status", DefinedValueCache.GetName( person.MaritalStatusValueId ), DefinedValueCache.GetName( newMaritalStatusId ) ); person.MaritalStatusValueId = newMaritalStatusId; } break; } case RegistrationPersonFieldType.MobilePhone: { SavePhone( fieldValue, person, Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE.AsGuid(), changes ); break; } case RegistrationPersonFieldType.HomePhone: { SavePhone( fieldValue, person, Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME.AsGuid(), changes ); break; } case RegistrationPersonFieldType.WorkPhone: { SavePhone( fieldValue, person, Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_WORK.AsGuid(), changes ); break; } } } } // Save the person ( and family if needed ) SavePerson( rockContext, person, registrantInfo.FamilyGuid, campusId, location, adultRoleId, childRoleId, multipleFamilyGroupIds, singleFamilyId ); // Load the person's attributes person.LoadAttributes(); // Set any of the template's person fields foreach ( var field in RegistrationTemplate.Forms .SelectMany( f => f.Fields .Where( t => t.FieldSource == RegistrationFieldSource.PersonAttribute && t.AttributeId.HasValue ) ) ) { // Find the registrant's value var fieldValue = registrantInfo.FieldValues .Where( f => f.Key == field.Id ) .Select( f => f.Value ) .FirstOrDefault(); if ( fieldValue != null ) { var attribute = AttributeCache.Read( field.AttributeId.Value ); if ( attribute != null ) { string originalValue = person.GetAttributeValue( attribute.Key ); string newValue = fieldValue.ToString(); person.SetAttributeValue( attribute.Key, fieldValue.ToString() ); if ( ( originalValue ?? string.Empty ).Trim() != ( newValue ?? string.Empty ).Trim() ) { string formattedOriginalValue = string.Empty; if ( !string.IsNullOrWhiteSpace( originalValue ) ) { formattedOriginalValue = attribute.FieldType.Field.FormatValue( null, originalValue, attribute.QualifierValues, false ); } string formattedNewValue = string.Empty; if ( !string.IsNullOrWhiteSpace( newValue ) ) { formattedNewValue = attribute.FieldType.Field.FormatValue( null, newValue, attribute.QualifierValues, false ); } History.EvaluateChange( changes, attribute.Name, formattedOriginalValue, formattedNewValue ); } } } } person.SaveAttributeValues( rockContext ); GroupMember groupMember = null; // If the registration instance linkage specified a group to add registrant to, add them if there not already // part of that group if ( group != null ) { groupMember = group.Members.Where( m => m.PersonId == person.Id ).FirstOrDefault(); if ( groupMember == null && group.GroupType.DefaultGroupRoleId.HasValue ) { groupMember = new GroupMember(); groupMemberService.Add( groupMember ); groupMember.GroupId = group.Id; groupMember.PersonId = person.Id; if ( RegistrationTemplate.GroupTypeId.HasValue && RegistrationTemplate.GroupTypeId == group.GroupTypeId && RegistrationTemplate.GroupMemberRoleId.HasValue ) { groupMember.GroupRoleId = RegistrationTemplate.GroupMemberRoleId.Value; groupMember.GroupMemberStatus = RegistrationTemplate.GroupMemberStatus; } else { groupMember.GroupRoleId = group.GroupType.DefaultGroupRoleId.Value; groupMember.GroupMemberStatus = GroupMemberStatus.Active; } } rockContext.SaveChanges(); // Set any of the template's group member attributes groupMember.LoadAttributes(); foreach ( var field in RegistrationTemplate.Forms .SelectMany( f => f.Fields .Where( t => t.FieldSource == RegistrationFieldSource.GroupMemberAttribute && t.AttributeId.HasValue ) ) ) { // Find the registrant's value var fieldValue = registrantInfo.FieldValues .Where( f => f.Key == field.Id ) .Select( f => f.Value ) .FirstOrDefault(); if ( fieldValue != null ) { var attribute = AttributeCache.Read( field.AttributeId.Value ); if ( attribute != null ) { groupMember.SetAttributeValue( attribute.Key, fieldValue.ToString() ); } } } groupMember.SaveAttributeValues( rockContext ); } var registrant = new RegistrationRegistrant(); registrantService.Add( registrant ); registrant.RegistrationId = registration.Id; registrant.PersonAliasId = person.PrimaryAliasId; registrant.Cost = registrantInfo.Cost; registrant.GroupMemberId = groupMember != null ? groupMember.Id : (int?)null; // Add or Update fees foreach ( var feeValue in registrantInfo.FeeValues.Where( f => f.Value != null ) ) { foreach ( var uiFee in feeValue.Value ) { var fee = new RegistrationRegistrantFee(); registrant.Fees.Add( fee ); fee.RegistrationTemplateFeeId = feeValue.Key; fee.Option = uiFee.Option; fee.Quantity = uiFee.Quantity; fee.Cost = uiFee.Cost; } } rockContext.SaveChanges(); // Set any of the templat's registrant attributes registrant.LoadAttributes(); foreach ( var field in RegistrationTemplate.Forms .SelectMany( f => f.Fields .Where( t => t.FieldSource == RegistrationFieldSource.RegistrationAttribute && t.AttributeId.HasValue ) ) ) { // Find the registrant's value var fieldValue = registrantInfo.FieldValues .Where( f => f.Key == field.Id ) .Select( f => f.Value ) .FirstOrDefault(); if ( fieldValue != null ) { var attribute = AttributeCache.Read( field.AttributeId.Value ); if ( attribute != null ) { registrant.SetAttributeValue( attribute.Key, fieldValue.ToString() ); } } registrant.SaveAttributeValues( rockContext ); } } return registration; }
/// <summary> /// Shows the success panel /// </summary> private void ShowSuccess( int registrationId ) { lSuccessTitle.Text = "Congratulations"; lSuccess.Text = "You have succesfully completed this registration."; try { using ( var rockContext = new RockContext() ) { var registration = new RegistrationService( rockContext ) .Queryable( "RegistrationInstance.RegistrationTemplate" ) .FirstOrDefault( r => r.Id == registrationId ); if ( registration != null && registration.RegistrationInstance != null && registration.RegistrationInstance.RegistrationTemplate != null ) { var template = registration.RegistrationInstance.RegistrationTemplate; var mergeFields = new Dictionary<string, object>(); mergeFields.Add( "CurrentPerson", CurrentPerson ); mergeFields.Add( "RegistrationInstance", registration.RegistrationInstance ); mergeFields.Add( "Registration", registration ); if ( template != null && !string.IsNullOrWhiteSpace( template.SuccessTitle ) ) { lSuccessTitle.Text = template.SuccessTitle.ResolveMergeFields( mergeFields ); } else { lSuccessTitle.Text = "Congratulations"; } if ( template != null && !string.IsNullOrWhiteSpace( template.SuccessText ) ) { lSuccess.Text = template.SuccessText.ResolveMergeFields( mergeFields ); } else { lSuccess.Text = "You have succesfully completed this " + RegistrationTerm.ToLower(); } // show debug info if ( GetAttributeValue( "EnableDebug" ).AsBoolean() && UserCanEdit ) { lSuccessDebug.Visible = true; lSuccessDebug.Text = mergeFields.lavaDebugInfo(); } } } } catch ( Exception ex ) { ExceptionLogService.LogException( ex, Context, this.RockPage.PageId, this.RockPage.Site.Id, CurrentPersonAlias ); } SetPanel( 3 ); }
/// <summary> /// Gets the group. /// </summary> /// <param name="registrationId">The group identifier.</param> /// <returns></returns> private Registration GetRegistration( int? registrationId, RockContext rockContext = null ) { if ( registrationId.HasValue && registrationId.Value != 0 ) { rockContext = rockContext ?? new RockContext(); var registration = new RegistrationService( rockContext ) .Queryable( "RegistrationInstance.RegistrationTemplate.Forms.Fields,PersonAlias.Person,Group,Registrants.Fees" ).AsNoTracking() .Where( r => r.Id == registrationId.Value ) .FirstOrDefault(); return registration; } return null; }
/// <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; // get registrations where // + template is active // + instance is active // + template has a number of days between reminders // + template as fields needed to send a reminder email // + the registration has a cost // + the registration has been closed within the last xx days (to prevent eternal nagging) using ( RockContext rockContext = new RockContext()) { int sendCount = 0; int registrationInstanceCount = 0; var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read().GetValue( "ExternalApplicationRoot" ); RegistrationService registrationService = new RegistrationService( rockContext ); var currentDate = RockDateTime.Today; var cutoffDays = dataMap.GetIntFromString( "CutoffDate" ); var registrations = registrationService.Queryable( "RegistrationInstance" ) .Where( r => r.RegistrationInstance.RegistrationTemplate.IsActive && r.RegistrationInstance.IsActive == true && (r.RegistrationInstance.RegistrationTemplate.PaymentReminderTimeSpan != null && r.RegistrationInstance.RegistrationTemplate.PaymentReminderTimeSpan != 0) && r.RegistrationInstance.RegistrationTemplate.PaymentReminderEmailTemplate != null && r.RegistrationInstance.RegistrationTemplate.PaymentReminderEmailTemplate.Length > 0 && r.RegistrationInstance.RegistrationTemplate.PaymentReminderFromEmail != null && r.RegistrationInstance.RegistrationTemplate.PaymentReminderFromEmail.Length > 0 && r.RegistrationInstance.RegistrationTemplate.PaymentReminderSubject != null && r.RegistrationInstance.RegistrationTemplate.PaymentReminderSubject.Length > 0 && (r.RegistrationInstance.RegistrationTemplate.Cost != 0 || (r.RegistrationInstance.Cost != null && r.RegistrationInstance.Cost != 0)) && (r.RegistrationInstance.EndDateTime == null || currentDate <= System.Data.Entity.SqlServer.SqlFunctions.DateAdd("day", cutoffDays, r.RegistrationInstance.EndDateTime) ) ) .ToList(); registrationInstanceCount = registrations.Select( r => r.RegistrationInstance.Id ).Distinct().Count(); foreach(var registration in registrations ) { if ( registration.DiscountedCost > registration.TotalPaid ) { var reminderDate = RockDateTime.Now.AddDays( registration.RegistrationInstance.RegistrationTemplate.PaymentReminderTimeSpan.Value * -1 ); if ( registration.LastPaymentReminderDateTime < reminderDate ) { var recipients = new List<string>(); Dictionary<string, object> mergeObjects = new Dictionary<string, object>(); mergeObjects.Add( "Registration", registration ); mergeObjects.Add( "RegistrationInstance", registration.RegistrationInstance ); recipients.Add( registration.ConfirmationEmail ); string message = registration.RegistrationInstance.RegistrationTemplate.PaymentReminderEmailTemplate.ResolveMergeFields( mergeObjects ); string fromEmail = registration.RegistrationInstance.RegistrationTemplate.PaymentReminderFromEmail.ResolveMergeFields( mergeObjects ); string fromName = registration.RegistrationInstance.RegistrationTemplate.PaymentReminderFromName.ResolveMergeFields( mergeObjects ); string subject = registration.RegistrationInstance.RegistrationTemplate.PaymentReminderSubject.ResolveMergeFields( mergeObjects ); Email.Send( fromEmail, fromName, subject, recipients, message, appRoot ); registration.LastPaymentReminderDateTime = RockDateTime.Now; rockContext.SaveChanges(); sendCount++; } } } context.Result = string.Format("Sent {0} from {1}", "reminder".ToQuantity( sendCount ), "registration instances".ToQuantity(registrationInstanceCount) ); } }
/// <summary> /// Handles the Click event of the btnDelete 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 btnDelete_Click( object sender, EventArgs e ) { RockContext rockContext = new RockContext(); if ( RegistrationId.HasValue ) { var registrationService = new RegistrationService( rockContext ); Registration registration = registrationService.Get( RegistrationId.Value ); if ( registration != null ) { if ( !registration.IsAuthorized( Authorization.EDIT, this.CurrentPerson ) ) { mdDeleteWarning.Show( "You are not authorized to delete this registration.", ModalAlertType.Information ); return; } string errorMessage; if ( !registrationService.CanDelete( registration, out errorMessage ) ) { mdDeleteWarning.Show( errorMessage, ModalAlertType.Information ); return; } registrationService.Delete( registration ); rockContext.SaveChanges(); } var pageParams = new Dictionary<string, string>(); pageParams.Add( "RegistrationInstanceId", RegistrationInstanceId.ToString() ); NavigateToParentPage( pageParams ); } }
protected void lbRegister_Click( object sender, EventArgs e ) { var rockContext = new RockContext(); // get the person who was passed in for the registration registar Person person = null; Guid personGuid = Guid.Empty; if ( Request["PersonGuid"] != null ) { personGuid = Request["PersonGuid"].AsGuid(); person = new PersonService( _rockContext ).Get( personGuid ); } if ( person == null ) { lErrors.Text = "<div class='alert alert-warning'>Invalid person guid was passed.</div>"; return; } // get event item int eventItemOccurrenceId = hfSelectedEventId.Value.AsInteger(); // find registration var eventGroup = new EventItemOccurrenceGroupMapService( _rockContext ).Queryable() .Where( m => m.EventItemOccurrenceId == eventItemOccurrenceId ) .Select( m => m.Group ) .FirstOrDefault(); var registrationLinkages = eventGroup.Linkages.ToList(); if ( registrationLinkages.Count() == 0 ) { lErrors.Text = "<div class='alert alert-warning'>No registration instances exists for this event.</div>"; return; } EventItemOccurrenceGroupMap registrationLinkage = registrationLinkages.First(); // create new registration var registrationService = new RegistrationService( rockContext ); Registration registration = new Registration(); registrationService.Add( registration ); registration.RegistrationInstanceId = registrationLinkage.RegistrationInstanceId.Value; registration.ConfirmationEmail = ebEmailReminder.Text; registration.PersonAliasId = person.PrimaryAliasId; registration.FirstName = person.NickName; registration.LastName = person.LastName; registration.IsTemporary = true; // add registrants foreach ( int registrantId in cblRegistrants.SelectedValuesAsInt ) { RegistrationRegistrant registrant = new RegistrationRegistrant(); registrant.PersonAliasId = registrantId; registration.Registrants.Add( registrant ); } rockContext.SaveChanges(); // redirect to registration page var queryParams = new Dictionary<string, string>(); queryParams.Add( "RegistrationInstanceId", registrationLinkage.RegistrationInstanceId.ToString()); queryParams.Add( "RegistrationId", registration.Id.ToString() ); queryParams.Add( "StartAtBeginning", GetAttributeValue( "StartRegistrationAtBeginning" ) ); if ( !string.IsNullOrWhiteSpace( registrationLinkage.UrlSlug ) ) { queryParams.Add( "Slug", registrationLinkage.UrlSlug ); } if (registrationLinkage.Group != null) { queryParams.Add( "GroupId", registrationLinkage.GroupId.ToString() ); } NavigateToLinkedPage( "RegistrationPage", queryParams ); }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click( object sender, EventArgs e ) { if ( RegistrationId.HasValue ) { Registration registration = null; RockContext rockContext = new RockContext(); var registrationService = new RegistrationService( rockContext ); bool newRegistration = false; if ( RegistrationId.Value != 0 ) { registration = registrationService.Queryable().Where( g => g.Id == RegistrationId.Value ).FirstOrDefault(); } if ( registration == null ) { registration = new Registration { RegistrationInstanceId = RegistrationInstanceId ?? 0 }; registrationService.Add( registration ); newRegistration = true; } if ( registration != null && RegistrationInstanceId > 0 ) { registration.PersonAliasId = ppPerson.PersonAliasId; registration.FirstName = tbFirstName.Text; registration.LastName = tbLastName.Text; registration.ConfirmationEmail = ebConfirmationEmail.Text; registration.DiscountCode = ddlDiscountCode.SelectedValue; registration.DiscountPercentage = nbDiscountPercentage.Text.AsDecimal() * 0.01m; registration.DiscountAmount = cbDiscountAmount.Text.AsDecimal(); if ( !Page.IsValid ) { return; } if ( !registration.IsValid ) { // Controls will render the error messages return; } // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges() rockContext.WrapTransaction( () => { rockContext.SaveChanges(); } ); if ( newRegistration ) { var pageRef = CurrentPageReference; pageRef.Parameters.AddOrReplace("RegistrationId", registration.Id.ToString()); NavigateToPage( pageRef ); } else { // Reload registration var reloadedRegistration = GetRegistration( registration.Id ); lWizardRegistrationName.Text = reloadedRegistration.ToString(); ShowReadonlyDetails( reloadedRegistration ); } } } }
/// <summary> /// Executes this instance. /// </summary> public void Execute() { using ( var rockContext = new RockContext() ) { var registration = new RegistrationService( rockContext ) .Queryable( "RegistrationInstance.RegistrationTemplate" ).AsNoTracking() .FirstOrDefault( r => r.Id == RegistrationId ); if ( registration != null && !string.IsNullOrEmpty( registration.ConfirmationEmail ) && registration.RegistrationInstance != null && registration.RegistrationInstance.RegistrationTemplate != null ) { var template = registration.RegistrationInstance.RegistrationTemplate; var mergeFields = new Dictionary<string, object>(); mergeFields.Add( "RegistrationInstance", registration.RegistrationInstance ); mergeFields.Add( "Registration", registration ); var recipients = new Dictionary<string, Dictionary<string, object>>(); // Contact if ( !string.IsNullOrWhiteSpace( registration.RegistrationInstance.ContactEmail ) && ( template.Notify & RegistrationNotify.RegistrationContact ) == RegistrationNotify.RegistrationContact ) { recipients.AddOrIgnore( registration.RegistrationInstance.ContactEmail, mergeFields ); } // Group Followers if ( registration.GroupId.HasValue && ( template.Notify & RegistrationNotify.GroupFollowers ) == RegistrationNotify.GroupFollowers ) { new GroupService( rockContext ).GetFollowers( registration.GroupId.Value ) .Where( f => f.Email != null && f.Email != "" ) .Select( f => f.Email ) .ToList() .ForEach( f => recipients.AddOrIgnore( f, mergeFields ) ); } // Group Leaders if ( ( template.Notify & RegistrationNotify.GroupLeaders ) == RegistrationNotify.GroupLeaders ) { new GroupMemberService( rockContext ).GetLeaders( registration.GroupId.Value ) .Where( m => m.Person != null && m.Person.Email != null && m.Person.Email != "" ) .Select( m => m.Person.Email ) .ToList() .ForEach( m => recipients.AddOrIgnore( m, mergeFields ) ); } if ( recipients.Any() ) { var recipientList = new List<RecipientData>(); recipients.ToList().ForEach( r => recipientList.Add( new RecipientData( r.Key, r.Value ) ) ); Email.Send( Rock.SystemGuid.SystemEmail.REGISTRATION_NOTIFICATION.AsGuid(), recipientList, AppRoot, ThemeRoot ); } } } }
private void ProcessPostSave( RegistrationService registrationService, Registration registration, List<int> previousRegistrantIds, RockContext rockContext ) { try { SavePersonNotes( rockContext, previousRegistrantIds, registration ); AddRegistrantsToGroup( rockContext, registration ); string appRoot = ResolveRockUrl( "~/" ); string themeRoot = ResolveRockUrl( "~~/" ); var confirmation = new Rock.Transactions.SendRegistrationConfirmationTransaction(); confirmation.RegistrationId = registration.Id; confirmation.AppRoot = appRoot; confirmation.ThemeRoot = themeRoot; Rock.Transactions.RockQueue.TransactionQueue.Enqueue( confirmation ); var notification = new Rock.Transactions.SendRegistrationNotificationTransaction(); notification.RegistrationId = registration.Id; notification.AppRoot = appRoot; notification.ThemeRoot = themeRoot; Rock.Transactions.RockQueue.TransactionQueue.Enqueue( notification ); var newRegistration = registrationService .Queryable( "Registrants.PersonAlias.Person,Registrants.GroupMember,RegistrationInstance.Account,RegistrationInstance.RegistrationTemplate.Fees,RegistrationInstance.RegistrationTemplate.Discounts,RegistrationInstance.RegistrationTemplate.Forms.Fields.Attribute,RegistrationInstance.RegistrationTemplate.FinancialGateway" ) .Where( r => r.Id == registration.Id ) .FirstOrDefault(); if ( newRegistration != null ) { RegistrationInstanceState = newRegistration.RegistrationInstance; RegistrationState = new RegistrationInfo( newRegistration, rockContext ); RegistrationState.PreviousPaymentTotal = registrationService.GetTotalPayments( registration.Id ); } } catch ( Exception postSaveEx ) { ShowWarning( "The following occurred after processing your " + RegistrationTerm, postSaveEx.Message ); ExceptionLogService.LogException( postSaveEx, Context, RockPage.PageId, RockPage.Layout.SiteId, CurrentPersonAlias ); } }
/// <summary> /// Binds the registrations grid. /// </summary> private void BindRegistrationsGrid() { int? instanceId = hfRegistrationInstanceId.Value.AsIntegerOrNull(); if ( instanceId.HasValue ) { using ( var rockContext = new RockContext() ) { var registrationEntityType = EntityTypeCache.Read( typeof( Rock.Model.Registration ) ); var instance = new RegistrationInstanceService( rockContext ).Get( instanceId.Value ); _instanceHasCost = instance != null && instance.RegistrationTemplate.Cost > 0.0m; var qry = new RegistrationService( rockContext ) .Queryable( "PersonAlias.Person,Registrants.PersonAlias.Person,Registrants.Fees.RegistrationTemplateFee" ) .AsNoTracking() .Where( r => r.RegistrationInstanceId == instanceId.Value ); if ( drpRegistrationDateRange.LowerValue.HasValue ) { qry = qry.Where( r => r.CreatedDateTime.HasValue && r.CreatedDateTime.Value >= drpRegistrationDateRange.LowerValue.Value ); } if ( drpRegistrationDateRange.UpperValue.HasValue ) { qry = qry.Where( r => r.CreatedDateTime.HasValue && r.CreatedDateTime.Value <= drpRegistrationDateRange.UpperValue.Value ); } if ( !string.IsNullOrWhiteSpace( tbRegistrationRegisteredByFirstName.Text ) ) { string pfname = tbRegistrationRegisteredByFirstName.Text; qry = qry.Where( r => r.FirstName.StartsWith( pfname ) || r.PersonAlias.Person.NickName.StartsWith( pfname ) || r.PersonAlias.Person.FirstName.StartsWith( pfname ) ); } if ( !string.IsNullOrWhiteSpace( tbRegistrationRegisteredByLastName.Text ) ) { string plname = tbRegistrationRegisteredByLastName.Text; qry = qry.Where( r => r.LastName.StartsWith( plname ) || r.PersonAlias.Person.LastName.StartsWith( plname ) ); } if ( !string.IsNullOrWhiteSpace( tbRegistrationRegistrantFirstName.Text ) ) { string rfname = tbRegistrationRegistrantFirstName.Text; qry = qry.Where( r => r.Registrants.Any( p => p.PersonAlias.Person.NickName.StartsWith( rfname ) || p.PersonAlias.Person.FirstName.StartsWith( rfname ) ) ); } if ( !string.IsNullOrWhiteSpace( tbRegistrationRegistrantLastName.Text ) ) { string rlname = tbRegistrationRegistrantLastName.Text; qry = qry.Where( r => r.Registrants.Any( p => p.PersonAlias.Person.LastName.StartsWith( rlname ) ) ); } // If filtering on payment status, need to do some sub-querying... if ( ddlRegistrationPaymentStatus.SelectedValue != "" && registrationEntityType != null ) { // Get all the registrant costs var rCosts = new Dictionary<int, decimal>(); qry .Select( r => new { RegistrationId = r.Id, Costs = r.Registrants.Sum( p => p.Cost ), Fees = r.Registrants.SelectMany( p => p.Fees ).Sum( f => f.Cost ) } ).ToList() .ForEach( c => rCosts.AddOrReplace( c.RegistrationId, c.Costs + c.Fees ) ); var rPayments = new Dictionary<int, decimal>(); new FinancialTransactionDetailService( rockContext ) .Queryable().AsNoTracking() .Where( d => d.EntityTypeId.HasValue && d.EntityId.HasValue && d.EntityTypeId.Value == registrationEntityType.Id && rCosts.Keys.Contains( d.EntityId.Value ) ) .Select( d => new { RegistrationId = d.EntityId.Value, Payment = d.Amount } ) .ToList() .GroupBy( d => d.RegistrationId ) .Select( d => new { RegistrationId = d.Key, Payments = d.Sum( p => p.Payment ) } ) .ToList() .ForEach( p => rPayments.AddOrReplace( p.RegistrationId, p.Payments ) ); var rPmtSummary = rCosts .Join( rPayments, c => c.Key, p => p.Key, ( c, p ) => new { RegistrationId = c.Key, Costs = c.Value, Payments = p.Value } ) .ToList(); var ids = new List<int>(); if ( ddlRegistrationPaymentStatus.SelectedValue == "Paid in Full" ) { ids = rPmtSummary .Where( r => r.Costs <= r.Payments ) .Select( r => r.RegistrationId ) .ToList(); } else { ids = rPmtSummary .Where( r => r.Costs > r.Payments ) .Select( r => r.RegistrationId ) .ToList(); } qry = qry.Where( r => ids.Contains( r.Id ) ); } IOrderedQueryable<Registration> orderedQry = null; SortProperty sortProperty = gRegistrations.SortProperty; if ( sortProperty != null ) { orderedQry = qry.Sort( sortProperty ); } else { orderedQry = qry.OrderByDescending( r => r.CreatedDateTime ); } gRegistrations.SetLinqDataSource( orderedQry ); // Get all the payments for any registrations being displayed on the current page. // This is used in the RowDataBound event but queried now so that each row does // not have to query for the data. var currentPageRegistrations = gRegistrations.DataSource as List<Registration>; if ( currentPageRegistrations != null && registrationEntityType != null ) { var registrationIds = currentPageRegistrations .Select( r => r.Id ) .ToList(); RegistrationPayments = new FinancialTransactionDetailService( rockContext ) .Queryable().AsNoTracking() .Where( d => d.EntityTypeId.HasValue && d.EntityId.HasValue && d.EntityTypeId.Value == registrationEntityType.Id && registrationIds.Contains( d.EntityId.Value ) ) .ToList(); } gRegistrations.DataBind(); } } }
/// <summary> /// Saves the changes. /// </summary> /// <returns></returns> private int? SaveChanges() { if ( !string.IsNullOrWhiteSpace( TransactionCode ) ) { ShowError( string.Empty, "You have already completed this " + RegistrationTerm.ToLower() ); return null; } Registration registration = null; if ( RegistrationState != null && RegistrationState.Registrants.Any() && RegistrationTemplate != null ) { var rockContext = new RockContext(); var registrationService = new RegistrationService( rockContext ); bool isNewRegistration = true; var previousRegistrantIds = new List<int>(); if ( RegistrationState.RegistrationId.HasValue ) { var previousRegistration = registrationService.Get( RegistrationState.RegistrationId.Value ); if ( previousRegistration != null ) { isNewRegistration = false; previousRegistrantIds = previousRegistration.Registrants .Where( r => r.PersonAlias != null ) .Select( r => r.PersonAlias.PersonId ) .ToList(); } } try { bool hasPayment = ( RegistrationState.PaymentAmount ?? 0.0m ) > 0.0m; // Save the registration registration = SaveRegistration( rockContext, hasPayment ); if ( registration != null ) { // If there is a payment being made, process the payment if ( hasPayment ) { string errorMessage = string.Empty; if ( Using3StepGateway ) { if ( !ProcessStep3( rockContext, registration, hfStep2ReturnQueryString.Value, out errorMessage ) ) { throw new Exception( errorMessage ); } } else { if ( !ProcessPayment( rockContext, registration, out errorMessage ) ) { throw new Exception( errorMessage ); } } } // If there is a valid registration, and nothing went wrong processing the payment, add registrants to group and send the notifications if ( registration != null && !registration.IsTemporary ) { ProcessPostSave( registrationService, registration, previousRegistrantIds, rockContext ); } } } catch ( Exception ex ) { ExceptionLogService.LogException( ex, Context, this.RockPage.PageId, this.RockPage.Site.Id, CurrentPersonAlias ); string message = ex.Message; while ( ex.InnerException != null ) { ex = ex.InnerException; message = ex.Message; } ShowError( "An Error Occurred Processing Your " + RegistrationTerm, ex.Message ); // Try to delete the registration if it was just created try { if ( isNewRegistration && registration != null && registration.Id > 0 ) { RegistrationState.RegistrationId = null; using ( var newRockContext = new RockContext() ) { HistoryService.DeleteChanges( newRockContext, typeof( Registration ), registration.Id ); var newRegistrationService = new RegistrationService( newRockContext ); var newRegistration = newRegistrationService.Get( registration.Id ); if ( newRegistration != null ) { newRegistrationService.Delete( newRegistration ); newRockContext.SaveChanges(); } } } } catch { } return (int?)null; } } return registration != null ? registration.Id : (int?)null; }
/// <summary> /// Handles the Delete event of the gRegistrations control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RowEventArgs"/> instance containing the event data.</param> protected void gRegistrations_Delete( object sender, RowEventArgs e ) { using ( var rockContext = new RockContext() ) { var registrationService = new RegistrationService( rockContext ); var registration = registrationService.Get( e.RowKeyId ); if ( registration != null ) { int registrationInstanceId = registration.RegistrationInstanceId; if ( !registration.IsAuthorized( Authorization.EDIT, this.CurrentPerson ) ) { mdDeleteWarning.Show( "You are not authorized to delete this registration.", ModalAlertType.Information ); return; } string errorMessage; if ( !registrationService.CanDelete( registration, out errorMessage ) ) { mdRegistrationsGridWarning.Show( errorMessage, ModalAlertType.Information ); return; } registrationService.Delete( registration ); rockContext.SaveChanges(); SetHasPayments( registrationInstanceId, rockContext ); } } BindRegistrationsGrid(); }
/// <summary> /// Saves the registration. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="hasPayment">if set to <c>true</c> [has payment].</param> /// <returns></returns> private Registration SaveRegistration( RockContext rockContext, bool hasPayment ) { var registrationService = new RegistrationService( rockContext ); var registrantService = new RegistrationRegistrantService( rockContext ); var registrantFeeService = new RegistrationRegistrantFeeService( rockContext ); var personService = new PersonService( rockContext ); var groupService = new GroupService( rockContext ); // variables to keep track of the family that new people should be added to int? singleFamilyId = null; var multipleFamilyGroupIds = new Dictionary<Guid, int>(); var dvcConnectionStatus = DefinedValueCache.Read( GetAttributeValue( "ConnectionStatus" ).AsGuid() ); var dvcRecordStatus = DefinedValueCache.Read( GetAttributeValue( "RecordStatus" ).AsGuid() ); var familyGroupType = GroupTypeCache.Read( Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY ); var adultRoleId = familyGroupType.Roles .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid() ) ) .Select( r => r.Id ) .FirstOrDefault(); var childRoleId = familyGroupType.Roles .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid() ) ) .Select( r => r.Id ) .FirstOrDefault(); bool newRegistration = false; Registration registration = null; Person registrar = null; var registrationChanges = new List<string>(); if ( RegistrationState.RegistrationId.HasValue ) { registration = registrationService.Get( RegistrationState.RegistrationId.Value ); } if ( registration == null ) { newRegistration = true; registration = new Registration(); registrationService.Add( registration ); registrationChanges.Add( "Created Registration" ); } else { if ( registration.PersonAlias != null && registration.PersonAlias.Person != null ) { registrar = registration.PersonAlias.Person; } } registration.RegistrationInstanceId = RegistrationInstanceState.Id; // If the Registration Instance linkage specified a group, load it now Group group = null; if ( GroupId.HasValue ) { group = new GroupService( rockContext ).Get( GroupId.Value ); if ( group != null && ( !registration.GroupId.HasValue || registration.GroupId.Value != group.Id ) ) { registration.GroupId = group.Id; History.EvaluateChange( registrationChanges, "Group", string.Empty, group.Name ); } } bool newRegistrar = newRegistration || registration.FirstName == null || !registration.FirstName.Equals( RegistrationState.FirstName, StringComparison.OrdinalIgnoreCase ) || registration.LastName == null || !registration.LastName.Equals( RegistrationState.LastName, StringComparison.OrdinalIgnoreCase ); History.EvaluateChange( registrationChanges, "First Name", registration.FirstName, RegistrationState.FirstName ); registration.FirstName = RegistrationState.FirstName; History.EvaluateChange( registrationChanges, "Last Name", registration.LastName, RegistrationState.LastName ); registration.LastName = RegistrationState.LastName; History.EvaluateChange( registrationChanges, "Confirmation Email", registration.ConfirmationEmail, RegistrationState.ConfirmationEmail ); registration.ConfirmationEmail = RegistrationState.ConfirmationEmail; History.EvaluateChange( registrationChanges, "Discount Code", registration.DiscountCode, RegistrationState.DiscountCode ); registration.DiscountCode = RegistrationState.DiscountCode; History.EvaluateChange( registrationChanges, "Discount Percentage", registration.DiscountPercentage, RegistrationState.DiscountPercentage ); registration.DiscountPercentage = RegistrationState.DiscountPercentage; History.EvaluateChange( registrationChanges, "Discount Amount", registration.DiscountAmount, RegistrationState.DiscountAmount ); registration.DiscountAmount = RegistrationState.DiscountAmount; if ( newRegistrar ) { if ( CurrentPerson != null && CurrentPerson.NickName == null ) { CurrentPerson.NickName = CurrentPerson.FirstName; } // If the 'your name' value equals the currently logged in person, use their person alias id if ( CurrentPerson != null && ( CurrentPerson.NickName.Trim().Equals( registration.FirstName.Trim(), StringComparison.OrdinalIgnoreCase ) || CurrentPerson.FirstName.Trim().Equals( registration.FirstName.Trim(), StringComparison.OrdinalIgnoreCase ) ) && CurrentPerson.LastName.Trim().Equals( registration.LastName.Trim(), StringComparison.OrdinalIgnoreCase ) ) { registrar = CurrentPerson; registration.PersonAliasId = CurrentPerson.PrimaryAliasId; // If email that logged in user used is different than their stored email address, update their stored value if ( !string.IsNullOrWhiteSpace( registration.ConfirmationEmail ) && !registration.ConfirmationEmail.Trim().Equals( CurrentPerson.Email.Trim(), StringComparison.OrdinalIgnoreCase ) && ( !cbUpdateEmail.Visible || cbUpdateEmail.Checked ) ) { var person = personService.Get( CurrentPerson.Id ); if ( person != null ) { var personChanges = new List<string>(); History.EvaluateChange( personChanges, "Email", person.Email, registration.ConfirmationEmail ); person.Email = registration.ConfirmationEmail; HistoryService.SaveChanges( new RockContext(), typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(), person.Id, personChanges, true, CurrentPersonAliasId ); } } } else { // otherwise look for one and one-only match by name/email var personMatches = personService.GetByMatch( registration.FirstName, registration.LastName, registration.ConfirmationEmail ); if ( personMatches.Count() == 1 ) { registrar = personMatches.First(); registration.PersonAliasId = registrar.PrimaryAliasId; } else { registrar = null; registration.PersonAlias = null; registration.PersonAliasId = null; } } } // Set the family guid for any other registrants that were selected to be in the same family if ( registrar != null ) { var family = registrar.GetFamilies( rockContext ).FirstOrDefault(); if ( family != null ) { multipleFamilyGroupIds.AddOrIgnore( RegistrationState.FamilyGuid, family.Id ); if ( !singleFamilyId.HasValue ) { singleFamilyId = family.Id; } } } // Make sure there's an actual person associated to registration if ( !registration.PersonAliasId.HasValue ) { // If a match was not found, create a new person var person = new Person(); person.FirstName = registration.FirstName; person.LastName = registration.LastName; person.IsEmailActive = true; person.Email = registration.ConfirmationEmail; 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; } registrar = SavePerson( rockContext, person, RegistrationState.FamilyGuid, CampusId, null, adultRoleId, childRoleId, multipleFamilyGroupIds, ref singleFamilyId ); registration.PersonAliasId = registrar != null ? registrar.PrimaryAliasId : (int?)null; History.EvaluateChange( registrationChanges, "Registrar", string.Empty, registrar.FullName ); } else { if ( newRegistration ) { History.EvaluateChange( registrationChanges, "Registrar", string.Empty, registration.ToString() ); } } // if this registration was marked as temporary (started from another page, then specified in the url), set IsTemporary to False now that we are done if ( registration.IsTemporary ) { registration.IsTemporary = false; } // Save the registration ( so we can get an id ) rockContext.SaveChanges(); RegistrationState.RegistrationId = registration.Id; try { Task.Run( () => HistoryService.SaveChanges( new RockContext(), typeof( Registration ), Rock.SystemGuid.Category.HISTORY_EVENT_REGISTRATION.AsGuid(), registration.Id, registrationChanges, true, CurrentPersonAliasId ) ); // Get each registrant foreach ( var registrantInfo in RegistrationState.Registrants.ToList() ) { var registrantChanges = new List<string>(); var personChanges = new List<string>(); var familyChanges = new List<string>(); RegistrationRegistrant registrant = null; Person person = null; string firstName = registrantInfo.GetFirstName( RegistrationTemplate ); string lastName = registrantInfo.GetLastName( RegistrationTemplate ); string email = registrantInfo.GetEmail( RegistrationTemplate ); if ( registrantInfo.Id > 0 ) { registrant = registration.Registrants.FirstOrDefault( r => r.Id == registrantInfo.Id ); if ( registrant != null ) { person = registrant.Person; if ( person != null && ( ( registrant.Person.FirstName.Equals( firstName, StringComparison.OrdinalIgnoreCase ) || registrant.Person.NickName.Equals( firstName, StringComparison.OrdinalIgnoreCase ) ) && registrant.Person.LastName.Equals( lastName, StringComparison.OrdinalIgnoreCase ) ) ) { // } else { person = null; registrant.PersonAlias = null; registrant.PersonAliasId = null; } } } if ( person == null ) { // Try to find a matching person based on name and email address var personMatches = personService.GetByMatch( firstName, lastName, email ); if ( personMatches.Count() == 1 ) { person = personMatches.First(); } // Try to find a matching person based on name within same family as registrar if ( person == null && registrar != null && registrantInfo.FamilyGuid == RegistrationState.FamilyGuid ) { var familyMembers = registrar.GetFamilyMembers( true, rockContext ) .Where( m => ( m.Person.FirstName == firstName || m.Person.NickName == firstName ) && m.Person.LastName == lastName ) .Select( m => m.Person ) .ToList(); if ( familyMembers.Count() == 1 ) { person = familyMembers.First(); if ( !string.IsNullOrWhiteSpace( email ) ) { person.Email = email; } } if ( familyMembers.Count() > 1 && !string.IsNullOrWhiteSpace( email ) ) { familyMembers = familyMembers .Where( m => m.Email != null && m.Email.Equals( email, StringComparison.OrdinalIgnoreCase ) ) .ToList(); if ( familyMembers.Count() == 1 ) { person = familyMembers.First(); } } } } if ( person == null ) { // If a match was not found, create a new person person = new Person(); person.FirstName = firstName; person.LastName = lastName; person.IsEmailActive = true; person.Email = email; 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; } } int? campusId = CampusId; Location location = null; // Set any of the template's person fields foreach ( var field in RegistrationTemplate.Forms .SelectMany( f => f.Fields .Where( t => t.FieldSource == RegistrationFieldSource.PersonField ) ) ) { // Find the registrant's value var fieldValue = registrantInfo.FieldValues .Where( f => f.Key == field.Id ) .Select( f => f.Value.FieldValue ) .FirstOrDefault(); if ( fieldValue != null ) { switch ( field.PersonFieldType ) { case RegistrationPersonFieldType.Campus: { if ( fieldValue != null ) { campusId = fieldValue.ToString().AsIntegerOrNull(); } break; } case RegistrationPersonFieldType.Address: { location = fieldValue as Location; break; } case RegistrationPersonFieldType.Birthdate: { var birthMonth = person.BirthMonth; var birthDay = person.BirthDay; var birthYear = person.BirthYear; person.SetBirthDate( fieldValue as DateTime? ); History.EvaluateChange( personChanges, "Birth Month", birthMonth, person.BirthMonth ); History.EvaluateChange( personChanges, "Birth Day", birthDay, person.BirthDay ); History.EvaluateChange( personChanges, "Birth Year", birthYear, person.BirthYear ); break; } case RegistrationPersonFieldType.Grade: { var newGraduationYear = fieldValue.ToString().AsIntegerOrNull(); History.EvaluateChange( personChanges, "Graduation Year", person.GraduationYear, newGraduationYear ); person.GraduationYear = newGraduationYear; break; } case RegistrationPersonFieldType.Gender: { var newGender = fieldValue.ToString().ConvertToEnumOrNull<Gender>() ?? Gender.Unknown; History.EvaluateChange( personChanges, "Gender", person.Gender, newGender ); person.Gender = newGender; break; } case RegistrationPersonFieldType.MaritalStatus: { if ( fieldValue != null ) { int? newMaritalStatusId = fieldValue.ToString().AsIntegerOrNull(); History.EvaluateChange( personChanges, "Marital Status", DefinedValueCache.GetName( person.MaritalStatusValueId ), DefinedValueCache.GetName( newMaritalStatusId ) ); person.MaritalStatusValueId = newMaritalStatusId; } break; } case RegistrationPersonFieldType.MobilePhone: { SavePhone( fieldValue, person, Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE.AsGuid(), personChanges ); break; } case RegistrationPersonFieldType.HomePhone: { SavePhone( fieldValue, person, Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME.AsGuid(), personChanges ); break; } case RegistrationPersonFieldType.WorkPhone: { SavePhone( fieldValue, person, Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_WORK.AsGuid(), personChanges ); break; } } } } // Save the person ( and family if needed ) SavePerson( rockContext, person, registrantInfo.FamilyGuid, campusId, location, adultRoleId, childRoleId, multipleFamilyGroupIds, ref singleFamilyId ); // Load the person's attributes person.LoadAttributes(); // Set any of the template's person fields foreach ( var field in RegistrationTemplate.Forms .SelectMany( f => f.Fields .Where( t => t.FieldSource == RegistrationFieldSource.PersonAttribute && t.AttributeId.HasValue ) ) ) { // Find the registrant's value var fieldValue = registrantInfo.FieldValues .Where( f => f.Key == field.Id ) .Select( f => f.Value.FieldValue ) .FirstOrDefault(); if ( fieldValue != null ) { var attribute = AttributeCache.Read( field.AttributeId.Value ); if ( attribute != null ) { string originalValue = person.GetAttributeValue( attribute.Key ); string newValue = fieldValue.ToString(); person.SetAttributeValue( attribute.Key, fieldValue.ToString() ); // DateTime values must be stored in ISO8601 format as http://www.rockrms.com/Rock/Developer/BookContent/16/16#datetimeformatting if ( attribute.FieldType.Guid.Equals( Rock.SystemGuid.FieldType.DATE.AsGuid() ) || attribute.FieldType.Guid.Equals( Rock.SystemGuid.FieldType.DATE_TIME.AsGuid() ) ) { DateTime aDateTime; if ( DateTime.TryParse( newValue, out aDateTime ) ) { newValue = aDateTime.ToString( "o" ); } } if ( ( originalValue ?? string.Empty ).Trim() != ( newValue ?? string.Empty ).Trim() ) { string formattedOriginalValue = string.Empty; if ( !string.IsNullOrWhiteSpace( originalValue ) ) { formattedOriginalValue = attribute.FieldType.Field.FormatValue( null, originalValue, attribute.QualifierValues, false ); } string formattedNewValue = string.Empty; if ( !string.IsNullOrWhiteSpace( newValue ) ) { formattedNewValue = attribute.FieldType.Field.FormatValue( null, newValue, attribute.QualifierValues, false ); } Helper.SaveAttributeValue( person, attribute, newValue, rockContext ); History.EvaluateChange( personChanges, attribute.Name, formattedOriginalValue, formattedNewValue ); } } } } string registrantName = person.FullName + ": "; personChanges.ForEach( c => registrantChanges.Add( c ) ); if ( registrant == null ) { registrant = new RegistrationRegistrant(); registrant.Guid = registrantInfo.Guid; registrantService.Add( registrant ); registrant.RegistrationId = registration.Id; } registrant.PersonAliasId = person.PrimaryAliasId; registrant.Cost = registrantInfo.Cost; // Remove fees // Remove/delete any registrant fees that are no longer in UI with quantity foreach ( var dbFee in registrant.Fees.ToList() ) { if ( !registrantInfo.FeeValues.Keys.Contains( dbFee.RegistrationTemplateFeeId ) || registrantInfo.FeeValues[dbFee.RegistrationTemplateFeeId] == null || !registrantInfo.FeeValues[dbFee.RegistrationTemplateFeeId] .Any( f => f.Option == dbFee.Option && f.Quantity > 0 ) ) { registrantChanges.Add( string.Format( "Removed '{0}' Fee (Quantity:{1:N0}, Cost:{2:C2}, Option:{3}", dbFee.RegistrationTemplateFee.Name, dbFee.Quantity, dbFee.Cost, dbFee.Option ) ); registrant.Fees.Remove( dbFee ); registrantFeeService.Delete( dbFee ); } } // Add or Update fees foreach ( var uiFee in registrantInfo.FeeValues.Where( f => f.Value != null ) ) { foreach ( var uiFeeOption in uiFee.Value ) { var dbFee = registrant.Fees .Where( f => f.RegistrationTemplateFeeId == uiFee.Key && f.Option == uiFeeOption.Option ) .FirstOrDefault(); if ( dbFee == null ) { dbFee = new RegistrationRegistrantFee(); dbFee.RegistrationTemplateFeeId = uiFee.Key; dbFee.Option = uiFeeOption.Option; registrant.Fees.Add( dbFee ); } var templateFee = dbFee.RegistrationTemplateFee; if ( templateFee == null ) { templateFee = RegistrationTemplate.Fees.Where( f => f.Id == uiFee.Key ).FirstOrDefault(); } string feeName = templateFee != null ? templateFee.Name : "Fee"; if ( !string.IsNullOrWhiteSpace( uiFeeOption.Option ) ) { feeName = string.Format( "{0} ({1})", feeName, uiFeeOption.Option ); } if ( dbFee.Id <= 0 ) { registrantChanges.Add( feeName + " Fee Added" ); } History.EvaluateChange( registrantChanges, feeName + " Quantity", dbFee.Quantity, uiFeeOption.Quantity ); dbFee.Quantity = uiFeeOption.Quantity; History.EvaluateChange( registrantChanges, feeName + " Cost", dbFee.Cost, uiFeeOption.Cost ); dbFee.Cost = uiFeeOption.Cost; } } rockContext.SaveChanges(); registrantInfo.Id = registrant.Id; // Set any of the templat's registrant attributes registrant.LoadAttributes(); foreach ( var field in RegistrationTemplate.Forms .SelectMany( f => f.Fields .Where( t => t.FieldSource == RegistrationFieldSource.RegistrationAttribute && t.AttributeId.HasValue ) ) ) { // Find the registrant's value var fieldValue = registrantInfo.FieldValues .Where( f => f.Key == field.Id ) .Select( f => f.Value.FieldValue ) .FirstOrDefault(); if ( fieldValue != null ) { var attribute = AttributeCache.Read( field.AttributeId.Value ); if ( attribute != null ) { string originalValue = registrant.GetAttributeValue( attribute.Key ); string newValue = fieldValue.ToString(); registrant.SetAttributeValue( attribute.Key, fieldValue.ToString() ); // DateTime values must be stored in ISO8601 format as http://www.rockrms.com/Rock/Developer/BookContent/16/16#datetimeformatting if ( attribute.FieldType.Guid.Equals( Rock.SystemGuid.FieldType.DATE.AsGuid() ) || attribute.FieldType.Guid.Equals( Rock.SystemGuid.FieldType.DATE_TIME.AsGuid() ) ) { DateTime aDateTime; if ( DateTime.TryParse( fieldValue.ToString(), out aDateTime ) ) { newValue = aDateTime.ToString( "o" ); } } if ( ( originalValue ?? string.Empty ).Trim() != ( newValue ?? string.Empty ).Trim() ) { string formattedOriginalValue = string.Empty; if ( !string.IsNullOrWhiteSpace( originalValue ) ) { formattedOriginalValue = attribute.FieldType.Field.FormatValue( null, originalValue, attribute.QualifierValues, false ); } string formattedNewValue = string.Empty; if ( !string.IsNullOrWhiteSpace( newValue ) ) { formattedNewValue = attribute.FieldType.Field.FormatValue( null, newValue, attribute.QualifierValues, false ); } Helper.SaveAttributeValue( registrant, attribute, newValue, rockContext ); History.EvaluateChange( registrantChanges, attribute.Name, formattedOriginalValue, formattedNewValue ); } } } } Task.Run( () => HistoryService.SaveChanges( new RockContext(), typeof( Registration ), Rock.SystemGuid.Category.HISTORY_EVENT_REGISTRATION.AsGuid(), registration.Id, registrantChanges, "Registrant: " + person.FullName, null, null, true, CurrentPersonAliasId ) ); // Clear this registran't family guid so it's not updated again registrantInfo.FamilyGuid = Guid.Empty; } rockContext.SaveChanges(); } catch ( Exception ex ) { using ( var newRockContext = new RockContext() ) { if ( newRegistration ) { var newRegistrationService = new RegistrationService( newRockContext ); var savedRegistration = new RegistrationService( newRockContext ).Get( registration.Id ); if ( savedRegistration != null ) { HistoryService.DeleteChanges( newRockContext, typeof( Registration ), savedRegistration.Id ); newRegistrationService.Delete( savedRegistration ); newRockContext.SaveChanges(); } } } throw ex; } return registration; }
/// <summary> /// Tries to renew the registration session. This method locks tables /// during processing. After returning, you must check the <see cref="RegistrationSession.RegistrationCount"/> /// property to ensure that enough spots still exist. This can happen if /// the session was expired but was able to be partially renewed. /// </summary> /// <param name="sessionGuid">The session unique identifier.</param> /// <returns>The <see cref="RegistrationSession"/> that was renewed or <c>null</c> if it could not be found.</returns> public static RegistrationSession TryToRenewSession(Guid sessionGuid) { using (var rockContext = new RockContext()) { var registrationSessionService = new RegistrationSessionService(rockContext); var registrationService = new RegistrationService(rockContext); RegistrationSession registrationSession = null; var wasRenewed = rockContext.WrapTransactionIf(() => { /* * This is an anti-pattern. Do not just copy this and use it * as a pattern elsewhere. Discuss with the team before trying * to use this anywhere else. * * This single use-case was discussed between Jon and Daniel on * 9/17/2021 and deemed the best choice for the moment. In the * future we might convert this to a helper method that doesn't * require custom SQL each place it is used - but we really * shouldn't do full table locks as a matter of practice. * * Daniel Hazelbaker 9/17/2021 */ // Initiate a full table lock so nothing else can query data, // otherwise they might get a count that will no longer be // valid after our transaction is committed. rockContext.Database.ExecuteSqlCommand("SELECT TOP 1 Id FROM [RegistrationSession] WITH (TABLOCKX, HOLDLOCK)"); // Try to find the session to renew, if we can't find it then // return a failure indication. registrationSession = registrationSessionService.Get(sessionGuid); if (registrationSession is null) { return(false); } // Attempt to get the context that describes the registration // and the number of available slots. var context = registrationService.GetRegistrationContext(registrationSession.RegistrationInstanceId, out var errorMessage); if (errorMessage.IsNotNullOrWhiteSpace()) { return(false); } // Check if the session has expired already before we set the new // expiration window. var wasExpired = registrationSession.ExpirationDateTime < RockDateTime.Now; // Set the new expiration registrationSession.ExpirationDateTime = context.RegistrationSettings.TimeoutMinutes.HasValue ? RockDateTime.Now.AddMinutes(context.RegistrationSettings.TimeoutMinutes.Value) : RockDateTime.Now.AddDays(1); // If the session was expired then the number of reserved spots // might no longer be valid. Check if there are fewer spots // actually available and update the count. if (wasExpired && context.SpotsRemaining.HasValue) { if (context.SpotsRemaining.Value < registrationSession.RegistrationCount) { registrationSession.RegistrationCount = context.SpotsRemaining.Value; } } // Persist the new session information to the database. rockContext.SaveChanges(); return(true); }); return(wasRenewed ? registrationSession : null); } }
/// <summary> /// Sets the registration state /// </summary> private bool SetRegistrationState() { string registrationSlug = PageParameter( SLUG_PARAM_NAME ); int? registrationInstanceId = PageParameter( REGISTRATION_INSTANCE_ID_PARAM_NAME ).AsIntegerOrNull(); int? registrationId = PageParameter( REGISTRATION_ID_PARAM_NAME ).AsIntegerOrNull(); int? groupId = PageParameter( GROUP_ID_PARAM_NAME ).AsIntegerOrNull(); int? campusId = PageParameter( CAMPUS_ID_PARAM_NAME ).AsIntegerOrNull(); int? eventOccurrenceId = PageParameter( EVENT_OCCURRENCE_ID_PARAM_NAME ).AsIntegerOrNull(); // Not inside a "using" due to serialization needing context to still be active var rockContext = new RockContext(); // An existing registration id was specified if ( registrationId.HasValue ) { var registrationService = new RegistrationService( rockContext ); var registration = registrationService .Queryable( "Registrants.PersonAlias.Person,Registrants.GroupMember,RegistrationInstance.Account,RegistrationInstance.RegistrationTemplate.Fees,RegistrationInstance.RegistrationTemplate.Discounts,RegistrationInstance.RegistrationTemplate.Forms.Fields.Attribute,RegistrationInstance.RegistrationTemplate.FinancialGateway" ) .Where( r => r.Id == registrationId.Value ) .FirstOrDefault(); if ( registration == null ) { ShowError( "Error", "Registration not found" ); return false; } if ( CurrentPersonId == null ) { ShowWarning( "Please log in", "You must be logged in to access this registration." ); return false; } // Only allow the person that was logged in when this registration was created. // If the logged in person, registered on someone elses behalf (for example, husband logged in, but entered wife's name as the Registrar), // also allow that person to access the regisratiuon if ( ( registration.PersonAlias != null && registration.PersonAlias.PersonId == CurrentPersonId.Value ) || ( registration.CreatedByPersonAlias != null && registration.CreatedByPersonAlias.PersonId == CurrentPersonId.Value ) ) { RegistrationInstanceState = registration.RegistrationInstance; RegistrationState = new RegistrationInfo( registration, rockContext ); RegistrationState.PreviousPaymentTotal = registrationService.GetTotalPayments( registration.Id ); } else { ShowWarning( "Sorry", "You are not allowed to view or edit the selected registration since you are not the one who created the registration." ); return false; } // set the max number of steps in the progress bar numHowMany.Value = registration.Registrants.Count(); this.ProgressBarSteps = numHowMany.Value * FormCount + 2; // set group id if ( groupId.HasValue ) { GroupId = groupId; } else if ( !string.IsNullOrWhiteSpace( registrationSlug ) ) { var dateTime = RockDateTime.Now; var linkage = new EventItemOccurrenceGroupMapService( rockContext ) .Queryable().AsNoTracking() .Where( l => l.UrlSlug == registrationSlug && l.RegistrationInstance != null && l.RegistrationInstance.IsActive && l.RegistrationInstance.RegistrationTemplate != null && l.RegistrationInstance.RegistrationTemplate.IsActive && ( !l.RegistrationInstance.StartDateTime.HasValue || l.RegistrationInstance.StartDateTime <= dateTime ) && ( !l.RegistrationInstance.EndDateTime.HasValue || l.RegistrationInstance.EndDateTime > dateTime ) ) .FirstOrDefault(); if ( linkage != null ) { GroupId = linkage.GroupId; } } } // A registration slug was specified if ( RegistrationState == null && !string.IsNullOrWhiteSpace( registrationSlug ) ) { var dateTime = RockDateTime.Now; var linkage = new EventItemOccurrenceGroupMapService( rockContext ) .Queryable( "RegistrationInstance.Account,RegistrationInstance.RegistrationTemplate.Fees,RegistrationInstance.RegistrationTemplate.Discounts,RegistrationInstance.RegistrationTemplate.Forms.Fields.Attribute,RegistrationInstance.RegistrationTemplate.FinancialGateway" ) .Where( l => l.UrlSlug == registrationSlug && l.RegistrationInstance != null && l.RegistrationInstance.IsActive && l.RegistrationInstance.RegistrationTemplate != null && l.RegistrationInstance.RegistrationTemplate.IsActive && ( !l.RegistrationInstance.StartDateTime.HasValue || l.RegistrationInstance.StartDateTime <= dateTime ) && ( !l.RegistrationInstance.EndDateTime.HasValue || l.RegistrationInstance.EndDateTime > dateTime ) ) .FirstOrDefault(); if ( linkage != null ) { RegistrationInstanceState = linkage.RegistrationInstance; GroupId = linkage.GroupId; RegistrationState = new RegistrationInfo( CurrentPerson ); } } // A group id and campus id were specified if ( RegistrationState == null && groupId.HasValue && campusId.HasValue ) { var dateTime = RockDateTime.Now; var linkage = new EventItemOccurrenceGroupMapService( rockContext ) .Queryable( "RegistrationInstance.Account,RegistrationInstance.RegistrationTemplate.Fees,RegistrationInstance.RegistrationTemplate.Discounts,RegistrationInstance.RegistrationTemplate.Forms.Fields.Attribute,RegistrationInstance.RegistrationTemplate.FinancialGateway" ) .Where( l => l.GroupId == groupId && l.EventItemOccurrence != null && l.EventItemOccurrence.CampusId == campusId && l.RegistrationInstance != null && l.RegistrationInstance.IsActive && l.RegistrationInstance.RegistrationTemplate != null && l.RegistrationInstance.RegistrationTemplate.IsActive && ( !l.RegistrationInstance.StartDateTime.HasValue || l.RegistrationInstance.StartDateTime <= dateTime ) && ( !l.RegistrationInstance.EndDateTime.HasValue || l.RegistrationInstance.EndDateTime > dateTime ) ) .FirstOrDefault(); CampusId = campusId; if ( linkage != null ) { RegistrationInstanceState = linkage.RegistrationInstance; GroupId = linkage.GroupId; RegistrationState = new RegistrationInfo( CurrentPerson ); } } // A registration instance id was specified if ( RegistrationState == null && registrationInstanceId.HasValue ) { var dateTime = RockDateTime.Now; RegistrationInstanceState = new RegistrationInstanceService( rockContext ) .Queryable( "Account,RegistrationTemplate.Fees,RegistrationTemplate.Discounts,RegistrationTemplate.Forms.Fields.Attribute,RegistrationTemplate.FinancialGateway" ) .Where( r => r.Id == registrationInstanceId.Value && r.IsActive && r.RegistrationTemplate != null && r.RegistrationTemplate.IsActive && ( !r.StartDateTime.HasValue || r.StartDateTime <= dateTime ) && ( !r.EndDateTime.HasValue || r.EndDateTime > dateTime ) ) .FirstOrDefault(); if ( RegistrationInstanceState != null ) { RegistrationState = new RegistrationInfo( CurrentPerson ); } } // If registration instance id and event occurrence were specified, but a group (linkage) hasn't been loaded, find the first group for the event occurrence if ( RegistrationInstanceState != null && eventOccurrenceId.HasValue && !groupId.HasValue ) { var eventItemOccurrence = new EventItemOccurrenceService( rockContext ) .Queryable() .Where( o => o.Id == eventOccurrenceId.Value ) .FirstOrDefault(); if ( eventItemOccurrence != null ) { CampusId = eventItemOccurrence.CampusId; var linkage = eventItemOccurrence.Linkages .Where( l => l.RegistrationInstanceId == RegistrationInstanceState.Id ) .FirstOrDefault(); if ( linkage != null ) { GroupId = linkage.GroupId; } } } if ( RegistrationState != null && RegistrationState.FamilyGuid == Guid.Empty && RegistrationTemplate != null && RegistrationTemplate.RegistrantsSameFamily != RegistrantsSameFamily.Ask ) { RegistrationState.FamilyGuid = Guid.NewGuid(); } if ( RegistrationState != null && !RegistrationState.Registrants.Any() ) { SetRegistrantState( 1 ); } if ( RegistrationTemplate != null && RegistrationTemplate.FinancialGateway != null ) { var threeStepGateway = RegistrationTemplate.FinancialGateway.GetGatewayComponent() as ThreeStepGatewayComponent; Using3StepGateway = threeStepGateway != null; if ( Using3StepGateway ) { Step2IFrameUrl = ResolveRockUrl( threeStepGateway.Step2FormUrl ); } } return true; }
/// <summary> /// Saves the changes. /// </summary> /// <returns></returns> private int? SaveChanges() { Registration registration = null; if ( !string.IsNullOrWhiteSpace( TransactionCode ) ) { ShowError( string.Empty, "You have already completed this " + RegistrationTerm.ToLower() ); } else { try { if ( RegistrationState != null && RegistrationState.Registrants.Any() && RegistrationTemplate != null ) { var rockContext = new RockContext(); rockContext.WrapTransaction( () => { bool hasPayment = ( RegistrationState.PaymentAmount ?? 0.0m ) > 0.0m; if ( RegistrationState.RegistrationId.HasValue ) { registration = new RegistrationService( rockContext ).Get( RegistrationState.RegistrationId.Value ); } else { registration = SaveRegistration( rockContext, hasPayment ); } if ( registration != null ) { if ( hasPayment ) { string errorMessage = string.Empty; if ( !ProcessPayment( rockContext, registration, out errorMessage ) ) { registration = null; throw new Exception( errorMessage ); } } if ( registration != null ) { string appRoot = ResolveRockUrl( "~/" ); string themeRoot = ResolveRockUrl( "~~/" ); var confirmation = new Rock.Transactions.SendRegistrationConfirmationTransaction(); confirmation.RegistrationId = registration.Id; confirmation.AppRoot = appRoot; confirmation.ThemeRoot = themeRoot; Rock.Transactions.RockQueue.TransactionQueue.Enqueue( confirmation ); var notification = new Rock.Transactions.SendRegistrationNotificationTransaction(); notification.RegistrationId = registration.Id; notification.AppRoot = appRoot; notification.ThemeRoot = themeRoot; Rock.Transactions.RockQueue.TransactionQueue.Enqueue( notification ); } } } ); // Re-create State if ( registration != null ) { var registrationService = new RegistrationService( rockContext ); var newRegistration = registrationService .Queryable( "Registrants.PersonAlias.Person,Registrants.GroupMember,RegistrationInstance.Account,RegistrationInstance.RegistrationTemplate.Fees,RegistrationInstance.RegistrationTemplate.Discounts,RegistrationInstance.RegistrationTemplate.Forms.Fields.Attribute,RegistrationInstance.RegistrationTemplate.FinancialGateway" ) .AsNoTracking() .Where( r => r.Id == registration.Id ) .FirstOrDefault(); if ( newRegistration != null ) { RegistrationInstanceState = newRegistration.RegistrationInstance; RegistrationState = new RegistrationInfo( newRegistration, rockContext ); RegistrationState.PreviousPaymentTotal = registrationService.GetTotalPayments( registration.Id ); } } } } catch ( Exception ex ) { ExceptionLogService.LogException( ex, Context, this.RockPage.PageId, this.RockPage.Site.Id, CurrentPersonAlias ); ShowError( "An Error Occurred Processing Your " + RegistrationTerm, ex.Message ); return (int?)null; } } return registration != null ? registration.Id : (int?)null; }
/// <summary> /// Shows the success panel /// </summary> private void ShowSuccess( int registrationId ) { decimal currentStep = ( FormCount * RegistrationState.RegistrantCount ) + ( Using3StepGateway ? 3 : 2 ); PercentComplete = ( currentStep / ProgressBarSteps ) * 100.0m; pnlSuccessProgressBar.Visible = GetAttributeValue( "DisplayProgressBar" ).AsBoolean(); lSuccessTitle.Text = "Congratulations"; lSuccess.Text = "You have successfully completed this registration."; try { var rockContext = new RockContext(); var registration = new RegistrationService( rockContext ) .Queryable( "RegistrationInstance.RegistrationTemplate" ) .FirstOrDefault( r => r.Id == registrationId ); if ( registration != null && registration.RegistrationInstance != null && registration.RegistrationInstance.RegistrationTemplate != null ) { var template = registration.RegistrationInstance.RegistrationTemplate; var mergeFields = new Dictionary<string, object>(); mergeFields.Add( "CurrentPerson", CurrentPerson ); mergeFields.Add( "RegistrationInstance", registration.RegistrationInstance ); mergeFields.Add( "Registration", registration ); if ( template != null && !string.IsNullOrWhiteSpace( template.SuccessTitle ) ) { lSuccessTitle.Text = template.SuccessTitle.ResolveMergeFields( mergeFields ); } else { lSuccessTitle.Text = "Congratulations"; } if ( template != null && !string.IsNullOrWhiteSpace( template.SuccessText ) ) { lSuccess.Text = template.SuccessText.ResolveMergeFields( mergeFields ); } else { lSuccess.Text = "You have successfully completed this " + RegistrationTerm.ToLower(); } // show debug info if ( GetAttributeValue( "EnableDebug" ).AsBoolean() && UserCanEdit ) { lSuccessDebug.Visible = true; lSuccessDebug.Text = mergeFields.lavaDebugInfo(); } } if ( nbAmountPaid.Visible = true && nbAmountPaid.Text.AsDecimalOrNull().HasValue && nbAmountPaid.Text.AsDecimalOrNull().Value > 0.0M && ( rblSavedCC.Items.Count == 0 || ( rblSavedCC.SelectedValueAsId() ?? 0 ) == 0 ) ) { cbSaveAccount.Visible = true; pnlSaveAccount.Visible = true; txtSaveAccount.Visible = true; // If current person does not have a login, have them create a username and password phCreateLogin.Visible = !new UserLoginService( rockContext ).GetByPersonId( CurrentPersonId ).Any(); } else { pnlSaveAccount.Visible = false; } } catch ( Exception ex ) { ExceptionLogService.LogException( ex, Context, this.RockPage.PageId, this.RockPage.Site.Id, CurrentPersonAlias ); } SetPanel( 4 ); }
/// <summary> /// Sets the registration state /// </summary> private void SetRegistrationState() { string registrationSlug = PageParameter( REGISTRATION_SLUG_PARAM_NAME ); int? registrationInstanceId = PageParameter( REGISTRATION_INSTANCE_ID_PARAM_NAME ).AsIntegerOrNull(); int? registrationId = PageParameter( REGISTRATION_ID_PARAM_NAME ).AsIntegerOrNull(); int? groupId = PageParameter( REGISTRATION_GROUP_ID_PARAM_NAME ).AsIntegerOrNull(); int? campusId = PageParameter( REGISTRATION_CAMPUS_ID_PARAM_NAME ).AsIntegerOrNull(); // Not inside a "using" due to serialization needing context to still be active var rockContext = new RockContext(); // An existing registration id was specified if ( registrationId.HasValue ) { var registrationService = new RegistrationService( rockContext ); var registration = registrationService .Queryable( "Registrants.PersonAlias.Person,Registrants.GroupMember,RegistrationInstance.Account,RegistrationInstance.RegistrationTemplate.Fees,RegistrationInstance.RegistrationTemplate.Discounts,RegistrationInstance.RegistrationTemplate.Forms.Fields.Attribute,RegistrationInstance.RegistrationTemplate.FinancialGateway" ) .Where( r => r.Id == registrationId.Value ) .FirstOrDefault(); if ( registration != null ) { RegistrationInstanceState = registration.RegistrationInstance; RegistrationState = new RegistrationInfo( registration, rockContext ); RegistrationState.PreviousPaymentTotal = registrationService.GetTotalPayments( registration.Id ); } } // A registration slug was specified if ( RegistrationState == null && !string.IsNullOrWhiteSpace( registrationSlug ) ) { var dateTime = RockDateTime.Now; var linkage = new EventItemOccurrenceGroupMapService( rockContext ) .Queryable( "RegistrationInstance.Account,RegistrationInstance.RegistrationTemplate.Fees,RegistrationInstance.RegistrationTemplate.Discounts,RegistrationInstance.RegistrationTemplate.Forms.Fields.Attribute,RegistrationInstance.RegistrationTemplate.FinancialGateway" ) .Where( l => l.UrlSlug == registrationSlug && l.RegistrationInstance != null && l.RegistrationInstance.IsActive && l.RegistrationInstance.RegistrationTemplate != null && l.RegistrationInstance.RegistrationTemplate.IsActive && (!l.RegistrationInstance.StartDateTime.HasValue || l.RegistrationInstance.StartDateTime <= dateTime ) && (!l.RegistrationInstance.EndDateTime.HasValue || l.RegistrationInstance.EndDateTime > dateTime ) ) .FirstOrDefault(); if ( linkage != null ) { RegistrationInstanceState = linkage.RegistrationInstance; GroupId = linkage.GroupId; RegistrationState = new RegistrationInfo( CurrentPerson ); } } // A group id and campus id were specified if ( RegistrationState == null && groupId.HasValue && campusId.HasValue ) { var dateTime = RockDateTime.Now; var linkage = new EventItemOccurrenceGroupMapService( rockContext ) .Queryable( "RegistrationInstance.Account,RegistrationInstance.RegistrationTemplate.Fees,RegistrationInstance.RegistrationTemplate.Discounts,RegistrationInstance.RegistrationTemplate.Forms.Fields.Attribute,RegistrationInstance.RegistrationTemplate.FinancialGateway" ) .Where( l => l.GroupId == groupId && l.EventItemOccurrence != null && l.EventItemOccurrence.CampusId == campusId && l.RegistrationInstance != null && l.RegistrationInstance.IsActive && l.RegistrationInstance.RegistrationTemplate != null && l.RegistrationInstance.RegistrationTemplate.IsActive && ( !l.RegistrationInstance.StartDateTime.HasValue || l.RegistrationInstance.StartDateTime <= dateTime ) && ( !l.RegistrationInstance.EndDateTime.HasValue || l.RegistrationInstance.EndDateTime > dateTime ) ) .FirstOrDefault(); if ( linkage != null ) { RegistrationInstanceState = linkage.RegistrationInstance; GroupId = linkage.GroupId; RegistrationState = new RegistrationInfo( CurrentPerson ); } } // A registratio instance id was specified if ( RegistrationState == null && registrationInstanceId.HasValue ) { var dateTime = RockDateTime.Now; RegistrationInstanceState = new RegistrationInstanceService( rockContext ) .Queryable( "Account,RegistrationTemplate.Fees,RegistrationTemplate.Discounts,RegistrationTemplate.Forms.Fields.Attribute,RegistrationTemplate.FinancialGateway" ) .Where( r => r.Id == registrationInstanceId.Value && r.IsActive && r.RegistrationTemplate != null && r.RegistrationTemplate.IsActive && ( !r.StartDateTime.HasValue || r.StartDateTime <= dateTime ) && ( !r.EndDateTime.HasValue || r.EndDateTime > dateTime ) ) .FirstOrDefault(); if ( RegistrationInstanceState != null ) { RegistrationState = new RegistrationInfo( CurrentPerson ); } } if ( RegistrationState != null && !RegistrationState.Registrants.Any() ) { SetRegistrantState( 1 ); } }
/// <summary> /// Binds the registrations grid. /// </summary> private void BindRegistrationsGrid() { int? instanceId = hfRegistrationInstanceId.Value.AsIntegerOrNull(); if ( instanceId.HasValue ) { using ( var rockContext = new RockContext() ) { var registrationEntityType = EntityTypeCache.Read( typeof( Rock.Model.Registration ) ); var instance = new RegistrationInstanceService( rockContext ).Get( instanceId.Value ); decimal cost = instance.RegistrationTemplate.Cost; if ( instance.RegistrationTemplate.SetCostOnInstance ?? false ) { cost = instance.Cost ?? 0.0m; } _instanceHasCost = cost > 0.0m; var qry = new RegistrationService( rockContext ) .Queryable( "PersonAlias.Person,Registrants.PersonAlias.Person,Registrants.Fees.RegistrationTemplateFee" ) .AsNoTracking() .Where( r => r.RegistrationInstanceId == instanceId.Value && !r.IsTemporary ); if ( drpRegistrationDateRange.LowerValue.HasValue ) { qry = qry.Where( r => r.CreatedDateTime.HasValue && r.CreatedDateTime.Value >= drpRegistrationDateRange.LowerValue.Value ); } if ( drpRegistrationDateRange.UpperValue.HasValue ) { qry = qry.Where( r => r.CreatedDateTime.HasValue && r.CreatedDateTime.Value <= drpRegistrationDateRange.UpperValue.Value ); } if ( !string.IsNullOrWhiteSpace( tbRegistrationRegisteredByFirstName.Text ) ) { string pfname = tbRegistrationRegisteredByFirstName.Text; qry = qry.Where( r => r.FirstName.StartsWith( pfname ) || r.PersonAlias.Person.NickName.StartsWith( pfname ) || r.PersonAlias.Person.FirstName.StartsWith( pfname ) ); } if ( !string.IsNullOrWhiteSpace( tbRegistrationRegisteredByLastName.Text ) ) { string plname = tbRegistrationRegisteredByLastName.Text; qry = qry.Where( r => r.LastName.StartsWith( plname ) || r.PersonAlias.Person.LastName.StartsWith( plname ) ); } if ( !string.IsNullOrWhiteSpace( tbRegistrationRegistrantFirstName.Text ) ) { string rfname = tbRegistrationRegistrantFirstName.Text; qry = qry.Where( r => r.Registrants.Any( p => p.PersonAlias.Person.NickName.StartsWith( rfname ) || p.PersonAlias.Person.FirstName.StartsWith( rfname ) ) ); } if ( !string.IsNullOrWhiteSpace( tbRegistrationRegistrantLastName.Text ) ) { string rlname = tbRegistrationRegistrantLastName.Text; qry = qry.Where( r => r.Registrants.Any( p => p.PersonAlias.Person.LastName.StartsWith( rlname ) ) ); } // If filtering on payment status, need to do some sub-querying... if ( ddlRegistrationPaymentStatus.SelectedValue != "" && registrationEntityType != null ) { // Get all the registrant costs var rCosts = new Dictionary<int, decimal>(); qry.ToList() .Select( r => new { RegistrationId = r.Id, DiscountCosts = r.Registrants.Sum( p => (decimal?)( p.DiscountedCost( r.DiscountPercentage, r.DiscountAmount) ) ) ?? 0.0m, } ).ToList() .ForEach( c => rCosts.AddOrReplace( c.RegistrationId, c.DiscountCosts ) ); var rPayments = new Dictionary<int, decimal>(); new FinancialTransactionDetailService( rockContext ) .Queryable().AsNoTracking() .Where( d => d.EntityTypeId.HasValue && d.EntityId.HasValue && d.EntityTypeId.Value == registrationEntityType.Id && rCosts.Keys.Contains( d.EntityId.Value ) ) .Select( d => new { RegistrationId = d.EntityId.Value, Payment = d.Amount } ) .ToList() .GroupBy( d => d.RegistrationId ) .Select( d => new { RegistrationId = d.Key, Payments = d.Sum( p => p.Payment ) } ) .ToList() .ForEach( p => rPayments.AddOrReplace( p.RegistrationId, p.Payments ) ); var rPmtSummary = rCosts .Join( rPayments, c => c.Key, p => p.Key, ( c, p ) => new { RegistrationId = c.Key, Costs = c.Value, Payments = p.Value } ) .ToList(); var ids = new List<int>(); if ( ddlRegistrationPaymentStatus.SelectedValue == "Paid in Full" ) { ids = rPmtSummary .Where( r => r.Costs <= r.Payments ) .Select( r => r.RegistrationId ) .ToList(); } else { ids = rPmtSummary .Where( r => r.Costs > r.Payments ) .Select( r => r.RegistrationId ) .ToList(); } qry = qry.Where( r => ids.Contains( r.Id ) ); } SortProperty sortProperty = gRegistrations.SortProperty; if ( sortProperty != null ) { // If sorting by Total Cost or Balance Due, the database query needs to be run first without ordering, // and then ordering needs to be done in memory since TotalCost and BalanceDue are not databae fields. if ( sortProperty.Property == "TotalCost" ) { if ( sortProperty.Direction == SortDirection.Ascending ) { gRegistrations.SetLinqDataSource( qry.ToList().OrderBy( r => r.TotalCost ).AsQueryable() ); } else { gRegistrations.SetLinqDataSource( qry.ToList().OrderByDescending( r => r.TotalCost ).AsQueryable() ); } } else if ( sortProperty.Property == "BalanceDue" ) { if ( sortProperty.Direction == SortDirection.Ascending ) { gRegistrations.SetLinqDataSource( qry.ToList().OrderBy( r => r.BalanceDue ).AsQueryable() ); } else { gRegistrations.SetLinqDataSource( qry.ToList().OrderByDescending( r => r.BalanceDue ).AsQueryable() ); } } else { gRegistrations.SetLinqDataSource( qry.Sort( sortProperty ) ); } } else { gRegistrations.SetLinqDataSource( qry.OrderByDescending( r => r.CreatedDateTime ) ); } // Get all the payments for any registrations being displayed on the current page. // This is used in the RowDataBound event but queried now so that each row does // not have to query for the data. var currentPageRegistrations = gRegistrations.DataSource as List<Registration>; if ( currentPageRegistrations != null && registrationEntityType != null ) { var registrationIds = currentPageRegistrations .Select( r => r.Id ) .ToList(); RegistrationPayments = new FinancialTransactionDetailService( rockContext ) .Queryable().AsNoTracking() .Where( d => d.EntityTypeId.HasValue && d.EntityId.HasValue && d.EntityTypeId.Value == registrationEntityType.Id && registrationIds.Contains( d.EntityId.Value ) ) .ToList(); } var discountCodeHeader = gRegistrations.Columns.GetColumnByHeaderText( "Discount Code" ); if ( discountCodeHeader != null ) { discountCodeHeader.Visible = GetAttributeValue( "DisplayDiscountCodes" ).AsBoolean(); } gRegistrations.DataBind(); } } }
/// <summary> /// Handles the Delete event of the gRegistrations control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RowEventArgs"/> instance containing the event data.</param> protected void gRegistrations_Delete( object sender, RowEventArgs e ) { using ( var rockContext = new RockContext() ) { var registrationService = new RegistrationService( rockContext ); var registration = registrationService.Get( e.RowKeyId ); if ( registration != null ) { int registrationInstanceId = registration.RegistrationInstanceId; if ( !UserCanEdit && !registration.IsAuthorized( Authorization.EDIT, this.CurrentPerson ) && !registration.IsAuthorized( Authorization.ADMINISTRATE, this.CurrentPerson ) ) { mdDeleteWarning.Show( "You are not authorized to delete this registration.", ModalAlertType.Information ); return; } string errorMessage; if ( !registrationService.CanDelete( registration, out errorMessage ) ) { mdRegistrationsGridWarning.Show( errorMessage, ModalAlertType.Information ); return; } var changes = new List<string>(); changes.Add( "Deleted registration" ); rockContext.WrapTransaction( () => { HistoryService.SaveChanges( rockContext, typeof( Registration ), Rock.SystemGuid.Category.HISTORY_EVENT_REGISTRATION.AsGuid(), registration.Id, changes ); registrationService.Delete( registration ); rockContext.SaveChanges(); } ); SetHasPayments( registrationInstanceId, rockContext ); } } BindRegistrationsGrid(); }
/// <summary> /// Gets the registration cost summary information. /// </summary> /// <param name="context">The context.</param> /// <param name="registration">The registration.</param> /// <returns></returns> public List <RegistrationCostSummaryInfo> GetRegistrationCostSummaryInfo(RegistrationContext context, RegistrationEntryBlockArgs registration) { var minimumInitialPaymentPerRegistrant = context.RegistrationSettings.PerRegistrantMinInitialPayment; var defaultPaymentAmountPerRegistrant = context.RegistrationSettings.PerRegistrantDefaultInitialPayment; var rockContext = Context as RockContext; var registrationService = new RegistrationService(rockContext); // Get the cost/fee summary var costs = new List <RegistrationCostSummaryInfo>(); var discountedRegistrantsRemaining = context.Discount?.RegistrationTemplateDiscount?.MaxRegistrants; var discountModel = context.Discount?.RegistrationTemplateDiscount; foreach (var registrant in registration.Registrants) { var discountApplies = discountModel != null && (!discountedRegistrantsRemaining.HasValue || discountedRegistrantsRemaining.Value > 0); if (discountedRegistrantsRemaining.HasValue) { discountedRegistrantsRemaining--; } // Use this to hold the amount of discount remaining if the discount is greater than the registrant cost. The remaining dollars can be applied to eligable fees. decimal discountAmountRemaining = 0.0m; var firstName = registrationService.GetFirstName(context.RegistrationSettings, registrant); var lastName = registrationService.GetLastName(context.RegistrationSettings, registrant); // The registrant name for the payment summary grid var costSummary = new RegistrationCostSummaryInfo { Type = RegistrationCostSummaryType.Cost, Description = string.Format("{0} {1}", firstName, lastName) }; // If the registrant is on the waitlist then set costs to 0 and add a waitlist indicator to the name for the payment summary grid if (registrant.IsOnWaitList) { costSummary.Description += " (Waiting List)"; costSummary.Cost = 0.0m; costSummary.DiscountedCost = 0.0m; costSummary.MinPayment = 0.0m; costSummary.DefaultPayment = 0.0m; } else { // Add the registrant cost to the cost summary costSummary.Cost = context.RegistrationSettings.PerRegistrantCost; // Default the DiscountedCost to the same as the actual cost costSummary.DiscountedCost = costSummary.Cost; // Check if a discount should be applied to the registrant and set the DiscountedCost if (discountApplies) { // Apply the percentage if it exists if (discountModel.DiscountPercentage > 0.0m) { // If the DiscountPercentage is greater than 100% than set it to 0, otherwise compute the discount and set the DiscountedCost costSummary.DiscountedCost = discountModel.DiscountPercentage >= 1.0m ? 0.0m : costSummary.Cost - (costSummary.Cost * discountModel.DiscountPercentage); } else if (discountModel.DiscountAmount > 0) { // Apply the discount amount // If the DiscountAmount is greater than the cost then set the DiscountedCost to 0 and store the remaining amount to be applied to eligable fees later. if (discountModel.DiscountAmount > costSummary.Cost) { discountAmountRemaining = discountModel.DiscountAmount - costSummary.Cost; costSummary.DiscountedCost = 0.0m; } else { // Compute the DiscountedCost using the DiscountAmount costSummary.DiscountedCost = costSummary.Cost - discountModel.DiscountAmount; } } } // If registration allows a minimum payment calculate that amount, otherwise use the discounted amount as minimum costSummary.MinPayment = minimumInitialPaymentPerRegistrant.HasValue ? minimumInitialPaymentPerRegistrant.Value : costSummary.DiscountedCost; costSummary.DefaultPayment = defaultPaymentAmountPerRegistrant; } // Add the cost to the list costs.Add(costSummary); foreach (var kvp in registrant.FeeItemQuantities) { var feeItemGuid = kvp.Key; var quantity = kvp.Value; if (quantity < 1) { // Don't include a line item for things the user didn't choose continue; } // Get the fee from the template var templateFeeItems = context.RegistrationSettings.Fees.SelectMany(f => f.FeeItems); var templateFeeItem = templateFeeItems.First(f => f.Guid == feeItemGuid); var templateFee = templateFeeItem.RegistrationTemplateFee; decimal cost = templateFeeItem.Cost; var desc = GetFeeLineItemDescription(templateFee, templateFeeItem, quantity); var feeCostSummary = new RegistrationCostSummaryInfo { Type = RegistrationCostSummaryType.Fee, Description = desc, Cost = quantity * cost, // Default the DiscountedCost to be the same as the Cost DiscountedCost = quantity * cost }; if (templateFee != null && templateFee.DiscountApplies && discountApplies) { if (discountModel.DiscountPercentage > 0.0m) { feeCostSummary.DiscountedCost = discountModel.DiscountPercentage >= 1.0m ? 0.0m : feeCostSummary.Cost - (feeCostSummary.Cost * discountModel.DiscountPercentage); } else if (discountModel.DiscountAmount > 0 && discountAmountRemaining > 0) { // If there is any discount amount remaining after subracting it from the cost then it can be applied here // If the DiscountAmount is greater than the cost then set the DiscountedCost to 0 and store the remaining amount to be applied to eligable fees later. if (discountAmountRemaining > feeCostSummary.Cost) { discountAmountRemaining -= feeCostSummary.DiscountedCost; feeCostSummary.DiscountedCost = 0.0m; } else { // Compute the DiscountedCost using the DiscountAmountRemaining feeCostSummary.DiscountedCost = feeCostSummary.Cost - discountAmountRemaining; } } } // If template allows a minimum payment, then fees are not included, otherwise it is included feeCostSummary.MinPayment = minimumInitialPaymentPerRegistrant.HasValue ? 0 : feeCostSummary.DiscountedCost; // Add the fee cost to the list costs.Add(feeCostSummary); } } return(costs); }