Created
October 20, 2021 17:51
-
-
Save msisaifu/4bc288496afc2a338bd7caccc102f953 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class KitchenRenovationCalculator { | |
// ******************************************************************** | |
// ***** For demo purposes here the price and factor are hardcoded ***** | |
// ***** Once complete the functions SetFactor and setPrices will add all of those dynamically from your end ***** | |
// ******************************************************************** | |
setFactor(factors) { } | |
setPrices(prices) { } | |
removeMetalChimneyPrice = 600.00 | |
chimneyLevelFactor = 1.00 | |
removeLoadBearingWallPrice = 6800.00; | |
additionalWalkInPantrySpaceSF = 0; | |
constructNewPantryFinalCost = 0; | |
windowFinalCost = 0; | |
// ******************************************************************** | |
// ***** QUESTION # 01 to user - FLOOR LEVEL ***** | |
// ******************************************************************** | |
setKitchenFloorLevel(floorLevelName) { | |
if (['upper level', 'main level', 'lower level', 'basement level'].includes(floorLevelName)) { | |
this.floorLevelName = floorLevelName; | |
} else { | |
return alert('Invalid Input') | |
} | |
switch (this.floorLevelName) { | |
case 'upper level': | |
this.chimneyLevelFactor = 1.00; | |
this.plumbingLevelFactor = 1.08; | |
this.windowLevelFactor = 1.07; | |
this.floorProtectionMaskingLevelFactor = 1.20; | |
break; | |
case 'main level': | |
this.chimneyLevelFactor = 1.50; | |
this.plumbingLevelFactor = 1.00; | |
this.windowLevelFactor = 1.00; | |
this.floorProtectionMaskingLevelFactor = 1.00; | |
break; | |
case 'lower level': | |
this.chimneyLevelFactor = 2.00; | |
this.plumbingLevelFactor = 1.12; | |
this.windowLevelFactor = 0.95; | |
this.floorProtectionMaskingLevelFactor = 1.10; | |
break; | |
case 'basement level': | |
this.chimneyLevelFactor = 2.25; | |
this.plumbingLevelFactor = 1.15; | |
this.windowLevelFactor = 0.85; | |
this.floorProtectionMaskingLevelFactor = 1.15; | |
break; | |
default: | |
alert('Invalid Input'); | |
} | |
} | |
// ******************************************************************** | |
// ***** QUESTION # 02 to user - YEAR HOUSE BUILT ***** | |
// ******************************************************************** | |
setHouseBuiltYear(yearBuilt) { | |
if (yearBuilt > 2019) { | |
this.yearBuiltFactor = 1.00; // neutral for homes built in 2020s | |
} else if (yearBuilt > 2009 && yearBuilt < 2020) { | |
this.yearBuiltFactor = 1.03; // 3% higher for homes built in 2010s | |
} else if (yearBuilt > 1999 && yearBuilt < 2010) { | |
this.yearBuiltFactor = 1.06; // 6% higher for homes built in 2000s | |
} else if (yearBuilt > 1989 && yearBuilt < 2000) { | |
this.yearBuiltFactor = 1.10; // 10% higher for homes built in 1990s | |
} else if (yearBuilt > 1979 && yearBuilt < 1990) { | |
this.yearBuiltFactor = 1.14; // 14% higher for homes built in 1980s | |
} else if (yearBuilt > 1969 && yearBuilt < 1980) { | |
this.yearBuiltFactor = 1.18; // 18% higher for homes built in 1970s | |
} else if (yearBuilt > 1959 && yearBuilt < 1970) { | |
this.yearBuiltFactor = 1.22; // 22% higher for homes built in 1960s | |
} else if (yearBuilt > 1949 && yearBuilt < 1960) { | |
this.yearBuiltFactor = 1.26; // 26% higher for homes built in 1950s | |
} else if (yearBuilt > 1939 && yearBuilt < 1950) { | |
this.yearBuiltFactor = 1.30; // 30% higher for homes built in 1940s | |
} else if (yearBuilt > 1929 && yearBuilt < 1940) { | |
this.yearBuiltFactor = 1.34; // 34% higher for homes built in 1930s | |
} else if (yearBuilt > 1919 && yearBuilt < 1930) { | |
this.yearBuiltFactor = 1.38; // 38% higher for homes built in 1920s | |
} else if (yearBuilt > 1909 && yearBuilt < 1920) { | |
this.yearBuiltFactor = 1.40; // 40% higher for homes built in 1910s | |
} else if (yearBuilt > 1899 && yearBuilt < 1910) { | |
this.yearBuiltFactor = 1.40; // 40% higher for homes built in 1900s | |
} else if (yearBuilt < 1900) { | |
this.yearBuiltFactor = 1.40; // 40% higher for homes built pre 1900s | |
} else { | |
console.log("Invalid Selection") | |
} | |
} | |
// ******************************************************************** | |
// ***** QUESTION # 03 to user - INCLUDE DINING ROOM/AREA? ***** | |
// ******************************************************************** | |
setIncludeDining(includeDining) { | |
this.includeDining = includeDining; | |
if (this.includeDining) { | |
this.roomTypeName = "Kitchen/Dining Area"; | |
} else { | |
this.roomTypeName = "Kitchen"; | |
} | |
this.roomTypeNameSingular = this.roomTypeName; | |
} | |
setDiningRoomSize(notSure, size, relativeSize) { | |
if (this.includeDining) { | |
if (notSure) { | |
switch (relativeSize) { | |
case 'Tiny': | |
this.diningSizeSF = 60; | |
break; | |
case 'Small': | |
this.diningSizeSF = 80; | |
break; | |
case 'Average': | |
this.diningSizeSF = 100; | |
break; | |
case 'Large': | |
this.diningSizeSF = 140; | |
break; | |
case 'Extra Large': | |
this.diningSizeSF = 288; | |
break; | |
default: | |
alert('Invalid Selection') | |
} | |
} | |
if (size) { | |
if (size < 50 || size > 500) { | |
alert('Please enter a square footage from 50 to 500') | |
} else { | |
this.diningSizeSF = size; | |
} | |
} | |
this.DiningRoomSizeIsSet = true; | |
} | |
} | |
// ******************************************************************** | |
// ***** QUESTION # 04 to user - ROOM SIZE ***** | |
// ******************************************************************** | |
setKitchenSize(notSure, size, relativeSize) { | |
if (size) { | |
if (size < 60 || size > 600) { | |
return alert('Please enter the current approximate size of this Kitchen (Excluding dining room/area): (min 60, max 600)') | |
} | |
} | |
if (notSure) { | |
switch (relativeSize) { | |
case 'Tiny': | |
this.kitchenSizeSF = 70; | |
break; | |
case 'Small': | |
this.kitchenSizeSF = 100; | |
break; | |
case 'Average': | |
this.kitchenSizeSF = 140; | |
break; | |
case 'Large': | |
this.kitchenSizeSF = 170; | |
break; | |
case 'Extra Large': | |
this.kitchenSizeSF = 200; | |
break; | |
case 'Huge': | |
this.kitchenSizeSF = 280; | |
break; | |
default: | |
alert('Invalid Selection') | |
} | |
} else { | |
this.kitchenSizeSF = size; | |
} | |
this.kitchenSizeIsSet = true; | |
} | |
calculeRoomWallFactor() { | |
if (this.kitchenSizeIsSet) { | |
this.roomWallFactor = ((this.kitchenSizeSF - 144) * 0.00125) + 1; | |
if (this.roomWallFactor > 1.50) { | |
this.roomWallFactor = 1.50; // assign max value of 1.50 to roomWallFactor for kitchens | |
} | |
// ASSIGN VALUE OF kitchenSizeFactor: | |
this.kitchenSizeFactor = (this.kitchenSizeSF / 180) + 0.222; | |
if (this.kitchenSizeFactor > 1.50) { | |
this.kitchenSizeFactor = 1.50; // Assign max value of 1.50 | |
} else if (this.kitchenSizeFactor < 0.85) { | |
this.kitchenSizeFactor = 0.85; // Assign min value of 0.85 | |
} | |
} | |
if (this.includeDining) { | |
this.roomSizeSF = this.kitchenSizeSF + this.diningSizeSF; | |
} else { | |
this.roomSizeSF = this.kitchenSizeSF; | |
} | |
return this.roomSizeSF; | |
} | |
// ******************************************************************** | |
// ***** QUESTION # 05 to user - CEILING HEIGHT ***** | |
// ******************************************************************** | |
setCeilingHeight(notSure, ceilingHeight) { | |
if (notSure) { | |
this.ceilingHeight = 8.5; // assign a value to ceilingHeight to be used in later calculations | |
this.ceilingFactor = 1.05; | |
} else { | |
switch (parseInt(ceilingHeight)) { | |
case 7: | |
this.ceilingHeight = 8; // assign minimum height of 8 feet for doing calculation | |
this.ceilingFactor = 1.00; | |
break; | |
case 8: | |
this.ceilingFactor = 1.00; | |
break; | |
case 9: | |
this.ceilingFactor = 1.15; | |
break; | |
case 10: | |
this.ceilingFactor = 1.35; | |
break; | |
case 11: | |
this.ceilingFactor = 1.45; | |
break; | |
case 12: | |
this.ceilingFactor = 1.60; | |
break; | |
case 16: | |
this.ceilingFactor = 2.05; | |
break; | |
default: | |
alert('Invalid Selection') | |
} | |
} | |
} | |
// ******************************************************************** | |
// ***** QUESTION # 06 to user - CEILING VAULTED? ***** | |
// ******************************************************************** | |
setIsCeilingVaulted(isVaulted) { | |
let vaultFactor; | |
if (isVaulted) { | |
vaultFactor = 1.2 | |
} else { | |
vaultFactor = 1.08 // only happen when user isn't sure | |
} | |
this.ceilingFactor = (this.ceilingFactor * vaultFactor); | |
} | |
// ******************************************************************** | |
// ***** QUESTION # 07 to user - WALL REMOVAL ***** | |
// ******************************************************************** | |
setWallRemoval(removeWallTrue, loadBearingTrue, floorAboveTrue, removeChimneyTrue, brickChimneyTrue) { | |
if (removeWallTrue) { | |
if (loadBearingTrue) { | |
if (floorAboveTrue) { | |
this.floorAboveFactor = 1.12;; | |
} | |
this.removeWallCost = this.removeLoadBearingWallPrice * this.floorAboveFactor * ((this.yearBuiltFactor + 1) / 2); | |
} else if (loadBearingTrue === "no") { | |
this.removeWallCost = this.removeNonLoadBearingWallPrice; | |
} else if (loadBearingTrue === "not sure") { | |
if (this.floorLevelName === "basement level" && this.yearBuiltFactor < 1.26) { // i.e. built in 1960's or newer | |
this.removeWallCost = this.removeNonLoadBearingWallPrice; | |
} else if (this.yearBuiltFactor > 1.10) { // i.e. built before 1990 | |
this.removeWallCost = this.removeNonLoadBearingWallPrice * 2; // double price if built 1989 or earlier than for a definite non-load bearing wall removal price | |
} else { | |
this.removeWallCost = this.removeNonLoadBearingWallPrice * 1.25; // 25% Higher if built 1990 or newer | |
} | |
} else { | |
alert("Invalid Input") | |
} | |
}; | |
if (removeChimneyTrue === "yes") { | |
if (brickChimneyTrue === "yes") { | |
this.removeChimneyCost = this.removeBrickChimneyPrice * ((this.yearBuiltFactor + 1) / 2) * this.chimneyLevelFactor * this.ceilingFactor; | |
} else if (brickChimneyTrue === "no") { | |
this.removeChimneyCost = this.removeMetalChimneyPrice * ((this.yearBuiltFactor + 1) / 2) * this.chimneyLevelFactor * this.ceilingFactor; | |
} | |
} else if (brickChimneyTrue === "not sure") { | |
this.removeChimneyCost = this.removeMetalChimneyPrice * 1.25 * ((this.yearBuiltFactor + 1) / 2) * this.chimneyLevelFactor * this.ceilingFactor; // 25% higher than standard metal chimney price if "not sure" selected by user | |
} else { | |
return alert("Invalid Selection"); | |
} | |
this.wallRemovalFinalCost = (this.removeWallCost * this.yearBuiltFactor * this.roomWallFactor * this.ceilingFactor) + this.removeChimneyCost; // Calculates cost to remove / relocate wall if required // Note yearBuiltFactor is used multiple times in load bearing walls which is correct | |
} | |
// ******************************************************************** | |
// ***** QUESTION # 08 to user - LAYOUT ***** | |
// ******************************************************************** | |
setLayout(removeWallTrue, changeKitchenLayoutTrue, relocateKitchenElectricalTrue, relocateKitchenPlumbingTrue){ | |
const [changeKitchenLayoutPrice, relocateKitchenElectricalPrice, relocateKitchenPlumbingPrice ] = [999.99, 999.99, 999.99]; | |
let { kitchenSizeFactor, plumbingLevelFactor, yearBuiltFactor } = this, | |
changeKitchenLayoutCost = 0, relocateKitchenElectricalCost = 0, relocateKitchenPlumbingCost = 0; | |
if (removeWallTrue === "yes"){ | |
if (changeKitchenLayoutTrue === "yes") { | |
changeKitchenLayoutCost = changeKitchenLayoutPrice * kitchenSizeFactor * plumbingLevelFactor * ((yearBuiltFactor + 1) / 2); | |
if (relocateKitchenElectricalTrue === "yes") { | |
relocateKitchenElectricalCost = relocateKitchenElectricalPrice * ((kitchenSizeFactor + 1) / 2) * ((yearBuiltFactor + 1) / 2); | |
} | |
if (relocateKitchenPlumbingTrue === "yes") { | |
relocateKitchenPlumbingCost = relocateKitchenPlumbingPrice * plumbingLevelFactor * ((kitchenSizeFactor + 1) / 2) * ((yearBuiltFactor + 1) / 2); | |
} | |
} | |
} else { | |
if (relocateKitchenPlumbingTrue === "yes" ){ | |
relocateKitchenPlumbingCost = relocateKitchenPlumbingPrice * plumbingLevelFactor * ((kitchenSizeFactor + 1) / 2) * ((yearBuiltFactor + 1) / 2); | |
} | |
} | |
this.changeKitchenLayoutFinalCost = changeKitchenLayoutCost + relocateKitchenElectricalCost + relocateKitchenPlumbingCost; | |
} | |
// ******************************************************************** | |
// ***** QUESTION # 09 to user - PANTRY/CLOSET ***** | |
// ******************************************************************** | |
setPentry(containsPantryTrue, pantryPreExistingTrue, pantryLocation, pantrySize, pantryType){ | |
const _pantryLocationData = { | |
"Corner between cabinets": 5.25, | |
"End of cabinets": 2.75, | |
"Away from cabinets": 0, | |
"Other": 1.5 | |
}; | |
const _pantrySizeData = { | |
"Average": { newPantrySizeFactor: 1.00, pantryFootprintFactor: 1.00, additionalWalkInPantrySpaceSF : 30 }, | |
"Small": { newPantrySizeFactor : 0.85, pantryFootprintFactor : 0.9, additionalWalkInPantrySpaceSF : 20 }, | |
"Large": { newPantrySizeFactor: 1.20, pantryFootprintFactor: 1.10, additionalWalkInPantrySpaceSF : 40 }, | |
}; | |
const _constructNewPantryPrice = 999.99; | |
let { ceilingFactor, yearBuiltFactor } = this, _newPantrySizeFactor = 0, _pantryFootprintFactor = 0; | |
this.pantryFootprint = 0; | |
if (containsPantryTrue === "yes"){ | |
if (_pantryLocationData[pantryLocation]){ | |
this.pantryFootprint = _pantryLocationData[pantryLocation]; | |
} else { | |
return alert("Invalid Selection"); | |
} | |
if (_pantrySizeData[pantrySize]) { | |
_newPantrySizeFactor = _pantrySizeData[pantrySize].newPantrySizeFactor; | |
_pantryFootprintFactor = _pantrySizeData[pantrySize].pantryFootprintFactor; | |
} else { | |
return alert("Invalid Selection"); | |
} | |
if (pantryLocation === "Away from cabinets" || pantryLocation === "Other"){ | |
if (pantryType === "Walk-in"){ | |
if (_pantrySizeData[pantrySize]) { | |
this.additionalWalkInPantrySpaceSF = _pantrySizeData[pantrySize].additionalWalkInPantrySpaceSF; | |
} | |
} | |
} | |
this.pantryFootprint = this.pantryFootprint * _pantryFootprintFactor; | |
if (pantryPreExistingTrue === "yes") { | |
this.constructNewPantryFinalCost = _constructNewPantryPrice * _newPantrySizeFactor * ((ceilingFactor + 1) / 2) * ((yearBuiltFactor + 1) / 2); | |
} | |
} | |
} | |
// ******************************************************************** | |
// ***** QUESTION # 10 to user - WINDOWS ***** | |
// ******************************************************************** | |
setWindow(replaceWindowsTrue, windowGrade, windowBlindGrade, newWindowOpeningTrue, installWindowBlindsTrue, | |
windowBlindCount, smallWindowCount = 0, mediumWindowCount = 0, largeWindowCount = 0, newWindowOpeningCount = 0){ | |
const _windowGradeData = { | |
"Bronze": { windowGradeFactor: 0.90, windowBlindGradeFactor: 0.80}, | |
"Silver": { windowGradeFactor: 1.00, windowBlindGradeFactor: 1.00}, | |
"Gold": { windowGradeFactor: 1.25, windowBlindGradeFactor: 1.50}, | |
"Platinum": { windowGradeFactor: 1.50, windowBlindGradeFactor: 2.25}, | |
}; | |
const [ _smallWindowPrice, _mediumWindowPrice, _largeWindowPrice ] = [875.00, 980.00, 1250.00, ]; | |
const [_smallWindowBlindPrice, _mediumWindowBlindPrice, _largeWindowBlindPrice] = [80.00, 120.00, 160.00]; | |
const _newWindowOpeningPrice = 1100.00; | |
let { roomSizeSF, windowLevelFactor, yearBuiltFactor, windowFinalCost } = this, | |
_approxWindowCount = roomSizeSF / 90, _windowGradeFactor = 1.00, _windowBlindGradeFactor = 1.00, | |
_smallWindowCost = 0, _mediumWindowCost = 0, _largeWindowCost = 0, _newWindowOpeningCost = 0; | |
_approxWindowCount = _approxWindowCount > 7 ? 7 : _approxWindowCount; | |
if (replaceWindowsTrue === "yes") { | |
if (_windowGradeData[windowGrade]) { | |
_windowGradeFactor = _windowGradeData[windowGrade].windowGradeFactor; | |
} else { | |
return alert("Invalid Selection"); | |
} | |
_smallWindowCost = smallWindowCount * _smallWindowPrice * _windowGradeFactor * windowLevelFactor * ((yearBuiltFactor + 1) / 2); // multiply # of small windows by constant price per small window | |
_mediumWindowCost = mediumWindowCount * _mediumWindowPrice * _windowGradeFactor * windowLevelFactor * ((yearBuiltFactor + 1) / 2); // multiply # of medium windows by constant price per medium window | |
_largeWindowCost = largeWindowCount * _largeWindowPrice * _windowGradeFactor * windowLevelFactor * ((yearBuiltFactor + 1) / 2); // multiply # of large windows by constant price per large window | |
let _totalWindowCount = [_smallWindowCost, _mediumWindowCost, _largeWindowCost].reduce((old, current) => old + current, 0); // assigns total number of windows to be installed for this room | |
if (newWindowOpeningTrue === "yes") { | |
_newWindowOpeningCost = newWindowOpeningCount * _newWindowOpeningPrice * windowLevelFactor * ((yearBuiltFactor + 1) / 2); | |
} | |
if (installWindowBlindsTrue === "yes") { | |
if (_windowGradeData[windowBlindGrade]) { | |
_windowBlindGradeFactor = _windowGradeData[windowBlindGrade].windowBlindGradeFactor; | |
} else { | |
return alert("Invalid Selection"); | |
} | |
let _smallWindowBlindCost = smallWindowCount * _smallWindowBlindPrice * _windowBlindGradeFactor, | |
_mediumWindowBlindCost = mediumWindowCount * _mediumWindowBlindPrice * _windowBlindGradeFactor, | |
_largeWindowBlindCost = largeWindowCount * _largeWindowBlindPrice * _windowBlindGradeFactor, | |
_totalWindowBlindCost = _smallWindowBlindCost + _mediumWindowBlindCost + _largeWindowBlindCost; | |
this.windowFinalCost = windowFinalCost + _totalWindowBlindCost; | |
} | |
this.windowFinalCost = _smallWindowCost + _mediumWindowCost + _largeWindowCost + _newWindowOpeningCost; | |
if (_totalWindowCount < 2) { | |
this.windowFinalCost = windowFinalCost + singleWindowInstallBaseFee; // add the base install fee to total cost if only 1 window is to be installed | |
} | |
else if (_totalWindowCount > 3) { | |
this.windowFinalCost = windowFinalCost * 0.94; // 6% discount once installing 4 or more windows | |
} | |
} else if (replaceWindowsTrue === "no") { | |
if (installWindowBlindsTrue === "yes") { | |
if (windowBlindCount === "not sure") { | |
windowBlindCount = approxWindowCount; | |
} | |
else { | |
windowBlindCount = +windowBlindCount; | |
} | |
if (_windowGradeData[windowBlindGrade]) { | |
_windowBlindGradeFactor = _windowGradeData[windowBlindGrade].windowBlindGradeFactor; | |
} else { | |
return alert("Invalid Selection"); | |
} | |
let _totalWindowBlindCost = windowBlindCount * _mediumWindowBlindPrice * _windowBlindGradeFactor; | |
this.windowFinalCost = _totalWindowBlindCost; | |
} | |
} | |
} | |
getTotalCost() { | |
console.log(`Cost for WALL REMOVAL is $ ${this.wallRemovalFinalCost}.`) | |
} | |
} | |
let kitchenCalculator = new KitchenRenovationCalculator(); | |
kitchenCalculator.setKitchenFloorLevel('main level') | |
console.log('Level name: ' + kitchenCalculator.floorLevelName) | |
kitchenCalculator.setHouseBuiltYear(1950) | |
console.log('Year Built Factor: ' + kitchenCalculator.yearBuiltFactor) | |
kitchenCalculator.setIncludeDining(true) | |
kitchenCalculator.setDiningRoomSize(notSure = true, size = null, relativeSize = 'Average') | |
console.log('Dining Room Size: ' + kitchenCalculator.diningSizeSF) | |
kitchenCalculator.setKitchenSize(notSure = true, size = null, relativeSize = 'Average') | |
console.log('Kitchen Size: ' + kitchenCalculator.kitchenSizeSF + ' SF') | |
console.log('Room Wall Factor: ' + kitchenCalculator.calculeRoomWallFactor()) | |
kitchenCalculator.setCeilingHeight(notSure = true, ceilingHeight = null) | |
console.log('Ceiling Height: ' + kitchenCalculator.ceilingHeight) | |
kitchenCalculator.setIsCeilingVaulted(isVaulted = true) | |
kitchenCalculator.setWallRemoval(removeWallTrue = 'yes', loadBearingTrue = 'yes', floorAboveTrue = 'yes', removeChimneyTrue = 'no', brickChimneyTrue = 'not sure'); | |
kitchenCalculator.setLayout(removeWallTrue = 'yes', changeKitchenLayoutTrue = 'yes', relocateKitchenElectricalTrue = 'yes', relocateKitchenPlumbingTrue = 'yes'); | |
console.log('Layout Cost: ' + kitchenCalculator.changeKitchenLayoutFinalCost) | |
kitchenCalculator.setPentry(containsPantryTrue = 'yes', pantryPreExistingTrue = 'yes', pantryLocation = 'Other', pantrySize = 'Average', pantryType = 'Walk-in'); | |
console.log('Pentry Cost: ' + kitchenCalculator.constructNewPantryFinalCost); | |
kitchenCalculator.setWindow(replaceWindowsTrue = 'yes', windowGrade = 'Gold', windowBlindGrade = 'Platinum', newWindowOpeningTrue = 'yes', | |
installWindowBlindsTrue = 'yes' , windowBlindCount = 1, smallWindowCount = 1, mediumWindowCount = 1, largeWindowCount = 1, newWindowOpeningCount = 1); | |
console.log('Window Cost: ' + kitchenCalculator.windowFinalCost); | |
console.log(kitchenCalculator.getTotalCost()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment