summaryrefslogtreecommitdiff
path: root/ShedCalc/BOMController.swift
diff options
context:
space:
mode:
authorArturs Artamonovs <arturs.artamonovs@protonmail.com>2026-08-26 21:37:56 +0100
committerArturs Artamonovs <arturs.artamonovs@protonmail.com>2026-08-26 21:37:56 +0100
commite8b5398d8f9a2d4fa9ed339fec774badc270979f (patch)
tree2e4607262e7887cdb37003568d846503b35f9cc8 /ShedCalc/BOMController.swift
parent91d0042017e6c46f2c9f5d42d438836efa6d53e4 (diff)
downloadShedCalc-e8b5398d8f9a2d4fa9ed339fec774badc270979f.tar.gz
ShedCalc-e8b5398d8f9a2d4fa9ed339fec774badc270979f.zip
All views seem to work ok
Diffstat (limited to 'ShedCalc/BOMController.swift')
-rw-r--r--ShedCalc/BOMController.swift153
1 files changed, 153 insertions, 0 deletions
diff --git a/ShedCalc/BOMController.swift b/ShedCalc/BOMController.swift
index fa05eeb..be70a65 100644
--- a/ShedCalc/BOMController.swift
+++ b/ShedCalc/BOMController.swift
@@ -4,4 +4,157 @@
//
// Created by Jacky Jack on 01/08/2026.
//
+import SwiftUI
+import Combine
+private func roundUpPieces(_ value: Float) -> Int {
+ Int(value.rounded(.up))
+}
+
+private func roundUpPieces(_ value: Double) -> Int {
+ Int(value.rounded(.up))
+}
+
+struct MaterialItem: Identifiable {
+ let materialName: String
+ let pricePerMeter: Double
+ let totalMeters: Double
+ let totalPrice: Double
+ let metersPerPiece: Double
+ let totalPieces: Double
+
+ let id = UUID()
+}
+class BOMController {
+
+ func calcBOM(from paramModel: ParamModel) -> [MaterialItem] {
+ var items: [MaterialItem] = []
+ items.append(calcOSB(from: paramModel))
+ items.append(calcWallTimber2x4(from: paramModel))
+ items.append(calcFloorTimber2x4(from: paramModel))
+ items.append(calcRoofTimber2x4(from: paramModel))
+ items.append(calcRoofFelt(from: paramModel))
+ items.append(calcWeatherWrap(from: paramModel))
+ items.append(calcCladding(from: paramModel))
+ return items
+ }
+
+ private func calcOSB(from paramModel: ParamModel) -> MaterialItem {
+ let totalOSBarea = paramModel.floorArea()
+ let OSBPrice = totalOSBarea*paramModel.OSBSheetPrice
+ let OSBPricePerMeter = paramModel.OSBSheetPrice / (1.2*2.4)
+ let totalPieces = roundUpPieces(totalOSBarea / (1.2*2.4))
+ return MaterialItem(
+ materialName: "OSB",
+ pricePerMeter: Double(OSBPricePerMeter),
+ totalMeters: Double(totalOSBarea),
+ totalPrice: Double(totalPieces)*Double(paramModel.OSBSheetPrice),
+ metersPerPiece:Double(paramModel.OSBSheetPrice),
+ totalPieces: Double(totalPieces))
+ }
+
+ private func calcWallTimber2x4(from paramModel: ParamModel) -> MaterialItem {
+ let totalLength = paramModel.totalWallBeamLength()
+ let timberBeamPrice = paramModel.timberBeamPrice
+ let totalPrice = totalLength*timberBeamPrice
+ let pieceSize = paramModel.timberLengthSize
+ let totalPieces = roundUpPieces(totalLength/pieceSize)
+ return MaterialItem(
+ materialName: "2x4",
+ pricePerMeter: Double(timberBeamPrice),
+ totalMeters: Double(totalLength),
+ totalPrice: Double(totalPrice),
+ metersPerPiece:Double(pieceSize),
+ totalPieces: Double(totalPieces)
+ )
+ }
+ private func calcFloorTimber2x4(from paramModel: ParamModel) -> MaterialItem {
+ let joistLength = paramModel.totalJoistBeamLength() * 2
+ let spacersLength = Double(paramModel.lengthBeamNum())*paramModel.beamSpace
+ let timberBeamPrice = paramModel.timberBeamPrice
+ let totalLength = Double(paramModel.lengthBeamNum())*paramModel.beamSpace
+ let totalPrice = totalLength*timberBeamPrice
+ let pieceSize = Double(paramModel.timberLengthSize)
+ let totalPieces = roundUpPieces(totalLength/pieceSize)
+ return MaterialItem(
+ materialName: "Floor 2x4",
+ pricePerMeter: Double(timberBeamPrice),
+ totalMeters: Double(totalLength),
+ totalPrice: Double(totalPrice),
+ metersPerPiece:Double(pieceSize),
+ totalPieces: Double(totalPieces)
+ )
+ }
+
+ private func calcRoofTimber2x4(from paramModel: ParamModel) -> MaterialItem {
+ let joistLength = paramModel.totalJoistBeamLength() * 2
+ let spacersLength = Double(paramModel.lengthBeamNum())*paramModel.beamSpace
+ let timberBeamPrice = paramModel.timberBeamPrice
+ let totalLength = Double(paramModel.lengthBeamNum())*paramModel.beamSpace
+ let totalPrice = totalLength*timberBeamPrice
+ let pieceSize = Double(paramModel.timberLengthSize)
+ let totalPieces = roundUpPieces(totalLength/pieceSize)
+ return MaterialItem(
+ materialName: "Roof 2x4",
+ pricePerMeter: Double(timberBeamPrice),
+ totalMeters: Double(totalLength),
+ totalPrice: Double(totalPrice),
+ metersPerPiece:Double(pieceSize),
+ totalPieces: Double(totalPieces)
+ )
+ }
+
+ private func calcRoofFelt(from paramModel: ParamModel) -> MaterialItem {
+ let roofArea = paramModel.roofArea()
+ let feltRollArea = Double(paramModel.feltWidth)*Double(paramModel.feltLength)
+ var feltPricePerMeter:Double = 0.0
+ if paramModel.feltPrice > 0.0 {
+ feltPricePerMeter = Double(paramModel.feltPrice) / feltRollArea
+ }
+ let totalPieces = roundUpPieces(Double(roofArea)/Double(feltRollArea))
+
+ let totalPrice = Double(totalPieces) * paramModel.feltPrice
+
+ return MaterialItem(
+ materialName: "Roof Felt",
+ pricePerMeter: Double(feltPricePerMeter),
+ totalMeters: Double(roofArea),
+ totalPrice: Double(totalPrice),
+ metersPerPiece:Double(feltRollArea),
+ totalPieces: Double(totalPieces)
+ )
+ }
+
+ private func calcWeatherWrap(from paramModel: ParamModel) -> MaterialItem {
+
+ return MaterialItem(
+ materialName: "Weather Wrap",
+ pricePerMeter: Double(0.1),
+ totalMeters: Double(0.1),
+ totalPrice: Double(0.1),
+ metersPerPiece:Double(0.1),
+ totalPieces: Double(0.1)
+ )
+ }
+
+ private func calcCladding(from paramModel: ParamModel) -> MaterialItem {
+ let wallArea = Double(paramModel.length*paramModel.height)*2 + Double(paramModel.width*paramModel.height)*2
+ let singleCladArea = paramModel.claddingLength * (Double(paramModel.claddingWidth) - paramModel.claddingOverlap)
+ let claddingPieces = wallArea/singleCladArea
+ let totalPieces = roundUpPieces(claddingPieces)
+ let totalPrice = Double(totalPieces) * paramModel.claddingPrice
+ return MaterialItem(
+ materialName: "Cladding",
+ pricePerMeter: Double(paramModel.claddingPrice),
+ totalMeters: Double(claddingPieces*paramModel.claddingLength),
+ totalPrice: Double(totalPrice),
+ metersPerPiece:Double(paramModel.claddingLength),
+ totalPieces: Double(totalPieces)
+ )
+ }
+
+ private func calcBeam(from paramModel: ParamModel) -> MaterialItem {
+ return MaterialItem(materialName: "2x4", pricePerMeter: 1.0, totalMeters: 10, totalPrice: 100, metersPerPiece: 1.2, totalPieces: 11.2)
+ }
+
+}