diff --git a/EstateReportingAPI.DataTrasferObjects/CalendarYear.cs b/EstateReportingAPI.DataTrasferObjects/CalendarYear.cs new file mode 100644 index 0000000..2a28958 --- /dev/null +++ b/EstateReportingAPI.DataTrasferObjects/CalendarYear.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace EstateReportingAPI.DataTrasferObjects +{ + public class CalendarYear + { + public Int32 Year{ get; set; } + } + + public class CalendarDate + { + public DateTime Date { get; set; } + public String DayOfWeek{ get; set; } + public Int32 DayOfWeekNumber{ get; set; } + public String DayOfWeekShort{ get; set; } + public String MonthName{ get; set; } + public String MonthNameShort { get; set; } + public Int32 MonthNumber { get; set; } + public Int32 WeekNumber { get; set; } + public String WeekNumberString { get; set; } + public Int32 Year { get; set; } + public String YearWeekNumber { get; set; } + } +} diff --git a/EstateReportingAPI.DataTrasferObjects/EstateReportingAPI.DataTrasferObjects.csproj b/EstateReportingAPI.DataTrasferObjects/EstateReportingAPI.DataTrasferObjects.csproj new file mode 100644 index 0000000..b4b43f4 --- /dev/null +++ b/EstateReportingAPI.DataTrasferObjects/EstateReportingAPI.DataTrasferObjects.csproj @@ -0,0 +1,8 @@ + + + + netstandard2.1 + enable + + + diff --git a/EstateReportingAPI.sln b/EstateReportingAPI.sln index 4edd8a0..5f726bd 100644 --- a/EstateReportingAPI.sln +++ b/EstateReportingAPI.sln @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EstateReportingAPI", "Estat EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EstateReportingAPI.Tests", "EstateReportingAPI.Tests\EstateReportingAPI.Tests.csproj", "{1124CAC0-A2B3-44FF-8B16-C8722D7042A2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EstateReportingAPI.DataTrasferObjects", "EstateReportingAPI.DataTrasferObjects\EstateReportingAPI.DataTrasferObjects.csproj", "{4BEC708B-2A02-486F-8BEF-AD9D6220DD74}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -31,6 +33,10 @@ Global {1124CAC0-A2B3-44FF-8B16-C8722D7042A2}.Debug|Any CPU.Build.0 = Debug|Any CPU {1124CAC0-A2B3-44FF-8B16-C8722D7042A2}.Release|Any CPU.ActiveCfg = Release|Any CPU {1124CAC0-A2B3-44FF-8B16-C8722D7042A2}.Release|Any CPU.Build.0 = Release|Any CPU + {4BEC708B-2A02-486F-8BEF-AD9D6220DD74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4BEC708B-2A02-486F-8BEF-AD9D6220DD74}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4BEC708B-2A02-486F-8BEF-AD9D6220DD74}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4BEC708B-2A02-486F-8BEF-AD9D6220DD74}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -39,6 +45,7 @@ Global {8E6ED1E8-9776-49F3-ADEB-17A03318E136} = {713556C8-BFC0-4AB6-8F13-7631C1C82D07} {DC3AEC92-739F-45E6-8513-CFAEA826984A} = {C48C544B-7C3B-4AA2-8A37-E49296A86499} {1124CAC0-A2B3-44FF-8B16-C8722D7042A2} = {C48C544B-7C3B-4AA2-8A37-E49296A86499} + {4BEC708B-2A02-486F-8BEF-AD9D6220DD74} = {713556C8-BFC0-4AB6-8F13-7631C1C82D07} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B2BE269B-F142-45A3-9B75-483227C765A6} diff --git a/EstateReportingAPI/Bootstrapper/MiddlewareRegistry.cs b/EstateReportingAPI/Bootstrapper/MiddlewareRegistry.cs index 425fcff..eed960f 100644 --- a/EstateReportingAPI/Bootstrapper/MiddlewareRegistry.cs +++ b/EstateReportingAPI/Bootstrapper/MiddlewareRegistry.cs @@ -1,7 +1,9 @@ namespace EstateReportingAPI.Bootstrapper{ using System.Diagnostics.CodeAnalysis; + using System.Net.Security; using System.Reflection; using Common; + using EstateManagement.Database.Contexts; using Lamar; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Extensions.Diagnostics.HealthChecks; @@ -9,9 +11,49 @@ using Microsoft.OpenApi.Models; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; + using Shared.EntityFramework; + using Shared.EntityFramework.ConnectionStringConfiguration; using Shared.General; + using Shared.Repositories; using Swashbuckle.AspNetCore.Filters; + public class RepositoryRegistry : ServiceRegistry{ + public RepositoryRegistry(){ + + Boolean useConnectionStringConfig = bool.Parse(ConfigurationReader.GetValue("AppSettings", "UseConnectionStringConfig")); + + if (useConnectionStringConfig) + { + String connectionStringConfigurationConnString = ConfigurationReader.GetConnectionString("ConnectionStringConfiguration"); + this.AddSingleton(); + this.AddTransient(c => { return new ConnectionStringConfigurationContext(connectionStringConfigurationConnString); }); + + // TODO: Read this from a the database and set + } + else + { + this.AddSingleton(); + } + + this.AddSingleton, DbContextFactory>(); + + this.AddSingleton>(cont => connectionString => + { + String databaseEngine = + ConfigurationReader.GetValue("AppSettings", "DatabaseEngine"); + + return databaseEngine switch + { + "MySql" => new EstateManagementMySqlContext(connectionString), + "SqlServer" => new EstateManagementSqlServerContext(connectionString), + _ => throw new + NotSupportedException($"Unsupported Database Engine {databaseEngine}") + }; + }); + } + } + + [ExcludeFromCodeCoverage] public class MiddlewareRegistry : ServiceRegistry{ public MiddlewareRegistry(){ diff --git a/EstateReportingAPI/Common/ConfigurationReaderConnectionStringRepository.cs b/EstateReportingAPI/Common/ConfigurationReaderConnectionStringRepository.cs new file mode 100644 index 0000000..cbbf27f --- /dev/null +++ b/EstateReportingAPI/Common/ConfigurationReaderConnectionStringRepository.cs @@ -0,0 +1,65 @@ +using Microsoft.Data.SqlClient; +using MySqlConnector; +using Shared.General; +using Shared.Repositories; +using System.Data.Common; +using System.Diagnostics.CodeAnalysis; + +namespace EstateReportingAPI.Common +{ + [ExcludeFromCodeCoverage] + public class ConfigurationReaderConnectionStringRepository : IConnectionStringConfigurationRepository + { + #region Methods + + public async Task CreateConnectionString(String externalIdentifier, + String connectionStringIdentifier, + String connectionString, + CancellationToken cancellationToken) + { + throw new NotImplementedException("This is only required to complete the interface"); + } + + public async Task DeleteConnectionStringConfiguration(String externalIdentifier, + String connectionStringIdentifier, + CancellationToken cancellationToken) + { + throw new NotImplementedException("This is only required to complete the interface"); + } + + public async Task GetConnectionString(String externalIdentifier, + String connectionStringIdentifier, + CancellationToken cancellationToken) + { + String connectionString = string.Empty; + String databaseName = string.Empty; + + String databaseEngine = ConfigurationReader.GetValue("AppSettings", "DatabaseEngine"); + + databaseName = $"{connectionStringIdentifier}{externalIdentifier}"; + connectionString = ConfigurationReader.GetConnectionString(connectionStringIdentifier); + + DbConnectionStringBuilder builder = null; + + if (databaseEngine == "MySql") + { + builder = new MySqlConnectionStringBuilder(connectionString) + { + Database = databaseName + }; + } + else + { + // Default to SQL Server + builder = new SqlConnectionStringBuilder(connectionString) + { + InitialCatalog = databaseName + }; + } + + return builder.ToString(); + } + + #endregion + } +} diff --git a/EstateReportingAPI/Controllers/Dimensions.cs b/EstateReportingAPI/Controllers/Dimensions.cs new file mode 100644 index 0000000..a99ae7e --- /dev/null +++ b/EstateReportingAPI/Controllers/Dimensions.cs @@ -0,0 +1,84 @@ +namespace EstateReportingAPI.Controllers +{ + using DataTrasferObjects; + using EstateManagement.Database.Contexts; + using EstateManagement.Database.Entities; + using Microsoft.AspNetCore.Authorization; + using Microsoft.AspNetCore.Mvc; + using Shared.EntityFramework; + using System.Diagnostics.CodeAnalysis; + + [ExcludeFromCodeCoverage] + [Route(DimensionsController.ControllerRoute)] + [ApiController] + //[Authorize] + public class DimensionsController : ControllerBase + { + private readonly IDbContextFactory ContextFactory; + + public DimensionsController(IDbContextFactory contextFactory){ + this.ContextFactory = contextFactory; + } + + private const String ConnectionStringIdentifier = "EstateReportingReadModel"; + + #region Others + + /// + /// The controller name + /// + public const String ControllerName = "dimensions"; + + /// + /// The controller route + /// + private const String ControllerRoute = "api/" + DimensionsController.ControllerName; + + #endregion + + [HttpGet] + [Route("getcalendaryears")] + public async Task GetCalendarYears([FromHeader] Guid estateId, CancellationToken cancellationToken){ + + EstateManagementGenericContext? context = await this.ContextFactory.GetContext(estateId, DimensionsController.ConnectionStringIdentifier, cancellationToken); + + List years = context.Calendar.Where(c => c.Date <= DateTime.Now.Date).GroupBy(c => c.Year).Select(y => y.Key).ToList(); + + List response = new List(); + + years.ForEach(y => response.Add(new CalendarYear{ + Year = y + })); + + return this.Ok(response); + } + + //[HttpGet] + //public async Task GetCalendarDates([FromHeader] Guid estateId, [FromQuery] Int32 year, CancellationToken cancellationToken) + //{ + // EstateManagementGenericContext? context = await this.ContextFactory.GetContext(estateId, DimensionsController.ConnectionStringIdentifier, cancellationToken); + + // List dates= context.Calendar.Where(c => c.Date <= DateTime.Now.Date).ToList(); + + // List response = new List(); + + // dates.ForEach(d => response.Add(new CalendarDate{ + // Year = d.Year, + // Date = d.Date, + // DayOfWeek = d.DayOfWeek, + // DayOfWeekNumber = d.DayOfWeekNumber, + // DayOfWeekShort = d.DayOfWeekShort, + // MonthName = d.MonthNameLong, + // MonthNameShort = d.MonthNameShort, + // MonthNumber = d.MonthNumber, + // WeekNumber = d.WeekNumber ?? 0, + // WeekNumberString = d.WeekNumberString, + // YearWeekNumber = d.YearWeekNumber, + // })); + + // return this.Ok(); + //} + } + + +} diff --git a/EstateReportingAPI/EstateReportingAPI.csproj b/EstateReportingAPI/EstateReportingAPI.csproj index 674f62c..8a6f6bf 100644 --- a/EstateReportingAPI/EstateReportingAPI.csproj +++ b/EstateReportingAPI/EstateReportingAPI.csproj @@ -9,6 +9,7 @@ + @@ -36,7 +37,7 @@ - + diff --git a/EstateReportingAPI/Startup.cs b/EstateReportingAPI/Startup.cs index 9c6c865..9f80c1e 100644 --- a/EstateReportingAPI/Startup.cs +++ b/EstateReportingAPI/Startup.cs @@ -36,6 +36,7 @@ public void ConfigureContainer(ServiceRegistry services) ConfigurationReader.Initialise(Configuration); services.IncludeRegistry(); + services.IncludeRegistry(); Container = new Container(services); } diff --git a/EstateReportingAPI/appsettings.json b/EstateReportingAPI/appsettings.json index 10f68b8..4204bfd 100644 --- a/EstateReportingAPI/appsettings.json +++ b/EstateReportingAPI/appsettings.json @@ -5,5 +5,10 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "AppSettings": { + "DatabaseEngine": "SqlServer" + //"DatabaseEngine": "MySql", + } + }