diff --git a/WebAPI/Controllers/LayersController.cs b/WebAPI/Controllers/LayersController.cs index f651c8a..7fb6b04 100644 --- a/WebAPI/Controllers/LayersController.cs +++ b/WebAPI/Controllers/LayersController.cs @@ -196,9 +196,9 @@ namespace WebAPI.Controllers layersToProcess = new List(); - foreach (Layer layer in processWorkerLayers) + foreach (Layer processWorker in processWorkerLayers) { - string? sourceName = layer?.Records?.Single(x => x.Code == "Source")?.Desc1; + string? sourceName = processWorker?.Records?.Single(x => x.Code == "Source")?.Desc1; if (sourceName == null) { logsController.AddEntry(new LogEntry @@ -206,7 +206,7 @@ namespace WebAPI.Controllers Title = "Process error", Type = LogEntryType.error, LogType = LogType.import, - Message = layer?.Name + " Source record not found", + Message = processWorker?.Name + " Source record not found", CreatedAt = DateTime.UtcNow }); return BadRequest(); @@ -221,7 +221,7 @@ namespace WebAPI.Controllers Title = "Process error", Type = LogEntryType.error, LogType = LogType.import, - Message = layer?.Name + " Source layer not found " + sourceLayer, + Message = processWorker?.Name + " Source layer not found " + sourceLayer, CreatedAt = DateTime.UtcNow }); return BadRequest(); @@ -233,7 +233,7 @@ namespace WebAPI.Controllers var endDateParsed = DateTime.ParseExact(endDate, "yyyy.MM.dd", null); if (startDateParsed.Date <= DateTime.UtcNow.Date && endDateParsed.Date >= DateTime.UtcNow.Date) { - string? processType = layer?.Records?.Single(x => x.Code == "ProcessType")?.Desc1; + string? processType = processWorker?.Records?.Single(x => x.Code == "ProcessType")?.Desc1; if (processType == null) { logsController.AddEntry(new LogEntry @@ -241,28 +241,34 @@ namespace WebAPI.Controllers Title = "Process error", Type = LogEntryType.error, LogType = LogType.import, - Message = layer?.Name + " ProcessType record not found", + Message = processWorker?.Name + " ProcessType record not found", CreatedAt = DateTime.UtcNow }); return BadRequest(); } else { - Layer processedLayer; + Layer? processedLayer = null; switch (processType) { case "Copy": - CopyProcessor processor = new CopyProcessor(db); - processedLayer = processor.process(sourceLayer); + CopyProcessor cp = new CopyProcessor(db, googleSheetValues); + processedLayer = cp.process(sourceLayer, processWorker?.Id); break; - case "Deaggregate": + case "Deaggregation": + DeaggregationProcessor dp = new DeaggregationProcessor(db, googleSheetValues); + processedLayer = dp.process(sourceLayer, processWorker?.Id); break; } + if (processedLayer != null) + { + AddLayer(processedLayer, Guid.Parse("F392209E-123E-4651-A5A4-0B1D6CF9FF9D")); + } } } } } } - + return Ok(); } catch (Exception e) { @@ -270,13 +276,12 @@ namespace WebAPI.Controllers { Title = "Process error", Type = LogEntryType.error, - LogType = LogType.import, + LogType = LogType.process, Message = e.ToString(), CreatedAt = DateTime.UtcNow }); return BadRequest(e.ToString()); } - return Ok(); } @@ -391,18 +396,16 @@ namespace WebAPI.Controllers input.ModifiedById = currentUserId; input.CreatedAt = DateTime.UtcNow; input.ModifiedAt = DateTime.UtcNow; - db.Layers.Add(input); SaveRecords(input.Id, input.Records!, currentUserId); db.SaveChanges(); return input; } - private void SaveRecords(Guid id, ICollection records, Guid currentUserId) + private void SaveRecords(Guid id, ICollection records, Guid currentUserId) { try { - List ids = new List(); foreach (Record record in records) { record.CreatedById = currentUserId; @@ -410,7 +413,6 @@ namespace WebAPI.Controllers record.ModifiedById = currentUserId; record.ModifiedAt = DateTime.UtcNow; record.LayerId = id; - db.Records.Add(record); } } @@ -418,6 +420,21 @@ namespace WebAPI.Controllers { throw; } + } + private void SaveSources(ICollection sources) + { + try + { + foreach (ProcessSource processSource in sources) + { + Console.WriteLine($"{processSource.LayerId} {processSource.SourceId}"); + // db.ProcessSources.Add(processSource); + } + } + catch (Exception) + { + throw; + } } } } \ No newline at end of file diff --git a/WebAPI/Migrations/20230918093055_TypeO.Designer.cs b/WebAPI/Migrations/20230918093055_TypeO.Designer.cs new file mode 100644 index 0000000..38b0d51 --- /dev/null +++ b/WebAPI/Migrations/20230918093055_TypeO.Designer.cs @@ -0,0 +1,330 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using WebAPI; + +#nullable disable + +namespace WebAPI.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20230918093055_TypeO")] + partial class TypeO + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.11") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("WebAPI.Models.Layer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModifiedAt") + .HasColumnType("datetime2"); + + b.Property("ModifiedById") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Number") + .HasColumnType("int"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("Source") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("ModifiedById"); + + b.HasIndex("ParentId"); + + b.ToTable("Layers"); + }); + + modelBuilder.Entity("WebAPI.Models.ProcessSource", b => + { + b.Property("LayerId") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("LayerId", "SourceId"); + + b.HasIndex("SourceId"); + + b.ToTable("ProcessSources"); + }); + + modelBuilder.Entity("WebAPI.Models.Record", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedById") + .HasColumnType("uniqueidentifier"); + + b.Property("Desc1") + .HasColumnType("nvarchar(max)"); + + b.Property("Desc2") + .HasColumnType("nvarchar(max)"); + + b.Property("Desc3") + .HasColumnType("nvarchar(max)"); + + b.Property("Desc4") + .HasColumnType("nvarchar(max)"); + + b.Property("Desc5") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LayerId") + .HasColumnType("uniqueidentifier"); + + b.Property("ModifiedAt") + .HasColumnType("datetime2"); + + b.Property("ModifiedById") + .HasColumnType("uniqueidentifier"); + + b.Property("Value1") + .HasColumnType("real"); + + b.Property("Value10") + .HasColumnType("real"); + + b.Property("Value11") + .HasColumnType("real"); + + b.Property("Value12") + .HasColumnType("real"); + + b.Property("Value13") + .HasColumnType("real"); + + b.Property("Value14") + .HasColumnType("real"); + + b.Property("Value15") + .HasColumnType("real"); + + b.Property("Value16") + .HasColumnType("real"); + + b.Property("Value17") + .HasColumnType("real"); + + b.Property("Value18") + .HasColumnType("real"); + + b.Property("Value19") + .HasColumnType("real"); + + b.Property("Value2") + .HasColumnType("real"); + + b.Property("Value20") + .HasColumnType("real"); + + b.Property("Value21") + .HasColumnType("real"); + + b.Property("Value22") + .HasColumnType("real"); + + b.Property("Value23") + .HasColumnType("real"); + + b.Property("Value24") + .HasColumnType("real"); + + b.Property("Value25") + .HasColumnType("real"); + + b.Property("Value26") + .HasColumnType("real"); + + b.Property("Value27") + .HasColumnType("real"); + + b.Property("Value28") + .HasColumnType("real"); + + b.Property("Value29") + .HasColumnType("real"); + + b.Property("Value3") + .HasColumnType("real"); + + b.Property("Value30") + .HasColumnType("real"); + + b.Property("Value31") + .HasColumnType("real"); + + b.Property("Value4") + .HasColumnType("real"); + + b.Property("Value5") + .HasColumnType("real"); + + b.Property("Value6") + .HasColumnType("real"); + + b.Property("Value7") + .HasColumnType("real"); + + b.Property("Value8") + .HasColumnType("real"); + + b.Property("Value9") + .HasColumnType("real"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("LayerId"); + + b.HasIndex("ModifiedById"); + + b.ToTable("Records"); + }); + + modelBuilder.Entity("WebAPI.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasColumnType("nvarchar(max)"); + + b.Property("UserName") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("WebAPI.Models.Layer", b => + { + b.HasOne("WebAPI.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WebAPI.Models.User", "ModifiedBy") + .WithMany() + .HasForeignKey("ModifiedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WebAPI.Models.Layer", "Parent") + .WithMany() + .HasForeignKey("ParentId"); + + b.Navigation("CreatedBy"); + + b.Navigation("ModifiedBy"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("WebAPI.Models.ProcessSource", b => + { + b.HasOne("WebAPI.Models.Layer", "Source") + .WithMany("Sources") + .HasForeignKey("SourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Source"); + }); + + modelBuilder.Entity("WebAPI.Models.Record", b => + { + b.HasOne("WebAPI.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WebAPI.Models.Layer", null) + .WithMany("Records") + .HasForeignKey("LayerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WebAPI.Models.User", "ModifiedBy") + .WithMany() + .HasForeignKey("ModifiedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("ModifiedBy"); + }); + + modelBuilder.Entity("WebAPI.Models.Layer", b => + { + b.Navigation("Records"); + + b.Navigation("Sources"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/WebAPI/Migrations/20230918093055_TypeO.cs b/WebAPI/Migrations/20230918093055_TypeO.cs new file mode 100644 index 0000000..50fdc6a --- /dev/null +++ b/WebAPI/Migrations/20230918093055_TypeO.cs @@ -0,0 +1,60 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace WebAPI.Migrations +{ + /// + public partial class TypeO : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Layers_Layers_parentId", + table: "Layers"); + + migrationBuilder.RenameColumn( + name: "parentId", + table: "Layers", + newName: "ParentId"); + + migrationBuilder.RenameIndex( + name: "IX_Layers_parentId", + table: "Layers", + newName: "IX_Layers_ParentId"); + + migrationBuilder.AddForeignKey( + name: "FK_Layers_Layers_ParentId", + table: "Layers", + column: "ParentId", + principalTable: "Layers", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Layers_Layers_ParentId", + table: "Layers"); + + migrationBuilder.RenameColumn( + name: "ParentId", + table: "Layers", + newName: "parentId"); + + migrationBuilder.RenameIndex( + name: "IX_Layers_ParentId", + table: "Layers", + newName: "IX_Layers_parentId"); + + migrationBuilder.AddForeignKey( + name: "FK_Layers_Layers_parentId", + table: "Layers", + column: "parentId", + principalTable: "Layers", + principalColumn: "Id"); + } + } +} diff --git a/WebAPI/Migrations/AppDbContextModelSnapshot.cs b/WebAPI/Migrations/AppDbContextModelSnapshot.cs index 5c5f110..9b03931 100644 --- a/WebAPI/Migrations/AppDbContextModelSnapshot.cs +++ b/WebAPI/Migrations/AppDbContextModelSnapshot.cs @@ -17,7 +17,7 @@ namespace WebAPI.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "7.0.10") + .HasAnnotation("ProductVersion", "7.0.11") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); @@ -50,6 +50,9 @@ namespace WebAPI.Migrations b.Property("Number") .HasColumnType("int"); + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + b.Property("Source") .IsRequired() .HasColumnType("nvarchar(max)"); @@ -57,16 +60,13 @@ namespace WebAPI.Migrations b.Property("Type") .HasColumnType("int"); - b.Property("parentId") - .HasColumnType("uniqueidentifier"); - b.HasKey("Id"); b.HasIndex("CreatedById"); b.HasIndex("ModifiedById"); - b.HasIndex("parentId"); + b.HasIndex("ParentId"); b.ToTable("Layers"); }); @@ -268,15 +268,15 @@ namespace WebAPI.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("WebAPI.Models.Layer", "parent") + b.HasOne("WebAPI.Models.Layer", "Parent") .WithMany() - .HasForeignKey("parentId"); + .HasForeignKey("ParentId"); b.Navigation("CreatedBy"); b.Navigation("ModifiedBy"); - b.Navigation("parent"); + b.Navigation("Parent"); }); modelBuilder.Entity("WebAPI.Models.ProcessSource", b => diff --git a/WebAPI/Program.cs b/WebAPI/Program.cs index 2b62098..d1e4820 100644 --- a/WebAPI/Program.cs +++ b/WebAPI/Program.cs @@ -9,7 +9,10 @@ using WebAPI; var builder = WebApplication.CreateBuilder(args); var connectionString = builder.Configuration.GetConnectionString("SQLDatabase"); -builder.Services.AddDbContext(x => x.UseSqlServer(connectionString)); +builder.Services.AddDbContext(x => { + x.UseSqlServer(connectionString); + x.EnableSensitiveDataLogging(); + }); builder.Services.AddCors(options => { diff --git a/WebAPI/dataProcessors/copy.processor.cs b/WebAPI/dataProcessors/copy.processor.cs index db5a7da..e8fa63f 100644 --- a/WebAPI/dataProcessors/copy.processor.cs +++ b/WebAPI/dataProcessors/copy.processor.cs @@ -1,4 +1,7 @@ using Google.Apis.Sheets.v4; +using Google.Apis.Sheets.v4.Data; +using Microsoft.EntityFrameworkCore; +using Newtonsoft.Json.Linq; using System.Globalization; using WebAPI.Models; @@ -7,21 +10,98 @@ namespace WebAPI.dataProcessors public class CopyProcessor { private AppDbContext db; + private SpreadsheetsResource.ValuesResource googleSheetValues; public CopyProcessor( - AppDbContext _db) + AppDbContext _db, + SpreadsheetsResource.ValuesResource _googleSheetValues) { db = _db; + googleSheetValues = _googleSheetValues; } - public Layer process(Layer sourceLayer) - { - Layer dataSource = this.db.Layers - .Where(x => x.ParentId == sourceLayer.Id) - .OrderByDescending(x => x.CreatedAt) - .First(); - - return null; + public Layer process(Layer sourceImportWorker, Guid? parentId) + { + string? sheetId = sourceImportWorker.Records!.Where(x => x.Code == "SheetId").FirstOrDefault()?.Desc1; + if (sheetId == null) + { + throw new Exception($"SheetId not found, {sourceImportWorker.Name}"); + } + string? sheetTabName = sourceImportWorker.Records!.Where(x => x.Code == "SheetTabName").FirstOrDefault()?.Desc1; + if (sheetId == null) + { + throw new Exception($"SheetTabName not found, {sourceImportWorker.Name}"); + } + string? importYearCell = sourceImportWorker.Records!.Where(x => x.Code == "ImportYear").FirstOrDefault()?.Desc1; + if (importYearCell == null) + { + throw new Exception($"ImportYear not found, {sourceImportWorker.Name}"); + } + string? importMonthCell = sourceImportWorker.Records!.Where(x => x.Code == "ImportMonth").FirstOrDefault()?.Desc1; + if (importMonthCell == null) + { + throw new Exception($"ImportMonth not found, {sourceImportWorker.Name}"); + } + string? importNameCell = sourceImportWorker.Records!.Where(x => x.Code == "ImportName").FirstOrDefault()?.Desc1; + if (importNameCell == null) + { + throw new Exception($"ImportName not found, {sourceImportWorker.Name}"); + } + var nameResponse = googleSheetValues.Get(sheetId, $"{sheetTabName}!{importNameCell}:{importNameCell}").Execute(); + string? name = nameResponse.Values[0][0].ToString(); + if (name == null) + { + throw new Exception($"ImportName cell is empty, {sourceImportWorker.Name}"); + } + var yearResponse = googleSheetValues.Get(sheetId, $"{sheetTabName}!{importYearCell}:{importYearCell}").Execute(); + string? year = yearResponse.Values[0][0].ToString(); + if (year == null) + { + throw new Exception($"ImportYear cell is empty, {sourceImportWorker.Name}"); + } + var monthResponse = googleSheetValues.Get(sheetId, $"{sheetTabName}!{importMonthCell}:{importMonthCell}").Execute(); + string? month = monthResponse.Values[0][0].ToString(); + if (month == null) + { + throw new Exception($"ImportMonth cell is empty, {sourceImportWorker.Name}"); + } + + Layer response = new Layer + { + Id = Guid.NewGuid(), + Source = "", + Type = LayerType.processed, + ParentId = parentId, + Number = db.Layers.Count() + 1, + Records = new List(), + Sources = new List() + }; + + Layer dataSource = db.Layers + .Include(x => x.Records) + .Where(x => x.ParentId == sourceImportWorker.Id && !x.IsDeleted) + .OrderByDescending(x => x.CreatedAt) + .First(); + response.Sources.Add(new ProcessSource + { + LayerId = response.Id, + SourceId = dataSource.Id + }); + response.Name = $"L{response.Number}-P-{name}-{year}/{month}-{DateTime.Now.ToString("yyyyMMddHHmm")}"; + + foreach (Record source in dataSource.Records!) + { + Record record = new Record + { + Id = Guid.NewGuid(), + Code = source.Code, + Value1 = source.Value1, + CreatedAt = DateTime.UtcNow, + ModifiedAt = DateTime.UtcNow + }; + response.Records.Add(record); + } + return response; } } } diff --git a/WebAPI/dataProcessors/deaggregation.processor.cs b/WebAPI/dataProcessors/deaggregation.processor.cs index c217f5f..f8b0412 100644 --- a/WebAPI/dataProcessors/deaggregation.processor.cs +++ b/WebAPI/dataProcessors/deaggregation.processor.cs @@ -1,22 +1,262 @@ using Google.Apis.Sheets.v4; +using Microsoft.EntityFrameworkCore; +using System; using System.Globalization; using WebAPI.Models; namespace WebAPI.dataProcessors { - public class deaggregationProcessor + public class DeaggregationProcessor { - private AppDbContext db; + private AppDbContext db; + private SpreadsheetsResource.ValuesResource googleSheetValues; - public deaggregationProcessor( - AppDbContext _db) + public DeaggregationProcessor( + AppDbContext _db, + SpreadsheetsResource.ValuesResource _googleSheetValues) { db = _db; + googleSheetValues = _googleSheetValues; } - public Layer process() + public Layer process(Layer sourceImportWorker, Guid? parentId) + { + string? sheetId = sourceImportWorker.Records!.Where(x => x.Code == "SheetId").FirstOrDefault()?.Desc1; + if (sheetId == null) + { + throw new Exception($"SheetId not found, {sourceImportWorker.Name}"); + } + string? sheetTabName = sourceImportWorker.Records!.Where(x => x.Code == "SheetTabName").FirstOrDefault()?.Desc1; + if (sheetId == null) + { + throw new Exception($"SheetTabName not found, {sourceImportWorker.Name}"); + } + string? importYearCell = sourceImportWorker.Records!.Where(x => x.Code == "ImportYear").FirstOrDefault()?.Desc1; + if (importYearCell == null) + { + throw new Exception($"ImportYear not found, {sourceImportWorker.Name}"); + } + string? importMonthCell = sourceImportWorker.Records!.Where(x => x.Code == "ImportMonth").FirstOrDefault()?.Desc1; + if (importMonthCell == null) + { + throw new Exception($"ImportMonth not found, {sourceImportWorker.Name}"); + } + string? importNameCell = sourceImportWorker.Records!.Where(x => x.Code == "ImportName").FirstOrDefault()?.Desc1; + if (importNameCell == null) + { + throw new Exception($"ImportName not found, {sourceImportWorker.Name}"); + } + var nameResponse = googleSheetValues.Get(sheetId, $"{sheetTabName}!{importNameCell}:{importNameCell}").Execute(); + string? name = nameResponse.Values[0][0].ToString(); + if (name == null) + { + throw new Exception($"ImportName cell is empty, {sourceImportWorker.Name}"); + } + var yearResponse = googleSheetValues.Get(sheetId, $"{sheetTabName}!{importYearCell}:{importYearCell}").Execute(); + int? year = int.Parse(yearResponse.Values[0][0].ToString() ?? ""); + if (year == null) + { + throw new Exception($"ImportYear cell is empty, {sourceImportWorker.Name}"); + } + var monthResponse = googleSheetValues.Get(sheetId, $"{sheetTabName}!{importMonthCell}:{importMonthCell}").Execute(); + string? month = monthResponse.Values[0][0].ToString(); + if (month == null) + { + throw new Exception($"ImportMonth cell is empty, {sourceImportWorker.Name}"); + } + + Layer response = new Layer + { + Id = Guid.NewGuid(), + Source = "", + Type = LayerType.processed, + ParentId = parentId, + Number = db.Layers.Count() + 1, + Records = new List(), + // Sources = new List() + }; + response.Name = $"L{response.Number}-P-{name}-{year}/{month}-{DateTime.Now.ToString("yyyyMMddHHmm")}"; + + List dataSources = db.Layers + .Include(x => x.Records) + .Where(x => x.ParentId == sourceImportWorker.Id + && x.CreatedAt.Month == int.Parse(month) + && x.CreatedAt.Year == year + && !x.IsDeleted) + .OrderBy(x => x.CreatedAt) + .ToList(); + + /* + foreach (Layer source in dataSources) + { + response.Sources.Add(new ProcessSource + { + LayerId = response.Id, + SourceId = source.Id + }); + } + */ + + List allRecords = dataSources.SelectMany(x => x.Records!).ToList(); + + + + foreach (Record baseRecord in dataSources.First()?.Records!) + { + List codeRecords = allRecords.Where(x => x.Code == baseRecord.Code).ToList(); + + Record processedRecord = new Record + { + Id = Guid.NewGuid(), + Code = baseRecord.Code, + CreatedAt = DateTime.UtcNow, + ModifiedAt = DateTime.UtcNow + }; + + int lastDayInMonth = DateTime.DaysInMonth(year ?? 0, int.Parse(month ?? "")); + float previousValue = 0; + //day 1 + float firstVal = codeRecords + .Where(x => x.CreatedAt.Date <= new DateTime(year ?? 0, int.Parse(month ?? ""), 1)) + .OrderByDescending(x => x.CreatedAt) + .FirstOrDefault()?.Value1 ?? 0; + setValue(processedRecord, 1, firstVal); + previousValue = firstVal; + //days 2-29/30 + + + for (int i=2; i x.CreatedAt.Day == i && x.CreatedAt.Month == int.Parse(month ?? "")) + .OrderByDescending(x => x.CreatedAt) + .FirstOrDefault()?.Value1; + if (dayVal == null) + { + setValue(processedRecord, i, 0); + } else + { + float processedVal = (dayVal ?? 0) - previousValue; + setValue(processedRecord, i, processedVal); + previousValue = processedVal; + } + } + //last day + float? lastVal = codeRecords + .Where(x => x.CreatedAt.Date >= new DateTime(year ?? 0, int.Parse(month ?? ""), lastDayInMonth)) + .OrderByDescending(x => x.CreatedAt) + .FirstOrDefault()?.Value1; + + if (lastVal == null) + { + setValue(processedRecord, lastDayInMonth, 0); + } else + { + setValue(processedRecord, lastDayInMonth, (lastVal ?? 0) - previousValue); + } + + response.Records.Add(processedRecord); + } + return response; + } + private void setValue(Record record, int number, float? value) { - return null; + switch (number) + { + case 1: + record.Value1 = value; + break; + case 2: + record.Value2 = value; + break; + case 3: + record.Value3 = value; + break; + case 4: + record.Value4 = value; + break; + case 5: + record.Value5 = value; + break; + case 6: + record.Value6 = value; + break; + case 7: + record.Value7 = value; + break; + case 8: + record.Value8 = value; + break; + case 9: + record.Value9 = value; + break; + case 10: + record.Value10 = value; + break; + case 11: + record.Value11 = value; + break; + case 12: + record.Value12 = value; + break; + case 13: + record.Value13 = value; + break; + case 14: + record.Value14 = value; + break; + case 15: + record.Value15 = value; + break; + case 16: + record.Value16 = value; + break; + case 17: + record.Value17 = value; + break; + case 18: + record.Value18 = value; + break; + case 19: + record.Value19 = value; + break; + case 20: + record.Value20 = value; + break; + case 21: + record.Value21 = value; + break; + case 22: + record.Value22 = value; + break; + case 23: + record.Value23 = value; + break; + case 24: + record.Value24 = value; + break; + case 25: + record.Value25 = value; + break; + case 26: + record.Value26 = value; + break; + case 27: + record.Value27 = value; + break; + case 28: + record.Value28 = value; + break; + case 29: + record.Value29 = value; + break; + case 30: + record.Value30 = value; + break; + case 31: + record.Value31 = value; + break; + } } } }