/// <summary> /// Returns the field's current value(s) /// </summary> /// <param name="parentControl">The parent control.</param> /// <param name="value">Information about the value</param> /// <param name="configurationValues">The configuration values.</param> /// <param name="condensed">Flag indicating if the value should be condensed (i.e. for use in a grid column)</param> /// <returns></returns> public override string FormatValue(Control parentControl, string value, Dictionary <string, ConfigurationValue> configurationValues, bool condensed) { string formattedValue = string.Empty; if (!string.IsNullOrWhiteSpace(value)) { using (var rockContext = new RockContext()) { var noteType = NoteTypeCache.Get(value.AsGuid()); if (noteType != null) { formattedValue = noteType.Name; } } } return(base.FormatValue(parentControl, formattedValue, null, condensed)); }
protected void mdEdit_SaveClick(object sender, EventArgs e) { RockContext rockContext = new RockContext(); NoteService noteService = new NoteService(rockContext); var keys = (ddlMatrixItem.SelectedValue).SplitDelimitedValues(); var personId = keys[0].AsInteger(); var matrixId = keys[1].AsInteger(); var scheduleGuid = keys[2].AsGuid(); AttributeMatrixItemService attributeMatrixItemService = new AttributeMatrixItemService(rockContext); var matrix = attributeMatrixItemService.Get(matrixId); matrix.LoadAttributes(); var noteType = NoteTypeCache.Get(GetAttributeValue("NoteType").AsGuid()); var noteId = hfNoteId.ValueAsInt(); var note = noteService.Get(noteId); if (note == null) { note = new Note { NoteTypeId = noteType.Id, EntityId = personId, ForeignId = matrixId, ForeignGuid = scheduleGuid, Caption = "Medication Distributed" }; noteService.Add(note); } note.Text = string.Format( "<span class=\"field-name\">{0}</span> was distributed at <span class=\"field-name\">{1}</span>", matrix.GetAttributeValue("Medication"), dtpDateTime.SelectedDateTime.Value); note.CreatedDateTime = dtpDateTime.SelectedDateTime.Value; rockContext.SaveChanges(true); mdEdit.Hide(); ShowNotesModal(hfPersonId.ValueAsInt()); }
public object SaveUserValues(Guid itemGuid, Dictionary <string, string> userValues) { if (RequestContext.CurrentPerson == null) { return(ActionStatusCode(System.Net.HttpStatusCode.Unauthorized)); } using (var rockContext = new RockContext()) { var contentChannelItemService = new ContentChannelItemService(rockContext); var noteService = new NoteService(rockContext); var noteTypeId = NoteTypeCache.Get(SystemGuid.NoteType.CONTENT_CHANNEL_ITEM_STRUCTURED_CONTENT_USER_VALUE).Id; var item = contentChannelItemService.Get(itemGuid); if (item == null) { return(ActionNotFound()); } var note = noteService.Queryable() .Where(a => a.NoteTypeId == noteTypeId && a.EntityId == item.Id) .Where(a => a.CreatedByPersonAliasId.HasValue && a.CreatedByPersonAlias.PersonId == RequestContext.CurrentPerson.Id) .FirstOrDefault(); if (note == null) { note = new Note { NoteTypeId = noteTypeId, EntityId = item.Id }; noteService.Add(note); } note.Text = userValues.ToJson(); rockContext.SaveChanges(); } return(ActionOk()); }
/// <summary> /// Formats the selection. /// </summary> /// <param name="entityType">Type of the entity.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override string FormatSelection(Type entityType, string selection) { string result = "Person Note"; var selectionConfig = SelectionConfig.Parse(selection); if (selectionConfig != null) { NoteTypeCache selectedNoteType = null; if (selectionConfig.NoteTypeId.HasValue) { selectedNoteType = NoteTypeCache.Get(selectionConfig.NoteTypeId.Value); } if (selectedNoteType != null) { result = $"Has a {selectedNoteType.Name} note"; } else { result = "Has a note"; } var containingText = selectionConfig.NoteContains; if (containingText.IsNotNullOrWhiteSpace()) { result += $" containing '{containingText}'"; } if (selectionConfig.DateRangeMode != null) { var dateRangeString = SlidingDateRangePicker.FormatDelimitedValues(selectionConfig.DelimitedValues); if (dateRangeString.IsNotNullOrWhiteSpace()) { result += $" Date Range: {dateRangeString}"; } } } return(result); }
private void ShowNotesModal(int personId) { RockContext rockContext = new RockContext(); NoteService noteService = new NoteService(rockContext); var noteType = NoteTypeCache.Get(GetAttributeValue("NoteType").AsGuid()); var today = dpDate.SelectedDate.Value; var tomorrow = today.AddDays(1); var notes = noteService.Queryable() .Where(n => n.EntityId == personId) .Where(n => n.NoteTypeId == noteType.Id) .Where(n => n.CreatedDateTime >= today && n.CreatedDateTime < tomorrow) .Where(n => n.ForeignId != null) .ToList(); gNotes.DataSource = notes; gNotes.DataBind(); hfPersonId.Value = personId.ToString(); mdNotes.Show(); }
protected void Distribute_Click(object sender, Rock.Web.UI.Controls.RowEventArgs e) { RockContext rockContext = new RockContext(); NoteService noteService = new NoteService(rockContext); var keys = (( string )e.RowKeyValue).SplitDelimitedValues(); var personId = keys[0].AsInteger(); var matrixId = keys[1].AsInteger(); var scheduleGuid = keys[2].AsGuid(); AttributeMatrixItemService attributeMatrixItemService = new AttributeMatrixItemService(rockContext); var matrix = attributeMatrixItemService.Get(matrixId); matrix.LoadAttributes(); var noteType = NoteTypeCache.Get(GetAttributeValue("NoteType").AsGuid()); Note history = new Note() { NoteTypeId = noteType.Id, EntityId = personId, ForeignId = matrixId, Caption = "Medication Distributed", Text = string.Format("<span class=\"field-name\">{0}</span> was distributed at <span class=\"field-name\">{1}</span>", matrix.GetAttributeValue("Medication"), Rock.RockDateTime.Now), ForeignGuid = scheduleGuid }; noteService.Add(history); rockContext.SaveChanges(); //for clicking distribute after the fact if (dpDate.SelectedDate.HasValue && dpDate.SelectedDate.Value.Date != Rock.RockDateTime.Today) { history.CreatedDateTime = dpDate.SelectedDate.Value; rockContext.SaveChanges(); } BindGrid(); }
/// <summary> /// Formats the selection. /// </summary> /// <param name="entityType">Type of the entity.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override string FormatSelection(Type entityType, string selection) { var result = "Created Person Note"; var selectionConfig = SelectionConfig.Parse(selection); if (selectionConfig != null) { result = $"Created {selectionConfig.MinimumCount} or more Person {"Note".PluralizeIf( selectionConfig.MinimumCount > 1 )}"; if (selectionConfig.NoteTypeIds.Any()) { var noteTypeNames = new List <string>(); foreach (var noteTypeId in selectionConfig.NoteTypeIds) { var noteType = NoteTypeCache.Get(noteTypeId); if (noteType != null) { noteTypeNames.Add(noteType.Name); } } result += string.Format(" with note types: {0}.", noteTypeNames.AsDelimited(",")); } if (selectionConfig.DelimitedValues.IsNotNullOrWhiteSpace()) { var dateRangeString = SlidingDateRangePicker.FormatDelimitedValues(selectionConfig.DelimitedValues); if (dateRangeString.IsNotNullOrWhiteSpace()) { result += $" Date Range: {dateRangeString}"; } } } return(result); }
/// <summary> /// Outputs server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter" /> object and stores tracing information about the control if tracing is enabled. /// </summary> /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter" /> object that receives the control content.</param> public override void RenderControl(HtmlTextWriter writer) { var noteType = NoteTypeId.HasValue ? NoteTypeCache.Get(NoteTypeId.Value) : null; StringBuilder noteCss = new StringBuilder(); noteCss.Append("note-editor js-note-editor meta"); if (!string.IsNullOrEmpty(this.CssClass)) { noteCss.Append(" " + this.CssClass); } writer.AddAttribute(HtmlTextWriterAttribute.Class, noteCss.ToString()); if (this.Style[HtmlTextWriterStyle.Display] != null) { writer.AddStyleAttribute(HtmlTextWriterStyle.Display, this.Style[HtmlTextWriterStyle.Display]); } if (!ShowEditMode) { writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none"); } if (this.NoteId.HasValue) { writer.AddAttribute("rel", this.NoteId.Value.ToStringSafe()); } writer.RenderBeginTag(HtmlTextWriterTag.Div); // Edit Mode HTML... if (NoteOptions.DisplayType == NoteDisplayType.Full && NoteOptions.UsePersonIcon) { writer.AddAttribute(HtmlTextWriterAttribute.Class, "meta-figure"); writer.RenderBeginTag(HtmlTextWriterTag.Div); writer.AddAttribute(HtmlTextWriterAttribute.Class, "avatar avatar-lg"); writer.RenderBeginTag(HtmlTextWriterTag.Div); writer.Write(Person.GetPersonPhotoImageTag(CreatedByPersonId, CreatedByPhotoId, null, CreatedByGender, null, 50, 50)); writer.RenderEndTag(); // avatar div writer.RenderEndTag(); // meta-figure div } writer.AddAttribute(HtmlTextWriterAttribute.Class, "meta-body"); writer.RenderBeginTag(HtmlTextWriterTag.Div); writer.AddAttribute(HtmlTextWriterAttribute.Class, "noteentry-control"); writer.RenderBeginTag(HtmlTextWriterTag.Div); _tbNote.RenderControl(writer); _hfNoteId.RenderControl(writer); _hfParentNoteId.RenderControl(writer); writer.RenderEndTag(); // Options writer.AddAttribute(HtmlTextWriterAttribute.Class, "settings clearfix"); writer.RenderBeginTag(HtmlTextWriterTag.Div); // The optional create date text box, but only for new notes... if (NoteOptions.ShowCreateDateInput && !NoteId.HasValue) { writer.AddAttribute(HtmlTextWriterAttribute.Class, "createDate"); writer.RenderBeginTag(HtmlTextWriterTag.Div); _dtCreateDate.RenderControl(writer); writer.RenderEndTag(); // createDate div } _ddlNoteType.RenderControl(writer); _hfHasUnselectableNoteType.RenderControl(writer); if (NoteOptions.DisplayType == NoteDisplayType.Full) { if (NoteOptions.ShowAlertCheckBox) { _cbAlert.RenderControl(writer); } if (NoteOptions.ShowPrivateCheckBox) { _cbPrivate.RenderControl(writer); } } writer.AddAttribute(HtmlTextWriterAttribute.Class, "commands"); writer.RenderBeginTag(HtmlTextWriterTag.Div); _mdEditWarning.RenderControl(writer); if (NoteOptions.DisplayType == NoteDisplayType.Full) { if (NoteOptions.ShowSecurityButton) { _aSecurity.Attributes["data-title"] = this.Label; _aSecurity.RenderControl(writer); } } writer.AddAttribute(HtmlTextWriterAttribute.Class, "edit-note-cancel js-editnote-cancel btn btn-link btn-xs"); writer.RenderBeginTag(HtmlTextWriterTag.A); writer.Write("Cancel"); writer.RenderEndTag(); _lbSaveNote.Text = "Save " + Label; _lbSaveNote.CommandName = "SaveNote"; _lbSaveNote.CommandArgument = this.NoteId.ToString(); _lbSaveNote.RenderControl(writer); writer.RenderEndTag(); // commands div writer.RenderEndTag(); // settings div writer.RenderEndTag(); // panel body writer.RenderEndTag(); // ???? }
private List <MedicalItem> GetMedicalItems(bool overrideHideDistributed = false) { RockContext rockContext = new RockContext(); GroupService groupService = new GroupService(rockContext); AttributeMatrixService attributeMatrixService = new AttributeMatrixService(rockContext); AttributeValueService attributeValueService = new AttributeValueService(rockContext); AttributeMatrixItemService attributeMatrixItemService = new AttributeMatrixItemService(rockContext); NoteService noteService = new NoteService(rockContext); var groupIdStrings = GetAttributeValue("GroupIds").SplitDelimitedValues(); var groupIds = new List <int>(); foreach (var id in groupIdStrings) { groupIds.Add(id.AsInteger()); } var groups = groupService.GetByIds(groupIds); if (cpCampus.SelectedCampusId != null && cpCampus.SelectedCampusId != 0) { groups = groups.Where(g => g.CampusId == cpCampus.SelectedCampusId); } var groupTypeIds = groups.ToList().Select(g => g.GroupTypeId.ToString()).Distinct(); var personEntityid = EntityTypeCache.GetId <Rock.Model.Person>().Value; var groupMemberEntityid = EntityTypeCache.GetId <Rock.Model.GroupMember>().Value; var key = GetAttributeValue("MedicationMatrixKey"); var days = GetAttributeValue(AttributeKey.Days).AsIntegerOrNull() ?? 14; var cutoffDate = Rock.RockDateTime.Today.AddDays(-days); var lastMedicationCheckinAttribute = AttributeCache.Get(Constants.PERSON_ATTRIBUTE_LASTMEDICATIONCHECKIN.AsGuid()); var allowedPersonIds = attributeValueService.GetByAttributeId(lastMedicationCheckinAttribute.Id) .Where(av => av.ValueAsDateTime != null && av.ValueAsDateTime >= cutoffDate) .Select(av => av.EntityId); var groupMembers = groups .SelectMany(g => g.Members) .Where(gm => allowedPersonIds.Contains(gm.PersonId)); AttributeService attributeService = new AttributeService(rockContext); List <int> attributeIds = attributeService.Queryable() .Where(a => a.EntityTypeId == personEntityid && a.Key == key) .Select(a => a.Id).ToList(); if (attributeIds == null) { nbAlert.Visible = true; nbAlert.Text = "Medication attribute not found"; return(null); } List <int> filterAttributeIds = null; var filterAttributeKey = GetAttributeValue("GroupMemberAttributeFilter"); if (!string.IsNullOrWhiteSpace(filterAttributeKey)) { filterAttributeIds = attributeService.Queryable() .Where(a => (groupIdStrings.Contains(a.EntityTypeQualifierValue) || groupTypeIds.Contains(a.EntityTypeQualifierValue)) && a.Key == filterAttributeKey && a.EntityTypeId == groupMemberEntityid) .Select(a => a.Id).ToList(); } var attributeMatrixItemEntityId = EntityTypeCache.GetId <AttributeMatrixItem>(); var qry = groupMembers .Join( attributeValueService.Queryable().Where(av => attributeIds.Contains(av.AttributeId)), m => m.PersonId, av => av.EntityId.Value, (m, av) => new { Person = m.Person, Member = m, AttributeValue = av.Value } ) .Join( attributeMatrixService.Queryable(), m => m.AttributeValue, am => am.Guid.ToString(), (m, am) => new { Person = m.Person, Member = m.Member, AttributeMatrix = am } ) .Join( attributeMatrixItemService.Queryable(), m => m.AttributeMatrix.Id, ami => ami.AttributeMatrixId, (m, ami) => new { Person = m.Person, Member = m.Member, AttributeMatrixItem = ami, TemplateId = ami.AttributeMatrix.AttributeMatrixTemplateId } ) .Join( attributeService.Queryable(), m => new { TemplateIdString = m.TemplateId.ToString(), EntityTypeId = attributeMatrixItemEntityId }, a => new { TemplateIdString = a.EntityTypeQualifierValue, EntityTypeId = a.EntityTypeId }, (m, a) => new { Person = m.Person, Member = m.Member, AttributeMatrixItem = m.AttributeMatrixItem, Attribute = a } ) .Join( attributeValueService.Queryable(), m => new { EntityId = m.AttributeMatrixItem.Id, AttributeId = m.Attribute.Id }, av => new { EntityId = av.EntityId ?? 0, AttributeId = av.AttributeId }, (m, av) => new { Person = m.Person, Member = m.Member, Attribute = m.Attribute, AttributeValue = av, MatrixItemId = m.AttributeMatrixItem.Id, FilterValue = "" } ); if (filterAttributeIds != null && pnlAttribute.Visible && !string.IsNullOrWhiteSpace(ddlAttribute.SelectedValue)) { var filterValue = ddlAttribute.SelectedValue; qry = qry .Join( attributeValueService.Queryable().Where(av => filterAttributeIds.Contains(av.AttributeId)), m => new { Id = m.Member.Id, Value = filterValue }, av => new { Id = av.EntityId ?? 0, Value = av.Value }, (m, av) => new { Person = m.Person, Member = m.Member, Attribute = m.Attribute, AttributeValue = m.AttributeValue, MatrixItemId = m.MatrixItemId, FilterValue = av.Value }); } var members = qry.ToList().GroupBy(a => a.Person).ToList(); var firstDay = (dpDate.SelectedDate ?? Rock.RockDateTime.Today).Date; var nextday = firstDay.AddDays(1); var personIds = members.Select(m => m.Key.Id); var attributeMatrixEntityTypeId = EntityTypeCache.GetId <AttributeMatrixItem>().Value; var noteType = NoteTypeCache.Get(GetAttributeValue("NoteType").AsGuid()); if (noteType == null) { return(new List <MedicalItem>()); } var noteItems = noteService.Queryable() .Where(n => n.NoteTypeId == noteType.Id) .Where(n => personIds.Contains(n.EntityId ?? 0)) .Where(h => h.CreatedDateTime >= firstDay && h.CreatedDateTime < nextday) .Where(h => h.ForeignId != null) .ToList(); foreach (var member in members) { if (!string.IsNullOrWhiteSpace(tbName.Text) && !member.Key.FullName.ToLower().Contains(tbName.Text.ToLower()) && !member.Key.FullNameReversed.ToLower().Contains(tbName.Text.ToLower())) { continue; } var medicines = member.GroupBy(m => m.MatrixItemId); foreach (var medicine in medicines) { var scheduleAtt = medicine.FirstOrDefault(m => m.Attribute.Key == "Schedule"); if (scheduleAtt == null || scheduleAtt.AttributeValue.Value == null) { continue; } var schedules = scheduleAtt.AttributeValue.Value.SplitDelimitedValues(); foreach (var schedule in schedules) { if (ddlSchedule.SelectedValue != "" && ddlSchedule.SelectedValue.AsGuid() != schedule.AsGuid()) { continue; } var medicalItem = new MedicalItem() { Person = member.Key.FullNameReversed, GroupMemberId = member.Key.Id, GroupMember = member.Key.Members.FirstOrDefault(), PersonId = member.Key.Id, FilterAttribute = member.FirstOrDefault().FilterValue, }; if (!string.IsNullOrWhiteSpace(schedule)) { var dv = DefinedValueCache.Get(schedule.AsGuid()); if (dv != null) { medicalItem.Schedule = dv.Value; medicalItem.ScheduleGuid = dv.Guid; } } var medAtt = medicine.FirstOrDefault(m => m.Attribute.Key == "Medication"); if (medAtt != null) { medicalItem.Medication = medAtt.AttributeValue.Value; } var instructionAtt = medicine.FirstOrDefault(m => m.Attribute.Key == "Instructions"); if (instructionAtt != null) { medicalItem.Instructions = instructionAtt.AttributeValue.Value; } medicalItem.Key = string.Format("{0}|{1}|{2}", medicalItem.PersonId, medicine.Key, medicalItem.ScheduleGuid); var notes = noteItems .Where(n => n.EntityId == medicalItem.PersonId && n.ForeignId == medicine.Key && n.ForeignGuid == medicalItem.ScheduleGuid); if (notes.Any()) { medicalItem.Distributed = true; medicalItem.History = string.Join("<br>", notes.Select(n => n.Text)); } medicalItems.Add(medicalItem); } } if (overrideHideDistributed == false && cbHideDistributed.Checked == true) { medicalItems = medicalItems.Where(i => i.Distributed == false).ToList(); } } SortProperty sortProperty = gGrid.SortProperty; if (sortProperty != null) { if (sortProperty.Property == "Person") { if (sortProperty.Direction == SortDirection.Ascending) { medicalItems = medicalItems.OrderBy(mi => mi.Person).ToList(); } else { medicalItems = medicalItems.OrderByDescending(mi => mi.Person).ToList(); } } } else { medicalItems = medicalItems.OrderBy(mi => mi.Person).ToList(); gGrid.SortProperty = new SortProperty() { Property = "Person" }; } return(medicalItems); }
/// <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) { NoteWatch noteWatch; var rockContext = new RockContext(); var noteWatchService = new NoteWatchService(rockContext); var noteWatchId = hfNoteWatchId.Value.AsInteger(); if (noteWatchId == 0) { noteWatch = new NoteWatch(); noteWatchService.Add(noteWatch); } else { noteWatch = noteWatchService.Get(noteWatchId); } noteWatch.NoteTypeId = ddlNoteType.SelectedValue.AsIntegerOrNull(); noteWatch.EntityTypeId = etpEntityType.SelectedEntityTypeId; if (noteWatch.EntityTypeId.HasValue) { if (noteWatch.EntityTypeId.Value == EntityTypeCache.GetId <Rock.Model.Person>()) { noteWatch.EntityId = ppWatchedPerson.PersonId; } else if (noteWatch.EntityTypeId.Value == EntityTypeCache.GetId <Rock.Model.Group>()) { noteWatch.EntityId = gpWatchedGroup.GroupId; } else { noteWatch.EntityId = nbWatchedEntityId.Text.AsIntegerOrNull(); } } noteWatch.WatcherPersonAliasId = ppWatcherPerson.PersonAliasId; noteWatch.WatcherGroupId = gpWatcherGroup.GroupId; noteWatch.IsWatching = cbIsWatching.Checked; noteWatch.AllowOverride = cbAllowOverride.Checked; // see if the Watcher parameters are valid if (!noteWatch.IsValidWatcher) { nbWatcherMustBeSelectWarning.Visible = true; return; } // see if the Watch filters parameters are valid if (!noteWatch.IsValidWatchFilter) { nbWatchFilterMustBeSeletedWarning.Visible = true; return; } if (!noteWatch.IsValid) { return; } // See if there is a matching filter that doesn't allow overrides if (noteWatch.IsWatching == false) { if (!noteWatch.IsAbleToUnWatch(rockContext)) { var nonOverridableNoteWatch = noteWatch.GetNonOverridableNoteWatches(rockContext).FirstOrDefault(); if (nonOverridableNoteWatch != null) { string otherNoteWatchLink; if (nonOverridableNoteWatch.IsAuthorized(Rock.Security.Authorization.VIEW, this.CurrentPerson)) { var otherNoteWatchWatchPageReference = new Rock.Web.PageReference(this.CurrentPageReference); otherNoteWatchWatchPageReference.QueryString = new System.Collections.Specialized.NameValueCollection(otherNoteWatchWatchPageReference.QueryString); otherNoteWatchWatchPageReference.QueryString["NoteWatchId"] = nonOverridableNoteWatch.Id.ToString(); otherNoteWatchLink = string.Format("<a href='{0}'>note watch</a>", otherNoteWatchWatchPageReference.BuildUrl()); } else { otherNoteWatchLink = "note watch"; } nbUnableToOverride.Text = string.Format( "Unable to set Watching to false. This would override another {0} that doesn't allow overrides.", otherNoteWatchLink); nbUnableToOverride.Visible = true; return; } } } // see if the NoteType allows following if (noteWatch.NoteTypeId.HasValue) { var noteTypeCache = NoteTypeCache.Get(noteWatch.NoteTypeId.Value); if (noteTypeCache != null) { if (noteTypeCache.AllowsWatching == false) { nbNoteTypeWarning.Visible = true; return; } } } rockContext.SaveChanges(); NavigateToNoteWatchParentPage(); }
/// <summary> /// Executes the specified workflow. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="action">The action.</param> /// <param name="entity">The entity.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Execute(RockContext rockContext, WorkflowAction action, object entity, out List <string> errorMessages) { errorMessages = new List <string>(); var person = GetPersonAliasFromActionAttribute(AttributeKey.Person, rockContext, action, errorMessages); if (person != null) { var mergeFields = GetMergeFields(action); NoteService noteService = new NoteService(rockContext); Note note = new Note(); note.EntityId = person.Id; note.Caption = GetAttributeValue(action, AttributeKey.Caption).ResolveMergeFields(mergeFields); note.IsAlert = GetAttributeValue(action, AttributeKey.Alert).AsBoolean(); note.IsPrivateNote = false; note.Text = GetAttributeValue(action, AttributeKey.Text).ResolveMergeFields(mergeFields); note.EditedDateTime = RockDateTime.Now; // Add a NoteUrl for a person based on the existing Person Profile page, routes, and parameters. var personPageService = new PageService(rockContext); var personPage = personPageService.Get(SystemGuid.Page.PERSON_PROFILE_PERSON_PAGES.AsGuid()); // If the Person Profile Page has at least one route and at least one Page Context, use those to build the Note URL. if (personPage.PageRoutes.Count > 0 && personPage.PageContexts.Count > 0) { var personPageRoute = personPage.PageRoutes.First(); var personPageContext = personPage.PageContexts.First(); var personIdParameter = personPageContext.IdParameter; var personPageParameter = new Dictionary <string, string> { { personIdParameter, person.Id.ToString() } }; var personPageReference = new Web.PageReference(personPage.Id, personPageRoute.Id); note.NoteUrl = personPageReference.BuildRouteURL(personPageParameter); } var noteType = NoteTypeCache.Get(GetAttributeValue(action, AttributeKey.NoteType).AsGuid()); if (noteType != null) { note.NoteTypeId = noteType.Id; } // get author var author = GetPersonAliasFromActionAttribute(AttributeKey.Author, rockContext, action, errorMessages); if (author != null) { note.CreatedByPersonAliasId = author.PrimaryAlias.Id; } noteService.Add(note); rockContext.SaveChanges(); return(true); } else { errorMessages.Add("No person was provided for the note."); } errorMessages.ForEach(m => action.AddLogEntry(m, true)); return(true); }
/// <summary> /// Gets the cache object associated with this Entity /// </summary> /// <returns></returns> public IEntityCache GetCacheObject() { return(NoteTypeCache.Get(this.Id)); }
/// <summary> /// Executes the specified workflow. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="action">The action.</param> /// <param name="entity">The entity.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages) { errorMessages = new List <string>(); Guid? groupGuid = null; Person person = null; Group group = null; string noteValue = string.Empty; string captionValue = string.Empty; bool isAlert = false; // get the group attribute Guid groupAttributeGuid = GetAttributeValue(action, "Group").AsGuid(); if (!groupAttributeGuid.IsEmpty()) { groupGuid = action.GetWorklowAttributeValue(groupAttributeGuid).AsGuidOrNull(); if (groupGuid.HasValue) { group = new GroupService(rockContext).Get(groupGuid.Value); if (group == null) { errorMessages.Add("The group provided does not exist."); } } else { errorMessages.Add("Invalid group provided."); } } // get person alias guid Guid personAliasGuid = Guid.Empty; string personAttribute = GetAttributeValue(action, "Person"); Guid guid = personAttribute.AsGuid(); if (!guid.IsEmpty()) { var attribute = AttributeCache.Get(guid, rockContext); if (attribute != null) { string value = action.GetWorklowAttributeValue(guid); personAliasGuid = value.AsGuid(); } if (personAliasGuid != Guid.Empty) { person = new PersonAliasService(rockContext).Queryable() .Where(p => p.Guid.Equals(personAliasGuid)) .Select(p => p.Person) .FirstOrDefault(); } else { errorMessages.Add("The person could not be found!"); } } // get caption captionValue = GetAttributeValue(action, "Caption"); guid = captionValue.AsGuid(); if (guid.IsEmpty()) { captionValue = captionValue.ResolveMergeFields(GetMergeFields(action)); } else { var workflowAttributeValue = action.GetWorklowAttributeValue(guid); if (workflowAttributeValue != null) { captionValue = workflowAttributeValue; } } // get group member note noteValue = GetAttributeValue(action, "Note"); guid = noteValue.AsGuid(); if (guid.IsEmpty()) { noteValue = noteValue.ResolveMergeFields(GetMergeFields(action)); } else { var workflowAttributeValue = action.GetWorklowAttributeValue(guid); if (workflowAttributeValue != null) { noteValue = workflowAttributeValue; } } // get alert type string isAlertString = GetAttributeValue(action, "IsAlert"); guid = isAlertString.AsGuid(); if (guid.IsEmpty()) { isAlert = isAlertString.AsBoolean(); } else { var workflowAttributeValue = action.GetWorklowAttributeValue(guid); if (workflowAttributeValue != null) { isAlert = workflowAttributeValue.AsBoolean(); } } // get note type NoteTypeCache noteType = null; Guid noteTypeGuid = GetAttributeValue(action, "NoteType").AsGuid(); if (!noteTypeGuid.IsEmpty()) { noteType = NoteTypeCache.Get(noteTypeGuid, rockContext); if (noteType == null) { errorMessages.Add("The note type provided does not exist."); } } else { errorMessages.Add("Invalid note type provided."); } // set note if (group != null && person != null && noteType != null) { var groupMembers = new GroupMemberService(rockContext).Queryable() .Where(m => m.Group.Guid == groupGuid && m.PersonId == person.Id).ToList(); if (groupMembers.Count() > 0) { foreach (var groupMember in groupMembers) { NoteService noteservice = new NoteService(rockContext); Note note = new Note(); noteservice.Add(note); note.NoteTypeId = noteType.Id; note.Text = noteValue; note.IsAlert = isAlert; note.Caption = captionValue; note.EntityId = groupMember.Id; rockContext.SaveChanges(); } } else { errorMessages.Add(string.Format("{0} is not a member of the group {1}.", person.FullName, group.Name)); } } errorMessages.ForEach(m => action.AddLogEntry(m, true)); return(true); }
protected void lbSaveAccounts_Click(object sender, EventArgs e) { using (var rockContext = new RockContext()) { var txn = GetTransaction(rockContext); { decimal totalAmount = TransactionDetailsState.Select(d => d.Amount).ToList().Sum(); if (txn.TotalAmount != totalAmount) { nbError.Title = "Incorrect Amount"; nbError.Text = string.Format("<p>When updating account allocations, the total amount needs to remain the same as the original amount ({0}).</p>", txn.TotalAmount.FormatAsCurrency()); nbError.Visible = true; return; } var txnDetailService = new FinancialScheduledTransactionDetailService(rockContext); var accountService = new FinancialAccountService(rockContext); // Delete any transaction details that were removed var txnDetailsInDB = txnDetailService.Queryable().Where(a => a.ScheduledTransactionId.Equals(txn.Id)).ToList(); var deletedDetails = from txnDetail in txnDetailsInDB where !TransactionDetailsState.Select(d => d.Guid).Contains(txnDetail.Guid) select txnDetail; bool accountChanges = deletedDetails.Any(); deletedDetails.ToList().ForEach(txnDetail => { txnDetailService.Delete(txnDetail); }); var changeSummary = new StringBuilder(); // Save Transaction Details foreach (var editorTxnDetail in TransactionDetailsState) { editorTxnDetail.Account = accountService.Get(editorTxnDetail.AccountId); // Add or Update the activity type var txnDetail = txn.ScheduledTransactionDetails.FirstOrDefault(d => d.Guid.Equals(editorTxnDetail.Guid)); if (txnDetail == null) { accountChanges = true; txnDetail = new FinancialScheduledTransactionDetail(); txnDetail.Guid = editorTxnDetail.Guid; txn.ScheduledTransactionDetails.Add(txnDetail); } else { if (txnDetail.AccountId != editorTxnDetail.AccountId || txnDetail.Amount != editorTxnDetail.Amount || txnDetail.Summary != editorTxnDetail.Summary) { accountChanges = true; } } changeSummary.AppendFormat("{0}: {1}", editorTxnDetail.Account != null ? editorTxnDetail.Account.Name : "?", editorTxnDetail.Amount.FormatAsCurrency()); changeSummary.AppendLine(); txnDetail.AccountId = editorTxnDetail.AccountId; txnDetail.Amount = editorTxnDetail.Amount; txnDetail.Summary = editorTxnDetail.Summary; } if (accountChanges) { // save changes rockContext.SaveChanges(); // Add a note about the change var noteType = NoteTypeCache.Get(Rock.SystemGuid.NoteType.SCHEDULED_TRANSACTION_NOTE.AsGuid()); if (noteType != null) { var noteService = new NoteService(rockContext); var note = new Note(); note.NoteTypeId = noteType.Id; note.EntityId = txn.Id; note.Caption = "Updated Transaction"; note.Text = changeSummary.ToString(); noteService.Add(note); } rockContext.SaveChanges(); } ShowView(txn); } } }
protected void CreateUser() { var rockContext = new RockContext(); var userLoginService = new UserLoginService(rockContext); if (!IsUserAuthorized(Authorization.ADMINISTRATE)) { return; } rockContext.WrapTransaction(() => { var personService = new PersonService(rockContext); var restUser = new Person(); personService.Add(restUser); rockContext.SaveChanges(); // the rest user name gets saved as the last name on a person restUser.LastName = "apollos"; restUser.RecordTypeValueId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_RESTUSER.AsGuid()).Id; restUser.RecordStatusValueId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_ACTIVE.AsGuid()).Id; if (restUser.IsValid) { rockContext.SaveChanges(); } // the description gets saved as a system note for the person var noteType = NoteTypeCache.Get(Rock.SystemGuid.NoteType.PERSON_TIMELINE_NOTE.AsGuid()); if (noteType != null) { var noteService = new NoteService(rockContext); var note = noteService.Get(noteType.Id, restUser.Id).FirstOrDefault(); if (note == null) { note = new Note(); noteService.Add(note); } note.NoteTypeId = noteType.Id; note.EntityId = restUser.Id; note.Text = "Apollos API User - used for authenticating Apollos Server with Rock"; } rockContext.SaveChanges(); // the key gets saved in the api key field of a user login (which you have to create if needed) var entityType = new EntityTypeService(rockContext) .Get("Rock.Security.Authentication.Database"); var userLogin = new UserLogin(); userLoginService.Add(userLogin); userLogin.UserName = Guid.NewGuid().ToString(); userLogin.IsConfirmed = true; userLogin.ApiKey = GenerateKey(); userLogin.PersonId = restUser.Id; userLogin.EntityTypeId = entityType.Id; rockContext.SaveChanges(); var groupMemberService = new GroupMemberService(rockContext); var groupMember = new GroupMember(); groupMember.PersonId = restUser.Id; var adminGroup = new GroupService(rockContext).Get(Rock.SystemGuid.Group.GROUP_ADMINISTRATORS.AsGuid()); groupMember.GroupId = adminGroup.Id; var securityGroupMember = adminGroup.GroupType.Roles.Where(r => r.Guid.Equals(Rock.SystemGuid.GroupRole.GROUPROLE_SECURITY_GROUP_MEMBER.AsGuid())).First(); groupMember.GroupRoleId = securityGroupMember.Id; groupMember.GroupMemberStatus = GroupMemberStatus.Active; if (groupMember.IsValid) { groupMemberService.Add(groupMember); rockContext.SaveChanges(); } }); }
/// <summary> /// Create an EntityField for an Attribute. /// </summary> /// <param name="attribute">The attribute.</param> /// <param name="limitToFilterableAttributes"></param> public static EntityField GetEntityFieldForAttribute(AttributeCache attribute, bool limitToFilterableAttributes = true) { // Ensure field name only has Alpha, Numeric and underscore chars string fieldName = attribute.Key.RemoveSpecialCharacters().Replace(".", ""); EntityField entityField = null; // Make sure that the attributes field type actually renders a filter control if limitToFilterableAttributes var fieldType = FieldTypeCache.Get(attribute.FieldTypeId); if (fieldType != null && (!limitToFilterableAttributes || fieldType.Field.HasFilterControl())) { entityField = new EntityField(fieldName, FieldKind.Attribute, typeof(string), attribute.Guid, fieldType); entityField.Title = attribute.Name; entityField.TitleWithoutQualifier = entityField.Title; foreach (var config in attribute.QualifierValues) { entityField.FieldConfig.Add(config.Key, config.Value); } // Special processing for Entity Type "Group" or "GroupMember" to handle sub-types that are distinguished by GroupTypeId. if ((attribute.EntityTypeId == EntityTypeCache.GetId(typeof(Group)) || attribute.EntityTypeId == EntityTypeCache.GetId(typeof(GroupMember)) && attribute.EntityTypeQualifierColumn == "GroupTypeId")) { var groupType = GroupTypeCache.Get(attribute.EntityTypeQualifierValue.AsInteger()); if (groupType != null) { // Append the Qualifier to the title entityField.AttributeEntityTypeQualifierName = groupType.Name; entityField.Title = string.Format("{0} ({1})", attribute.Name, groupType.Name); } } // Special processing for Entity Type "ConnectionRequest" to handle sub-types that are distinguished by ConnectionOpportunityId. if (attribute.EntityTypeId == EntityTypeCache.GetId(typeof(ConnectionRequest)) && attribute.EntityTypeQualifierColumn == "ConnectionOpportunityId") { using (var rockContext = new RockContext()) { var connectionOpportunityName = new ConnectionOpportunityService(rockContext).GetSelect(attribute.EntityTypeQualifierValue.AsInteger(), s => s.Name); if (connectionOpportunityName != null) { // Append the Qualifier to the title entityField.AttributeEntityTypeQualifierName = connectionOpportunityName; entityField.Title = string.Format("{0} (Opportunity: {1})", attribute.Name, connectionOpportunityName); } } } // Special processing for Entity Type "ContentChannelItem" to handle sub-types that are distinguished by ContentChannelTypeId. if (attribute.EntityTypeId == EntityTypeCache.GetId(typeof(ContentChannelItem)) && attribute.EntityTypeQualifierColumn == "ContentChannelTypeId") { using (var rockContext = new RockContext()) { var contentChannelTypeName = new ContentChannelTypeService(rockContext).GetSelect(attribute.EntityTypeQualifierValue.AsInteger(), s => s.Name); if (contentChannelTypeName != null) { // Append the Qualifier to the title entityField.AttributeEntityTypeQualifierName = contentChannelTypeName; entityField.Title = string.Format("{0} (ChannelType: {1})", attribute.Name, contentChannelTypeName); } } } // Special processing for Entity Type "Registration" to handle sub-types that are distinguished by RegistrationTemplateId. if (attribute.EntityTypeId == EntityTypeCache.GetId(typeof(Registration)) && attribute.EntityTypeQualifierColumn == "RegistrationTemplateId") { using (var rockContext = new RockContext()) { var RegistrationTemplateName = new RegistrationTemplateService(rockContext).GetSelect(attribute.EntityTypeQualifierValue.AsInteger(), s => s.Name); if (RegistrationTemplateName != null) { // Append the Qualifier to the title entityField.AttributeEntityTypeQualifierName = RegistrationTemplateName; entityField.Title = string.Format("{0} (Registration Template: {1})", attribute.Name, RegistrationTemplateName); } } } // Special processing for Entity Type "ContentChannelItem" to handle sub-types that are distinguished by ContentChannelId. if (attribute.EntityTypeId == EntityTypeCache.GetId(typeof(ContentChannelItem)) && attribute.EntityTypeQualifierColumn == "ContentChannelId") { var contentChannel = ContentChannelCache.Get(attribute.EntityTypeQualifierValue.AsInteger()); if (contentChannel != null) { // Append the Qualifier to the title entityField.AttributeEntityTypeQualifierName = contentChannel.Name; entityField.Title = string.Format("{0} (Channel: {1})", attribute.Name, contentChannel.Name); } } // Special processing for Entity Type "Note" to handle sub-types that are distinguished by NoteTypeId. if (attribute.EntityTypeId == EntityTypeCache.GetId(typeof(Note)) && attribute.EntityTypeQualifierColumn == "NoteTypeId") { var noteType = NoteTypeCache.Get(attribute.EntityTypeQualifierValue.AsInteger()); if (noteType != null) { // Append the Qualifier to the title entityField.AttributeEntityTypeQualifierName = noteType.Name; entityField.Title = string.Format("{0} ({1})", attribute.Name, noteType.Name); } } // Special processing for Entity Type "Workflow" to handle sub-types that are distinguished by WorkflowTypeId. if (attribute.EntityTypeId == EntityTypeCache.GetId(typeof(Rock.Model.Workflow)) && attribute.EntityTypeQualifierColumn == "WorkflowTypeId") { int workflowTypeId = attribute.EntityTypeQualifierValue.AsInteger(); if (_workflowTypeNameLookup == null) { using (var rockContext = new RockContext()) { _workflowTypeNameLookup = new WorkflowTypeService(rockContext).Queryable().ToDictionary(k => k.Id, v => v.Name); } } var workflowTypeName = _workflowTypeNameLookup.ContainsKey(workflowTypeId) ? _workflowTypeNameLookup[workflowTypeId] : null; if (workflowTypeName != null) { // Append the Qualifier to the title for Workflow Attributes entityField.AttributeEntityTypeQualifierName = workflowTypeName; entityField.Title = string.Format("({1}) {0} ", attribute.Name, workflowTypeName); } } } return(entityField); }
/// <summary> /// Shows the view. /// </summary> /// <param name="txn">The TXN.</param> private void ShowView(FinancialScheduledTransaction txn) { if (txn != null) { hlStatus.Text = txn.IsActive ? "Active" : "Inactive"; hlStatus.LabelType = txn.IsActive ? LabelType.Success : LabelType.Danger; string rockUrlRoot = ResolveRockUrl("/"); var detailsLeft = new DescriptionList() .Add("Person", (txn.AuthorizedPersonAlias != null && txn.AuthorizedPersonAlias.Person != null) ? txn.AuthorizedPersonAlias.Person.GetAnchorTag(rockUrlRoot) : string.Empty); var detailsRight = new DescriptionList() .Add("Amount", (txn.ScheduledTransactionDetails.Sum(d => (decimal?)d.Amount) ?? 0.0M).FormatAsCurrency()) .Add("Frequency", txn.TransactionFrequencyValue != null ? txn.TransactionFrequencyValue.Value : string.Empty) .Add("Start Date", txn.StartDate.ToShortDateString()) .Add("End Date", txn.EndDate.HasValue ? txn.EndDate.Value.ToShortDateString() : string.Empty) .Add("Next Payment Date", txn.NextPaymentDate.HasValue ? txn.NextPaymentDate.Value.ToShortDateString() : string.Empty) .Add("Last Status Refresh", txn.LastStatusUpdateDateTime.HasValue ? txn.LastStatusUpdateDateTime.Value.ToString("g") : string.Empty); detailsLeft.Add("Source", txn.SourceTypeValue != null ? txn.SourceTypeValue.Value : string.Empty); if (txn.FinancialPaymentDetail != null && txn.FinancialPaymentDetail.CurrencyTypeValue != null) { var paymentMethodDetails = new DescriptionList(); var currencyType = txn.FinancialPaymentDetail.CurrencyTypeValue; if (currencyType.Guid.Equals(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD.AsGuid())) { // Credit Card paymentMethodDetails.Add("Type", currencyType.Value + (txn.FinancialPaymentDetail.CreditCardTypeValue != null ? (" - " + txn.FinancialPaymentDetail.CreditCardTypeValue.Value) : string.Empty)); paymentMethodDetails.Add("Name on Card", txn.FinancialPaymentDetail.NameOnCard.Trim()); paymentMethodDetails.Add("Account Number", txn.FinancialPaymentDetail.AccountNumberMasked); paymentMethodDetails.Add("Expires", txn.FinancialPaymentDetail.ExpirationDate); } else { // ACH paymentMethodDetails.Add("Type", currencyType.Value); paymentMethodDetails.Add("Account Number", txn.FinancialPaymentDetail.AccountNumberMasked); } detailsLeft.Add("Payment Method", paymentMethodDetails.GetFormattedList("{0}: {1}").AsDelimited("<br/>")); } GatewayComponent gateway = null; if (txn.FinancialGateway != null) { gateway = txn.FinancialGateway.GetGatewayComponent(); if (gateway != null) { detailsLeft.Add("Payment Gateway", GatewayContainer.GetComponentName(gateway.TypeName)); } } detailsLeft .Add("Transaction Code", txn.TransactionCode) .Add("Schedule Id", txn.GatewayScheduleId); lDetailsLeft.Text = detailsLeft.Html; lDetailsRight.Text = detailsRight.Html; gAccountsView.DataSource = txn.ScheduledTransactionDetails.ToList(); gAccountsView.DataBind(); var noteType = NoteTypeCache.Get(Rock.SystemGuid.NoteType.SCHEDULED_TRANSACTION_NOTE.AsGuid()); if (noteType != null) { var rockContext = new RockContext(); rptrNotes.DataSource = new NoteService(rockContext).Get(noteType.Id, txn.Id) .Where(n => n.CreatedDateTime.HasValue) .OrderBy(n => n.CreatedDateTime) .ToList() .Select(n => new { n.Caption, Text = n.Text.ConvertCrLfToHtmlBr(), Person = (n.CreatedByPersonAlias != null && n.CreatedByPersonAlias.Person != null) ? n.CreatedByPersonAlias.Person.FullName : "", Date = n.CreatedDateTime.HasValue ? n.CreatedDateTime.Value.ToShortDateString() : "", Time = n.CreatedDateTime.HasValue ? n.CreatedDateTime.Value.ToShortTimeString() : "" }) .ToList(); rptrNotes.DataBind(); } lbRefresh.Visible = gateway != null && gateway.GetScheduledPaymentStatusSupported; lbUpdate.Visible = gateway != null && gateway.UpdateScheduledPaymentSupported; lbCancelSchedule.Visible = txn.IsActive; lbReactivateSchedule.Visible = !txn.IsActive && gateway != null && gateway.ReactivateScheduledPaymentSupported; } }
/// <summary> /// Outputs server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter" /> object and stores tracing information about the control if tracing is enabled. /// </summary> /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter" /> object that receives the control content.</param> public override void RenderControl(HtmlTextWriter writer) { if (CSSClass != string.Empty) { writer.AddAttribute(HtmlTextWriterAttribute.Class, "note " + CSSClass); } else { writer.AddAttribute(HtmlTextWriterAttribute.Class, "note"); } if (this.NoteId.HasValue) { writer.AddAttribute("rel", this.NoteId.Value.ToStringSafe()); } writer.RenderBeginTag(HtmlTextWriterTag.Div); // Edit Mode HTML... writer.AddAttribute(HtmlTextWriterAttribute.Class, "panel panel-noteentry"); if (NoteId.HasValue || !AddAlwaysVisible) { writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none"); } writer.RenderBeginTag(HtmlTextWriterTag.Div); writer.AddAttribute(HtmlTextWriterAttribute.Class, "panel-body"); writer.RenderBeginTag(HtmlTextWriterTag.Div); if (DisplayType == NoteDisplayType.Full && UsePersonIcon) { writer.Write(Person.GetPersonPhotoImageTag(CreatedByPersonId, CreatedByPhotoId, null, CreatedByGender, null, 50, 50)); } writer.AddAttribute(HtmlTextWriterAttribute.Class, "noteentry-control"); writer.RenderBeginTag(HtmlTextWriterTag.Div); _ddlNoteType.RenderControl(writer); _tbNote.RenderControl(writer); writer.RenderEndTag(); // The optional create date text box, but only for new notes... if (ShowCreateDateInput && !NoteId.HasValue) { writer.AddAttribute(HtmlTextWriterAttribute.Class, "createDate clearfix"); writer.RenderBeginTag(HtmlTextWriterTag.Div); _dtCreateDate.RenderControl(writer); writer.RenderEndTag(); // createDate div } if (DisplayType == NoteDisplayType.Full) { // Options writer.AddAttribute(HtmlTextWriterAttribute.Class, "settings clearfix"); writer.RenderBeginTag(HtmlTextWriterTag.Div); writer.AddAttribute(HtmlTextWriterAttribute.Class, "options pull-left"); writer.RenderBeginTag(HtmlTextWriterTag.Div); if (ShowAlertCheckBox) { _cbAlert.RenderControl(writer); } if (ShowPrivateCheckBox) { _cbPrivate.RenderControl(writer); } writer.RenderEndTag(); if (ShowSecurityButton && this.NoteId.HasValue) { _sbSecurity.EntityId = this.NoteId.Value; _sbSecurity.Title = this.Label; _sbSecurity.RenderControl(writer); } writer.RenderEndTag(); // settings div } writer.RenderEndTag(); // panel body writer.AddAttribute(HtmlTextWriterAttribute.Class, "panel-footer"); writer.RenderBeginTag(HtmlTextWriterTag.Div); _lbSaveNote.Text = "Save " + Label; _lbSaveNote.RenderControl(writer); if (NoteId.HasValue || !AddAlwaysVisible) { writer.AddAttribute(HtmlTextWriterAttribute.Class, "edit-note-cancel btn btn-link btn-xs"); writer.RenderBeginTag(HtmlTextWriterTag.A); writer.Write("Cancel"); writer.RenderEndTag(); } writer.RenderEndTag(); // panel-footer div writer.RenderEndTag(); // note-entry div if (NoteId.HasValue) { // View Mode HTML... writer.AddAttribute(HtmlTextWriterAttribute.Class, ArticleClass); writer.RenderBeginTag("article"); if (DisplayType == NoteDisplayType.Full) { if (UsePersonIcon) { writer.Write(Person.GetPersonPhotoImageTag(CreatedByPersonId, CreatedByPhotoId, CreatedByAge, CreatedByGender, null, 50, 50)); } else { writer.AddAttribute(HtmlTextWriterAttribute.Class, IconClass); writer.RenderBeginTag(HtmlTextWriterTag.I); writer.RenderEndTag(); } } writer.AddAttribute(HtmlTextWriterAttribute.Class, "details"); writer.RenderBeginTag(HtmlTextWriterTag.Div); // first, encode the text to ensure html tags get encoded string renderedText = Text.EncodeHtml(); // convert any http, etc text into clickable links (do this before applying Markdown) renderedText = renderedText.Linkify(); // convert any markdown into HTML, and convert into crlf into <br /> renderedText = renderedText.ConvertMarkdownToHtml(true); if (DisplayType == NoteDisplayType.Full) { // Heading writer.RenderBeginTag(HtmlTextWriterTag.H5); if (DisplayNoteTypeHeading & this.NoteTypeId.HasValue) { var noteType = NoteTypeCache.Get(this.NoteTypeId.Value); if (noteType != null) { writer.RenderBeginTag(HtmlTextWriterTag.Strong); writer.Write(noteType.Name + " "); writer.RenderEndTag(); } } string heading = Caption; if (string.IsNullOrWhiteSpace(Caption)) { heading = CreatedByName; } writer.Write(heading.EncodeHtml()); if (CreatedDateTime.HasValue) { writer.Write(" "); writer.AddAttribute("class", "date"); writer.RenderBeginTag(HtmlTextWriterTag.Span); writer.Write(CreatedDateTime.Value.ToRelativeDateString(6)); writer.RenderEndTag(); } writer.RenderEndTag(); writer.Write(renderedText); } else { writer.Write(renderedText); writer.Write(" - "); if (!string.IsNullOrWhiteSpace(CreatedByName)) { writer.AddAttribute("class", "note-author"); writer.RenderBeginTag(HtmlTextWriterTag.Span); writer.Write(CreatedByName); writer.RenderEndTag(); writer.Write(" "); } if (CreatedDateTime.HasValue) { writer.AddAttribute("class", "note-created"); writer.RenderBeginTag(HtmlTextWriterTag.Span); writer.Write(CreatedDateTime.Value.ToRelativeDateString(6)); writer.RenderEndTag(); } } writer.RenderEndTag(); // Details Div if (CanEdit) { writer.AddAttribute(HtmlTextWriterAttribute.Class, "actions rollover-item"); writer.RenderBeginTag(HtmlTextWriterTag.Div); _lbDeleteNote.RenderControl(writer); writer.AddAttribute(HtmlTextWriterAttribute.Class, "edit-note"); writer.AddAttribute(HtmlTextWriterAttribute.Href, "#"); writer.RenderBeginTag(HtmlTextWriterTag.A); writer.AddAttribute(HtmlTextWriterAttribute.Class, "fa fa-pencil"); writer.RenderBeginTag(HtmlTextWriterTag.I); writer.RenderEndTag(); writer.RenderEndTag(); // A writer.RenderEndTag(); // actions } writer.RenderEndTag(); // article } writer.RenderEndTag(); }
/// <summary> /// Determines whether the specified action is authorized on this note. /// Special note on the VIEW action: a person can view a note if they have normal VIEW access, but also have any of the following is true of the note: /// - Approved, /// - The current person is the one who created the note, /// - The current person is the one who last edited the note, /// - No Approval is required, /// - The current person is an approver /// </summary> /// <param name="action">The action.</param> /// <param name="person">The person.</param> /// <returns></returns> public override bool IsAuthorized(string action, Person person) { /* * SUMMARY OF NOTE SECURITY LOGIC * * Private - Private notes are ONLY viewable by the creator. No one else no matter what their permissions are can see them. * * Approve - This is a custom security verb for notes. * * View - You can view a note if you have View security to the note itself * OR you have approval rights to the note * OR you created or modified it in the past * OR you have rights based off of the note type * * Edit - Edit access gives you rights to add a new note * AND edit notes that you have authored * IMPORTANT - Edit does not give you rights to edit notes that someone else has authored * * Administrate - Allows you to edit notes, even those you did not create. */ if (this.IsPrivateNote) { // If this is a private note, the creator has FULL access to it. Everybody else has NO access (including admins) if (this.CreatedByPersonAlias?.PersonId == person?.Id) { return(true); } else { return(false); } } if (action.Equals(Rock.Security.Authorization.APPROVE, StringComparison.OrdinalIgnoreCase)) { // If checking the APPROVE action, let people Approve private notes that they created (see above), otherwise just use the normal IsAuthorized return(base.IsAuthorized(action, person)); } else if (action.Equals(Rock.Security.Authorization.VIEW, StringComparison.OrdinalIgnoreCase)) { // View has special rules depending on the approval status and APPROVE verb // first check if have normal VIEW access on the base if (!base.IsAuthorized(Authorization.VIEW, person)) { return(false); } if (this.ApprovalStatus == NoteApprovalStatus.Approved) { return(true); } else if (this.CreatedByPersonAliasId == person?.PrimaryAliasId) { return(true); } else if (this.EditedByPersonAliasId == person?.PrimaryAliasId) { return(true); } else if (NoteTypeCache.Get(this.NoteTypeId)?.RequiresApprovals != true) { /* * 1/21/2021 - Shaun * If this Note does not have an assigned NoteType, it should be assumed that the NoteType does not * require approvals. This is likely because a new instance of a Note entity was created to check * authorization for viewing Note entities in general, and in this case the first check (to * base.IsAuthorized) is sufficient to permit access. * * Reason: Notes should be available for DataViews. */ return(true); } else if (this.IsAuthorized(Authorization.APPROVE, person)) { return(true); } return(false); } else if (action.Equals(Rock.Security.Authorization.EDIT, StringComparison.OrdinalIgnoreCase)) { // If this note was created by the logged person, they should be able to EDIT their own note, // otherwise EDIT (and DELETE) of other people's notes require ADMINISTRATE if (CreatedByPersonAlias?.PersonId == person?.Id) { return(true); } else { return(base.IsAuthorized(Rock.Security.Authorization.ADMINISTRATE, person)); } } else { // If this note was created by the logged person, they should be able to do any action (except for APPROVE) if (CreatedByPersonAlias?.PersonId == person?.Id) { return(true); } return(base.IsAuthorized(action, person)); } }
/// <summary> /// Gets the type of the note. /// </summary> private void GetNoteType() { noteType = NoteTypeCache.Get(Rock.SystemGuid.NoteType.PRAYER_COMMENT.AsGuid()); }
/// <summary> /// Shows the view. /// </summary> /// <param name="groupId">The group identifier.</param> /// <param name="groupMemberId">The group member identifier.</param> protected void ShowView(int groupId, int groupMemberId) { pnlView.Visible = true; pnlMain.Visible = true; pnlEditPreferences.Visible = false; hfGroupId.Value = groupId.ToString(); hfGroupMemberId.Value = groupMemberId.ToString(); var rockContext = new RockContext(); var group = new GroupService(rockContext).Get(groupId); if (group == null) { pnlView.Visible = false; return; } var groupMember = new GroupMemberService(rockContext).Queryable().Where(a => a.GroupId == groupId && a.Id == groupMemberId).FirstOrDefault(); if (groupMember == null) { pnlView.Visible = false; return; } group.LoadAttributes(rockContext); // set page title to the trip name RockPage.Title = group.GetAttributeValue("OpportunityTitle"); RockPage.BrowserTitle = group.GetAttributeValue("OpportunityTitle"); RockPage.Header.Title = group.GetAttributeValue("OpportunityTitle"); var mergeFields = LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson, new CommonMergeFieldsOptions { GetLegacyGlobalMergeFields = false }); mergeFields.Add("Group", group); groupMember.LoadAttributes(rockContext); mergeFields.Add("GroupMember", groupMember); // Left Top Sidebar var photoGuid = group.GetAttributeValue("OpportunityPhoto"); imgOpportunityPhoto.ImageUrl = string.Format("~/GetImage.ashx?Guid={0}", photoGuid); // Top Main string profileLavaTemplate = this.GetAttributeValue("ProfileLavaTemplate"); if (groupMember.PersonId == this.CurrentPersonId) { // show a warning about missing Photo or Intro if the current person is viewing their own profile var warningItems = new List <string>(); if (!groupMember.Person.PhotoId.HasValue) { warningItems.Add("photo"); } if (groupMember.GetAttributeValue("PersonalOpportunityIntroduction").IsNullOrWhiteSpace()) { warningItems.Add("personal opportunity introduction"); } nbProfileWarning.Text = "<stong>Tip!</strong> Edit your profile to add a " + warningItems.AsDelimited(", ", " and ") + "."; nbProfileWarning.Visible = warningItems.Any(); } else { nbProfileWarning.Visible = false; } btnEditProfile.Visible = groupMember.PersonId == this.CurrentPersonId; lMainTopContentHtml.Text = profileLavaTemplate.ResolveMergeFields(mergeFields); bool disablePublicContributionRequests = groupMember.GetAttributeValue("DisablePublicContributionRequests").AsBoolean(); // only show Contribution stuff if the current person is the participant and contribution requests haven't been disabled bool showContributions = !disablePublicContributionRequests && (groupMember.PersonId == this.CurrentPersonId); btnContributionsTab.Visible = showContributions; // Progress var entityTypeIdGroupMember = EntityTypeCache.GetId <Rock.Model.GroupMember>(); var contributionTotal = new FinancialTransactionDetailService(rockContext).Queryable() .Where(d => d.EntityTypeId == entityTypeIdGroupMember && d.EntityId == groupMemberId) .Sum(a => (decimal?)a.Amount) ?? 0.00M; var individualFundraisingGoal = groupMember.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull(); if (!individualFundraisingGoal.HasValue) { individualFundraisingGoal = group.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull(); } var amountLeft = individualFundraisingGoal - contributionTotal; var percentMet = individualFundraisingGoal > 0 ? contributionTotal * 100 / individualFundraisingGoal : 100; mergeFields.Add("AmountLeft", amountLeft); mergeFields.Add("PercentMet", percentMet); var queryParams = new Dictionary <string, string>(); queryParams.Add("GroupId", hfGroupId.Value); queryParams.Add("GroupMemberId", hfGroupMemberId.Value); mergeFields.Add("MakeDonationUrl", LinkedPageUrl("DonationPage", queryParams)); var opportunityType = DefinedValueCache.Get(group.GetAttributeValue("OpportunityType").AsGuid()); string makeDonationButtonText = null; if (groupMember.PersonId == this.CurrentPersonId) { makeDonationButtonText = "Make Payment"; } else { makeDonationButtonText = string.Format("Contribute to {0} {1}", RockFilters.Possessive(groupMember.Person.NickName), opportunityType); } mergeFields.Add("MakeDonationButtonText", makeDonationButtonText); var progressLavaTemplate = this.GetAttributeValue("ProgressLavaTemplate"); lProgressHtml.Text = progressLavaTemplate.ResolveMergeFields(mergeFields); // set text on the return button btnMainPage.Text = opportunityType.Value + " Page"; // Tab:Updates btnUpdatesTab.Visible = false; bool showContentChannelUpdates = false; var updatesContentChannelGuid = group.GetAttributeValue("UpdateContentChannel").AsGuidOrNull(); if (updatesContentChannelGuid.HasValue) { var contentChannel = new ContentChannelService(rockContext).Get(updatesContentChannelGuid.Value); if (contentChannel != null) { showContentChannelUpdates = true; // only show the UpdatesTab if there is another Tab option btnUpdatesTab.Visible = btnContributionsTab.Visible; string updatesLavaTemplate = this.GetAttributeValue("UpdatesLavaTemplate"); var contentChannelItems = new ContentChannelItemService(rockContext).Queryable().Where(a => a.ContentChannelId == contentChannel.Id).AsNoTracking().ToList(); mergeFields.Add("ContentChannelItems", contentChannelItems); lUpdatesContentItemsHtml.Text = updatesLavaTemplate.ResolveMergeFields(mergeFields); btnUpdatesTab.Text = string.Format("{0} Updates ({1})", opportunityType, contentChannelItems.Count()); } } if (showContentChannelUpdates) { SetActiveTab("Updates"); } else if (showContributions) { SetActiveTab("Contributions"); } else { SetActiveTab(""); } // Tab: Contributions BindContributionsGrid(); // Tab:Comments var noteType = NoteTypeCache.Get(this.GetAttributeValue("NoteType").AsGuid()); if (noteType != null) { notesCommentsTimeline.NoteOptions.SetNoteTypes(new List <NoteTypeCache> { noteType }); } notesCommentsTimeline.NoteOptions.EntityId = groupMember.Id; // show the Add button on comments for any logged in person notesCommentsTimeline.AddAllowed = true; var enableCommenting = group.GetAttributeValue("EnableCommenting").AsBoolean(); if (CurrentPerson == null) { notesCommentsTimeline.Visible = enableCommenting && (notesCommentsTimeline.NoteCount > 0); lNoLoginNoCommentsYet.Visible = notesCommentsTimeline.NoteCount == 0; pnlComments.Visible = enableCommenting; btnLoginToComment.Visible = enableCommenting; } else { lNoLoginNoCommentsYet.Visible = false; notesCommentsTimeline.Visible = enableCommenting; pnlComments.Visible = enableCommenting; btnLoginToComment.Visible = false; } // if btnContributionsTab is the only visible tab, hide the tab since there is nothing else to tab to if (!btnUpdatesTab.Visible && btnContributionsTab.Visible) { SetActiveTab("Contributions"); btnContributionsTab.Visible = false; } }
public BlockActionResult SaveNote(Guid?noteGuid, Guid?parentNoteGuid, Guid noteTypeGuid, string text, bool isAlert, bool isPrivate) { var noteType = NoteTypeCache.Get(noteTypeGuid); if (noteType == null) { return(ActionBadRequest("Invalid note type.")); } var entityType = EntityTypeCache.Get(ContextEntityType); var entity = entityType != null?RequestContext.GetContextEntity(entityType.GetEntityType()) : null; if (entity == null) { return(ActionBadRequest("Unknown note type.")); } using (var rockContext = new RockContext()) { var noteService = new NoteService(rockContext); Note note; var parentNote = parentNoteGuid.HasValue ? noteService.Get(parentNoteGuid.Value) : null; if (!noteGuid.HasValue) { if (!noteType.IsAuthorized(Authorization.EDIT, RequestContext.CurrentPerson)) { return(ActionForbidden("Not authorized to add note.")); } note = rockContext.Notes.Create(); note.IsSystem = false; note.EntityId = entity.Id; note.ParentNoteId = parentNote?.Id; noteService.Add(note); } else { note = noteService.Get(noteGuid.Value); if (note == null) { return(ActionNotFound()); } if (!note.IsAuthorized(Authorization.EDIT, RequestContext.CurrentPerson)) { return(ActionForbidden("Not authorized to edit note.")); } } // If the note is new or is owned by the current person then // update the private flag. if (note.Id == 0 || (note.CreatedByPersonId.HasValue && RequestContext.CurrentPerson?.Id == note.CreatedByPersonId)) { note.IsPrivateNote = isPrivate; } // It's up to the client to handle logic for non-user selectable // note types. note.NoteTypeId = noteType.Id; string personalNoteCaption = "You - Personal Note"; if (string.IsNullOrWhiteSpace(note.Caption)) { note.Caption = note.IsPrivateNote ? personalNoteCaption : string.Empty; } else { // if the note still has the personalNoteCaption, but was changed to have IsPrivateNote to false, change the caption to empty string if (note.Caption == personalNoteCaption && !note.IsPrivateNote) { note.Caption = string.Empty; } } note.Text = text; note.IsAlert = isAlert; note.EditedByPersonAliasId = RequestContext.CurrentPerson?.PrimaryAliasId; note.EditedDateTime = RockDateTime.Now; if (noteType.RequiresApprovals) { if (note.IsAuthorized(Authorization.APPROVE, RequestContext.CurrentPerson)) { note.ApprovalStatus = NoteApprovalStatus.Approved; note.ApprovedByPersonAliasId = RequestContext.CurrentPerson?.PrimaryAliasId; note.ApprovedDateTime = RockDateTime.Now; } else { note.ApprovalStatus = NoteApprovalStatus.PendingApproval; } } else { note.ApprovalStatus = NoteApprovalStatus.Approved; } rockContext.SaveChanges(); return(ActionOk(GetNoteObject(note))); } }
/// <summary> /// Handles the Click event of the lbSaveNote 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 lbSaveNote_Click(object sender, EventArgs e) { if (_ddlNoteType.Visible) { NoteTypeId = _ddlNoteType.SelectedValueAsInt() ?? 0; } var rockPage = this.Page as RockPage; if (rockPage != null && NoteTypeId.HasValue) { var currentPerson = rockPage.CurrentPerson; var rockContext = new RockContext(); var service = new NoteService(rockContext); Note note = null; if (NoteId.HasValue) { note = service.Get(NoteId.Value); } if (note == null) { note = new Note(); note.IsSystem = false; note.EntityId = EntityId; note.ParentNoteId = _hfParentNoteId.Value.AsIntegerOrNull(); service.Add(note); } else { if (!note.IsAuthorized(Authorization.EDIT, currentPerson)) { // if somehow a person is trying to edit a note that they aren't authorized to edit, don't update the note _mdEditWarning.Show("Not authorized to edit note", ModalAlertType.Warning); return; } } if (_hfHasUnselectableNoteType.Value.AsBoolean() && note.NoteTypeId > 0 && note.Id > 0) { // a note type with an unselectable notetype was edited, so just keep the notetype that is had before } else { note.NoteTypeId = NoteTypeId.Value; } string personalNoteCaption = "You - Personal Note"; if (string.IsNullOrWhiteSpace(note.Caption)) { note.Caption = IsPrivate ? personalNoteCaption : string.Empty; } else { // if the note still has the personalNoteCaption, but was changed to have IsPrivateNote to false, change the caption to empty string if (note.Caption == personalNoteCaption && !IsPrivate) { note.Caption = string.Empty; } } note.Text = Text; note.IsAlert = IsAlert; note.IsPrivateNote = IsPrivate; if (NoteOptions.ShowCreateDateInput) { note.CreatedDateTime = _dtCreateDate.SelectedDateTime; } note.EditedByPersonAliasId = currentPerson?.PrimaryAliasId; note.EditedDateTime = RockDateTime.Now; note.NoteUrl = this.RockBlock()?.CurrentPageReference?.BuildUrl(); var noteType = NoteTypeCache.Get(note.NoteTypeId); if (noteType.RequiresApprovals) { if (note.IsAuthorized(Authorization.APPROVE, currentPerson)) { note.ApprovalStatus = NoteApprovalStatus.Approved; note.ApprovedByPersonAliasId = currentPerson?.PrimaryAliasId; note.ApprovedDateTime = RockDateTime.Now; } else { note.ApprovalStatus = NoteApprovalStatus.PendingApproval; } } else { note.ApprovalStatus = NoteApprovalStatus.Approved; } rockContext.SaveChanges(); if (SaveButtonClick != null) { SaveButtonClick(this, new NoteEventArgs(note.Id)); } } }
/// <summary> /// Determines whether the specified action is authorized on this note. /// Special note on the VIEW action: a person can view a note if they have normal VIEW access, but also have any of the following is true of the note: /// - Approved, /// - The current person is the one who created the note, /// - The current person is the one who last edited the note, /// - No Approval is required, /// - The current person is an approver /// </summary> /// <param name="action">The action.</param> /// <param name="person">The person.</param> /// <returns></returns> public override bool IsAuthorized(string action, Person person) { if (this.IsPrivateNote) { // If this is a private note, the creator has FULL access to it. Everybody else has NO access (including admins) if (this.CreatedByPersonAlias?.PersonId == person?.Id) { return(true); } else { return(false); } } if (action.Equals(Rock.Security.Authorization.APPROVE, StringComparison.OrdinalIgnoreCase)) { // If checking the APPROVE action, let people Approve private notes that they created (see above), otherwise just use the normal IsAuthorized return(base.IsAuthorized(action, person)); } else if (action.Equals(Rock.Security.Authorization.VIEW, StringComparison.OrdinalIgnoreCase)) { // View has special rules depending on the approval status and APPROVE verb // first check if have normal VIEW access on the base if (!base.IsAuthorized(Authorization.VIEW, person)) { return(false); } if (this.ApprovalStatus == NoteApprovalStatus.Approved) { return(true); } else if (this.CreatedByPersonAliasId == person?.PrimaryAliasId) { return(true); } else if (this.EditedByPersonAliasId == person?.PrimaryAliasId) { return(true); } else if (NoteTypeCache.Get(this.NoteTypeId)?.RequiresApprovals != true) { /* * 1/21/2021 - Shaun * If this Note does not have an assigned NoteType, it should be assumed that the NoteType does not * require approvals. This is likely because a new instance of a Note entity was created to check * authorization for viewing Note entities in general, and in this case the first check (to * base.IsAuthorized) is sufficient to permit access. * * Reason: Notes should be available for DataViews. */ return(true); } else if (this.IsAuthorized(Authorization.APPROVE, person)) { return(true); } return(false); } else if (action.Equals(Rock.Security.Authorization.EDIT, StringComparison.OrdinalIgnoreCase)) { // If this note was created by the logged person, they should be able to EDIT their own note, // otherwise EDIT (and DELETE) of other people's notes require ADMINISTRATE if (CreatedByPersonAlias?.PersonId == person?.Id) { return(true); } else { return(base.IsAuthorized(Rock.Security.Authorization.ADMINISTRATE, person)); } } else { // If this note was created by the logged person, they should be able to do any action (except for APPROVE) if (CreatedByPersonAlias?.PersonId == person?.Id) { return(true); } return(base.IsAuthorized(action, person)); } }
/// <summary> /// Handles the Click event of the lbSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> protected void lbSave_Click(object sender, EventArgs e) { var rockContext = new RockContext(); var userLoginService = new UserLoginService(rockContext); var userLogin = userLoginService.Queryable().Where(a => a.ApiKey == tbKey.Text).FirstOrDefault(); if (userLogin != null && userLogin.PersonId != int.Parse(hfRestUserId.Value)) { // this key already exists in the database. Show the error and get out of here. nbWarningMessage.Text = "This API Key already exists. Please enter a different one, or generate one by clicking the 'Generate Key' button below. "; nbWarningMessage.Visible = true; return; } rockContext.WrapTransaction(() => { var personService = new PersonService(rockContext); var restUser = new Person(); if (int.Parse(hfRestUserId.Value) != 0) { restUser = personService.Get(int.Parse(hfRestUserId.Value)); } else { personService.Add(restUser); rockContext.SaveChanges(); } // the rest user name gets saved as the last name on a person restUser.LastName = tbName.Text; restUser.RecordTypeValueId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_RESTUSER.AsGuid()).Id; if (cbActive.Checked) { restUser.RecordStatusValueId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_ACTIVE.AsGuid()).Id; } else { restUser.RecordStatusValueId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE.AsGuid()).Id; } if (restUser.IsValid) { rockContext.SaveChanges(); } // the description gets saved as a system note for the person var noteType = NoteTypeCache.Get(Rock.SystemGuid.NoteType.PERSON_TIMELINE_NOTE.AsGuid()); if (noteType != null) { var noteService = new NoteService(rockContext); var note = noteService.Get(noteType.Id, restUser.Id).FirstOrDefault(); if (note == null) { note = new Note(); noteService.Add(note); } note.NoteTypeId = noteType.Id; note.EntityId = restUser.Id; note.Text = tbDescription.Text; } rockContext.SaveChanges(); // the key gets saved in the api key field of a user login (which you have to create if needed) var entityType = new EntityTypeService(rockContext) .Get("Rock.Security.Authentication.Database"); userLogin = userLoginService.GetByPersonId(restUser.Id).FirstOrDefault(); if (userLogin == null) { userLogin = new UserLogin(); userLoginService.Add(userLogin); } if (string.IsNullOrWhiteSpace(userLogin.UserName)) { userLogin.UserName = Guid.NewGuid().ToString(); } userLogin.IsConfirmed = true; userLogin.ApiKey = tbKey.Text; userLogin.PersonId = restUser.Id; userLogin.EntityTypeId = entityType.Id; rockContext.SaveChanges(); }); NavigateToParentPage(); }
/// <summary> /// Returns all Non-Overridable NoteWatches that would prevent this NoteWatch from enabling IsWatching=False /// Returns a Queryable of zero or more NoteWatches /// </summary> /// <param name="rockContext">The rock context.</param> /// <returns> /// <c>true</c> if [is allowed to unwatch]; otherwise, <c>false</c>. /// </returns> public IQueryable <NoteWatch> GetNonOverridableNoteWatches(RockContext rockContext) { var noteWatchService = new NoteWatchService(rockContext); // we are only concerned about other IsWatching watches that don't allow overrides var noteWatchesWithOverrideNotAllowedQuery = noteWatchService.Queryable().Where(a => a.AllowOverride == false && a.IsWatching && a.Id != this.Id); // limit to notewatches for the same watcher person (or where the watcher person is part of the watcher group) if (this.WatcherPersonAliasId.HasValue) { var watcherPerson = this.WatcherPersonAlias?.Person ?? new PersonAliasService(rockContext).Get(this.WatcherPersonAliasId.Value).Person; // limit to watch that are watched by the same person, or watched by a group that a person is an active member of noteWatchesWithOverrideNotAllowedQuery = noteWatchesWithOverrideNotAllowedQuery .Where(a => a.WatcherPersonAliasId.HasValue && a.WatcherPersonAlias.PersonId == this.WatcherPersonAlias.PersonId || a.WatcherGroup.Members.Any(gm => gm.GroupMemberStatus == GroupMemberStatus.Active && gm.Person.Aliases.Any(x => x.PersonId == watcherPerson.Id)) ); } else if (this.WatcherGroupId.HasValue) { // if the watcher is a Group, make sure it isn't trying to override another watch where the watcher is the same group noteWatchesWithOverrideNotAllowedQuery = noteWatchesWithOverrideNotAllowedQuery.Where(a => a.WatcherGroupId.HasValue && a.WatcherGroupId.Value == this.WatcherGroupId.Value); } else { // invalid NoteWatch so just return a false query (no records) return(noteWatchesWithOverrideNotAllowedQuery.Where(a => false)); } NoteTypeCache noteType = null; if (this.NoteTypeId.HasValue) { noteType = NoteTypeCache.Get(this.NoteTypeId.Value); } var noteWatchEntityTypeId = this.EntityTypeId ?? noteType?.EntityTypeId; //// Find NoteWatches that could override this note watch //// We are mostly looking for NoteWatches that are the same or less specific than this watch // at a minimum, the EntityType must be the same noteWatchesWithOverrideNotAllowedQuery = noteWatchesWithOverrideNotAllowedQuery.Where(a => (a.EntityTypeId.HasValue && a.EntityTypeId.Value == noteWatchEntityTypeId) || (a.NoteTypeId.HasValue && a.NoteType.EntityTypeId == noteWatchEntityTypeId)); // look for non-overridable notewatches that not specific to a NoteType, NoteId, or Entity,etc var globalEntityTypeNoteWatchesWithNoOverridesQuery = noteWatchesWithOverrideNotAllowedQuery.Where(a => a.NoteTypeId == null && a.NoteId == null && a.EntityId == null); if (globalEntityTypeNoteWatchesWithNoOverridesQuery.Any()) { // found at least one non-overridable notewatch that covers all notes for the note watch, so it any attempt to unwatch wouldn't block due to the override return(globalEntityTypeNoteWatchesWithNoOverridesQuery); } // if this notewatch is more specific, look for ones that are the same or less specific if (this.NoteTypeId.HasValue) { var noteTypeNoteWatchesWithNoOverridesQuery = noteWatchesWithOverrideNotAllowedQuery.Where(a => (a.NoteTypeId.HasValue && a.NoteTypeId.Value == this.NoteTypeId.Value) && a.NoteId == null && a.EntityId == null); if (noteTypeNoteWatchesWithNoOverridesQuery.Any()) { // found at least one non-overridable notewatch that covers all notes for the note watch and NoteType, so it any attempt to unwatch wouldn't block due to the override return(noteTypeNoteWatchesWithNoOverridesQuery); } } if (this.NoteId.HasValue) { var noteNoteWatchesWithNoOverridesQuery = noteWatchesWithOverrideNotAllowedQuery.Where(a => (a.NoteId.HasValue && a.NoteId.Value == this.NoteId.Value) && a.EntityId == null); if (noteNoteWatchesWithNoOverridesQuery.Any()) { // found at least one non-overridable notewatch that covers this exact note for the note watch, so it any attempt to unwatch wouldn't block due to the override return(noteNoteWatchesWithNoOverridesQuery); } } if (this.EntityId.HasValue) { var entityNoteWatchesWithNoOverridesQuery = noteWatchesWithOverrideNotAllowedQuery.Where(a => a.NoteTypeId == null && a.NoteId == null && (a.EntityId.HasValue && (a.EntityId == this.EntityId.Value))); if (entityNoteWatchesWithNoOverridesQuery.Any()) { // found at least one non-overridable notewatch that covers this exact same entity for the note watch, so it any attempt to unwatch wouldn't block due to the override return(entityNoteWatchesWithNoOverridesQuery); } } // no non-overridable conditions found, so return a false query (no records) return(noteWatchesWithOverrideNotAllowedQuery.Where(a => false)); }
/// <summary> /// Updates the note watch notification digest. /// </summary> /// <param name="personIdNotificationDigestList">The person identifier notification digest list.</param> /// <param name="rockContext">The rock context.</param> /// <param name="noteId">The note identifier.</param> private void UpdateNoteWatchNotificationDigest(Dictionary <int, NoteWatchPersonToNotifyList> personIdNotificationDigestList, RockContext rockContext, int noteId) { var noteService = new Rock.Model.NoteService(rockContext); var note = noteService.Queryable().Include(a => a.EditedByPersonAlias).FirstOrDefault(a => a.Id == noteId); if (note == null || !note.EntityId.HasValue) { // shouldn't' happen return; } var noteType = NoteTypeCache.Get(note.NoteTypeId); // make sure the note's notetype has an EntityTypeId (is should, but just in case it doesn't) int?noteEntityTypeId = noteType?.EntityTypeId; if (!noteEntityTypeId.HasValue) { return; } var noteWatchService = new Rock.Model.NoteWatchService(rockContext); // narrow it down to NoteWatches for the same EntityType as the Note var noteWatchesQuery = noteWatchService.Queryable() .Where(a => (a.EntityTypeId.HasValue && a.EntityTypeId.Value == noteEntityTypeId.Value) || (a.NoteTypeId.HasValue && a.NoteType.EntityTypeId == noteEntityTypeId)); // narrow it down to either note watches on.. // 1) specific Entity // 2) specific Note // 3) any note of the NoteType // 4) any note on the EntityType // specific Entity noteWatchesQuery = noteWatchesQuery.Where(a => (a.EntityId == null) || (note.EntityId.HasValue && a.EntityId.Value == note.EntityId.Value)); // or specifically for this Note's ParentNote (a reply to the Note) noteWatchesQuery = noteWatchesQuery.Where(a => (a.NoteId == null) || (note.ParentNoteId.HasValue && a.NoteId.Value == note.ParentNoteId)); // or specifically for this note's note type noteWatchesQuery = noteWatchesQuery.Where(a => (a.NoteTypeId == null) || (a.NoteTypeId.Value == note.NoteTypeId)); // if there are any NoteWatches that relate to this note, process them if (noteWatchesQuery.Any()) { var noteWatchesForNote = noteWatchesQuery.Include(a => a.WatcherPersonAlias.Person).AsNoTracking().ToList(); List <NoteWatchPersonToNotify> noteWatchPersonToNotifyListAll = new List <NoteWatchPersonToNotify>(); // loop thru Watches to get a list of people to possibly notify/override foreach (var noteWatch in noteWatchesForNote) { // if a specific person is the watcher, add them var watcherPerson = noteWatch.WatcherPersonAlias?.Person; if (watcherPerson != null) { // Since this is iterated do not add the person to the list if they are already there. var exists = noteWatchPersonToNotifyListAll.Where(p => p.Person.Email.Contains(watcherPerson.Email)).Any(); if (!exists) { noteWatchPersonToNotifyListAll.Add(new NoteWatchPersonToNotify(watcherPerson, note, noteWatch)); } } if (noteWatch.WatcherGroupId.HasValue) { var watcherPersonsFromGroup = new GroupMemberService(rockContext).Queryable() .Where(a => a.GroupMemberStatus == GroupMemberStatus.Active && a.GroupId == noteWatch.WatcherGroupId.Value) .Select(a => a.Person).ToList(); if (watcherPersonsFromGroup.Any()) { // Do not add people from the group that are already added. var distinctWatchers = watcherPersonsFromGroup.Where(wg => !noteWatchPersonToNotifyListAll.Where(w => w.Person.Email.Contains(wg.Email)).Any()); noteWatchPersonToNotifyListAll.AddRange(distinctWatchers.Select(a => new NoteWatchPersonToNotify(a, note, noteWatch))); } } } var noteWatchPersonToNotifyList = noteWatchPersonToNotifyListAll.Where(a => a.NoteWatch.IsWatching).ToList(); var noteWatchPersonToNotifyListWatchDisabled = noteWatchPersonToNotifyListAll.Where(a => !a.NoteWatch.IsWatching).ToList(); var noteWatchPersonToNotifyListNoOverride = noteWatchPersonToNotifyList.Where(a => a.NoteWatch.AllowOverride == false).ToList(); foreach (var noteWatchPersonToNotify in noteWatchPersonToNotifyList) { // check if somebody wanted to specifically NOT watch this (and there isn't another watch that prevents overrides) if (noteWatchPersonToNotifyListWatchDisabled.Any(a => a.Person.Id == noteWatchPersonToNotify.Person.Id)) { // Person Requested to NOT watch, now make sure that they aren't force to watch based on Override = False if (!noteWatchPersonToNotifyListNoOverride.Any(a => a.Person.Id == noteWatchPersonToNotify.Person.Id)) { // person requested to NOT watch, and there aren't any overrides to prevent that, so jump out to the next one continue; } } NoteWatchPersonToNotifyList personToNotifyList; if (personIdNotificationDigestList.ContainsKey(noteWatchPersonToNotify.Person.Id)) { // This just create a place holder for the Note referring to item in the digest by key of person personToNotifyList = personIdNotificationDigestList[noteWatchPersonToNotify.Person.Id] ?? new NoteWatchPersonToNotifyList(noteWatchPersonToNotify.Person); } else { // This just creates a new place holder for the Note in the digest personToNotifyList = new NoteWatchPersonToNotifyList(noteWatchPersonToNotify.Person); personIdNotificationDigestList.Add(noteWatchPersonToNotify.Person.Id, personToNotifyList); } // Only include the note if the watcher person is authorized to view the note if (noteWatchPersonToNotify.Note.IsAuthorized(Rock.Security.Authorization.VIEW, noteWatchPersonToNotify.Person)) { // This is where the get added to the item of the digest personToNotifyList.Add(noteWatchPersonToNotify); } } } }
/// <summary> /// Determines whether the specified action is authorized on this note. /// Special note on the VIEW action: a person can view a note if they have normal VIEW access, but also have any of the following is true of the note: /// - Approved, /// - The current person is the one who created the note, /// - The current person is the one who last edited the note, /// - No Approval is required, /// - The current person is an approver /// </summary> /// <param name="action">The action.</param> /// <param name="person">The person.</param> /// <returns></returns> public override bool IsAuthorized(string action, Person person) { if (this.IsPrivateNote) { // If this is a private note, the creator has FULL access to it. Everybody else has NO access (including admins) if (this.CreatedByPersonAlias?.PersonId == person?.Id) { return(true); } else { return(false); } } if (action.Equals(Rock.Security.Authorization.APPROVE, StringComparison.OrdinalIgnoreCase)) { // If checking the APPROVE action, let people Approve private notes that they created (see above), otherwise just use the normal IsAuthorized return(base.IsAuthorized(action, person)); } else if (action.Equals(Rock.Security.Authorization.VIEW, StringComparison.OrdinalIgnoreCase)) { // View has special rules depending on the approval status and APPROVE verb // first check if have normal VIEW access on the base if (!base.IsAuthorized(Authorization.VIEW, person)) { return(false); } if (this.ApprovalStatus == NoteApprovalStatus.Approved) { return(true); } else if (this.CreatedByPersonAliasId == person?.PrimaryAliasId) { return(true); } else if (this.EditedByPersonAliasId == person?.PrimaryAliasId) { return(true); } else if (NoteTypeCache.Get(this.NoteTypeId)?.RequiresApprovals == false) { return(true); } else if (this.IsAuthorized(Authorization.APPROVE, person)) { return(true); } return(false); } else if (action.Equals(Rock.Security.Authorization.EDIT, StringComparison.OrdinalIgnoreCase)) { // If this note was created by the logged person, they should be be able to EDIT their own note, // otherwise EDIT (and DELETE) of other people's notes require ADMINISTRATE if (CreatedByPersonAlias?.PersonId == person?.Id) { return(true); } else { return(base.IsAuthorized(Rock.Security.Authorization.ADMINISTRATE, person)); } } else { // If this note was created by the logged person, they should be be able to do any action (except for APPROVE) if (CreatedByPersonAlias?.PersonId == person?.Id) { return(true); } return(base.IsAuthorized(action, person)); } }
/// <summary> /// Shows the view. /// </summary> /// <param name="groupId">The group identifier.</param> protected void ShowView(int groupId) { pnlView.Visible = true; hfGroupId.Value = groupId.ToString(); var rockContext = new RockContext(); var group = new GroupService(rockContext).Get(groupId); if (group == null) { pnlView.Visible = false; return; } group.LoadAttributes(rockContext); var opportunityType = DefinedValueCache.Get(group.GetAttributeValue("OpportunityType").AsGuid()); if (this.GetAttributeValue("SetPageTitletoOpportunityTitle").AsBoolean()) { RockPage.Title = group.GetAttributeValue("OpportunityTitle"); RockPage.BrowserTitle = group.GetAttributeValue("OpportunityTitle"); RockPage.Header.Title = group.GetAttributeValue("OpportunityTitle"); } var mergeFields = LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson, new CommonMergeFieldsOptions { GetLegacyGlobalMergeFields = false }); mergeFields.Add("Block", this.BlockCache); mergeFields.Add("Group", group); // Left Sidebar var photoGuid = group.GetAttributeValue("OpportunityPhoto").AsGuidOrNull(); imgOpportunityPhoto.Visible = photoGuid.HasValue; imgOpportunityPhoto.ImageUrl = string.Format("~/GetImage.ashx?Guid={0}", photoGuid); var groupMembers = group.Members.ToList(); foreach (var gm in groupMembers) { gm.LoadAttributes(rockContext); } // only show the 'Donate to a Participant' button if there are participants that are taking contribution requests btnDonateToParticipant.Visible = groupMembers.Where(a => !a.GetAttributeValue("DisablePublicContributionRequests").AsBoolean()).Any(); if (!string.IsNullOrWhiteSpace(opportunityType.GetAttributeValue("core_DonateButtonText"))) { btnDonateToParticipant.Text = opportunityType.GetAttributeValue("core_DonateButtonText"); } RegistrationInstance registrationInstance = null; var registrationInstanceId = group.GetAttributeValue("RegistrationInstance").AsIntegerOrNull(); if (registrationInstanceId.HasValue) { registrationInstance = new RegistrationInstanceService(rockContext).Get(registrationInstanceId.Value); } mergeFields.Add("RegistrationPage", LinkedPageRoute("RegistrationPage")); if (registrationInstance != null) { mergeFields.Add("RegistrationInstance", registrationInstance); mergeFields.Add("RegistrationInstanceLinkages", registrationInstance.Linkages); // populate merge fields for Registration Counts var maxRegistrantCount = 0; var currentRegistrationCount = 0; if (registrationInstance.MaxAttendees != 0) { maxRegistrantCount = registrationInstance.MaxAttendees; } currentRegistrationCount = new RegistrationRegistrantService(rockContext).Queryable().AsNoTracking() .Where(r => r.Registration.RegistrationInstanceId == registrationInstance.Id && r.OnWaitList == false) .Count(); mergeFields.Add("CurrentRegistrationCount", currentRegistrationCount); if (maxRegistrantCount != 0) { mergeFields.Add("MaxRegistrantCount", maxRegistrantCount); mergeFields.Add("RegistrationSpotsAvailable", maxRegistrantCount - currentRegistrationCount); } } string sidebarLavaTemplate = this.GetAttributeValue("SidebarLavaTemplate"); lSidebarHtml.Text = sidebarLavaTemplate.ResolveMergeFields(mergeFields); SetActiveTab("Details"); // Top Main string summaryLavaTemplate = this.GetAttributeValue("SummaryLavaTemplate"); lMainTopContentHtml.Text = summaryLavaTemplate.ResolveMergeFields(mergeFields); // only show the leader toolbox link of the currentperson has a leader role in the group btnLeaderToolbox.Visible = group.Members.Any(a => a.PersonId == this.CurrentPersonId && a.GroupRole.IsLeader); //// Participant Actions // only show if the current person is a group member var groupMember = group.Members.FirstOrDefault(a => a.PersonId == this.CurrentPersonId); if (groupMember != null) { hfGroupMemberId.Value = groupMember.Id.ToString(); pnlParticipantActions.Visible = true; } else { hfGroupMemberId.Value = null; pnlParticipantActions.Visible = false; } mergeFields.Add("GroupMember", groupMember); // Progress if (groupMember != null && pnlParticipantActions.Visible) { var entityTypeIdGroupMember = EntityTypeCache.GetId <Rock.Model.GroupMember>(); var contributionTotal = new FinancialTransactionDetailService(rockContext).Queryable() .Where(d => d.EntityTypeId == entityTypeIdGroupMember && d.EntityId == groupMember.Id) .Sum(a => (decimal?)a.Amount) ?? 0.00M; var individualFundraisingGoal = groupMember.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull(); if (!individualFundraisingGoal.HasValue) { individualFundraisingGoal = group.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull(); } var amountLeft = individualFundraisingGoal - contributionTotal; var percentMet = individualFundraisingGoal > 0 ? contributionTotal * 100 / individualFundraisingGoal : 100; mergeFields.Add("AmountLeft", amountLeft); mergeFields.Add("PercentMet", percentMet); var queryParams = new Dictionary <string, string>(); queryParams.Add("GroupId", hfGroupId.Value); queryParams.Add("GroupMemberId", hfGroupMemberId.Value); mergeFields.Add("MakeDonationUrl", LinkedPageUrl("DonationPage", queryParams)); mergeFields.Add("ParticipantPageUrl", LinkedPageUrl("ParticipantPage", queryParams)); string makeDonationButtonText = null; if (groupMember.PersonId == this.CurrentPersonId) { makeDonationButtonText = "Make Payment"; } else { makeDonationButtonText = string.Format("Contribute to {0} {1}", RockFilters.Possessive(groupMember.Person.NickName), opportunityType); } mergeFields.Add("MakeDonationButtonText", makeDonationButtonText); var participantLavaTemplate = this.GetAttributeValue("ParticipantLavaTemplate"); lParticipantActionsHtml.Text = participantLavaTemplate.ResolveMergeFields(mergeFields); } // Tab:Details lDetailsHtml.Text = group.GetAttributeValue("OpportunityDetails"); btnDetailsTab.Text = string.Format("{0} Details", opportunityType); // Tab:Updates liUpdatesTab.Visible = false; var updatesContentChannelGuid = group.GetAttributeValue("UpdateContentChannel").AsGuidOrNull(); if (updatesContentChannelGuid.HasValue) { var contentChannel = new ContentChannelService(rockContext).Get(updatesContentChannelGuid.Value); if (contentChannel != null) { liUpdatesTab.Visible = true; string updatesLavaTemplate = this.GetAttributeValue("UpdatesLavaTemplate"); var contentChannelItems = new ContentChannelItemService(rockContext).Queryable().Where(a => a.ContentChannelId == contentChannel.Id).AsNoTracking().ToList(); mergeFields.Add("ContentChannelItems", contentChannelItems); lUpdatesContentItemsHtml.Text = updatesLavaTemplate.ResolveMergeFields(mergeFields); btnUpdatesTab.Text = string.Format("{0} Updates ({1})", opportunityType, contentChannelItems.Count()); } } // Tab:Comments var noteType = NoteTypeCache.Get(this.GetAttributeValue("NoteType").AsGuid()); if (noteType != null) { notesCommentsTimeline.NoteOptions.SetNoteTypes(new List <NoteTypeCache> { noteType }); } notesCommentsTimeline.NoteOptions.EntityId = groupId; // show the Add button on comments for any logged in person notesCommentsTimeline.AddAllowed = true; var enableCommenting = group.GetAttributeValue("EnableCommenting").AsBoolean(); btnCommentsTab.Text = string.Format("Comments ({0})", notesCommentsTimeline.NoteCount); if (CurrentPerson == null) { notesCommentsTimeline.Visible = enableCommenting && (notesCommentsTimeline.NoteCount > 0); lNoLoginNoCommentsYet.Visible = notesCommentsTimeline.NoteCount == 0; liCommentsTab.Visible = enableCommenting; btnLoginToComment.Visible = enableCommenting; } else { lNoLoginNoCommentsYet.Visible = false; notesCommentsTimeline.Visible = enableCommenting; liCommentsTab.Visible = enableCommenting; btnLoginToComment.Visible = false; } // if btnDetailsTab is the only visible tab, hide the tab since there is nothing else to tab to if (!liCommentsTab.Visible && !liUpdatesTab.Visible) { tlTabList.Visible = false; } }
/// <summary> /// Saves the person notes and history. /// </summary> /// <param name="registrationPersonFirstName">First name of the registration person.</param> /// <param name="registrationPersonLastName">Last name of the registration person.</param> /// <param name="currentPersonAliasId">The current person alias identifier.</param> /// <param name="previousRegistrantPersonIds">The previous registrant person ids.</param> public void SavePersonNotesAndHistory(string registrationPersonFirstName, string registrationPersonLastName, int?currentPersonAliasId, List <int> previousRegistrantPersonIds) { // Setup Note settings Registration registration = this; NoteTypeCache noteType = null; using (RockContext rockContext = new RockContext()) { RegistrationInstance registrationInstance = registration.RegistrationInstance ?? new RegistrationInstanceService(rockContext).Get(registration.RegistrationInstanceId); RegistrationTemplate registrationTemplate = registrationInstance.RegistrationTemplate ?? new RegistrationTemplateService(rockContext).Get(registrationInstance.RegistrationTemplateId); if (registrationTemplate != null && registrationTemplate.AddPersonNote) { noteType = NoteTypeCache.Get(Rock.SystemGuid.NoteType.PERSON_EVENT_REGISTRATION.AsGuid()); if (noteType != null) { var noteService = new NoteService(rockContext); var personAliasService = new PersonAliasService(rockContext); Person registrar = null; if (registration.PersonAliasId.HasValue) { registrar = personAliasService.GetPerson(registration.PersonAliasId.Value); } var registrantNames = new List <string>(); // Get each registrant foreach (var registrantPersonAliasId in registration.Registrants .Where(r => r.PersonAliasId.HasValue) .Select(r => r.PersonAliasId.Value) .ToList()) { var registrantPerson = personAliasService.GetPerson(registrantPersonAliasId); if (registrantPerson != null && (previousRegistrantPersonIds == null || !previousRegistrantPersonIds.Contains(registrantPerson.Id))) { var noteText = new StringBuilder(); noteText.AppendFormat("Registered for {0}", registrationInstance.Name); string registrarFullName = string.Empty; if (registrar != null && registrar.Id != registrantPerson.Id) { registrarFullName = string.Format(" by {0}", registrar.FullName); registrantNames.Add(registrantPerson.FullName); } if (registrar != null && (registrationPersonFirstName != registrar.NickName || registrationPersonLastName != registrar.LastName)) { registrarFullName = string.Format(" by {0}", registrationPersonFirstName + " " + registrationPersonLastName); } noteText.Append(registrarFullName); if (noteText.Length > 0) { var note = new Note(); note.NoteTypeId = noteType.Id; note.IsSystem = false; note.IsAlert = false; note.IsPrivateNote = false; note.EntityId = registrantPerson.Id; note.Caption = string.Empty; note.Text = noteText.ToString(); if (registrar == null) { note.CreatedByPersonAliasId = currentPersonAliasId; } else { note.CreatedByPersonAliasId = registrar.PrimaryAliasId; } noteService.Add(note); } var changes = new History.HistoryChangeList(); changes.AddChange(History.HistoryVerb.Registered, History.HistoryChangeType.Record, null); HistoryService.SaveChanges( rockContext, typeof(Person), Rock.SystemGuid.Category.HISTORY_PERSON_REGISTRATION.AsGuid(), registrantPerson.Id, changes, registrationInstance.Name, typeof(Registration), registration.Id, false, currentPersonAliasId, rockContext.SourceOfChange); } } if (registrar != null && registrantNames.Any()) { string namesText = string.Empty; if (registrantNames.Count >= 2) { int lessOne = registrantNames.Count - 1; namesText = registrantNames.Take(lessOne).ToList().AsDelimited(", ") + " and " + registrantNames.Skip(lessOne).Take(1).First() + " "; } else { namesText = registrantNames.First() + " "; } var note = new Note(); note.NoteTypeId = noteType.Id; note.IsSystem = false; note.IsAlert = false; note.IsPrivateNote = false; note.EntityId = registrar.Id; note.Caption = string.Empty; note.Text = string.Format("Registered {0} for {1}", namesText, registrationInstance.Name); noteService.Add(note); var changes = new History.HistoryChangeList(); changes.AddChange(History.HistoryVerb.Registered, History.HistoryChangeType.Record, namesText); HistoryService.SaveChanges( rockContext, typeof(Person), Rock.SystemGuid.Category.HISTORY_PERSON_REGISTRATION.AsGuid(), registrar.Id, changes, registrationInstance.Name, typeof(Registration), registration.Id, false, currentPersonAliasId, rockContext.SourceOfChange); } rockContext.SaveChanges(); } } } }