diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Models/GeneratedCode.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Models/GeneratedCode.cs index 02330ad68..c6b416f68 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Models/GeneratedCode.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Models/GeneratedCode.cs @@ -56,6 +56,8 @@ public static class Fields public const string dfeta_account_dfeta_initialteachertraining = "dfeta_account_dfeta_initialteachertraining"; public const string dfeta_account_dfeta_qualification_he = "dfeta_account_dfeta_qualification_he"; public const string incident_customer_accounts = "incident_customer_accounts"; + public const string Referencedmsa_account_managingpartner = "Referencedmsa_account_managingpartner"; + public const string msa_contact_managingpartner = "msa_contact_managingpartner"; public const string Referencingaccount_master_account = "account_master_account"; public const string Referencingaccount_parent_account = "account_parent_account"; public const string account_primary_contact = "account_primary_contact"; @@ -63,6 +65,7 @@ public static class Fields public const string lk_accountbase_createdonbehalfby = "lk_accountbase_createdonbehalfby"; public const string lk_accountbase_modifiedby = "lk_accountbase_modifiedby"; public const string lk_accountbase_modifiedonbehalfby = "lk_accountbase_modifiedonbehalfby"; + public const string Referencingmsa_account_managingpartner = "msa_account_managingpartner"; public const string system_user_accounts = "system_user_accounts"; public const string user_accounts = "user_accounts"; } @@ -425,6 +428,46 @@ public System.Collections.Generic.IEnumerable + /// 1:N msa_account_managingpartner + /// + [Microsoft.Xrm.Sdk.RelationshipSchemaNameAttribute("msa_account_managingpartner", Microsoft.Xrm.Sdk.EntityRole.Referenced)] + public System.Collections.Generic.IEnumerable Referencedmsa_account_managingpartner + { + [System.Diagnostics.DebuggerNonUserCode()] + get + { + return this.GetRelatedEntities("msa_account_managingpartner", Microsoft.Xrm.Sdk.EntityRole.Referenced); + } + [System.Diagnostics.DebuggerNonUserCode()] + set + { + this.OnPropertyChanging("Referencedmsa_account_managingpartner"); + this.SetRelatedEntities("msa_account_managingpartner", Microsoft.Xrm.Sdk.EntityRole.Referenced, value); + this.OnPropertyChanged("Referencedmsa_account_managingpartner"); + } + } + + /// + /// 1:N msa_contact_managingpartner + /// + [Microsoft.Xrm.Sdk.RelationshipSchemaNameAttribute("msa_contact_managingpartner")] + public System.Collections.Generic.IEnumerable msa_contact_managingpartner + { + [System.Diagnostics.DebuggerNonUserCode()] + get + { + return this.GetRelatedEntities("msa_contact_managingpartner", null); + } + [System.Diagnostics.DebuggerNonUserCode()] + set + { + this.OnPropertyChanging("msa_contact_managingpartner"); + this.SetRelatedEntities("msa_contact_managingpartner", null, value); + this.OnPropertyChanged("msa_contact_managingpartner"); + } + } + /// /// N:1 account_master_account /// @@ -572,6 +615,27 @@ public TeachingRecordSystem.Core.Dqt.Models.SystemUser lk_accountbase_modifiedon } } + /// + /// N:1 msa_account_managingpartner + /// + [Microsoft.Xrm.Sdk.AttributeLogicalNameAttribute("msa_managingpartnerid")] + [Microsoft.Xrm.Sdk.RelationshipSchemaNameAttribute("msa_account_managingpartner", Microsoft.Xrm.Sdk.EntityRole.Referencing)] + public TeachingRecordSystem.Core.Dqt.Models.Account Referencingmsa_account_managingpartner + { + [System.Diagnostics.DebuggerNonUserCode()] + get + { + return this.GetRelatedEntity("msa_account_managingpartner", Microsoft.Xrm.Sdk.EntityRole.Referencing); + } + [System.Diagnostics.DebuggerNonUserCode()] + set + { + this.OnPropertyChanging("Referencingmsa_account_managingpartner"); + this.SetRelatedEntity("msa_account_managingpartner", Microsoft.Xrm.Sdk.EntityRole.Referencing, value); + this.OnPropertyChanged("Referencingmsa_account_managingpartner"); + } + } + /// /// N:1 system_user_accounts /// @@ -1180,6 +1244,7 @@ public static class Fields public const string lk_contact_modifiedonbehalfby = "lk_contact_modifiedonbehalfby"; public const string lk_contactbase_createdby = "lk_contactbase_createdby"; public const string lk_contactbase_modifiedby = "lk_contactbase_modifiedby"; + public const string msa_contact_managingpartner = "msa_contact_managingpartner"; public const string system_user_contacts = "system_user_contacts"; } @@ -2675,6 +2740,27 @@ public TeachingRecordSystem.Core.Dqt.Models.SystemUser lk_contactbase_modifiedby } } + /// + /// N:1 msa_contact_managingpartner + /// + [Microsoft.Xrm.Sdk.AttributeLogicalNameAttribute("msa_managingpartnerid")] + [Microsoft.Xrm.Sdk.RelationshipSchemaNameAttribute("msa_contact_managingpartner")] + public TeachingRecordSystem.Core.Dqt.Models.Account msa_contact_managingpartner + { + [System.Diagnostics.DebuggerNonUserCode()] + get + { + return this.GetRelatedEntity("msa_contact_managingpartner", null); + } + [System.Diagnostics.DebuggerNonUserCode()] + set + { + this.OnPropertyChanging("msa_contact_managingpartner"); + this.SetRelatedEntity("msa_contact_managingpartner", null, value); + this.OnPropertyChanged("msa_contact_managingpartner"); + } + } + /// /// N:1 system_user_contacts /// @@ -8398,6 +8484,7 @@ public static class Fields public const string dfeta_NoReAppuntildate = "dfeta_noreappuntildate"; public const string dfeta_PersonId = "dfeta_personid"; public const string dfeta_SanctionCodeId = "dfeta_sanctioncodeid"; + public const string dfeta_SanctionDetails = "dfeta_sanctiondetails"; public const string dfeta_sanctionId = "dfeta_sanctionid"; public const string Id = "dfeta_sanctionid"; public const string dfeta_Spent = "dfeta_spent"; @@ -8536,6 +8623,26 @@ public Microsoft.Xrm.Sdk.EntityReference dfeta_SanctionCodeId } } + /// + /// + /// + [Microsoft.Xrm.Sdk.AttributeLogicalNameAttribute("dfeta_sanctiondetails")] + public string dfeta_SanctionDetails + { + [System.Diagnostics.DebuggerNonUserCode()] + get + { + return this.GetAttributeValue("dfeta_sanctiondetails"); + } + [System.Diagnostics.DebuggerNonUserCode()] + set + { + this.OnPropertyChanging("dfeta_SanctionDetails"); + this.SetAttributeValue("dfeta_sanctiondetails", value); + this.OnPropertyChanged("dfeta_SanctionDetails"); + } + } + /// /// Unique identifier for entity instances /// @@ -8846,6 +8953,7 @@ public partial class dfeta_sanctioncode : Microsoft.Xrm.Sdk.Entity, System.Compo /// public static class Fields { + public const string dfeta_name = "dfeta_name"; public const string dfeta_sanctioncodeId = "dfeta_sanctioncodeid"; public const string Id = "dfeta_sanctioncodeid"; public const string dfeta_Value = "dfeta_value"; @@ -8900,6 +9008,26 @@ private void OnPropertyChanging(string propertyName) } } + /// + /// The name of the custom entity. + /// + [Microsoft.Xrm.Sdk.AttributeLogicalNameAttribute("dfeta_name")] + public string dfeta_name + { + [System.Diagnostics.DebuggerNonUserCode()] + get + { + return this.GetAttributeValue("dfeta_name"); + } + [System.Diagnostics.DebuggerNonUserCode()] + set + { + this.OnPropertyChanging("dfeta_name"); + this.SetAttributeValue("dfeta_name", value); + this.OnPropertyChanged("dfeta_name"); + } + } + /// /// Unique identifier for entity instances /// diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Queries/GetSanctionDetailsByContactIdQuery.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Queries/GetSanctionDetailsByContactIdQuery.cs new file mode 100644 index 000000000..c54badbd9 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Queries/GetSanctionDetailsByContactIdQuery.cs @@ -0,0 +1,5 @@ +namespace TeachingRecordSystem.Core.Dqt.Queries; + +public record GetSanctionDetailsByContactIdQuery(Guid ContactId) : ICrmQuery; + +public record SanctionDetailResult(dfeta_sanction Sanction, string Description); diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetAllSanctionCodesHandler.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetAllSanctionCodesHandler.cs index 119f846c5..c870fd628 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetAllSanctionCodesHandler.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetAllSanctionCodesHandler.cs @@ -14,7 +14,8 @@ public async Task Execute(GetAllSanctionCodesQuery query, EntityName = dfeta_sanctioncode.EntityLogicalName, ColumnSet = new ColumnSet( dfeta_sanctioncode.Fields.dfeta_sanctioncodeId, - dfeta_sanctioncode.Fields.dfeta_Value) + dfeta_sanctioncode.Fields.dfeta_Value, + dfeta_sanctioncode.Fields.dfeta_name) }; queryExpression.Criteria.AddCondition(dfeta_sanctioncode.Fields.StateCode, ConditionOperator.Equal, (int)dfeta_sanctioncodeState.Active); diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetSanctionDetailsByContactIdHandler.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetSanctionDetailsByContactIdHandler.cs new file mode 100644 index 000000000..0181d368a --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/GetSanctionDetailsByContactIdHandler.cs @@ -0,0 +1,45 @@ +using Microsoft.PowerPlatform.Dataverse.Client; +using Microsoft.Xrm.Sdk.Messages; +using Microsoft.Xrm.Sdk.Query; +using TeachingRecordSystem.Core.Dqt.Queries; + +namespace TeachingRecordSystem.Core.Dqt.QueryHandlers; + +public class GetSanctionDetailsByContactIdHandler : ICrmQueryHandler +{ + public async Task Execute(GetSanctionDetailsByContactIdQuery query, IOrganizationServiceAsync organizationService) + { + var filter = new FilterExpression(); + filter.AddCondition(dfeta_sanction.Fields.dfeta_PersonId, ConditionOperator.Equal, query.ContactId); + + var queryExpression = new QueryExpression(dfeta_sanction.EntityLogicalName) + { + ColumnSet = new ColumnSet( + dfeta_sanction.PrimaryIdAttribute, + dfeta_sanction.Fields.dfeta_SanctionDetails, + dfeta_sanction.Fields.dfeta_PersonId, + dfeta_sanction.Fields.dfeta_StartDate, + dfeta_sanction.Fields.dfeta_EndDate, + dfeta_sanction.Fields.dfeta_Spent, + dfeta_sanction.Fields.StateCode), + Criteria = filter + }; + + var sanctionCodeLink = queryExpression.AddLink( + dfeta_sanctioncode.EntityLogicalName, + dfeta_sanction.Fields.dfeta_SanctionCodeId, + dfeta_sanctioncode.PrimaryIdAttribute, + JoinOperator.Inner); + + sanctionCodeLink.Columns = new ColumnSet(dfeta_sanctioncode.PrimaryIdAttribute, dfeta_sanctioncode.Fields.dfeta_name); + sanctionCodeLink.EntityAlias = typeof(dfeta_sanctioncode).Name; + + var request = new RetrieveMultipleRequest() + { + Query = queryExpression + }; + + var result = (RetrieveMultipleResponse)await organizationService.ExecuteAsync(request); + return result.EntityCollection.Entities.Select(entity => new SanctionDetailResult(entity.ToEntity(), entity.Extract().dfeta_name)).ToArray(); + } +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Infrastructure/Filters/CheckPersonExistsFilter.cs b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Infrastructure/Filters/CheckPersonExistsFilter.cs new file mode 100644 index 000000000..179ffa9a6 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Infrastructure/Filters/CheckPersonExistsFilter.cs @@ -0,0 +1,29 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Xrm.Sdk.Query; +using TeachingRecordSystem.Core.Dqt.Models; +using TeachingRecordSystem.Core.Dqt.Queries; + +namespace TeachingRecordSystem.SupportUi.Infrastructure.Filters; + +public class CheckPersonExistsFilter : IAsyncPageFilter +{ + public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) + { + var personId = context.RouteData.Values["personId"] as string; + if (personId is not null) + { + var crmQueryDispatcher = context.HttpContext.RequestServices.GetRequiredService(); + var person = await crmQueryDispatcher.ExecuteQuery(new GetContactDetailByIdQuery(Guid.Parse(personId), new ColumnSet(Contact.Fields.Id))); + if (person is null) + { + context.Result = new NotFoundResult(); + return; + } + } + + await next(); + } + + public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) => Task.CompletedTask; +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/Alert/Close.cshtml b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/Alert/Close.cshtml new file mode 100644 index 000000000..5a7e81625 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/Alert/Close.cshtml @@ -0,0 +1,7 @@ +@page "/alerts/{alertId}/close" +@model TeachingRecordSystem.SupportUi.Pages.Alerts.Alert.CloseModel +@{ + ViewBag.Title = "Close alert"; +} + +

@ViewBag.Title

diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/Alert/Close.cshtml.cs b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/Alert/Close.cshtml.cs new file mode 100644 index 000000000..7a8e895cf --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/Alert/Close.cshtml.cs @@ -0,0 +1,10 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace TeachingRecordSystem.SupportUi.Pages.Alerts.Alert; + +public class CloseModel : PageModel +{ + public void OnGet() + { + } +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/Alert/Index.cshtml b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/Alert/Index.cshtml new file mode 100644 index 000000000..0813e6657 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/Alert/Index.cshtml @@ -0,0 +1,7 @@ +@page "/alerts/{alertId}" +@model IndexModel +@{ + ViewBag.Title = "Alert"; +} + +

@ViewBag.Title

diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/Alert/Index.cshtml.cs b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/Alert/Index.cshtml.cs new file mode 100644 index 000000000..163e6f653 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/Alert/Index.cshtml.cs @@ -0,0 +1,10 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace TeachingRecordSystem.SupportUi.Pages.Alerts.Alert; + +public class IndexModel : PageModel +{ + public void OnGet() + { + } +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Common/PersonSubNavigationTab.cs b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Common/PersonSubNavigationTab.cs new file mode 100644 index 000000000..149613550 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Common/PersonSubNavigationTab.cs @@ -0,0 +1,8 @@ +namespace TeachingRecordSystem.SupportUi.Pages.Common; + +public enum PersonSubNavigationTab +{ + General, + Alerts, + ChangeLog +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/Layout.cshtml b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/Layout.cshtml new file mode 100644 index 000000000..9b011a80e --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/Layout.cshtml @@ -0,0 +1,37 @@ +@using TeachingRecordSystem.Core.Dqt.Models; +@using TeachingRecordSystem.SupportUi.Pages.Common; +@{ + Layout = "_Layout"; + var selectedTab = (PersonSubNavigationTab)ViewBag.SelectedTab; + var personId = (Guid)ViewBag.PersonId; + var search = (string)ViewBag.Search; + var sortBy = (ContactSearchSortByOption?)ViewBag.SortBy; + var pageNumber = (int?)ViewBag.PageNumber; +} + +@section BeforeContent { + Back to find a record +} + +

@ViewBag.Title

+ +
+
+ + @RenderBody() +
+
diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/AddAlert.cshtml b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/AddAlert.cshtml new file mode 100644 index 000000000..e74afd506 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/AddAlert.cshtml @@ -0,0 +1,7 @@ +@page "/persons/{personId}/alerts/new" +@model TeachingRecordSystem.SupportUi.Pages.Persons.PersonDetail.AddAlertModel +@{ + ViewBag.Title = "Add alert"; +} + +

@ViewBag.Title

diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/AddAlert.cshtml.cs b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/AddAlert.cshtml.cs new file mode 100644 index 000000000..071843f2d --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/AddAlert.cshtml.cs @@ -0,0 +1,10 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace TeachingRecordSystem.SupportUi.Pages.Persons.PersonDetail; + +public class AddAlertModel : PageModel +{ + public void OnGet() + { + } +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/Alerts.cshtml b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/Alerts.cshtml new file mode 100644 index 000000000..3af05c611 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/Alerts.cshtml @@ -0,0 +1,82 @@ +@page "/persons/{personId}/alerts" +@using TeachingRecordSystem.SupportUi.Pages.Common; +@model TeachingRecordSystem.SupportUi.Pages.Persons.PersonDetail.AlertsModel +@{ + Layout = "Layout"; + ViewBag.SelectedTab = PersonSubNavigationTab.Alerts; + ViewBag.PersonId = Model.PersonId; + ViewBag.Search = Model.Search; + ViewBag.SortBy = Model.SortBy; + ViewBag.PageNumber = Model.PageNumber; + ViewBag.Title = Model.Name; +} + +

Current alerts

+ +@if (Model.CurrentAlerts is null || Model.CurrentAlerts.Length == 0) +{ +

No current alerts

+} +else +{ + @foreach (var alert in Model.CurrentAlerts) + { + + @alert.Description + + Close + + + + Start date + @(alert.StartDate.HasValue ? alert.StartDate.Value.ToString("dd/MM/yyyy") : "-") + + + Details + + @if (!string.IsNullOrEmpty(@alert.Details)) + { + var lines = @alert.Details.Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); + @for (int i = 0; i < lines.Length; i++) + { + @lines[i] + @if (i < lines.Length - 1) + { +
+ } + } + } +
+
+
+
+ } +} + +Add an alert + +@if (Model.PreviousAlerts is not null && Model.PreviousAlerts.Length > 0) +{ + + + + + + + + + + + + @foreach (var alert in Model.PreviousAlerts) + { + + + + + + + } + +
Previous alerts
AlertStart dateEnd dateStatus
@alert.Description@(alert.StartDate.HasValue ? alert.StartDate.Value.ToString("dd/MM/yyyy") : "-")@(alert.EndDate.HasValue ? alert.EndDate.Value.ToString("dd/MM/yyyy") : "-")@alert.Status
+} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/Alerts.cshtml.cs b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/Alerts.cshtml.cs new file mode 100644 index 000000000..fefd94bcd --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/Alerts.cshtml.cs @@ -0,0 +1,101 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.Xrm.Sdk.Query; +using TeachingRecordSystem.Core.Dqt.Models; +using TeachingRecordSystem.Core.Dqt.Queries; + +namespace TeachingRecordSystem.SupportUi.Pages.Persons.PersonDetail; + +public class AlertsModel : PageModel +{ + private readonly ICrmQueryDispatcher _crmQueryDispatcher; + + public AlertsModel(ICrmQueryDispatcher crmQueryDispatcher) + { + _crmQueryDispatcher = crmQueryDispatcher; + } + + [FromRoute] + public Guid PersonId { get; set; } + + [FromQuery] + public string? Search { get; set; } + + [FromQuery] + public int? PageNumber { get; set; } + + [FromQuery] + public ContactSearchSortByOption? SortBy { get; set; } + + public string? Name { get; set; } + + public AlertInfo[]? CurrentAlerts { get; set; } + + public AlertInfo[]? PreviousAlerts { get; set; } + + public async Task OnGet() + { + var contactDetail = await _crmQueryDispatcher.ExecuteQuery( + new GetContactDetailByIdQuery( + PersonId, + new ColumnSet( + Contact.Fields.FirstName, + Contact.Fields.MiddleName, + Contact.Fields.LastName, + Contact.Fields.dfeta_StatedFirstName, + Contact.Fields.dfeta_StatedMiddleName, + Contact.Fields.dfeta_StatedLastName))); + + Name = contactDetail!.Contact.ResolveFullName(includeMiddleName: false); + + var sanctions = await _crmQueryDispatcher.ExecuteQuery(new GetSanctionDetailsByContactIdQuery(PersonId)); + + var allAlerts = sanctions!.Select(MapSanction); + + CurrentAlerts = allAlerts + .Where(alert => alert.Status == AlertStatus.Active) + .OrderBy(a => a.StartDate) + .ToArray(); + + PreviousAlerts = allAlerts + .Except(CurrentAlerts) + .OrderBy(a => a.StartDate) + .ToArray(); + + return Page(); + } + + private AlertInfo MapSanction(SanctionDetailResult sanction) + { + var alertStatus = sanction.Sanction.StateCode == dfeta_sanctionState.Inactive ? AlertStatus.Inactive : + sanction.Sanction.dfeta_EndDate is null ? AlertStatus.Active : + AlertStatus.Closed; + + return new AlertInfo() + { + AlertId = sanction.Sanction.Id, + Description = sanction.Description, + Details = sanction.Sanction.dfeta_SanctionDetails, + StartDate = sanction.Sanction.dfeta_StartDate.ToDateOnlyWithDqtBstFix(isLocalTime: true), + EndDate = sanction.Sanction.dfeta_EndDate.ToDateOnlyWithDqtBstFix(isLocalTime: true), + Status = alertStatus + }; + } + + public record AlertInfo + { + public required Guid AlertId { get; init; } + public required string Description { get; init; } + public required string Details { get; init; } + public required DateOnly? StartDate { get; init; } + public required DateOnly? EndDate { get; init; } + public required AlertStatus Status { get; init; } + } + + public enum AlertStatus + { + Active, + Inactive, + Closed + } +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/ChangeLog.cshtml b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/ChangeLog.cshtml new file mode 100644 index 000000000..202e1fd2a --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/ChangeLog.cshtml @@ -0,0 +1,14 @@ +@page "/persons/{personId}/changelog" +@using TeachingRecordSystem.SupportUi.Pages.Common; +@model TeachingRecordSystem.SupportUi.Pages.Persons.PersonDetail.ChangeLogModel +@{ + Layout = "Layout"; + ViewBag.SelectedTab = PersonSubNavigationTab.ChangeLog; + ViewBag.PersonId = Model.PersonId; + ViewBag.Search = Model.Search; + ViewBag.SortBy = Model.SortBy; + ViewBag.PageNumber = Model.PageNumber; + ViewBag.Title = Model.Name; +} + +

Change log goes here

diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/ChangeLog.cshtml.cs b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/ChangeLog.cshtml.cs new file mode 100644 index 000000000..f7324be95 --- /dev/null +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/ChangeLog.cshtml.cs @@ -0,0 +1,54 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.Xrm.Sdk.Query; +using TeachingRecordSystem.Core.Dqt.Models; +using TeachingRecordSystem.Core.Dqt.Queries; + +namespace TeachingRecordSystem.SupportUi.Pages.Persons.PersonDetail; + +public class ChangeLogModel : PageModel +{ + private readonly ICrmQueryDispatcher _crmQueryDispatcher; + + public ChangeLogModel(ICrmQueryDispatcher crmQueryDispatcher) + { + _crmQueryDispatcher = crmQueryDispatcher; + } + + [FromRoute] + public Guid PersonId { get; set; } + + [FromQuery] + public string? Search { get; set; } + + [FromQuery] + public int? PageNumber { get; set; } + + [FromQuery] + public ContactSearchSortByOption? SortBy { get; set; } + + public string? Name { get; set; } + + public async Task OnGet() + { + var contactDetail = await _crmQueryDispatcher.ExecuteQuery( + new GetContactDetailByIdQuery( + PersonId, + new ColumnSet( + Contact.Fields.FirstName, + Contact.Fields.MiddleName, + Contact.Fields.LastName, + Contact.Fields.dfeta_StatedFirstName, + Contact.Fields.dfeta_StatedMiddleName, + Contact.Fields.dfeta_StatedLastName))); + + if (contactDetail is null) + { + return NotFound(); + } + + Name = contactDetail.Contact.ResolveFullName(includeMiddleName: false); + + return Page(); + } +} diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/Index.cshtml b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/Index.cshtml index 984202b15..8e11fe418 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/Index.cshtml +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/Index.cshtml @@ -1,60 +1,38 @@ @page "/persons/{personId}" +@using TeachingRecordSystem.SupportUi.Pages.Common; @model TeachingRecordSystem.SupportUi.Pages.Persons.PersonDetail.IndexModel @{ - ViewBag.Title = @Model.Person!.Name; + Layout = "Layout"; + ViewBag.SelectedTab = PersonSubNavigationTab.General; + ViewBag.PersonId = Model.PersonId; + ViewBag.Search = Model.Search; + ViewBag.SortBy = Model.SortBy; + ViewBag.PageNumber = Model.PageNumber; + ViewBag.Title = Model.Person!.Name; } -@section BeforeContent { - -} - -

@ViewBag.Title

- -
-
- - - @if (Model.SelectedTab == IndexModel.PersonSubNavigationTab.General) - { - - Personal Details - - - Name - @Model.Person.FullName - - - Date of birth - @(Model.Person.DateOfBirth.HasValue ? Model.Person.DateOfBirth.Value.ToString("dd/MM/yyyy") : "Not provided") - - - TRN - @(!string.IsNullOrEmpty(Model.Person.Trn) ? Model.Person.Trn : "Not provided") - - - Email - @(!string.IsNullOrEmpty(Model.Person.Email) ? Model.Person.Email : "Not provided") - - - Mobile number - @(!string.IsNullOrEmpty(Model.Person.MobileNumber) ? Model.Person.MobileNumber : "Not provided") - - - - } -
-
+ + Personal Details + + + Name + @Model.Person.FullName + + + Date of birth + @(Model.Person.DateOfBirth.HasValue ? Model.Person.DateOfBirth.Value.ToString("dd/MM/yyyy") : "Not provided") + + + TRN + @(!string.IsNullOrEmpty(Model.Person.Trn) ? Model.Person.Trn : "Not provided") + + + Email + @(!string.IsNullOrEmpty(Model.Person.Email) ? Model.Person.Email : "Not provided") + + + Mobile number + @(!string.IsNullOrEmpty(Model.Person.MobileNumber) ? Model.Person.MobileNumber : "Not provided") + + + diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/Index.cshtml.cs b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/Index.cshtml.cs index bd8883772..ec7daa51d 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/Index.cshtml.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Persons/PersonDetail/Index.cshtml.cs @@ -25,17 +25,12 @@ public IndexModel(ICrmQueryDispatcher crmQueryDispatcher) public int? PageNumber { get; set; } [FromQuery] - public ContactSearchSortByOption SortBy { get; set; } - - [FromQuery] - public PersonSubNavigationTab? SelectedTab { get; set; } + public ContactSearchSortByOption? SortBy { get; set; } public PersonInfo? Person { get; set; } public async Task OnGet() { - SelectedTab ??= PersonSubNavigationTab.General; - var contactDetail = await _crmQueryDispatcher.ExecuteQuery( new GetContactDetailByIdQuery( PersonId, @@ -52,12 +47,7 @@ public async Task OnGet() Contact.Fields.MobilePhone, Contact.Fields.dfeta_NINumber))); - if (contactDetail is null) - { - return NotFound(); - } - - Person = MapContact(contactDetail.Contact); + Person = MapContact(contactDetail!.Contact); return Page(); } @@ -86,11 +76,4 @@ public record PersonInfo public required string? Email { get; init; } public required string? MobileNumber { get; init; } } - - public enum PersonSubNavigationTab - { - General, - Alerts, - ChangeLog - } } diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Shared/_Layout.cshtml b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Shared/_Layout.cshtml index 20c0c334f..4001861de 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Shared/_Layout.cshtml +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Shared/_Layout.cshtml @@ -49,7 +49,7 @@ }
  • - All records + Find a record
  • if (User.IsInRole(UserRoles.Administrator)) diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Program.cs b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Program.cs index 1ca33ccdf..98aa7fe58 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Program.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Program.cs @@ -96,7 +96,15 @@ }); builder.Services - .AddRazorPages() + .AddRazorPages(options => + { + options.Conventions.AddFolderApplicationModelConvention( + "/Persons/PersonDetail", + model => + { + model.Filters.Add(new CheckPersonExistsFilter()); + }); + }) .AddMvcOptions(options => { var policy = new AuthorizationPolicyBuilder() diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/TrsLinkGenerator.cs b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/TrsLinkGenerator.cs index 675cba515..2862a4d49 100644 --- a/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/TrsLinkGenerator.cs +++ b/TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/TrsLinkGenerator.cs @@ -1,5 +1,4 @@ using TeachingRecordSystem.Core.Dqt.Models; -using static TeachingRecordSystem.SupportUi.Pages.Persons.PersonDetail.IndexModel; namespace TeachingRecordSystem.SupportUi; @@ -18,6 +17,10 @@ public TrsLinkGenerator(LinkGenerator linkGenerator) public string SignedOut() => GetRequiredPathByPage("/SignedOut"); + public string Alert(Guid alertId) => GetRequiredPathByPage("/Alerts/Alert/Index", routeValues: new { alertId }); + + public string CloseAlert(Guid alertId) => GetRequiredPathByPage("/Alerts/Alert/Close", routeValues: new { alertId }); + public string Cases() => GetRequiredPathByPage("/Cases/Index"); public string EditCase(string ticketNumber) => GetRequiredPathByPage("/Cases/EditCase/Index", routeValues: new { ticketNumber }); @@ -31,8 +34,16 @@ public TrsLinkGenerator(LinkGenerator linkGenerator) public string Persons(string? search = null, ContactSearchSortByOption? sortBy = null, int? pageNumber = null) => GetRequiredPathByPage("/Persons/Index", routeValues: new { search, sortBy, pageNumber }); - public string PersonDetail(Guid personId, PersonSubNavigationTab? selectedTab = null, string? search = null, ContactSearchSortByOption? sortBy = null, int? pageNumber = null) => - GetRequiredPathByPage("/Persons/PersonDetail/Index", routeValues: new { personId, selectedTab, search, sortBy, pageNumber }); + public string PersonDetail(Guid personId, string? search = null, ContactSearchSortByOption? sortBy = null, int? pageNumber = null) => + GetRequiredPathByPage("/Persons/PersonDetail/Index", routeValues: new { personId, search, sortBy, pageNumber }); + + public string PersonAlerts(Guid personId, string? search = null, ContactSearchSortByOption? sortBy = null, int? pageNumber = null) => + GetRequiredPathByPage("/Persons/PersonDetail/Alerts", routeValues: new { personId, search, sortBy, pageNumber }); + + public string PersonAddAlert(Guid personId) => GetRequiredPathByPage("/Persons/PersonDetail/AddAlert", routeValues: new { personId }); + + public string PersonChangeLog(Guid personId, string? search = null, ContactSearchSortByOption? sortBy = null, int? pageNumber = null) => + GetRequiredPathByPage("/Persons/PersonDetail/ChangeLog", routeValues: new { personId, search, sortBy, pageNumber }); public string Users() => GetRequiredPathByPage("/Users/Index"); diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.Tests/QueryTests/GetSanctionDetailsByContactIdTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.Tests/QueryTests/GetSanctionDetailsByContactIdTests.cs new file mode 100644 index 000000000..ea4275eaa --- /dev/null +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.Core.Dqt.Tests/QueryTests/GetSanctionDetailsByContactIdTests.cs @@ -0,0 +1,51 @@ +namespace TeachingRecordSystem.Core.Dqt.Tests.QueryTests; + +public class GetSanctionDetailsByContactIdTests : IAsyncLifetime +{ + private readonly CrmClientFixture.TestDataScope _dataScope; + private readonly CrmQueryDispatcher _crmQueryDispatcher; + + public GetSanctionDetailsByContactIdTests(CrmClientFixture crmClientFixture) + { + _dataScope = crmClientFixture.CreateTestDataScope(); + _crmQueryDispatcher = crmClientFixture.CreateQueryDispatcher(); + } + + public Task InitializeAsync() => Task.CompletedTask; + + public async Task DisposeAsync() => await _dataScope.DisposeAsync(); + + [Fact] + public async Task WhenCalled_ForContactWithoutSanctions_ReturnsEmptyArray() + { + // Arrange + var person = await _dataScope.TestData.CreatePerson(); + + // Act + var sanctions = await _crmQueryDispatcher.ExecuteQuery(new GetSanctionDetailsByContactIdQuery(person.ContactId)); + + // Assert + Assert.Empty(sanctions); + } + + [Fact] + public async Task WhenCalled_ForContactWithSanctions_ReturnsSanctionsAsExpected() + { + // Arrange + var sanction1Code = "G1"; + var sanction1CodeName = (await _dataScope.TestData.ReferenceDataCache.GetSanctionCodeByValue(sanction1Code)).dfeta_name; + var sanction2Code = "A1"; + var sanction2CodeName = (await _dataScope.TestData.ReferenceDataCache.GetSanctionCodeByValue(sanction2Code)).dfeta_name; + var person = await _dataScope.TestData.CreatePerson(x => x.WithSanction(sanction1Code).WithSanction(sanction2Code)); + + // Act + var sanctions = await _crmQueryDispatcher.ExecuteQuery(new GetSanctionDetailsByContactIdQuery(person.ContactId)); + + // Assert + Assert.Equal(2, sanctions.Length); + Assert.Collection( + sanctions, + s => Assert.Equal(sanction1CodeName, s.Description), + s => Assert.Equal(sanction2CodeName, s.Description)); + } +} diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.SupportUi.Tests/PageTests/Persons/PersonDetail/AlertsTests.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.SupportUi.Tests/PageTests/Persons/PersonDetail/AlertsTests.cs new file mode 100644 index 000000000..27bce23e0 --- /dev/null +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.SupportUi.Tests/PageTests/Persons/PersonDetail/AlertsTests.cs @@ -0,0 +1,145 @@ +namespace TeachingRecordSystem.SupportUi.Tests.PageTests.Persons.PersonDetail; + +public class AlertsTests : TestBase +{ + public AlertsTests(HostFixture hostFixture) + : base(hostFixture) + { + } + + [Fact] + public async Task Get_WithPersonIdForNonExistentPerson_ReturnsNotFound() + { + // Arrange + var nonExistentPersonId = Guid.NewGuid().ToString(); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/persons/{nonExistentPersonId}/alerts"); + + // Act + var response = await HttpClient.SendAsync(request); + + // Assert + Assert.Equal(StatusCodes.Status404NotFound, (int)response.StatusCode); + } + + [Fact] + public async Task Get_WithPersonIdForPersonWithNoAlerts_DisplaysNoCurrentAlerts() + { + // Arrange + var person = await TestData.CreatePerson(); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/persons/{person.ContactId}/alerts"); + + // Act + var response = await HttpClient.SendAsync(request); + + // Assert + Assert.Equal(StatusCodes.Status200OK, (int)response.StatusCode); + + var doc = await response.GetDocument(); + var noCurrentAlerts = doc.GetElementByTestId("no-current-alerts"); + Assert.NotNull(noCurrentAlerts); + } + + [Fact] + public async Task Get_WithPersonIdForPersonWithOnlyPreviousAlerts_DisplaysExpectedContent() + { + // Arrange + var sanctionCode = "G1"; + var sanctionCodeName = (await TestData.ReferenceDataCache.GetSanctionCodeByValue(sanctionCode)).dfeta_name; + var sanctionStartDate = new DateOnly(2023, 05, 01); + var sanctionEndDate = new DateOnly(2023, 08, 20); + var person = await TestData.CreatePerson(x => x.WithSanction(sanctionCode, startDate: sanctionStartDate, endDate: sanctionEndDate)); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/persons/{person.ContactId}/alerts"); + + // Act + var response = await HttpClient.SendAsync(request); + + // Assert + Assert.Equal(StatusCodes.Status200OK, (int)response.StatusCode); + + var doc = await response.GetDocument(); + var noCurrentAlerts = doc.GetElementByTestId("no-current-alerts"); + Assert.NotNull(noCurrentAlerts); + + var previousAlerts = doc.GetElementByTestId("previous-alerts"); + Assert.NotNull(previousAlerts); + + var previousAlert = previousAlerts.GetElementByTestId($"previous-alert-{person.Sanctions[0].SanctionId}"); + Assert.NotNull(previousAlert); + Assert.Equal(sanctionCodeName, previousAlert.GetElementByTestId($"previous-alert-description-{person.Sanctions[0].SanctionId}")!.TextContent); + Assert.Equal(sanctionStartDate.ToString("dd/MM/yyyy"), previousAlert.GetElementByTestId($"previous-alert-start-date-{person.Sanctions[0].SanctionId}")!.TextContent); + Assert.Equal(sanctionEndDate.ToString("dd/MM/yyyy"), previousAlert.GetElementByTestId($"previous-alert-end-date-{person.Sanctions[0].SanctionId}")!.TextContent); + Assert.Equal("Closed", previousAlert.GetElementByTestId($"previous-alert-status-{person.Sanctions[0].SanctionId}")!.TextContent); + } + + [Fact] + public async Task Get_WithPersonIdForPersonWithOnlyCurrentAlerts_DisplaysExpectedContent() + { + // Arrange + var sanctionCode = "G1"; + var sanctionCodeName = (await TestData.ReferenceDataCache.GetSanctionCodeByValue(sanctionCode)).dfeta_name; + var sanctionStartDate = new DateOnly(2023, 05, 01); + var person = await TestData.CreatePerson(x => x.WithSanction(sanctionCode, startDate: sanctionStartDate)); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/persons/{person.ContactId}/alerts"); + + // Act + var response = await HttpClient.SendAsync(request); + + // Assert + Assert.Equal(StatusCodes.Status200OK, (int)response.StatusCode); + + var doc = await response.GetDocument(); + var currentAlert = doc.GetElementByTestId($"current-alert-{person.Sanctions[0].SanctionId}"); + Assert.NotNull(currentAlert); + Assert.Equal(sanctionStartDate.ToString("dd/MM/yyyy"), currentAlert.GetElementByTestId($"current-alert-start-date-{person.Sanctions[0].SanctionId}")!.TextContent); + var details = currentAlert.GetElementByTestId($"current-alert-details-{person.Sanctions[0].SanctionId}"); + Assert.NotNull(details); + + var previousAlerts = doc.GetElementByTestId("previous-alerts"); + Assert.Null(previousAlerts); + } + + [Fact] + public async Task Get_WithPersonIdForPersonWithCurrentAndPreviousAlerts_DisplaysExpectedContent() + { + // Arrange + var sanction1Code = "G1"; + var sanction1CodeName = (await TestData.ReferenceDataCache.GetSanctionCodeByValue(sanction1Code)).dfeta_name; + var sanction1StartDate = new DateOnly(2023, 05, 01); + + var sanction2Code = "A1"; + var sanction2CodeName = (await TestData.ReferenceDataCache.GetSanctionCodeByValue(sanction2Code)).dfeta_name; + var sanction2StartDate = new DateOnly(2019, 06, 24); + var sanction2EndDate = new DateOnly(2020, 07, 30); + + var person = await TestData.CreatePerson(x => x.WithSanction(sanction1Code, startDate: sanction1StartDate).WithSanction(sanction2Code, startDate: sanction2StartDate, endDate: sanction2EndDate)); + + var request = new HttpRequestMessage(HttpMethod.Get, $"/persons/{person.ContactId}/alerts"); + + // Act + var response = await HttpClient.SendAsync(request); + + // Assert + Assert.Equal(StatusCodes.Status200OK, (int)response.StatusCode); + + var doc = await response.GetDocument(); + var currentAlert = doc.GetElementByTestId($"current-alert-{person.Sanctions[0].SanctionId}"); + Assert.NotNull(currentAlert); + Assert.Equal(sanction1StartDate.ToString("dd/MM/yyyy"), currentAlert.GetElementByTestId($"current-alert-start-date-{person.Sanctions[0].SanctionId}")!.TextContent); + var details = currentAlert.GetElementByTestId($"current-alert-details-{person.Sanctions[0].SanctionId}"); + Assert.NotNull(details); + + var previousAlerts = doc.GetElementByTestId("previous-alerts"); + Assert.NotNull(previousAlerts); + + var previousAlert = previousAlerts.GetElementByTestId($"previous-alert-{person.Sanctions[1].SanctionId}"); + Assert.NotNull(previousAlert); + Assert.Equal(sanction2CodeName, previousAlert.GetElementByTestId($"previous-alert-description-{person.Sanctions[1].SanctionId}")!.TextContent); + Assert.Equal(sanction2StartDate.ToString("dd/MM/yyyy"), previousAlert.GetElementByTestId($"previous-alert-start-date-{person.Sanctions[1].SanctionId}")!.TextContent); + Assert.Equal(sanction2EndDate.ToString("dd/MM/yyyy"), previousAlert.GetElementByTestId($"previous-alert-end-date-{person.Sanctions[1].SanctionId}")!.TextContent); + Assert.Equal("Closed", previousAlert.GetElementByTestId($"previous-alert-status-{person.Sanctions[1].SanctionId}")!.TextContent); + } +} diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/CrmTestData.CreatePerson.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/CrmTestData.CreatePerson.cs index e74cc5139..61fd802dc 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/CrmTestData.CreatePerson.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/CrmTestData.CreatePerson.cs @@ -108,9 +108,10 @@ public CreatePersonBuilder WithSanction( DateOnly? startDate = null, DateOnly? endDate = null, DateOnly? reviewDate = null, - bool spent = false) + bool spent = false, + string details = "lorem ipsum") { - _sanctions.Add(new(sanctionCode, startDate, endDate, reviewDate, spent)); + _sanctions.Add(new(Guid.NewGuid(), sanctionCode, startDate, endDate, reviewDate, spent, details)); return this; } @@ -173,6 +174,7 @@ public async Task Execute(CrmTestData testData) { Target = new dfeta_sanction() { + Id = sanction.SanctionId, dfeta_PersonId = personId.ToEntityReference(Contact.EntityLogicalName), dfeta_SanctionCodeId = sanctionCode.Id.ToEntityReference(dfeta_sanctioncode.EntityLogicalName), dfeta_StartDate = sanction.StartDate?.FromDateOnlyWithDqtBstFix(isLocalTime: true), @@ -232,5 +234,5 @@ public record CreatePersonResult }; } - public record Sanction(string SanctionCode, DateOnly? StartDate, DateOnly? EndDate, DateOnly? ReviewDate, bool Spent); + public record Sanction(Guid SanctionId, string SanctionCode, DateOnly? StartDate, DateOnly? EndDate, DateOnly? ReviewDate, bool Spent, string Details); } diff --git a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/SeedCrmReferenceData.cs b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/SeedCrmReferenceData.cs index 57419444a..3e6bb0d31 100644 --- a/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/SeedCrmReferenceData.cs +++ b/TeachingRecordSystem/tests/TeachingRecordSystem.TestCommon/SeedCrmReferenceData.cs @@ -38,22 +38,26 @@ private void AddSanctionCodes() { _xrmFakedContext.CreateEntity(new dfeta_sanctioncode() { - dfeta_Value = "G1" + dfeta_Value = "G1", + dfeta_name = "G1 Description" }); _xrmFakedContext.CreateEntity(new dfeta_sanctioncode() { - dfeta_Value = "A1" + dfeta_Value = "A1", + dfeta_name = "A1 Description" }); _xrmFakedContext.CreateEntity(new dfeta_sanctioncode() { - dfeta_Value = "A17" + dfeta_Value = "A17", + dfeta_name = "A17 Description" }); _xrmFakedContext.CreateEntity(new dfeta_sanctioncode() { - dfeta_Value = "A18" + dfeta_Value = "A18", + dfeta_name = "A18 Description" }); } } diff --git a/crm_attributes.json b/crm_attributes.json index f7674bfa5..4af9f69a2 100644 --- a/crm_attributes.json +++ b/crm_attributes.json @@ -52,7 +52,7 @@ "statecode", "telephone1", "dfeta_slugid", - "dfeta_allowpiiupdatesfromregister" + "dfeta_allowpiiupdatesfromregister", "dfeta_previouslastname" ], "dfeta_businesseventaudit":[ @@ -198,8 +198,9 @@ "statecode" ], "dfeta_sanctioncode" : [ - "dfeta_value", + "dfeta_name", "dfeta_sanctioncodeid", + "dfeta_value", "statecode" ], "dfeta_sanction": [ @@ -208,6 +209,7 @@ "dfeta_personid", "dfeta_sanctionid", "dfeta_sanctioncodeid", + "dfeta_sanctiondetails", "dfeta_spent", "dfeta_startdate", "statecode" diff --git a/tools/coretools/CrmSvcUtil.exe.config b/tools/coretools/CrmSvcUtil.exe.config index 86fbf0130..52599fac4 100644 --- a/tools/coretools/CrmSvcUtil.exe.config +++ b/tools/coretools/CrmSvcUtil.exe.config @@ -20,7 +20,7 @@ - +