From 92e07c97d79cf68f26f21f073edfd393b33f495b Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Sun, 17 May 2026 19:11:29 +0100 Subject: [PATCH] Numerious fixes. --- .../schemas/inventory/filamentstock.schema.js | 8 ++++++++ .../schemas/production/gcodefile.schema.js | 8 ++++++++ src/routes/inventory/filamentstocks.js | 4 +++- src/routes/production/gcodefiles.js | 4 ++-- src/services/inventory/filamentstocks.js | 15 ++++++++++++--- src/services/inventory/stocktransfers.js | 1 + src/services/misc/export.js | 3 ++- src/services/production/gcodefiles.js | 8 +++++--- 8 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/database/schemas/inventory/filamentstock.schema.js b/src/database/schemas/inventory/filamentstock.schema.js index 67938a6..e9743fa 100644 --- a/src/database/schemas/inventory/filamentstock.schema.js +++ b/src/database/schemas/inventory/filamentstock.schema.js @@ -19,6 +19,7 @@ const filamentStockSchema = new Schema( net: { type: Number, required: true }, gross: { type: Number, required: true }, }, + filament: { type: mongoose.Schema.Types.ObjectId, ref: 'filament', required: true }, filamentSku: { type: mongoose.Schema.Types.ObjectId, ref: 'filamentSku', required: true }, stockLocation: { type: mongoose.Schema.Types.ObjectId, @@ -29,6 +30,13 @@ const filamentStockSchema = new Schema( { timestamps: true } ); +filamentStockSchema.pre('validate', async function () { + if (!this.filament && this.filamentSku) { + const sku = await mongoose.model('filamentSku').findById(this.filamentSku).select('filament').lean(); + if (sku?.filament) this.filament = sku.filament; + } +}); + const rollupConfigs = [ { name: 'totalCurrentWeight', diff --git a/src/database/schemas/production/gcodefile.schema.js b/src/database/schemas/production/gcodefile.schema.js index c2776ce..acd137b 100644 --- a/src/database/schemas/production/gcodefile.schema.js +++ b/src/database/schemas/production/gcodefile.schema.js @@ -14,6 +14,7 @@ const gcodeFileSchema = new mongoose.Schema( name: { required: true, type: String }, gcodeFileName: { required: false, type: String }, size: { type: Number, required: false }, + filament: { type: Schema.Types.ObjectId, ref: 'filament', required: true }, filamentSku: { type: Schema.Types.ObjectId, ref: 'filamentSku', required: true }, parts: [partSchema], file: { type: mongoose.SchemaTypes.ObjectId, ref: 'file', required: false }, @@ -22,6 +23,13 @@ const gcodeFileSchema = new mongoose.Schema( { timestamps: true } ); +gcodeFileSchema.pre('validate', async function () { + if (!this.filament && this.filamentSku) { + const sku = await mongoose.model('filamentSku').findById(this.filamentSku).select('filament').lean(); + if (sku?.filament) this.filament = sku.filament; + } +}); + gcodeFileSchema.index({ name: 'text', brand: 'text' }); gcodeFileSchema.virtual('id').get(function () { diff --git a/src/routes/inventory/filamentstocks.js b/src/routes/inventory/filamentstocks.js index f506241..6a59519 100644 --- a/src/routes/inventory/filamentstocks.js +++ b/src/routes/inventory/filamentstocks.js @@ -19,6 +19,8 @@ import { router.get('/', isAuthenticated, (req, res) => { const { page, limit, property, search, sort, order } = req.query; const allowedFilters = [ + 'filament', + 'filament._id', 'filamentSku', 'state', 'startingWeight', @@ -33,7 +35,7 @@ router.get('/', isAuthenticated, (req, res) => { router.get('/properties', isAuthenticated, (req, res) => { let properties = convertPropertiesString(req.query.properties); - const allowedFilters = ['filamentSku', 'state.type']; + const allowedFilters = ['filament', 'filament._id', 'filamentSku', 'state.type']; const filter = getFilter(req.query, allowedFilters, false); var masterFilter = {}; if (req.query.masterFilter) { diff --git a/src/routes/production/gcodefiles.js b/src/routes/production/gcodefiles.js index 5fdc821..18040f1 100644 --- a/src/routes/production/gcodefiles.js +++ b/src/routes/production/gcodefiles.js @@ -16,14 +16,14 @@ import { convertPropertiesString, getFilter } from '../../utils.js'; // list of gcodeFiles router.get('/', isAuthenticated, (req, res) => { const { page, limit, property, search, sort, order } = req.query; - const allowedFilters = ['_id', 'name', 'filament._id']; + const allowedFilters = ['_id', 'name', 'filament', 'filament._id', 'filamentSku', 'filamentSku._id']; const filter = getFilter(req.query, allowedFilters); listGCodeFilesRouteHandler(req, res, page, limit, property, filter, search, sort, order); }); router.get('/properties', isAuthenticated, (req, res) => { let properties = convertPropertiesString(req.query.properties); - const allowedFilters = ['filament']; + const allowedFilters = ['filament', 'filament._id', 'filamentSku', 'filamentSku._id']; const filter = getFilter(req.query, allowedFilters, false); listGCodeFilesByPropertiesRouteHandler(req, res, properties, filter); }); diff --git a/src/services/inventory/filamentstocks.js b/src/services/inventory/filamentstocks.js index f96ba10..4b26d3b 100644 --- a/src/services/inventory/filamentstocks.js +++ b/src/services/inventory/filamentstocks.js @@ -36,7 +36,11 @@ export const listFilamentStocksRouteHandler = async ( search, sort, order, - populate: [{ path: 'filamentSku' }, { path: 'stockLocation' }], + populate: [ + { path: 'filament' }, + { path: 'filamentSku', populate: 'filament' }, + { path: 'stockLocation' }, + ], }); if (result?.error) { @@ -60,7 +64,7 @@ export const listFilamentStocksByPropertiesRouteHandler = async ( model: filamentStockModel, properties, filter, - populate: ['filamentSku', 'stockLocation'], + populate: ['filament', { path: 'filamentSku', populate: 'filament' }, 'stockLocation'], masterFilter, }); @@ -79,7 +83,11 @@ export const getFilamentStockRouteHandler = async (req, res) => { const result = await getObject({ model: filamentStockModel, id, - populate: [{ path: 'filamentSku' }, { path: 'stockLocation' }], + populate: [ + { path: 'filament' }, + { path: 'filamentSku', populate: 'filament' }, + { path: 'stockLocation' }, + ], }); if (result?.error) { logger.warn(`Filament Stock not found with supplied id.`); @@ -147,6 +155,7 @@ export const newFilamentStockRouteHandler = async (req, res) => { updatedAt: new Date(), startingWeight: req.body.startingWeight, currentWeight: req.body.currentWeight, + filament: req.body.filament, filamentSku: req.body.filamentSku, state: req.body.state, stockLocation: req.body.stockLocation, diff --git a/src/services/inventory/stocktransfers.js b/src/services/inventory/stocktransfers.js index 5704197..898f49a 100644 --- a/src/services/inventory/stocktransfers.js +++ b/src/services/inventory/stocktransfers.js @@ -88,6 +88,7 @@ async function executePostedLine(transferId, line) { state: src.state, startingWeight: destWeight, currentWeight: destWeight, + filament: src.filament, filamentSku: src.filamentSku, stockLocation: toLocId, }); diff --git a/src/services/misc/export.js b/src/services/misc/export.js index c959276..bb1c504 100644 --- a/src/services/misc/export.js +++ b/src/services/misc/export.js @@ -11,7 +11,8 @@ export const EXPORT_FILTER_BY_TYPE = { printer: ['host'], job: ['printer', 'gcodeFile'], subJob: ['job'], - filamentStock: ['filamentSku'], + filamentStock: ['filament', 'filament._id', 'filamentSku'], + gcodeFile: ['filament', 'filament._id', 'filamentSku'], filament: ['material', 'material._id', 'name', 'diameter', 'cost'], filamentSku: ['filament', 'vendor', 'costTaxRate'], material: ['name', 'tags'], diff --git a/src/services/production/gcodefiles.js b/src/services/production/gcodefiles.js index 0ba99a1..3850365 100644 --- a/src/services/production/gcodefiles.js +++ b/src/services/production/gcodefiles.js @@ -35,7 +35,7 @@ export const listGCodeFilesRouteHandler = async ( search, sort, order, - populate: ['filamentSku'], + populate: ['filament', { path: 'filamentSku', populate: 'filament' }], }); if (result?.error) { @@ -58,7 +58,7 @@ export const listGCodeFilesByPropertiesRouteHandler = async ( model: gcodeFileModel, properties, filter, - populate: 'filamentSku', + populate: ['filament', { path: 'filamentSku', populate: 'filament' }], }); if (result?.error) { @@ -76,7 +76,7 @@ export const getGCodeFileRouteHandler = async (req, res) => { const result = await getObject({ model: gcodeFileModel, id, - populate: ['filamentSku', 'parts.partSku'], + populate: ['filament', { path: 'filamentSku', populate: 'filament' }, 'parts.partSku'], }); if (result?.error) { logger.warn(`GCodeFile not found with supplied id.`); @@ -113,6 +113,7 @@ export const editGCodeFileRouteHandler = async (req, res) => { updatedAt: new Date(), name: req.body.name, file: req.body.file, + filament: req.body.filament, filamentSku: req.body.filamentSku, parts: req.body.parts, }; @@ -140,6 +141,7 @@ export const newGCodeFileRouteHandler = async (req, res) => { updatedAt: new Date(), name: req.body.name, file: req.body.file, + filament: req.body.filament, filamentSku: req.body.filamentSku, parts: req.body.parts, };