122 lines
4.2 KiB
TypeScript
122 lines
4.2 KiB
TypeScript
import { Schema, model } from "mongoose";
|
|
|
|
import { IDimensions, IPrice, IProductVariant, ISaleFormat, IStatistics } from "./Abstraction/IProductVariant";
|
|
import { ProductMarketStatus } from "../../../common/enums/product.enum";
|
|
|
|
const productStatisticsSchema = new Schema<IStatistics>(
|
|
{
|
|
satisfied: { type: { rate: Number, count: Number } },
|
|
dissatisfied: { type: { rate: Number, count: Number } },
|
|
},
|
|
{ _id: false },
|
|
);
|
|
|
|
const productSaleFormat = new Schema<ISaleFormat>(
|
|
{
|
|
// isWholeSale: Boolean,
|
|
wholeSale: { type: [{ from: Number, to: Number, price: Number }] },
|
|
},
|
|
{ _id: false },
|
|
);
|
|
|
|
export const productDimensionsSchema = new Schema<IDimensions>(
|
|
{
|
|
package_weight: Number,
|
|
package_height: Number,
|
|
package_length: Number,
|
|
package_width: Number,
|
|
},
|
|
{ _id: false },
|
|
);
|
|
|
|
const productPriceSchema = new Schema<IPrice>(
|
|
{
|
|
order_limit: { type: Number, required: true },
|
|
retailPrice: { type: Number },
|
|
selling_price: { type: Number },
|
|
//specialSale
|
|
is_specialSale: { type: Boolean, default: false },
|
|
discount_percent: { type: Number, default: 0 },
|
|
specialSale_order_limit: { type: Number, default: null },
|
|
specialSale_quantity: { type: Number, default: null },
|
|
specialSale_endDate: { type: String, default: null },
|
|
},
|
|
{ _id: false },
|
|
);
|
|
|
|
const productVariantSchema = new Schema<IProductVariant>(
|
|
{
|
|
product: { type: Number, ref: "Product", required: true },
|
|
statistics: { type: productStatisticsSchema },
|
|
warranty: { type: Number, ref: "Warranty", required: true },
|
|
shop: { type: Schema.Types.ObjectId, ref: "Shop", required: true },
|
|
market_status: { type: String, enum: ProductMarketStatus, required: true },
|
|
postingTime: { type: Number, required: true },
|
|
price: { type: productPriceSchema, required: true },
|
|
stock: { type: Number, required: true },
|
|
isFreeShip: { type: Boolean, default: false },
|
|
isWholeSale: { type: Boolean, default: false },
|
|
saleFormat: { type: productSaleFormat },
|
|
dimensions: { type: productDimensionsSchema, required: true },
|
|
sellerSpecialCode: { type: String },
|
|
themeValue: { type: Schema.Types.ObjectId, ref: "ThemeValue", required: true },
|
|
deleted: { type: Boolean, default: false },
|
|
},
|
|
{ timestamps: true, toObject: { virtuals: true, versionKey: false }, toJSON: { virtuals: true, versionKey: false }, id: false },
|
|
);
|
|
|
|
productVariantSchema.index({ product: 1, deleted: 1 });
|
|
productVariantSchema.index({ shop: 1, product: 1, deleted: 1 });
|
|
productVariantSchema.index({ market_status: 1, deleted: 1 });
|
|
|
|
productVariantSchema.pre("save", function (next) {
|
|
if (this.price) {
|
|
if (this.price.retailPrice) {
|
|
this.price.retailPrice = Number(this.price.retailPrice);
|
|
const sellingPrice =
|
|
this.price.discount_percent > 0 ? this.price.retailPrice * ((100 - this.price.discount_percent) / 100) : this.price.retailPrice;
|
|
|
|
this.price.selling_price = Number(sellingPrice);
|
|
}
|
|
}
|
|
|
|
next();
|
|
});
|
|
|
|
productVariantSchema.pre(["findOneAndUpdate", "updateOne", "updateMany"], function (next) {
|
|
const update = this.getUpdate() as IProductVariant;
|
|
if (!update) return next();
|
|
|
|
// ensure price object exists in the update object
|
|
if (update.price && update.price.retailPrice !== undefined) {
|
|
const retailPrice = Number(update.price.retailPrice);
|
|
const discountPercent = update.price.discount_percent || 0;
|
|
|
|
// calculate selling price based on retailPrice and discount_percent
|
|
const sellingPrice = discountPercent > 0 ? retailPrice * ((100 - discountPercent) / 100) : retailPrice;
|
|
|
|
// set the calculated selling price in the update object
|
|
update.price.retailPrice = retailPrice;
|
|
update.price.selling_price = Number(sellingPrice);
|
|
update.price.discount_percent = discountPercent;
|
|
}
|
|
|
|
next();
|
|
});
|
|
|
|
const ProductVariantModel = model<IProductVariant>("ProductVariant", productVariantSchema);
|
|
|
|
export { ProductVariantModel };
|
|
|
|
// const productSpecialSale = new Schema<ISpecialSale>(
|
|
// {
|
|
// endDate: String,
|
|
// type: { type: String, enum: ProductDiscountType, required: true },
|
|
// discountValue: Number,
|
|
// order_limit: Number,
|
|
// quantity: Number,
|
|
// priceAfterDiscount: Number,
|
|
// },
|
|
// { _id: false },
|
|
// );
|