diff --git a/src/database/schemas/inventory/filamentstock.schema.js b/src/database/schemas/inventory/filamentstock.schema.js index 8e48672..67938a6 100644 --- a/src/database/schemas/inventory/filamentstock.schema.js +++ b/src/database/schemas/inventory/filamentstock.schema.js @@ -20,6 +20,11 @@ const filamentStockSchema = new Schema( gross: { type: Number, required: true }, }, filamentSku: { type: mongoose.Schema.Types.ObjectId, ref: 'filamentSku', required: true }, + stockLocation: { + type: mongoose.Schema.Types.ObjectId, + ref: 'stockLocation', + required: false, + }, }, { timestamps: true } ); diff --git a/src/database/schemas/inventory/partstock.schema.js b/src/database/schemas/inventory/partstock.schema.js index 95d6baf..f8d9347 100644 --- a/src/database/schemas/inventory/partstock.schema.js +++ b/src/database/schemas/inventory/partstock.schema.js @@ -12,6 +12,11 @@ const partStockSchema = new Schema( progress: { type: Number, required: false }, }, partSku: { type: mongoose.Schema.Types.ObjectId, ref: 'partSku', required: true }, + stockLocation: { + type: mongoose.Schema.Types.ObjectId, + ref: 'stockLocation', + required: false, + }, currentQuantity: { type: Number, required: true }, sourceType: { type: String, required: true }, source: { type: Schema.Types.ObjectId, refPath: 'sourceType', required: true }, diff --git a/src/database/schemas/inventory/productstock.schema.js b/src/database/schemas/inventory/productstock.schema.js index 86afaa4..b6038c0 100644 --- a/src/database/schemas/inventory/productstock.schema.js +++ b/src/database/schemas/inventory/productstock.schema.js @@ -19,6 +19,11 @@ const productStockSchema = new Schema( }, postedAt: { type: Date, required: false }, productSku: { type: mongoose.Schema.Types.ObjectId, ref: 'productSku', required: true }, + stockLocation: { + type: mongoose.Schema.Types.ObjectId, + ref: 'stockLocation', + required: false, + }, currentQuantity: { type: Number, required: true }, partStocks: [partStockUsageSchema], }, diff --git a/src/database/schemas/inventory/stockevent.schema.js b/src/database/schemas/inventory/stockevent.schema.js index ca11179..cc0bd31 100644 --- a/src/database/schemas/inventory/stockevent.schema.js +++ b/src/database/schemas/inventory/stockevent.schema.js @@ -25,7 +25,7 @@ const stockEventSchema = new Schema( ownerType: { type: String, required: true, - enum: ['user', 'subJob', 'stockAudit'], + enum: ['user', 'subJob', 'stockAudit', 'stockTransfer'], }, timestamp: { type: Date, default: Date.now }, }, diff --git a/src/database/schemas/inventory/stocklocation.schema.js b/src/database/schemas/inventory/stocklocation.schema.js new file mode 100644 index 0000000..db99cc6 --- /dev/null +++ b/src/database/schemas/inventory/stocklocation.schema.js @@ -0,0 +1,29 @@ +import mongoose from 'mongoose'; +import { generateId } from '../../utils.js'; +const { Schema } = mongoose; + +const stockLocationSchema = new Schema( + { + _reference: { type: String, default: () => generateId()() }, + name: { type: String, required: true }, + notes: { type: String, required: false }, + }, + { timestamps: true } +); + +stockLocationSchema.statics.stats = async function () { + const total = await this.countDocuments({}); + return { total: { count: total } }; +}; + +stockLocationSchema.statics.history = async function () { + return []; +}; + +stockLocationSchema.virtual('id').get(function () { + return this._id; +}); + +stockLocationSchema.set('toJSON', { virtuals: true }); + +export const stockLocationModel = mongoose.model('stockLocation', stockLocationSchema); diff --git a/src/database/schemas/inventory/stocktransfer.schema.js b/src/database/schemas/inventory/stocktransfer.schema.js new file mode 100644 index 0000000..284bcd4 --- /dev/null +++ b/src/database/schemas/inventory/stocktransfer.schema.js @@ -0,0 +1,71 @@ +import mongoose from 'mongoose'; +import { generateId } from '../../utils.js'; +const { Schema } = mongoose; + +const stockTransferLineSchema = new Schema( + { + fromStockType: { + type: String, + required: true, + enum: ['filamentStock', 'partStock', 'productStock'], + }, + fromStock: { + type: Schema.Types.ObjectId, + refPath: 'fromStockType', + required: true, + }, + quantity: { type: Number, required: true }, + toStockLocation: { + type: Schema.Types.ObjectId, + ref: 'stockLocation', + required: true, + }, + toStockType: { + type: String, + required: false, + enum: ['filamentStock', 'partStock', 'productStock'], + }, + toStock: { + type: Schema.Types.ObjectId, + refPath: 'toStockType', + required: false, + }, + }, + { _id: true } +); + +const stockTransferSchema = new Schema( + { + _reference: { type: String, default: () => generateId()() }, + state: { + type: { type: String, required: true, default: 'draft' }, + progress: { type: Number, required: false }, + }, + postedAt: { type: Date, required: false }, + lines: { type: [stockTransferLineSchema], default: [] }, + }, + { timestamps: true } +); + +stockTransferSchema.statics.stats = async function () { + const [draft, posted] = await Promise.all([ + this.countDocuments({ 'state.type': 'draft' }), + this.countDocuments({ 'state.type': 'posted' }), + ]); + return { + draft: { count: draft }, + posted: { count: posted }, + }; +}; + +stockTransferSchema.statics.history = async function () { + return []; +}; + +stockTransferSchema.virtual('id').get(function () { + return this._id; +}); + +stockTransferSchema.set('toJSON', { virtuals: true }); + +export const stockTransferModel = mongoose.model('stockTransfer', stockTransferSchema); diff --git a/src/database/schemas/management/part.schema.js b/src/database/schemas/management/part.schema.js index de89983..71008dc 100644 --- a/src/database/schemas/management/part.schema.js +++ b/src/database/schemas/management/part.schema.js @@ -31,19 +31,10 @@ partSchema.virtual('id').get(function () { partSchema.set('toJSON', { virtuals: true }); partSchema.statics.recalculate = async function (part, user) { - const orderItemModel = mongoose.model('orderItem'); - const itemId = part._id; - const draftOrderItems = await orderItemModel - .find({ - 'state.type': 'draft', - itemType: 'part', - item: itemId, - }) - .populate('order') - .lean(); - - for (const orderItem of draftOrderItems) { - await orderItemModel.recalculate(orderItem, user); + const partSkuModel = mongoose.model('partSku'); + const skus = await partSkuModel.find({ part: part._id }).select('_id').lean(); + for (const sku of skus) { + await partSkuModel.recalculate(sku, user); } }; diff --git a/src/database/schemas/models.js b/src/database/schemas/models.js index 86c5a26..f771452 100644 --- a/src/database/schemas/models.js +++ b/src/database/schemas/models.js @@ -17,6 +17,8 @@ import { stockEventModel } from './inventory/stockevent.schema.js'; import { stockAuditModel } from './inventory/stockaudit.schema.js'; import { partStockModel } from './inventory/partstock.schema.js'; import { productStockModel } from './inventory/productstock.schema.js'; +import { stockLocationModel } from './inventory/stocklocation.schema.js'; +import { stockTransferModel } from './inventory/stocktransfer.schema.js'; import { auditLogModel } from './management/auditlog.schema.js'; import { userModel } from './management/user.schema.js'; import { appPasswordModel } from './management/apppassword.schema.js'; @@ -157,6 +159,20 @@ export const models = { referenceField: '_reference', label: 'Product Stock', }, + SLN: { + model: stockLocationModel, + idField: '_id', + type: 'stockLocation', + referenceField: '_reference', + label: 'Stock Location', + }, + STT: { + model: stockTransferModel, + idField: '_id', + type: 'stockTransfer', + referenceField: '_reference', + label: 'Stock Transfer', + }, ADL: { model: auditLogModel, idField: '_id',