import config from '../../config.js'; import { filamentProfileModel } from '../../database/schemas/production/filamentprofile.schema.js'; import log4js from 'log4js'; import mongoose from 'mongoose'; import { deleteObject, editObject, getObject, listObjects, listObjectsByProperties, newObject, searchObjects, } from '../../database/database.js'; const logger = log4js.getLogger('FilamentProfiles'); logger.level = config.server.logLevel; const FILAMENT_PROFILE_POPULATE = ['filament', 'compatiblePrinters']; export const filamentProfileFields = [ 'name', 'filamentType', 'filament', 'filamentIsSupport', 'filamentSoluble', 'filamentPrintable', 'filamentAdhesivenessCategory', 'temperatureVitrification', 'idleTemperature', 'pelletFlowCoefficient', 'requiredNozzleHrc', 'filamentFlowRatio', 'enablePressureAdvance', 'pressureAdvance', 'adaptivePressureAdvance', 'adaptivePressureAdvanceBridges', 'adaptivePressureAdvanceOverhangs', 'adaptivePressureAdvanceModel', 'activateChamberTempControl', 'chamberTemperature', 'chamberMinimalTemperature', 'nozzleTemperatureInitialLayer', 'nozzleTemperature', 'nozzleTemperatureRangeLow', 'nozzleTemperatureRangeHigh', 'hotPlateTempInitialLayer', 'hotPlateTemp', 'coolPlateTempInitialLayer', 'coolPlateTemp', 'engPlateTempInitialLayer', 'engPlateTemp', 'texturedPlateTempInitialLayer', 'texturedPlateTemp', 'texturedCoolPlateTempInitialLayer', 'texturedCoolPlateTemp', 'supertackPlateTempInitialLayer', 'supertackPlateTemp', 'filamentAdaptiveVolumetricSpeed', 'filamentMaxVolumetricSpeed', 'volumetricSpeedCoefficients', 'closeFanTheFirstXLayers', 'fullFanSpeedLayer', 'fanMinSpeed', 'fanMaxSpeed', 'reduceFanStopStartFreq', 'slowDownForLayerCooling', 'dontSlowDownOuterWall', 'slowDownMinSpeed', 'slowDownLayerTime', 'fanCoolingLayerTime', 'enableOverhangBridgeFan', 'overhangFanThreshold', 'overhangFanSpeed', 'internalBridgeFanSpeed', 'supportMaterialInterfaceFanSpeed', 'ironingFanSpeed', 'initialLayerFanSpeed', 'firstXLayerFanSpeed', 'additionalCoolingFanSpeed', 'additionalFanFullSpeedLayer', 'closeAdditionalFanFirstXLayers', 'activateAirFiltration', 'activateAirFiltrationDuringPrint', 'activateAirFiltrationOnCompletion', 'duringPrintExhaustFanSpeed', 'completePrintExhaustFanSpeed', 'filamentRetractionLength', 'filamentRetractionSpeed', 'filamentDeretractionSpeed', 'filamentRetractionMinimumTravel', 'filamentRetractWhenChangingLayer', 'filamentRetractBeforeWipe', 'filamentRetractAfterWipe', 'filamentRetractRestartExtra', 'filamentRetractLiftAbove', 'filamentRetractLiftBelow', 'filamentRetractLiftEnforce', 'filamentWipe', 'filamentWipeDistance', 'filamentZHop', 'filamentZHopTypes', 'filamentLongRetractionsWhenCut', 'filamentRetractionDistancesWhenCut', 'longRetractionsWhenEc', 'retractionDistancesWhenEc', 'filamentLoadingSpeed', 'filamentLoadingSpeedStart', 'filamentUnloadingSpeed', 'filamentUnloadingSpeedStart', 'filamentChangeLength', 'filamentChangeLengthNc', 'filamentToolchangeDelay', 'filamentExtruderCompatibility', 'filamentExtruderVariant', 'filamentMultitoolRamming', 'filamentMultitoolRammingFlow', 'filamentMultitoolRammingVolume', 'filamentRammingParameters', 'filamentRammingTravelTime', 'filamentRammingTravelTimeNc', 'filamentRammingVolumetricSpeed', 'filamentRammingVolumetricSpeedNc', 'filamentMinimalPurgeOnWipeTower', 'filamentTowerInterfacePreExtrusionDist', 'filamentTowerInterfacePreExtrusionLength', 'filamentTowerInterfacePrintTemp', 'filamentTowerInterfacePurgeVolume', 'filamentTowerIroningArea', 'filamentCoolingBeforeTower', 'filamentCoolingInitialSpeed', 'filamentCoolingFinalSpeed', 'filamentCoolingMoves', 'filamentFlushTemp', 'filamentFlushTempFast', 'filamentFlushVolumetricSpeed', 'filamentPreCoolingTemperature', 'filamentPreCoolingTemperatureNc', 'filamentPreheatTemperatureDelta', 'filamentPrimeVolumeNc', 'filamentRetractLengthNc', 'filamentStampingDistance', 'filamentStampingLoadingSpeed', 'filamentStartGcode', 'filamentEndGcode', 'filamentChangeExtrusionRoleGcode', 'filamentShrink', 'filamentShrinkageCompensationZ', 'filamentDevAmsDryingTemperature', 'filamentDevAmsDryingTime', 'filamentDevAmsDryingHeatDistortionTemperature', 'filamentDevAmsDryingAmsLimitations', 'filamentDevChamberDryingBedTemperature', 'filamentDevChamberDryingTime', 'filamentDevDryingCoolingTemperature', 'filamentDevDryingSofteningTemperature', 'compatiblePrinters', 'compatiblePrintersCondition', 'compatiblePrints', 'compatiblePrintsCondition', 'filamentNotes', ]; const pickFilamentProfileFields = (body = {}) => Object.fromEntries( filamentProfileFields .filter((field) => Object.hasOwn(body, field)) .map((field) => [field, body[field]]) ); export const listFilamentProfilesRouteHandler = async ( req, res, page = 1, limit = 25, property = '', filter = {}, search = '', sort = '', order = 'ascend' ) => { const result = await listObjects({ model: filamentProfileModel, page, limit, property, filter, search, sort, order, populate: FILAMENT_PROFILE_POPULATE, }); if (result?.error) { logger.error('Error listing filament profiles.'); return res.status(result.code).send(result); } logger.debug(`List of filament profiles (Page ${page}, Limit ${limit}). Count: ${result.length}`); res.send(result); }; export const listFilamentProfilesByPropertiesRouteHandler = async ( req, res, properties = [], filter = {} ) => { const result = await listObjectsByProperties({ model: filamentProfileModel, properties, filter, populate: FILAMENT_PROFILE_POPULATE, }); if (result?.error) { logger.error('Error listing filament profiles.'); return res.status(result.code).send(result); } logger.debug(`List of filament profiles. Count: ${result.length}`); res.send(result); }; export const searchFilamentProfilesRouteHandler = async (req, res, search) => { const result = await searchObjects({ model: filamentProfileModel, search, }); res.send(result); }; export const getFilamentProfileRouteHandler = async (req, res) => { const id = req.params.id; const result = await getObject({ model: filamentProfileModel, id, populate: FILAMENT_PROFILE_POPULATE, }); if (result?.error) { logger.warn('Filament profile not found with supplied id.'); return res.status(result.code).send(result); } logger.debug(`Retrieved filament profile with ID: ${id}`); res.send(result); }; export const editFilamentProfileRouteHandler = async (req, res) => { const id = new mongoose.Types.ObjectId(req.params.id); const updateData = { updatedAt: new Date(), ...pickFilamentProfileFields(req.body), }; const result = await editObject({ model: filamentProfileModel, id, updateData, user: req.user, }); if (result?.error) { logger.error('Error editing filament profile:', result.error); return res.status(result.code).send(result); } logger.debug(`Edited filament profile with ID: ${id}`); res.send(result); }; export const newFilamentProfileRouteHandler = async (req, res) => { const newData = { ...pickFilamentProfileFields(req.body), }; const result = await newObject({ model: filamentProfileModel, newData, user: req.user, }); if (result?.error) { logger.error('No filament profile created:', result.error); return res.status(result.code).send(result); } logger.debug(`New filament profile with ID: ${result._id}`); res.send(result); }; export const deleteFilamentProfileRouteHandler = async (req, res) => { const id = new mongoose.Types.ObjectId(req.params.id); const result = await deleteObject({ model: filamentProfileModel, id, user: req.user, }); if (result?.error) { logger.error('No filament profile deleted:', result.error); return res.status(result.code).send(result); } logger.debug(`Deleted filament profile with ID: ${result._id}`); res.send(result); };