Skip to content

Commit

Permalink
Merge pull request #449 from DFE-Digital/fix/190310
Browse files Browse the repository at this point in the history
fix/190310 - Category/Section Order & Section/Question Order
  • Loading branch information
Zac-Digital authored Jan 16, 2024
2 parents 498dbc7 + bae59f1 commit 9b8a53a
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,14 @@ private static void CopySectionsToPage(PageDbEntity page, List<SectionDbEntity>
/// <returns></returns>
private IQueryable<SectionDbEntity> SectionsForPageQueryable(PageDbEntity page)
=> _db.Sections.Where(section => section.Category != null && section.Category.ContentPages.Any(categoryPage => categoryPage.Slug == page.Slug))
.Where(section => section.Order != null)
.OrderBy(section => section.Order)
.Select(section => new SectionDbEntity()
{
CategoryId = section.CategoryId,
Id = section.Id,
Name = section.Name,
Questions = section.Questions.Select(question => new QuestionDbEntity()
Questions = section.Questions.Where(question => question.Order != null).OrderBy(question => question.Order).Select(question => new QuestionDbEntity()
{
Slug = question.Slug,
Id = question.Id,
Expand Down
31 changes: 27 additions & 4 deletions src/Dfe.PlanTech.AzureFunctions/Functions/QueueReceiver.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using Azure.Messaging.ServiceBus;
using Dfe.PlanTech.AzureFunctions.Mappings;
using Dfe.PlanTech.Domain;
using Dfe.PlanTech.Domain.Caching.Exceptions;
using Dfe.PlanTech.Domain.Content.Models;
using Dfe.PlanTech.Infrastructure.Data;
using Microsoft.Azure.Functions.Worker;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.Extensions.Logging;
using System.Reflection;
using System.Text;

namespace Dfe.PlanTech.AzureFunctions
Expand All @@ -15,6 +17,7 @@ public class QueueReceiver : BaseFunction
{
private readonly CmsDbContext _db;
private readonly JsonToEntityMappers _mappers;
private readonly Type _dontCopyValueAttribute = typeof(DontCopyValueAttribute);

public QueueReceiver(ILoggerFactory loggerFactory, CmsDbContext db, JsonToEntityMappers mappers) : base(loggerFactory.CreateLogger<QueueReceiver>())
{
Expand Down Expand Up @@ -136,14 +139,34 @@ private async Task<long> UpsertEntityInDatabase(ContentComponentDbEntity entity,
return await _db.SaveChangesAsync();
}

private static void UpdateProperties(ContentComponentDbEntity entity, ContentComponentDbEntity existing)
private void UpdateProperties(ContentComponentDbEntity entity, ContentComponentDbEntity existing)
{
var properties = entity.GetType().GetProperties();

foreach (var property in properties.Where(property => property.Name != "Id"))
foreach (var property in PropertiesToCopy(entity))
{
property.SetValue(existing, property.GetValue(entity));
}
}

/// <summary>
/// Get properties to copy for the selected entity
/// </summary>
/// <remarks>
/// Returns all properties, except properties ending with "Id" (i.e. relationship fields), and properties that have
/// a <see cref="DontCopyValueAttribute"/> attribute.
/// </remarks>
/// <param name="entity">Entity to get copyable properties for</param>
/// <returns></returns>
private IEnumerable<PropertyInfo> PropertiesToCopy(ContentComponentDbEntity entity)
=> entity.GetType()
.GetProperties()
.Where(property => !property.Name.EndsWith("Id") && !HasDontCopyValueAttribute(property));

/// <summary>
/// Does the property have a <see cref="DontCopyValueAttribute"/> property attached to it?
/// </summary>
/// <param name="property"></param>
/// <returns></returns>
private bool HasDontCopyValueAttribute(PropertyInfo property)
=> property.CustomAttributes.Any(attribute => attribute.AttributeType == _dontCopyValueAttribute);
}
}
7 changes: 6 additions & 1 deletion src/Dfe.PlanTech.AzureFunctions/Mappings/CategoryMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ public CategoryMapper(CmsDbContext db, ILogger<CategoryMapper> logger, JsonSeria

public override Dictionary<string, object?> PerformAdditionalMapping(Dictionary<string, object?> values)
{
int order = 0;
values = MoveValueToNewKey(values, "header", "headerId");

UpdateReferencesArray(values, "sections", _db.Sections, (id, section) => section.CategoryId = Payload!.Sys.Id);
UpdateReferencesArray(values, "sections", _db.Sections, (id, section) =>
{
section.CategoryId = Payload!.Sys.Id;
section.Order = order++;
});

return values;
}
Expand Down
7 changes: 6 additions & 1 deletion src/Dfe.PlanTech.AzureFunctions/Mappings/SectionMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ public SectionMapper(CmsDbContext db, ILogger<SectionMapper> logger, JsonSeriali

public override Dictionary<string, object?> PerformAdditionalMapping(Dictionary<string, object?> values)
{
int order = 0;
values = MoveValueToNewKey(values, "interstitialPage", "interstitialPageId");

UpdateReferencesArray(values, "questions", _db.Questions, (id, question) => question.SectionId = Payload!.Sys.Id);
UpdateReferencesArray(values, "questions", _db.Questions, (id, question) =>
{
question.SectionId = Payload!.Sys.Id;
question.Order = order++;
});

UpdateReferencesArray(values, "recommendations", _db.RecommendationPages, (id, recommendationPage) => recommendationPage.SectionId = Payload!.Sys.Id);

Expand Down
7 changes: 6 additions & 1 deletion src/Dfe.PlanTech.AzureFunctions/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,22 @@
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Dfe.PlanTech.AzureFunctions
{
[ExcludeFromCodeCoverage]
public static class Startup
{
public static void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
services.AddDbContext<CmsDbContext>(options => options.UseSqlServer(configuration["AZURE_SQL_CONNECTIONSTRING"]));
services.AddDbContext<CmsDbContext>(options =>
{
options.UseSqlServer(configuration["AZURE_SQL_CONNECTIONSTRING"]);
});

services.AddAzureClients(builder =>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
BEGIN TRANSACTION;
GO

-- Track the order that a piece of content should appear when being consumed.
ALTER TABLE [Contentful].[ContentComponents]
ADD [Order] bigint NULL;

COMMIT;
GO
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ public abstract class ContentComponentDbEntity : IContentComponentDbEntity

public bool Deleted { get; set; }

[DontCopyValue]
public long? Order { get; set; }

public List<PageDbEntity> BeforeTitleContentPages { get; set; } = new();

public List<PageDbEntity> ContentPages { get; set; } = new();
Expand Down
7 changes: 7 additions & 0 deletions src/Dfe.PlanTech.Domain/DontCopyValueAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Dfe.PlanTech.Domain;

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
public class DontCopyValueAttribute : Attribute
{

}
Loading

0 comments on commit 9b8a53a

Please sign in to comment.