Files
ember-market-frontend/backend/models/Promotion.model.js
2025-03-10 17:39:37 +00:00

126 lines
3.0 KiB
JavaScript

import mongoose from "mongoose";
const PromotionSchema = new mongoose.Schema(
{
storeId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Store",
required: [true, "Store ID is required"]
},
code: {
type: String,
required: [true, "Promotion code is required"],
trim: true,
uppercase: true,
minlength: [3, "Promotion code must be at least 3 characters"],
maxlength: [20, "Promotion code cannot exceed 20 characters"]
},
discountType: {
type: String,
required: [true, "Discount type is required"],
enum: {
values: ["percentage", "fixed"],
message: "Discount type must be either percentage or fixed"
}
},
discountValue: {
type: Number,
required: [true, "Discount value is required"],
validate: {
validator: function(value) {
if (this.discountType === "percentage") {
return value > 0 && value <= 100;
}
return value > 0;
},
message: props =>
props.value <= 0
? "Discount value must be greater than 0"
: "Percentage discount cannot exceed 100%"
}
},
minOrderAmount: {
type: Number,
default: 0,
min: [0, "Minimum order amount cannot be negative"]
},
maxUsage: {
type: Number,
default: null
},
usageCount: {
type: Number,
default: 0
},
isActive: {
type: Boolean,
default: true
},
startDate: {
type: Date,
default: Date.now
},
endDate: {
type: Date,
default: null
},
description: {
type: String,
trim: true,
maxlength: [200, "Description cannot exceed 200 characters"]
}
},
{
timestamps: true
}
);
// Compound index to ensure unique promo codes per store
PromotionSchema.index({ storeId: 1, code: 1 }, { unique: true });
// Check if a promotion is valid and can be applied
PromotionSchema.methods.isValid = function() {
const now = new Date();
// Check if promotion is active
if (!this.isActive) return false;
// Check if promotion has expired
if (this.endDate && now > this.endDate) return false;
// Check if promotion has reached max usage (if set)
if (this.maxUsage !== null && this.usageCount >= this.maxUsage) return false;
return true;
};
// Calculate discount amount for a given order total
PromotionSchema.methods.calculateDiscount = function(orderTotal) {
if (!this.isValid()) {
return 0;
}
if (orderTotal < this.minOrderAmount) {
return 0;
}
let discountAmount = 0;
if (this.discountType === "percentage") {
discountAmount = (orderTotal * this.discountValue) / 100;
} else {
// Fixed amount discount
discountAmount = this.discountValue;
// Ensure discount doesn't exceed order total
if (discountAmount > orderTotal) {
discountAmount = orderTotal;
}
}
return parseFloat(discountAmount.toFixed(2));
};
const Promotion = mongoose.model("Promotion", PromotionSchema);
export default Promotion;