import { asc, eq } from "drizzle-orm"; import type { DetailedDeviceRowPower, EstimateBalanceSnapshot, } from "../../shared/estimate-balance/estimate-balance.js"; import { calculateRowTotalPower } from "../../domain/calculations/circuit-power-calculation.js"; import type { AppDatabase } from "../database-context.js"; import { circuitDeviceRows } from "../schema/circuit-device-rows.js"; import { circuitLists } from "../schema/circuit-lists.js"; import { circuits } from "../schema/circuits.js"; import { estimateBalances } from "../schema/estimate-balances.js"; import { readEstimateBalances } from "./estimate-balance.persistence.js"; /** Read side of the estimate-balance module; writes go through commands. */ export class EstimateBalanceRepository { constructor(private readonly database: AppDatabase) {} listByProject(projectId: string): EstimateBalanceSnapshot[] { return readEstimateBalances(this.database, projectId); } findById(projectId: string, balanceId: string): EstimateBalanceSnapshot | null { return readEstimateBalances(this.database, projectId, balanceId)[0] ?? null; } nextSortOrder(projectId: string): number { const rows = this.database .select({ sortOrder: estimateBalances.sortOrder }) .from(estimateBalances) .where(eq(estimateBalances.projectId, projectId)) .orderBy(asc(estimateBalances.sortOrder)) .all(); return rows.length ? Math.max(...rows.map((row) => row.sortOrder)) + 1 : 0; } /** * Device rows of all circuit lists of the project with their total power * (quantity · power per unit · device GZF, like the circuit tree). */ listDetailedDeviceRowPower(projectId: string): DetailedDeviceRowPower[] { return this.database .select({ costGroup: circuitDeviceRows.costGroup, quantity: circuitDeviceRows.quantity, powerPerUnit: circuitDeviceRows.powerPerUnit, simultaneityFactor: circuitDeviceRows.simultaneityFactor, cosPhi: circuitDeviceRows.cosPhi, }) .from(circuitDeviceRows) .innerJoin(circuits, eq(circuits.id, circuitDeviceRows.circuitId)) .innerJoin(circuitLists, eq(circuitLists.id, circuits.circuitListId)) .where(eq(circuitLists.projectId, projectId)) .all() .map((row) => ({ costGroup: row.costGroup, kw: calculateRowTotalPower(row.quantity, row.powerPerUnit, row.simultaneityFactor), cosPhi: row.cosPhi, })); } }