Implemented product stocks.
All checks were successful
farmcontrol/farmcontrol-ws/pipeline/head This commit looks good

This commit is contained in:
Tom Butcher 2026-03-07 13:38:19 +00:00
parent bfbcfc3e66
commit a9999f95d0
2 changed files with 67 additions and 2 deletions

View File

@ -0,0 +1,64 @@
import mongoose from 'mongoose';
import { generateId } from '../../utils.js';
const { Schema } = mongoose;
import { aggregateRollups, aggregateRollupsHistory } from '../../database.js';
const partStockUsageSchema = new Schema({
partStock: { type: Schema.Types.ObjectId, ref: 'partStock', required: false },
part: { type: Schema.Types.ObjectId, ref: 'part', required: true },
quantity: { type: Number, required: true },
});
// Define the main productStock schema - tracks assembled products consisting of part stocks
const productStockSchema = new Schema(
{
_reference: { type: String, default: () => generateId()() },
state: {
type: { type: String, required: true },
progress: { type: Number, required: false },
},
product: { type: mongoose.Schema.Types.ObjectId, ref: 'product', required: true },
currentQuantity: { type: Number, required: true },
partStocks: [partStockUsageSchema],
},
{ timestamps: true }
);
const rollupConfigs = [
{
name: 'totalCurrentQuantity',
filter: {},
rollups: [{ name: 'totalCurrentQuantity', property: 'currentQuantity', operation: 'sum' }],
},
];
productStockSchema.statics.stats = async function () {
const results = await aggregateRollups({
model: this,
rollupConfigs: rollupConfigs,
});
return results;
};
productStockSchema.statics.history = async function (from, to) {
const results = await aggregateRollupsHistory({
model: this,
startDate: from,
endDate: to,
rollupConfigs: rollupConfigs,
});
return results;
};
// Add virtual id getter
productStockSchema.virtual('id').get(function () {
return this._id;
});
// Configure JSON serialization to include virtuals
productStockSchema.set('toJSON', { virtuals: true });
// Create and export the model
export const productStockModel = mongoose.model('productStock', productStockSchema);

View File

@ -12,6 +12,7 @@ import { orderItemModel } from './inventory/orderitem.schema.js';
import { stockEventModel } from './inventory/stockevent.schema.js'; import { stockEventModel } from './inventory/stockevent.schema.js';
import { stockAuditModel } from './inventory/stockaudit.schema.js'; import { stockAuditModel } from './inventory/stockaudit.schema.js';
import { partStockModel } from './inventory/partstock.schema.js'; import { partStockModel } from './inventory/partstock.schema.js';
import { productStockModel } from './inventory/productstock.schema.js';
import { auditLogModel } from './management/auditlog.schema.js'; import { auditLogModel } from './management/auditlog.schema.js';
import { userModel } from './management/user.schema.js'; import { userModel } from './management/user.schema.js';
import { appPasswordModel } from './management/apppassword.schema.js'; import { appPasswordModel } from './management/apppassword.schema.js';
@ -115,12 +116,12 @@ export const models = {
label: 'Part Stock', label: 'Part Stock',
}, },
PDS: { PDS: {
model: null, model: productStockModel,
idField: '_id', idField: '_id',
type: 'productStock', type: 'productStock',
referenceField: '_reference', referenceField: '_reference',
label: 'Product Stock', label: 'Product Stock',
}, // No productStockModel found },
ADL: { ADL: {
model: auditLogModel, model: auditLogModel,
idField: '_id', idField: '_id',