| Name | Message | Date |
|---|---|---|
| 📄 AdminAuthService.cs | 11 days ago | |
| 📄 DateService.cs | 11 days ago |
📄
MatDenDagen/Services/DateService.cs
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using System; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; using MatDenDagen.Infrastructure.Storage.Database; using MatDenDagen.Models; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; namespace MatDenDagen.Services; public sealed class DateService(ILogger<DateService> logger, Random random, QuestionnaireContext questionnaireContext) { private const string DateSpanConfigKey = "DateSpan"; private const string DateConfigKey = "DateConfig"; public async Task<DateSpan?> GetDateSpanAsync() { var config = await questionnaireContext.Configs.FirstOrDefaultAsync(c => c.Key == DateSpanConfigKey); if (config?.Value == null) { return null; } try { return JsonSerializer.Deserialize<DateSpan>(config.Value); } catch (Exception ex) { logger.LogError(ex, "Failed to deserialize DateSpan from database"); return null; } } public async Task SaveDateSpanAsync(DateSpan dateSpan) { if (!dateSpan.IsValid) { throw new ArgumentException("Invalid date span: start date must be before or equal to end date"); } var config = await questionnaireContext.Configs.FirstOrDefaultAsync(c => c.Key == DateSpanConfigKey); var jsonValue = JsonSerializer.Serialize(dateSpan, ConfigJsonSerializerContext.Default.DateSpan); if (config == null) { questionnaireContext.Configs.Add(new Config { Key = DateSpanConfigKey, Value = jsonValue }); } else { config.Value = jsonValue; questionnaireContext.Configs.Update(config); } await questionnaireContext.SaveChangesAsync(); } public async Task<DateConfig?> GetDateConfigAsync() { var config = await questionnaireContext.Configs.FirstOrDefaultAsync(c => c.Key == DateConfigKey); if (config?.Value == null) { return null; } try { return JsonSerializer.Deserialize<DateConfig>(config.Value); } catch (Exception ex) { logger.LogError(ex, "Failed to deserialize DateConfig from database"); return null; } } public async Task<DateOnly?> RandomizeDateAsync() { var dateSpan = await GetDateSpanAsync(); if (dateSpan == null || !dateSpan.IsValid) { logger.LogWarning("Cannot randomize date: no valid date span configured"); return null; } var randomDate = dateSpan.GetRandomDate(random); var dateConfig = new DateConfig { TheDay = randomDate }; var jsonValue = JsonSerializer.Serialize(dateConfig, ConfigJsonSerializerContext.Default.DateConfig); var config = await questionnaireContext.Configs.FirstOrDefaultAsync(c => c.Key == DateConfigKey); if (config == null) { questionnaireContext.Configs.Add(new Config { Key = DateConfigKey, Value = jsonValue }); } else { config.Value = jsonValue; questionnaireContext.Configs.Update(config); } await questionnaireContext.SaveChangesAsync(); logger.LogInformation("Randomized date to {RandomDate}", randomDate); return randomDate; } } [JsonSerializable(typeof(DateSpan))] [JsonSerializable(typeof(DateConfig))] public sealed partial class ConfigJsonSerializerContext : JsonSerializerContext; public static class DateServiceCollectionExtensions { public static IServiceCollection AddDateService(this IServiceCollection services) { services.TryAddSingleton(Random.Shared); services.AddTransient<DateService>(); return services; } }