Updated log level in config.json to 'trace' for more detailed logging. Refactored inventory schemas by removing redundant stock event calculation functions and integrating stock event recalculation logic into the stockevent schema, enhancing overall data management and performance.

This commit is contained in:
Tom Butcher 2026-07-26 16:10:31 +01:00
parent 8423db2858
commit 9a22fd6452
5 changed files with 88 additions and 114 deletions

View File

@ -2,7 +2,7 @@
"development": { "development": {
"server": { "server": {
"port": 8787, "port": 8787,
"logLevel": "debug" "logLevel": "trace"
}, },
"auth": { "auth": {
"enabled": true, "enabled": true,

View File

@ -1,26 +1,7 @@
import mongoose from 'mongoose'; import mongoose from 'mongoose';
import { generateId } from '../../utils.js'; import { generateId } from '../../utils.js';
const { Schema } = mongoose; const { Schema } = mongoose;
import { aggregateRollups, aggregateRollupsHistory, editObject } from '../../database.js'; import { aggregateRollups, aggregateRollupsHistory } from '../../database.js';
import { stockEventModel } from './stockevent.schema.js';
const getStockEventTotal = async (stock, parentType) => {
const stockId = stock?._id;
if (!stockId) return null;
const parentId =
stockId instanceof mongoose.Types.ObjectId ? stockId : new mongoose.Types.ObjectId(stockId);
const [result] = await stockEventModel.aggregate([
{ $match: { parent: parentId, parentType } },
{ $group: { _id: null, total: { $sum: '$value' }, count: { $sum: 1 } } },
]);
return {
total: result?.total ?? 0,
count: result?.count ?? 0,
};
};
// Define the main filamentStock schema // Define the main filamentStock schema
const filamentStockSchema = new Schema( const filamentStockSchema = new Schema(
@ -91,29 +72,6 @@ filamentStockSchema.statics.history = async function (from, to) {
return results; return results;
}; };
filamentStockSchema.statics.recalculate = async function (filamentStock, user) {
const events = await getStockEventTotal(filamentStock, this.modelName);
if (!events?.count) return;
const net = events.total;
const startingNet = filamentStock.startingWeight?.net ?? 0;
const startingGross = filamentStock.startingWeight?.gross ?? 0;
const gross = startingNet > 0 ? (startingGross * net) / startingNet : net;
await editObject({
model: this,
id: filamentStock._id,
updateData: {
currentWeight: {
net,
gross,
},
},
user,
recalculate: false,
});
};
// Add virtual id getter // Add virtual id getter
filamentStockSchema.virtual('id').get(function () { filamentStockSchema.virtual('id').get(function () {
return this._id; return this._id;

View File

@ -1,26 +1,7 @@
import mongoose from 'mongoose'; import mongoose from 'mongoose';
import { generateId } from '../../utils.js'; import { generateId } from '../../utils.js';
const { Schema } = mongoose; const { Schema } = mongoose;
import { aggregateRollups, aggregateRollupsHistory, editObject } from '../../database.js'; import { aggregateRollups, aggregateRollupsHistory } from '../../database.js';
import { stockEventModel } from './stockevent.schema.js';
const getStockEventTotal = async (stock, parentType) => {
const stockId = stock?._id;
if (!stockId) return null;
const parentId =
stockId instanceof mongoose.Types.ObjectId ? stockId : new mongoose.Types.ObjectId(stockId);
const [result] = await stockEventModel.aggregate([
{ $match: { parent: parentId, parentType } },
{ $group: { _id: null, total: { $sum: '$value' }, count: { $sum: 1 } } },
]);
return {
total: result?.total ?? 0,
count: result?.count ?? 0,
};
};
// Define the main partStock schema // Define the main partStock schema
const partStockSchema = new Schema( const partStockSchema = new Schema(
@ -74,21 +55,6 @@ partStockSchema.statics.history = async function (from, to) {
return results; return results;
}; };
partStockSchema.statics.recalculate = async function (partStock, user) {
const events = await getStockEventTotal(partStock, this.modelName);
if (!events?.count) return;
await editObject({
model: this,
id: partStock._id,
updateData: {
currentQuantity: events.total,
},
user,
recalculate: false,
});
};
// Add virtual id getter // Add virtual id getter
partStockSchema.virtual('id').get(function () { partStockSchema.virtual('id').get(function () {
return this._id; return this._id;

View File

@ -1,26 +1,7 @@
import mongoose from 'mongoose'; import mongoose from 'mongoose';
import { generateId } from '../../utils.js'; import { generateId } from '../../utils.js';
const { Schema } = mongoose; const { Schema } = mongoose;
import { aggregateRollups, aggregateRollupsHistory, editObject } from '../../database.js'; import { aggregateRollups, aggregateRollupsHistory } from '../../database.js';
import { stockEventModel } from './stockevent.schema.js';
const getStockEventTotal = async (stock, parentType) => {
const stockId = stock?._id;
if (!stockId) return null;
const parentId =
stockId instanceof mongoose.Types.ObjectId ? stockId : new mongoose.Types.ObjectId(stockId);
const [result] = await stockEventModel.aggregate([
{ $match: { parent: parentId, parentType } },
{ $group: { _id: null, total: { $sum: '$value' }, count: { $sum: 1 } } },
]);
return {
total: result?.total ?? 0,
count: result?.count ?? 0,
};
};
const partStockUsageSchema = new Schema({ const partStockUsageSchema = new Schema({
partStock: { type: Schema.Types.ObjectId, ref: 'partStock', required: false }, partStock: { type: Schema.Types.ObjectId, ref: 'partStock', required: false },
@ -89,21 +70,6 @@ productStockSchema.statics.history = async function (from, to) {
return results; return results;
}; };
productStockSchema.statics.recalculate = async function (productStock, user) {
const events = await getStockEventTotal(productStock, this.modelName);
if (!events?.count) return;
await editObject({
model: this,
id: productStock._id,
updateData: {
currentQuantity: events.total,
},
user,
recalculate: false,
});
};
// Add virtual id getter // Add virtual id getter
productStockSchema.virtual('id').get(function () { productStockSchema.virtual('id').get(function () {
return this._id; return this._id;

View File

@ -1,7 +1,85 @@
import mongoose from 'mongoose'; import mongoose from 'mongoose';
import { generateId } from '../../utils.js'; import { generateId } from '../../utils.js';
import { getObject, editObject } from '../../database.js';
const { Schema } = mongoose; const { Schema } = mongoose;
const parentStockModelNames = {
filamentStock: 'filamentStock',
partStock: 'partStock',
productStock: 'productStock',
};
const initialStockStates = {
filamentStock: 'unconsumed',
partStock: 'new',
};
const getStockEventTotal = async (parentId, parentType) => {
if (!parentId) return null;
const objectId =
parentId instanceof mongoose.Types.ObjectId ? parentId : new mongoose.Types.ObjectId(parentId);
const [result] = await mongoose.model('stockEvent').aggregate([
{ $match: { parent: objectId, parentType } },
{ $group: { _id: null, total: { $sum: '$value' }, count: { $sum: 1 } } },
]);
return {
total: result?.total ?? 0,
count: result?.count ?? 0,
};
};
const buildParentUpdateData = (parentType, parentStock, events) => {
const updateData = {};
if (parentType === 'filamentStock') {
const net = events.total;
const startingNet = parentStock.startingWeight?.net ?? 0;
const startingGross = parentStock.startingWeight?.gross ?? 0;
const gross = startingNet > 0 ? (startingGross * net) / startingNet : net;
updateData.currentWeight = { net, gross };
} else {
updateData.currentQuantity = events.total;
}
if (parentStock.state?.type !== 'draft') {
const initialState = initialStockStates[parentType];
if (initialState && parentStock.state?.type === initialState) {
updateData.state = { ...parentStock.state, type: 'used' };
}
}
return updateData;
};
const recalculateParentStock = async (parentType, parentId, user) => {
if (!parentType || !parentId) return;
const modelName = parentStockModelNames[parentType];
if (!modelName) return;
const parentModel = mongoose.model(modelName);
const parentStock = await getObject({
model: parentModel,
id: parentId,
cached: true,
});
if (!parentStock || parentStock.error) return;
const events = await getStockEventTotal(parentId, parentType);
if (!events?.count) return;
await editObject({
model: parentModel,
id: parentStock._id,
updateData: buildParentUpdateData(parentType, parentStock, events),
user,
recalculate: false,
});
};
const stockEventSchema = new Schema( const stockEventSchema = new Schema(
{ {
_reference: { type: String, default: () => generateId()() }, _reference: { type: String, default: () => generateId()() },
@ -34,6 +112,12 @@ const stockEventSchema = new Schema(
stockEventSchema.index({ parentType: 'text', ownerType: 'text', unit: 'text' }); stockEventSchema.index({ parentType: 'text', ownerType: 'text', unit: 'text' });
stockEventSchema.statics.recalculate = async function (stockEvent, user) {
const parentType = stockEvent.parentType;
const parentId = stockEvent.parent?._id || stockEvent.parent;
await recalculateParentStock(parentType, parentId, user);
};
// Add virtual id getter // Add virtual id getter
stockEventSchema.virtual('id').get(function () { stockEventSchema.virtual('id').get(function () {
return this._id; return this._id;