| Current Path : /home/deltalab/PMS/partner-manager-backend/models/mongoose/ |
| Current File : //home/deltalab/PMS/partner-manager-backend/models/mongoose/product.js |
const mongoose = require('mongoose');
const { Schema } = mongoose;
const { AttributeSchema } = require('./category');
const { OfferSchema } = require('./offer');
// SCHEMA ============================================
const AttrbuteValueSchema = new mongoose.Schema(
{
attribute: AttributeSchema,
value: Schema.Types.Mixed,
},
{
_id: false,
},
);
const ProductMediaSchema = new mongoose.Schema(
{
name: String,
url: String,
type: String,
data: String, // Base64 media content
filePath: String,
showPath: String,
imsgid: String, // The ims id associated to this media (if any)
},
{
_id: false,
},
);
const ProductBookedInventorySchema = new mongoose.Schema(
{
amount: Number,
omsgid: String,
fulfilled: Boolean,
channelId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Channel',
required: false,
},
},
{
timestamps: true,
_id: false,
},
);
/**
* The amount of a given product in a warehouse
*/
const ProductInventorySchema = new mongoose.Schema(
{
warehouseId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Warehouse',
unique: true,
},
amount: Number,
bookings: [ProductBookedInventorySchema],
},
{
_id: false,
},
);
const SizeSchema = new mongoose.Schema(
{
height: Number,
length: Number,
width: Number,
},
{
_id: false,
},
);
const RecommendationSchema = new mongoose.Schema(
{
productId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Product',
},
similarProducts: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Product',
}],
},
{
_id: false,
},
);
const ProductBaseSchema = new mongoose.Schema(
{
masterId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Master',
},
title: { type: String, required: true },
description: String,
customDescription: String,
brand: String,
price: Number,
originalPrice: Number,
msrp: Number,
imsgid: String, // the global idenfier provided by IMS upon creation
customerSku: String,
sku: { type: String, required: true },
barcode: String, // EAN, ISBN, other
requiresShipping: Boolean, // if this product has to be shipped
inventoryLevels: [ProductInventorySchema],
bookedQuantity: Number,
trackInventory: Boolean,
sellBelowZero: Boolean,
showMsrp: Boolean,
refrigerated: Boolean,
deleted: { type: Boolean, required: true, default: false },
weight: Number,
size: SizeSchema,
media: [ProductMediaSchema],
categoryId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Category',
},
offers: [OfferSchema],
imsCategories: [String],
imsTaxCode: String,
attributeSetId: String,
channelId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Channel',
required: true,
},
attributes: [AttrbuteValueSchema],
linkedProducts: [RecommendationSchema],
// linkedProducts: [{
// type: mongoose.Schema.Types.ObjectId,
// ref: 'Product',
// }],
recomExplanation: String,
minimumAgeRequired: Boolean,
fragile: Boolean,
bottle: Boolean,
imsEnabled: Boolean,
isValidFrom: Boolean,
validFrom: Date,
isValidUntil: Boolean,
validUntil: Date,
urlKey: String,
},
{
_id: false,
},
);
// Product quantity is based on inventory levels
ProductBaseSchema.virtual('quantity')
.set(() => {
// throw new Error(`cannot set product quantity directly: use inventoryLevels`);
console.log('cannot set product quantity directly: use inventoryLevels');
})
.get(() => {
// sanity check
if (!this.inventoryLevels || this.inventoryLevels.length === 0) return 0;
// reduce inventory amount to a single quantity
return this.inventoryLevels.reduce((quantity, inventory) => quantity + inventory.amount, 0);
});
const ProductSchema = new mongoose.Schema(
{
partnerId: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'Partner',
},
},
{
timestamps: true,
versionKey: false,
},
).add(ProductBaseSchema); // Using add() will copy over the product base methods too!
// MODELS ============================================
const productMediaModel = mongoose.model('Media', ProductMediaSchema);
const productInventoryModel = mongoose.model('ProductInventory', ProductInventorySchema);
const productBaseModel = mongoose.model('ProductBase', ProductBaseSchema);
const productModel = mongoose.model('Product', ProductSchema);
const recommendationModel = mongoose.model('Recommendation', RecommendationSchema);
// EXPORTS ===========================================
module.exports = {
productBaseModel,
productInventoryModel,
productMediaModel,
productModel,
recommendationModel,
ProductBaseSchema,
ProductInventorySchema,
ProductMediaSchema,
ProductSchema,
SizeSchema,
RecommendationSchema,
};