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 },
],
};
}
}