Refactor inventory schemas to remove redundant stock event calculations
- Removed the `getStockEventTotal` function and associated `recalculate` methods from filamentStock, partStock, and productStock schemas to streamline code and reduce redundancy. - Updated stockEvent schema to include a new `recalculate` method that centralizes stock recalculation logic for improved maintainability. - Enhanced the stockEvent schema with additional utility functions for building update data and recalculating parent stock based on events.
This commit is contained in:
parent
0b39eef045
commit
67f929e369
@ -1,26 +1,7 @@
|
||||
import mongoose from 'mongoose';
|
||||
import { generateId } from '../../utils.js';
|
||||
const { Schema } = mongoose;
|
||||
import { aggregateRollups, aggregateRollupsHistory, editObject } 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,
|
||||
};
|
||||
};
|
||||
import { aggregateRollups, aggregateRollupsHistory } from '../../database.js';
|
||||
|
||||
// Define the main filamentStock schema
|
||||
const filamentStockSchema = new Schema(
|
||||
@ -91,29 +72,6 @@ filamentStockSchema.statics.history = async function (from, to) {
|
||||
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
|
||||
filamentStockSchema.virtual('id').get(function () {
|
||||
return this._id;
|
||||
|
||||
@ -1,26 +1,7 @@
|
||||
import mongoose from 'mongoose';
|
||||
import { generateId } from '../../utils.js';
|
||||
const { Schema } = mongoose;
|
||||
import { aggregateRollups, aggregateRollupsHistory, editObject } 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,
|
||||
};
|
||||
};
|
||||
import { aggregateRollups, aggregateRollupsHistory } from '../../database.js';
|
||||
|
||||
// Define the main partStock schema
|
||||
const partStockSchema = new Schema(
|
||||
@ -74,21 +55,6 @@ partStockSchema.statics.history = async function (from, to) {
|
||||
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
|
||||
partStockSchema.virtual('id').get(function () {
|
||||
return this._id;
|
||||
|
||||
@ -1,26 +1,7 @@
|
||||
import mongoose from 'mongoose';
|
||||
import { generateId } from '../../utils.js';
|
||||
const { Schema } = mongoose;
|
||||
import { aggregateRollups, aggregateRollupsHistory, editObject } 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,
|
||||
};
|
||||
};
|
||||
import { aggregateRollups, aggregateRollupsHistory } from '../../database.js';
|
||||
|
||||
const partStockUsageSchema = new Schema({
|
||||
partStock: { type: Schema.Types.ObjectId, ref: 'partStock', required: false },
|
||||
@ -89,21 +70,6 @@ productStockSchema.statics.history = async function (from, to) {
|
||||
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
|
||||
productStockSchema.virtual('id').get(function () {
|
||||
return this._id;
|
||||
|
||||
@ -1,7 +1,85 @@
|
||||
import mongoose from 'mongoose';
|
||||
import { generateId } from '../../utils.js';
|
||||
import { getObject, editObject } from '../../database.js';
|
||||
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(
|
||||
{
|
||||
_reference: { type: String, default: () => generateId()() },
|
||||
@ -34,6 +112,12 @@ const stockEventSchema = new Schema(
|
||||
|
||||
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
|
||||
stockEventSchema.virtual('id').get(function () {
|
||||
return this._id;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user