namespace MeterVault.Infrastructure.Import; /// Meter ids the reference profiles map columns to. Defaults are the fixed conventions /// used by the golden reconciliation tests; the importer supplies real database ids at runtime. public sealed record ReferenceMeterIds( int Haus, int Netz, int Auto, int Solar1, int Solar2, int Wasser, int OilTank, int Burner) { public static readonly ReferenceMeterIds Default = new(1, 2, 3, 4, 5, 10, 20, 21); } /// Category ids the Kosten profile maps cost columns to. public sealed record ReferenceCategoryIds(int Heizung, int Strom, int Wasser, int Pool) { public static readonly ReferenceCategoryIds Default = new(1, 2, 3, 4); } /// /// Built-in mapping profiles for the four reference Energiebilanz sheets (SDD §6.3). /// They ship as example imports and as the golden reconciliation fixtures. /// public static class ReferenceProfiles { public const int Haus = 1; public const int Netz = 2; public const int Auto = 3; public const int Solar1 = 4; public const int Solar2 = 5; public const int Wasser = 10; public const int OilTank = 20; public const int Burner = 21; public const int CategoryHeizung = 1; public const int CategoryStrom = 2; public const int CategoryWasser = 3; public const int CategoryPool = 4; /// Linear heating-oil tank calibration: 7000 L / 150 cm ≈ 46.667 L/cm. public const double OilLitresPerCm = 7000d / 150d; public static MappingProfile Electricity(ReferenceMeterIds? ids = null) { ids ??= ReferenceMeterIds.Default; return new MappingProfile { Name = "Energiebilanz — Strom", DateColumn = 0, DateKind = DateKind.MonthName, FirstDataRowIndex = 1, Columns = [ new ColumnMapping { Index = 1, Role = MappingRole.Reading, MeterId = ids.Haus, Unit = "kWh" }, new ColumnMapping { Index = 2, Role = MappingRole.Reading, MeterId = ids.Netz, Unit = "kWh" }, // Index 3 is a blank spacer column — left unmapped (Ignore). new ColumnMapping { Index = 4, Role = MappingRole.Reading, MeterId = ids.Auto, Unit = "kWh" }, new ColumnMapping { Index = 5, Role = MappingRole.Reading, MeterId = ids.Solar1, Unit = "kWh" }, new ColumnMapping { Index = 6, Role = MappingRole.Reading, MeterId = ids.Solar2, Unit = "kWh" }, ], }; } public static MappingProfile Water(ReferenceMeterIds? ids = null) { ids ??= ReferenceMeterIds.Default; return new MappingProfile { Name = "Energiebilanz — Wasser", DateColumn = 0, DateKind = DateKind.MonthName, FirstDataRowIndex = 1, DetectCumulativeSwaps = true, Columns = [ new ColumnMapping { Index = 1, Role = MappingRole.Reading, MeterId = ids.Wasser, Unit = "m3", SwapConsumptionColumn = 2, }, ], }; } public static MappingProfile HeatingOil(ReferenceMeterIds? ids = null) { ids ??= ReferenceMeterIds.Default; return new MappingProfile { Name = "Energiebilanz — Heizöl", DateColumn = 0, DateKind = DateKind.Auto, // early rows DD.MM.YYYY, later rows month names. AnchorMonthsToEnd = true, // a monthly snapshot sorts after same-month day-dated readings. HeaderRowIndex = 3, FirstDataRowIndex = 4, Columns = [ new ColumnMapping { Index = 1, Role = MappingRole.Reading, MeterId = ids.Burner, Unit = "h" }, new ColumnMapping { Index = 4, Role = MappingRole.TankLevel, MeterId = ids.OilTank, Unit = "cm" }, new ColumnMapping { Index = 7, Role = MappingRole.Delivery, MeterId = ids.OilTank, Unit = "L" }, ], }; } public static MappingProfile Costs(ReferenceCategoryIds? ids = null) { ids ??= ReferenceCategoryIds.Default; return new MappingProfile { Name = "Energiebilanz — Kosten", DateColumn = 0, DateKind = DateKind.MonthName, FirstDataRowIndex = 1, Columns = [ new ColumnMapping { Index = 3, Role = MappingRole.ManualCost, CategoryId = ids.Heizung }, new ColumnMapping { Index = 4, Role = MappingRole.ManualCost, CategoryId = ids.Strom }, new ColumnMapping { Index = 5, Role = MappingRole.ManualCost, CategoryId = ids.Wasser }, new ColumnMapping { Index = 6, Role = MappingRole.ManualCost, CategoryId = ids.Pool }, ], }; } }