import mongoose from 'mongoose'; import { generateId } from '../../utils.js'; import { aggregateRollups, editObject } from '../../database.js'; const { Schema } = mongoose; const toId = (value) => { if (value == null) return null; if (typeof value === 'object' && value._id) return String(value._id); return String(value); }; const listingVarientSchema = new Schema( { _reference: { type: String, default: () => generateId()() }, listing: { type: Schema.Types.ObjectId, ref: 'listing', required: true }, product: { type: Schema.Types.ObjectId, ref: 'product', required: false }, productSku: { type: Schema.Types.ObjectId, ref: 'productSku', required: false }, state: { type: { type: String, enum: ['draft', 'active', 'inactive', 'deleted', 'suspended', 'syncing'], default: 'draft', }, message: { type: String, required: false }, }, externalReference: { type: String, required: false }, price: { type: Number, required: false }, currency: { type: String, required: false }, priceTaxRate: { type: Schema.Types.ObjectId, ref: 'taxRate', required: false }, priceWithTax: { type: Number, required: false }, lastSyncedAt: { type: Date, required: false }, stockQuantity: { type: Number, required: false, default: 0 }, }, { timestamps: true } ); listingVarientSchema.index({ currency: 'text', 'state.type': 'text' }); listingVarientSchema.index({ listing: 1, externalReference: 1 }, { unique: true, sparse: true }); listingVarientSchema.virtual('id').get(function () { return this._id; }); listingVarientSchema.set('toJSON', { virtuals: true, transform(doc, ret) { if (!ret.state && ret.status) { ret.state = { type: ret.status, message: null }; } if (ret.status) delete ret.status; return ret; }, }); listingVarientSchema.statics.recalculate = async function (listingVarient, user) { const listingId = listingVarient?.listing?._id || listingVarient?.listing; const varientId = listingVarient?._id; const productSkuId = toId(listingVarient?.productSku); if (varientId && productSkuId && (await this.exists({ _id: varientId }))) { let listing = listingVarient.listing; if (!listing?.stockLocation) { listing = await mongoose .model('listing') .findById(listingId) .select('stockLocation product') .lean(); } const stockLocationId = toId(listing?.stockLocation); if (stockLocationId) { const stockRollup = await aggregateRollups({ model: mongoose.model('productStock'), baseFilter: { productSku: new mongoose.Types.ObjectId(productSkuId), stockLocation: new mongoose.Types.ObjectId(stockLocationId), }, rollupConfigs: [ { name: 'stockQuantity', rollups: [{ name: 'stockQuantity', property: 'currentQuantity', operation: 'sum' }], }, ], }); const stockQuantity = stockRollup.stockQuantity?.sum || 0; if (listingVarient.stockQuantity !== stockQuantity) { await editObject({ model: this, id: varientId, updateData: { stockQuantity }, user, recalculate: false, }); } } } if (!listingId) { return; } const rollupResults = await aggregateRollups({ model: this, baseFilter: { listing: new mongoose.Types.ObjectId(listingId) }, rollupConfigs: [ { name: 'stockQuantity', rollups: [{ name: 'stockQuantity', property: 'stockQuantity', operation: 'sum' }], }, ], }); await editObject({ model: mongoose.model('listing'), id: listingId, updateData: { stockQuantity: rollupResults.stockQuantity?.sum || 0, }, user, recalculate: false, }); }; export const listingVarientModel = mongoose.model('listingVarient', listingVarientSchema);