forked from jappel/leistungsbilanz-ts
Add optional room areas
This commit is contained in:
parent
a6500e2b26
commit
dce31ee143
26 changed files with 3669 additions and 78 deletions
|
|
@ -18,6 +18,19 @@ type FloorLike = Pick<FloorDto, "id" | "name"> & {
|
|||
buildingId?: string | null;
|
||||
};
|
||||
type RoomLike = Pick<RoomDto, "floorId">;
|
||||
type RoomAreaLike = Pick<RoomDto, "floorId" | "areaM2">;
|
||||
|
||||
export interface RoomAreaSummary {
|
||||
areaM2: number;
|
||||
roomCount: number;
|
||||
missingAreaCount: number;
|
||||
}
|
||||
|
||||
export interface StructureAreaSummaries {
|
||||
total: RoomAreaSummary;
|
||||
byBuilding: Map<string | null, RoomAreaSummary>;
|
||||
byFloor: Map<string | null, RoomAreaSummary>;
|
||||
}
|
||||
|
||||
export interface FloorGroup<TFloor extends FloorLike = FloorLike> {
|
||||
/** null for floors without (known) building. */
|
||||
|
|
@ -262,6 +275,59 @@ export function countRoomsByFloor(
|
|||
return counts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sums only known room areas and counts missing values separately. Rooms with
|
||||
* no known floor/building are grouped under null for the corresponding UI
|
||||
* entries "Ohne Etage" and "Ohne Gebäude".
|
||||
*/
|
||||
export function summarizeRoomAreas(
|
||||
rooms: ReadonlyArray<RoomAreaLike>,
|
||||
floors: ReadonlyArray<FloorLike>,
|
||||
buildings: ReadonlyArray<BuildingLike>
|
||||
): StructureAreaSummaries {
|
||||
const buildingIds = toIdSet(buildings);
|
||||
const floorsById = new Map(floors.map((floor) => [floor.id, floor]));
|
||||
const byBuilding = new Map<string | null, RoomAreaSummary>();
|
||||
const byFloor = new Map<string | null, RoomAreaSummary>();
|
||||
const total = emptyAreaSummary();
|
||||
|
||||
for (const room of rooms) {
|
||||
const floor = room.floorId === null ? undefined : floorsById.get(room.floorId);
|
||||
const floorId = floor?.id ?? null;
|
||||
const buildingId = floor
|
||||
? resolveFloorBuildingId(floor, buildingIds)
|
||||
: null;
|
||||
addRoomArea(total, room.areaM2);
|
||||
addRoomArea(summaryFor(byFloor, floorId), room.areaM2);
|
||||
addRoomArea(summaryFor(byBuilding, buildingId), room.areaM2);
|
||||
}
|
||||
return { total, byBuilding, byFloor };
|
||||
}
|
||||
|
||||
function emptyAreaSummary(): RoomAreaSummary {
|
||||
return { areaM2: 0, roomCount: 0, missingAreaCount: 0 };
|
||||
}
|
||||
|
||||
function summaryFor(
|
||||
summaries: Map<string | null, RoomAreaSummary>,
|
||||
key: string | null
|
||||
) {
|
||||
const existing = summaries.get(key);
|
||||
if (existing) return existing;
|
||||
const created = emptyAreaSummary();
|
||||
summaries.set(key, created);
|
||||
return created;
|
||||
}
|
||||
|
||||
function addRoomArea(summary: RoomAreaSummary, areaM2: number | null) {
|
||||
summary.roomCount += 1;
|
||||
if (areaM2 === null) {
|
||||
summary.missingAreaCount += 1;
|
||||
} else {
|
||||
summary.areaM2 += areaM2;
|
||||
}
|
||||
}
|
||||
|
||||
/** "EG · Haus A", "EG" (floor without building) or "Ohne Etage". */
|
||||
export function describeRoomLocation(
|
||||
room: RoomLike,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue