WIP: Using project detail for duct size calculations, fix trunk sizes querying database for room data, it's now eagerly loaded.

This commit is contained in:
2026-01-27 08:59:36 -05:00
parent 1663c0a514
commit 066b3003d0
4 changed files with 192 additions and 58 deletions

View File

@@ -5,6 +5,14 @@ import ManualDCore
extension DatabaseClient {
func calculateDuctSizes(
details: Project.Detail
) async throws -> (DuctSizes, DuctSizeSharedRequest) {
let (rooms, shared) = try await calculateRoomDuctSizes(details: details)
let (trunks, _) = try await calculateTrunkDuctSizes(details: details)
return (.init(rooms: rooms, trunks: trunks), shared)
}
func calculateDuctSizes(
projectID: Project.ID
) async throws -> (DuctSizes, DuctSizeSharedRequest, [Room]) {
@@ -24,6 +32,16 @@ extension DatabaseClient {
)
}
func calculateRoomDuctSizes(
details: Project.Detail
) async throws -> ([DuctSizes.RoomContainer], DuctSizeSharedRequest) {
@Dependency(\.manualD) var manualD
let shared = try sharedDuctRequest(details: details)
let rooms = try await manualD.calculateRoomSizes(rooms: details.rooms, sharedRequest: shared)
return (rooms, shared)
}
func calculateRoomDuctSizes(
projectID: Project.ID
) async throws -> ([DuctSizes.RoomContainer], DuctSizeSharedRequest) {
@@ -40,6 +58,20 @@ extension DatabaseClient {
)
}
func calculateTrunkDuctSizes(
details: Project.Detail
) async throws -> ([DuctSizes.TrunkContainer], DuctSizeSharedRequest) {
@Dependency(\.manualD) var manualD
let shared = try sharedDuctRequest(details: details)
let trunks = try await manualD.calculateTrunkSizes(
rooms: details.rooms,
trunks: details.trunks,
sharedRequest: shared
)
return (trunks, shared)
}
func calculateTrunkDuctSizes(
projectID: Project.ID
) async throws -> ([DuctSizes.TrunkContainer], DuctSizeSharedRequest) {
@@ -57,6 +89,32 @@ extension DatabaseClient {
)
}
func sharedDuctRequest(details: Project.Detail) throws -> DuctSizeSharedRequest {
guard
let dfrResponse = designFrictionRate(
componentLosses: details.componentLosses,
equipmentInfo: details.equipmentInfo,
equivalentLengths: details.maxContainer
)
else {
throw ProjectClientError("Project not complete.")
}
guard let projectSHR = details.project.sensibleHeatRatio else {
throw ProjectClientError("Project sensible heat ratio not set.")
}
let ensuredTEL = try dfrResponse.ensureMaxContainer()
return .init(
equipmentInfo: dfrResponse.equipmentInfo,
maxSupplyLength: ensuredTEL.supply,
maxReturnLenght: ensuredTEL.return,
designFrictionRate: dfrResponse.designFrictionRate,
projectSHR: projectSHR
)
}
func sharedDuctRequest(_ projectID: Project.ID) async throws -> DuctSizeSharedRequest {
guard let dfrResponse = try await designFrictionRate(projectID: projectID) else {
@@ -107,25 +165,36 @@ extension DatabaseClient {
}
func designFrictionRate(
projectID: Project.ID
) async throws -> DesignFrictionRateResponse? {
guard let equipmentInfo = try await equipment.fetch(projectID) else {
return nil
}
componentLosses: [ComponentPressureLoss],
equipmentInfo: EquipmentInfo,
equivalentLengths: EffectiveLength.MaxContainer
) -> DesignFrictionRateResponse? {
guard let tel = equivalentLengths.total,
componentLosses.count > 0
else { return nil }
let equivalentLengths = try await effectiveLength.fetchMax(projectID)
guard let tel = equivalentLengths.total else { return nil }
let componentLosses = try await componentLoss.fetch(projectID)
guard componentLosses.count > 0 else { return nil }
let availableStaticPressure =
equipmentInfo.staticPressure - componentLosses.total
let availableStaticPressure = equipmentInfo.staticPressure - componentLosses.total
return .init(
designFrictionRate: (availableStaticPressure * 100) / tel,
equipmentInfo: equipmentInfo,
telMaxContainer: equivalentLengths
)
}
func designFrictionRate(
projectID: Project.ID
) async throws -> DesignFrictionRateResponse? {
guard let equipmentInfo = try await equipment.fetch(projectID) else {
return nil
}
return try await designFrictionRate(
componentLosses: componentLoss.fetch(projectID),
equipmentInfo: equipmentInfo,
equivalentLengths: effectiveLength.fetchMax(projectID)
)
}
}

View File

@@ -48,29 +48,72 @@ extension ProjectClient: DependencyKey {
extension DatabaseClient {
// fileprivate func makePdfRequest(_ projectID: Project.ID) async throws -> PdfClient.Request {
// @Dependency(\.manualD) var manualD
//
// guard let project = try await projects.get(projectID) else {
// throw ProjectClientError("Project not found. id: \(projectID)")
// }
// let frictionRateResponse = try await manualD.frictionRate(projectID: projectID)
// guard let frictionRate = frictionRateResponse.frictionRate else {
// throw ProjectClientError("Friction rate not found. id: \(projectID)")
// }
// let (ductSizes, sharedInfo, rooms) = try await calculateDuctSizes(projectID: projectID)
//
// return .init(
// project: project,
// rooms: rooms,
// componentLosses: frictionRateResponse.componentLosses,
// ductSizes: ductSizes,
// equipmentInfo: sharedInfo.equipmentInfo,
// maxSupplyTEL: sharedInfo.maxSupplyLength,
// maxReturnTEL: sharedInfo.maxReturnLenght,
// frictionRate: frictionRate,
// projectSHR: sharedInfo.projectSHR
// )
// }
fileprivate func makePdfRequest(_ projectID: Project.ID) async throws -> PdfClient.Request {
@Dependency(\.manualD) var manualD
guard let project = try await projects.get(projectID) else {
guard let projectDetails = try await projects.detail(projectID) else {
throw ProjectClientError("Project not found. id: \(projectID)")
}
let frictionRateResponse = try await manualD.frictionRate(projectID: projectID)
let (ductSizes, shared) = try await calculateDuctSizes(details: projectDetails)
let frictionRateResponse = try await manualD.frictionRate(details: projectDetails)
guard let frictionRate = frictionRateResponse.frictionRate else {
throw ProjectClientError("Friction rate not found. id: \(projectID)")
}
let (ductSizes, sharedInfo, rooms) = try await calculateDuctSizes(projectID: projectID)
return .init(
project: project,
rooms: rooms,
componentLosses: frictionRateResponse.componentLosses,
details: projectDetails,
ductSizes: ductSizes,
equipmentInfo: sharedInfo.equipmentInfo,
maxSupplyTEL: sharedInfo.maxSupplyLength,
maxReturnTEL: sharedInfo.maxReturnLenght,
frictionRate: frictionRate,
projectSHR: sharedInfo.projectSHR
shared: shared,
frictionRate: frictionRate
)
}
}
extension PdfClient.Request {
init(
details: Project.Detail,
ductSizes: DuctSizes,
shared: DuctSizeSharedRequest,
frictionRate: FrictionRate
) {
self.init(
project: details.project,
rooms: details.rooms,
componentLosses: details.componentLosses,
ductSizes: ductSizes,
equipmentInfo: details.equipmentInfo,
maxSupplyTEL: shared.maxSupplyLength,
maxReturnTEL: shared.maxReturnLenght,
frictionRate: frictionRate,
projectSHR: shared.projectSHR
)
}
}