import { validationResult } from 'express-validator' import { Building, Management, Simulation, User } from '../db/index.js' import { getUserFromRequest, success, warning } from '../helpers/index.js' import { executeSimulation, getInformation } from '../services/external.js' import { ResponseCode } from '../ENUMS.js' export const createBuilding = async (req, res) => { const validationErrors = validationResult(req) if (!validationErrors.isEmpty()) { return warning(res, { code: ResponseCode.ValidationError }) } const { accessor } = getUserFromRequest(req) const { buildingAddress, buildingGmlId, buildingName, buildingPrefix } = req.body const mgmt = await Management.findOne() if (mgmt.prefixList.indexOf(buildingPrefix) !== -1) { return warning(res, { code: ResponseCode.PrefixUnavailable }) } await mgmt.prefixList.push(buildingPrefix) await mgmt.save() const result = await Building.create({ prefix: buildingPrefix, name: buildingName, address: buildingAddress, gmlid: buildingGmlId || null, owner: accessor }) if (result) { const user = await User.findById(accessor) user.ofBuilding = result._id user.save() return success(res, { code: ResponseCode.Created, id: result._id }) } warning(res, { code: ResponseCode.NotCreated }) } export const getApartments = async (req, res) => { const validationErrors = validationResult(req) if (!validationErrors.isEmpty()) { return warning(res, { code: ResponseCode.ValidationError }) } const { id } = req.params const result = await Building.findOne({ _id: id }).select('apartments.name apartments.image apartments.linkedTo apartments.owner') if (result) { return success(res, { data: result.apartments }) } warning(res, { code: ResponseCode.NotFound }) } export const getBuilding = async (req, res) => { const validationErrors = validationResult(req) if (!validationErrors.isEmpty()) { return warning(res, { code: ResponseCode.ValidationError }) } const { accessor, role } = getUserFromRequest(req) const { id } = req.params let result if (role === 'administrator') { result = await Building.findOne({ _id: id, owner: accessor }).select('_id name address data apartments gmlid prefix createdAt') } else { result = await Building.findOne({ _id: id, 'apartments.owner': accessor }).select('_id name address data apartments gmlid prefix createdAt') } if (result) { return success(res, { data: result }) } warning(res, { code: ResponseCode.NotFound }) } export const getBuildings = async (req, res) => { const { accessor } = getUserFromRequest(req) const result = await Building.find({ owner: accessor }).select('_id name address data apartments gmlid setupCompleted prefix createdAt') if (result) { return success(res, { data: result }) } warning(res, { code: ResponseCode.NotFound }) } export const getSimulation = async (req, res) => { const { id } = req.params const { gmlId } = req.query const building = await Building.findById(id) if (building) { const simulationId = gmlId || building.gmlId if (gmlId) { await Building.findByIdAndUpdate({ _id: building._id }, { gmlId }) } if (simulationId) { const prefetched = await getInformation(simulationId) // DEVINFO Hier könnte das Object für ein Request an die CS-T-API verändert werden. // Wenn keine GML-Id in der Datenbank gespeichert wurden, kann über die API eine angefügt werden. // Es wird ein Request zur Abfrage bestehender Information für die ausgewählt GML-Id ausgeführt. // Die entsprechenden Object-Keys werden im Standard-Request-Body durch die neuen Daten ersetzt // Request 1: /api/v1/buildings//simulations/run // Request 2: /api/v1/buildings//simulations/run?gmlId= // Example Id: DENW39AL1000nJfc const simData = { gmlId: simulationId, atticType: 'unknown', basementType: 'unknown', comparisonRenovationType: 'no', existingModuleArea: '0', existingModuleEfficiency: '15', renovationType: 'no', roofType: 'unknown', simulateModuleEfficiency: '15', typeOfEnergy: 'unknown', yearOfConstruction: '2000', ...prefetched } const simResult = await executeSimulation(simData) if (simResult) { const { successful, errorMessage, ...rest } = simResult await Simulation.create({ buildingId: id, gmlId: simulationId, prefetched, result: rest }) return success(res, { data: { successful, errorMessage, prefetched, result: rest } }) } return warning(res, { code: ResponseCode.InvalidInput }) } return warning(res, { code: ResponseCode.MissingParameter }) } warning(res, { code: ResponseCode.NotFound }) } export const getUsers = async (req, res) => { const { id } = req.params const result = await User.find({ linkedTo: id }).select('_id username') if (result) { return success(res, { data: result }) } warning(res, { code: ResponseCode.UserNotFound }) } export const updateBuilding = async (req, res) => { const { id } = req.params const { buildingAddress, gmlid, buildingName, buildingPrefix } = req.body const building = await Building.findById(id) if (building) { const updateQuery = { address: buildingAddress, gmlid, name: buildingName, updatedAt: Date.now() } if (building.prefix === null && !building.setupCompleted) { const mgmt = await Management.findOne() if (mgmt.prefixList.indexOf(buildingPrefix) !== -1) { return warning(res, { code: ResponseCode.PrefixUnavailable }, 200) } updateQuery.prefix = buildingPrefix updateQuery.setupCompleted = true await mgmt.prefixList.push(buildingPrefix) await mgmt.save() } const result = await Building.findByIdAndUpdate(building._id, updateQuery, { new: true, runValidators: true }) if (result) { return success(res, { data: result }) } } warning(res, { code: ResponseCode.NotFound }) } export const updateBuildingDataBasement = async (req, res) => { const validationErrors = validationResult(req) if (!validationErrors.isEmpty()) { return warning(res, { code: ResponseCode.ValidationError }) } const { id } = req.params const { basementInsulatingMaterial, basementInsulatingMaterialThickness, basementRefurbishmentComment, heatedBasement, insulatedBasementCeiling, insulatedBasementFloor } = req.body const result = await Building.findByIdAndUpdate(id, { $set: { updatedAt: Date.now(), 'data.basementInsulatingMaterial': basementInsulatingMaterial, 'data.basementInsulatingMaterialThickness': basementInsulatingMaterialThickness, 'data.basementRefurbishmentComment': basementRefurbishmentComment, 'data.heatedBasement': heatedBasement, 'data.insulatedBasementCeiling': insulatedBasementCeiling, 'data.insulatedBasementFloor': insulatedBasementFloor } }, { new: true, runValidators: true }) .select([ 'data.basementInsulatingMaterial', 'data.basementInsulatingMaterialThickness', 'data.basementRefurbishmentComment', 'data.heatedBasement', 'data.insulatedBasementCeiling', 'data.insulatedBasementFloor' ]) if (result) { return success(res, { code: ResponseCode.UpdateSuccess, data: result.data }) } warning(res, { code: ResponseCode.NotFound }) } export const updateBuildingDataCharacteristics = async (req, res) => { const validationErrors = validationResult(req) if (!validationErrors.isEmpty()) { return warning(res, { code: ResponseCode.ValidationError }) } const { id } = req.params const { characteristicsComment, energyPerformanceCertificate, listedBuilding, livingSpace, numberOfFloors, yearOfConstruction } = req.body const result = await Building.findByIdAndUpdate(id, { $set: { updatedAt: Date.now(), 'data.characteristicsComment': characteristicsComment, 'data.energyPerformanceCertificate': energyPerformanceCertificate, 'data.listedBuilding': listedBuilding, 'data.livingSpace': livingSpace, 'data.numberOfFloors': numberOfFloors, 'data.yearOfConstruction': yearOfConstruction } }, { new: true, runValidators: true }) .select([ 'data.characteristicsComment', 'data.energyPerformanceCertificate', 'data.listedBuilding', 'data.livingSpace', 'data.numberOfFloors', 'data.yearOfConstruction' ]) if (result) { return success(res, { code: ResponseCode.UpdateSuccess, data: result.data }) } warning(res, { code: ResponseCode.NotFound }) } export const updateBuildingDataFacade = async (req, res) => { const validationErrors = validationResult(req) if (!validationErrors.isEmpty()) { return warning(res, { code: ResponseCode.ValidationError }) } const { id } = req.params const { buildingStructure, buildingStructureThickness, facadeInsulatingMaterial, facadeInsulatingMaterialThickness, facadeEast, facadeNorth, facadeRefurbishmentComment, facadeSouth, facadeWest } = req.body const result = await Building.findByIdAndUpdate(id, { $set: { updatedAt: Date.now(), 'data.buildingStructure': buildingStructure, 'data.buildingStructureThickness': buildingStructureThickness, 'data.facadeInsulatingMaterial': facadeInsulatingMaterial, 'data.facadeInsulatingMaterialThickness': facadeInsulatingMaterialThickness, 'data.facadeEast': facadeEast, 'data.facadeNorth': facadeNorth, 'data.facadeRefurbishmentComment': facadeRefurbishmentComment, 'data.facadeSouth': facadeSouth, 'data.facadeWest': facadeWest } }, { new: true, runValidators: true }) .select([ 'data.buildingStructure', 'data.buildingStructureThickness', 'data.facadeInsulatingMaterial', 'data.facadeInsulatingMaterialThickness', 'data.facadeEast', 'data.facadeNorth', 'data.facadeRefurbishmentComment', 'data.facadeSouth', 'data.facadeWest' ]) if (result) { return success(res, { code: ResponseCode.UpdateSuccess, data: result.data }) } warning(res, { code: ResponseCode.NotFound }) } export const updateBuildingDataHeating = async (req, res) => { const validationErrors = validationResult(req) if (!validationErrors.isEmpty()) { return warning(res, { code: ResponseCode.ValidationError }) } const { id } = req.params const { heatingConsumption, heatingInstallation, heatingInstallationComment, photovoltaic, photovoltaicArea, photovoltaicYield, pipeSystem, selfContainedCentralHeating, solarHeat, solarHeatArea } = req.body const result = await Building.findByIdAndUpdate(id, { $set: { updatedAt: Date.now(), 'data.heatingConsumption': heatingConsumption, 'data.heatingInstallation': heatingInstallation, 'data.heatingInstallationComment': heatingInstallationComment, 'data.photovoltaic': photovoltaic, 'data.photovoltaicArea': photovoltaicArea, 'data.photovoltaicYield': photovoltaicYield, 'data.pipeSystem': pipeSystem, 'data.selfContainedCentralHeating': selfContainedCentralHeating, 'data.solarHeat': solarHeat, 'data.solarHeatArea': solarHeatArea } }, { new: true, runValidators: true }) .select([ 'data.heatingConsumption', 'data.heatingInstallation', 'data.heatingInstallationComment', 'data.photovoltaic', 'data.photovoltaicArea', 'data.photovoltaicYield', 'data.pipeSystem', 'data.selfContainedCentralHeating', 'data.solarHeat', 'data.solarHeatArea' ]) if (result) { return success(res, { code: ResponseCode.UpdateSuccess, data: result.data }) } warning(res, { code: ResponseCode.NotFound }) } export const updateBuildingDataRoof = async (req, res) => { const { id } = req.params const { clouding, flatRoof, heatedAttic, roofArea, roofInsulatingMaterial, roofInsulatingMaterialThickness, roofRefurbishmentComment } = req.body const result = await Building.findByIdAndUpdate(id, { $set: { updatedAt: Date.now(), 'data.clouding': clouding, 'data.flatRoof': flatRoof, 'data.heatedAttic': heatedAttic, 'data.roofArea': roofArea, 'data.roofInsulatingMaterial': roofInsulatingMaterial, 'data.roofInsulatingMaterialThickness': roofInsulatingMaterialThickness, 'data.roofRefurbishmentComment': roofRefurbishmentComment } }, { new: true, runValidators: true }) .select([ 'data.clouding', 'data.flatRoof', 'data.heatedAttic', 'data.roofArea', 'data.roofInsulatingMaterial', 'data.roofInsulatingMaterialThickness', 'data.roofRefurbishmentComment' ]) if (result) { return success(res, { code: ResponseCode.UpdateSuccess, data: result.data }) } warning(res, { code: ResponseCode.NotFound }) }