This commit introduces a new utility function, `toId`, to handle ID conversions in the `listingvarient.schema.js` file. The `recalculate` method is updated to compute and update the stock quantity for listing variants based on product SKU and stock location. Additionally, a new test case is added in `stockQuantity.recalculate.test.js` to verify the correct behavior of stock quantity calculations before rolling up, ensuring comprehensive test coverage for this functionality.
124 lines
3.8 KiB
JavaScript
124 lines
3.8 KiB
JavaScript
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);
|