This commit is contained in:
mahyargdz
2025-09-14 15:15:03 +03:30
commit be82059172
534 changed files with 51310 additions and 0 deletions
@@ -0,0 +1,118 @@
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 },
color: { type: Number, ref: "Color", required: false },
size: { type: Number, ref: "Size", required: false },
meterage: { type: Number, ref: "Meterage", required: false },
},
{ timestamps: true, toObject: { virtuals: true, versionKey: false }, toJSON: { virtuals: true, versionKey: false }, id: false },
);
productVariantSchema.pre("save", function (next) {
if (this.price) {
if (this.price.retailPrice) {
this.price.retailPrice = Math.round(this.price.retailPrice / 10000) * 10000;
const sellingPrice =
this.price.discount_percent > 0 ? this.price.retailPrice * ((100 - this.price.discount_percent) / 100) : this.price.retailPrice;
this.price.selling_price = Math.round(sellingPrice / 10000) * 10000;
}
}
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 = Math.round(update.price.retailPrice / 10000) * 10000;
const discountPercent = Math.round(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 = Math.round(sellingPrice / 10000) * 10000;
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 },
// );