-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDbBackedReportingPlanSource.cs
More file actions
73 lines (60 loc) · 3.24 KB
/
Copy pathDbBackedReportingPlanSource.cs
File metadata and controls
73 lines (60 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using LantanaGroup.Link.DMRP.Data.Entities;
using LantanaGroup.Link.Shared.Application.Services.Security;
using LantanaGroup.Link.Shared.Domain.Repositories.Interfaces;
namespace LantanaGroup.Link.DMRP.Business
{
/// <summary>
/// Reads a facility's reporting plan out of the module's own tables, resolving each row through
/// its measure mapping.
/// </summary>
/// <remarks>
/// This is the source of reporting plans until the DMRP API client exists. It reports what Link
/// last recorded rather than what the API says right now, so a plan is only as current as the last
/// write to the reporting plans table.
/// </remarks>
public sealed class DbBackedReportingPlanSource : IReportingPlanSource
{
private readonly ILogger<DbBackedReportingPlanSource> _logger;
private readonly IEntityRepository<FacilityReportingPlan> _plans;
private readonly IEntityRepository<MeasureMapping> _measureMappings;
public DbBackedReportingPlanSource(ILogger<DbBackedReportingPlanSource> logger,
IEntityRepository<FacilityReportingPlan> plans,
IEntityRepository<MeasureMapping> measureMappings)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_plans = plans ?? throw new ArgumentNullException(nameof(plans));
_measureMappings = measureMappings ?? throw new ArgumentNullException(nameof(measureMappings));
}
public async Task<IReadOnlyList<ReportingPlanEntry>> GetForPeriodAsync(string facilityId, int month, int year,
CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrWhiteSpace(facilityId);
var plans = await _plans.FindAsync(p => p.FacilityId == facilityId
&& p.ReportingMonth == month
&& p.ReportingYear == year
&& p.IsReporting, cancellationToken);
if (plans.Count == 0)
{
return Array.Empty<ReportingPlanEntry>();
}
var mappingIds = plans.Select(p => p.MeasureMappingId).Distinct().ToList();
var mappings = await _measureMappings.FindAsync(m => mappingIds.Contains(m.Id), cancellationToken);
var mappingsById = mappings.ToDictionary(m => m.Id);
var entries = new List<ReportingPlanEntry>(plans.Count);
foreach (var plan in plans)
{
if (!mappingsById.TryGetValue(plan.MeasureMappingId, out var mapping))
{
// The reporting plan's foreign key guarantees the mapping row exists, so this is a
// read that raced a delete rather than an ordinary miss.
_logger.LogWarning(
"Reporting plan {PlanId} for facility {FacilityId} references measure mapping {MeasureMappingId}, which was not found. The measure is excluded from the facility's schedule.",
plan.Id.SanitizeForLog(), facilityId.SanitizeForLog(), plan.MeasureMappingId.SanitizeForLog());
continue;
}
entries.Add(new ReportingPlanEntry(mapping.Measure, mapping.DQM, mapping.Frequency));
}
return entries;
}
}
}